@lumencast/runtime 0.7.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.
Files changed (80) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/animate/keyframes.js +8 -1
  3. package/dist/animate/keyframes.js.map +1 -1
  4. package/dist/app.d.ts +4 -1
  5. package/dist/app.d.ts.map +1 -1
  6. package/dist/app.js +2 -1
  7. package/dist/app.js.map +1 -1
  8. package/dist/{broadcast-DUYqvcgo.js → broadcast-ryjLRD5q.js} +3 -3
  9. package/dist/{broadcast-DUYqvcgo.js.map → broadcast-ryjLRD5q.js.map} +1 -1
  10. package/dist/{control-CL8TWXaE.js → control-AgxbXOVS.js} +4 -4
  11. package/dist/{control-CL8TWXaE.js.map → control-AgxbXOVS.js.map} +1 -1
  12. package/dist/{index-C6viWFcT.js → index-DrXsLYhe.js} +309 -212
  13. package/dist/index-DrXsLYhe.js.map +1 -0
  14. package/dist/index.d.ts +4 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.html +1 -1
  17. package/dist/index.js +13 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/lumencast.js +14 -9
  20. package/dist/mount.d.ts.map +1 -1
  21. package/dist/mount.js +5 -0
  22. package/dist/mount.js.map +1 -1
  23. package/dist/overlay/runtime-context.d.ts +11 -0
  24. package/dist/overlay/runtime-context.d.ts.map +1 -1
  25. package/dist/overlay/runtime-context.js +8 -0
  26. package/dist/overlay/runtime-context.js.map +1 -1
  27. package/dist/render/asset-resolve.d.ts +27 -0
  28. package/dist/render/asset-resolve.d.ts.map +1 -0
  29. package/dist/render/asset-resolve.js +86 -0
  30. package/dist/render/asset-resolve.js.map +1 -0
  31. package/dist/render/bundle.d.ts +1 -1
  32. package/dist/render/bundle.d.ts.map +1 -1
  33. package/dist/render/bundle.js +4 -0
  34. package/dist/render/bundle.js.map +1 -1
  35. package/dist/render/headless.d.ts +39 -0
  36. package/dist/render/headless.d.ts.map +1 -0
  37. package/dist/render/headless.js +83 -0
  38. package/dist/render/headless.js.map +1 -0
  39. package/dist/render/keyframe-player.d.ts.map +1 -1
  40. package/dist/render/keyframe-player.js +15 -1
  41. package/dist/render/keyframe-player.js.map +1 -1
  42. package/dist/render/primitives/capture.d.ts +40 -0
  43. package/dist/render/primitives/capture.d.ts.map +1 -0
  44. package/dist/render/primitives/capture.js +171 -0
  45. package/dist/render/primitives/capture.js.map +1 -0
  46. package/dist/render/primitives/index.d.ts.map +1 -1
  47. package/dist/render/primitives/index.js +3 -0
  48. package/dist/render/primitives/index.js.map +1 -1
  49. package/dist/render/primitives/media.d.ts +11 -2
  50. package/dist/render/primitives/media.d.ts.map +1 -1
  51. package/dist/render/primitives/media.js +14 -3
  52. package/dist/render/primitives/media.js.map +1 -1
  53. package/dist/render/prop-allowlist.d.ts.map +1 -1
  54. package/dist/render/prop-allowlist.js +5 -0
  55. package/dist/render/prop-allowlist.js.map +1 -1
  56. package/dist/{status-pill-jJT54n07.js → status-pill-BxCdj-KZ.js} +2 -2
  57. package/dist/{status-pill-jJT54n07.js.map → status-pill-BxCdj-KZ.js.map} +1 -1
  58. package/dist/{test-84XodL1c.js → test-CaRHj_J6.js} +4 -4
  59. package/dist/{test-84XodL1c.js.map → test-CaRHj_J6.js.map} +1 -1
  60. package/dist/{tree-BIimahCf.js → tree-BLIxJbD3.js} +515 -432
  61. package/dist/tree-BLIxJbD3.js.map +1 -0
  62. package/dist/types.d.ts +10 -0
  63. package/dist/types.d.ts.map +1 -1
  64. package/package.json +6 -5
  65. package/src/animate/keyframes.ts +8 -1
  66. package/src/app.tsx +5 -0
  67. package/src/index.ts +29 -0
  68. package/src/mount.ts +5 -0
  69. package/src/overlay/runtime-context.tsx +14 -0
  70. package/src/render/asset-resolve.ts +97 -0
  71. package/src/render/bundle.ts +9 -1
  72. package/src/render/headless.tsx +129 -0
  73. package/src/render/keyframe-player.tsx +14 -1
  74. package/src/render/primitives/capture.tsx +210 -0
  75. package/src/render/primitives/index.ts +3 -0
  76. package/src/render/primitives/media.tsx +14 -3
  77. package/src/render/prop-allowlist.ts +5 -0
  78. package/src/types.ts +10 -0
  79. package/dist/index-C6viWFcT.js.map +0 -1
  80. package/dist/tree-BIimahCf.js.map +0 -1
