@lumencast/runtime 0.4.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.
Files changed (130) hide show
  1. package/README.md +57 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/animate/frame-coalescer.d.ts +13 -0
  4. package/dist/animate/frame-coalescer.d.ts.map +1 -0
  5. package/dist/animate/frame-coalescer.js +46 -0
  6. package/dist/animate/frame-coalescer.js.map +1 -0
  7. package/dist/animate/keyframes.d.ts +1 -1
  8. package/dist/animate/keyframes.d.ts.map +1 -1
  9. package/dist/animate/keyframes.js +20 -6
  10. package/dist/animate/keyframes.js.map +1 -1
  11. package/dist/animate/transitions.d.ts +4 -1
  12. package/dist/animate/transitions.d.ts.map +1 -1
  13. package/dist/animate/transitions.js +30 -3
  14. package/dist/animate/transitions.js.map +1 -1
  15. package/dist/{broadcast-DzZ8TVGZ.js → broadcast-3vYij4k-.js} +3 -3
  16. package/dist/{broadcast-DzZ8TVGZ.js.map → broadcast-3vYij4k-.js.map} +1 -1
  17. package/dist/{control-gbDGvdR0.js → control-BFNkY7-6.js} +4 -4
  18. package/dist/{control-gbDGvdR0.js.map → control-BFNkY7-6.js.map} +1 -1
  19. package/dist/{index-oteiocFe.js → index-CyOlpZAL.js} +305 -150
  20. package/dist/index-CyOlpZAL.js.map +1 -0
  21. package/dist/index.d.ts +5 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.html +1 -1
  24. package/dist/index.js +10 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/lumencast.js +9 -2
  27. package/dist/mount.d.ts.map +1 -1
  28. package/dist/mount.js +11 -1
  29. package/dist/mount.js.map +1 -1
  30. package/dist/render/bind-animate.d.ts +40 -0
  31. package/dist/render/bind-animate.d.ts.map +1 -0
  32. package/dist/render/bind-animate.js +329 -0
  33. package/dist/render/bind-animate.js.map +1 -0
  34. package/dist/render/bundle.d.ts +48 -6
  35. package/dist/render/bundle.d.ts.map +1 -1
  36. package/dist/render/bundle.js +71 -4
  37. package/dist/render/bundle.js.map +1 -1
  38. package/dist/render/color-interp.d.ts +18 -0
  39. package/dist/render/color-interp.d.ts.map +1 -0
  40. package/dist/render/color-interp.js +303 -0
  41. package/dist/render/color-interp.js.map +1 -0
  42. package/dist/render/css-color.d.ts +16 -0
  43. package/dist/render/css-color.d.ts.map +1 -0
  44. package/dist/render/css-color.js +130 -0
  45. package/dist/render/css-color.js.map +1 -0
  46. package/dist/render/diagnostics.d.ts +26 -0
  47. package/dist/render/diagnostics.d.ts.map +1 -0
  48. package/dist/render/diagnostics.js +58 -0
  49. package/dist/render/diagnostics.js.map +1 -0
  50. package/dist/render/fill.d.ts +15 -3
  51. package/dist/render/fill.d.ts.map +1 -1
  52. package/dist/render/fill.js +81 -14
  53. package/dist/render/fill.js.map +1 -1
  54. package/dist/render/filter-clamp.d.ts +35 -0
  55. package/dist/render/filter-clamp.d.ts.map +1 -0
  56. package/dist/render/filter-clamp.js +90 -0
  57. package/dist/render/filter-clamp.js.map +1 -0
  58. package/dist/render/keyframe-player.d.ts +4 -1
  59. package/dist/render/keyframe-player.d.ts.map +1 -1
  60. package/dist/render/keyframe-player.js +2 -2
  61. package/dist/render/keyframe-player.js.map +1 -1
  62. package/dist/render/primitives/frame.d.ts +16 -1
  63. package/dist/render/primitives/frame.d.ts.map +1 -1
  64. package/dist/render/primitives/frame.js +42 -7
  65. package/dist/render/primitives/frame.js.map +1 -1
  66. package/dist/render/primitives/image.d.ts +1 -1
  67. package/dist/render/primitives/image.d.ts.map +1 -1
  68. package/dist/render/primitives/image.js +6 -3
  69. package/dist/render/primitives/image.js.map +1 -1
  70. package/dist/render/primitives/index.d.ts +3 -0
  71. package/dist/render/primitives/index.d.ts.map +1 -1
  72. package/dist/render/primitives/index.js.map +1 -1
  73. package/dist/render/primitives/instance.d.ts +1 -1
  74. package/dist/render/primitives/instance.d.ts.map +1 -1
  75. package/dist/render/primitives/instance.js +10 -13
  76. package/dist/render/primitives/instance.js.map +1 -1
  77. package/dist/render/primitives/shape.d.ts +9 -3
  78. package/dist/render/primitives/shape.d.ts.map +1 -1
  79. package/dist/render/primitives/shape.js +56 -12
  80. package/dist/render/primitives/shape.js.map +1 -1
  81. package/dist/render/primitives/text.d.ts +35 -4
  82. package/dist/render/primitives/text.d.ts.map +1 -1
  83. package/dist/render/primitives/text.js +179 -7
  84. package/dist/render/primitives/text.js.map +1 -1
  85. package/dist/render/prop-allowlist.d.ts +10 -0
  86. package/dist/render/prop-allowlist.d.ts.map +1 -0
  87. package/dist/render/prop-allowlist.js +112 -0
  88. package/dist/render/prop-allowlist.js.map +1 -0
  89. package/dist/render/svg-path.d.ts +35 -0
  90. package/dist/render/svg-path.d.ts.map +1 -0
  91. package/dist/render/svg-path.js +211 -0
  92. package/dist/render/svg-path.js.map +1 -0
  93. package/dist/render/tree.d.ts.map +1 -1
  94. package/dist/render/tree.js +30 -5
  95. package/dist/render/tree.js.map +1 -1
  96. package/dist/{status-pill-Cgdl9FtP.js → status-pill-DIpXc5du.js} +2 -2
  97. package/dist/{status-pill-Cgdl9FtP.js.map → status-pill-DIpXc5du.js.map} +1 -1
  98. package/dist/{test-CAnkHA0n.js → test-ByRec1kd.js} +4 -4
  99. package/dist/{test-CAnkHA0n.js.map → test-ByRec1kd.js.map} +1 -1
  100. package/dist/tree-D5wYHpPu.js +1230 -0
  101. package/dist/tree-D5wYHpPu.js.map +1 -0
  102. package/dist/types.d.ts +26 -0
  103. package/dist/types.d.ts.map +1 -1
  104. package/package.json +5 -4
  105. package/src/animate/frame-coalescer.ts +63 -0
  106. package/src/animate/keyframes.ts +24 -5
  107. package/src/animate/transitions.ts +33 -3
  108. package/src/index.ts +24 -0
  109. package/src/mount.ts +12 -1
  110. package/src/render/bind-animate.tsx +370 -0
  111. package/src/render/bundle.ts +102 -10
  112. package/src/render/color-interp.ts +303 -0
  113. package/src/render/css-color.ts +145 -0
  114. package/src/render/diagnostics.ts +75 -0
  115. package/src/render/fill.tsx +85 -14
  116. package/src/render/filter-clamp.ts +99 -0
  117. package/src/render/keyframe-player.tsx +10 -2
  118. package/src/render/primitives/frame.tsx +47 -7
  119. package/src/render/primitives/image.tsx +6 -2
  120. package/src/render/primitives/index.ts +3 -0
  121. package/src/render/primitives/instance.tsx +14 -15
  122. package/src/render/primitives/shape.tsx +76 -12
  123. package/src/render/primitives/text.tsx +224 -7
  124. package/src/render/prop-allowlist.ts +119 -0
  125. package/src/render/svg-path.ts +215 -0
  126. package/src/render/tree.tsx +41 -6
  127. package/src/types.ts +27 -0
  128. package/dist/index-oteiocFe.js.map +0 -1
  129. package/dist/tree-DVYXwItH.js +0 -512
  130. package/dist/tree-DVYXwItH.js.map +0 -1
