@lumencast/runtime 0.1.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 (204) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +79 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/animate/crossfade.d.ts +13 -0
  5. package/dist/animate/crossfade.d.ts.map +1 -0
  6. package/dist/animate/crossfade.js +10 -0
  7. package/dist/animate/crossfade.js.map +1 -0
  8. package/dist/animate/keyframes.d.ts +42 -0
  9. package/dist/animate/keyframes.d.ts.map +1 -0
  10. package/dist/animate/keyframes.js +94 -0
  11. package/dist/animate/keyframes.js.map +1 -0
  12. package/dist/animate/transitions.d.ts +38 -0
  13. package/dist/animate/transitions.d.ts.map +1 -0
  14. package/dist/animate/transitions.js +81 -0
  15. package/dist/animate/transitions.js.map +1 -0
  16. package/dist/app.d.ts +16 -0
  17. package/dist/app.d.ts.map +1 -0
  18. package/dist/app.js +35 -0
  19. package/dist/app.js.map +1 -0
  20. package/dist/broadcast-BqOhSNsY.js +11 -0
  21. package/dist/broadcast-BqOhSNsY.js.map +1 -0
  22. package/dist/control-CRFn328D.js +16 -0
  23. package/dist/control-CRFn328D.js.map +1 -0
  24. package/dist/dev-entry.d.ts +2 -0
  25. package/dist/dev-entry.d.ts.map +1 -0
  26. package/dist/dev-entry.js +31 -0
  27. package/dist/dev-entry.js.map +1 -0
  28. package/dist/index-DUhPPRvw.js +583 -0
  29. package/dist/index-DUhPPRvw.js.map +1 -0
  30. package/dist/index.d.ts +4 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.html +46 -0
  33. package/dist/index.js +3 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/internal/validate-options.d.ts +5 -0
  36. package/dist/internal/validate-options.d.ts.map +1 -0
  37. package/dist/internal/validate-options.js +19 -0
  38. package/dist/internal/validate-options.js.map +1 -0
  39. package/dist/lumencast.js +5 -0
  40. package/dist/lumencast.js.map +1 -0
  41. package/dist/modes/broadcast.d.ts +3 -0
  42. package/dist/modes/broadcast.d.ts.map +1 -0
  43. package/dist/modes/broadcast.js +9 -0
  44. package/dist/modes/broadcast.js.map +1 -0
  45. package/dist/modes/control.d.ts +4 -0
  46. package/dist/modes/control.d.ts.map +1 -0
  47. package/dist/modes/control.js +12 -0
  48. package/dist/modes/control.js.map +1 -0
  49. package/dist/modes/test.d.ts +4 -0
  50. package/dist/modes/test.d.ts.map +1 -0
  51. package/dist/modes/test.js +13 -0
  52. package/dist/modes/test.js.map +1 -0
  53. package/dist/mount.d.ts +3 -0
  54. package/dist/mount.d.ts.map +1 -0
  55. package/dist/mount.js +144 -0
  56. package/dist/mount.js.map +1 -0
  57. package/dist/overlay/control.d.ts +2 -0
  58. package/dist/overlay/control.d.ts.map +1 -0
  59. package/dist/overlay/control.js +127 -0
  60. package/dist/overlay/control.js.map +1 -0
  61. package/dist/overlay/runtime-context.d.ts +20 -0
  62. package/dist/overlay/runtime-context.d.ts.map +1 -0
  63. package/dist/overlay/runtime-context.js +14 -0
  64. package/dist/overlay/runtime-context.js.map +1 -0
  65. package/dist/overlay/status-pill.d.ts +2 -0
  66. package/dist/overlay/status-pill.d.ts.map +1 -0
  67. package/dist/overlay/status-pill.js +29 -0
  68. package/dist/overlay/status-pill.js.map +1 -0
  69. package/dist/overlay/test.d.ts +5 -0
  70. package/dist/overlay/test.d.ts.map +1 -0
  71. package/dist/overlay/test.js +116 -0
  72. package/dist/overlay/test.js.map +1 -0
  73. package/dist/render/bundle.d.ts +102 -0
  74. package/dist/render/bundle.d.ts.map +1 -0
  75. package/dist/render/bundle.js +86 -0
  76. package/dist/render/bundle.js.map +1 -0
  77. package/dist/render/fill.d.ts +41 -0
  78. package/dist/render/fill.d.ts.map +1 -0
  79. package/dist/render/fill.js +95 -0
  80. package/dist/render/fill.js.map +1 -0
  81. package/dist/render/keyframe-player.d.ts +10 -0
  82. package/dist/render/keyframe-player.d.ts.map +1 -0
  83. package/dist/render/keyframe-player.js +65 -0
  84. package/dist/render/keyframe-player.js.map +1 -0
  85. package/dist/render/primitives/frame.d.ts +12 -0
  86. package/dist/render/primitives/frame.d.ts.map +1 -0
  87. package/dist/render/primitives/frame.js +65 -0
  88. package/dist/render/primitives/frame.js.map +1 -0
  89. package/dist/render/primitives/grid.d.ts +4 -0
  90. package/dist/render/primitives/grid.d.ts.map +1 -0
  91. package/dist/render/primitives/grid.js +14 -0
  92. package/dist/render/primitives/grid.js.map +1 -0
  93. package/dist/render/primitives/image.d.ts +5 -0
  94. package/dist/render/primitives/image.d.ts.map +1 -0
  95. package/dist/render/primitives/image.js +25 -0
  96. package/dist/render/primitives/image.js.map +1 -0
  97. package/dist/render/primitives/index.d.ts +10 -0
  98. package/dist/render/primitives/index.d.ts.map +1 -0
  99. package/dist/render/primitives/index.js +22 -0
  100. package/dist/render/primitives/index.js.map +1 -0
  101. package/dist/render/primitives/instance.d.ts +4 -0
  102. package/dist/render/primitives/instance.d.ts.map +1 -0
  103. package/dist/render/primitives/instance.js +35 -0
  104. package/dist/render/primitives/instance.js.map +1 -0
  105. package/dist/render/primitives/media.d.ts +6 -0
  106. package/dist/render/primitives/media.d.ts.map +1 -0
  107. package/dist/render/primitives/media.js +19 -0
  108. package/dist/render/primitives/media.js.map +1 -0
  109. package/dist/render/primitives/shape.d.ts +12 -0
  110. package/dist/render/primitives/shape.d.ts.map +1 -0
  111. package/dist/render/primitives/shape.js +66 -0
  112. package/dist/render/primitives/shape.js.map +1 -0
  113. package/dist/render/primitives/stack.d.ts +13 -0
  114. package/dist/render/primitives/stack.d.ts.map +1 -0
  115. package/dist/render/primitives/stack.js +45 -0
  116. package/dist/render/primitives/stack.js.map +1 -0
  117. package/dist/render/primitives/text.d.ts +6 -0
  118. package/dist/render/primitives/text.d.ts.map +1 -0
  119. package/dist/render/primitives/text.js +27 -0
  120. package/dist/render/primitives/text.js.map +1 -0
  121. package/dist/render/scope.d.ts +10 -0
  122. package/dist/render/scope.d.ts.map +1 -0
  123. package/dist/render/scope.js +27 -0
  124. package/dist/render/scope.js.map +1 -0
  125. package/dist/render/stagger-context.d.ts +9 -0
  126. package/dist/render/stagger-context.d.ts.map +1 -0
  127. package/dist/render/stagger-context.js +22 -0
  128. package/dist/render/stagger-context.js.map +1 -0
  129. package/dist/render/tree.d.ts +9 -0
  130. package/dist/render/tree.d.ts.map +1 -0
  131. package/dist/render/tree.js +139 -0
  132. package/dist/render/tree.js.map +1 -0
  133. package/dist/render/universal-wrapper.d.ts +16 -0
  134. package/dist/render/universal-wrapper.d.ts.map +1 -0
  135. package/dist/render/universal-wrapper.js +58 -0
  136. package/dist/render/universal-wrapper.js.map +1 -0
  137. package/dist/state/apply-delta.d.ts +11 -0
  138. package/dist/state/apply-delta.d.ts.map +1 -0
  139. package/dist/state/apply-delta.js +23 -0
  140. package/dist/state/apply-delta.js.map +1 -0
  141. package/dist/state/apply-snapshot.d.ts +6 -0
  142. package/dist/state/apply-snapshot.d.ts.map +1 -0
  143. package/dist/state/apply-snapshot.js +6 -0
  144. package/dist/state/apply-snapshot.js.map +1 -0
  145. package/dist/state/store.d.ts +28 -0
  146. package/dist/state/store.d.ts.map +1 -0
  147. package/dist/state/store.js +119 -0
  148. package/dist/state/store.js.map +1 -0
  149. package/dist/status-pill-DCHvrd_y.js +241 -0
  150. package/dist/status-pill-DCHvrd_y.js.map +1 -0
  151. package/dist/test-DBCtwx_I.js +210 -0
  152. package/dist/test-DBCtwx_I.js.map +1 -0
  153. package/dist/transport/reconnect.d.ts +22 -0
  154. package/dist/transport/reconnect.d.ts.map +1 -0
  155. package/dist/transport/reconnect.js +60 -0
  156. package/dist/transport/reconnect.js.map +1 -0
  157. package/dist/transport/ws.d.ts +66 -0
  158. package/dist/transport/ws.d.ts.map +1 -0
  159. package/dist/transport/ws.js +270 -0
  160. package/dist/transport/ws.js.map +1 -0
  161. package/dist/tree-CnhX02kd.js +494 -0
  162. package/dist/tree-CnhX02kd.js.map +1 -0
  163. package/dist/types.d.ts +38 -0
  164. package/dist/types.d.ts.map +1 -0
  165. package/dist/types.js +3 -0
  166. package/dist/types.js.map +1 -0
  167. package/package.json +64 -0
  168. package/src/animate/crossfade.tsx +31 -0
  169. package/src/animate/keyframes.ts +142 -0
  170. package/src/animate/transitions.ts +116 -0
  171. package/src/app.tsx +84 -0
  172. package/src/dev-entry.tsx +38 -0
  173. package/src/index.ts +24 -0
  174. package/src/internal/validate-options.ts +20 -0
  175. package/src/modes/broadcast.tsx +8 -0
  176. package/src/modes/control.tsx +17 -0
  177. package/src/modes/test.tsx +19 -0
  178. package/src/mount.ts +169 -0
  179. package/src/overlay/control.tsx +239 -0
  180. package/src/overlay/runtime-context.tsx +37 -0
  181. package/src/overlay/status-pill.tsx +37 -0
  182. package/src/overlay/test.tsx +213 -0
  183. package/src/render/bundle.ts +208 -0
  184. package/src/render/fill.tsx +163 -0
  185. package/src/render/keyframe-player.tsx +89 -0
  186. package/src/render/primitives/frame.tsx +78 -0
  187. package/src/render/primitives/grid.tsx +20 -0
  188. package/src/render/primitives/image.tsx +35 -0
  189. package/src/render/primitives/index.ts +35 -0
  190. package/src/render/primitives/instance.tsx +70 -0
  191. package/src/render/primitives/media.tsx +28 -0
  192. package/src/render/primitives/shape.tsx +135 -0
  193. package/src/render/primitives/stack.tsx +48 -0
  194. package/src/render/primitives/text.tsx +38 -0
  195. package/src/render/scope.tsx +27 -0
  196. package/src/render/stagger-context.tsx +24 -0
  197. package/src/render/tree.tsx +182 -0
  198. package/src/render/universal-wrapper.tsx +95 -0
  199. package/src/state/apply-delta.ts +24 -0
  200. package/src/state/apply-snapshot.ts +8 -0
  201. package/src/state/store.ts +141 -0
  202. package/src/transport/reconnect.ts +83 -0
  203. package/src/transport/ws.ts +359 -0
  204. package/src/types.ts +54 -0