@@ -1,75 +1,80 @@
1
- import { batch as y, signal as p } from "@preact/signals-react";
2
- import { createRoot as B } from "react-dom/client";
3
- import { createContext as W, useContext as z, lazy as T, Suspense as H, createElement as G } from "react";
4
- import { jsx as f } from "react/jsx-runtime";
5
- import { useSignals as X } from "@preact/signals-react/runtime";
6
- import { AnimatePresence as Y, motion as K } from "framer-motion";
7
- import { SequenceTracker as J, encodeFrame as R, input as Q, WS_SUBPROTOCOLS as Z, WS_SUBPROTOCOL_V1_1 as V, subscribe as ee, decodeServerFrame as te, LumencastError as A } from "@lumencast/protocol";
8
- const P = W(null);
9
- function se({
1
+ import { batch as w, signal as g } from "@preact/signals-react";
2
+ import { createRoot as D } from "react-dom/client";
3
+ import { createContext as K, useContext as C, lazy as S, Suspense as Z, createElement as J, StrictMode as Q } from "react";
4
+ import { jsx as h } from "react/jsx-runtime";
5
+ import { useSignals as V } from "@preact/signals-react/runtime";
6
+ import { AnimatePresence as ee, motion as te } from "framer-motion";
7
+ import { SequenceTracker as se, encodeFrame as O, input as ne, WS_SUBPROTOCOLS as re, WS_SUBPROTOCOL_V1_1 as ie, subscribe as oe, decodeServerFrame as ce, LumencastError as L } from "@lumencast/protocol";
8
+ const T = K(null);
9
+ function F({
10
10
  value: t,
11
11
  children: e
12
12
  }) {
13
- return /* @__PURE__ */ f(P.Provider, { value: t, children: e });
13
+ return /* @__PURE__ */ h(T.Provider, { value: t, children: e });
14
14
  }
15
- function Ye() {
16
- const t = z(P);
15
+ function Ve() {
16
+ const t = C(T);
17
17
  if (!t)
18
18
  throw new Error(
19
19
  "Lumencast overlay components must be rendered inside LumencastRuntimeProvider"
20
20
  );
21
21
  return t;
22
22
  }
23
- const ne = T(
24
- () => import("./broadcast-DUYqvcgo.js").then((t) => ({ default: t.BroadcastMode }))
25
- ), re = T(
26
- () => import("./control-CL8TWXaE.js").then((t) => ({ default: t.ControlMode }))
27
- ), ie = T(() => import("./test-84XodL1c.js").then((t) => ({ default: t.TestMode })));
28
- function oe({
23
+ function et() {
24
+ return C(T);
25
+ }
26
+ const ae = S(
27
+ () => import("./broadcast-ryjLRD5q.js").then((t) => ({ default: t.BroadcastMode }))
28
+ ), ue = S(
29
+ () => import("./control-AgxbXOVS.js").then((t) => ({ default: t.ControlMode }))
30
+ ), le = S(() => import("./test-CaRHj_J6.js").then((t) => ({ default: t.TestMode })));
31
+ function he({
29
32
  mode: t,
30
33
  store: e,
31
34
  bundleSignal: s,
32
35
  statusSignal: n,
33
36
  crossfadeKeySignal: r,
34
- sendInput: o
37
+ sendInput: i,
38
+ resolveCaptureDevice: c
35
39
  }) {
36
- X();
37
- const c = s.value, a = n.value, d = r.value;
38
- if (!c) return null;
39
- const l = t === "broadcast" ? ne : t === "control" ? re : ie;
40
- return /* @__PURE__ */ f(Y, { mode: "sync", children: /* @__PURE__ */ f(
41
- K.div,
40
+ V();
41
+ const a = s.value, f = n.value, u = r.value;
42
+ if (!a) return null;
43
+ const p = t === "broadcast" ? ae : t === "control" ? ue : le;
44
+ return /* @__PURE__ */ h(ee, { mode: "sync", children: /* @__PURE__ */ h(
45
+ te.div,
42
46
  {
43
47
  initial: { opacity: 0 },
44
48
  animate: { opacity: 1 },
45
49
  exit: { opacity: 0 },
46
50
  transition: { duration: 0.4, ease: "easeInOut" },
47
51
  style: { position: "absolute", inset: 0 },
48
- children: /* @__PURE__ */ f(
49
- se,
52
+ children: /* @__PURE__ */ h(
53
+ F,
50
54
  {
51
55
  value: {
52
56
  mode: t,
53
57
  store: e,
54
- bundle: c,
55
- status: a,
56
- sendInput: o
58
+ bundle: a,
59
+ status: f,
60
+ sendInput: i,
61
+ ...c !== void 0 ? { resolveCaptureDevice: c } : {}
57
62
  },
58
- children: /* @__PURE__ */ f(H, { fallback: null, children: /* @__PURE__ */ f(l, {}) })
63
+ children: /* @__PURE__ */ h(Z, { fallback: null, children: /* @__PURE__ */ h(p, {}) })
59
64
  }
60
65
  )
61
66
  },
62
- d
67
+ u
63
68
  ) });
64
69
  }
65
- const ce = "<anon>", b = /* @__PURE__ */ new Set();
66
- function ae(t) {
70
+ const fe = "<anon>", b = /* @__PURE__ */ new Set();
71
+ function q(t) {
67
72
  return b.add(t), () => {
68
73
  b.delete(t);
69
74
  };
70
75
  }
71
- function $(t, e, s) {
72
- const n = { nodeId: t ?? ce, field: e, reason: s };
76
+ function B(t, e, s) {
77
+ const n = { nodeId: t ?? fe, field: e, reason: s };
73
78
  if (b.size > 0) {
74
79
  for (const r of b)
75
80
  try {
@@ -79,41 +84,41 @@ function $(t, e, s) {
79
84
  return;
80
85
  }
81
86
  }
82
- const le = 100, ue = 4, he = 64, fe = {
83
- blur: le,
84
- brightness: ue
87
+ const de = 100, me = 4, pe = 64, ge = {
88
+ blur: de,
89
+ brightness: me
85
90
  };
86
- function O(t, e) {
91
+ function N(t, e) {
87
92
  if (typeof e != "number" || !Number.isFinite(e) || e < 0 || Object.is(e, -0)) return null;
88
- const s = fe[t];
93
+ const s = ge[t];
89
94
  return e > s ? s : e;
90
95
  }
91
- const de = /^blur\((\d{1,7}(?:\.\d{1,4})?)px\) brightness\((\d{1,7}(?:\.\d{1,4})?)\)$/, Ke = "blur(0px) brightness(1)";
92
- function me(t) {
93
- if (typeof t != "string" || t.length === 0 || t.length > he) return null;
94
- const e = de.exec(t);
96
+ const ve = /^blur\((\d{1,7}(?:\.\d{1,4})?)px\) brightness\((\d{1,7}(?:\.\d{1,4})?)\)$/, tt = "blur(0px) brightness(1)";
97
+ function be(t) {
98
+ if (typeof t != "string" || t.length === 0 || t.length > pe) return null;
99
+ const e = ve.exec(t);
95
100
  if (!e) return null;
96
- const s = O("blur", Number(e[1])), n = O("brightness", Number(e[2]));
101
+ const s = N("blur", Number(e[1])), n = N("brightness", Number(e[2]));
97
102
  return s === null || n === null ? null : `blur(${s}px) brightness(${n})`;
98
103
  }
99
- function pe(t, e) {
100
- $(
104
+ function ye(t, e) {
105
+ B(
101
106
  e,
102
107
  t,
103
108
  "rejected unsafe filter value : outside the R8 caps or not a finite number >= 0"
104
109
  );
105
110
  }
106
- const ge = { duration: 0 }, be = {
111
+ const ke = { duration: 0 }, we = {
107
112
  linear: "linear",
108
113
  "cubic-in": "easeIn",
109
114
  "cubic-out": "easeOut",
110
115
  "cubic-in-out": "easeInOut"
111
116
  };
112
- function Je(t) {
113
- return !t || t.kind === "none" ? ge : t.kind === "tween" ? {
117
+ function st(t) {
118
+ return !t || t.kind === "none" ? ke : t.kind === "tween" ? {
114
119
  type: "tween",
115
120
  duration: (t.duration_ms ?? 0) / 1e3,
116
- ease: t.ease ? be[t.ease] ?? "easeOut" : "easeOut"
121
+ ease: t.ease ? we[t.ease] ?? "easeOut" : "easeOut"
117
122
  } : t.kind === "spring" ? {
118
123
  type: "spring",
119
124
  ...t.stiffness !== void 0 ? { stiffness: t.stiffness } : {},
@@ -125,7 +130,7 @@ function Je(t) {
125
130
  ease: "easeInOut"
126
131
  };
127
132
  }
128
- const ve = {
133
+ const Se = {
129
134
  opacity: 1,
130
135
  scale: 1,
131
136
  scaleX: 1,
@@ -137,12 +142,12 @@ const ve = {
137
142
  // framer interpolates between structurally-identical filter lists
138
143
  // (the compiler emits the same two-function form, clamped per R8).
139
144
  filter: "blur(0px) brightness(1)"
140
- }, ke = {
145
+ }, Te = {
141
146
  kind: "tween",
142
147
  duration_ms: 400,
143
148
  ease: "cubic-out"
144
149
  };
145
- function Qe(t, e, s) {
150
+ function nt(t, e, s) {
146
151
  for (const n of e) {
147
152
  const r = t(n);
148
153
  if (r !== void 0) return r;
@@ -152,29 +157,29 @@ function Qe(t, e, s) {
152
157
  const r = t(n);
153
158
  if (r !== void 0) return r;
154
159
  }
155
- return ke;
160
+ return Te;
156
161
  }
157
162
  }
158
- function Ze(t, e, s) {
163
+ function rt(t, e, s) {
159
164
  if (!e || Object.keys(e).length === 0)
160
165
  return { initial: t, animate: t };
161
166
  let n = e;
162
167
  if (e.filter !== void 0) {
163
- const o = me(e.filter);
164
- n = { ...e }, o === null ? (pe("animate_initial.filter", s), delete n.filter) : n.filter = o;
168
+ const i = be(e.filter);
169
+ n = { ...e }, i === null ? (ye("animate_initial.filter", s), delete n.filter) : n.filter = i;
165
170
  }
166
171
  const r = { ...t };
167
- for (const o of Object.keys(n))
168
- o in r || (r[o] = ve[o] ?? 0);
172
+ for (const i of Object.keys(n))
173
+ i in r || (r[i] = Se[i] ?? 0);
169
174
  return { initial: n, animate: r };
170
175
  }
171
- function ye(t) {
176
+ function _e(t) {
172
177
  if (typeof t != "object" || t === null) return;
173
178
  const e = t, s = e.kind;
174
179
  if (s === "snap")
175
180
  return { kind: "none" };
176
181
  if (s === "tween") {
177
- const n = typeof e.duration_ms == "number" ? e.duration_ms : 0, r = Te[e.easing] ?? "cubic-out";
182
+ const n = typeof e.duration_ms == "number" ? e.duration_ms : 0, r = Ee[e.easing] ?? "cubic-out";
178
183
  return { kind: "tween", duration_ms: n, ease: r };
179
184
  }
180
185
  if (s === "spring") {
@@ -182,53 +187,53 @@ function ye(t) {
182
187
  return typeof e.stiffness == "number" && (n.stiffness = e.stiffness), typeof e.damping == "number" && (n.damping = e.damping), typeof e.mass == "number" && (n.mass = e.mass), n;
183
188
  }
184
189
  }
185
- const Te = {
190
+ const Ee = {
186
191
  linear: "linear",
187
192
  "ease-in": "cubic-in",
188
193
  "ease-out": "cubic-out",
189
194
  "ease-in-out": "cubic-in-out"
190
195
  };
191
- function we(t, e) {
192
- y(() => {
196
+ function Ie(t, e) {
197
+ w(() => {
193
198
  for (const s of e.patches) {
194
- const n = ye(s.transition);
199
+ const n = _e(s.transition);
195
200
  n !== void 0 ? t.setWithTransition(s.path, s.value, n) : t.set(s.path, s.value);
196
201
  }
197
202
  });
198
203
  }
199
- function Se(t, e) {
204
+ function Ae(t, e) {
200
205
  t.reset(e.state);
201
206
  }
202
- class _e {
207
+ class Re {
203
208
  signals = /* @__PURE__ */ new Map();
204
209
  transitions = /* @__PURE__ */ new Map();
205
210
  signal(e) {
206
211
  let s = this.signals.get(e);
207
- return s || (s = p(void 0), this.signals.set(e, s)), s;
212
+ return s || (s = g(void 0), this.signals.set(e, s)), s;
208
213
  }
209
214
  transitionSignal(e) {
210
215
  let s = this.transitions.get(e);
211
- return s || (s = p(void 0), this.transitions.set(e, s)), s;
216
+ return s || (s = g(void 0), this.transitions.set(e, s)), s;
212
217
  }
213
218
  set(e, s) {
214
219
  const n = this.signal(e);
215
220
  k(n.peek(), s) || (n.value = s);
216
221
  }
217
222
  setWithTransition(e, s, n) {
218
- y(() => {
223
+ w(() => {
219
224
  const r = this.transitionSignal(e);
220
225
  r.peek() !== n && (r.value = n);
221
- const o = this.signal(e);
222
- k(o.peek(), s) || (o.value = s);
226
+ const i = this.signal(e);
227
+ k(i.peek(), s) || (i.value = s);
223
228
  });
224
229
  }
225
230
  reset(e) {
226
- y(() => {
231
+ w(() => {
227
232
  const s = /* @__PURE__ */ new Set();
228
233
  for (const [n, r] of Object.entries(e)) {
229
234
  s.add(n);
230
- const o = this.signal(n);
231
- k(o.peek(), r) || (o.value = r);
235
+ const i = this.signal(n);
236
+ k(i.peek(), r) || (i.value = r);
232
237
  const c = this.transitions.get(n);
233
238
  c && c.peek() !== void 0 && (c.value = void 0);
234
239
  }
@@ -246,8 +251,8 @@ class _e {
246
251
  return e;
247
252
  }
248
253
  }
249
- function Ee() {
250
- return new _e();
254
+ function W() {
255
+ return new Re();
251
256
  }
252
257
  function k(t, e) {
253
258
  if (t === e) return !0;
@@ -258,22 +263,26 @@ function k(t, e) {
258
263
  if (t[c] !== e[c]) return !1;
259
264
  return !0;
260
265
  }
261
- const s = t, n = e, r = Object.keys(s), o = Object.keys(n);
262
- if (r.length !== o.length) return !1;
266
+ const s = t, n = e, r = Object.keys(s), i = Object.keys(n);
267
+ if (r.length !== i.length) return !1;
263
268
  for (const c of r)
264
269
  if (s[c] !== n[c]) return !1;
265
270
  return !0;
266
271
  }
267
- const Ie = /* @__PURE__ */ new Set([
268
- "x-lumencast.color-srgb-1.0"
269
- ]), Re = /^x-[a-z0-9-]+(?:\.[a-z0-9-]+)*$/, Ae = /^(?:0|[1-9][0-9]*)$/, N = ".authoring";
270
- function Oe(t) {
272
+ const Oe = /* @__PURE__ */ new Set([
273
+ "x-lumencast.color-srgb-1.0",
274
+ // RFC-0001 / ADR 004 this runtime ships the Zab capture plugin, so a
275
+ // bundle declaring `x-zab.capture/1` in `profiles[]` is compatible (it is
276
+ // NOT rejected as BUNDLE_INCOMPATIBLE, §17.3.1).
277
+ "x-zab.capture/1"
278
+ ]), Le = /^x-[a-z0-9-]+(?:\.[a-z0-9-]+)*$/, Ne = /^(?:0|[1-9][0-9]*)$/, x = ".authoring";
279
+ function xe(t) {
271
280
  const e = t.indexOf("/");
272
281
  if (e < 0) return !1;
273
282
  const s = t.slice(0, e), n = t.slice(e + 1);
274
- return !Ae.test(n) || !s.endsWith(N) ? !1 : Re.test(s.slice(0, -N.length));
283
+ return !Ne.test(n) || !s.endsWith(x) ? !1 : Le.test(s.slice(0, -x.length));
275
284
  }
276
- class L extends Error {
285
+ class U extends Error {
277
286
  code = "BUNDLE_INCOMPATIBLE";
278
287
  unsupportedProfiles;
279
288
  constructor(e) {
@@ -284,17 +293,17 @@ class L extends Error {
284
293
  ), this.name = "BundleIncompatibleError", this.unsupportedProfiles = e;
285
294
  }
286
295
  }
287
- function U(t, e = Ie) {
296
+ function P(t, e = Oe) {
288
297
  const s = t.profiles;
289
298
  if (!s) return;
290
299
  if (!Array.isArray(s))
291
- throw new L(["<malformed: profiles is not an array>"]);
300
+ throw new U(["<malformed: profiles is not an array>"]);
292
301
  if (s.length === 0) return;
293
- const n = s.filter((r) => typeof r != "string" || !Oe(r) && !e.has(r)).map((r) => typeof r == "string" ? r : "<malformed: non-string profile entry>");
302
+ const n = s.filter((r) => typeof r != "string" || !xe(r) && !e.has(r)).map((r) => typeof r == "string" ? r : "<malformed: non-string profile entry>");
294
303
  if (n.length > 0)
295
- throw new L(n);
304
+ throw new U(n);
296
305
  }
297
- class Ne {
306
+ class Ue {
298
307
  cache = /* @__PURE__ */ new Map();
299
308
  baseUrl;
300
309
  pathPrefix;
@@ -317,12 +326,12 @@ class Ne {
317
326
  return this.resolveUrl ? this.resolveUrl(e, s) : `${this.baseUrl}${this.pathPrefix}/${encodeURIComponent(e)}/bundle?v=${encodeURIComponent(s)}`;
318
327
  }
319
328
  preload(e) {
320
- U(e), this.cache.set(e.scene_version, e);
329
+ P(e), this.cache.set(e.scene_version, e);
321
330
  }
322
331
  async get(e, s) {
323
332
  const n = this.cache.get(s);
324
333
  if (n) return n;
325
- const r = this.buildUrl(e, s), o = await this.buildInit(), c = o ? await this.fetchImpl(r, o) : await this.fetchImpl(r);
334
+ const r = this.buildUrl(e, s), i = await this.buildInit(), c = i ? await this.fetchImpl(r, i) : await this.fetchImpl(r);
326
335
  if (!c.ok)
327
336
  throw new Error(`bundle fetch failed: ${c.status} ${c.statusText}`);
328
337
  const a = await c.json();
@@ -330,19 +339,19 @@ class Ne {
330
339
  throw new Error(
331
340
  `bundle scene_version mismatch: expected ${s}, got ${a.scene_version}`
332
341
  );
333
- return U(a), this.cache.set(s, a), a;
342
+ return P(a), this.cache.set(s, a), a;
334
343
  }
335
344
  }
336
- function Le(t) {
337
- return new Ne(t);
345
+ function Pe(t) {
346
+ return new Ue(t);
338
347
  }
339
- const g = {
348
+ const v = {
340
349
  initial: 200,
341
350
  max: 5e3,
342
351
  factor: 2,
343
352
  jitter: 0.2
344
353
  };
345
- class Ue {
354
+ class je {
346
355
  constructor(e, s) {
347
356
  this.opts = e, this.random = s;
348
357
  }
@@ -366,20 +375,20 @@ class Ue {
366
375
  this._attempt = 0;
367
376
  }
368
377
  }
369
- function xe(t = {}) {
378
+ function Me(t = {}) {
370
379
  const e = {
371
- initial: t.initial ?? g.initial,
372
- max: t.max ?? g.max,
373
- factor: t.factor ?? g.factor,
374
- jitter: t.jitter ?? g.jitter
380
+ initial: t.initial ?? v.initial,
381
+ max: t.max ?? v.max,
382
+ factor: t.factor ?? v.factor,
383
+ jitter: t.jitter ?? v.jitter
375
384
  };
376
385
  if (e.initial <= 0) throw new RangeError("initial must be > 0");
377
386
  if (e.max < e.initial) throw new RangeError("max must be >= initial");
378
387
  if (e.factor < 1) throw new RangeError("factor must be >= 1");
379
388
  if (e.jitter < 0 || e.jitter > 1) throw new RangeError("jitter must be within [0, 1]");
380
- return new Ue(e, t.random ?? Math.random);
389
+ return new je(e, t.random ?? Math.random);
381
390
  }
382
- class h extends Error {
391
+ class m extends Error {
383
392
  recoverable;
384
393
  code;
385
394
  cause;
@@ -387,14 +396,14 @@ class h extends Error {
387
396
  super(e), this.name = "TransportError", this.recoverable = s, this.code = n, this.cause = r;
388
397
  }
389
398
  }
390
- class Me {
399
+ class $e {
391
400
  status = "disconnected";
392
401
  socket = null;
393
402
  token;
394
403
  url;
395
404
  WebSocketCtor;
396
405
  schedule;
397
- seq = new J();
406
+ seq = new se();
398
407
  opts;
399
408
  scheduler;
400
409
  reconnectTimer = null;
@@ -406,7 +415,7 @@ class Me {
406
415
  throw new TypeError(
407
416
  "Lumencast WsClient: no WebSocket implementation found in this environment"
408
417
  );
409
- this.WebSocketCtor = s, this.schedule = xe(e.reconnect), this.scheduler = e.scheduler ?? {
418
+ this.WebSocketCtor = s, this.schedule = Me(e.reconnect), this.scheduler = e.scheduler ?? {
410
419
  setTimeout: globalThis.setTimeout.bind(globalThis),
411
420
  clearTimeout: globalThis.clearTimeout.bind(globalThis)
412
421
  };
@@ -420,11 +429,11 @@ class Me {
420
429
  * authenticate the render-bundle GET with the same credential. A
421
430
  * `LumencastTokenProvider` is awaited. */
422
431
  resolveCurrentToken() {
423
- return x(this.token);
432
+ return j(this.token);
424
433
  }
425
434
  /** Send `input` patches to the server. No-op if not connected. */
426
435
  sendInput(e) {
427
- !this.socket || this.socket.readyState !== this.WebSocketCtor.OPEN || e.length !== 0 && this.socket.send(R(Q(e)));
436
+ !this.socket || this.socket.readyState !== this.WebSocketCtor.OPEN || e.length !== 0 && this.socket.send(O(ne(e)));
428
437
  }
429
438
  /** Replace the auth token. Closes and reopens with the new token. */
430
439
  setToken(e) {
@@ -440,10 +449,10 @@ class Me {
440
449
  this.setStatus("connecting");
441
450
  let e;
442
451
  try {
443
- e = await x(this.token);
452
+ e = await j(this.token);
444
453
  } catch (n) {
445
454
  this.opts.onTransportError?.(
446
- new h(
455
+ new m(
447
456
  `failed to resolve token: ${n.message}`,
448
457
  !0,
449
458
  "AUTH_DENIED",
@@ -455,10 +464,10 @@ class Me {
455
464
  if (!this.active) return;
456
465
  let s;
457
466
  try {
458
- s = new this.WebSocketCtor(this.url, [...Z]);
467
+ s = new this.WebSocketCtor(this.url, [...re]);
459
468
  } catch (n) {
460
469
  this.opts.onTransportError?.(
461
- new h(
470
+ new m(
462
471
  `failed to open WebSocket: ${n.message}`,
463
472
  !0,
464
473
  "INTERNAL",
@@ -471,25 +480,25 @@ class Me {
471
480
  }
472
481
  handleOpen(e) {
473
482
  if (!this.socket) return;
474
- const n = this.socket.protocol === V && this.seq.last > 0, r = n ? this.seq.last : void 0;
483
+ const n = this.socket.protocol === ie && this.seq.last > 0, r = n ? this.seq.last : void 0;
475
484
  n || this.seq.reset();
476
- const o = ee({
485
+ const i = oe({
477
486
  token: e,
478
487
  ...this.opts.scene !== void 0 ? { scene: this.opts.scene } : {},
479
488
  ...this.opts.session !== void 0 ? { session: this.opts.session } : {},
480
489
  ...r !== void 0 ? { since_sequence: r } : {}
481
490
  });
482
- this.socket.send(R(o));
491
+ this.socket.send(O(i));
483
492
  }
484
493
  handleMessage(e) {
485
494
  const s = typeof e.data == "string" ? e.data : "";
486
495
  if (!s) return;
487
496
  let n;
488
497
  try {
489
- n = te(s);
498
+ n = ce(s);
490
499
  } catch (r) {
491
- const o = (r instanceof A, r.message), c = r instanceof A ? r.code : "INTERNAL";
492
- this.opts.onTransportError?.(new h(`codec: ${o}`, !0, c, r)), this.closeSocket(), this.scheduleReconnect();
500
+ const i = (r instanceof L, r.message), c = r instanceof L ? r.code : "INTERNAL";
501
+ this.opts.onTransportError?.(new m(`codec: ${i}`, !0, c, r)), this.closeSocket(), this.scheduleReconnect();
493
502
  return;
494
503
  }
495
504
  if (n !== null)
@@ -497,7 +506,7 @@ class Me {
497
506
  case "snapshot": {
498
507
  if (n.seq < 1) {
499
508
  this.opts.onTransportError?.(
500
- new h(`snapshot seq must be >= 1, got ${n.seq}`, !0, "VERSION_GAP")
509
+ new m(`snapshot seq must be >= 1, got ${n.seq}`, !0, "VERSION_GAP")
501
510
  ), this.closeSocket(), this.scheduleReconnect();
502
511
  return;
503
512
  }
@@ -508,7 +517,7 @@ class Me {
508
517
  const r = this.seq.observe(n.seq);
509
518
  if (r.kind === "gap") {
510
519
  this.opts.onTransportError?.(
511
- new h(
520
+ new m(
512
521
  `sequence gap: expected ${this.seq.last + 1}, got ${n.seq}`,
513
522
  !0,
514
523
  "VERSION_GAP"
@@ -541,7 +550,7 @@ class Me {
541
550
  }
542
551
  if (e.code === 4401 || e.code === 4403 || e.code === 1008) {
543
552
  this.opts.onTransportError?.(
544
- new h(`server closed: ${e.code} ${e.reason}`, !1, "AUTH_DENIED")
553
+ new m(`server closed: ${e.code} ${e.reason}`, !1, "AUTH_DENIED")
545
554
  ), this.close();
546
555
  return;
547
556
  }
@@ -571,10 +580,10 @@ class Me {
571
580
  this.status !== e && (this.status = e, this.opts.onStatus?.(e));
572
581
  }
573
582
  }
574
- async function x(t) {
583
+ async function j(t) {
575
584
  return typeof t == "string" ? t : await t.fetch();
576
585
  }
577
- function Pe(t) {
586
+ function De(t) {
578
587
  if (!(t.target instanceof HTMLElement))
579
588
  throw new TypeError("mount: `target` must be an HTMLElement");
580
589
  if (typeof t.serverUrl != "string" || t.serverUrl.length === 0)
@@ -586,107 +595,110 @@ function Pe(t) {
586
595
  throw new TypeError("mount: `scene` is required when mode === 'test'");
587
596
  }
588
597
  }
589
- function Ve(t) {
590
- Pe(t), t.onStatus?.("disconnected");
591
- const e = Ee(), s = je(t.serverUrl), n = Le({
598
+ function it(t) {
599
+ De(t), t.onStatus?.("disconnected");
600
+ const e = W(), s = Fe(t.serverUrl), n = Pe({
592
601
  baseUrl: s,
593
602
  ...t.resolveBundleUrl !== void 0 ? { resolveUrl: t.resolveBundleUrl } : {},
594
- getAuthToken: () => m.resolveCurrentToken()
595
- }), r = p(null), o = p("disconnected"), c = p("__initial__"), a = (i) => {
596
- o.value = i, t.onStatus?.(i);
597
- }, d = (i) => {
598
- t.onError?.(i);
603
+ getAuthToken: () => d.resolveCurrentToken()
604
+ }), r = g(null), i = g("disconnected"), c = g("__initial__"), a = (o) => {
605
+ i.value = o, t.onStatus?.(o);
606
+ }, f = (o) => {
607
+ t.onError?.(o);
599
608
  };
600
- let l = !0;
601
- const j = t.onDiagnostic ? ae(t.onDiagnostic) : void 0, m = new Me({
609
+ let u = !0;
610
+ const p = t.onDiagnostic ? q(t.onDiagnostic) : void 0, d = new $e({
602
611
  url: t.serverUrl,
603
612
  token: t.token,
604
613
  ...t.scene !== void 0 ? { scene: t.scene } : {},
605
614
  ...t.testSession !== void 0 ? { session: t.testSession } : {},
606
615
  onStatus: a,
607
- onSnapshot: (i) => {
608
- l && (C(
616
+ onSnapshot: (o) => {
617
+ u && (H(
609
618
  n,
610
619
  r,
611
620
  c,
612
- i.scene_id,
613
- i.scene_version,
614
- () => Se(e, i),
615
- d
621
+ o.scene_id,
622
+ o.scene_version,
623
+ () => Ae(e, o),
624
+ f
616
625
  ), t.onMetric?.({
617
626
  name: "snapshot_received",
618
- scene_id: i.scene_id,
619
- path_count: Object.keys(i.state).length
627
+ scene_id: o.scene_id,
628
+ path_count: Object.keys(o.state).length
620
629
  }));
621
630
  },
622
- onDelta: (i) => {
623
- if (!l) return;
624
- const v = performance.now();
625
- we(e, i), t.onMetric?.({
631
+ onDelta: (o) => {
632
+ if (!u) return;
633
+ const y = performance.now();
634
+ Ie(e, o), t.onMetric?.({
626
635
  name: "delta_applied",
627
- duration_ms: performance.now() - v
628
- }), t.onMetric?.({ name: "delta_received", count: 1, path_count: i.patches.length });
636
+ duration_ms: performance.now() - y
637
+ }), t.onMetric?.({ name: "delta_received", count: 1, path_count: o.patches.length });
629
638
  },
630
- onSceneChanged: (i) => {
631
- l && t.onMetric?.({
639
+ onSceneChanged: (o) => {
640
+ u && t.onMetric?.({
632
641
  name: "scene_changed",
633
642
  from: r.value?.scene_version ?? null,
634
- to: i.scene_version
643
+ to: o.scene_version
635
644
  });
636
645
  },
637
- onServerError: (i) => {
638
- d({
639
- code: i.code,
640
- message: i.message,
641
- recoverable: i.recoverable
646
+ onServerError: (o) => {
647
+ f({
648
+ code: o.code,
649
+ message: o.message,
650
+ recoverable: o.recoverable
642
651
  });
643
652
  },
644
- onTransportError: (i) => {
645
- d($e(i));
653
+ onTransportError: (o) => {
654
+ f(Ce(o));
646
655
  }
647
656
  });
648
- m.start();
649
- const w = B(t.target);
650
- return w.render(
651
- G(oe, {
657
+ d.start();
658
+ const _ = D(t.target);
659
+ return _.render(
660
+ J(he, {
652
661
  mode: t.mode,
653
662
  store: e,
654
663
  bundleSignal: r,
655
- statusSignal: o,
664
+ statusSignal: i,
656
665
  crossfadeKeySignal: c,
657
- sendInput: (i) => m.sendInput(i)
666
+ sendInput: (o) => d.sendInput(o),
667
+ // ADR 004 §A1.3 — thread the host capture resolver to the runtime context
668
+ // so the `x-zab.capture` primitive's ACQUIRE mode can pin a device.
669
+ ...t.resolveCaptureDevice !== void 0 ? { resolveCaptureDevice: t.resolveCaptureDevice } : {}
658
670
  })
659
671
  ), {
660
672
  disconnect() {
661
- l && (l = !1, j?.(), m.close(), w.unmount());
673
+ u && (u = !1, p?.(), d.close(), _.unmount());
662
674
  },
663
- setToken(i) {
664
- l && m.setToken(i);
675
+ setToken(o) {
676
+ u && d.setToken(o);
665
677
  }
666
678
  };
667
- async function C(i, v, D, S, _, F, q) {
668
- let E;
679
+ async function H(o, y, G, E, I, X, Y) {
680
+ let A;
669
681
  try {
670
- E = await i.get(S, _);
671
- } catch (I) {
672
- q({
682
+ A = await o.get(E, I);
683
+ } catch (R) {
684
+ Y({
673
685
  code: "BUNDLE_FETCH_FAILED",
674
- message: I instanceof Error ? I.message : "render bundle fetch failed",
686
+ message: R instanceof Error ? R.message : "render bundle fetch failed",
675
687
  recoverable: !0
676
688
  });
677
689
  return;
678
690
  }
679
- l && (F(), v.value = E, D.value = `${S}::${_}`);
691
+ u && (X(), y.value = A, G.value = `${E}::${I}`);
680
692
  }
681
693
  }
682
- function $e(t) {
694
+ function Ce(t) {
683
695
  return {
684
696
  code: t.code,
685
697
  message: t.message,
686
698
  recoverable: t.recoverable
687
699
  };
688
700
  }
689
- function je(t) {
701
+ function Fe(t) {
690
702
  try {
691
703
  const e = new URL(t);
692
704
  return `${e.protocol === "wss:" ? "https:" : "http:"}//${e.host}`;
@@ -694,7 +706,7 @@ function je(t) {
694
706
  return "";
695
707
  }
696
708
  }
697
- const Ce = [
709
+ const qe = [
698
710
  "visible",
699
711
  "opacity",
700
712
  "universal_opacity",
@@ -711,13 +723,13 @@ const Ce = [
711
723
  // compiler and consumed by the Tree (built into a `<mask>` SVG element).
712
724
  "mask"
713
725
  ];
714
- function u(t) {
715
- return /* @__PURE__ */ new Set([...Ce, ...t]);
726
+ function l(t) {
727
+ return /* @__PURE__ */ new Set([...qe, ...t]);
716
728
  }
717
- const De = {
718
- stack: u(["direction", "gap", "wrap", "crossGap", "align", "justify"]),
719
- grid: u(["cols", "rows", "gap"]),
720
- frame: u([
729
+ const Be = {
730
+ stack: l(["direction", "gap", "wrap", "crossGap", "align", "justify"]),
731
+ grid: l(["cols", "rows", "gap"]),
732
+ frame: l([
721
733
  "x",
722
734
  "y",
723
735
  "width",
@@ -728,7 +740,7 @@ const De = {
728
740
  "backgrounds",
729
741
  "clipsContent"
730
742
  ]),
731
- text: u([
743
+ text: l([
732
744
  "value",
733
745
  "size",
734
746
  "font",
@@ -742,8 +754,8 @@ const De = {
742
754
  "fontStyle",
743
755
  "maxLines"
744
756
  ]),
745
- image: u(["src", "alt", "fit", "position", "width", "height"]),
746
- shape: u([
757
+ image: l(["src", "alt", "fit", "position", "width", "height"]),
758
+ shape: l([
747
759
  "geometry",
748
760
  "kind",
749
761
  "width",
@@ -758,18 +770,23 @@ const De = {
758
770
  "paths",
759
771
  "ariaLabel"
760
772
  ]),
761
- media: u(["src", "loop", "mute", "autoplay", "fit"]),
762
- instance: u(["scene_id", "scene_version", "size", "position"]),
773
+ media: l(["src", "loop", "mute", "autoplay", "fit"]),
774
+ instance: l(["scene_id", "scene_version", "size", "position"]),
775
+ // RFC-0001 / ADR 004 — vendor capture placeholder. `width`/`height` are the
776
+ // flattened geometry (universal) ; the `x-zab.*` props are carried as
777
+ // metadata (the renderer reserves the box, ignores deviceRef). Listed so
778
+ // they are NOT flagged as silent drops by the anti-drop audit.
779
+ "x-zab.capture": l(["x-zab.sourceKind", "x-zab.deviceRef", "width", "height"]),
763
780
  // `repeat` is dispatched specially by the tree ; its only consumed
764
781
  // binding is `items`.
765
782
  repeat: /* @__PURE__ */ new Set(["items"])
766
783
  };
767
- function Fe(t, e) {
768
- const s = De[t];
784
+ function We(t, e) {
785
+ const s = Be[t];
769
786
  return !!(s === void 0 || s.has(e) || t === "instance" && (e === "params" || e.startsWith("params.")));
770
787
  }
771
788
  const M = /* @__PURE__ */ new WeakSet();
772
- function et(t) {
789
+ function ot(t) {
773
790
  if (M.has(t)) return;
774
791
  M.add(t);
775
792
  const e = /* @__PURE__ */ new Set([
@@ -777,30 +794,110 @@ function et(t) {
777
794
  ...Object.keys(t.bindings ?? {})
778
795
  ]);
779
796
  for (const s of e)
780
- Fe(t.kind, s) || $(
797
+ We(t.kind, s) || B(
781
798
  t.id,
782
799
  `${t.kind}.${s}`,
783
800
  "is not consumed by this primitive's renderer ; the prop is ignored (anti-silent-drop, ADR 001 §3.4)"
784
801
  );
785
802
  }
803
+ const ze = { width: 1920, height: 1080 }, He = () => {
804
+ };
805
+ function ct(t) {
806
+ const e = t.stage ?? ze, s = t.target;
807
+ s.style.position ||= "relative", s.style.width = `${e.width}px`, s.style.height = `${e.height}px`, s.style.overflow = "hidden";
808
+ const n = t.onDiagnostic ? q(t.onDiagnostic) : void 0, r = W();
809
+ r.reset(t.defaults ?? {});
810
+ const i = D(s);
811
+ return {
812
+ ready: new Promise((a) => {
813
+ import("./broadcast-ryjLRD5q.js").then(({ BroadcastMode: f }) => {
814
+ i.render(
815
+ /* @__PURE__ */ h(Q, { children: /* @__PURE__ */ h(
816
+ F,
817
+ {
818
+ value: {
819
+ mode: "broadcast",
820
+ store: r,
821
+ bundle: t.bundle,
822
+ status: "live",
823
+ sendInput: He
824
+ },
825
+ children: /* @__PURE__ */ h(f, {})
826
+ }
827
+ ) })
828
+ );
829
+ const u = new Promise((d) => {
830
+ requestAnimationFrame(() => requestAnimationFrame(() => d()));
831
+ }), p = typeof document < "u" && document.fonts ? document.fonts.ready.then(() => {
832
+ }) : Promise.resolve();
833
+ Promise.all([u, p]).then(() => a());
834
+ });
835
+ }),
836
+ unmount() {
837
+ n?.(), i.unmount();
838
+ }
839
+ };
840
+ }
841
+ function z(t, e) {
842
+ if (typeof t != "string") return t;
843
+ if (e[t]) return e[t];
844
+ const s = /^assets\/([A-Za-z0-9]+)\.[A-Za-z0-9]+$/.exec(t);
845
+ return s && s[1] !== void 0 && e[s[1]] ? e[s[1]] : t;
846
+ }
847
+ function $(t, e) {
848
+ if (t === null || typeof t != "object") return;
849
+ if (Array.isArray(t)) {
850
+ for (const n of t) $(n, e);
851
+ return;
852
+ }
853
+ const s = t;
854
+ "src" in s && (s.src = z(s.src, e));
855
+ for (const n of Object.values(s))
856
+ n && typeof n == "object" && $(n, e);
857
+ }
858
+ function at(t, e) {
859
+ const s = { ...t };
860
+ for (const [n, r] of Object.entries(s))
861
+ n.startsWith("__lit.image.") && (s[n] = z(r, e));
862
+ return s;
863
+ }
864
+ async function ut(t) {
865
+ const e = [];
866
+ for (const s of t)
867
+ try {
868
+ const n = new FontFace(s.family, s.src, {
869
+ weight: String(s.weight),
870
+ style: s.style ?? "normal"
871
+ });
872
+ await n.load(), document.fonts.add(n), e.push(s.family);
873
+ } catch {
874
+ }
875
+ return e;
876
+ }
786
877
  export {
787
- ce as A,
788
- L as B,
789
- Ke as F,
790
- De as P,
791
- Ie as S,
878
+ fe as A,
879
+ U as B,
880
+ tt as F,
881
+ Be as P,
882
+ Oe as S,
792
883
  et as a,
793
- ae as b,
794
- O as c,
795
- Ve as d,
796
- $ as e,
797
- Oe as i,
798
- Ze as m,
799
- Qe as r,
800
- me as s,
801
- Je as t,
802
- Ye as u,
803
- U as v,
804
- pe as w
884
+ ot as b,
885
+ N as c,
886
+ q as d,
887
+ B as e,
888
+ xe as f,
889
+ it as g,
890
+ ct as h,
891
+ ut as i,
892
+ z as j,
893
+ at as k,
894
+ $ as l,
895
+ rt as m,
896
+ nt as r,
897
+ be as s,
898
+ st as t,
899
+ Ve as u,
900
+ P as v,
901
+ ye as w
805
902
  };
806
- //# sourceMappingURL=index-C6viWFcT.js.map
903
+ //# sourceMappingURL=index-DrXsLYhe.js.map