@@ -1,100 +1,148 @@
1
- import { batch as k, signal as d } from "@preact/signals-react";
2
- import { createRoot as U } from "react-dom/client";
3
- import { createContext as P, useContext as $, lazy as b, Suspense as j, createElement as x } from "react";
4
- import { jsx as l } from "react/jsx-runtime";
5
- import { useSignals as C } from "@preact/signals-react/runtime";
6
- import { AnimatePresence as q, motion as D } from "framer-motion";
7
- import { SequenceTracker as W, encodeFrame as _, input as B, WS_SUBPROTOCOLS as F, WS_SUBPROTOCOL_V1_1 as H, subscribe as z, decodeServerFrame as G, LumencastError as I } from "@lumencast/protocol";
8
- const O = P(null);
9
- function K({
1
+ import { batch as y, signal as d } from "@preact/signals-react";
2
+ import { createRoot as q } from "react-dom/client";
3
+ import { createContext as B, useContext as W, lazy as S, Suspense as H, createElement as z } from "react";
4
+ import { jsx as h } from "react/jsx-runtime";
5
+ import { useSignals as G } from "@preact/signals-react/runtime";
6
+ import { AnimatePresence as X, motion as Y } from "framer-motion";
7
+ import { SequenceTracker as K, encodeFrame as R, input as J, WS_SUBPROTOCOLS as Q, WS_SUBPROTOCOL_V1_1 as Z, subscribe as V, decodeServerFrame as ee, LumencastError as A } from "@lumencast/protocol";
8
+ const M = B(null);
9
+ function te({
10
10
  value: t,
11
11
  children: e
12
12
  }) {
13
- return /* @__PURE__ */ l(O.Provider, { value: t, children: e });
13
+ return /* @__PURE__ */ h(M.Provider, { value: t, children: e });
14
14
  }
15
- function Ie() {
16
- const t = $(O);
15
+ function Ye() {
16
+ const t = W(M);
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 Y = b(
24
- () => import("./broadcast-DzZ8TVGZ.js").then((t) => ({ default: t.BroadcastMode }))
25
- ), J = b(
26
- () => import("./control-gbDGvdR0.js").then((t) => ({ default: t.ControlMode }))
27
- ), Q = b(() => import("./test-CAnkHA0n.js").then((t) => ({ default: t.TestMode })));
28
- function X({
23
+ const se = S(
24
+ () => import("./broadcast-3vYij4k-.js").then((t) => ({ default: t.BroadcastMode }))
25
+ ), ne = S(
26
+ () => import("./control-BFNkY7-6.js").then((t) => ({ default: t.ControlMode }))
27
+ ), re = S(() => import("./test-ByRec1kd.js").then((t) => ({ default: t.TestMode })));
28
+ function ie({
29
29
  mode: t,
30
30
  store: e,
31
31
  bundleSignal: s,
32
32
  statusSignal: n,
33
33
  crossfadeKeySignal: r,
34
- sendInput: c
34
+ sendInput: i
35
35
  }) {
36
- C();
37
- const i = s.value, m = n.value, h = r.value;
38
- if (!i) return null;
39
- const a = t === "broadcast" ? Y : t === "control" ? J : Q;
40
- return /* @__PURE__ */ l(q, { mode: "sync", children: /* @__PURE__ */ l(
41
- D.div,
36
+ G();
37
+ const c = s.value, b = n.value, f = r.value;
38
+ if (!c) return null;
39
+ const a = t === "broadcast" ? se : t === "control" ? ne : re;
40
+ return /* @__PURE__ */ h(X, { mode: "sync", children: /* @__PURE__ */ h(
41
+ Y.div,
42
42
  {
43
43
  initial: { opacity: 0 },
44
44
  animate: { opacity: 1 },
45
45
  exit: { opacity: 0 },
46
46
  transition: { duration: 0.4, ease: "easeInOut" },
47
47
  style: { position: "absolute", inset: 0 },
48
- children: /* @__PURE__ */ l(
49
- K,
48
+ children: /* @__PURE__ */ h(
49
+ te,
50
50
  {
51
51
  value: {
52
52
  mode: t,
53
53
  store: e,
54
- bundle: i,
55
- status: m,
56
- sendInput: c
54
+ bundle: c,
55
+ status: b,
56
+ sendInput: i
57
57
  },
58
- children: /* @__PURE__ */ l(j, { fallback: null, children: /* @__PURE__ */ l(a, {}) })
58
+ children: /* @__PURE__ */ h(H, { fallback: null, children: /* @__PURE__ */ h(a, {}) })
59
59
  }
60
60
  )
61
61
  },
62
- h
62
+ f
63
63
  ) });
64
64
  }
65
- const Z = { duration: 0 }, V = {
65
+ const oe = "<anon>", g = /* @__PURE__ */ new Set();
66
+ function ce(t) {
67
+ return g.add(t), () => {
68
+ g.delete(t);
69
+ };
70
+ }
71
+ function P(t, e, s) {
72
+ const n = { nodeId: t ?? oe, field: e, reason: s };
73
+ if (g.size > 0) {
74
+ for (const r of g)
75
+ try {
76
+ r(n);
77
+ } catch {
78
+ }
79
+ return;
80
+ }
81
+ }
82
+ const ae = 100, le = 4, ue = 64, he = {
83
+ blur: ae,
84
+ brightness: le
85
+ };
86
+ function O(t, e) {
87
+ if (typeof e != "number" || !Number.isFinite(e) || e < 0 || Object.is(e, -0)) return null;
88
+ const s = he[t];
89
+ return e > s ? s : e;
90
+ }
91
+ const fe = /^blur\((\d{1,7}(?:\.\d{1,4})?)px\) brightness\((\d{1,7}(?:\.\d{1,4})?)\)$/, Ke = "blur(0px) brightness(1)";
92
+ function de(t) {
93
+ if (typeof t != "string" || t.length === 0 || t.length > ue) return null;
94
+ const e = fe.exec(t);
95
+ if (!e) return null;
96
+ const s = O("blur", Number(e[1])), n = O("brightness", Number(e[2]));
97
+ return s === null || n === null ? null : `blur(${s}px) brightness(${n})`;
98
+ }
99
+ function me(t, e) {
100
+ P(
101
+ e,
102
+ t,
103
+ "rejected unsafe filter value : outside the R8 caps or not a finite number >= 0"
104
+ );
105
+ }
106
+ const pe = { duration: 0 }, ge = {
66
107
  linear: "linear",
67
108
  "cubic-in": "easeIn",
68
109
  "cubic-out": "easeOut",
69
110
  "cubic-in-out": "easeInOut"
70
111
  };
71
- function Re(t) {
72
- return !t || t.kind === "none" ? Z : t.kind === "tween" ? {
112
+ function Je(t) {
113
+ return !t || t.kind === "none" ? pe : t.kind === "tween" ? {
73
114
  type: "tween",
74
115
  duration: (t.duration_ms ?? 0) / 1e3,
75
- ease: t.ease ? V[t.ease] ?? "easeOut" : "easeOut"
116
+ ease: t.ease ? ge[t.ease] ?? "easeOut" : "easeOut"
76
117
  } : t.kind === "spring" ? {
77
118
  type: "spring",
78
119
  ...t.stiffness !== void 0 ? { stiffness: t.stiffness } : {},
79
- ...t.damping !== void 0 ? { damping: t.damping } : {}
120
+ ...t.damping !== void 0 ? { damping: t.damping } : {},
121
+ ...t.mass !== void 0 ? { mass: t.mass } : {}
80
122
  } : {
81
123
  type: "tween",
82
124
  duration: (t.duration_ms ?? 400) / 1e3,
83
125
  ease: "easeInOut"
84
126
  };
85
127
  }
86
- const ee = {
128
+ const be = {
87
129
  opacity: 1,
88
130
  scale: 1,
131
+ scaleX: 1,
132
+ scaleY: 1,
89
133
  rotate: 0,
90
134
  x: 0,
91
- y: 0
92
- }, te = {
135
+ y: 0,
136
+ // LSML §6.1 filter identity — both functions are always present so
137
+ // framer interpolates between structurally-identical filter lists
138
+ // (the compiler emits the same two-function form, clamped per R8).
139
+ filter: "blur(0px) brightness(1)"
140
+ }, ve = {
93
141
  kind: "tween",
94
142
  duration_ms: 400,
95
143
  ease: "cubic-out"
96
144
  };
97
- function Oe(t, e, s) {
145
+ function Qe(t, e, s) {
98
146
  for (const n of e) {
99
147
  const r = t(n);
100
148
  if (r !== void 0) return r;
@@ -104,49 +152,54 @@ function Oe(t, e, s) {
104
152
  const r = t(n);
105
153
  if (r !== void 0) return r;
106
154
  }
107
- return te;
155
+ return ve;
108
156
  }
109
157
  }
110
- function Ae(t, e) {
158
+ function Ze(t, e, s) {
111
159
  if (!e || Object.keys(e).length === 0)
112
160
  return { initial: t, animate: t };
113
- const s = { ...t };
114
- for (const n of Object.keys(e))
115
- n in s || (s[n] = ee[n] ?? 0);
116
- return { initial: e, animate: s };
161
+ let n = e;
162
+ if (e.filter !== void 0) {
163
+ const i = de(e.filter);
164
+ n = { ...e }, i === null ? (me("animate_initial.filter", s), delete n.filter) : n.filter = i;
165
+ }
166
+ const r = { ...t };
167
+ for (const i of Object.keys(n))
168
+ i in r || (r[i] = be[i] ?? 0);
169
+ return { initial: n, animate: r };
117
170
  }
118
- function se(t) {
171
+ function ke(t) {
119
172
  if (typeof t != "object" || t === null) return;
120
173
  const e = t, s = e.kind;
121
174
  if (s === "snap")
122
175
  return { kind: "none" };
123
176
  if (s === "tween") {
124
- const n = typeof e.duration_ms == "number" ? e.duration_ms : 0, r = ne[e.easing] ?? "cubic-out";
177
+ const n = typeof e.duration_ms == "number" ? e.duration_ms : 0, r = ye[e.easing] ?? "cubic-out";
125
178
  return { kind: "tween", duration_ms: n, ease: r };
126
179
  }
127
180
  if (s === "spring") {
128
181
  const n = { kind: "spring" };
129
- return typeof e.stiffness == "number" && (n.stiffness = e.stiffness), typeof e.damping == "number" && (n.damping = e.damping), n;
182
+ 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;
130
183
  }
131
184
  }
132
- const ne = {
185
+ const ye = {
133
186
  linear: "linear",
134
187
  "ease-in": "cubic-in",
135
188
  "ease-out": "cubic-out",
136
189
  "ease-in-out": "cubic-in-out"
137
190
  };
138
- function re(t, e) {
139
- k(() => {
191
+ function Se(t, e) {
192
+ y(() => {
140
193
  for (const s of e.patches) {
141
- const n = se(s.transition);
194
+ const n = ke(s.transition);
142
195
  n !== void 0 ? t.setWithTransition(s.path, s.value, n) : t.set(s.path, s.value);
143
196
  }
144
197
  });
145
198
  }
146
- function oe(t, e) {
199
+ function we(t, e) {
147
200
  t.reset(e.state);
148
201
  }
149
- class ie {
202
+ class Te {
150
203
  signals = /* @__PURE__ */ new Map();
151
204
  transitions = /* @__PURE__ */ new Map();
152
205
  signal(e) {
@@ -159,25 +212,25 @@ class ie {
159
212
  }
160
213
  set(e, s) {
161
214
  const n = this.signal(e);
162
- v(n.peek(), s) || (n.value = s);
215
+ k(n.peek(), s) || (n.value = s);
163
216
  }
164
217
  setWithTransition(e, s, n) {
165
- k(() => {
218
+ y(() => {
166
219
  const r = this.transitionSignal(e);
167
220
  r.peek() !== n && (r.value = n);
168
- const c = this.signal(e);
169
- v(c.peek(), s) || (c.value = s);
221
+ const i = this.signal(e);
222
+ k(i.peek(), s) || (i.value = s);
170
223
  });
171
224
  }
172
225
  reset(e) {
173
- k(() => {
226
+ y(() => {
174
227
  const s = /* @__PURE__ */ new Set();
175
228
  for (const [n, r] of Object.entries(e)) {
176
229
  s.add(n);
177
- const c = this.signal(n);
178
- v(c.peek(), r) || (c.value = r);
179
- const i = this.transitions.get(n);
180
- i && i.peek() !== void 0 && (i.value = void 0);
230
+ const i = this.signal(n);
231
+ k(i.peek(), r) || (i.value = r);
232
+ const c = this.transitions.get(n);
233
+ c && c.peek() !== void 0 && (c.value = void 0);
181
234
  }
182
235
  for (const n of this.signals.keys())
183
236
  if (!s.has(n)) {
@@ -193,28 +246,34 @@ class ie {
193
246
  return e;
194
247
  }
195
248
  }
196
- function ce() {
197
- return new ie();
249
+ function _e() {
250
+ return new Te();
198
251
  }
199
- function v(t, e) {
252
+ function k(t, e) {
200
253
  if (t === e) return !0;
201
254
  if (t === null || e === null || typeof t != typeof e || typeof t != "object" || Array.isArray(t) !== Array.isArray(e)) return !1;
202
255
  if (Array.isArray(t) && Array.isArray(e)) {
203
256
  if (t.length !== e.length) return !1;
204
- for (let i = 0; i < t.length; i++)
205
- if (t[i] !== e[i]) return !1;
257
+ for (let c = 0; c < t.length; c++)
258
+ if (t[c] !== e[c]) return !1;
206
259
  return !0;
207
260
  }
208
- const s = t, n = e, r = Object.keys(s), c = Object.keys(n);
209
- if (r.length !== c.length) return !1;
210
- for (const i of r)
211
- if (s[i] !== n[i]) return !1;
261
+ const s = t, n = e, r = Object.keys(s), i = Object.keys(n);
262
+ if (r.length !== i.length) return !1;
263
+ for (const c of r)
264
+ if (s[c] !== n[c]) return !1;
212
265
  return !0;
213
266
  }
214
- const ae = /* @__PURE__ */ new Set([
267
+ const Ee = /* @__PURE__ */ new Set([
215
268
  "x-lumencast.color-srgb-1.0"
216
- ]);
217
- class ue extends Error {
269
+ ]), Ie = /^x-[a-z0-9-]+(?:\.[a-z0-9-]+)*$/, Re = /^(?:0|[1-9][0-9]*)$/, N = ".authoring";
270
+ function Ae(t) {
271
+ const e = t.indexOf("/");
272
+ if (e < 0) return !1;
273
+ const s = t.slice(0, e), n = t.slice(e + 1);
274
+ return !Re.test(n) || !s.endsWith(N) ? !1 : Ie.test(s.slice(0, -N.length));
275
+ }
276
+ class L extends Error {
218
277
  code = "BUNDLE_INCOMPATIBLE";
219
278
  unsupportedProfiles;
220
279
  constructor(e) {
@@ -225,40 +284,47 @@ class ue extends Error {
225
284
  ), this.name = "BundleIncompatibleError", this.unsupportedProfiles = e;
226
285
  }
227
286
  }
228
- function R(t, e = ae) {
287
+ function U(t, e = Ee) {
229
288
  const s = t.profiles;
230
- if (!s || s.length === 0) return;
231
- const n = s.filter((r) => !e.has(r));
289
+ if (!s) return;
290
+ if (!Array.isArray(s))
291
+ throw new L(["<malformed: profiles is not an array>"]);
292
+ if (s.length === 0) return;
293
+ const n = s.filter((r) => typeof r != "string" || !Ae(r) && !e.has(r)).map((r) => typeof r == "string" ? r : "<malformed: non-string profile entry>");
232
294
  if (n.length > 0)
233
- throw new ue(n);
295
+ throw new L(n);
234
296
  }
235
- class le {
297
+ class Oe {
236
298
  cache = /* @__PURE__ */ new Map();
237
299
  baseUrl;
238
300
  pathPrefix;
301
+ resolveUrl;
239
302
  fetchImpl;
240
303
  constructor(e) {
241
- this.baseUrl = e.baseUrl.replace(/\/$/, ""), this.pathPrefix = (e.pathPrefix ?? "/lsdp/v1/scenes").replace(/\/$/, ""), this.fetchImpl = e.fetchImpl ?? globalThis.fetch.bind(globalThis);
304
+ this.baseUrl = e.baseUrl.replace(/\/$/, ""), this.pathPrefix = (e.pathPrefix ?? "/lsdp/v1/scenes").replace(/\/$/, ""), this.resolveUrl = e.resolveUrl, this.fetchImpl = e.fetchImpl ?? globalThis.fetch.bind(globalThis);
305
+ }
306
+ buildUrl(e, s) {
307
+ return this.resolveUrl ? this.resolveUrl(e, s) : `${this.baseUrl}${this.pathPrefix}/${encodeURIComponent(e)}/bundle?v=${encodeURIComponent(s)}`;
242
308
  }
243
309
  preload(e) {
244
- R(e), this.cache.set(e.scene_version, e);
310
+ U(e), this.cache.set(e.scene_version, e);
245
311
  }
246
312
  async get(e, s) {
247
313
  const n = this.cache.get(s);
248
314
  if (n) return n;
249
- const r = `${this.baseUrl}${this.pathPrefix}/${encodeURIComponent(e)}/bundle?v=${encodeURIComponent(s)}`, c = await this.fetchImpl(r);
250
- if (!c.ok)
251
- throw new Error(`bundle fetch failed: ${c.status} ${c.statusText}`);
252
- const i = await c.json();
253
- if (i.scene_version !== s)
315
+ const r = this.buildUrl(e, s), i = await this.fetchImpl(r);
316
+ if (!i.ok)
317
+ throw new Error(`bundle fetch failed: ${i.status} ${i.statusText}`);
318
+ const c = await i.json();
319
+ if (c.scene_version !== s)
254
320
  throw new Error(
255
- `bundle scene_version mismatch: expected ${s}, got ${i.scene_version}`
321
+ `bundle scene_version mismatch: expected ${s}, got ${c.scene_version}`
256
322
  );
257
- return R(i), this.cache.set(s, i), i;
323
+ return U(c), this.cache.set(s, c), c;
258
324
  }
259
325
  }
260
- function he(t) {
261
- return new le(t);
326
+ function Ne(t) {
327
+ return new Oe(t);
262
328
  }
263
329
  const p = {
264
330
  initial: 200,
@@ -266,7 +332,7 @@ const p = {
266
332
  factor: 2,
267
333
  jitter: 0.2
268
334
  };
269
- class de {
335
+ class Le {
270
336
  constructor(e, s) {
271
337
  this.opts = e, this.random = s;
272
338
  }
@@ -290,7 +356,7 @@ class de {
290
356
  this._attempt = 0;
291
357
  }
292
358
  }
293
- function fe(t = {}) {
359
+ function Ue(t = {}) {
294
360
  const e = {
295
361
  initial: t.initial ?? p.initial,
296
362
  max: t.max ?? p.max,
@@ -301,7 +367,7 @@ function fe(t = {}) {
301
367
  if (e.max < e.initial) throw new RangeError("max must be >= initial");
302
368
  if (e.factor < 1) throw new RangeError("factor must be >= 1");
303
369
  if (e.jitter < 0 || e.jitter > 1) throw new RangeError("jitter must be within [0, 1]");
304
- return new de(e, t.random ?? Math.random);
370
+ return new Le(e, t.random ?? Math.random);
305
371
  }
306
372
  class u extends Error {
307
373
  recoverable;
@@ -311,14 +377,14 @@ class u extends Error {
311
377
  super(e), this.name = "TransportError", this.recoverable = s, this.code = n, this.cause = r;
312
378
  }
313
379
  }
314
- class pe {
380
+ class xe {
315
381
  status = "disconnected";
316
382
  socket = null;
317
383
  token;
318
384
  url;
319
385
  WebSocketCtor;
320
386
  schedule;
321
- seq = new W();
387
+ seq = new K();
322
388
  opts;
323
389
  scheduler;
324
390
  reconnectTimer = null;
@@ -330,7 +396,7 @@ class pe {
330
396
  throw new TypeError(
331
397
  "Lumencast WsClient: no WebSocket implementation found in this environment"
332
398
  );
333
- this.WebSocketCtor = s, this.schedule = fe(e.reconnect), this.scheduler = e.scheduler ?? {
399
+ this.WebSocketCtor = s, this.schedule = Ue(e.reconnect), this.scheduler = e.scheduler ?? {
334
400
  setTimeout: globalThis.setTimeout.bind(globalThis),
335
401
  clearTimeout: globalThis.clearTimeout.bind(globalThis)
336
402
  };
@@ -341,7 +407,7 @@ class pe {
341
407
  }
342
408
  /** Send `input` patches to the server. No-op if not connected. */
343
409
  sendInput(e) {
344
- !this.socket || this.socket.readyState !== this.WebSocketCtor.OPEN || e.length !== 0 && this.socket.send(_(B(e)));
410
+ !this.socket || this.socket.readyState !== this.WebSocketCtor.OPEN || e.length !== 0 && this.socket.send(R(J(e)));
345
411
  }
346
412
  /** Replace the auth token. Closes and reopens with the new token. */
347
413
  setToken(e) {
@@ -357,7 +423,7 @@ class pe {
357
423
  this.setStatus("connecting");
358
424
  let e;
359
425
  try {
360
- e = await me(this.token);
426
+ e = await Me(this.token);
361
427
  } catch (n) {
362
428
  this.opts.onTransportError?.(
363
429
  new u(
@@ -372,7 +438,7 @@ class pe {
372
438
  if (!this.active) return;
373
439
  let s;
374
440
  try {
375
- s = new this.WebSocketCtor(this.url, [...F]);
441
+ s = new this.WebSocketCtor(this.url, [...Q]);
376
442
  } catch (n) {
377
443
  this.opts.onTransportError?.(
378
444
  new u(
@@ -388,25 +454,25 @@ class pe {
388
454
  }
389
455
  handleOpen(e) {
390
456
  if (!this.socket) return;
391
- const n = this.socket.protocol === H && this.seq.last > 0, r = n ? this.seq.last : void 0;
457
+ const n = this.socket.protocol === Z && this.seq.last > 0, r = n ? this.seq.last : void 0;
392
458
  n || this.seq.reset();
393
- const c = z({
459
+ const i = V({
394
460
  token: e,
395
461
  ...this.opts.scene !== void 0 ? { scene: this.opts.scene } : {},
396
462
  ...this.opts.session !== void 0 ? { session: this.opts.session } : {},
397
463
  ...r !== void 0 ? { since_sequence: r } : {}
398
464
  });
399
- this.socket.send(_(c));
465
+ this.socket.send(R(i));
400
466
  }
401
467
  handleMessage(e) {
402
468
  const s = typeof e.data == "string" ? e.data : "";
403
469
  if (!s) return;
404
470
  let n;
405
471
  try {
406
- n = G(s);
472
+ n = ee(s);
407
473
  } catch (r) {
408
- const c = (r instanceof I, r.message), i = r instanceof I ? r.code : "INTERNAL";
409
- this.opts.onTransportError?.(new u(`codec: ${c}`, !0, i, r)), this.closeSocket(), this.scheduleReconnect();
474
+ const i = (r instanceof A, r.message), c = r instanceof A ? r.code : "INTERNAL";
475
+ this.opts.onTransportError?.(new u(`codec: ${i}`, !0, c, r)), this.closeSocket(), this.scheduleReconnect();
410
476
  return;
411
477
  }
412
478
  if (n !== null)
@@ -488,10 +554,10 @@ class pe {
488
554
  this.status !== e && (this.status = e, this.opts.onStatus?.(e));
489
555
  }
490
556
  }
491
- async function me(t) {
557
+ async function Me(t) {
492
558
  return typeof t == "string" ? t : await t.fetch();
493
559
  }
494
- function ge(t) {
560
+ function Pe(t) {
495
561
  if (!(t.target instanceof HTMLElement))
496
562
  throw new TypeError("mount: `target` must be an HTMLElement");
497
563
  if (typeof t.serverUrl != "string" || t.serverUrl.length === 0)
@@ -503,29 +569,32 @@ function ge(t) {
503
569
  throw new TypeError("mount: `scene` is required when mode === 'test'");
504
570
  }
505
571
  }
506
- function Le(t) {
507
- ge(t), t.onStatus?.("disconnected");
508
- const e = ce(), s = ke(t.serverUrl), n = he({ baseUrl: s }), r = d(null), c = d("disconnected"), i = d("__initial__"), m = (o) => {
509
- c.value = o, t.onStatus?.(o);
510
- }, h = (o) => {
572
+ function Ve(t) {
573
+ Pe(t), t.onStatus?.("disconnected");
574
+ const e = _e(), s = je(t.serverUrl), n = Ne({
575
+ baseUrl: s,
576
+ ...t.resolveBundleUrl !== void 0 ? { resolveUrl: t.resolveBundleUrl } : {}
577
+ }), r = d(null), i = d("disconnected"), c = d("__initial__"), b = (o) => {
578
+ i.value = o, t.onStatus?.(o);
579
+ }, f = (o) => {
511
580
  t.onError?.(o);
512
581
  };
513
582
  let a = !0;
514
- const f = new pe({
583
+ const $ = t.onDiagnostic ? ce(t.onDiagnostic) : void 0, m = new xe({
515
584
  url: t.serverUrl,
516
585
  token: t.token,
517
586
  ...t.scene !== void 0 ? { scene: t.scene } : {},
518
587
  ...t.testSession !== void 0 ? { session: t.testSession } : {},
519
- onStatus: m,
588
+ onStatus: b,
520
589
  onSnapshot: (o) => {
521
- a && (A(
590
+ a && (j(
522
591
  n,
523
592
  r,
524
- i,
593
+ c,
525
594
  o.scene_id,
526
595
  o.scene_version,
527
- () => oe(e, o),
528
- h
596
+ () => we(e, o),
597
+ f
529
598
  ), t.onMetric?.({
530
599
  name: "snapshot_received",
531
600
  scene_id: o.scene_id,
@@ -534,10 +603,10 @@ function Le(t) {
534
603
  },
535
604
  onDelta: (o) => {
536
605
  if (!a) return;
537
- const g = performance.now();
538
- re(e, o), t.onMetric?.({
606
+ const v = performance.now();
607
+ Se(e, o), t.onMetric?.({
539
608
  name: "delta_applied",
540
- duration_ms: performance.now() - g
609
+ duration_ms: performance.now() - v
541
610
  }), t.onMetric?.({ name: "delta_received", count: 1, path_count: o.patches.length });
542
611
  },
543
612
  onSceneChanged: (o) => {
@@ -548,58 +617,58 @@ function Le(t) {
548
617
  });
549
618
  },
550
619
  onServerError: (o) => {
551
- h({
620
+ f({
552
621
  code: o.code,
553
622
  message: o.message,
554
623
  recoverable: o.recoverable
555
624
  });
556
625
  },
557
626
  onTransportError: (o) => {
558
- h(ve(o));
627
+ f($e(o));
559
628
  }
560
629
  });
561
- f.start();
562
- const S = U(t.target);
563
- return S.render(
564
- x(X, {
630
+ m.start();
631
+ const w = q(t.target);
632
+ return w.render(
633
+ z(ie, {
565
634
  mode: t.mode,
566
635
  store: e,
567
636
  bundleSignal: r,
568
- statusSignal: c,
569
- crossfadeKeySignal: i,
570
- sendInput: (o) => f.sendInput(o)
637
+ statusSignal: i,
638
+ crossfadeKeySignal: c,
639
+ sendInput: (o) => m.sendInput(o)
571
640
  })
572
641
  ), {
573
642
  disconnect() {
574
- a && (a = !1, f.close(), S.unmount());
643
+ a && (a = !1, $?.(), m.close(), w.unmount());
575
644
  },
576
645
  setToken(o) {
577
- a && f.setToken(o);
646
+ a && m.setToken(o);
578
647
  }
579
648
  };
580
- async function A(o, g, L, y, T, M, N) {
581
- let w;
649
+ async function j(o, v, C, T, _, D, F) {
650
+ let E;
582
651
  try {
583
- w = await o.get(y, T);
584
- } catch (E) {
585
- N({
652
+ E = await o.get(T, _);
653
+ } catch (I) {
654
+ F({
586
655
  code: "BUNDLE_FETCH_FAILED",
587
- message: E instanceof Error ? E.message : "render bundle fetch failed",
656
+ message: I instanceof Error ? I.message : "render bundle fetch failed",
588
657
  recoverable: !0
589
658
  });
590
659
  return;
591
660
  }
592
- a && (M(), g.value = w, L.value = `${y}::${T}`);
661
+ a && (D(), v.value = E, C.value = `${T}::${_}`);
593
662
  }
594
663
  }
595
- function ve(t) {
664
+ function $e(t) {
596
665
  return {
597
666
  code: t.code,
598
667
  message: t.message,
599
668
  recoverable: t.recoverable
600
669
  };
601
670
  }
602
- function ke(t) {
671
+ function je(t) {
603
672
  try {
604
673
  const e = new URL(t);
605
674
  return `${e.protocol === "wss:" ? "https:" : "http:"}//${e.host}`;
@@ -607,11 +676,97 @@ function ke(t) {
607
676
  return "";
608
677
  }
609
678
  }
679
+ const Ce = ["visible", "opacity", "universal_opacity", "rotation", "sizing"];
680
+ function l(t) {
681
+ return /* @__PURE__ */ new Set([...Ce, ...t]);
682
+ }
683
+ const De = {
684
+ stack: l(["direction", "gap", "wrap", "crossGap", "align", "justify"]),
685
+ grid: l(["cols", "rows", "gap"]),
686
+ frame: l([
687
+ "x",
688
+ "y",
689
+ "width",
690
+ "height",
691
+ "scale",
692
+ "rotate",
693
+ "background",
694
+ "backgrounds",
695
+ "clipsContent"
696
+ ]),
697
+ text: l([
698
+ "value",
699
+ "size",
700
+ "font",
701
+ "weight",
702
+ "colour",
703
+ "align",
704
+ "lineHeight",
705
+ "letterSpacing",
706
+ "textTransform",
707
+ "textDecoration",
708
+ "fontStyle",
709
+ "maxLines"
710
+ ]),
711
+ image: l(["src", "alt", "fit", "position", "width", "height"]),
712
+ shape: l([
713
+ "geometry",
714
+ "kind",
715
+ "width",
716
+ "height",
717
+ "radius",
718
+ "fill",
719
+ "fills",
720
+ "stroke",
721
+ "stroke_width",
722
+ "strokes",
723
+ "pathData",
724
+ "paths",
725
+ "ariaLabel"
726
+ ]),
727
+ media: l(["src", "loop", "mute", "autoplay", "fit"]),
728
+ instance: l(["scene_id", "scene_version", "size", "position"]),
729
+ // `repeat` is dispatched specially by the tree ; its only consumed
730
+ // binding is `items`.
731
+ repeat: /* @__PURE__ */ new Set(["items"])
732
+ };
733
+ function Fe(t, e) {
734
+ const s = De[t];
735
+ return !!(s === void 0 || s.has(e) || t === "instance" && (e === "params" || e.startsWith("params.")));
736
+ }
737
+ const x = /* @__PURE__ */ new WeakSet();
738
+ function et(t) {
739
+ if (x.has(t)) return;
740
+ x.add(t);
741
+ const e = /* @__PURE__ */ new Set([
742
+ ...Object.keys(t.props ?? {}),
743
+ ...Object.keys(t.bindings ?? {})
744
+ ]);
745
+ for (const s of e)
746
+ Fe(t.kind, s) || P(
747
+ t.id,
748
+ `${t.kind}.${s}`,
749
+ "is not consumed by this primitive's renderer ; the prop is ignored (anti-silent-drop, ADR 001 §3.4)"
750
+ );
751
+ }
610
752
  export {
611
- Le as a,
612
- Ae as m,
613
- Oe as r,
614
- Re as t,
615
- Ie as u
753
+ oe as A,
754
+ L as B,
755
+ Ke as F,
756
+ De as P,
757
+ Ee as S,
758
+ et as a,
759
+ ce as b,
760
+ O as c,
761
+ Ve as d,
762
+ P as e,
763
+ Ae as i,
764
+ Ze as m,
765
+ Qe as r,
766
+ de as s,
767
+ Je as t,
768
+ Ye as u,
769
+ U as v,
770
+ me as w
616
771
  };
617
- //# sourceMappingURL=index-oteiocFe.js.map
772
+ //# sourceMappingURL=index-CyOlpZAL.js.map