@@ -0,0 +1,119 @@
1
+ // State store — one signal per leaf path.
2
+ //
3
+ // Integration point between the WS layer (snapshot + delta) and the render
4
+ // layer. Each path Lumencast has ever seen owns a `Signal<unknown>`;
5
+ // readers subscribe via @preact/signals-react `useSignals()` and re-render
6
+ // only when their path's value changes.
7
+ //
8
+ // LSDP/1.1 §3.2.2 — incoming deltas may carry a per-leaf `transition`
9
+ // directive. The store keeps the most-recent directive per path so the
10
+ // renderer can pick it up on the next animation cycle. Snapshots clear
11
+ // any pending transitions for the affected paths (snapshots are not
12
+ // animated transitions).
13
+ import { signal, batch } from "@preact/signals-react";
14
+ class StoreImpl {
15
+ signals = new Map();
16
+ transitions = new Map();
17
+ signal(path) {
18
+ let s = this.signals.get(path);
19
+ if (!s) {
20
+ s = signal(undefined);
21
+ this.signals.set(path, s);
22
+ }
23
+ return s;
24
+ }
25
+ transitionSignal(path) {
26
+ let s = this.transitions.get(path);
27
+ if (!s) {
28
+ s = signal(undefined);
29
+ this.transitions.set(path, s);
30
+ }
31
+ return s;
32
+ }
33
+ set(path, value) {
34
+ const s = this.signal(path);
35
+ if (!shallowEqual(s.peek(), value)) {
36
+ s.value = value;
37
+ }
38
+ }
39
+ setWithTransition(path, value, transition) {
40
+ batch(() => {
41
+ const ts = this.transitionSignal(path);
42
+ // Update transition before value so the render that observes the
43
+ // new value sees the correct transition.
44
+ if (ts.peek() !== transition)
45
+ ts.value = transition;
46
+ const s = this.signal(path);
47
+ if (!shallowEqual(s.peek(), value))
48
+ s.value = value;
49
+ });
50
+ }
51
+ reset(state) {
52
+ batch(() => {
53
+ const seen = new Set();
54
+ for (const [path, value] of Object.entries(state)) {
55
+ seen.add(path);
56
+ const s = this.signal(path);
57
+ if (!shallowEqual(s.peek(), value)) {
58
+ s.value = value;
59
+ }
60
+ // Snapshots are not animated transitions — clear any pending
61
+ // per-path directive (LSDP/1.1 §3.2.2 — directives apply to
62
+ // the NEXT delta only, snapshots reseed state authoritatively).
63
+ const ts = this.transitions.get(path);
64
+ if (ts && ts.peek() !== undefined)
65
+ ts.value = undefined;
66
+ }
67
+ for (const path of this.signals.keys()) {
68
+ if (!seen.has(path)) {
69
+ const s = this.signals.get(path);
70
+ if (s && s.peek() !== undefined)
71
+ s.value = undefined;
72
+ }
73
+ }
74
+ });
75
+ }
76
+ toRecord() {
77
+ const out = {};
78
+ for (const [path, s] of this.signals.entries()) {
79
+ out[path] = s.peek();
80
+ }
81
+ return out;
82
+ }
83
+ }
84
+ export function createStore() {
85
+ return new StoreImpl();
86
+ }
87
+ function shallowEqual(a, b) {
88
+ if (a === b)
89
+ return true;
90
+ if (a === null || b === null)
91
+ return false;
92
+ if (typeof a !== typeof b)
93
+ return false;
94
+ if (typeof a !== "object")
95
+ return false;
96
+ if (Array.isArray(a) !== Array.isArray(b))
97
+ return false;
98
+ if (Array.isArray(a) && Array.isArray(b)) {
99
+ if (a.length !== b.length)
100
+ return false;
101
+ for (let i = 0; i < a.length; i++) {
102
+ if (a[i] !== b[i])
103
+ return false;
104
+ }
105
+ return true;
106
+ }
107
+ const ao = a;
108
+ const bo = b;
109
+ const ak = Object.keys(ao);
110
+ const bk = Object.keys(bo);
111
+ if (ak.length !== bk.length)
112
+ return false;
113
+ for (const k of ak) {
114
+ if (ao[k] !== bo[k])
115
+ return false;
116
+ }
117
+ return true;
118
+ }
119
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/state/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,241 @@
1
+ import { jsxs as c, jsx as s } from "react/jsx-runtime";
2
+ import { useSignals as g } from "@preact/signals-react/runtime";
3
+ import { u as d } from "./index-DUhPPRvw.js";
4
+ const f = {
5
+ position: "fixed",
6
+ bottom: 12,
7
+ left: 12,
8
+ zIndex: 1e5,
9
+ width: 320,
10
+ maxHeight: "70vh",
11
+ overflowY: "auto",
12
+ padding: 12,
13
+ fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, sans-serif",
14
+ fontSize: 12,
15
+ color: "#e5e7eb",
16
+ background: "rgba(17, 24, 39, 0.92)",
17
+ border: "1px solid rgba(75, 85, 99, 0.6)",
18
+ borderRadius: 10,
19
+ boxShadow: "0 8px 32px rgba(0, 0, 0, 0.45)"
20
+ }, m = {
21
+ display: "flex",
22
+ flexDirection: "column",
23
+ gap: 4,
24
+ padding: "6px 0",
25
+ borderBottom: "1px solid rgba(75, 85, 99, 0.35)"
26
+ }, h = {
27
+ color: "#9ca3af",
28
+ fontSize: 10.5,
29
+ letterSpacing: "0.02em",
30
+ textTransform: "uppercase"
31
+ }, p = {
32
+ background: "rgba(31, 41, 55, 0.8)",
33
+ border: "1px solid rgba(75, 85, 99, 0.6)",
34
+ borderRadius: 6,
35
+ color: "#f9fafb",
36
+ padding: "4px 6px",
37
+ fontSize: 12,
38
+ width: "100%"
39
+ };
40
+ function k() {
41
+ const { bundle: o, store: t, sendInput: a } = d();
42
+ g();
43
+ const n = o.operator_inputs ?? [];
44
+ if (n.length === 0) return null;
45
+ const e = /* @__PURE__ */ new Map();
46
+ for (const r of n) {
47
+ const l = r.group ?? "General", i = e.get(l) ?? [];
48
+ i.push(r), e.set(l, i);
49
+ }
50
+ return /* @__PURE__ */ c("div", { style: f, "data-testid": "lumencast-control-panel", children: [
51
+ /* @__PURE__ */ s(
52
+ "div",
53
+ {
54
+ style: {
55
+ fontWeight: 600,
56
+ fontSize: 11,
57
+ letterSpacing: "0.06em",
58
+ color: "#9ca3af",
59
+ textTransform: "uppercase",
60
+ marginBottom: 6
61
+ },
62
+ children: "Operator inputs"
63
+ }
64
+ ),
65
+ [...e.entries()].map(([r, l]) => /* @__PURE__ */ c("div", { style: { marginBottom: 8 }, children: [
66
+ /* @__PURE__ */ s(
67
+ "div",
68
+ {
69
+ style: {
70
+ color: "#6b7280",
71
+ fontSize: 10,
72
+ letterSpacing: "0.04em",
73
+ textTransform: "uppercase",
74
+ padding: "4px 0"
75
+ },
76
+ children: r
77
+ }
78
+ ),
79
+ l.map((i) => /* @__PURE__ */ s(
80
+ b,
81
+ {
82
+ entry: i,
83
+ currentValue: t.signal(i.path).value,
84
+ onCommit: (u) => (
85
+ // Operator-control values come from form widgets typed per
86
+ // OperatorInput.type; coerce to LeafValue at the boundary.
87
+ a([
88
+ {
89
+ path: i.path,
90
+ value: u
91
+ }
92
+ ])
93
+ )
94
+ },
95
+ i.path
96
+ ))
97
+ ] }, r))
98
+ ] });
99
+ }
100
+ function b({
101
+ entry: o,
102
+ currentValue: t,
103
+ onCommit: a
104
+ }) {
105
+ return /* @__PURE__ */ c("div", { style: m, children: [
106
+ /* @__PURE__ */ s("span", { style: h, children: o.label }),
107
+ /* @__PURE__ */ s(x, { entry: o, currentValue: t, onCommit: a })
108
+ ] });
109
+ }
110
+ function x({
111
+ entry: o,
112
+ currentValue: t,
113
+ onCommit: a
114
+ }) {
115
+ switch (o.type) {
116
+ case "boolean": {
117
+ const n = t === !0;
118
+ return /* @__PURE__ */ c("label", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
119
+ /* @__PURE__ */ s("input", { type: "checkbox", checked: n, onChange: (e) => a(e.target.checked) }),
120
+ /* @__PURE__ */ s("span", { style: { fontSize: 11, color: "#d1d5db" }, children: n ? "on" : "off" })
121
+ ] });
122
+ }
123
+ case "number": {
124
+ const n = o.min, e = o.max, r = o.step;
125
+ return /* @__PURE__ */ s(
126
+ "input",
127
+ {
128
+ type: "number",
129
+ style: p,
130
+ value: typeof t == "number" ? t : "",
131
+ min: n,
132
+ max: e,
133
+ step: r,
134
+ onChange: (l) => {
135
+ const i = Number(l.target.value);
136
+ Number.isFinite(i) && a(i);
137
+ }
138
+ }
139
+ );
140
+ }
141
+ case "text": {
142
+ const n = o.max_length;
143
+ return /* @__PURE__ */ s(
144
+ "input",
145
+ {
146
+ type: "text",
147
+ style: p,
148
+ value: typeof t == "string" ? t : "",
149
+ maxLength: n,
150
+ onChange: (e) => a(e.target.value)
151
+ }
152
+ );
153
+ }
154
+ case "colour":
155
+ return /* @__PURE__ */ s(
156
+ "input",
157
+ {
158
+ type: "color",
159
+ style: p,
160
+ value: typeof t == "string" ? t : "#000000",
161
+ onChange: (n) => a(n.target.value)
162
+ }
163
+ );
164
+ case "duration":
165
+ return /* @__PURE__ */ s(
166
+ "input",
167
+ {
168
+ type: "number",
169
+ style: p,
170
+ value: typeof t == "number" ? t : "",
171
+ min: 0,
172
+ step: 100,
173
+ onChange: (n) => {
174
+ const e = Number(n.target.value);
175
+ Number.isFinite(e) && e >= 0 && a(e);
176
+ }
177
+ }
178
+ );
179
+ case "select":
180
+ case "enum": {
181
+ const n = o.enum_values ?? o.options ?? [];
182
+ return /* @__PURE__ */ s(
183
+ "select",
184
+ {
185
+ style: p,
186
+ value: typeof t == "string" ? t : "",
187
+ onChange: (e) => a(e.target.value),
188
+ children: n.map((e) => /* @__PURE__ */ s("option", { value: e, children: e }, e))
189
+ }
190
+ );
191
+ }
192
+ case "path-ref":
193
+ default:
194
+ return /* @__PURE__ */ s(
195
+ "input",
196
+ {
197
+ type: "text",
198
+ style: p,
199
+ value: typeof t == "string" ? t : "",
200
+ onChange: (n) => a(n.target.value)
201
+ }
202
+ );
203
+ }
204
+ }
205
+ const y = {
206
+ live: "rgba(34, 197, 94, 0.85)",
207
+ connecting: "rgba(234, 179, 8, 0.85)",
208
+ disconnected: "rgba(239, 68, 68, 0.85)"
209
+ }, v = {
210
+ live: "live",
211
+ connecting: "reconnecting",
212
+ disconnected: "disconnected"
213
+ };
214
+ function w() {
215
+ const { status: o } = d();
216
+ return /* @__PURE__ */ s(
217
+ "div",
218
+ {
219
+ "data-testid": "lumencast-status-pill",
220
+ style: {
221
+ position: "fixed",
222
+ top: 12,
223
+ right: 12,
224
+ padding: "4px 10px",
225
+ fontSize: 11,
226
+ fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, sans-serif",
227
+ color: "white",
228
+ background: y[o] ?? "#444",
229
+ borderRadius: 999,
230
+ userSelect: "none",
231
+ pointerEvents: "none"
232
+ },
233
+ children: v[o] ?? o
234
+ }
235
+ );
236
+ }
237
+ export {
238
+ k as C,
239
+ w as S
240
+ };
241
+ //# sourceMappingURL=status-pill-DCHvrd_y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-pill-DCHvrd_y.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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"}
@@ -0,0 +1,210 @@
1
+ import { jsxs as i, jsx as t, Fragment as y } from "react/jsx-runtime";
2
+ import { T as b } from "./tree-CnhX02kd.js";
3
+ import { S as h, C as x } from "./status-pill-DCHvrd_y.js";
4
+ import { useSignals as S } from "@preact/signals-react/runtime";
5
+ import { useState as f } from "react";
6
+ import { u } from "./index-DUhPPRvw.js";
7
+ const k = {
8
+ position: "fixed",
9
+ bottom: 12,
10
+ right: 12,
11
+ zIndex: 100001,
12
+ width: 360,
13
+ maxHeight: "70vh",
14
+ overflowY: "auto",
15
+ padding: 12,
16
+ fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, sans-serif",
17
+ fontSize: 12,
18
+ color: "#e5e7eb",
19
+ background: "rgba(8, 47, 73, 0.92)",
20
+ border: "1px solid rgba(56, 189, 248, 0.4)",
21
+ borderRadius: 10,
22
+ boxShadow: "0 8px 32px rgba(0, 0, 0, 0.45)"
23
+ }, c = {
24
+ fontWeight: 600,
25
+ fontSize: 11,
26
+ letterSpacing: "0.06em",
27
+ color: "#7dd3fc",
28
+ textTransform: "uppercase",
29
+ marginBottom: 6
30
+ }, l = {
31
+ background: "rgba(14, 165, 233, 0.4)",
32
+ border: "1px solid rgba(125, 211, 252, 0.5)",
33
+ borderRadius: 6,
34
+ color: "#f0f9ff",
35
+ padding: "3px 8px",
36
+ fontSize: 11,
37
+ cursor: "pointer"
38
+ }, v = {
39
+ display: "flex",
40
+ flexDirection: "column",
41
+ gap: 4,
42
+ padding: "6px 0",
43
+ borderBottom: "1px solid rgba(56, 189, 248, 0.2)"
44
+ };
45
+ function T() {
46
+ const { bundle: e, store: n, sendInput: o } = u();
47
+ S();
48
+ const [s, a] = f(""), p = e.external_adapters ?? [], g = n.toRecord(), m = Object.entries(g).filter(
49
+ ([r]) => s === "" || r.includes(s)
50
+ );
51
+ return /* @__PURE__ */ i("div", { style: k, "data-testid": "lumencast-test-panel", children: [
52
+ /* @__PURE__ */ t("div", { style: c, children: "Time" }),
53
+ /* @__PURE__ */ i("div", { style: { display: "flex", gap: 6, marginBottom: 8 }, children: [
54
+ /* @__PURE__ */ t(
55
+ "button",
56
+ {
57
+ type: "button",
58
+ style: l,
59
+ onClick: () => o([{ path: "__test.tick", value: 100 }]),
60
+ children: "tick +100ms"
61
+ }
62
+ ),
63
+ /* @__PURE__ */ t(
64
+ "button",
65
+ {
66
+ type: "button",
67
+ style: l,
68
+ onClick: () => o([{ path: "__test.tick", value: 1e3 }]),
69
+ children: "tick +1s"
70
+ }
71
+ ),
72
+ /* @__PURE__ */ t(
73
+ "button",
74
+ {
75
+ type: "button",
76
+ style: l,
77
+ onClick: () => o([{ path: "__test.reset", value: !0 }]),
78
+ children: "reset"
79
+ }
80
+ )
81
+ ] }),
82
+ /* @__PURE__ */ t("div", { style: c, children: "External adapters" }),
83
+ p.length === 0 && /* @__PURE__ */ t("div", { style: { color: "#94a3b8", fontStyle: "italic", fontSize: 11 }, children: "No external adapters declared in this scene." }),
84
+ p.map((r) => /* @__PURE__ */ t(
85
+ _,
86
+ {
87
+ adapter: r,
88
+ onMock: (d) => (
89
+ // LSDP/1 patch values must be leaf — JSON-encode the structured payload.
90
+ o([
91
+ {
92
+ path: "__test.mock_adapter",
93
+ value: JSON.stringify({ key: r.key, payload: d })
94
+ }
95
+ ])
96
+ )
97
+ },
98
+ r.key
99
+ )),
100
+ /* @__PURE__ */ t("div", { style: { ...c, marginTop: 12 }, children: "State" }),
101
+ /* @__PURE__ */ t(
102
+ "input",
103
+ {
104
+ type: "text",
105
+ placeholder: "filter paths…",
106
+ value: s,
107
+ onChange: (r) => a(r.target.value),
108
+ style: {
109
+ background: "rgba(8, 47, 73, 0.6)",
110
+ border: "1px solid rgba(125, 211, 252, 0.4)",
111
+ borderRadius: 6,
112
+ color: "#e0f2fe",
113
+ padding: "4px 6px",
114
+ fontSize: 11,
115
+ width: "100%",
116
+ marginBottom: 6
117
+ }
118
+ }
119
+ ),
120
+ /* @__PURE__ */ t("div", { style: { fontFamily: "monospace", fontSize: 10.5 }, children: m.map(([r, d]) => /* @__PURE__ */ i(
121
+ "div",
122
+ {
123
+ style: {
124
+ display: "grid",
125
+ gridTemplateColumns: "1fr auto",
126
+ gap: 8,
127
+ padding: "2px 0",
128
+ borderBottom: "1px dashed rgba(125, 211, 252, 0.15)"
129
+ },
130
+ children: [
131
+ /* @__PURE__ */ t("span", { style: { color: "#bae6fd" }, children: r }),
132
+ /* @__PURE__ */ t("span", { style: { color: "#fef3c7" }, children: C(d) })
133
+ ]
134
+ },
135
+ r
136
+ )) })
137
+ ] });
138
+ }
139
+ function _({
140
+ adapter: e,
141
+ onMock: n
142
+ }) {
143
+ const [o, s] = f("{}");
144
+ return /* @__PURE__ */ i("div", { style: v, children: [
145
+ /* @__PURE__ */ i(
146
+ "div",
147
+ {
148
+ style: {
149
+ display: "flex",
150
+ justifyContent: "space-between",
151
+ alignItems: "center"
152
+ },
153
+ children: [
154
+ /* @__PURE__ */ t("span", { style: { color: "#e0f2fe" }, children: e.label }),
155
+ /* @__PURE__ */ t("span", { style: { color: "#94a3b8", fontSize: 10 }, children: e.kind })
156
+ ]
157
+ }
158
+ ),
159
+ /* @__PURE__ */ t(
160
+ "textarea",
161
+ {
162
+ value: o,
163
+ onChange: (a) => s(a.target.value),
164
+ rows: 2,
165
+ style: {
166
+ fontFamily: "monospace",
167
+ fontSize: 10.5,
168
+ background: "rgba(8, 47, 73, 0.6)",
169
+ color: "#e0f2fe",
170
+ border: "1px solid rgba(125, 211, 252, 0.3)",
171
+ borderRadius: 4,
172
+ padding: 4,
173
+ resize: "vertical"
174
+ }
175
+ }
176
+ ),
177
+ /* @__PURE__ */ t(
178
+ "button",
179
+ {
180
+ type: "button",
181
+ style: l,
182
+ onClick: () => {
183
+ try {
184
+ const a = JSON.parse(o);
185
+ n(a);
186
+ } catch {
187
+ n(o);
188
+ }
189
+ },
190
+ children: "fire"
191
+ }
192
+ )
193
+ ] });
194
+ }
195
+ function C(e) {
196
+ return e === void 0 ? "—" : e === null ? "null" : typeof e == "string" || typeof e == "object" ? JSON.stringify(e) : String(e);
197
+ }
198
+ function B() {
199
+ const { store: e, bundle: n } = u();
200
+ return /* @__PURE__ */ i(y, { children: [
201
+ /* @__PURE__ */ t(b, { node: n.root, store: e }),
202
+ /* @__PURE__ */ t(h, {}),
203
+ /* @__PURE__ */ t(x, {}),
204
+ /* @__PURE__ */ t(T, {})
205
+ ] });
206
+ }
207
+ export {
208
+ B as TestMode
209
+ };
210
+ //# sourceMappingURL=test-DBCtwx_I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-DBCtwx_I.js","sources":["../src/overlay/test.tsx","../src/modes/test.tsx"],"sourcesContent":["import { useSignals } from \"@preact/signals-react/runtime\";\nimport { useState } from \"react\";\nimport { useLumencastRuntime } from \"./runtime-context\";\n\nconst PANEL_STYLE: React.CSSProperties = {\n position: \"fixed\",\n bottom: 12,\n right: 12,\n zIndex: 100_001,\n width: 360,\n maxHeight: \"70vh\",\n overflowY: \"auto\",\n padding: 12,\n fontFamily: \"system-ui, -apple-system, BlinkMacSystemFont, sans-serif\",\n fontSize: 12,\n color: \"#e5e7eb\",\n background: \"rgba(8, 47, 73, 0.92)\",\n border: \"1px solid rgba(56, 189, 248, 0.4)\",\n borderRadius: 10,\n boxShadow: \"0 8px 32px rgba(0, 0, 0, 0.45)\",\n};\n\nconst SECTION_TITLE: React.CSSProperties = {\n fontWeight: 600,\n fontSize: 11,\n letterSpacing: \"0.06em\",\n color: \"#7dd3fc\",\n textTransform: \"uppercase\",\n marginBottom: 6,\n};\n\nconst BUTTON_STYLE: React.CSSProperties = {\n background: \"rgba(14, 165, 233, 0.4)\",\n border: \"1px solid rgba(125, 211, 252, 0.5)\",\n borderRadius: 6,\n color: \"#f0f9ff\",\n padding: \"3px 8px\",\n fontSize: 11,\n cursor: \"pointer\",\n};\n\nconst ADAPTER_ROW: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n padding: \"6px 0\",\n borderBottom: \"1px solid rgba(56, 189, 248, 0.2)\",\n};\n\n/** Test-mode overlay : adapter mocker + state inspector + time\n * controls. Drives the server's __test.* family via the same `sendInput`\n * channel. */\nexport function TestPanel() {\n const { bundle, store, sendInput } = useLumencastRuntime();\n useSignals();\n const [filter, setFilter] = useState(\"\");\n\n const adapters = bundle.external_adapters ?? [];\n const stateRecord = store.toRecord();\n const filteredEntries = Object.entries(stateRecord).filter(\n ([k]) => filter === \"\" || k.includes(filter),\n );\n\n return (\n <div style={PANEL_STYLE} data-testid=\"lumencast-test-panel\">\n {/* Time controls */}\n <div style={SECTION_TITLE}>Time</div>\n <div style={{ display: \"flex\", gap: 6, marginBottom: 8 }}>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.tick\", value: 100 }])}\n >\n tick +100ms\n </button>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.tick\", value: 1_000 }])}\n >\n tick +1s\n </button>\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => sendInput([{ path: \"__test.reset\", value: true }])}\n >\n reset\n </button>\n </div>\n\n {/* Adapter mocker */}\n <div style={SECTION_TITLE}>External adapters</div>\n {adapters.length === 0 && (\n <div style={{ color: \"#94a3b8\", fontStyle: \"italic\", fontSize: 11 }}>\n No external adapters declared in this scene.\n </div>\n )}\n {adapters.map((adapter) => (\n <AdapterRow\n key={adapter.key}\n adapter={adapter}\n onMock={(payload) =>\n // LSDP/1 patch values must be leaf — JSON-encode the structured payload.\n sendInput([\n {\n path: \"__test.mock_adapter\",\n value: JSON.stringify({ key: adapter.key, payload }),\n },\n ])\n }\n />\n ))}\n\n {/* State inspector */}\n <div style={{ ...SECTION_TITLE, marginTop: 12 }}>State</div>\n <input\n type=\"text\"\n placeholder=\"filter paths…\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n style={{\n background: \"rgba(8, 47, 73, 0.6)\",\n border: \"1px solid rgba(125, 211, 252, 0.4)\",\n borderRadius: 6,\n color: \"#e0f2fe\",\n padding: \"4px 6px\",\n fontSize: 11,\n width: \"100%\",\n marginBottom: 6,\n }}\n />\n <div style={{ fontFamily: \"monospace\", fontSize: 10.5 }}>\n {filteredEntries.map(([path, value]) => (\n <div\n key={path}\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr auto\",\n gap: 8,\n padding: \"2px 0\",\n borderBottom: \"1px dashed rgba(125, 211, 252, 0.15)\",\n }}\n >\n <span style={{ color: \"#bae6fd\" }}>{path}</span>\n <span style={{ color: \"#fef3c7\" }}>{formatValue(value)}</span>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nfunction AdapterRow({\n adapter,\n onMock,\n}: {\n adapter: { key: string; label: string; kind: string };\n onMock: (payload: unknown) => void;\n}) {\n const [draft, setDraft] = useState(\"{}\");\n return (\n <div style={ADAPTER_ROW}>\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n }}\n >\n <span style={{ color: \"#e0f2fe\" }}>{adapter.label}</span>\n <span style={{ color: \"#94a3b8\", fontSize: 10 }}>{adapter.kind}</span>\n </div>\n <textarea\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n rows={2}\n style={{\n fontFamily: \"monospace\",\n fontSize: 10.5,\n background: \"rgba(8, 47, 73, 0.6)\",\n color: \"#e0f2fe\",\n border: \"1px solid rgba(125, 211, 252, 0.3)\",\n borderRadius: 4,\n padding: 4,\n resize: \"vertical\",\n }}\n />\n <button\n type=\"button\"\n style={BUTTON_STYLE}\n onClick={() => {\n try {\n const parsed = JSON.parse(draft);\n onMock(parsed);\n } catch {\n onMock(draft);\n }\n }}\n >\n fire\n </button>\n </div>\n );\n}\n\nfunction formatValue(value: unknown): string {\n if (value === undefined) return \"—\";\n if (value === null) return \"null\";\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n","import { Tree } from \"../render/tree\";\nimport { ControlPanel } from \"../overlay/control\";\nimport { TestPanel } from \"../overlay/test\";\nimport { StatusPill } from \"../overlay/status-pill\";\nimport { useLumencastRuntime } from \"../overlay/runtime-context\";\n\n/** Test mode : scene + operator overlay + test extensions (adapter\n * mocker, state inspector, time controls). */\nexport function TestMode() {\n const { store, bundle } = useLumencastRuntime();\n return (\n <>\n <Tree node={bundle.root} store={store} />\n <StatusPill />\n <ControlPanel />\n <TestPanel />\n </>\n );\n}\n"],"names":["PANEL_STYLE","SECTION_TITLE","BUTTON_STYLE","ADAPTER_ROW","TestPanel","bundle","store","sendInput","useLumencastRuntime","useSignals","filter","setFilter","useState","adapters","stateRecord","filteredEntries","k","jsxs","jsx","adapter","AdapterRow","payload","e","path","value","formatValue","onMock","draft","setDraft","parsed","TestMode","Fragment","Tree","StatusPill","ControlPanel"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface ReconnectScheduleOptions {
2
+ /** First delay in milliseconds. */
3
+ initial?: number;
4
+ /** Maximum delay in milliseconds. */
5
+ max?: number;
6
+ /** Multiplicative factor between attempts (>= 1). */
7
+ factor?: number;
8
+ /** Jitter as a fraction of the delay (0 disables, 0.2 = ±20 %). */
9
+ jitter?: number;
10
+ /** Random source — only injected for tests. */
11
+ random?: () => number;
12
+ }
13
+ export interface ReconnectSchedule {
14
+ /** Returns the delay to wait before the n-th attempt (1-indexed). */
15
+ delayFor(attempt: number): number;
16
+ /** Reset to attempt 1 (called on a successful connection). */
17
+ reset(): void;
18
+ /** Current attempt counter. */
19
+ readonly attempt: number;
20
+ }
21
+ export declare function createReconnectSchedule(opts?: ReconnectScheduleOptions): ReconnectSchedule;
22
+ //# sourceMappingURL=reconnect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect.d.ts","sourceRoot":"","sources":["../../src/transport/reconnect.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,wBAAwB;IACvC,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AASD,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,8DAA8D;IAC9D,KAAK,IAAI,IAAI,CAAC;IACd,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAgCD,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,wBAA6B,GAAG,iBAAiB,CAY9F"}