@shiftbloom-studio/symphony-state 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +198 -0
- package/dist/adapters/atom.cjs +36 -0
- package/dist/adapters/atom.cjs.map +1 -0
- package/dist/adapters/atom.d.cts +8 -0
- package/dist/adapters/atom.d.ts +8 -0
- package/dist/adapters/atom.js +34 -0
- package/dist/adapters/atom.js.map +1 -0
- package/dist/adapters/external.cjs +16 -0
- package/dist/adapters/external.cjs.map +1 -0
- package/dist/adapters/external.d.cts +13 -0
- package/dist/adapters/external.d.ts +13 -0
- package/dist/adapters/external.js +14 -0
- package/dist/adapters/external.js.map +1 -0
- package/dist/adapters/query.cjs +17 -0
- package/dist/adapters/query.cjs.map +1 -0
- package/dist/adapters/query.d.cts +16 -0
- package/dist/adapters/query.d.ts +16 -0
- package/dist/adapters/query.js +15 -0
- package/dist/adapters/query.js.map +1 -0
- package/dist/adapters/redux.cjs +20 -0
- package/dist/adapters/redux.cjs.map +1 -0
- package/dist/adapters/redux.d.cts +15 -0
- package/dist/adapters/redux.d.ts +15 -0
- package/dist/adapters/redux.js +18 -0
- package/dist/adapters/redux.js.map +1 -0
- package/dist/adapters/url.cjs +39 -0
- package/dist/adapters/url.cjs.map +1 -0
- package/dist/adapters/url.d.cts +13 -0
- package/dist/adapters/url.d.ts +13 -0
- package/dist/adapters/url.js +37 -0
- package/dist/adapters/url.js.map +1 -0
- package/dist/adapters/zustand.cjs +16 -0
- package/dist/adapters/zustand.cjs.map +1 -0
- package/dist/adapters/zustand.d.cts +10 -0
- package/dist/adapters/zustand.d.ts +10 -0
- package/dist/adapters/zustand.js +14 -0
- package/dist/adapters/zustand.js.map +1 -0
- package/dist/devtools.cjs +159 -0
- package/dist/devtools.cjs.map +1 -0
- package/dist/devtools.d.cts +9 -0
- package/dist/devtools.d.ts +9 -0
- package/dist/devtools.js +157 -0
- package/dist/devtools.js.map +1 -0
- package/dist/index.cjs +560 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +20 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +552 -0
- package/dist/index.js.map +1 -0
- package/dist/react.cjs +576 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +40 -0
- package/dist/react.d.ts +40 -0
- package/dist/react.js +569 -0
- package/dist/react.js.map +1 -0
- package/dist/types-B1uzdpYH.d.cts +67 -0
- package/dist/types-B1uzdpYH.d.ts +67 -0
- package/package.json +127 -0
package/dist/react.cjs
ADDED
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
// src/react/SymphonyProvider.tsx
|
|
7
|
+
var SymphonyContext = react.createContext(null);
|
|
8
|
+
var SymphonyProvider = ({ conductor, children }) => {
|
|
9
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SymphonyContext.Provider, { value: conductor, children });
|
|
10
|
+
};
|
|
11
|
+
var useConductor = () => {
|
|
12
|
+
const conductor = react.useContext(SymphonyContext);
|
|
13
|
+
if (!conductor) {
|
|
14
|
+
throw new Error("SymphonyProvider is missing in the React tree.");
|
|
15
|
+
}
|
|
16
|
+
return conductor;
|
|
17
|
+
};
|
|
18
|
+
var useSection = (key) => {
|
|
19
|
+
const conductor = useConductor();
|
|
20
|
+
const getSnapshot = react.useCallback(() => conductor.getSectionValue(key), [
|
|
21
|
+
conductor,
|
|
22
|
+
key
|
|
23
|
+
]);
|
|
24
|
+
const subscribe = react.useCallback(
|
|
25
|
+
(cb) => conductor.subscribe(key, cb),
|
|
26
|
+
[conductor, key]
|
|
27
|
+
);
|
|
28
|
+
const value = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
29
|
+
const handle = react.useMemo(
|
|
30
|
+
() => ({
|
|
31
|
+
value,
|
|
32
|
+
get: () => value,
|
|
33
|
+
set: (next) => conductor.getSection(key).set(next),
|
|
34
|
+
patch: (partial) => conductor.getSection(key).patch(partial),
|
|
35
|
+
subscribe: (cb) => conductor.subscribe(key, cb)
|
|
36
|
+
}),
|
|
37
|
+
[conductor, key, value, subscribe]
|
|
38
|
+
);
|
|
39
|
+
return handle;
|
|
40
|
+
};
|
|
41
|
+
var useSelector = (key, selector, equality = Object.is) => {
|
|
42
|
+
const conductor = useConductor();
|
|
43
|
+
const selectedRef = react.useRef();
|
|
44
|
+
const getSnapshot = react.useCallback(() => {
|
|
45
|
+
const value = conductor.getSectionValue(key);
|
|
46
|
+
const nextSelected = selector(value);
|
|
47
|
+
if (selectedRef.current !== void 0 && equality(selectedRef.current, nextSelected)) {
|
|
48
|
+
return selectedRef.current;
|
|
49
|
+
}
|
|
50
|
+
selectedRef.current = nextSelected;
|
|
51
|
+
return nextSelected;
|
|
52
|
+
}, [conductor, key, selector, equality]);
|
|
53
|
+
const subscribe = react.useCallback(
|
|
54
|
+
(cb) => conductor.subscribe(key, cb),
|
|
55
|
+
[conductor, key]
|
|
56
|
+
);
|
|
57
|
+
return react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
58
|
+
};
|
|
59
|
+
var escapeJson = (value) => value.replace(/</g, "\\u003c").replace(/>/g, "\\u003e");
|
|
60
|
+
var SymphonyScript = ({
|
|
61
|
+
state,
|
|
62
|
+
globalKey = "__SYMPHONY_STATE__"
|
|
63
|
+
}) => {
|
|
64
|
+
const serialized = escapeJson(JSON.stringify(state));
|
|
65
|
+
const script = `window[${JSON.stringify(globalKey)}]=${serialized};`;
|
|
66
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
67
|
+
"script",
|
|
68
|
+
{
|
|
69
|
+
"data-symphony": true,
|
|
70
|
+
dangerouslySetInnerHTML: { __html: script }
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/core/scheduler.ts
|
|
76
|
+
var scheduleMicrotask = (flush) => {
|
|
77
|
+
if (typeof queueMicrotask === "function") {
|
|
78
|
+
queueMicrotask(flush);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
Promise.resolve().then(flush);
|
|
82
|
+
};
|
|
83
|
+
var createScheduler = (scheduler) => {
|
|
84
|
+
if (!scheduler || scheduler === "microtask") {
|
|
85
|
+
return scheduleMicrotask;
|
|
86
|
+
}
|
|
87
|
+
if (scheduler === "sync") {
|
|
88
|
+
return (flush) => flush();
|
|
89
|
+
}
|
|
90
|
+
if (scheduler === "raf") {
|
|
91
|
+
return (flush) => {
|
|
92
|
+
if (typeof requestAnimationFrame === "function") {
|
|
93
|
+
requestAnimationFrame(() => flush());
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
scheduleMicrotask(flush);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return scheduler;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// src/core/conductor.ts
|
|
103
|
+
var defaultPersist = (value, config) => {
|
|
104
|
+
if (!config.storage) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const serialize = config.serialize ?? JSON.stringify;
|
|
108
|
+
config.storage.setItem(config.key, serialize(value));
|
|
109
|
+
};
|
|
110
|
+
var readPersist = (config) => {
|
|
111
|
+
if (!config.storage) {
|
|
112
|
+
return void 0;
|
|
113
|
+
}
|
|
114
|
+
const raw = config.storage.getItem(config.key);
|
|
115
|
+
if (!raw) {
|
|
116
|
+
return void 0;
|
|
117
|
+
}
|
|
118
|
+
const deserialize = config.deserialize ?? JSON.parse;
|
|
119
|
+
return deserialize(raw);
|
|
120
|
+
};
|
|
121
|
+
var now = () => Date.now();
|
|
122
|
+
var isObject = (value) => typeof value === "object" && value !== null;
|
|
123
|
+
var createDependencyOrder = (dependencies) => {
|
|
124
|
+
const indegree = /* @__PURE__ */ new Map();
|
|
125
|
+
const outgoing = /* @__PURE__ */ new Map();
|
|
126
|
+
dependencies.forEach((deps, key) => {
|
|
127
|
+
indegree.set(key, deps.length);
|
|
128
|
+
deps.forEach((dep) => {
|
|
129
|
+
if (!outgoing.has(dep)) {
|
|
130
|
+
outgoing.set(dep, []);
|
|
131
|
+
}
|
|
132
|
+
outgoing.get(dep)?.push(key);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
const queue = [];
|
|
136
|
+
indegree.forEach((count, key) => {
|
|
137
|
+
if (count === 0) {
|
|
138
|
+
queue.push(key);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
const order = [];
|
|
142
|
+
while (queue.length > 0) {
|
|
143
|
+
const current = queue.shift();
|
|
144
|
+
if (!current) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
order.push(current);
|
|
148
|
+
const children = outgoing.get(current) ?? [];
|
|
149
|
+
for (const child of children) {
|
|
150
|
+
const next = (indegree.get(child) ?? 0) - 1;
|
|
151
|
+
indegree.set(child, next);
|
|
152
|
+
if (next === 0) {
|
|
153
|
+
queue.push(child);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (order.length !== dependencies.size) {
|
|
158
|
+
const cycle = [...dependencies.keys()].filter((key) => !order.includes(key));
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Dependency cycle detected in sections: ${cycle.join(", ")}`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
return order;
|
|
164
|
+
};
|
|
165
|
+
var resolveStorage = (persist) => {
|
|
166
|
+
if (!persist) {
|
|
167
|
+
return void 0;
|
|
168
|
+
}
|
|
169
|
+
if (persist.storage) {
|
|
170
|
+
return persist;
|
|
171
|
+
}
|
|
172
|
+
if (typeof window === "undefined") {
|
|
173
|
+
return { ...persist, storage: null };
|
|
174
|
+
}
|
|
175
|
+
return { ...persist, storage: window.localStorage };
|
|
176
|
+
};
|
|
177
|
+
var createConductor = (config) => {
|
|
178
|
+
const sections = /* @__PURE__ */ new Map();
|
|
179
|
+
const updates = /* @__PURE__ */ new Map();
|
|
180
|
+
const effects = /* @__PURE__ */ new Set();
|
|
181
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
182
|
+
const scheduler = createScheduler(config.scheduler);
|
|
183
|
+
const transactionHistory = [];
|
|
184
|
+
const transactionHistoryLimit = config.transactionHistoryLimit ?? 20;
|
|
185
|
+
const persistValue = (state, value) => {
|
|
186
|
+
if (!state.persist) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const persist = resolveStorage(state.persist);
|
|
190
|
+
if (!persist?.storage) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (persist.throttleMs && persist.throttleMs > 0) {
|
|
194
|
+
if (state.persistTimer) {
|
|
195
|
+
clearTimeout(state.persistTimer);
|
|
196
|
+
}
|
|
197
|
+
state.persistTimer = setTimeout(() => {
|
|
198
|
+
defaultPersist(value, persist);
|
|
199
|
+
}, persist.throttleMs);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
defaultPersist(value, persist);
|
|
203
|
+
};
|
|
204
|
+
const hydrateValue = (state) => {
|
|
205
|
+
const persist = resolveStorage(state.persist);
|
|
206
|
+
if (!persist?.storage) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const stored = readPersist(persist);
|
|
210
|
+
if (stored !== void 0) {
|
|
211
|
+
state.value = stored;
|
|
212
|
+
state.adapter?.set(stored);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const bootstrapValues = (() => {
|
|
216
|
+
if (!config.bootstrap) {
|
|
217
|
+
return void 0;
|
|
218
|
+
}
|
|
219
|
+
if (typeof config.bootstrap === "function") {
|
|
220
|
+
return config.bootstrap();
|
|
221
|
+
}
|
|
222
|
+
return config.bootstrap;
|
|
223
|
+
})();
|
|
224
|
+
for (const definition of config.sections) {
|
|
225
|
+
if (sections.has(definition.key)) {
|
|
226
|
+
throw new Error(`Section with key "${definition.key}" already exists.`);
|
|
227
|
+
}
|
|
228
|
+
const dependsOn = definition.dependsOn ?? [];
|
|
229
|
+
const state = {
|
|
230
|
+
key: definition.key,
|
|
231
|
+
adapter: definition.source,
|
|
232
|
+
subscribers: /* @__PURE__ */ new Set(),
|
|
233
|
+
dependsOn,
|
|
234
|
+
persist: definition.persist,
|
|
235
|
+
value: definition.source.get()
|
|
236
|
+
};
|
|
237
|
+
sections.set(definition.key, state);
|
|
238
|
+
dependencies.set(definition.key, dependsOn);
|
|
239
|
+
}
|
|
240
|
+
const derivedDefinitions = config.derived ?? [];
|
|
241
|
+
for (const definition of derivedDefinitions) {
|
|
242
|
+
if (sections.has(definition.key)) {
|
|
243
|
+
throw new Error(`Section with key "${definition.key}" already exists.`);
|
|
244
|
+
}
|
|
245
|
+
const state = {
|
|
246
|
+
key: definition.key,
|
|
247
|
+
subscribers: /* @__PURE__ */ new Set(),
|
|
248
|
+
dependsOn: definition.inputs,
|
|
249
|
+
value: void 0,
|
|
250
|
+
derived: {
|
|
251
|
+
inputs: definition.inputs,
|
|
252
|
+
compute: definition.compute,
|
|
253
|
+
lastInputs: void 0
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
sections.set(definition.key, state);
|
|
257
|
+
dependencies.set(definition.key, definition.inputs);
|
|
258
|
+
}
|
|
259
|
+
const order = createDependencyOrder(dependencies);
|
|
260
|
+
for (const [key, state] of sections) {
|
|
261
|
+
if (bootstrapValues && key in bootstrapValues) {
|
|
262
|
+
const value = bootstrapValues[key];
|
|
263
|
+
state.value = value;
|
|
264
|
+
state.adapter?.set(value);
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (state.persist) {
|
|
268
|
+
hydrateValue(state);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const stagedChanges = /* @__PURE__ */ new Set();
|
|
272
|
+
const pendingNotifications = /* @__PURE__ */ new Set();
|
|
273
|
+
let scheduled = false;
|
|
274
|
+
let transactionDepth = 0;
|
|
275
|
+
let lastTransactionLabel;
|
|
276
|
+
const notifySubscribers = () => {
|
|
277
|
+
scheduled = false;
|
|
278
|
+
for (const key of pendingNotifications) {
|
|
279
|
+
const state = sections.get(key);
|
|
280
|
+
if (!state) {
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
for (const subscriber of state.subscribers) {
|
|
284
|
+
subscriber();
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
pendingNotifications.clear();
|
|
288
|
+
};
|
|
289
|
+
const scheduleNotify = (keys) => {
|
|
290
|
+
for (const key of keys) {
|
|
291
|
+
pendingNotifications.add(key);
|
|
292
|
+
}
|
|
293
|
+
if (scheduled) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
scheduled = true;
|
|
297
|
+
scheduler(notifySubscribers);
|
|
298
|
+
};
|
|
299
|
+
const markChanged = (key) => {
|
|
300
|
+
stagedChanges.add(key);
|
|
301
|
+
};
|
|
302
|
+
const applyUpdate = (state, update) => {
|
|
303
|
+
if (update.type === "set") {
|
|
304
|
+
if (Object.is(state.value, update.value)) {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
state.adapter?.set(update.value);
|
|
308
|
+
state.value = update.value;
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
if (state.adapter?.patch) {
|
|
312
|
+
if (isObject(state.value) && isObject(update.value)) {
|
|
313
|
+
const next = { ...state.value, ...update.value };
|
|
314
|
+
const changed = Object.keys(update.value).some(
|
|
315
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
316
|
+
(k) => !Object.is(state.value[k], update.value[k])
|
|
317
|
+
);
|
|
318
|
+
if (!changed) {
|
|
319
|
+
return false;
|
|
320
|
+
}
|
|
321
|
+
state.adapter.patch(update.value);
|
|
322
|
+
state.value = next;
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
state.adapter.patch(update.value);
|
|
326
|
+
state.value = update.value;
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
329
|
+
if (isObject(state.value) && isObject(update.value)) {
|
|
330
|
+
const next = { ...state.value, ...update.value };
|
|
331
|
+
const changed = Object.keys(update.value).some(
|
|
332
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
333
|
+
(k) => !Object.is(state.value[k], update.value[k])
|
|
334
|
+
);
|
|
335
|
+
if (!changed) {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
state.adapter?.set(next);
|
|
339
|
+
state.value = next;
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
throw new Error(`Section "${state.key}" does not support patch updates.`);
|
|
343
|
+
};
|
|
344
|
+
const computeDerived = (state) => {
|
|
345
|
+
if (!state.derived) {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
const inputs = state.derived.inputs.map((key) => {
|
|
349
|
+
const inputState = sections.get(key);
|
|
350
|
+
if (!inputState) {
|
|
351
|
+
throw new Error(`Missing input section "${key}".`);
|
|
352
|
+
}
|
|
353
|
+
return inputState.value;
|
|
354
|
+
});
|
|
355
|
+
if (state.derived.lastInputs && inputs.every((value, index) => Object.is(value, state.derived?.lastInputs?.[index]))) {
|
|
356
|
+
return false;
|
|
357
|
+
}
|
|
358
|
+
const next = state.derived.compute(...inputs);
|
|
359
|
+
const changed = !Object.is(state.value, next);
|
|
360
|
+
state.value = next;
|
|
361
|
+
state.derived.lastInputs = inputs;
|
|
362
|
+
return changed;
|
|
363
|
+
};
|
|
364
|
+
for (const key of order) {
|
|
365
|
+
const state = sections.get(key);
|
|
366
|
+
if (!state?.derived) {
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
computeDerived(state);
|
|
370
|
+
}
|
|
371
|
+
const runEffects = (changedKeys) => {
|
|
372
|
+
if (effects.size === 0) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const api = {
|
|
376
|
+
get: (key) => getSectionValue(key),
|
|
377
|
+
set: (key, value) => setSectionValue(key, value),
|
|
378
|
+
patch: (key, value) => patchSectionValue(key, value),
|
|
379
|
+
transaction: (fn, label) => transaction(fn, label)
|
|
380
|
+
};
|
|
381
|
+
for (const effect2 of effects) {
|
|
382
|
+
if (!effect2.when.some((key) => changedKeys.includes(key))) {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
const limit = effect2.maxDepth ?? 5;
|
|
386
|
+
if (transactionDepth > limit) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
`Effect depth exceeded while running effect for sections: ${effect2.when.join(", ")}`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
effect2.run(api);
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
const commit = () => {
|
|
395
|
+
if (updates.size === 0 && stagedChanges.size === 0) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const changedKeys = [];
|
|
399
|
+
for (const key of order) {
|
|
400
|
+
const state = sections.get(key);
|
|
401
|
+
if (!state) {
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
const update = updates.get(key);
|
|
405
|
+
if (update && !state.derived) {
|
|
406
|
+
const changed = applyUpdate(state, update);
|
|
407
|
+
if (changed) {
|
|
408
|
+
persistValue(state, state.value);
|
|
409
|
+
changedKeys.push(key);
|
|
410
|
+
}
|
|
411
|
+
updates.delete(key);
|
|
412
|
+
}
|
|
413
|
+
if (state.derived) {
|
|
414
|
+
const derivedChanged = computeDerived(state);
|
|
415
|
+
if (derivedChanged) {
|
|
416
|
+
changedKeys.push(key);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (changedKeys.length > 0) {
|
|
421
|
+
scheduleNotify(changedKeys);
|
|
422
|
+
transactionHistory.unshift({
|
|
423
|
+
label: lastTransactionLabel,
|
|
424
|
+
touched: [...new Set(changedKeys)],
|
|
425
|
+
timestamp: now()
|
|
426
|
+
});
|
|
427
|
+
if (transactionHistory.length > transactionHistoryLimit) {
|
|
428
|
+
transactionHistory.length = transactionHistoryLimit;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
stagedChanges.clear();
|
|
432
|
+
lastTransactionLabel = void 0;
|
|
433
|
+
runEffects(changedKeys);
|
|
434
|
+
};
|
|
435
|
+
const beginTransaction = (label) => {
|
|
436
|
+
transactionDepth += 1;
|
|
437
|
+
if (label) {
|
|
438
|
+
lastTransactionLabel = label;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
const endTransaction = () => {
|
|
442
|
+
transactionDepth -= 1;
|
|
443
|
+
if (transactionDepth === 0) {
|
|
444
|
+
commit();
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
const transaction = (fn, label) => {
|
|
448
|
+
beginTransaction(label);
|
|
449
|
+
try {
|
|
450
|
+
fn();
|
|
451
|
+
} finally {
|
|
452
|
+
endTransaction();
|
|
453
|
+
}
|
|
454
|
+
};
|
|
455
|
+
const setSectionValue = (key, value) => {
|
|
456
|
+
if (!sections.has(key)) {
|
|
457
|
+
throw new Error(`Unknown section "${key}".`);
|
|
458
|
+
}
|
|
459
|
+
if (transactionDepth === 0) {
|
|
460
|
+
return transaction(() => setSectionValue(key, value));
|
|
461
|
+
}
|
|
462
|
+
const state = sections.get(key);
|
|
463
|
+
if (state?.derived) {
|
|
464
|
+
throw new Error(`Cannot set derived section "${key}".`);
|
|
465
|
+
}
|
|
466
|
+
updates.set(key, { type: "set", value });
|
|
467
|
+
markChanged(key);
|
|
468
|
+
};
|
|
469
|
+
const patchSectionValue = (key, value) => {
|
|
470
|
+
if (!sections.has(key)) {
|
|
471
|
+
throw new Error(`Unknown section "${key}".`);
|
|
472
|
+
}
|
|
473
|
+
if (transactionDepth === 0) {
|
|
474
|
+
return transaction(() => patchSectionValue(key, value));
|
|
475
|
+
}
|
|
476
|
+
const state = sections.get(key);
|
|
477
|
+
if (state?.derived) {
|
|
478
|
+
throw new Error(`Cannot patch derived section "${key}".`);
|
|
479
|
+
}
|
|
480
|
+
updates.set(key, { type: "patch", value });
|
|
481
|
+
markChanged(key);
|
|
482
|
+
};
|
|
483
|
+
const getSectionValue = (key) => {
|
|
484
|
+
const state = sections.get(key);
|
|
485
|
+
if (!state) {
|
|
486
|
+
throw new Error(`Unknown section "${key}".`);
|
|
487
|
+
}
|
|
488
|
+
return state.value;
|
|
489
|
+
};
|
|
490
|
+
const subscribe = (key, cb) => {
|
|
491
|
+
const state = sections.get(key);
|
|
492
|
+
if (!state) {
|
|
493
|
+
throw new Error(`Unknown section "${key}".`);
|
|
494
|
+
}
|
|
495
|
+
state.subscribers.add(cb);
|
|
496
|
+
return () => {
|
|
497
|
+
state.subscribers.delete(cb);
|
|
498
|
+
};
|
|
499
|
+
};
|
|
500
|
+
const getSection = (key) => {
|
|
501
|
+
return {
|
|
502
|
+
get: () => getSectionValue(key),
|
|
503
|
+
set: (next) => setSectionValue(key, next),
|
|
504
|
+
patch: (next) => patchSectionValue(key, next),
|
|
505
|
+
subscribe: (cb) => subscribe(key, cb)
|
|
506
|
+
};
|
|
507
|
+
};
|
|
508
|
+
const effect = (definition) => {
|
|
509
|
+
effects.add(definition);
|
|
510
|
+
return () => effects.delete(definition);
|
|
511
|
+
};
|
|
512
|
+
const getSnapshot = () => {
|
|
513
|
+
const snapshot = { sections: {}, transactions: [] };
|
|
514
|
+
for (const [key, state] of sections) {
|
|
515
|
+
snapshot.sections[key] = state.value;
|
|
516
|
+
}
|
|
517
|
+
snapshot.transactions = [...transactionHistory];
|
|
518
|
+
return snapshot;
|
|
519
|
+
};
|
|
520
|
+
const destroy = () => {
|
|
521
|
+
sections.forEach((state) => {
|
|
522
|
+
state.adapter?.destroy?.();
|
|
523
|
+
if (state.persistTimer) {
|
|
524
|
+
clearTimeout(state.persistTimer);
|
|
525
|
+
}
|
|
526
|
+
state.subscribers.clear();
|
|
527
|
+
});
|
|
528
|
+
sections.clear();
|
|
529
|
+
updates.clear();
|
|
530
|
+
effects.clear();
|
|
531
|
+
};
|
|
532
|
+
return {
|
|
533
|
+
getSection,
|
|
534
|
+
getSectionValue,
|
|
535
|
+
subscribe,
|
|
536
|
+
transaction,
|
|
537
|
+
effect,
|
|
538
|
+
getSnapshot,
|
|
539
|
+
destroy
|
|
540
|
+
};
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
// src/react/createSymphony.ts
|
|
544
|
+
var createSymphony = (config) => {
|
|
545
|
+
const sectionEntries = Object.values(config.sections);
|
|
546
|
+
const sections = [];
|
|
547
|
+
const derived = [];
|
|
548
|
+
for (const entry of sectionEntries) {
|
|
549
|
+
if ("source" in entry) {
|
|
550
|
+
sections.push(entry);
|
|
551
|
+
} else {
|
|
552
|
+
derived.push(entry);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
const conductor = createConductor({
|
|
556
|
+
sections,
|
|
557
|
+
derived,
|
|
558
|
+
scheduler: config.scheduler,
|
|
559
|
+
bootstrap: config.bootstrap
|
|
560
|
+
});
|
|
561
|
+
return {
|
|
562
|
+
conductor,
|
|
563
|
+
Provider: SymphonyProvider,
|
|
564
|
+
useSection: (key) => useSection(String(key)),
|
|
565
|
+
useSelector: (key, selector, equality) => useSelector(String(key), selector, equality)
|
|
566
|
+
};
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
exports.SymphonyProvider = SymphonyProvider;
|
|
570
|
+
exports.SymphonyScript = SymphonyScript;
|
|
571
|
+
exports.createSymphony = createSymphony;
|
|
572
|
+
exports.useConductor = useConductor;
|
|
573
|
+
exports.useSection = useSection;
|
|
574
|
+
exports.useSelector = useSelector;
|
|
575
|
+
//# sourceMappingURL=react.cjs.map
|
|
576
|
+
//# sourceMappingURL=react.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/SymphonyProvider.tsx","../src/react/hooks.ts","../src/react/SymphonyScript.tsx","../src/core/scheduler.ts","../src/core/conductor.ts","../src/react/createSymphony.ts"],"names":["createContext","useContext","useCallback","useSyncExternalStore","useMemo","useRef","jsx","effect"],"mappings":";;;;;;AAGA,IAAM,eAAA,GAAkBA,oBAAgC,IAAI,CAAA;AAOrD,IAAM,gBAAA,GAAmB,CAAC,EAAE,SAAA,EAAW,UAAS,KAA6B;AAClF,EAAA,sCACG,eAAA,CAAgB,QAAA,EAAhB,EAAyB,KAAA,EAAO,WAC9B,QAAA,EACH,CAAA;AAEJ;AAEO,IAAM,eAAe,MAAM;AAChC,EAAA,MAAM,SAAA,GAAYC,iBAAW,eAAe,CAAA;AAC5C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,EAClE;AACA,EAAA,OAAO,SAAA;AACT;ACpBO,IAAM,UAAA,GAAa,CAAK,GAAA,KAAiD;AAC9E,EAAA,MAAM,YAAY,YAAA,EAAa;AAE/B,EAAA,MAAM,cAAcC,iBAAA,CAAY,MAAM,SAAA,CAAU,eAAA,CAAmB,GAAG,CAAA,EAAG;AAAA,IACvE,SAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,SAAA,GAAYA,iBAAA;AAAA,IAChB,CAAC,EAAA,KAAmB,SAAA,CAAU,SAAA,CAAU,KAAK,EAAE,CAAA;AAAA,IAC/C,CAAC,WAAW,GAAG;AAAA,GACjB;AAEA,EAAA,MAAM,KAAA,GAAQC,0BAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,WAAW,CAAA;AAEtE,EAAA,MAAM,MAAA,GAASC,aAAA;AAAA,IACb,OAAO;AAAA,MACL,KAAA;AAAA,MACA,KAAK,MAAM,KAAA;AAAA,MACX,GAAA,EAAK,CAAC,IAAA,KAAY,SAAA,CAAU,WAAc,GAAG,CAAA,CAAE,IAAI,IAAI,CAAA;AAAA,MACvD,KAAA,EAAO,CAAC,OAAA,KACN,SAAA,CAAU,WAAc,GAAG,CAAA,CAAE,MAAM,OAAO,CAAA;AAAA,MAC5C,WAAW,CAAC,EAAA,KAAmB,SAAA,CAAU,SAAA,CAAU,KAAK,EAAE;AAAA,KAC5D,CAAA;AAAA,IACA,CAAC,SAAA,EAAW,GAAA,EAAK,KAAA,EAAO,SAAS;AAAA,GACnC;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,IAAM,cAAc,CACzB,GAAA,EACA,QAAA,EACA,QAAA,GAAoC,OAAO,EAAA,KACxC;AACH,EAAA,MAAM,YAAY,YAAA,EAAa;AAC/B,EAAA,MAAM,cAAcC,YAAA,EAAU;AAE9B,EAAA,MAAM,WAAA,GAAcH,kBAAY,MAAM;AACpC,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,eAAA,CAAmB,GAAG,CAAA;AAC9C,IAAA,MAAM,YAAA,GAAe,SAAS,KAAK,CAAA;AACnC,IAAA,IACE,YAAY,OAAA,KAAY,MAAA,IACxB,SAAS,WAAA,CAAY,OAAA,EAAS,YAAY,CAAA,EAC1C;AACA,MAAA,OAAO,WAAA,CAAY,OAAA;AAAA,IACrB;AACA,IAAA,WAAA,CAAY,OAAA,GAAU,YAAA;AACtB,IAAA,OAAO,YAAA;AAAA,EACT,GAAG,CAAC,SAAA,EAAW,GAAA,EAAK,QAAA,EAAU,QAAQ,CAAC,CAAA;AAEvC,EAAA,MAAM,SAAA,GAAYA,iBAAA;AAAA,IAChB,CAAC,EAAA,KAAmB,SAAA,CAAU,SAAA,CAAU,KAAK,EAAE,CAAA;AAAA,IAC/C,CAAC,WAAW,GAAG;AAAA,GACjB;AAEA,EAAA,OAAOC,0BAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,WAAW,CAAA;AACjE;ACtDA,IAAM,UAAA,GAAa,CAAC,KAAA,KAClB,KAAA,CAAM,OAAA,CAAQ,MAAM,SAAS,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,SAAS,CAAA;AAEjD,IAAM,iBAAiB,CAAC;AAAA,EAC7B,KAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,KAA2B;AACzB,EAAA,MAAM,UAAA,GAAa,UAAA,CAAW,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACnD,EAAA,MAAM,SAAS,CAAA,OAAA,EAAU,IAAA,CAAK,UAAU,SAAS,CAAC,KAAK,UAAU,CAAA,CAAA,CAAA;AACjE,EAAA,uBACEG,cAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,eAAA,EAAa,IAAA;AAAA,MACb,uBAAA,EAAyB,EAAE,MAAA,EAAQ,MAAA;AAAO;AAAA,GAC5C;AAEJ;;;ACpBA,IAAM,iBAAA,GAAoB,CAAC,KAAA,KAAsB;AAC/C,EAAA,IAAI,OAAO,mBAAmB,UAAA,EAAY;AACxC,IAAA,cAAA,CAAe,KAAK,CAAA;AACpB,IAAA;AAAA,EACF;AACA,EAAA,OAAA,CAAQ,OAAA,EAAQ,CAAE,IAAA,CAAK,KAAK,CAAA;AAC9B,CAAA;AAEO,IAAM,eAAA,GAAkB,CAAC,SAAA,KAA0B;AACxD,EAAA,IAAI,CAAC,SAAA,IAAa,SAAA,KAAc,WAAA,EAAa;AAC3C,IAAA,OAAO,iBAAA;AAAA,EACT;AACA,EAAA,IAAI,cAAc,MAAA,EAAQ;AACxB,IAAA,OAAO,CAAC,UAAsB,KAAA,EAAM;AAAA,EACtC;AACA,EAAA,IAAI,cAAc,KAAA,EAAO;AACvB,IAAA,OAAO,CAAC,KAAA,KAAsB;AAC5B,MAAA,IAAI,OAAO,0BAA0B,UAAA,EAAY;AAC/C,QAAA,qBAAA,CAAsB,MAAM,OAAO,CAAA;AACnC,QAAA;AAAA,MACF;AACA,MAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,IACzB,CAAA;AAAA,EACF;AACA,EAAA,OAAO,SAAA;AACT,CAAA;;;ACZA,IAAM,cAAA,GAAiB,CAAK,KAAA,EAAU,MAAA,KAA6B;AACjE,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA;AAAA,EACF;AACA,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,SAAA,IAAa,IAAA,CAAK,SAAA;AAC3C,EAAA,MAAA,CAAO,QAAQ,OAAA,CAAQ,MAAA,CAAO,GAAA,EAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACrD,CAAA;AAEA,IAAM,WAAA,GAAc,CAAK,MAAA,KAA4C;AACnE,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,GAAG,CAAA;AAC7C,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,WAAA,IAAe,IAAA,CAAK,KAAA;AAC/C,EAAA,OAAO,YAAY,GAAG,CAAA;AACxB,CAAA;AAqBA,IAAM,GAAA,GAAM,MAAM,IAAA,CAAK,GAAA,EAAI;AAE3B,IAAM,WAAW,CAAC,KAAA,KAChB,OAAO,KAAA,KAAU,YAAY,KAAA,KAAU,IAAA;AAEzC,IAAM,qBAAA,GAAwB,CAAC,YAAA,KAAwC;AACrE,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAoB;AACzC,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAsB;AAC3C,EAAA,YAAA,CAAa,OAAA,CAAQ,CAAC,IAAA,EAAM,GAAA,KAAQ;AAClC,IAAA,QAAA,CAAS,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,MAAM,CAAA;AAC7B,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACpB,MAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG;AACtB,QAAA,QAAA,CAAS,GAAA,CAAI,GAAA,EAAK,EAAE,CAAA;AAAA,MACtB;AACA,MAAA,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG,IAAA,CAAK,GAAG,CAAA;AAAA,IAC7B,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AAED,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC/B,IAAA,IAAI,UAAU,CAAA,EAAG;AACf,MAAA,KAAA,CAAM,KAAK,GAAG,CAAA;AAAA,IAChB;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,EAAG;AACvB,IAAA,MAAM,OAAA,GAAU,MAAM,KAAA,EAAM;AAC5B,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA;AAAA,IACF;AACA,IAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAClB,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,GAAA,CAAI,OAAO,KAAK,EAAC;AAC3C,IAAA,KAAA,MAAW,SAAS,QAAA,EAAU;AAC5B,MAAA,MAAM,IAAA,GAAA,CAAQ,QAAA,CAAS,GAAA,CAAI,KAAK,KAAK,CAAA,IAAK,CAAA;AAC1C,MAAA,QAAA,CAAS,GAAA,CAAI,OAAO,IAAI,CAAA;AACxB,MAAA,IAAI,SAAS,CAAA,EAAG;AACd,QAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,YAAA,CAAa,IAAA,EAAM;AACtC,IAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,YAAA,CAAa,MAAM,CAAA,CAAE,MAAA,CAAO,CAAC,GAAA,KAAQ,CAAC,KAAA,CAAM,QAAA,CAAS,GAAG,CAAC,CAAA;AAC3E,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,uCAAA,EAA0C,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KAC5D;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA;AAEA,IAAM,cAAA,GAAiB,CAAK,OAAA,KAA6D;AACvF,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,IAAA,OAAO,OAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAO,EAAE,GAAG,OAAA,EAAS,OAAA,EAAS,IAAA,EAAK;AAAA,EACrC;AACA,EAAA,OAAO,EAAE,GAAG,OAAA,EAAS,OAAA,EAAS,OAAO,YAAA,EAAa;AACpD,CAAA;AAYO,IAAM,eAAA,GAAkB,CAAC,MAAA,KAAuC;AACrE,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAmC;AACxD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAoB;AACxC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAsB;AAC1C,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAAsB;AAC/C,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,MAAA,CAAO,SAAS,CAAA;AAClD,EAAA,MAAM,qBAAwC,EAAC;AAC/C,EAAA,MAAM,uBAAA,GAA0B,OAAO,uBAAA,IAA2B,EAAA;AAElE,EAAA,MAAM,YAAA,GAAe,CAAK,KAAA,EAAwB,KAAA,KAAa;AAC7D,IAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AAClB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,KAAA,CAAM,OAAO,CAAA;AAC5C,IAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,OAAA,CAAQ,UAAA,IAAc,OAAA,CAAQ,UAAA,GAAa,CAAA,EAAG;AAChD,MAAA,IAAI,MAAM,YAAA,EAAc;AACtB,QAAA,YAAA,CAAa,MAAM,YAAY,CAAA;AAAA,MACjC;AACA,MAAA,KAAA,CAAM,YAAA,GAAe,WAAW,MAAM;AACpC,QAAA,cAAA,CAAe,OAAO,OAAO,CAAA;AAAA,MAC/B,CAAA,EAAG,QAAQ,UAAU,CAAA;AACrB,MAAA;AAAA,IACF;AACA,IAAA,cAAA,CAAe,OAAO,OAAO,CAAA;AAAA,EAC/B,CAAA;AAEA,EAAA,MAAM,YAAA,GAAe,CAAK,KAAA,KAA2B;AACnD,IAAA,MAAM,OAAA,GAAU,cAAA,CAAe,KAAA,CAAM,OAAO,CAAA;AAC5C,IAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACrB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,MAAA,GAAS,YAAe,OAAO,CAAA;AACrC,IAAA,IAAI,WAAW,MAAA,EAAW;AACxB,MAAA,KAAA,CAAM,KAAA,GAAQ,MAAA;AACd,MAAA,KAAA,CAAM,OAAA,EAAS,IAAI,MAAM,CAAA;AAAA,IAC3B;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,mBAAmB,MAAM;AAC7B,IAAA,IAAI,CAAC,OAAO,SAAA,EAAW;AACrB,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAO,MAAA,CAAO,SAAA,KAAc,UAAA,EAAY;AAC1C,MAAA,OAAO,OAAO,SAAA,EAAU;AAAA,IAC1B;AACA,IAAA,OAAO,MAAA,CAAO,SAAA;AAAA,EAChB,CAAA,GAAG;AAEH,EAAA,KAAA,MAAW,UAAA,IAAc,OAAO,QAAA,EAAU;AACxC,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AAChC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,UAAA,CAAW,GAAG,CAAA,iBAAA,CAAmB,CAAA;AAAA,IACxE;AACA,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,SAAA,IAAa,EAAC;AAC3C,IAAA,MAAM,KAAA,GAA+B;AAAA,MACnC,KAAK,UAAA,CAAW,GAAA;AAAA,MAChB,SAAS,UAAA,CAAW,MAAA;AAAA,MACpB,WAAA,sBAAiB,GAAA,EAAI;AAAA,MACrB,SAAA;AAAA,MACA,SAAS,UAAA,CAAW,OAAA;AAAA,MACpB,KAAA,EAAO,UAAA,CAAW,MAAA,CAAO,GAAA;AAAI,KAC/B;AACA,IAAA,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,GAAA,EAAK,KAAK,CAAA;AAClC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAA,CAAW,GAAA,EAAK,SAAS,CAAA;AAAA,EAC5C;AAEA,EAAA,MAAM,kBAAA,GAAqB,MAAA,CAAO,OAAA,IAAW,EAAC;AAC9C,EAAA,KAAA,MAAW,cAAc,kBAAA,EAAoB;AAC3C,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,GAAG,CAAA,EAAG;AAChC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,UAAA,CAAW,GAAG,CAAA,iBAAA,CAAmB,CAAA;AAAA,IACxE;AACA,IAAA,MAAM,KAAA,GAA+B;AAAA,MACnC,KAAK,UAAA,CAAW,GAAA;AAAA,MAChB,WAAA,sBAAiB,GAAA,EAAI;AAAA,MACrB,WAAW,UAAA,CAAW,MAAA;AAAA,MACtB,KAAA,EAAO,MAAA;AAAA,MACP,OAAA,EAAS;AAAA,QACP,QAAQ,UAAA,CAAW,MAAA;AAAA,QACnB,SAAS,UAAA,CAAW,OAAA;AAAA,QACpB,UAAA,EAAY;AAAA;AACd,KACF;AACA,IAAA,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,GAAA,EAAK,KAAK,CAAA;AAClC,IAAA,YAAA,CAAa,GAAA,CAAI,UAAA,CAAW,GAAA,EAAK,UAAA,CAAW,MAAM,CAAA;AAAA,EACpD;AAEA,EAAA,MAAM,KAAA,GAAQ,sBAAsB,YAAY,CAAA;AAEhD,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,QAAA,EAAU;AACnC,IAAA,IAAI,eAAA,IAAmB,OAAO,eAAA,EAAiB;AAC7C,MAAA,MAAM,KAAA,GAAQ,gBAAgB,GAAG,CAAA;AACjC,MAAA,KAAA,CAAM,KAAA,GAAQ,KAAA;AACd,MAAA,KAAA,CAAM,OAAA,EAAS,IAAI,KAAK,CAAA;AACxB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,MAAM,OAAA,EAAS;AACjB,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,uBAAoB,GAAA,EAAY;AACtC,EAAA,MAAM,oBAAA,uBAA2B,GAAA,EAAY;AAC7C,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,gBAAA,GAAmB,CAAA;AACvB,EAAA,IAAI,oBAAA;AAEJ,EAAA,MAAM,oBAAoB,MAAM;AAC9B,IAAA,SAAA,GAAY,KAAA;AACZ,IAAA,KAAA,MAAW,OAAO,oBAAA,EAAsB;AACtC,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC9B,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA;AAAA,MACF;AACA,MAAA,KAAA,MAAW,UAAA,IAAc,MAAM,WAAA,EAAa;AAC1C,QAAA,UAAA,EAAW;AAAA,MACb;AAAA,IACF;AACA,IAAA,oBAAA,CAAqB,KAAA,EAAM;AAAA,EAC7B,CAAA;AAEA,EAAA,MAAM,cAAA,GAAiB,CAAC,IAAA,KAAmB;AACzC,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,oBAAA,CAAqB,IAAI,GAAG,CAAA;AAAA,IAC9B;AACA,IAAA,IAAI,SAAA,EAAW;AACb,MAAA;AAAA,IACF;AACA,IAAA,SAAA,GAAY,IAAA;AACZ,IAAA,SAAA,CAAU,iBAAiB,CAAA;AAAA,EAC7B,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,KAAgB;AACnC,IAAA,aAAA,CAAc,IAAI,GAAG,CAAA;AAAA,EACvB,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,KAAA,EAA8B,MAAA,KAA4B;AAC7E,IAAA,IAAI,MAAA,CAAO,SAAS,KAAA,EAAO;AACzB,MAAA,IAAI,OAAO,EAAA,CAAG,KAAA,CAAM,KAAA,EAAO,MAAA,CAAO,KAAK,CAAA,EAAG;AACxC,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,KAAA,CAAM,OAAA,EAAS,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA;AAC/B,MAAA,KAAA,CAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,KAAA,CAAM,SAAS,KAAA,EAAO;AACxB,MAAA,IAAI,SAAS,KAAA,CAAM,KAAK,KAAK,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA,EAAG;AACnD,QAAA,MAAM,OAAO,EAAE,GAAG,MAAM,KAAA,EAAO,GAAG,OAAO,KAAA,EAAM;AAC/C,QAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,CAAE,IAAA;AAAA;AAAA,UAExC,CAAC,CAAA,KAAM,CAAC,MAAA,CAAO,EAAA,CAAI,KAAA,CAAM,KAAA,CAAc,CAAC,CAAA,EAAI,MAAA,CAAO,KAAA,CAAc,CAAC,CAAC;AAAA,SACrE;AAEA,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA,OAAO,KAAA;AAAA,QACT;AAEA,QAAA,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,KAAyB,CAAA;AACpD,QAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AACd,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAM,MAAA,CAAO,KAAyB,CAAA;AACpD,MAAA,KAAA,CAAM,QAAQ,MAAA,CAAO,KAAA;AACrB,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,IAAI,SAAS,KAAA,CAAM,KAAK,KAAK,QAAA,CAAS,MAAA,CAAO,KAAK,CAAA,EAAG;AACnD,MAAA,MAAM,OAAO,EAAE,GAAG,MAAM,KAAA,EAAO,GAAG,OAAO,KAAA,EAAM;AAC/C,MAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,CAAE,IAAA;AAAA;AAAA,QAExC,CAAC,CAAA,KAAM,CAAC,MAAA,CAAO,EAAA,CAAI,KAAA,CAAM,KAAA,CAAc,CAAC,CAAA,EAAI,MAAA,CAAO,KAAA,CAAc,CAAC,CAAC;AAAA,OACrE;AAEA,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAO,KAAA;AAAA,MACT;AAEA,MAAA,KAAA,CAAM,OAAA,EAAS,IAAI,IAAI,CAAA;AACvB,MAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AACd,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY,KAAA,CAAM,GAAG,CAAA,iCAAA,CAAmC,CAAA;AAAA,EAC1E,CAAA;AAEA,EAAA,MAAM,cAAA,GAAiB,CAAC,KAAA,KAAiC;AACvD,IAAA,IAAI,CAAC,MAAM,OAAA,EAAS;AAClB,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAS,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,GAAA,CAAI,CAAC,GAAA,KAAQ;AAC/C,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AACnC,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,MACnD;AACA,MAAA,OAAO,UAAA,CAAW,KAAA;AAAA,IACpB,CAAC,CAAA;AACD,IAAA,IACE,MAAM,OAAA,CAAQ,UAAA,IACd,MAAA,CAAO,KAAA,CAAM,CAAC,KAAA,EAAO,KAAA,KAAU,MAAA,CAAO,EAAA,CAAG,OAAO,KAAA,CAAM,OAAA,EAAS,aAAa,KAAK,CAAC,CAAC,CAAA,EACnF;AACA,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,GAAG,MAAM,CAAA;AAC5C,IAAA,MAAM,UAAU,CAAC,MAAA,CAAO,EAAA,CAAG,KAAA,CAAM,OAAO,IAAI,CAAA;AAC5C,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AACd,IAAA,KAAA,CAAM,QAAQ,UAAA,GAAa,MAAA;AAC3B,IAAA,OAAO,OAAA;AAAA,EACT,CAAA;AAEA,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC9B,IAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,MAAA;AAAA,IACF;AACA,IAAA,cAAA,CAAe,KAAK,CAAA;AAAA,EACtB;AAEA,EAAA,MAAM,UAAA,GAAa,CAAC,WAAA,KAA0B;AAC5C,IAAA,IAAI,OAAA,CAAQ,SAAS,CAAA,EAAG;AACtB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,GAAA,GAAM;AAAA,MACV,GAAA,EAAK,CAAK,GAAA,KAAgB,eAAA,CAAmB,GAAG,CAAA;AAAA,MAChD,KAAK,CAAK,GAAA,EAAa,KAAA,KAAa,eAAA,CAAgB,KAAK,KAAK,CAAA;AAAA,MAC9D,OAAO,CAAmB,GAAA,EAAa,KAAA,KACrC,iBAAA,CAAkB,KAAK,KAAK,CAAA;AAAA,MAC9B,aAAa,CAAC,EAAA,EAAgB,KAAA,KAC5B,WAAA,CAAY,IAAI,KAAK;AAAA,KACzB;AAEA,IAAA,KAAA,MAAWC,WAAU,OAAA,EAAS;AAC5B,MAAA,IAAI,CAACA,OAAAA,CAAO,IAAA,CAAK,IAAA,CAAK,CAAC,QAAQ,WAAA,CAAY,QAAA,CAAS,GAAG,CAAC,CAAA,EAAG;AACzD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAA,GAAQA,QAAO,QAAA,IAAY,CAAA;AACjC,MAAA,IAAI,mBAAmB,KAAA,EAAO;AAC5B,QAAA,MAAM,IAAI,KAAA;AAAA,UACR,CAAA,yDAAA,EAA4DA,OAAAA,CAAO,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,SACpF;AAAA,MACF;AACA,MAAAA,OAAAA,CAAO,IAAI,GAAG,CAAA;AAAA,IAChB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,SAAS,MAAM;AACnB,IAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,CAAA,IAAK,aAAA,CAAc,SAAS,CAAA,EAAG;AAClD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,cAAwB,EAAC;AAE/B,IAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC9B,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA;AAAA,MACF;AACA,MAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAC9B,MAAA,IAAI,MAAA,IAAU,CAAC,KAAA,CAAM,OAAA,EAAS;AAC5B,QAAA,MAAM,OAAA,GAAU,WAAA,CAAY,KAAA,EAAO,MAAM,CAAA;AACzC,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,YAAA,CAAa,KAAA,EAAO,MAAM,KAAK,CAAA;AAC/B,UAAA,WAAA,CAAY,KAAK,GAAG,CAAA;AAAA,QACtB;AACA,QAAA,OAAA,CAAQ,OAAO,GAAG,CAAA;AAAA,MACpB;AACA,MAAA,IAAI,MAAM,OAAA,EAAS;AACjB,QAAA,MAAM,cAAA,GAAiB,eAAe,KAAK,CAAA;AAC3C,QAAA,IAAI,cAAA,EAAgB;AAClB,UAAA,WAAA,CAAY,KAAK,GAAG,CAAA;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAC1B,MAAA,cAAA,CAAe,WAAW,CAAA;AAC1B,MAAA,kBAAA,CAAmB,OAAA,CAAQ;AAAA,QACzB,KAAA,EAAO,oBAAA;AAAA,QACP,SAAS,CAAC,GAAG,IAAI,GAAA,CAAI,WAAW,CAAC,CAAA;AAAA,QACjC,WAAW,GAAA;AAAI,OAChB,CAAA;AACD,MAAA,IAAI,kBAAA,CAAmB,SAAS,uBAAA,EAAyB;AACvD,QAAA,kBAAA,CAAmB,MAAA,GAAS,uBAAA;AAAA,MAC9B;AAAA,IACF;AAEA,IAAA,aAAA,CAAc,KAAA,EAAM;AACpB,IAAA,oBAAA,GAAuB,MAAA;AACvB,IAAA,UAAA,CAAW,WAAW,CAAA;AAAA,EACxB,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,CAAC,KAAA,KAAmB;AAC3C,IAAA,gBAAA,IAAoB,CAAA;AACpB,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,oBAAA,GAAuB,KAAA;AAAA,IACzB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,iBAAiB,MAAM;AAC3B,IAAA,gBAAA,IAAoB,CAAA;AACpB,IAAA,IAAI,qBAAqB,CAAA,EAAG;AAC1B,MAAA,MAAA,EAAO;AAAA,IACT;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,WAAA,GAAc,CAAC,EAAA,EAAgB,KAAA,KAAmB;AACtD,IAAA,gBAAA,CAAiB,KAAK,CAAA;AACtB,IAAA,IAAI;AACF,MAAA,EAAA,EAAG;AAAA,IACL,CAAA,SAAE;AACA,MAAA,cAAA,EAAe;AAAA,IACjB;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,CAAC,GAAA,EAAa,KAAA,KAAmB;AACvD,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG;AACtB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,IAC7C;AACA,IAAA,IAAI,qBAAqB,CAAA,EAAG;AAC1B,MAAA,OAAO,WAAA,CAAY,MAAM,eAAA,CAAgB,GAAA,EAAK,KAAK,CAAC,CAAA;AAAA,IACtD;AACA,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC9B,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,4BAAA,EAA+B,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,IACxD;AACA,IAAA,OAAA,CAAQ,IAAI,GAAA,EAAK,EAAE,IAAA,EAAM,KAAA,EAAO,OAAO,CAAA;AACvC,IAAA,WAAA,CAAY,GAAG,CAAA;AAAA,EACjB,CAAA;AAEA,EAAA,MAAM,iBAAA,GAAoB,CAAC,GAAA,EAAa,KAAA,KAA4B;AAClE,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG;AACtB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,IAC7C;AACA,IAAA,IAAI,qBAAqB,CAAA,EAAG;AAC1B,MAAA,OAAO,WAAA,CAAY,MAAM,iBAAA,CAAkB,GAAA,EAAK,KAAK,CAAC,CAAA;AAAA,IACxD;AACA,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC9B,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,IAC1D;AACA,IAAA,OAAA,CAAQ,IAAI,GAAA,EAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AACzC,IAAA,WAAA,CAAY,GAAG,CAAA;AAAA,EACjB,CAAA;AAEA,EAAA,MAAM,eAAA,GAAkB,CAAK,GAAA,KAAmB;AAC9C,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC9B,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,IAC7C;AACA,IAAA,OAAO,KAAA,CAAM,KAAA;AAAA,EACf,CAAA;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,GAAA,EAAa,EAAA,KAAmB;AACjD,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC9B,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,iBAAA,EAAoB,GAAG,CAAA,EAAA,CAAI,CAAA;AAAA,IAC7C;AACA,IAAA,KAAA,CAAM,WAAA,CAAY,IAAI,EAAE,CAAA;AACxB,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,CAAM,WAAA,CAAY,OAAO,EAAE,CAAA;AAAA,IAC7B,CAAA;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,UAAA,GAAa,CAAK,GAAA,KAAkC;AACxD,IAAA,OAAO;AAAA,MACL,GAAA,EAAK,MAAM,eAAA,CAAmB,GAAG,CAAA;AAAA,MACjC,GAAA,EAAK,CAAC,IAAA,KAAS,eAAA,CAAgB,KAAK,IAAI,CAAA;AAAA,MACxC,KAAA,EAAO,CAAC,IAAA,KAAS,iBAAA,CAAkB,KAAK,IAAwB,CAAA;AAAA,MAChE,SAAA,EAAW,CAAC,EAAA,KAAO,SAAA,CAAU,KAAK,EAAE;AAAA,KACtC;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,MAAA,GAAS,CAAC,UAAA,KAAiC;AAC/C,IAAA,OAAA,CAAQ,IAAI,UAAU,CAAA;AACtB,IAAA,OAAO,MAAM,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA;AAAA,EACxC,CAAA;AAEA,EAAA,MAAM,cAAc,MAAyB;AAC3C,IAAA,MAAM,WAA8B,EAAE,QAAA,EAAU,EAAC,EAAG,YAAA,EAAc,EAAC,EAAE;AACrE,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,QAAA,EAAU;AACnC,MAAA,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,GAAI,KAAA,CAAM,KAAA;AAAA,IACjC;AACA,IAAA,QAAA,CAAS,YAAA,GAAe,CAAC,GAAG,kBAAkB,CAAA;AAC9C,IAAA,OAAO,QAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,UAAU,MAAM;AACpB,IAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,KAAA,KAAU;AAC1B,MAAA,KAAA,CAAM,SAAS,OAAA,IAAU;AACzB,MAAA,IAAI,MAAM,YAAA,EAAc;AACtB,QAAA,YAAA,CAAa,MAAM,YAAY,CAAA;AAAA,MACjC;AACA,MAAA,KAAA,CAAM,YAAY,KAAA,EAAM;AAAA,IAC1B,CAAC,CAAA;AACD,IAAA,QAAA,CAAS,KAAA,EAAM;AACf,IAAA,OAAA,CAAQ,KAAA,EAAM;AACd,IAAA,OAAA,CAAQ,KAAA,EAAM;AAAA,EAChB,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,eAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA;AAAA,IACA;AAAA,GACF;AACF,CAAA;;;ACjfO,IAAM,cAAA,GAAiB,CAG5B,MAAA,KAC+B;AAC/B,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA;AAEpD,EAAA,MAAM,WAAqC,EAAC;AAE5C,EAAA,MAAM,UAA2C,EAAC;AAElD,EAAA,KAAA,MAAW,SAAS,cAAA,EAAgB;AAClC,IAAA,IAAI,YAAY,KAAA,EAAO;AACrB,MAAA,QAAA,CAAS,KAAK,KAAmC,CAAA;AAAA,IACnD,CAAA,MAAO;AACL,MAAA,OAAA,CAAQ,KAAK,KAA0C,CAAA;AAAA,IACzD;AAAA,EACF;AAEA,EAAA,MAAM,YAAY,eAAA,CAAgB;AAAA,IAChC,QAAA;AAAA,IACA,OAAA;AAAA,IACA,WAAW,MAAA,CAAO,SAAA;AAAA,IAClB,WAAW,MAAA,CAAO;AAAA,GACnB,CAAA;AAED,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,QAAA,EAAU,gBAAA;AAAA,IACV,YAAY,CAAC,GAAA,KAAQ,UAAA,CAAW,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,IAC3C,WAAA,EAAa,CAAC,GAAA,EAAK,QAAA,EAAU,QAAA,KAC3B,YAAY,MAAA,CAAO,GAAG,CAAA,EAAG,QAAA,EAAU,QAAQ;AAAA,GAC/C;AACF","file":"react.cjs","sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport type { Conductor } from \"../core/types\";\n\nconst SymphonyContext = createContext<Conductor | null>(null);\n\nexport type SymphonyProviderProps = {\n conductor: Conductor;\n children: React.ReactNode;\n};\n\nexport const SymphonyProvider = ({ conductor, children }: SymphonyProviderProps) => {\n return (\n <SymphonyContext.Provider value={conductor}>\n {children}\n </SymphonyContext.Provider>\n );\n};\n\nexport const useConductor = () => {\n const conductor = useContext(SymphonyContext);\n if (!conductor) {\n throw new Error(\"SymphonyProvider is missing in the React tree.\");\n }\n return conductor;\n};\n","import { useCallback, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { SectionHandle } from \"../core/types\";\nimport { useConductor } from \"./SymphonyProvider\";\n\nexport const useSection = <T,>(key: string): SectionHandle<T> & { value: T } => {\n const conductor = useConductor();\n\n const getSnapshot = useCallback(() => conductor.getSectionValue<T>(key), [\n conductor,\n key\n ]);\n\n const subscribe = useCallback(\n (cb: () => void) => conductor.subscribe(key, cb),\n [conductor, key]\n );\n\n const value = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n const handle = useMemo(\n () => ({\n value,\n get: () => value,\n set: (next: T) => conductor.getSection<T>(key).set(next),\n patch: (partial: Partial<T>) =>\n conductor.getSection<T>(key).patch(partial),\n subscribe: (cb: () => void) => conductor.subscribe(key, cb)\n }),\n [conductor, key, value, subscribe]\n );\n\n return handle;\n};\n\nexport const useSelector = <T, S>(\n key: string,\n selector: (value: T) => S,\n equality: (a: S, b: S) => boolean = Object.is\n) => {\n const conductor = useConductor();\n const selectedRef = useRef<S>();\n\n const getSnapshot = useCallback(() => {\n const value = conductor.getSectionValue<T>(key);\n const nextSelected = selector(value);\n if (\n selectedRef.current !== undefined &&\n equality(selectedRef.current, nextSelected)\n ) {\n return selectedRef.current;\n }\n selectedRef.current = nextSelected;\n return nextSelected;\n }, [conductor, key, selector, equality]);\n\n const subscribe = useCallback(\n (cb: () => void) => conductor.subscribe(key, cb),\n [conductor, key]\n );\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n};\n","import React from \"react\";\n\nexport type SymphonyScriptProps = {\n state: Record<string, unknown>;\n globalKey?: string;\n};\n\nconst escapeJson = (value: string) =>\n value.replace(/</g, \"\\\\u003c\").replace(/>/g, \"\\\\u003e\");\n\nexport const SymphonyScript = ({\n state,\n globalKey = \"__SYMPHONY_STATE__\"\n}: SymphonyScriptProps) => {\n const serialized = escapeJson(JSON.stringify(state));\n const script = `window[${JSON.stringify(globalKey)}]=${serialized};`;\n return (\n <script\n data-symphony\n dangerouslySetInnerHTML={{ __html: script }}\n />\n );\n};\n","import type { Scheduler } from \"./types\";\n\nconst scheduleMicrotask = (flush: () => void) => {\n if (typeof queueMicrotask === \"function\") {\n queueMicrotask(flush);\n return;\n }\n Promise.resolve().then(flush);\n};\n\nexport const createScheduler = (scheduler?: Scheduler) => {\n if (!scheduler || scheduler === \"microtask\") {\n return scheduleMicrotask;\n }\n if (scheduler === \"sync\") {\n return (flush: () => void) => flush();\n }\n if (scheduler === \"raf\") {\n return (flush: () => void) => {\n if (typeof requestAnimationFrame === \"function\") {\n requestAnimationFrame(() => flush());\n return;\n }\n scheduleMicrotask(flush);\n };\n }\n return scheduler;\n};\n","import { createScheduler } from \"./scheduler\";\nimport type {\n Conductor,\n ConductorSnapshot,\n DerivedSectionDefinition,\n EffectDefinition,\n PersistConfig,\n Scheduler,\n SectionDefinition,\n SectionHandle,\n SourceAdapter,\n Subscriber,\n TransactionInfo\n} from \"./types\";\n\nconst defaultPersist = <T,>(value: T, config: PersistConfig<T>) => {\n if (!config.storage) {\n return;\n }\n const serialize = config.serialize ?? JSON.stringify;\n config.storage.setItem(config.key, serialize(value));\n};\n\nconst readPersist = <T,>(config: PersistConfig<T>): T | undefined => {\n if (!config.storage) {\n return undefined;\n }\n const raw = config.storage.getItem(config.key);\n if (!raw) {\n return undefined;\n }\n const deserialize = config.deserialize ?? JSON.parse;\n return deserialize(raw) as T;\n};\n\ntype SectionState<T> = {\n key: string;\n adapter?: SourceAdapter<T>;\n subscribers: Set<Subscriber>;\n dependsOn: string[];\n persist?: PersistConfig<T>;\n persistTimer?: ReturnType<typeof setTimeout>;\n value: T;\n derived?: {\n inputs: string[];\n compute: (...values: unknown[]) => T;\n lastInputs?: unknown[];\n };\n};\n\ntype Update =\n | { type: \"set\"; value: unknown }\n | { type: \"patch\"; value: Partial<unknown> };\n\nconst now = () => Date.now();\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null;\n\nconst createDependencyOrder = (dependencies: Map<string, string[]>) => {\n const indegree = new Map<string, number>();\n const outgoing = new Map<string, string[]>();\n dependencies.forEach((deps, key) => {\n indegree.set(key, deps.length);\n deps.forEach((dep) => {\n if (!outgoing.has(dep)) {\n outgoing.set(dep, []);\n }\n outgoing.get(dep)?.push(key);\n });\n });\n\n const queue: string[] = [];\n indegree.forEach((count, key) => {\n if (count === 0) {\n queue.push(key);\n }\n });\n\n const order: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift();\n if (!current) {\n continue;\n }\n order.push(current);\n const children = outgoing.get(current) ?? [];\n for (const child of children) {\n const next = (indegree.get(child) ?? 0) - 1;\n indegree.set(child, next);\n if (next === 0) {\n queue.push(child);\n }\n }\n }\n\n if (order.length !== dependencies.size) {\n const cycle = [...dependencies.keys()].filter((key) => !order.includes(key));\n throw new Error(\n `Dependency cycle detected in sections: ${cycle.join(\", \")}`\n );\n }\n\n return order;\n};\n\nconst resolveStorage = <T,>(persist?: PersistConfig<T>): PersistConfig<T> | undefined => {\n if (!persist) {\n return undefined;\n }\n if (persist.storage) {\n return persist;\n }\n if (typeof window === \"undefined\") {\n return { ...persist, storage: null };\n }\n return { ...persist, storage: window.localStorage };\n};\n\nexport type ConductorConfig = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n sections: SectionDefinition<any>[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n derived?: DerivedSectionDefinition<any>[];\n scheduler?: Scheduler;\n bootstrap?: Record<string, unknown> | (() => Record<string, unknown> | undefined);\n transactionHistoryLimit?: number;\n};\n\nexport const createConductor = (config: ConductorConfig): Conductor => {\n const sections = new Map<string, SectionState<unknown>>();\n const updates = new Map<string, Update>();\n const effects = new Set<EffectDefinition>();\n const dependencies = new Map<string, string[]>();\n const scheduler = createScheduler(config.scheduler);\n const transactionHistory: TransactionInfo[] = [];\n const transactionHistoryLimit = config.transactionHistoryLimit ?? 20;\n\n const persistValue = <T,>(state: SectionState<T>, value: T) => {\n if (!state.persist) {\n return;\n }\n const persist = resolveStorage(state.persist);\n if (!persist?.storage) {\n return;\n }\n if (persist.throttleMs && persist.throttleMs > 0) {\n if (state.persistTimer) {\n clearTimeout(state.persistTimer);\n }\n state.persistTimer = setTimeout(() => {\n defaultPersist(value, persist);\n }, persist.throttleMs);\n return;\n }\n defaultPersist(value, persist);\n };\n\n const hydrateValue = <T,>(state: SectionState<T>) => {\n const persist = resolveStorage(state.persist);\n if (!persist?.storage) {\n return;\n }\n const stored = readPersist<T>(persist);\n if (stored !== undefined) {\n state.value = stored;\n state.adapter?.set(stored);\n }\n };\n\n const bootstrapValues = (() => {\n if (!config.bootstrap) {\n return undefined;\n }\n if (typeof config.bootstrap === \"function\") {\n return config.bootstrap();\n }\n return config.bootstrap;\n })();\n\n for (const definition of config.sections) {\n if (sections.has(definition.key)) {\n throw new Error(`Section with key \"${definition.key}\" already exists.`);\n }\n const dependsOn = definition.dependsOn ?? [];\n const state: SectionState<unknown> = {\n key: definition.key,\n adapter: definition.source,\n subscribers: new Set(),\n dependsOn,\n persist: definition.persist,\n value: definition.source.get()\n };\n sections.set(definition.key, state);\n dependencies.set(definition.key, dependsOn);\n }\n\n const derivedDefinitions = config.derived ?? [];\n for (const definition of derivedDefinitions) {\n if (sections.has(definition.key)) {\n throw new Error(`Section with key \"${definition.key}\" already exists.`);\n }\n const state: SectionState<unknown> = {\n key: definition.key,\n subscribers: new Set(),\n dependsOn: definition.inputs,\n value: undefined,\n derived: {\n inputs: definition.inputs,\n compute: definition.compute,\n lastInputs: undefined\n }\n };\n sections.set(definition.key, state);\n dependencies.set(definition.key, definition.inputs);\n }\n\n const order = createDependencyOrder(dependencies);\n\n for (const [key, state] of sections) {\n if (bootstrapValues && key in bootstrapValues) {\n const value = bootstrapValues[key] as typeof state.value;\n state.value = value;\n state.adapter?.set(value);\n continue;\n }\n if (state.persist) {\n hydrateValue(state);\n }\n }\n\n const stagedChanges = new Set<string>();\n const pendingNotifications = new Set<string>();\n let scheduled = false;\n let transactionDepth = 0;\n let lastTransactionLabel: string | undefined;\n\n const notifySubscribers = () => {\n scheduled = false;\n for (const key of pendingNotifications) {\n const state = sections.get(key);\n if (!state) {\n continue;\n }\n for (const subscriber of state.subscribers) {\n subscriber();\n }\n }\n pendingNotifications.clear();\n };\n\n const scheduleNotify = (keys: string[]) => {\n for (const key of keys) {\n pendingNotifications.add(key);\n }\n if (scheduled) {\n return;\n }\n scheduled = true;\n scheduler(notifySubscribers);\n };\n\n const markChanged = (key: string) => {\n stagedChanges.add(key);\n };\n\n const applyUpdate = (state: SectionState<unknown>, update: Update): boolean => {\n if (update.type === \"set\") {\n if (Object.is(state.value, update.value)) {\n return false;\n }\n state.adapter?.set(update.value);\n state.value = update.value;\n return true;\n }\n\n if (state.adapter?.patch) {\n if (isObject(state.value) && isObject(update.value)) {\n const next = { ...state.value, ...update.value };\n const changed = Object.keys(update.value).some(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (k) => !Object.is((state.value as any)[k], (update.value as any)[k])\n );\n\n if (!changed) {\n return false;\n }\n\n state.adapter.patch(update.value as Partial<unknown>);\n state.value = next;\n return true;\n }\n\n state.adapter.patch(update.value as Partial<unknown>);\n state.value = update.value;\n return true;\n }\n\n if (isObject(state.value) && isObject(update.value)) {\n const next = { ...state.value, ...update.value };\n const changed = Object.keys(update.value).some(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (k) => !Object.is((state.value as any)[k], (update.value as any)[k])\n );\n\n if (!changed) {\n return false;\n }\n\n state.adapter?.set(next);\n state.value = next;\n return true;\n }\n\n throw new Error(`Section \"${state.key}\" does not support patch updates.`);\n };\n\n const computeDerived = (state: SectionState<unknown>) => {\n if (!state.derived) {\n return false;\n }\n const inputs = state.derived.inputs.map((key) => {\n const inputState = sections.get(key);\n if (!inputState) {\n throw new Error(`Missing input section \"${key}\".`);\n }\n return inputState.value;\n });\n if (\n state.derived.lastInputs &&\n inputs.every((value, index) => Object.is(value, state.derived?.lastInputs?.[index]))\n ) {\n return false;\n }\n const next = state.derived.compute(...inputs);\n const changed = !Object.is(state.value, next);\n state.value = next;\n state.derived.lastInputs = inputs;\n return changed;\n };\n\n for (const key of order) {\n const state = sections.get(key);\n if (!state?.derived) {\n continue;\n }\n computeDerived(state);\n }\n\n const runEffects = (changedKeys: string[]) => {\n if (effects.size === 0) {\n return;\n }\n const api = {\n get: <T,>(key: string) => getSectionValue<T>(key),\n set: <T,>(key: string, value: T) => setSectionValue(key, value),\n patch: <T extends object>(key: string, value: Partial<T>) =>\n patchSectionValue(key, value),\n transaction: (fn: () => void, label?: string) =>\n transaction(fn, label)\n };\n\n for (const effect of effects) {\n if (!effect.when.some((key) => changedKeys.includes(key))) {\n continue;\n }\n const limit = effect.maxDepth ?? 5;\n if (transactionDepth > limit) {\n throw new Error(\n `Effect depth exceeded while running effect for sections: ${effect.when.join(\", \")}`\n );\n }\n effect.run(api);\n }\n };\n\n const commit = () => {\n if (updates.size === 0 && stagedChanges.size === 0) {\n return;\n }\n const changedKeys: string[] = [];\n\n for (const key of order) {\n const state = sections.get(key);\n if (!state) {\n continue;\n }\n const update = updates.get(key);\n if (update && !state.derived) {\n const changed = applyUpdate(state, update);\n if (changed) {\n persistValue(state, state.value);\n changedKeys.push(key);\n }\n updates.delete(key);\n }\n if (state.derived) {\n const derivedChanged = computeDerived(state);\n if (derivedChanged) {\n changedKeys.push(key);\n }\n }\n }\n\n if (changedKeys.length > 0) {\n scheduleNotify(changedKeys);\n transactionHistory.unshift({\n label: lastTransactionLabel,\n touched: [...new Set(changedKeys)],\n timestamp: now()\n });\n if (transactionHistory.length > transactionHistoryLimit) {\n transactionHistory.length = transactionHistoryLimit;\n }\n }\n\n stagedChanges.clear();\n lastTransactionLabel = undefined;\n runEffects(changedKeys);\n };\n\n const beginTransaction = (label?: string) => {\n transactionDepth += 1;\n if (label) {\n lastTransactionLabel = label;\n }\n };\n\n const endTransaction = () => {\n transactionDepth -= 1;\n if (transactionDepth === 0) {\n commit();\n }\n };\n\n const transaction = (fn: () => void, label?: string) => {\n beginTransaction(label);\n try {\n fn();\n } finally {\n endTransaction();\n }\n };\n\n const setSectionValue = (key: string, value: unknown) => {\n if (!sections.has(key)) {\n throw new Error(`Unknown section \"${key}\".`);\n }\n if (transactionDepth === 0) {\n return transaction(() => setSectionValue(key, value));\n }\n const state = sections.get(key);\n if (state?.derived) {\n throw new Error(`Cannot set derived section \"${key}\".`);\n }\n updates.set(key, { type: \"set\", value });\n markChanged(key);\n };\n\n const patchSectionValue = (key: string, value: Partial<unknown>) => {\n if (!sections.has(key)) {\n throw new Error(`Unknown section \"${key}\".`);\n }\n if (transactionDepth === 0) {\n return transaction(() => patchSectionValue(key, value));\n }\n const state = sections.get(key);\n if (state?.derived) {\n throw new Error(`Cannot patch derived section \"${key}\".`);\n }\n updates.set(key, { type: \"patch\", value });\n markChanged(key);\n };\n\n const getSectionValue = <T,>(key: string): T => {\n const state = sections.get(key);\n if (!state) {\n throw new Error(`Unknown section \"${key}\".`);\n }\n return state.value as T;\n };\n\n const subscribe = (key: string, cb: Subscriber) => {\n const state = sections.get(key);\n if (!state) {\n throw new Error(`Unknown section \"${key}\".`);\n }\n state.subscribers.add(cb);\n return () => {\n state.subscribers.delete(cb);\n };\n };\n\n const getSection = <T,>(key: string): SectionHandle<T> => {\n return {\n get: () => getSectionValue<T>(key),\n set: (next) => setSectionValue(key, next),\n patch: (next) => patchSectionValue(key, next as Partial<unknown>),\n subscribe: (cb) => subscribe(key, cb)\n };\n };\n\n const effect = (definition: EffectDefinition) => {\n effects.add(definition);\n return () => effects.delete(definition);\n };\n\n const getSnapshot = (): ConductorSnapshot => {\n const snapshot: ConductorSnapshot = { sections: {}, transactions: [] };\n for (const [key, state] of sections) {\n snapshot.sections[key] = state.value;\n }\n snapshot.transactions = [...transactionHistory];\n return snapshot;\n };\n\n const destroy = () => {\n sections.forEach((state) => {\n state.adapter?.destroy?.();\n if (state.persistTimer) {\n clearTimeout(state.persistTimer);\n }\n state.subscribers.clear();\n });\n sections.clear();\n updates.clear();\n effects.clear();\n };\n\n return {\n getSection,\n getSectionValue,\n subscribe,\n transaction,\n effect,\n getSnapshot,\n destroy\n };\n};\n","import type {\n Conductor,\n DerivedSectionDefinition,\n Scheduler,\n SectionDefinition\n} from \"../core/types\";\nimport { createConductor } from \"../core/conductor\";\nimport { SymphonyProvider } from \"./SymphonyProvider\";\nimport { useSection, useSelector } from \"./hooks\";\n\ntype AnySectionDefinition =\n | SectionDefinition<unknown>\n | DerivedSectionDefinition<unknown>;\n\ntype SectionValues<Sections extends Record<string, AnySectionDefinition>> = {\n [K in keyof Sections]: Sections[K] extends SectionDefinition<infer T>\n ? T\n : Sections[K] extends DerivedSectionDefinition<infer T>\n ? T\n : never;\n};\n\nexport type CreateSymphonyConfig<Sections extends Record<string, AnySectionDefinition>> = {\n sections: Sections;\n scheduler?: Scheduler;\n bootstrap?: Record<string, unknown> | (() => Record<string, unknown> | undefined);\n};\n\nexport type SymphonyInstance<Sections extends Record<string, AnySectionDefinition>> = {\n conductor: Conductor;\n Provider: typeof SymphonyProvider;\n useSection: <K extends keyof Sections>(\n key: K\n ) => ReturnType<typeof useSection<SectionValues<Sections>[K]>>;\n useSelector: <K extends keyof Sections, S>(\n key: K,\n selector: (value: SectionValues<Sections>[K]) => S,\n equality?: (a: S, b: S) => boolean\n ) => S;\n};\n\nexport const createSymphony = <\n Sections extends Record<string, AnySectionDefinition>\n>(\n config: CreateSymphonyConfig<Sections>\n): SymphonyInstance<Sections> => {\n const sectionEntries = Object.values(config.sections);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sections: SectionDefinition<any>[] = [];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const derived: DerivedSectionDefinition<any>[] = [];\n\n for (const entry of sectionEntries) {\n if (\"source\" in entry) {\n sections.push(entry as SectionDefinition<unknown>);\n } else {\n derived.push(entry as DerivedSectionDefinition<unknown>);\n }\n }\n\n const conductor = createConductor({\n sections,\n derived,\n scheduler: config.scheduler,\n bootstrap: config.bootstrap\n });\n\n return {\n conductor,\n Provider: SymphonyProvider,\n useSection: (key) => useSection(String(key)),\n useSelector: (key, selector, equality) =>\n useSelector(String(key), selector, equality)\n };\n};\n"]}
|