@lumencast/runtime 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/animate/frame-coalescer.d.ts +13 -0
- package/dist/animate/frame-coalescer.d.ts.map +1 -0
- package/dist/animate/frame-coalescer.js +46 -0
- package/dist/animate/frame-coalescer.js.map +1 -0
- package/dist/animate/keyframes.d.ts +1 -1
- package/dist/animate/keyframes.d.ts.map +1 -1
- package/dist/animate/keyframes.js +20 -6
- package/dist/animate/keyframes.js.map +1 -1
- package/dist/animate/transitions.d.ts +33 -1
- package/dist/animate/transitions.d.ts.map +1 -1
- package/dist/animate/transitions.js +78 -3
- package/dist/animate/transitions.js.map +1 -1
- package/dist/{broadcast-B82fQPph.js → broadcast-3vYij4k-.js} +3 -3
- package/dist/{broadcast-B82fQPph.js.map → broadcast-3vYij4k-.js.map} +1 -1
- package/dist/{control-DIfwMYRb.js → control-BFNkY7-6.js} +4 -4
- package/dist/{control-DIfwMYRb.js.map → control-BFNkY7-6.js.map} +1 -1
- package/dist/{index-BFZXQAD7.js → index-CyOlpZAL.js} +318 -145
- package/dist/index-CyOlpZAL.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.html +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/lumencast.js +9 -2
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +11 -1
- package/dist/mount.js.map +1 -1
- package/dist/render/bind-animate.d.ts +40 -0
- package/dist/render/bind-animate.d.ts.map +1 -0
- package/dist/render/bind-animate.js +329 -0
- package/dist/render/bind-animate.js.map +1 -0
- package/dist/render/bundle.d.ts +48 -6
- package/dist/render/bundle.d.ts.map +1 -1
- package/dist/render/bundle.js +71 -4
- package/dist/render/bundle.js.map +1 -1
- package/dist/render/color-interp.d.ts +18 -0
- package/dist/render/color-interp.d.ts.map +1 -0
- package/dist/render/color-interp.js +303 -0
- package/dist/render/color-interp.js.map +1 -0
- package/dist/render/css-color.d.ts +16 -0
- package/dist/render/css-color.d.ts.map +1 -0
- package/dist/render/css-color.js +130 -0
- package/dist/render/css-color.js.map +1 -0
- package/dist/render/diagnostics.d.ts +26 -0
- package/dist/render/diagnostics.d.ts.map +1 -0
- package/dist/render/diagnostics.js +58 -0
- package/dist/render/diagnostics.js.map +1 -0
- package/dist/render/fill.d.ts +15 -3
- package/dist/render/fill.d.ts.map +1 -1
- package/dist/render/fill.js +81 -14
- package/dist/render/fill.js.map +1 -1
- package/dist/render/filter-clamp.d.ts +35 -0
- package/dist/render/filter-clamp.d.ts.map +1 -0
- package/dist/render/filter-clamp.js +90 -0
- package/dist/render/filter-clamp.js.map +1 -0
- package/dist/render/keyframe-player.d.ts +4 -1
- package/dist/render/keyframe-player.d.ts.map +1 -1
- package/dist/render/keyframe-player.js +2 -2
- package/dist/render/keyframe-player.js.map +1 -1
- package/dist/render/primitives/frame.d.ts +16 -1
- package/dist/render/primitives/frame.d.ts.map +1 -1
- package/dist/render/primitives/frame.js +44 -13
- package/dist/render/primitives/frame.js.map +1 -1
- package/dist/render/primitives/image.d.ts +1 -1
- package/dist/render/primitives/image.d.ts.map +1 -1
- package/dist/render/primitives/image.js +8 -5
- package/dist/render/primitives/image.js.map +1 -1
- package/dist/render/primitives/index.d.ts +3 -0
- package/dist/render/primitives/index.d.ts.map +1 -1
- package/dist/render/primitives/index.js.map +1 -1
- package/dist/render/primitives/instance.d.ts +1 -1
- package/dist/render/primitives/instance.d.ts.map +1 -1
- package/dist/render/primitives/instance.js +10 -13
- package/dist/render/primitives/instance.js.map +1 -1
- package/dist/render/primitives/shape.d.ts +9 -3
- package/dist/render/primitives/shape.d.ts.map +1 -1
- package/dist/render/primitives/shape.js +58 -14
- package/dist/render/primitives/shape.js.map +1 -1
- package/dist/render/primitives/text.d.ts +35 -4
- package/dist/render/primitives/text.d.ts.map +1 -1
- package/dist/render/primitives/text.js +181 -9
- package/dist/render/primitives/text.js.map +1 -1
- package/dist/render/prop-allowlist.d.ts +10 -0
- package/dist/render/prop-allowlist.d.ts.map +1 -0
- package/dist/render/prop-allowlist.js +112 -0
- package/dist/render/prop-allowlist.js.map +1 -0
- package/dist/render/svg-path.d.ts +35 -0
- package/dist/render/svg-path.d.ts.map +1 -0
- package/dist/render/svg-path.js +211 -0
- package/dist/render/svg-path.js.map +1 -0
- package/dist/render/tree.d.ts.map +1 -1
- package/dist/render/tree.js +30 -5
- package/dist/render/tree.js.map +1 -1
- package/dist/{status-pill-DNHbHdag.js → status-pill-DIpXc5du.js} +2 -2
- package/dist/{status-pill-DNHbHdag.js.map → status-pill-DIpXc5du.js.map} +1 -1
- package/dist/{test-Dp0QrKYM.js → test-ByRec1kd.js} +4 -4
- package/dist/{test-Dp0QrKYM.js.map → test-ByRec1kd.js.map} +1 -1
- package/dist/tree-D5wYHpPu.js +1230 -0
- package/dist/tree-D5wYHpPu.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/animate/frame-coalescer.ts +63 -0
- package/src/animate/keyframes.ts +24 -5
- package/src/animate/transitions.ts +85 -3
- package/src/index.ts +24 -0
- package/src/mount.ts +12 -1
- package/src/render/bind-animate.tsx +370 -0
- package/src/render/bundle.ts +102 -10
- package/src/render/color-interp.ts +303 -0
- package/src/render/css-color.ts +145 -0
- package/src/render/diagnostics.ts +75 -0
- package/src/render/fill.tsx +85 -14
- package/src/render/filter-clamp.ts +99 -0
- package/src/render/keyframe-player.tsx +10 -2
- package/src/render/primitives/frame.tsx +53 -14
- package/src/render/primitives/image.tsx +8 -4
- package/src/render/primitives/index.ts +3 -0
- package/src/render/primitives/instance.tsx +14 -15
- package/src/render/primitives/shape.tsx +78 -14
- package/src/render/primitives/text.tsx +226 -9
- package/src/render/prop-allowlist.ts +119 -0
- package/src/render/svg-path.ts +215 -0
- package/src/render/tree.tsx +41 -6
- package/src/types.ts +27 -0
- package/dist/index-BFZXQAD7.js.map +0 -1
- package/dist/tree-x5Qd9Kq0.js +0 -508
- package/dist/tree-x5Qd9Kq0.js.map +0 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** RC#10 — hard cap : 8 KiB per subpath `d` string. */
|
|
2
|
+
export declare const MAX_SUBPATH_LEN = 8192;
|
|
3
|
+
/**
|
|
4
|
+
* RC#10 — hard cap on commands per subpath. Aligned on the compiler's
|
|
5
|
+
* MAX_PATH_COMMANDS = 4000 (PR #39, deliberate authoring cap) so a live
|
|
6
|
+
* LSDP delta can never carry more commands than the authoring pipeline
|
|
7
|
+
* accepts. A shared constant module is tracked in issue #41 — do not
|
|
8
|
+
* diverge these two values in the meantime.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MAX_SUBPATH_COMMANDS = 4000;
|
|
11
|
+
/** RC#10 — hard cap on subpaths per shape. */
|
|
12
|
+
export declare const MAX_SUBPATHS = 64;
|
|
13
|
+
/**
|
|
14
|
+
* Validate an untrusted SVG path `d` string against the strict grammar
|
|
15
|
+
* above. Returns the validated (trimmed) string or `null` on rejection.
|
|
16
|
+
* A `null` MUST be handled as "omit the subpath + emit a diagnostic" —
|
|
17
|
+
* never interpolate the raw input into the DOM.
|
|
18
|
+
*/
|
|
19
|
+
export declare function validatePathData(value: unknown): string | null;
|
|
20
|
+
export interface SubPath {
|
|
21
|
+
d: string;
|
|
22
|
+
fillRule: "nonzero" | "evenodd";
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve a shape's `pathData` / `paths[]` props (LSML 1.1 §4.6) into
|
|
26
|
+
* validated subpaths ready for rendering — one `<path>` element per
|
|
27
|
+
* entry (ADR 001 §3.2.3). `pathData` is equivalent to
|
|
28
|
+
* `paths: [{ data: pathData, windingRule: "NONZERO" }]`.
|
|
29
|
+
*
|
|
30
|
+
* Re-runs at every render (RC#10 — props are live via LSDP deltas).
|
|
31
|
+
* Every rejected or unrendered field emits a diagnostic (ADR 001 §3.4,
|
|
32
|
+
* anti-silent-drop) that NEVER contains the value (R9).
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseShapePaths(resolved: Record<string, unknown>, nodeId?: string): SubPath[];
|
|
35
|
+
//# sourceMappingURL=svg-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-path.d.ts","sourceRoot":"","sources":["../../src/render/svg-path.ts"],"names":[],"mappings":"AAgCA,uDAAuD;AACvD,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AACzC,8CAA8C;AAC9C,eAAO,MAAM,YAAY,KAAK,CAAC;AAa/B;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAyE9D;AAED,MAAM,WAAW,OAAO;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,CA6C7F"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// Strict SVG path-data validator — the ONLY gate through which
|
|
2
|
+
// untrusted `d` strings (bundle props AND live LSDP deltas, see
|
|
3
|
+
// `resolveProps` in tree.tsx) may reach a rendered `<path d>` attribute.
|
|
4
|
+
//
|
|
5
|
+
// ADR 001 §6 RC#10 (allowlisted `d` grammar) + RC#12 (anti-ReDoS),
|
|
6
|
+
// threat model Bastion 2026-06-10, issue #30. Validation runs at EVERY
|
|
7
|
+
// render — props are wire-drivable, so a hostile delta arriving after
|
|
8
|
+
// mount goes through the exact same gate as a static prop.
|
|
9
|
+
//
|
|
10
|
+
// Accepted grammar (SVG path data, LSML 1.1 §4.6, nothing more) :
|
|
11
|
+
// - command letters : M m L l H h V v C c S s Q q T t A a Z z
|
|
12
|
+
// - numbers : [+-]? digits [. digits]? ([eE] [+-]? digits)?
|
|
13
|
+
// - separators : space, tab, CR, LF, comma
|
|
14
|
+
// Anything else — including `url(`, `data:`, `<`, `&`, parentheses,
|
|
15
|
+
// quotes, semicolons, braces — is REJECTED (null). Never passthrough.
|
|
16
|
+
//
|
|
17
|
+
// ── Linear-time justification (RC#12, written per Bastion) ──────────
|
|
18
|
+
// 1. Inputs longer than MAX_SUBPATH_LEN (8 KiB) are rejected on a
|
|
19
|
+
// single O(1) length check before any scanning — a 10⁶-command
|
|
20
|
+
// payload never reaches the scanner.
|
|
21
|
+
// 2. The scanner is a hand-written single forward pass : every loop
|
|
22
|
+
// iteration advances `i` by at least one character and there is no
|
|
23
|
+
// regex anywhere, so total work is O(min(n, 8192)) per value
|
|
24
|
+
// regardless of payload shape. No backtracking is possible by
|
|
25
|
+
// construction.
|
|
26
|
+
// 3. The command cap (MAX_SUBPATH_COMMANDS) additionally bounds the
|
|
27
|
+
// number of path segments the SVG engine will ever be asked to
|
|
28
|
+
// tessellate, independently of string length.
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────────
|
|
30
|
+
import { emitDiagnostic } from "./diagnostics";
|
|
31
|
+
/** RC#10 — hard cap : 8 KiB per subpath `d` string. */
|
|
32
|
+
export const MAX_SUBPATH_LEN = 8192;
|
|
33
|
+
/**
|
|
34
|
+
* RC#10 — hard cap on commands per subpath. Aligned on the compiler's
|
|
35
|
+
* MAX_PATH_COMMANDS = 4000 (PR #39, deliberate authoring cap) so a live
|
|
36
|
+
* LSDP delta can never carry more commands than the authoring pipeline
|
|
37
|
+
* accepts. A shared constant module is tracked in issue #41 — do not
|
|
38
|
+
* diverge these two values in the meantime.
|
|
39
|
+
*/
|
|
40
|
+
export const MAX_SUBPATH_COMMANDS = 4000;
|
|
41
|
+
/** RC#10 — hard cap on subpaths per shape. */
|
|
42
|
+
export const MAX_SUBPATHS = 64;
|
|
43
|
+
const CMD_CHARS = new Set("MmLlHhVvCcSsQqTtAaZz");
|
|
44
|
+
function isDigit(code) {
|
|
45
|
+
return code >= 0x30 && code <= 0x39; // 0-9
|
|
46
|
+
}
|
|
47
|
+
function isSeparator(code) {
|
|
48
|
+
// space, tab, CR, LF, comma
|
|
49
|
+
return code === 0x20 || code === 0x09 || code === 0x0d || code === 0x0a || code === 0x2c;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Validate an untrusted SVG path `d` string against the strict grammar
|
|
53
|
+
* above. Returns the validated (trimmed) string or `null` on rejection.
|
|
54
|
+
* A `null` MUST be handled as "omit the subpath + emit a diagnostic" —
|
|
55
|
+
* never interpolate the raw input into the DOM.
|
|
56
|
+
*/
|
|
57
|
+
export function validatePathData(value) {
|
|
58
|
+
if (typeof value !== "string")
|
|
59
|
+
return null;
|
|
60
|
+
// O(1) length gate BEFORE any per-character work (RC#12).
|
|
61
|
+
if (value.length === 0 || value.length > MAX_SUBPATH_LEN)
|
|
62
|
+
return null;
|
|
63
|
+
const d = value.trim();
|
|
64
|
+
if (d.length === 0)
|
|
65
|
+
return null;
|
|
66
|
+
// Contractual explicit rejects (Bastion RC#10) — redundant with the
|
|
67
|
+
// allowlist scan below, kept as belt-and-braces so the contract
|
|
68
|
+
// holds even if the grammar is ever extended.
|
|
69
|
+
const lower = d.toLowerCase();
|
|
70
|
+
if (lower.includes("url(") || lower.includes("data:"))
|
|
71
|
+
return null;
|
|
72
|
+
if (d.includes("<") || d.includes("&"))
|
|
73
|
+
return null;
|
|
74
|
+
// Single forward pass — tokenizes commands and numbers, rejects any
|
|
75
|
+
// character outside the allowlist, counts commands.
|
|
76
|
+
const n = d.length;
|
|
77
|
+
let i = 0;
|
|
78
|
+
let commands = 0;
|
|
79
|
+
let sawCommand = false;
|
|
80
|
+
while (i < n) {
|
|
81
|
+
const code = d.charCodeAt(i);
|
|
82
|
+
if (isSeparator(code)) {
|
|
83
|
+
i++;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const ch = d[i];
|
|
87
|
+
if (CMD_CHARS.has(ch)) {
|
|
88
|
+
// Path data must start with a moveto (M/m).
|
|
89
|
+
if (!sawCommand && ch !== "M" && ch !== "m")
|
|
90
|
+
return null;
|
|
91
|
+
sawCommand = true;
|
|
92
|
+
commands++;
|
|
93
|
+
if (commands > MAX_SUBPATH_COMMANDS)
|
|
94
|
+
return null;
|
|
95
|
+
i++;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
// Anything else must be a well-formed number token — and numbers
|
|
99
|
+
// can only appear after the leading moveto.
|
|
100
|
+
if (!sawCommand)
|
|
101
|
+
return null;
|
|
102
|
+
if (ch === "+" || ch === "-")
|
|
103
|
+
i++;
|
|
104
|
+
let digits = 0;
|
|
105
|
+
while (i < n && isDigit(d.charCodeAt(i))) {
|
|
106
|
+
i++;
|
|
107
|
+
digits++;
|
|
108
|
+
}
|
|
109
|
+
if (i < n && d[i] === ".") {
|
|
110
|
+
i++;
|
|
111
|
+
let fracDigits = 0;
|
|
112
|
+
while (i < n && isDigit(d.charCodeAt(i))) {
|
|
113
|
+
i++;
|
|
114
|
+
fracDigits++;
|
|
115
|
+
}
|
|
116
|
+
// A token ending in a bare "." (empty decimal part, e.g. "1.")
|
|
117
|
+
// must not be immediately followed by another "." — "1..2" is not
|
|
118
|
+
// valid SVG path data and would otherwise be mis-scanned as the
|
|
119
|
+
// two tokens "1." + ".2" (Probe bug report, issue #30).
|
|
120
|
+
if (fracDigits === 0 && i < n && d[i] === ".")
|
|
121
|
+
return null;
|
|
122
|
+
digits += fracDigits;
|
|
123
|
+
}
|
|
124
|
+
if (digits === 0)
|
|
125
|
+
return null; // bare sign / dot / forbidden char
|
|
126
|
+
if (i < n && (d[i] === "e" || d[i] === "E")) {
|
|
127
|
+
i++;
|
|
128
|
+
if (i < n && (d[i] === "+" || d[i] === "-"))
|
|
129
|
+
i++;
|
|
130
|
+
let expDigits = 0;
|
|
131
|
+
while (i < n && isDigit(d.charCodeAt(i))) {
|
|
132
|
+
i++;
|
|
133
|
+
expDigits++;
|
|
134
|
+
}
|
|
135
|
+
if (expDigits === 0)
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (commands === 0)
|
|
140
|
+
return null;
|
|
141
|
+
return d;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Resolve a shape's `pathData` / `paths[]` props (LSML 1.1 §4.6) into
|
|
145
|
+
* validated subpaths ready for rendering — one `<path>` element per
|
|
146
|
+
* entry (ADR 001 §3.2.3). `pathData` is equivalent to
|
|
147
|
+
* `paths: [{ data: pathData, windingRule: "NONZERO" }]`.
|
|
148
|
+
*
|
|
149
|
+
* Re-runs at every render (RC#10 — props are live via LSDP deltas).
|
|
150
|
+
* Every rejected or unrendered field emits a diagnostic (ADR 001 §3.4,
|
|
151
|
+
* anti-silent-drop) that NEVER contains the value (R9).
|
|
152
|
+
*/
|
|
153
|
+
export function parseShapePaths(resolved, nodeId) {
|
|
154
|
+
const rawPaths = resolved.paths;
|
|
155
|
+
const rawPathData = resolved.pathData;
|
|
156
|
+
if (Array.isArray(rawPaths)) {
|
|
157
|
+
if (rawPathData !== undefined) {
|
|
158
|
+
// Spec §4.6 : mutually exclusive. Tolerate with paths[] winning
|
|
159
|
+
// (mirrors the fills[]/fill precedence), but never silently.
|
|
160
|
+
warnPath(nodeId, "shape.pathData", "mutually exclusive with paths[] ; paths[] wins");
|
|
161
|
+
}
|
|
162
|
+
const out = [];
|
|
163
|
+
for (let idx = 0; idx < rawPaths.length; idx++) {
|
|
164
|
+
if (out.length >= MAX_SUBPATHS) {
|
|
165
|
+
warnPath(nodeId, "shape.paths", "subpath cap exceeded ; remaining entries dropped");
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
const entry = rawPaths[idx];
|
|
169
|
+
const d = validatePathData(typeof entry === "object" && entry !== null ? entry.data : undefined);
|
|
170
|
+
if (d === null) {
|
|
171
|
+
warnPath(nodeId, "shape.paths.data", "not a strict SVG path grammar (allowlist/caps)");
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
out.push({ d, fillRule: toFillRule(entry?.windingRule, nodeId) });
|
|
175
|
+
}
|
|
176
|
+
if (out.length === 0 && rawPaths.length > 0) {
|
|
177
|
+
warnPath(nodeId, "shape.paths", "no renderable subpath ; shape geometry omitted");
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
if (rawPathData !== undefined) {
|
|
182
|
+
const d = validatePathData(rawPathData);
|
|
183
|
+
if (d === null) {
|
|
184
|
+
warnPath(nodeId, "shape.pathData", "not a strict SVG path grammar (allowlist/caps)");
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
return [{ d, fillRule: "nonzero" }];
|
|
188
|
+
}
|
|
189
|
+
// geometry:"path" with neither prop — spec'd field combination we
|
|
190
|
+
// cannot render. Diagnostic, never a silent no-op (ADR 001 §3.4).
|
|
191
|
+
warnPath(nodeId, "shape.paths", "geometry is path but neither pathData nor paths[] is present");
|
|
192
|
+
return [];
|
|
193
|
+
}
|
|
194
|
+
function toFillRule(windingRule, nodeId) {
|
|
195
|
+
if (windingRule === undefined || windingRule === "NONZERO")
|
|
196
|
+
return "nonzero";
|
|
197
|
+
if (windingRule === "EVENODD")
|
|
198
|
+
return "evenodd";
|
|
199
|
+
warnPath(nodeId, "shape.paths.windingRule", "unknown winding rule ; defaulting to nonzero");
|
|
200
|
+
return "nonzero";
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Diagnostic for a rejected / unrendered path field. Bastion R9
|
|
204
|
+
* (ADR 001 §5.1) : the rejected VALUE is never logged nor forwarded —
|
|
205
|
+
* only `node.id` (RC#7, issue #34), the field name and a static reason.
|
|
206
|
+
* Routed through the structured diagnostics channel.
|
|
207
|
+
*/
|
|
208
|
+
function warnPath(nodeId, field, reason) {
|
|
209
|
+
emitDiagnostic(nodeId, field, reason);
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=svg-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-path.js","sourceRoot":"","sources":["../../src/render/svg-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/render/tree.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/render/tree.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAI5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAQ3C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,SAAS,GAAG,SAAS,CAK1D"}
|
package/dist/render/tree.js
CHANGED
|
@@ -2,12 +2,16 @@ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
|
2
2
|
// Recursive tree renderer — resolves bindings, dispatches to
|
|
3
3
|
// primitives, handles `repeat` specially.
|
|
4
4
|
import { useSignals } from "@preact/signals-react/runtime";
|
|
5
|
+
import { motion } from "framer-motion";
|
|
5
6
|
import { useMemo } from "react";
|
|
6
7
|
import { PRIMITIVES } from "./primitives";
|
|
7
8
|
import { PathScopeProvider, scopedPath, usePathScope } from "./scope";
|
|
8
9
|
import { UniversalWrapper } from "./universal-wrapper";
|
|
9
10
|
import { KeyframePlayer } from "./keyframe-player";
|
|
10
11
|
import { StaggerContext, computeStaggerDelayMs } from "./stagger-context";
|
|
12
|
+
import { useBindAnimate } from "./bind-animate";
|
|
13
|
+
import { checkNodeProps } from "./prop-allowlist";
|
|
14
|
+
import { emitDiagnostic } from "./diagnostics";
|
|
11
15
|
export function Tree({ node, store }) {
|
|
12
16
|
if (node.kind === "repeat") {
|
|
13
17
|
return _jsx(Repeat, { node: node, store: store });
|
|
@@ -28,11 +32,20 @@ function Node({ node, store }) {
|
|
|
28
32
|
// micro-optimisation to keep object identity stable across renders
|
|
29
33
|
// when the inputs haven't changed.
|
|
30
34
|
[node, store, scope, ...readBindingValues(node, store, scope)]);
|
|
35
|
+
// LSML 1.1 §6.3 — bindAnimate : continuous interpolation toward live
|
|
36
|
+
// leaf values, no remount (issue #33). Scalar channels ride motion
|
|
37
|
+
// values on a wrapping motion.div ; colour channels (§6.5) flow back
|
|
38
|
+
// into the primitive's resolved prop as interpolated, re-validated
|
|
39
|
+
// colour strings.
|
|
40
|
+
const bindAnimate = useBindAnimate(node, store, scope);
|
|
41
|
+
// ADR 001 §3.4 (issue #34) — audit static props + binding keys
|
|
42
|
+
// against the primitive's allowlist ; unknown props diagnose instead
|
|
43
|
+
// of dropping silently. Key sets are static per node (a live delta
|
|
44
|
+
// can only change values), so the check is once-per-node.
|
|
45
|
+
checkNodeProps(node);
|
|
31
46
|
const Primitive = PRIMITIVES[node.kind];
|
|
32
47
|
if (!Primitive) {
|
|
33
|
-
|
|
34
|
-
console.warn(`[lumencast] unknown render kind : ${node.kind}`);
|
|
35
|
-
}
|
|
48
|
+
emitDiagnostic(node.id, "kind", "unknown render kind ; node not rendered");
|
|
36
49
|
return null;
|
|
37
50
|
}
|
|
38
51
|
// LSDP/1.1 §3.2.2 — a per-leaf transition on the most recent delta
|
|
@@ -68,13 +81,24 @@ function Node({ node, store }) {
|
|
|
68
81
|
rotation: typeof resolved.rotation === "number" ? resolved.rotation : undefined,
|
|
69
82
|
sizing: extractSizing(resolved.sizing),
|
|
70
83
|
};
|
|
71
|
-
|
|
84
|
+
// Merge live-interpolated colour values (§6.5) over the resolved
|
|
85
|
+
// props — the primitive re-validates them through `parseCssColor`.
|
|
86
|
+
const resolvedWithColors = Object.keys(bindAnimate.colorProps).length > 0
|
|
87
|
+
? { ...resolved, ...bindAnimate.colorProps }
|
|
88
|
+
: resolved;
|
|
89
|
+
let body = (_jsx(UniversalWrapper, { ...universal, children: _jsx(Primitive, { resolved: resolvedWithColors, nodeId: node.id, transitionFor: transitionFor, animateInitial: node.animate_initial, children: children }) }));
|
|
90
|
+
// Scalar bindAnimate channels apply on a wrapping motion.div (same
|
|
91
|
+
// composition model as UniversalWrapper). Motion values mutate the
|
|
92
|
+
// style directly — zero React re-render per frame on the hot path.
|
|
93
|
+
if (bindAnimate.motionStyle) {
|
|
94
|
+
body = (_jsx(motion.div, { "data-lumencast-bind-animate": node.id ?? "", style: bindAnimate.motionStyle, children: body }));
|
|
95
|
+
}
|
|
72
96
|
// LSML 1.1 §6.6 — when a primitive declares keyframes, wrap the
|
|
73
97
|
// rendered subtree in a player that drives framer-motion through the
|
|
74
98
|
// step path. The player handles replay-on-key-change and reads any
|
|
75
99
|
// ambient stagger delay from StaggerContext (§6.7).
|
|
76
100
|
if (node.keyframes) {
|
|
77
|
-
return (_jsx(KeyframePlayer, { keyframes: node.keyframes, store: store, children: body }));
|
|
101
|
+
return (_jsx(KeyframePlayer, { keyframes: node.keyframes, store: store, nodeId: node.id, children: body }));
|
|
78
102
|
}
|
|
79
103
|
return body;
|
|
80
104
|
}
|
|
@@ -92,6 +116,7 @@ function extractSizing(value) {
|
|
|
92
116
|
function Repeat({ node, store }) {
|
|
93
117
|
useSignals();
|
|
94
118
|
const scope = usePathScope();
|
|
119
|
+
checkNodeProps(node);
|
|
95
120
|
const itemsBinding = node.bindings?.items;
|
|
96
121
|
const items = itemsBinding === undefined
|
|
97
122
|
? []
|
package/dist/render/tree.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/render/tree.tsx"],"names":[],"mappings":";AAAA,6DAA6D;AAC7D,0CAA0C;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AAGhD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEtE,OAAO,EAAE,gBAAgB,EAAmB,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/render/tree.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs as c, jsx as s } from "react/jsx-runtime";
|
|
2
2
|
import { useSignals as g } from "@preact/signals-react/runtime";
|
|
3
|
-
import { u as d } from "./index-
|
|
3
|
+
import { u as d } from "./index-CyOlpZAL.js";
|
|
4
4
|
const f = {
|
|
5
5
|
position: "fixed",
|
|
6
6
|
bottom: 12,
|
|
@@ -238,4 +238,4 @@ export {
|
|
|
238
238
|
k as C,
|
|
239
239
|
w as S
|
|
240
240
|
};
|
|
241
|
-
//# sourceMappingURL=status-pill-
|
|
241
|
+
//# sourceMappingURL=status-pill-DIpXc5du.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-pill-DNHbHdag.js","sources":["../src/overlay/control.tsx","../src/overlay/status-pill.tsx"],"sourcesContent":["import { useSignals } from \"@preact/signals-react/runtime\";\nimport type { OperatorInput } from \"../render/bundle\";\nimport { useLumencastRuntime } from \"./runtime-context\";\n\nconst PANEL_STYLE: React.CSSProperties = {\n position: \"fixed\",\n bottom: 12,\n left: 12,\n zIndex: 100_000,\n width: 320,\n maxHeight: \"70vh\",\n overflowY: \"auto\",\n padding: 12,\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, sans-serif\",\n fontSize: 12,\n color: \"#e5e7eb\",\n background: \"rgba(17, 24, 39, 0.92)\",\n border: \"1px solid rgba(75, 85, 99, 0.6)\",\n borderRadius: 10,\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.45)\",\n};\n\nconst ROW_STYLE: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n padding: \"6px 0\",\n borderBottom: \"1px solid rgba(75, 85, 99, 0.35)\",\n};\n\nconst LABEL_STYLE: React.CSSProperties = {\n color: \"#9ca3af\",\n fontSize: 10.5,\n letterSpacing: \"0.02em\",\n textTransform: \"uppercase\",\n};\n\nconst INPUT_STYLE: React.CSSProperties = {\n background: \"rgba(31, 41, 55, 0.8)\",\n border: \"1px solid rgba(75, 85, 99, 0.6)\",\n borderRadius: 6,\n color: \"#f9fafb\",\n padding: \"4px 6px\",\n fontSize: 12,\n width: \"100%\",\n};\n\nexport function ControlPanel() {\n const { bundle, store, sendInput } = useLumencastRuntime();\n useSignals();\n\n const inputs = bundle.operator_inputs ?? [];\n if (inputs.length === 0) return null;\n\n // Group entries by `group` field for readability.\n const groups = new Map<string, OperatorInput[]>();\n for (const entry of inputs) {\n const g = entry.group ?? \"General\";\n const list = groups.get(g) ?? [];\n list.push(entry);\n groups.set(g, list);\n }\n\n return (\n <div style={PANEL_STYLE} data-testid=\"lumencast-control-panel\">\n <div\n style={{\n fontWeight: 600,\n fontSize: 11,\n letterSpacing: \"0.06em\",\n color: \"#9ca3af\",\n textTransform: \"uppercase\",\n marginBottom: 6,\n }}\n >\n Operator inputs\n </div>\n {[...groups.entries()].map(([group, entries]) => (\n <div key={group} style={{ marginBottom: 8 }}>\n <div\n style={{\n color: \"#6b7280\",\n fontSize: 10,\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n padding: \"4px 0\",\n }}\n >\n {group}\n </div>\n {entries.map((entry) => (\n <InputRow\n key={entry.path}\n entry={entry}\n currentValue={store.signal(entry.path).value}\n onCommit={(v) =>\n // Operator-control values come from form widgets typed per\n // OperatorInput.type; coerce to LeafValue at the boundary.\n sendInput([\n {\n path: entry.path,\n value: v as Parameters<typeof sendInput>[0][number][\"value\"],\n },\n ])\n }\n />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\nfunction InputRow({\n entry,\n currentValue,\n onCommit,\n}: {\n entry: OperatorInput;\n currentValue: unknown;\n onCommit: (value: unknown) => void;\n}) {\n return (\n <div style={ROW_STYLE}>\n <span style={LABEL_STYLE}>{entry.label}</span>\n <Editor entry={entry} currentValue={currentValue} onCommit={onCommit} />\n </div>\n );\n}\n\nfunction Editor({\n entry,\n currentValue,\n onCommit,\n}: {\n entry: OperatorInput;\n currentValue: unknown;\n onCommit: (value: unknown) => void;\n}) {\n switch (entry.type) {\n case \"boolean\": {\n const checked = currentValue === true;\n return (\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <input type=\"checkbox\" checked={checked} onChange={(e) => onCommit(e.target.checked)} />\n <span style={{ fontSize: 11, color: \"#d1d5db\" }}>{checked ? \"on\" : \"off\"}</span>\n </label>\n );\n }\n case \"number\": {\n const min = entry.min as number | undefined;\n const max = entry.max as number | undefined;\n const step = entry.step as number | undefined;\n return (\n <input\n type=\"number\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"number\" ? currentValue : \"\"}\n min={min}\n max={max}\n step={step}\n onChange={(e) => {\n const n = Number(e.target.value);\n if (Number.isFinite(n)) onCommit(n);\n }}\n />\n );\n }\n case \"text\": {\n const max = entry.max_length as number | undefined;\n return (\n <input\n type=\"text\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"\"}\n maxLength={max}\n onChange={(e) => onCommit(e.target.value)}\n />\n );\n }\n case \"colour\": {\n return (\n <input\n type=\"color\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"#000000\"}\n onChange={(e) => onCommit(e.target.value)}\n />\n );\n }\n case \"duration\": {\n return (\n <input\n type=\"number\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"number\" ? currentValue : \"\"}\n min={0}\n step={100}\n onChange={(e) => {\n const n = Number(e.target.value);\n if (Number.isFinite(n) && n >= 0) onCommit(n);\n }}\n />\n );\n }\n case \"select\":\n case \"enum\": {\n const options =\n (entry.enum_values as string[] | undefined) ??\n (entry.options as string[] | undefined) ??\n [];\n return (\n <select\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"\"}\n onChange={(e) => onCommit(e.target.value)}\n >\n {options.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n );\n }\n case \"path-ref\":\n default:\n // FIXME (v2) — `path-ref` UX is deferred ; for now show a plain\n // text entry so the value is still editable.\n return (\n <input\n type=\"text\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"\"}\n onChange={(e) => onCommit(e.target.value)}\n />\n );\n }\n}\n","import { useLumencastRuntime } from \"./runtime-context\";\n\nconst COLOURS: Record<string, string> = {\n live: \"rgba(34, 197, 94, 0.85)\",\n connecting: \"rgba(234, 179, 8, 0.85)\",\n disconnected: \"rgba(239, 68, 68, 0.85)\",\n};\n\nconst LABELS: Record<string, string> = {\n live: \"live\",\n connecting: \"reconnecting\",\n disconnected: \"disconnected\",\n};\n\nexport function StatusPill() {\n const { status } = useLumencastRuntime();\n return (\n <div\n data-testid=\"lumencast-status-pill\"\n style={{\n position: \"fixed\",\n top: 12,\n right: 12,\n padding: \"4px 10px\",\n fontSize: 11,\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, sans-serif\",\n color: \"white\",\n background: COLOURS[status] ?? \"#444\",\n borderRadius: 999,\n userSelect: \"none\",\n pointerEvents: \"none\",\n }}\n >\n {LABELS[status] ?? status}\n </div>\n );\n}\n"],"names":["PANEL_STYLE","ROW_STYLE","LABEL_STYLE","INPUT_STYLE","ControlPanel","bundle","store","sendInput","useLumencastRuntime","useSignals","inputs","groups","entry","g","list","jsxs","jsx","group","entries","InputRow","v","currentValue","onCommit","Editor","checked","min","max","step","e","n","options","opt","COLOURS","LABELS","StatusPill","status"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"status-pill-DIpXc5du.js","sources":["../src/overlay/control.tsx","../src/overlay/status-pill.tsx"],"sourcesContent":["import { useSignals } from \"@preact/signals-react/runtime\";\nimport type { OperatorInput } from \"../render/bundle\";\nimport { useLumencastRuntime } from \"./runtime-context\";\n\nconst PANEL_STYLE: React.CSSProperties = {\n position: \"fixed\",\n bottom: 12,\n left: 12,\n zIndex: 100_000,\n width: 320,\n maxHeight: \"70vh\",\n overflowY: \"auto\",\n padding: 12,\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, sans-serif\",\n fontSize: 12,\n color: \"#e5e7eb\",\n background: \"rgba(17, 24, 39, 0.92)\",\n border: \"1px solid rgba(75, 85, 99, 0.6)\",\n borderRadius: 10,\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.45)\",\n};\n\nconst ROW_STYLE: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n padding: \"6px 0\",\n borderBottom: \"1px solid rgba(75, 85, 99, 0.35)\",\n};\n\nconst LABEL_STYLE: React.CSSProperties = {\n color: \"#9ca3af\",\n fontSize: 10.5,\n letterSpacing: \"0.02em\",\n textTransform: \"uppercase\",\n};\n\nconst INPUT_STYLE: React.CSSProperties = {\n background: \"rgba(31, 41, 55, 0.8)\",\n border: \"1px solid rgba(75, 85, 99, 0.6)\",\n borderRadius: 6,\n color: \"#f9fafb\",\n padding: \"4px 6px\",\n fontSize: 12,\n width: \"100%\",\n};\n\nexport function ControlPanel() {\n const { bundle, store, sendInput } = useLumencastRuntime();\n useSignals();\n\n const inputs = bundle.operator_inputs ?? [];\n if (inputs.length === 0) return null;\n\n // Group entries by `group` field for readability.\n const groups = new Map<string, OperatorInput[]>();\n for (const entry of inputs) {\n const g = entry.group ?? \"General\";\n const list = groups.get(g) ?? [];\n list.push(entry);\n groups.set(g, list);\n }\n\n return (\n <div style={PANEL_STYLE} data-testid=\"lumencast-control-panel\">\n <div\n style={{\n fontWeight: 600,\n fontSize: 11,\n letterSpacing: \"0.06em\",\n color: \"#9ca3af\",\n textTransform: \"uppercase\",\n marginBottom: 6,\n }}\n >\n Operator inputs\n </div>\n {[...groups.entries()].map(([group, entries]) => (\n <div key={group} style={{ marginBottom: 8 }}>\n <div\n style={{\n color: \"#6b7280\",\n fontSize: 10,\n letterSpacing: \"0.04em\",\n textTransform: \"uppercase\",\n padding: \"4px 0\",\n }}\n >\n {group}\n </div>\n {entries.map((entry) => (\n <InputRow\n key={entry.path}\n entry={entry}\n currentValue={store.signal(entry.path).value}\n onCommit={(v) =>\n // Operator-control values come from form widgets typed per\n // OperatorInput.type; coerce to LeafValue at the boundary.\n sendInput([\n {\n path: entry.path,\n value: v as Parameters<typeof sendInput>[0][number][\"value\"],\n },\n ])\n }\n />\n ))}\n </div>\n ))}\n </div>\n );\n}\n\nfunction InputRow({\n entry,\n currentValue,\n onCommit,\n}: {\n entry: OperatorInput;\n currentValue: unknown;\n onCommit: (value: unknown) => void;\n}) {\n return (\n <div style={ROW_STYLE}>\n <span style={LABEL_STYLE}>{entry.label}</span>\n <Editor entry={entry} currentValue={currentValue} onCommit={onCommit} />\n </div>\n );\n}\n\nfunction Editor({\n entry,\n currentValue,\n onCommit,\n}: {\n entry: OperatorInput;\n currentValue: unknown;\n onCommit: (value: unknown) => void;\n}) {\n switch (entry.type) {\n case \"boolean\": {\n const checked = currentValue === true;\n return (\n <label style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <input type=\"checkbox\" checked={checked} onChange={(e) => onCommit(e.target.checked)} />\n <span style={{ fontSize: 11, color: \"#d1d5db\" }}>{checked ? \"on\" : \"off\"}</span>\n </label>\n );\n }\n case \"number\": {\n const min = entry.min as number | undefined;\n const max = entry.max as number | undefined;\n const step = entry.step as number | undefined;\n return (\n <input\n type=\"number\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"number\" ? currentValue : \"\"}\n min={min}\n max={max}\n step={step}\n onChange={(e) => {\n const n = Number(e.target.value);\n if (Number.isFinite(n)) onCommit(n);\n }}\n />\n );\n }\n case \"text\": {\n const max = entry.max_length as number | undefined;\n return (\n <input\n type=\"text\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"\"}\n maxLength={max}\n onChange={(e) => onCommit(e.target.value)}\n />\n );\n }\n case \"colour\": {\n return (\n <input\n type=\"color\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"#000000\"}\n onChange={(e) => onCommit(e.target.value)}\n />\n );\n }\n case \"duration\": {\n return (\n <input\n type=\"number\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"number\" ? currentValue : \"\"}\n min={0}\n step={100}\n onChange={(e) => {\n const n = Number(e.target.value);\n if (Number.isFinite(n) && n >= 0) onCommit(n);\n }}\n />\n );\n }\n case \"select\":\n case \"enum\": {\n const options =\n (entry.enum_values as string[] | undefined) ??\n (entry.options as string[] | undefined) ??\n [];\n return (\n <select\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"\"}\n onChange={(e) => onCommit(e.target.value)}\n >\n {options.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n );\n }\n case \"path-ref\":\n default:\n // FIXME (v2) — `path-ref` UX is deferred ; for now show a plain\n // text entry so the value is still editable.\n return (\n <input\n type=\"text\"\n style={INPUT_STYLE}\n value={typeof currentValue === \"string\" ? currentValue : \"\"}\n onChange={(e) => onCommit(e.target.value)}\n />\n );\n }\n}\n","import { useLumencastRuntime } from \"./runtime-context\";\n\nconst COLOURS: Record<string, string> = {\n live: \"rgba(34, 197, 94, 0.85)\",\n connecting: \"rgba(234, 179, 8, 0.85)\",\n disconnected: \"rgba(239, 68, 68, 0.85)\",\n};\n\nconst LABELS: Record<string, string> = {\n live: \"live\",\n connecting: \"reconnecting\",\n disconnected: \"disconnected\",\n};\n\nexport function StatusPill() {\n const { status } = useLumencastRuntime();\n return (\n <div\n data-testid=\"lumencast-status-pill\"\n style={{\n position: \"fixed\",\n top: 12,\n right: 12,\n padding: \"4px 10px\",\n fontSize: 11,\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, sans-serif\",\n color: \"white\",\n background: COLOURS[status] ?? \"#444\",\n borderRadius: 999,\n userSelect: \"none\",\n pointerEvents: \"none\",\n }}\n >\n {LABELS[status] ?? status}\n </div>\n );\n}\n"],"names":["PANEL_STYLE","ROW_STYLE","LABEL_STYLE","INPUT_STYLE","ControlPanel","bundle","store","sendInput","useLumencastRuntime","useSignals","inputs","groups","entry","g","list","jsxs","jsx","group","entries","InputRow","v","currentValue","onCommit","Editor","checked","min","max","step","e","n","options","opt","COLOURS","LABELS","StatusPill","status"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsxs as i, jsx as t, Fragment as y } from "react/jsx-runtime";
|
|
2
|
-
import { T as b } from "./tree-
|
|
3
|
-
import { S as h, C as x } from "./status-pill-
|
|
2
|
+
import { T as b } from "./tree-D5wYHpPu.js";
|
|
3
|
+
import { S as h, C as x } from "./status-pill-DIpXc5du.js";
|
|
4
4
|
import { useSignals as S } from "@preact/signals-react/runtime";
|
|
5
5
|
import { useState as f } from "react";
|
|
6
|
-
import { u } from "./index-
|
|
6
|
+
import { u } from "./index-CyOlpZAL.js";
|
|
7
7
|
const k = {
|
|
8
8
|
position: "fixed",
|
|
9
9
|
bottom: 12,
|
|
@@ -207,4 +207,4 @@ function B() {
|
|
|
207
207
|
export {
|
|
208
208
|
B as TestMode
|
|
209
209
|
};
|
|
210
|
-
//# sourceMappingURL=test-
|
|
210
|
+
//# sourceMappingURL=test-ByRec1kd.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-Dp0QrKYM.js","sources":["../src/overlay/test.tsx","../src/modes/test.tsx"],"sourcesContent":["import { useSignals } from \"@preact/signals-react/runtime\";\nimport { useState } from \"react\";\nimport { useLumencastRuntime } from \"./runtime-context\";\n\nconst PANEL_STYLE: React.CSSProperties = {\n position: \"fixed\",\n bottom: 12,\n right: 12,\n zIndex: 100_001,\n width: 360,\n maxHeight: \"70vh\",\n overflowY: \"auto\",\n padding: 12,\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, sans-serif\",\n fontSize: 12,\n color: \"#e5e7eb\",\n background: \"rgba(8, 47, 73, 0.92)\",\n border: \"1px solid rgba(56, 189, 248, 0.4)\",\n borderRadius: 10,\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.45)\",\n};\n\nconst SECTION_TITLE: React.CSSProperties = {\n fontWeight: 600,\n fontSize: 11,\n letterSpacing: \"0.06em\",\n color: \"#7dd3fc\",\n textTransform: \"uppercase\",\n marginBottom: 6,\n};\n\nconst BUTTON_STYLE: React.CSSProperties = {\n background: \"rgba(14, 165, 233, 0.4)\",\n border: \"1px solid rgba(125, 211, 252, 0.5)\",\n borderRadius: 6,\n color: \"#f0f9ff\",\n padding: \"3px 8px\",\n fontSize: 11,\n cursor: \"pointer\",\n};\n\nconst ADAPTER_ROW: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n padding: \"6px 0\",\n borderBottom: \"1px solid rgba(56, 189, 248, 0.2)\",\n};\n\n/** Test-mode overlay : adapter mocker + state inspector + time\n * controls. Drives the server's __test.* family via the same `sendInput`\n * channel. */\nexport function TestPanel() {\n const { bundle, store, sendInput } = useLumencastRuntime();\n useSignals();\n const [filter, setFilter] = useState(\"\");\n\n const adapters = bundle.external_adapters ?? [];\n const stateRecord = store.toRecord();\n const filteredEntries = Object.entries(stateRecord).filter(\n ([k]) => filter === \"\" || k.includes(filter),\n );\n\n return (\n <div style={PANEL_STYLE} data-testid=\"lumencast-test-panel\">\n {/* Time controls */}\n <div style={SECTION_TITLE}>Time</div>\n <div style={{ display: \"flex\", gap: 6, marginBottom: 8 }}>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.tick\", value: 100 }])}\n >\n tick +100ms\n </button>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.tick\", value: 1_000 }])}\n >\n tick +1s\n </button>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.reset\", value: true }])}\n >\n reset\n </button>\n </div>\n\n {/* Adapter mocker */}\n <div style={SECTION_TITLE}>External adapters</div>\n {adapters.length === 0 && (\n <div style={{ color: \"#94a3b8\", fontStyle: \"italic\", fontSize: 11 }}>\n No external adapters declared in this scene.\n </div>\n )}\n {adapters.map((adapter) => (\n <AdapterRow\n key={adapter.key}\n adapter={adapter}\n onMock={(payload) =>\n // LSDP/1 patch values must be leaf — JSON-encode the structured payload.\n sendInput([\n {\n path: \"__test.mock_adapter\",\n value: JSON.stringify({ key: adapter.key, payload }),\n },\n ])\n }\n />\n ))}\n\n {/* State inspector */}\n <div style={{ ...SECTION_TITLE, marginTop: 12 }}>State</div>\n <input\n type=\"text\"\n placeholder=\"filter paths…\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n style={{\n background: \"rgba(8, 47, 73, 0.6)\",\n border: \"1px solid rgba(125, 211, 252, 0.4)\",\n borderRadius: 6,\n color: \"#e0f2fe\",\n padding: \"4px 6px\",\n fontSize: 11,\n width: \"100%\",\n marginBottom: 6,\n }}\n />\n <div style={{ fontFamily: \"monospace\", fontSize: 10.5 }}>\n {filteredEntries.map(([path, value]) => (\n <div\n key={path}\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr auto\",\n gap: 8,\n padding: \"2px 0\",\n borderBottom: \"1px dashed rgba(125, 211, 252, 0.15)\",\n }}\n >\n <span style={{ color: \"#bae6fd\" }}>{path}</span>\n <span style={{ color: \"#fef3c7\" }}>{formatValue(value)}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction AdapterRow({\n adapter,\n onMock,\n}: {\n adapter: { key: string; label: string; kind: string };\n onMock: (payload: unknown) => void;\n}) {\n const [draft, setDraft] = useState(\"{}\");\n return (\n <div style={ADAPTER_ROW}>\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span style={{ color: \"#e0f2fe\" }}>{adapter.label}</span>\n <span style={{ color: \"#94a3b8\", fontSize: 10 }}>{adapter.kind}</span>\n </div>\n <textarea\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n rows={2}\n style={{\n fontFamily: \"monospace\",\n fontSize: 10.5,\n background: \"rgba(8, 47, 73, 0.6)\",\n color: \"#e0f2fe\",\n border: \"1px solid rgba(125, 211, 252, 0.3)\",\n borderRadius: 4,\n padding: 4,\n resize: \"vertical\",\n }}\n />\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => {\n try {\n const parsed = JSON.parse(draft);\n onMock(parsed);\n } catch {\n onMock(draft);\n }\n }}\n >\n fire\n </button>\n </div>\n );\n}\n\nfunction formatValue(value: unknown): string {\n if (value === undefined) return \"—\";\n if (value === null) return \"null\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n","import { Tree } from \"../render/tree\";\nimport { ControlPanel } from \"../overlay/control\";\nimport { TestPanel } from \"../overlay/test\";\nimport { StatusPill } from \"../overlay/status-pill\";\nimport { useLumencastRuntime } from \"../overlay/runtime-context\";\n\n/** Test mode : scene + operator overlay + test extensions (adapter\n * mocker, state inspector, time controls). */\nexport function TestMode() {\n const { store, bundle } = useLumencastRuntime();\n return (\n <>\n <Tree node={bundle.root} store={store} />\n <StatusPill />\n <ControlPanel />\n <TestPanel />\n </>\n );\n}\n"],"names":["PANEL_STYLE","SECTION_TITLE","BUTTON_STYLE","ADAPTER_ROW","TestPanel","bundle","store","sendInput","useLumencastRuntime","useSignals","filter","setFilter","useState","adapters","stateRecord","filteredEntries","k","jsxs","jsx","adapter","AdapterRow","payload","e","path","value","formatValue","onMock","draft","setDraft","parsed","TestMode","Fragment","Tree","StatusPill","ControlPanel"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"test-ByRec1kd.js","sources":["../src/overlay/test.tsx","../src/modes/test.tsx"],"sourcesContent":["import { useSignals } from \"@preact/signals-react/runtime\";\nimport { useState } from \"react\";\nimport { useLumencastRuntime } from \"./runtime-context\";\n\nconst PANEL_STYLE: React.CSSProperties = {\n position: \"fixed\",\n bottom: 12,\n right: 12,\n zIndex: 100_001,\n width: 360,\n maxHeight: \"70vh\",\n overflowY: \"auto\",\n padding: 12,\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, sans-serif\",\n fontSize: 12,\n color: \"#e5e7eb\",\n background: \"rgba(8, 47, 73, 0.92)\",\n border: \"1px solid rgba(56, 189, 248, 0.4)\",\n borderRadius: 10,\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.45)\",\n};\n\nconst SECTION_TITLE: React.CSSProperties = {\n fontWeight: 600,\n fontSize: 11,\n letterSpacing: \"0.06em\",\n color: \"#7dd3fc\",\n textTransform: \"uppercase\",\n marginBottom: 6,\n};\n\nconst BUTTON_STYLE: React.CSSProperties = {\n background: \"rgba(14, 165, 233, 0.4)\",\n border: \"1px solid rgba(125, 211, 252, 0.5)\",\n borderRadius: 6,\n color: \"#f0f9ff\",\n padding: \"3px 8px\",\n fontSize: 11,\n cursor: \"pointer\",\n};\n\nconst ADAPTER_ROW: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n padding: \"6px 0\",\n borderBottom: \"1px solid rgba(56, 189, 248, 0.2)\",\n};\n\n/** Test-mode overlay : adapter mocker + state inspector + time\n * controls. Drives the server's __test.* family via the same `sendInput`\n * channel. */\nexport function TestPanel() {\n const { bundle, store, sendInput } = useLumencastRuntime();\n useSignals();\n const [filter, setFilter] = useState(\"\");\n\n const adapters = bundle.external_adapters ?? [];\n const stateRecord = store.toRecord();\n const filteredEntries = Object.entries(stateRecord).filter(\n ([k]) => filter === \"\" || k.includes(filter),\n );\n\n return (\n <div style={PANEL_STYLE} data-testid=\"lumencast-test-panel\">\n {/* Time controls */}\n <div style={SECTION_TITLE}>Time</div>\n <div style={{ display: \"flex\", gap: 6, marginBottom: 8 }}>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.tick\", value: 100 }])}\n >\n tick +100ms\n </button>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.tick\", value: 1_000 }])}\n >\n tick +1s\n </button>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.reset\", value: true }])}\n >\n reset\n </button>\n </div>\n\n {/* Adapter mocker */}\n <div style={SECTION_TITLE}>External adapters</div>\n {adapters.length === 0 && (\n <div style={{ color: \"#94a3b8\", fontStyle: \"italic\", fontSize: 11 }}>\n No external adapters declared in this scene.\n </div>\n )}\n {adapters.map((adapter) => (\n <AdapterRow\n key={adapter.key}\n adapter={adapter}\n onMock={(payload) =>\n // LSDP/1 patch values must be leaf — JSON-encode the structured payload.\n sendInput([\n {\n path: \"__test.mock_adapter\",\n value: JSON.stringify({ key: adapter.key, payload }),\n },\n ])\n }\n />\n ))}\n\n {/* State inspector */}\n <div style={{ ...SECTION_TITLE, marginTop: 12 }}>State</div>\n <input\n type=\"text\"\n placeholder=\"filter paths…\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n style={{\n background: \"rgba(8, 47, 73, 0.6)\",\n border: \"1px solid rgba(125, 211, 252, 0.4)\",\n borderRadius: 6,\n color: \"#e0f2fe\",\n padding: \"4px 6px\",\n fontSize: 11,\n width: \"100%\",\n marginBottom: 6,\n }}\n />\n <div style={{ fontFamily: \"monospace\", fontSize: 10.5 }}>\n {filteredEntries.map(([path, value]) => (\n <div\n key={path}\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr auto\",\n gap: 8,\n padding: \"2px 0\",\n borderBottom: \"1px dashed rgba(125, 211, 252, 0.15)\",\n }}\n >\n <span style={{ color: \"#bae6fd\" }}>{path}</span>\n <span style={{ color: \"#fef3c7\" }}>{formatValue(value)}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction AdapterRow({\n adapter,\n onMock,\n}: {\n adapter: { key: string; label: string; kind: string };\n onMock: (payload: unknown) => void;\n}) {\n const [draft, setDraft] = useState(\"{}\");\n return (\n <div style={ADAPTER_ROW}>\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span style={{ color: \"#e0f2fe\" }}>{adapter.label}</span>\n <span style={{ color: \"#94a3b8\", fontSize: 10 }}>{adapter.kind}</span>\n </div>\n <textarea\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n rows={2}\n style={{\n fontFamily: \"monospace\",\n fontSize: 10.5,\n background: \"rgba(8, 47, 73, 0.6)\",\n color: \"#e0f2fe\",\n border: \"1px solid rgba(125, 211, 252, 0.3)\",\n borderRadius: 4,\n padding: 4,\n resize: \"vertical\",\n }}\n />\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => {\n try {\n const parsed = JSON.parse(draft);\n onMock(parsed);\n } catch {\n onMock(draft);\n }\n }}\n >\n fire\n </button>\n </div>\n );\n}\n\nfunction formatValue(value: unknown): string {\n if (value === undefined) return \"—\";\n if (value === null) return \"null\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n","import { Tree } from \"../render/tree\";\nimport { ControlPanel } from \"../overlay/control\";\nimport { TestPanel } from \"../overlay/test\";\nimport { StatusPill } from \"../overlay/status-pill\";\nimport { useLumencastRuntime } from \"../overlay/runtime-context\";\n\n/** Test mode : scene + operator overlay + test extensions (adapter\n * mocker, state inspector, time controls). */\nexport function TestMode() {\n const { store, bundle } = useLumencastRuntime();\n return (\n <>\n <Tree node={bundle.root} store={store} />\n <StatusPill />\n <ControlPanel />\n <TestPanel />\n </>\n );\n}\n"],"names":["PANEL_STYLE","SECTION_TITLE","BUTTON_STYLE","ADAPTER_ROW","TestPanel","bundle","store","sendInput","useLumencastRuntime","useSignals","filter","setFilter","useState","adapters","stateRecord","filteredEntries","k","jsxs","jsx","adapter","AdapterRow","payload","e","path","value","formatValue","onMock","draft","setDraft","parsed","TestMode","Fragment","Tree","StatusPill","ControlPanel"],"mappings":"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"}
|