@lumencast/runtime 0.8.0 → 0.9.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/dist/.tsbuildinfo +1 -1
- package/dist/animate/keyframes.js +8 -1
- package/dist/animate/keyframes.js.map +1 -1
- package/dist/app.d.ts +4 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +2 -1
- package/dist/app.js.map +1 -1
- package/dist/{broadcast-Gcd-dmC7.js → broadcast-ryjLRD5q.js} +3 -3
- package/dist/{broadcast-Gcd-dmC7.js.map → broadcast-ryjLRD5q.js.map} +1 -1
- package/dist/{control-C5TfClga.js → control-AgxbXOVS.js} +4 -4
- package/dist/{control-C5TfClga.js.map → control-AgxbXOVS.js.map} +1 -1
- package/dist/{index-N-VqrIxN.js → index-DrXsLYhe.js} +144 -126
- package/dist/index-DrXsLYhe.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.html +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lumencast.js +4 -4
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +5 -0
- package/dist/mount.js.map +1 -1
- package/dist/overlay/runtime-context.d.ts +11 -0
- package/dist/overlay/runtime-context.d.ts.map +1 -1
- package/dist/overlay/runtime-context.js +8 -0
- package/dist/overlay/runtime-context.js.map +1 -1
- package/dist/render/bundle.d.ts +1 -1
- package/dist/render/bundle.d.ts.map +1 -1
- package/dist/render/bundle.js +4 -0
- package/dist/render/bundle.js.map +1 -1
- package/dist/render/keyframe-player.d.ts.map +1 -1
- package/dist/render/keyframe-player.js +15 -1
- package/dist/render/keyframe-player.js.map +1 -1
- package/dist/render/primitives/capture.d.ts +40 -0
- package/dist/render/primitives/capture.d.ts.map +1 -0
- package/dist/render/primitives/capture.js +171 -0
- package/dist/render/primitives/capture.js.map +1 -0
- package/dist/render/primitives/index.d.ts.map +1 -1
- package/dist/render/primitives/index.js +3 -0
- package/dist/render/primitives/index.js.map +1 -1
- package/dist/render/prop-allowlist.d.ts.map +1 -1
- package/dist/render/prop-allowlist.js +5 -0
- package/dist/render/prop-allowlist.js.map +1 -1
- package/dist/{status-pill-BaLQoIDl.js → status-pill-BxCdj-KZ.js} +2 -2
- package/dist/{status-pill-BaLQoIDl.js.map → status-pill-BxCdj-KZ.js.map} +1 -1
- package/dist/{test-CA30C2By.js → test-CaRHj_J6.js} +4 -4
- package/dist/{test-CA30C2By.js.map → test-CaRHj_J6.js.map} +1 -1
- package/dist/{tree-1coZ32nd.js → tree-BLIxJbD3.js} +502 -419
- package/dist/tree-BLIxJbD3.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/animate/keyframes.ts +8 -1
- package/src/app.tsx +5 -0
- package/src/index.ts +5 -0
- package/src/mount.ts +5 -0
- package/src/overlay/runtime-context.tsx +14 -0
- package/src/render/bundle.ts +9 -1
- package/src/render/keyframe-player.tsx +14 -1
- package/src/render/primitives/capture.tsx +210 -0
- package/src/render/primitives/index.ts +3 -0
- package/src/render/prop-allowlist.ts +5 -0
- package/src/types.ts +10 -0
- package/dist/index-N-VqrIxN.js.map +0 -1
- package/dist/tree-1coZ32nd.js.map +0 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { useOptionalLumencastRuntime } from "../../overlay/runtime-context";
|
|
4
|
+
/** `x-zab.capture` — context-aware capture primitive (Zab vendor primitive,
|
|
5
|
+
* RFC-0001 / ADR 004 §Amendment 1).
|
|
6
|
+
*
|
|
7
|
+
* The primitive reserves a box of the declared geometry so downstream layout
|
|
8
|
+
* (siblings, masks, stacks, grids) is unaffected — exactly as an `image` of
|
|
9
|
+
* the same geometry, in BOTH modes below. It picks a mode by **capability
|
|
10
|
+
* detection at mount** (feature detection, not an env flag) :
|
|
11
|
+
*
|
|
12
|
+
* - **ACQUIRE** (capable host, e.g. the Electron preview webview with
|
|
13
|
+
* auto-granted media permissions) : it acquires a live stream itself via
|
|
14
|
+
* `getUserMedia` (webcam/mic) or `getDisplayMedia` (screen/window) per
|
|
15
|
+
* `x-zab.sourceKind`, and renders it in a `<video>` for visual kinds
|
|
16
|
+
* (audio kinds stay visually empty). The physical device is resolved from
|
|
17
|
+
* the LOGICAL `x-zab.deviceRef` through a host-provided resolver
|
|
18
|
+
* (`resolveCaptureDevice`, §A1.3) — never a bundle-baked id. Any failure
|
|
19
|
+
* (no resolver, no device, permission denied, acquisition error) falls
|
|
20
|
+
* back to PLACEHOLDER WITHOUT throwing or blanking the surrounding tree.
|
|
21
|
+
*
|
|
22
|
+
* - **PLACEHOLDER** (non-capable host, e.g. CEF/Pulsar on-air) : the box is
|
|
23
|
+
* fully transparent, acquires nothing, reaches no device — the original
|
|
24
|
+
* §3.2 behaviour. The consuming app composites a native source behind it
|
|
25
|
+
* (ON-AIR PATH UNCHANGED).
|
|
26
|
+
*
|
|
27
|
+
* A stream-less box is a valid mode, not an error : NO diagnostic is emitted
|
|
28
|
+
* for PLACEHOLDER mode or for an ACQUIRE→PLACEHOLDER fallback.
|
|
29
|
+
*
|
|
30
|
+
* Geometry is the only layout input. `width`/`height` are the
|
|
31
|
+
* compiler-flattened `size:{w,h}` ; universal props (visible/opacity/
|
|
32
|
+
* position) are applied by the Tree's UniversalWrapper. An audio-only
|
|
33
|
+
* capture (`media.mic` / `media.app_audio`) may omit `size` → a zero-area
|
|
34
|
+
* box that never paints. */
|
|
35
|
+
export function Capture({ resolved }) {
|
|
36
|
+
const width = dimOr(resolved.width, "100%");
|
|
37
|
+
const height = dimOr(resolved.height, "100%");
|
|
38
|
+
const sourceKind = typeof resolved["x-zab.sourceKind"] === "string"
|
|
39
|
+
? resolved["x-zab.sourceKind"]
|
|
40
|
+
: "";
|
|
41
|
+
const deviceRef = typeof resolved["x-zab.deviceRef"] === "string"
|
|
42
|
+
? resolved["x-zab.deviceRef"]
|
|
43
|
+
: "";
|
|
44
|
+
// §A1.3 — the host-provided resolver, injected at mount through the runtime
|
|
45
|
+
// context (NOT the bundle, NOT the LSDP wire). Absent when the tree renders
|
|
46
|
+
// outside a host (direct embedding, tooling, tests) → the default-device
|
|
47
|
+
// path applies.
|
|
48
|
+
const runtime = useOptionalLumencastRuntime();
|
|
49
|
+
const resolveCaptureDevice = runtime?.resolveCaptureDevice;
|
|
50
|
+
const videoRef = useRef(null);
|
|
51
|
+
// `null` → PLACEHOLDER (non-capable, or ACQUIRE→PLACEHOLDER fallback).
|
|
52
|
+
// A `MediaStream` → ACQUIRE succeeded and a visual stream is mounted.
|
|
53
|
+
const [stream, setStream] = useState(null);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
// §A1.2(2) — capability detection at mount. A non-capable host (no
|
|
56
|
+
// `getUserMedia`, e.g. CEF/Pulsar on-air, or jsdom without a mock) stays
|
|
57
|
+
// in PLACEHOLDER : acquire nothing, no diagnostic.
|
|
58
|
+
if (!isCaptureCapable())
|
|
59
|
+
return;
|
|
60
|
+
let cancelled = false;
|
|
61
|
+
let acquired = null;
|
|
62
|
+
void (async () => {
|
|
63
|
+
try {
|
|
64
|
+
const media = await acquireStream(sourceKind, deviceRef, resolveCaptureDevice);
|
|
65
|
+
if (media === null)
|
|
66
|
+
return; // unknown/unsupported kind → PLACEHOLDER
|
|
67
|
+
if (cancelled) {
|
|
68
|
+
// Unmounted (or scene-changed) during acquisition — stop immediately
|
|
69
|
+
// so we never leave a camera light on (RC11).
|
|
70
|
+
stopStream(media);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
acquired = media;
|
|
74
|
+
setStream(media);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// §A1.2(2)(a) — any acquisition failure (permission denied, no device,
|
|
78
|
+
// getUserMedia rejected) falls back to PLACEHOLDER, no throw, no
|
|
79
|
+
// diagnostic.
|
|
80
|
+
}
|
|
81
|
+
})();
|
|
82
|
+
return () => {
|
|
83
|
+
cancelled = true;
|
|
84
|
+
// RC11 — stop the tracks at unmount / scene change. Clearing state is
|
|
85
|
+
// unnecessary (the component is gone) but stopping the device is not.
|
|
86
|
+
if (acquired !== null)
|
|
87
|
+
stopStream(acquired);
|
|
88
|
+
};
|
|
89
|
+
// Re-acquire when the logical source identity changes (a scene switch can
|
|
90
|
+
// reuse the node with a new sourceKind/deviceRef).
|
|
91
|
+
}, [sourceKind, deviceRef, resolveCaptureDevice]);
|
|
92
|
+
// Attach / detach the live stream to the <video> element imperatively —
|
|
93
|
+
// `srcObject` is not a serialisable attribute.
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
const el = videoRef.current;
|
|
96
|
+
if (el === null)
|
|
97
|
+
return;
|
|
98
|
+
el.srcObject = stream;
|
|
99
|
+
return () => {
|
|
100
|
+
if (el !== null)
|
|
101
|
+
el.srcObject = null;
|
|
102
|
+
};
|
|
103
|
+
}, [stream]);
|
|
104
|
+
// ACQUIRE with a visual stream → render the <video>. Audio-only kinds keep
|
|
105
|
+
// the transparent box (no visible element) even when acquired.
|
|
106
|
+
if (stream !== null && isVisualKind(sourceKind)) {
|
|
107
|
+
return (_jsx("video", { ref: videoRef, "data-lumencast-capture": true, autoPlay: true, muted: true, playsInline: true, style: { width, height, objectFit: "cover", pointerEvents: "none" } }));
|
|
108
|
+
}
|
|
109
|
+
// PLACEHOLDER (or audio-only ACQUIRE) — fully transparent, inert box.
|
|
110
|
+
return (_jsx("div", { "aria-hidden": true, "data-lumencast-capture": true, style: { width, height, opacity: 0, pointerEvents: "none" } }));
|
|
111
|
+
}
|
|
112
|
+
/** §A1.2(2) — capture-capable iff `navigator.mediaDevices.getUserMedia`
|
|
113
|
+
* exists and is callable in the current context. Feature detection only ;
|
|
114
|
+
* CEF/Pulsar on-air and jsdom (without a mock) report non-capable. */
|
|
115
|
+
function isCaptureCapable() {
|
|
116
|
+
return (typeof navigator !== "undefined" &&
|
|
117
|
+
typeof navigator.mediaDevices?.getUserMedia === "function");
|
|
118
|
+
}
|
|
119
|
+
/** Visual kinds render a `<video>` ; audio kinds stay visually empty. */
|
|
120
|
+
function isVisualKind(sourceKind) {
|
|
121
|
+
return (sourceKind === "media.webcam" ||
|
|
122
|
+
sourceKind === "media.screen" ||
|
|
123
|
+
sourceKind === "media.window");
|
|
124
|
+
}
|
|
125
|
+
/** Acquire a live stream for `sourceKind`, applying a host-resolved `deviceId`
|
|
126
|
+
* when available. Returns `null` for an unsupported/unknown kind (→
|
|
127
|
+
* PLACEHOLDER) ; throws are caught by the caller (→ PLACEHOLDER fallback). */
|
|
128
|
+
async function acquireStream(sourceKind, deviceRef, resolveCaptureDevice) {
|
|
129
|
+
const md = navigator.mediaDevices;
|
|
130
|
+
// §A1.3 — a resolver maps the LOGICAL deviceRef to a physical deviceId. No
|
|
131
|
+
// resolver / `null` result → default constraints (no deviceId), so "the cam
|
|
132
|
+
// traverses" on the first pass. The deviceId is a live constraint only.
|
|
133
|
+
const resolved = resolveCaptureDevice?.(deviceRef, sourceKind) ?? null;
|
|
134
|
+
const deviceId = resolved?.deviceId;
|
|
135
|
+
switch (sourceKind) {
|
|
136
|
+
case "media.webcam":
|
|
137
|
+
return md.getUserMedia({ video: deviceConstraint(deviceId) });
|
|
138
|
+
case "media.mic":
|
|
139
|
+
return md.getUserMedia({ audio: deviceConstraint(deviceId) });
|
|
140
|
+
case "media.app_audio":
|
|
141
|
+
return md.getUserMedia({ audio: deviceConstraint(deviceId) });
|
|
142
|
+
case "media.screen":
|
|
143
|
+
case "media.window":
|
|
144
|
+
// Display capture has no deviceId constraint (the picker selects the
|
|
145
|
+
// surface). The resolver is consulted but its id is not applicable here.
|
|
146
|
+
return md.getDisplayMedia({ video: true });
|
|
147
|
+
default:
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** A `getUserMedia` track constraint : a specific `deviceId` when resolved,
|
|
152
|
+
* else `true` (the host's default device). */
|
|
153
|
+
function deviceConstraint(deviceId) {
|
|
154
|
+
return typeof deviceId === "string" && deviceId.length > 0 ? { deviceId } : true;
|
|
155
|
+
}
|
|
156
|
+
/** Stop every track of a stream (RC11 — release the camera/mic, kill the
|
|
157
|
+
* device light). */
|
|
158
|
+
function stopStream(stream) {
|
|
159
|
+
for (const track of stream.getTracks())
|
|
160
|
+
track.stop();
|
|
161
|
+
}
|
|
162
|
+
/** A render dimension: a finite number → px, a non-empty string → verbatim,
|
|
163
|
+
* anything else → the fallback (matches the `image` primitive's helper). */
|
|
164
|
+
function dimOr(v, fallback) {
|
|
165
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
166
|
+
return `${v}px`;
|
|
167
|
+
if (typeof v === "string" && v.length > 0)
|
|
168
|
+
return v;
|
|
169
|
+
return fallback;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../../../src/render/primitives/capture.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/render/primitives/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/render/primitives/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAc5D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC;oEACgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;IACvD;;;;0EAIsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;IACjD;;;;;uEAKmE;IACnE,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,eAAO,MAAM,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC,CAWjF,CAAC"}
|
|
@@ -9,6 +9,7 @@ import { Image } from "./image";
|
|
|
9
9
|
import { Shape } from "./shape";
|
|
10
10
|
import { Media } from "./media";
|
|
11
11
|
import { Instance } from "./instance";
|
|
12
|
+
import { Capture } from "./capture";
|
|
12
13
|
export const PRIMITIVES = {
|
|
13
14
|
stack: Stack,
|
|
14
15
|
grid: Grid,
|
|
@@ -18,5 +19,7 @@ export const PRIMITIVES = {
|
|
|
18
19
|
shape: Shape,
|
|
19
20
|
media: Media,
|
|
20
21
|
instance: Instance,
|
|
22
|
+
// RFC-0001 / ADR 004 — Zab vendor capture placeholder (transparent, inert).
|
|
23
|
+
"x-zab.capture": Capture,
|
|
21
24
|
};
|
|
22
25
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/render/primitives/index.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,uEAAuE;AACvE,0DAA0D;AAK1D,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/render/primitives/index.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,uEAAuE;AACvE,0DAA0D;AAK1D,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,MAAM,CAAC,MAAM,UAAU,GAA+D;IACpF,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,KAAK;IACZ,KAAK,EAAE,KAAK;IACZ,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,QAAQ;IAClB,4EAA4E;IAC5E,eAAe,EAAE,OAAO;CACzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prop-allowlist.d.ts","sourceRoot":"","sources":["../../src/render/prop-allowlist.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkCvD,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"prop-allowlist.d.ts","sourceRoot":"","sources":["../../src/render/prop-allowlist.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkCvD,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAsDtF,CAAC;AAgBF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAgBrD"}
|
|
@@ -94,6 +94,11 @@ export const PRIMITIVE_PROP_ALLOWLIST = {
|
|
|
94
94
|
]),
|
|
95
95
|
media: allow(["src", "loop", "mute", "autoplay", "fit"]),
|
|
96
96
|
instance: allow(["scene_id", "scene_version", "size", "position"]),
|
|
97
|
+
// RFC-0001 / ADR 004 — vendor capture placeholder. `width`/`height` are the
|
|
98
|
+
// flattened geometry (universal) ; the `x-zab.*` props are carried as
|
|
99
|
+
// metadata (the renderer reserves the box, ignores deviceRef). Listed so
|
|
100
|
+
// they are NOT flagged as silent drops by the anti-drop audit.
|
|
101
|
+
"x-zab.capture": allow(["x-zab.sourceKind", "x-zab.deviceRef", "width", "height"]),
|
|
97
102
|
// `repeat` is dispatched specially by the tree ; its only consumed
|
|
98
103
|
// binding is `items`.
|
|
99
104
|
repeat: new Set(["items"]),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prop-allowlist.js","sourceRoot":"","sources":["../../src/render/prop-allowlist.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prop-allowlist.js","sourceRoot":"","sources":["../../src/render/prop-allowlist.ts"],"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-DrXsLYhe.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-BxCdj-KZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status-pill-BaLQoIDl.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-BxCdj-KZ.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 e, Fragment as y } from "react/jsx-runtime";
|
|
2
|
-
import { A as b, T as h, r as x } from "./tree-
|
|
3
|
-
import { S, C as k } from "./status-pill-
|
|
2
|
+
import { A as b, T as h, r as x } from "./tree-BLIxJbD3.js";
|
|
3
|
+
import { S, C as k } from "./status-pill-BxCdj-KZ.js";
|
|
4
4
|
import { useSignals as v } from "@preact/signals-react/runtime";
|
|
5
5
|
import { useState as f } from "react";
|
|
6
|
-
import { u } from "./index-
|
|
6
|
+
import { u } from "./index-DrXsLYhe.js";
|
|
7
7
|
const T = {
|
|
8
8
|
position: "fixed",
|
|
9
9
|
bottom: 12,
|
|
@@ -207,4 +207,4 @@ function F() {
|
|
|
207
207
|
export {
|
|
208
208
|
F as TestMode
|
|
209
209
|
};
|
|
210
|
-
//# sourceMappingURL=test-
|
|
210
|
+
//# sourceMappingURL=test-CaRHj_J6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-CA30C2By.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 { AllowedHostsProvider, readAllowedHosts } from \"../render/allowed-hosts\";\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 <AllowedHostsProvider hosts={readAllowedHosts(bundle)}>\n <Tree node={bundle.root} store={store} />\n </AllowedHostsProvider>\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","AllowedHostsProvider","readAllowedHosts","Tree","StatusPill","ControlPanel"],"mappings":";;;;;;AAIA,MAAMA,IAAmC;AAAA,EACvC,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,WAAW;AACb,GAEMC,IAAqC;AAAA,EACzC,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,eAAe;AAAA,EACf,OAAO;AAAA,EACP,eAAe;AAAA,EACf,cAAc;AAChB,GAEMC,IAAoC;AAAA,EACxC,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AACV,GAEMC,IAAmC;AAAA,EACvC,SAAS;AAAA,EACT,eAAe;AAAA,EACf,KAAK;AAAA,EACL,SAAS;AAAA,EACT,cAAc;AAChB;AAKO,SAASC,IAAY;AAC1B,QAAM,EAAE,QAAAC,GAAQ,OAAAC,GAAO,WAAAC,EAAA,IAAcC,EAAA;AACrC,EAAAC,EAAA;AACA,QAAM,CAACC,GAAQC,CAAS,IAAIC,EAAS,EAAE,GAEjCC,IAAWR,EAAO,qBAAqB,CAAA,GACvCS,IAAcR,EAAM,SAAA,GACpBS,IAAkB,OAAO,QAAQD,CAAW,EAAE;AAAA,IAClD,CAAC,CAACE,CAAC,MAAMN,MAAW,MAAMM,EAAE,SAASN,CAAM;AAAA,EAAA;AAG7C,SACE,gBAAAO,EAAC,OAAA,EAAI,OAAOjB,GAAa,eAAY,wBAEnC,UAAA;AAAA,IAAA,gBAAAkB,EAAC,OAAA,EAAI,OAAOjB,GAAe,UAAA,QAAI;AAAA,IAC/B,gBAAAgB,EAAC,OAAA,EAAI,OAAO,EAAE,SAAS,QAAQ,KAAK,GAAG,cAAc,EAAA,GACnD,UAAA;AAAA,MAAA,gBAAAC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAOhB;AAAA,UACP,SAAS,MAAMK,EAAU,CAAC,EAAE,MAAM,eAAe,OAAO,IAAA,CAAK,CAAC;AAAA,UAC/D,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGD,gBAAAW;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAOhB;AAAA,UACP,SAAS,MAAMK,EAAU,CAAC,EAAE,MAAM,eAAe,OAAO,IAAA,CAAO,CAAC;AAAA,UACjE,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,MAGD,gBAAAW;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAOhB;AAAA,UACP,SAAS,MAAMK,EAAU,CAAC,EAAE,MAAM,gBAAgB,OAAO,GAAA,CAAM,CAAC;AAAA,UACjE,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GACF;AAAA,IAGA,gBAAAW,EAAC,OAAA,EAAI,OAAOjB,GAAe,UAAA,qBAAiB;AAAA,IAC3CY,EAAS,WAAW,KACnB,gBAAAK,EAAC,SAAI,OAAO,EAAE,OAAO,WAAW,WAAW,UAAU,UAAU,GAAA,GAAM,UAAA,gDAErE;AAAA,IAEDL,EAAS,IAAI,CAACM,MACb,gBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QAEC,SAAAD;AAAA,QACA,QAAQ,CAACE;AAAA;AAAA,UAEPd,EAAU;AAAA,YACR;AAAA,cACE,MAAM;AAAA,cACN,OAAO,KAAK,UAAU,EAAE,KAAKY,EAAQ,KAAK,SAAAE,GAAS;AAAA,YAAA;AAAA,UACrD,CACD;AAAA;AAAA,MAAA;AAAA,MATEF,EAAQ;AAAA,IAAA,CAYhB;AAAA,IAGD,gBAAAD,EAAC,SAAI,OAAO,EAAE,GAAGjB,GAAe,WAAW,GAAA,GAAM,UAAA,SAAK;AAAA,IACtD,gBAAAiB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,aAAY;AAAA,QACZ,OAAOR;AAAA,QACP,UAAU,CAACY,MAAMX,EAAUW,EAAE,OAAO,KAAK;AAAA,QACzC,OAAO;AAAA,UACL,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,OAAO;AAAA,UACP,SAAS;AAAA,UACT,UAAU;AAAA,UACV,OAAO;AAAA,UACP,cAAc;AAAA,QAAA;AAAA,MAChB;AAAA,IAAA;AAAA,IAEF,gBAAAJ,EAAC,OAAA,EAAI,OAAO,EAAE,YAAY,aAAa,UAAU,KAAA,GAC9C,YAAgB,IAAI,CAAC,CAACK,GAAMC,CAAK,MAChC,gBAAAP;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,qBAAqB;AAAA,UACrB,KAAK;AAAA,UACL,SAAS;AAAA,UACT,cAAc;AAAA,QAAA;AAAA,QAGhB,UAAA;AAAA,UAAA,gBAAAC,EAAC,UAAK,OAAO,EAAE,OAAO,UAAA,GAAc,UAAAK,GAAK;AAAA,UACzC,gBAAAL,EAAC,UAAK,OAAO,EAAE,OAAO,UAAA,GAAc,UAAAO,EAAYD,CAAK,EAAA,CAAE;AAAA,QAAA;AAAA,MAAA;AAAA,MAVlDD;AAAA,IAAA,CAYR,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;AAEA,SAASH,EAAW;AAAA,EAClB,SAAAD;AAAA,EACA,QAAAO;AACF,GAGG;AACD,QAAM,CAACC,GAAOC,CAAQ,IAAIhB,EAAS,IAAI;AACvC,SACE,gBAAAK,EAAC,OAAA,EAAI,OAAOd,GACV,UAAA;AAAA,IAAA,gBAAAc;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,gBAAgB;AAAA,UAChB,YAAY;AAAA,QAAA;AAAA,QAGd,UAAA;AAAA,UAAA,gBAAAC,EAAC,UAAK,OAAO,EAAE,OAAO,UAAA,GAAc,YAAQ,OAAM;AAAA,UAClD,gBAAAA,EAAC,QAAA,EAAK,OAAO,EAAE,OAAO,WAAW,UAAU,GAAA,GAAO,UAAAC,EAAQ,KAAA,CAAK;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAEjE,gBAAAD;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,OAAOS;AAAA,QACP,UAAU,CAACL,MAAMM,EAASN,EAAE,OAAO,KAAK;AAAA,QACxC,MAAM;AAAA,QACN,OAAO;AAAA,UACL,YAAY;AAAA,UACZ,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,SAAS;AAAA,UACT,QAAQ;AAAA,QAAA;AAAA,MACV;AAAA,IAAA;AAAA,IAEF,gBAAAJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,OAAOhB;AAAA,QACP,SAAS,MAAM;AACb,cAAI;AACF,kBAAM2B,IAAS,KAAK,MAAMF,CAAK;AAC/B,YAAAD,EAAOG,CAAM;AAAA,UACf,QAAQ;AACN,YAAAH,EAAOC,CAAK;AAAA,UACd;AAAA,QACF;AAAA,QACD,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAED,GACF;AAEJ;AAEA,SAASF,EAAYD,GAAwB;AAC3C,SAAIA,MAAU,SAAkB,MAC5BA,MAAU,OAAa,SACvB,OAAOA,KAAU,YACjB,OAAOA,KAAU,WAAiB,KAAK,UAAUA,CAAK,IACnD,OAAOA,CAAK;AACrB;AC3MO,SAASM,IAAW;AACzB,QAAM,EAAE,OAAAxB,GAAO,QAAAD,EAAA,IAAWG,EAAA;AAC1B,SACE,gBAAAS,EAAAc,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAb,EAACc,GAAA,EAAqB,OAAOC,EAAiB5B,CAAM,GAClD,UAAA,gBAAAa,EAACgB,GAAA,EAAK,MAAM7B,EAAO,MAAM,OAAAC,EAAA,CAAc,GACzC;AAAA,sBACC6B,GAAA,EAAW;AAAA,sBACXC,GAAA,EAAa;AAAA,sBACbhC,GAAA,CAAA,CAAU;AAAA,EAAA,GACb;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"test-CaRHj_J6.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 { AllowedHostsProvider, readAllowedHosts } from \"../render/allowed-hosts\";\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 <AllowedHostsProvider hosts={readAllowedHosts(bundle)}>\n <Tree node={bundle.root} store={store} />\n </AllowedHostsProvider>\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","AllowedHostsProvider","readAllowedHosts","Tree","StatusPill","ControlPanel"],"mappings":"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"}
|