@hedystia/view 2.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 (102) hide show
  1. package/dist/constants.cjs +13 -0
  2. package/dist/constants.cjs.map +1 -0
  3. package/dist/constants.mjs +13 -0
  4. package/dist/constants.mjs.map +1 -0
  5. package/dist/context/context.cjs +51 -0
  6. package/dist/context/context.cjs.map +1 -0
  7. package/dist/context/context.d.cts +25 -0
  8. package/dist/context/context.d.mts +25 -0
  9. package/dist/context/context.mjs +50 -0
  10. package/dist/context/context.mjs.map +1 -0
  11. package/dist/fetch/resource.cjs +89 -0
  12. package/dist/fetch/resource.cjs.map +1 -0
  13. package/dist/fetch/resource.d.cts +14 -0
  14. package/dist/fetch/resource.d.mts +14 -0
  15. package/dist/fetch/resource.mjs +88 -0
  16. package/dist/fetch/resource.mjs.map +1 -0
  17. package/dist/index.cjs +58 -0
  18. package/dist/index.d.cts +15 -0
  19. package/dist/index.d.mts +15 -0
  20. package/dist/index.mjs +14 -0
  21. package/dist/jsx/element.cjs +201 -0
  22. package/dist/jsx/element.cjs.map +1 -0
  23. package/dist/jsx/element.d.cts +48 -0
  24. package/dist/jsx/element.d.mts +48 -0
  25. package/dist/jsx/element.mjs +199 -0
  26. package/dist/jsx/element.mjs.map +1 -0
  27. package/dist/jsx-dev-runtime.cjs +40 -0
  28. package/dist/jsx-dev-runtime.cjs.map +1 -0
  29. package/dist/jsx-dev-runtime.d.cts +21 -0
  30. package/dist/jsx-dev-runtime.d.mts +21 -0
  31. package/dist/jsx-dev-runtime.mjs +36 -0
  32. package/dist/jsx-dev-runtime.mjs.map +1 -0
  33. package/dist/jsx-runtime.cjs +5 -0
  34. package/dist/jsx-runtime.d.cts +3 -0
  35. package/dist/jsx-runtime.d.mts +3 -0
  36. package/dist/jsx-runtime.mjs +2 -0
  37. package/dist/jsx.d.cts +942 -0
  38. package/dist/jsx.d.mts +942 -0
  39. package/dist/lifecycle/hooks.cjs +56 -0
  40. package/dist/lifecycle/hooks.cjs.map +1 -0
  41. package/dist/lifecycle/hooks.d.cts +37 -0
  42. package/dist/lifecycle/hooks.d.mts +37 -0
  43. package/dist/lifecycle/hooks.mjs +54 -0
  44. package/dist/lifecycle/hooks.mjs.map +1 -0
  45. package/dist/render/engine.cjs +52 -0
  46. package/dist/render/engine.cjs.map +1 -0
  47. package/dist/render/engine.d.cts +31 -0
  48. package/dist/render/engine.d.mts +31 -0
  49. package/dist/render/engine.mjs +51 -0
  50. package/dist/render/engine.mjs.map +1 -0
  51. package/dist/render/flow.cjs +286 -0
  52. package/dist/render/flow.cjs.map +1 -0
  53. package/dist/render/flow.d.cts +64 -0
  54. package/dist/render/flow.d.mts +64 -0
  55. package/dist/render/flow.mjs +279 -0
  56. package/dist/render/flow.mjs.map +1 -0
  57. package/dist/scheduler/scheduler.cjs +61 -0
  58. package/dist/scheduler/scheduler.cjs.map +1 -0
  59. package/dist/scheduler/scheduler.d.cts +31 -0
  60. package/dist/scheduler/scheduler.d.mts +31 -0
  61. package/dist/scheduler/scheduler.mjs +59 -0
  62. package/dist/scheduler/scheduler.mjs.map +1 -0
  63. package/dist/signal/signal.cjs +387 -0
  64. package/dist/signal/signal.cjs.map +1 -0
  65. package/dist/signal/signal.d.cts +44 -0
  66. package/dist/signal/signal.d.mts +44 -0
  67. package/dist/signal/signal.mjs +370 -0
  68. package/dist/signal/signal.mjs.map +1 -0
  69. package/dist/store/index.cjs +1 -0
  70. package/dist/store/index.mjs +2 -0
  71. package/dist/store/store.cjs +94 -0
  72. package/dist/store/store.cjs.map +1 -0
  73. package/dist/store/store.d.cts +22 -0
  74. package/dist/store/store.d.mts +22 -0
  75. package/dist/store/store.mjs +91 -0
  76. package/dist/store/store.mjs.map +1 -0
  77. package/dist/style/computed.cjs +65 -0
  78. package/dist/style/computed.cjs.map +1 -0
  79. package/dist/style/computed.d.cts +18 -0
  80. package/dist/style/computed.d.mts +18 -0
  81. package/dist/style/computed.mjs +63 -0
  82. package/dist/style/computed.mjs.map +1 -0
  83. package/dist/text/text.cjs +74 -0
  84. package/dist/text/text.cjs.map +1 -0
  85. package/dist/text/text.d.cts +31 -0
  86. package/dist/text/text.d.mts +31 -0
  87. package/dist/text/text.mjs +72 -0
  88. package/dist/text/text.mjs.map +1 -0
  89. package/dist/types.d.cts +185 -0
  90. package/dist/types.d.mts +185 -0
  91. package/dist/utils/index.cjs +34 -0
  92. package/dist/utils/index.cjs.map +1 -0
  93. package/dist/utils/index.mjs +33 -0
  94. package/dist/utils/index.mjs.map +1 -0
  95. package/dist/watch/watcher.cjs +71 -0
  96. package/dist/watch/watcher.cjs.map +1 -0
  97. package/dist/watch/watcher.d.cts +17 -0
  98. package/dist/watch/watcher.d.mts +17 -0
  99. package/dist/watch/watcher.mjs +70 -0
  100. package/dist/watch/watcher.mjs.map +1 -0
  101. package/package.json +34 -0
  102. package/readme.md +395 -0
@@ -0,0 +1,370 @@
1
+ import { equalFn } from "../utils/index.mjs";
2
+ //#region src/signal/signal.ts
3
+ /** @internal */
4
+ let Owner = null;
5
+ /** @internal */
6
+ let Listener = null;
7
+ /** @internal */
8
+ let Updates = null;
9
+ /** @internal */
10
+ let Pending = null;
11
+ /**
12
+ * Create a reactive signal with an initial value
13
+ */
14
+ function sig(initial, options) {
15
+ return {
16
+ _value: initial,
17
+ _observers: null,
18
+ _observerSlots: null,
19
+ _comparator: options?.equals !== void 0 ? options.equals : equalFn
20
+ };
21
+ }
22
+ /**
23
+ * Read the value of a signal, registering a dependency if inside a reactive context
24
+ */
25
+ function val(signal) {
26
+ if (Listener !== null) {
27
+ if (signal._observers === null) {
28
+ signal._observers = [];
29
+ signal._observerSlots = [];
30
+ }
31
+ let index = signal._observers.indexOf(Listener);
32
+ if (index === -1) {
33
+ index = signal._observers.length;
34
+ signal._observers.push(Listener);
35
+ signal._observerSlots.push(Listener._sources === null ? 0 : Listener._sources.length);
36
+ if (Listener._sources === null) {
37
+ Listener._sources = [];
38
+ Listener._sourceSlots = [];
39
+ }
40
+ Listener._sources.push(signal);
41
+ Listener._sourceSlots.push(index);
42
+ }
43
+ }
44
+ const computed = signal;
45
+ if (computed._state === 1) recompute(computed);
46
+ return signal._value;
47
+ }
48
+ /** @internal - Remove a computation from all its source observer lists */
49
+ function cleanupSources(computation) {
50
+ if (computation._sources !== null) {
51
+ for (let j = computation._sources.length - 1; j >= 0; j--) {
52
+ const source = computation._sources[j];
53
+ const index = computation._sourceSlots[j];
54
+ const obs = source._observers;
55
+ const obsSlots = source._observerSlots;
56
+ if (obs && obsSlots && index < obs.length) {
57
+ const last = obs.pop();
58
+ const lastSlot = obsSlots.pop();
59
+ if (index < obs.length) {
60
+ obs[index] = last;
61
+ obsSlots[index] = lastSlot;
62
+ if (last._sourceSlots) last._sourceSlots[lastSlot] = index;
63
+ }
64
+ }
65
+ }
66
+ computation._sources = null;
67
+ computation._sourceSlots = null;
68
+ }
69
+ }
70
+ /** @internal - Run a computation with proper Listener tracking */
71
+ function runComputation(computation) {
72
+ const prevListener = Listener;
73
+ const prevOwner = Owner;
74
+ cleanupSources(computation);
75
+ Listener = computation;
76
+ Owner = computation._owner;
77
+ try {
78
+ const value = computation._fn(computation._value);
79
+ computation._value = value;
80
+ computation._state = 0;
81
+ const computed = computation._computed;
82
+ if (computed) {
83
+ computed._value = value;
84
+ computed._state = 0;
85
+ }
86
+ return value;
87
+ } finally {
88
+ Listener = prevListener;
89
+ Owner = prevOwner;
90
+ }
91
+ }
92
+ /** @internal */
93
+ function recompute(computed) {
94
+ const computation = computed._computation;
95
+ if (!computation?._fn) return;
96
+ runComputation(computation);
97
+ }
98
+ /**
99
+ * Set the value of a signal, notifying dependents
100
+ */
101
+ function set(signal, value) {
102
+ const comparator = signal._comparator;
103
+ if (comparator?.(signal._value, value)) return value;
104
+ signal._value = value;
105
+ if (signal._observers !== null) scheduleUpdate(signal);
106
+ return value;
107
+ }
108
+ /**
109
+ * Update a signal's value using a function of the previous value
110
+ */
111
+ function update(signal, fn) {
112
+ return set(signal, fn(signal._value));
113
+ }
114
+ /**
115
+ * Read a signal's value without registering a dependency
116
+ */
117
+ function peek(signal) {
118
+ return signal._value;
119
+ }
120
+ /** @internal - Propagate stale state through computed/memo observers */
121
+ function markDownstream(node) {
122
+ const observers = node._observers;
123
+ if (!observers) return;
124
+ for (let i = 0; i < observers.length; i++) {
125
+ const observer = observers[i];
126
+ if (observer._state !== 0) continue;
127
+ observer._state = 1;
128
+ const computed = observer._computed;
129
+ if (computed) {
130
+ computed._state = 1;
131
+ markDownstream(computed);
132
+ }
133
+ if (observer._user) {
134
+ if (Pending === null) Pending = [];
135
+ Pending.push(observer);
136
+ }
137
+ }
138
+ }
139
+ /** @internal */
140
+ function scheduleUpdate(signal) {
141
+ const observers = signal._observers;
142
+ if (observers === null) return;
143
+ for (let i = 0; i < observers.length; i++) {
144
+ const observer = observers[i];
145
+ if (observer._state === 0) {
146
+ observer._state = 1;
147
+ const computed = observer._computed;
148
+ if (computed) {
149
+ computed._state = 1;
150
+ markDownstream(computed);
151
+ }
152
+ if (Pending === null) Pending = [];
153
+ Pending.push(observer);
154
+ }
155
+ }
156
+ if (Updates === null) flushUpdates();
157
+ }
158
+ /** @internal */
159
+ function flushUpdates() {
160
+ const updates = Pending;
161
+ Pending = null;
162
+ if (updates === null) return;
163
+ for (let i = 0; i < updates.length; i++) {
164
+ const computation = updates[i];
165
+ if (computation._user && computation._state === 1) runComputation(computation);
166
+ }
167
+ Updates = null;
168
+ }
169
+ /**
170
+ * Create a derived reactive signal (computed value)
171
+ */
172
+ function memo(fn) {
173
+ const computed = {
174
+ _fn: fn,
175
+ _value: void 0,
176
+ _observers: null,
177
+ _observerSlots: null,
178
+ _sources: null,
179
+ _sourceSlots: null,
180
+ _state: 1
181
+ };
182
+ const computation = {
183
+ _fn: fn,
184
+ _value: void 0,
185
+ _sources: null,
186
+ _sourceSlots: null,
187
+ _observers: null,
188
+ _observerSlots: null,
189
+ _owner: Owner,
190
+ _cleanups: null,
191
+ _context: null,
192
+ _suspense: null,
193
+ _user: false,
194
+ _pure: true,
195
+ _state: 1,
196
+ _updatedAt: null
197
+ };
198
+ computed._computation = computation;
199
+ computation._computed = computed;
200
+ const callable = (() => {
201
+ if (computed._state === 1) recompute(computed);
202
+ return computed._value;
203
+ });
204
+ Object.defineProperty(callable, "_state", {
205
+ get() {
206
+ return computed._state;
207
+ },
208
+ set(v) {
209
+ computed._state = v;
210
+ },
211
+ enumerable: true,
212
+ configurable: true
213
+ });
214
+ Object.defineProperty(callable, "_value", {
215
+ get() {
216
+ return computed._value;
217
+ },
218
+ set(v) {
219
+ computed._value = v;
220
+ },
221
+ enumerable: true,
222
+ configurable: true
223
+ });
224
+ Object.defineProperty(callable, "_observers", {
225
+ get() {
226
+ return computed._observers;
227
+ },
228
+ set(v) {
229
+ computed._observers = v;
230
+ },
231
+ enumerable: true,
232
+ configurable: true
233
+ });
234
+ Object.defineProperty(callable, "_observerSlots", {
235
+ get() {
236
+ return computed._observerSlots;
237
+ },
238
+ set(v) {
239
+ computed._observerSlots = v;
240
+ },
241
+ enumerable: true,
242
+ configurable: true
243
+ });
244
+ Object.defineProperty(callable, "_sources", {
245
+ get() {
246
+ return computed._sources;
247
+ },
248
+ set(v) {
249
+ computed._sources = v;
250
+ },
251
+ enumerable: true,
252
+ configurable: true
253
+ });
254
+ Object.defineProperty(callable, "_sourceSlots", {
255
+ get() {
256
+ return computed._sourceSlots;
257
+ },
258
+ set(v) {
259
+ computed._sourceSlots = v;
260
+ },
261
+ enumerable: true,
262
+ configurable: true
263
+ });
264
+ Object.defineProperty(callable, "_fn", {
265
+ get() {
266
+ return computed._fn;
267
+ },
268
+ enumerable: true,
269
+ configurable: true
270
+ });
271
+ Object.defineProperty(callable, "_computation", {
272
+ get() {
273
+ return computed._computation;
274
+ },
275
+ set(v) {
276
+ computed._computation = v;
277
+ },
278
+ enumerable: true,
279
+ configurable: true
280
+ });
281
+ recompute(computed);
282
+ return callable;
283
+ }
284
+ /**
285
+ * Execute a function without tracking signal dependencies
286
+ */
287
+ function untrack(fn) {
288
+ const prevListener = Listener;
289
+ Listener = null;
290
+ try {
291
+ return fn();
292
+ } finally {
293
+ Listener = prevListener;
294
+ }
295
+ }
296
+ /**
297
+ * Batch multiple signal updates into a single reactive cycle
298
+ */
299
+ function batch(fn) {
300
+ const prevUpdates = Updates;
301
+ const prevPending = Pending;
302
+ Updates = [];
303
+ Pending = [];
304
+ try {
305
+ fn();
306
+ } finally {
307
+ if (prevPending !== null && prevPending.length > 0) Pending = prevPending.concat(Pending);
308
+ Updates = prevUpdates;
309
+ flushUpdates();
310
+ }
311
+ }
312
+ /**
313
+ * Create a reactive root context
314
+ */
315
+ function createRoot(fn) {
316
+ const prevOwner = Owner;
317
+ const prevListener = Listener;
318
+ const root = {
319
+ _owned: null,
320
+ _cleanups: null,
321
+ _owner: prevOwner,
322
+ _context: null
323
+ };
324
+ Owner = root;
325
+ Listener = null;
326
+ try {
327
+ return fn(() => cleanRoot(root));
328
+ } finally {
329
+ Owner = prevOwner;
330
+ Listener = prevListener;
331
+ }
332
+ }
333
+ /** @internal */
334
+ function cleanRoot(root) {
335
+ if (root._cleanups !== null) {
336
+ const cleanups = root._cleanups;
337
+ root._cleanups = null;
338
+ for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i]();
339
+ }
340
+ if (root._owned !== null) {
341
+ const owned = root._owned;
342
+ root._owned = null;
343
+ for (let i = 0; i < owned.length; i++) cleanNode(owned[i]);
344
+ }
345
+ }
346
+ /**
347
+ * Register a cleanup callback to run when the owner is disposed
348
+ */
349
+ function onCleanup(fn) {
350
+ if (Owner === null) return;
351
+ if (Owner._cleanups === null) Owner._cleanups = [];
352
+ Owner._cleanups.push(fn);
353
+ }
354
+ /** @internal */
355
+ function cleanNode(node) {
356
+ if ("_cleanups" in node && node._cleanups !== null) {
357
+ const cleanups = node._cleanups;
358
+ node._cleanups = null;
359
+ for (let i = cleanups.length - 1; i >= 0; i--) cleanups[i]();
360
+ }
361
+ if ("_owned" in node && node._owned !== null) {
362
+ const owned = node._owned;
363
+ node._owned = null;
364
+ for (let i = 0; i < owned.length; i++) cleanNode(owned[i]);
365
+ }
366
+ }
367
+ //#endregion
368
+ export { Owner, batch, cleanupSources, createRoot, memo, onCleanup, peek, runComputation, set, sig, untrack, update, val };
369
+
370
+ //# sourceMappingURL=signal.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal.mjs","names":[],"sources":["../../src/signal/signal.ts"],"sourcesContent":["/**\n * Reactive signal system for @hedystia/view\n *\n * Signals provide mutable state with automatic dependency tracking.\n */\n\nimport type {\n Computation,\n Computed,\n EffectFunction,\n Owner as OwnerType,\n Signal,\n SignalOptions,\n} from \"../types\";\nimport { equalFn } from \"../utils\";\n\n/** @internal */\nexport let Owner: OwnerType | null = null;\n\n/** @internal */\nexport let Listener: Computation<any> | null = null;\n\n/** @internal */\nlet Updates: Computation<any>[] | null = null;\n\n/** @internal */\nconst _Effects: Computation<any>[] | null = null;\n\n/** @internal */\nexport let Pending: Computation<any>[] | null = null;\n\n/**\n * Create a reactive signal with an initial value\n */\nexport function sig<T>(initial: T, options?: SignalOptions<T>): Signal<T> {\n const s: Signal<T> = {\n _value: initial,\n _observers: null,\n _observerSlots: null,\n _comparator: options?.equals !== undefined ? (options.equals as any) : equalFn,\n };\n return s;\n}\n\n/**\n * Read the value of a signal, registering a dependency if inside a reactive context\n */\nexport function val<T>(signal: Signal<T> | Computed<T>): T {\n if (Listener !== null) {\n if (signal._observers === null) {\n signal._observers = [];\n signal._observerSlots = [];\n }\n\n // Check if already registered\n let index = signal._observers.indexOf(Listener);\n if (index === -1) {\n index = signal._observers.length;\n signal._observers.push(Listener);\n signal._observerSlots!.push(Listener._sources === null ? 0 : Listener._sources.length);\n\n if (Listener._sources === null) {\n Listener._sources = [];\n Listener._sourceSlots = [];\n }\n Listener._sources.push(signal);\n Listener._sourceSlots!.push(index);\n }\n }\n\n // Check if computed needs re-evaluation\n const computed = signal as Computed<T>;\n if (computed._state === 1) {\n recompute(computed);\n }\n\n return signal._value;\n}\n\n/** @internal - Remove a computation from all its source observer lists */\nexport function cleanupSources(computation: Computation<any>): void {\n if (computation._sources !== null) {\n for (let j = computation._sources.length - 1; j >= 0; j--) {\n const source: Signal<any> = computation._sources[j]!;\n const index = computation._sourceSlots![j]!;\n const obs = source._observers;\n const obsSlots: number[] | null = source._observerSlots;\n if (obs && obsSlots && index < obs.length) {\n // Swap-and-pop: move last observer into this slot\n const last = obs.pop()!;\n const lastSlot = obsSlots.pop()!;\n if (index < obs.length) {\n obs[index] = last;\n obsSlots[index] = lastSlot;\n // Update the swapped observer's _sourceSlots to point to new index\n if (last._sourceSlots) {\n last._sourceSlots[lastSlot] = index;\n }\n }\n }\n }\n computation._sources = null;\n computation._sourceSlots = null;\n }\n}\n\n/** @internal - Run a computation with proper Listener tracking */\nexport function runComputation<T>(computation: Computation<T>): T | undefined {\n const prevListener = Listener;\n const prevOwner = Owner;\n\n cleanupSources(computation);\n Listener = computation;\n Owner = computation._owner;\n\n try {\n const value = computation._fn(computation._value as any);\n computation._value = value;\n computation._state = 0;\n\n const computed = (computation as any)._computed as Computed<T> | undefined;\n if (computed) {\n computed._value = value as T;\n computed._state = 0;\n }\n\n return value;\n } finally {\n Listener = prevListener;\n Owner = prevOwner;\n }\n}\n\n/** @internal */\nfunction recompute<T>(computed: Computed<T>): void {\n const computation = (computed as any)._computation as Computation<T>;\n if (!computation?._fn) {\n return;\n }\n runComputation(computation);\n}\n\n/**\n * Set the value of a signal, notifying dependents\n */\nexport function set<T>(signal: Signal<T>, value: T): T {\n const comparator = signal._comparator;\n if (comparator?.(signal._value, value)) {\n return value;\n }\n signal._value = value;\n if (signal._observers !== null) {\n scheduleUpdate(signal);\n }\n return value;\n}\n\n/**\n * Update a signal's value using a function of the previous value\n */\nexport function update<T>(signal: Signal<T>, fn: (prev: T) => T): T {\n const value = fn(signal._value);\n return set(signal, value);\n}\n\n/**\n * Read a signal's value without registering a dependency\n */\nexport function peek<T>(signal: Signal<T>): T {\n return signal._value;\n}\n\n/** @internal - Propagate stale state through computed/memo observers */\nfunction markDownstream(node: { _observers: Computation<any>[] | null }): void {\n const observers = node._observers;\n if (!observers) {\n return;\n }\n\n for (let i = 0; i < observers.length; i++) {\n const observer = observers[i]!;\n if (observer._state !== 0) {\n continue;\n }\n\n observer._state = 1;\n\n const computed = (observer as any)._computed as Computed<any> | undefined;\n if (computed) {\n computed._state = 1;\n markDownstream(computed);\n }\n\n if (observer._user) {\n if (Pending === null) {\n Pending = [];\n }\n Pending.push(observer);\n }\n }\n}\n\n/** @internal */\nfunction scheduleUpdate<T>(signal: Signal<T>): void {\n const observers = signal._observers;\n if (observers === null) {\n return;\n }\n\n for (let i = 0; i < observers.length; i++) {\n const observer = observers[i]!;\n if (observer._state === 0) {\n observer._state = 1;\n\n const computed = (observer as any)._computed as any;\n if (computed) {\n computed._state = 1;\n // Propagate stale state through downstream observers of this computed\n markDownstream(computed);\n }\n\n if (Pending === null) {\n Pending = [];\n }\n Pending.push(observer);\n }\n }\n\n // Only flush if not in a batch\n if (Updates === null) {\n flushUpdates();\n }\n}\n\n/** @internal */\nfunction flushUpdates(): void {\n const updates = Pending;\n Pending = null;\n if (updates === null) {\n return;\n }\n\n for (let i = 0; i < updates.length; i++) {\n const computation = updates[i]!;\n\n if (computation._user && computation._state === 1) {\n runComputation(computation);\n }\n // Non-user computations (memos) stay stale for lazy re-evaluation.\n // Don't force _state=1 here — recompute() may have already resolved it to 0.\n }\n Updates = null;\n}\n\n/**\n * Create a derived reactive signal (computed value)\n */\nexport function memo<T>(fn: () => T): Computed<T> {\n const computed: Computed<T> = {\n _fn: fn,\n _value: undefined as T,\n _observers: null,\n _observerSlots: null,\n _sources: null,\n _sourceSlots: null,\n _state: 1,\n } as Computed<T>;\n\n const computation: Computation<T> = {\n _fn: fn as EffectFunction<T>,\n _value: undefined,\n _sources: null,\n _sourceSlots: null,\n _observers: null,\n _observerSlots: null,\n _owner: Owner,\n _cleanups: null,\n _context: null,\n _suspense: null,\n _user: false,\n _pure: true,\n _state: 1,\n _updatedAt: null,\n };\n\n // Link computed and computation bidirectionally\n (computed as any)._computation = computation;\n (computation as any)._computed = computed;\n\n // Make computed callable and proxy all properties to computed\n const callable = (() => {\n if (computed._state === 1) {\n recompute(computed);\n }\n return computed._value;\n }) as Computed<T>;\n\n // Proxy all properties to computed so they stay in sync\n Object.defineProperty(callable, \"_state\", {\n get() {\n return computed._state;\n },\n set(v: 0 | 1 | 2) {\n computed._state = v;\n },\n enumerable: true,\n configurable: true,\n });\n Object.defineProperty(callable, \"_value\", {\n get() {\n return computed._value;\n },\n set(v: T) {\n computed._value = v;\n },\n enumerable: true,\n configurable: true,\n });\n Object.defineProperty(callable, \"_observers\", {\n get() {\n return computed._observers;\n },\n set(v: any) {\n computed._observers = v;\n },\n enumerable: true,\n configurable: true,\n });\n Object.defineProperty(callable, \"_observerSlots\", {\n get() {\n return computed._observerSlots;\n },\n set(v: any) {\n computed._observerSlots = v;\n },\n enumerable: true,\n configurable: true,\n });\n Object.defineProperty(callable, \"_sources\", {\n get() {\n return computed._sources;\n },\n set(v: any) {\n computed._sources = v;\n },\n enumerable: true,\n configurable: true,\n });\n Object.defineProperty(callable, \"_sourceSlots\", {\n get() {\n return computed._sourceSlots;\n },\n set(v: any) {\n computed._sourceSlots = v;\n },\n enumerable: true,\n configurable: true,\n });\n Object.defineProperty(callable, \"_fn\", {\n get() {\n return computed._fn;\n },\n enumerable: true,\n configurable: true,\n });\n Object.defineProperty(callable, \"_computation\", {\n get() {\n return (computed as any)._computation;\n },\n set(v: any) {\n (computed as any)._computation = v;\n },\n enumerable: true,\n configurable: true,\n });\n\n // Initial computation\n recompute(computed);\n\n return callable;\n}\n\n/**\n * Execute a function without tracking signal dependencies\n */\nexport function untrack<T>(fn: () => T): T {\n const prevListener = Listener;\n Listener = null;\n try {\n return fn();\n } finally {\n Listener = prevListener;\n }\n}\n\n/**\n * Batch multiple signal updates into a single reactive cycle\n */\nexport function batch(fn: () => void): void {\n const prevUpdates = Updates;\n const prevPending = Pending;\n Updates = [];\n Pending = [];\n try {\n fn();\n } finally {\n // Collect all pending updates\n if (prevPending !== null && prevPending.length > 0) {\n Pending = prevPending.concat(Pending);\n }\n Updates = prevUpdates;\n // Flush after batch completes\n flushUpdates();\n }\n}\n\n/**\n * Create a reactive root context\n */\nexport function createRoot<T>(fn: (dispose: () => void) => T): T {\n const prevOwner = Owner;\n const prevListener = Listener;\n const root: OwnerType = {\n _owned: null,\n _cleanups: null,\n _owner: prevOwner,\n _context: null,\n };\n Owner = root;\n Listener = null;\n\n try {\n return fn(() => cleanRoot(root));\n } finally {\n Owner = prevOwner;\n Listener = prevListener;\n }\n}\n\n/** @internal */\nfunction cleanRoot(root: OwnerType): void {\n if (root._cleanups !== null) {\n const cleanups = root._cleanups;\n root._cleanups = null;\n // Run cleanups in reverse order (LIFO)\n for (let i = cleanups.length - 1; i >= 0; i--) {\n cleanups[i]!();\n }\n }\n if (root._owned !== null) {\n const owned = root._owned;\n root._owned = null;\n for (let i = 0; i < owned.length; i++) {\n cleanNode(owned[i]!);\n }\n }\n}\n\n/**\n * Register a cleanup callback to run when the owner is disposed\n */\nexport function onCleanup(fn: () => void): void {\n if (Owner === null) {\n return;\n }\n if (Owner._cleanups === null) {\n Owner._cleanups = [];\n }\n Owner._cleanups.push(fn);\n}\n\n/** @internal */\nexport function cleanNode(node: Computation<any> | OwnerType): void {\n if (\"_cleanups\" in node && node._cleanups !== null) {\n const cleanups = node._cleanups;\n node._cleanups = null;\n // Run cleanups in reverse order (LIFO)\n for (let i = cleanups.length - 1; i >= 0; i--) {\n cleanups[i]!();\n }\n }\n if (\"_owned\" in node && node._owned !== null) {\n const owned = node._owned;\n node._owned = null;\n for (let i = 0; i < owned.length; i++) {\n cleanNode(owned[i]!);\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ require("./store.cjs");
@@ -0,0 +1,2 @@
1
+ import "./store.mjs";
2
+ export {};
@@ -0,0 +1,94 @@
1
+ const require_signal = require("../signal/signal.cjs");
2
+ const require_constants = require("../constants.cjs");
3
+ //#region src/store/store.ts
4
+ /**
5
+ * Global store system for @hedystia/view
6
+ *
7
+ * Provides reactive state management with nested path access.
8
+ * Uses Proxy for fine-grained reactivity on nested properties.
9
+ */
10
+ /**
11
+ * Create a reactive store from an initial state object
12
+ */
13
+ function store(initial) {
14
+ const signals = createSignals(initial);
15
+ return new Proxy(signals, { get(target, prop) {
16
+ if (prop === require_constants.$STORE) return true;
17
+ const value = target[prop];
18
+ if (typeof value === "object" && value !== null && require_constants.$STORE in value) return value;
19
+ return value;
20
+ } });
21
+ }
22
+ /** @internal */
23
+ function createSignals(obj) {
24
+ const result = {};
25
+ for (const key in obj) {
26
+ if (!Object.hasOwn(obj, key)) continue;
27
+ const value = obj[key];
28
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
29
+ result[key] = createSignals(value);
30
+ Object.defineProperty(result[key], require_constants.$STORE, {
31
+ value: true,
32
+ enumerable: false
33
+ });
34
+ } else if (Array.isArray(value)) result[key] = require_signal.sig(value.map((item) => {
35
+ if (typeof item === "object" && item !== null) return createSignals(item);
36
+ return require_signal.sig(item);
37
+ }));
38
+ else result[key] = require_signal.sig(value);
39
+ }
40
+ Object.defineProperty(result, require_constants.$STORE, {
41
+ value: true,
42
+ enumerable: false
43
+ });
44
+ return result;
45
+ }
46
+ /**
47
+ * Deep partial update of a store node
48
+ */
49
+ function patch(storeNode, partial) {
50
+ require_signal.batch(() => {
51
+ for (const key in partial) {
52
+ if (!Object.hasOwn(partial, key)) continue;
53
+ const value = partial[key];
54
+ const node = storeNode[key];
55
+ if (typeof node === "object" && node !== null && require_constants.$STORE in node && !("_value" in node)) patch(node, value);
56
+ else if (typeof node === "object" && node !== null && "_value" in node) require_signal.set(node, value);
57
+ }
58
+ });
59
+ }
60
+ /**
61
+ * Reset a store to its initial values
62
+ */
63
+ function reset(storeInstance, initial) {
64
+ require_signal.batch(() => {
65
+ for (const key in initial) {
66
+ if (!Object.hasOwn(initial, key)) continue;
67
+ const value = initial[key];
68
+ const node = storeInstance[key];
69
+ if (typeof node === "object" && node !== null && require_constants.$STORE in node && !("_value" in node)) reset(node, value);
70
+ else if (typeof node === "object" && node !== null && "_value" in node) require_signal.set(node, value);
71
+ }
72
+ });
73
+ }
74
+ /**
75
+ * Create a plain snapshot of a store node
76
+ */
77
+ function snap(storeNode) {
78
+ const result = {};
79
+ for (const key in storeNode) {
80
+ if (!Object.hasOwn(storeNode, key)) continue;
81
+ const value = storeNode[key];
82
+ if (typeof value === "object" && value !== null && require_constants.$STORE in value && !("_value" in value)) result[key] = snap(value);
83
+ else if (typeof value === "object" && value !== null && "_value" in value) result[key] = require_signal.val(value);
84
+ else result[key] = value;
85
+ }
86
+ return result;
87
+ }
88
+ //#endregion
89
+ exports.patch = patch;
90
+ exports.reset = reset;
91
+ exports.snap = snap;
92
+ exports.store = store;
93
+
94
+ //# sourceMappingURL=store.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.cjs","names":["$STORE","sig","val"],"sources":["../../src/store/store.ts"],"sourcesContent":["/**\n * Global store system for @hedystia/view\n *\n * Provides reactive state management with nested path access.\n * Uses Proxy for fine-grained reactivity on nested properties.\n */\n\nimport { $STORE } from \"../constants\";\nimport { batch, set as setSignal, sig, val } from \"../signal\";\nimport type { Signal, Store, StoreValue } from \"../types\";\n\n/**\n * Create a reactive store from an initial state object\n */\nexport function store<T extends Record<string, StoreValue>>(initial: T): Store<T> {\n const signals = createSignals(initial);\n const proxy = new Proxy(signals, {\n get(target, prop) {\n if (prop === $STORE) {\n return true;\n }\n const value = target[prop as keyof typeof target];\n if (typeof value === \"object\" && value !== null && $STORE in value) {\n return value;\n }\n return value;\n },\n }) as Store<T>;\n return proxy;\n}\n\n/** @internal */\nfunction createSignals(obj: Record<string, StoreValue>): any {\n const result: any = {};\n\n for (const key in obj) {\n if (!Object.hasOwn(obj, key)) {\n continue;\n }\n const value = obj[key];\n\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n result[key] = createSignals(value as Record<string, StoreValue>);\n Object.defineProperty(result[key], $STORE, { value: true, enumerable: false });\n } else if (Array.isArray(value)) {\n const arraySignals = value.map((item) => {\n if (typeof item === \"object\" && item !== null) {\n return createSignals(item as Record<string, StoreValue>);\n }\n return sig(item);\n });\n result[key] = sig(arraySignals);\n } else {\n result[key] = sig(value);\n }\n }\n\n Object.defineProperty(result, $STORE, { value: true, enumerable: false });\n return result;\n}\n\n/**\n * Deep partial update of a store node\n */\nexport function patch(storeNode: any, partial: Record<string, any>): void {\n batch(() => {\n for (const key in partial) {\n if (!Object.hasOwn(partial, key)) {\n continue;\n }\n const value = partial[key];\n const node = storeNode[key];\n if (typeof node === \"object\" && node !== null && $STORE in node && !(\"_value\" in node)) {\n patch(node, value);\n } else if (typeof node === \"object\" && node !== null && \"_value\" in node) {\n setSignal(node as Signal<any>, value);\n }\n }\n });\n}\n\n/**\n * Reset a store to its initial values\n */\nexport function reset(storeInstance: any, initial: Record<string, StoreValue>): void {\n batch(() => {\n for (const key in initial) {\n if (!Object.hasOwn(initial, key)) {\n continue;\n }\n const value = initial[key];\n const node = storeInstance[key];\n if (typeof node === \"object\" && node !== null && $STORE in node && !(\"_value\" in node)) {\n reset(node, value as Record<string, StoreValue>);\n } else if (typeof node === \"object\" && node !== null && \"_value\" in node) {\n setSignal(node as Signal<any>, value);\n }\n }\n });\n}\n\n/**\n * Create a plain snapshot of a store node\n */\nexport function snap(storeNode: any): any {\n const result: any = {};\n\n for (const key in storeNode) {\n if (!Object.hasOwn(storeNode, key)) {\n continue;\n }\n const value = storeNode[key];\n if (typeof value === \"object\" && value !== null && $STORE in value && !(\"_value\" in value)) {\n result[key] = snap(value);\n } else if (typeof value === \"object\" && value !== null && \"_value\" in value) {\n result[key] = val(value as Signal<any>);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,MAA4C,SAAsB;CAChF,MAAM,UAAU,cAAc,QAAQ;AAatC,QAZc,IAAI,MAAM,SAAS,EAC/B,IAAI,QAAQ,MAAM;AAChB,MAAI,SAASA,kBAAAA,OACX,QAAO;EAET,MAAM,QAAQ,OAAO;AACrB,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQA,kBAAAA,UAAU,MAC3D,QAAO;AAET,SAAO;IAEV,CAAC;;;AAKJ,SAAS,cAAc,KAAsC;CAC3D,MAAM,SAAc,EAAE;AAEtB,MAAK,MAAM,OAAO,KAAK;AACrB,MAAI,CAAC,OAAO,OAAO,KAAK,IAAI,CAC1B;EAEF,MAAM,QAAQ,IAAI;AAElB,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM,EAAE;AACxE,UAAO,OAAO,cAAc,MAAoC;AAChE,UAAO,eAAe,OAAO,MAAMA,kBAAAA,QAAQ;IAAE,OAAO;IAAM,YAAY;IAAO,CAAC;aACrE,MAAM,QAAQ,MAAM,CAO7B,QAAO,OAAOC,eAAAA,IANO,MAAM,KAAK,SAAS;AACvC,OAAI,OAAO,SAAS,YAAY,SAAS,KACvC,QAAO,cAAc,KAAmC;AAE1D,UAAOA,eAAAA,IAAI,KAAK;IAChB,CAC6B;MAE/B,QAAO,OAAOA,eAAAA,IAAI,MAAM;;AAI5B,QAAO,eAAe,QAAQD,kBAAAA,QAAQ;EAAE,OAAO;EAAM,YAAY;EAAO,CAAC;AACzE,QAAO;;;;;AAMT,SAAgB,MAAM,WAAgB,SAAoC;AACxE,gBAAA,YAAY;AACV,OAAK,MAAM,OAAO,SAAS;AACzB,OAAI,CAAC,OAAO,OAAO,SAAS,IAAI,CAC9B;GAEF,MAAM,QAAQ,QAAQ;GACtB,MAAM,OAAO,UAAU;AACvB,OAAI,OAAO,SAAS,YAAY,SAAS,QAAQA,kBAAAA,UAAU,QAAQ,EAAE,YAAY,MAC/E,OAAM,MAAM,MAAM;YACT,OAAO,SAAS,YAAY,SAAS,QAAQ,YAAY,KAClE,gBAAA,IAAU,MAAqB,MAAM;;GAGzC;;;;;AAMJ,SAAgB,MAAM,eAAoB,SAA2C;AACnF,gBAAA,YAAY;AACV,OAAK,MAAM,OAAO,SAAS;AACzB,OAAI,CAAC,OAAO,OAAO,SAAS,IAAI,CAC9B;GAEF,MAAM,QAAQ,QAAQ;GACtB,MAAM,OAAO,cAAc;AAC3B,OAAI,OAAO,SAAS,YAAY,SAAS,QAAQA,kBAAAA,UAAU,QAAQ,EAAE,YAAY,MAC/E,OAAM,MAAM,MAAoC;YACvC,OAAO,SAAS,YAAY,SAAS,QAAQ,YAAY,KAClE,gBAAA,IAAU,MAAqB,MAAM;;GAGzC;;;;;AAMJ,SAAgB,KAAK,WAAqB;CACxC,MAAM,SAAc,EAAE;AAEtB,MAAK,MAAM,OAAO,WAAW;AAC3B,MAAI,CAAC,OAAO,OAAO,WAAW,IAAI,CAChC;EAEF,MAAM,QAAQ,UAAU;AACxB,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQA,kBAAAA,UAAU,SAAS,EAAE,YAAY,OAClF,QAAO,OAAO,KAAK,MAAM;WAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,MACpE,QAAO,OAAOE,eAAAA,IAAI,MAAqB;MAEvC,QAAO,OAAO;;AAIlB,QAAO"}
@@ -0,0 +1,22 @@
1
+ import { Store, StoreValue } from "../types.cjs";
2
+
3
+ //#region src/store/store.d.ts
4
+ /**
5
+ * Create a reactive store from an initial state object
6
+ */
7
+ declare function store<T extends Record<string, StoreValue>>(initial: T): Store<T>;
8
+ /**
9
+ * Deep partial update of a store node
10
+ */
11
+ declare function patch(storeNode: any, partial: Record<string, any>): void;
12
+ /**
13
+ * Reset a store to its initial values
14
+ */
15
+ declare function reset(storeInstance: any, initial: Record<string, StoreValue>): void;
16
+ /**
17
+ * Create a plain snapshot of a store node
18
+ */
19
+ declare function snap(storeNode: any): any;
20
+ //#endregion
21
+ export { patch, reset, snap, store };
22
+ //# sourceMappingURL=store.d.cts.map
@@ -0,0 +1,22 @@
1
+ import { Store, StoreValue } from "../types.mjs";
2
+
3
+ //#region src/store/store.d.ts
4
+ /**
5
+ * Create a reactive store from an initial state object
6
+ */
7
+ declare function store<T extends Record<string, StoreValue>>(initial: T): Store<T>;
8
+ /**
9
+ * Deep partial update of a store node
10
+ */
11
+ declare function patch(storeNode: any, partial: Record<string, any>): void;
12
+ /**
13
+ * Reset a store to its initial values
14
+ */
15
+ declare function reset(storeInstance: any, initial: Record<string, StoreValue>): void;
16
+ /**
17
+ * Create a plain snapshot of a store node
18
+ */
19
+ declare function snap(storeNode: any): any;
20
+ //#endregion
21
+ export { patch, reset, snap, store };
22
+ //# sourceMappingURL=store.d.mts.map
@@ -0,0 +1,91 @@
1
+ import { batch, set, sig, val } from "../signal/signal.mjs";
2
+ import { $STORE } from "../constants.mjs";
3
+ //#region src/store/store.ts
4
+ /**
5
+ * Global store system for @hedystia/view
6
+ *
7
+ * Provides reactive state management with nested path access.
8
+ * Uses Proxy for fine-grained reactivity on nested properties.
9
+ */
10
+ /**
11
+ * Create a reactive store from an initial state object
12
+ */
13
+ function store(initial) {
14
+ const signals = createSignals(initial);
15
+ return new Proxy(signals, { get(target, prop) {
16
+ if (prop === $STORE) return true;
17
+ const value = target[prop];
18
+ if (typeof value === "object" && value !== null && $STORE in value) return value;
19
+ return value;
20
+ } });
21
+ }
22
+ /** @internal */
23
+ function createSignals(obj) {
24
+ const result = {};
25
+ for (const key in obj) {
26
+ if (!Object.hasOwn(obj, key)) continue;
27
+ const value = obj[key];
28
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
29
+ result[key] = createSignals(value);
30
+ Object.defineProperty(result[key], $STORE, {
31
+ value: true,
32
+ enumerable: false
33
+ });
34
+ } else if (Array.isArray(value)) result[key] = sig(value.map((item) => {
35
+ if (typeof item === "object" && item !== null) return createSignals(item);
36
+ return sig(item);
37
+ }));
38
+ else result[key] = sig(value);
39
+ }
40
+ Object.defineProperty(result, $STORE, {
41
+ value: true,
42
+ enumerable: false
43
+ });
44
+ return result;
45
+ }
46
+ /**
47
+ * Deep partial update of a store node
48
+ */
49
+ function patch(storeNode, partial) {
50
+ batch(() => {
51
+ for (const key in partial) {
52
+ if (!Object.hasOwn(partial, key)) continue;
53
+ const value = partial[key];
54
+ const node = storeNode[key];
55
+ if (typeof node === "object" && node !== null && $STORE in node && !("_value" in node)) patch(node, value);
56
+ else if (typeof node === "object" && node !== null && "_value" in node) set(node, value);
57
+ }
58
+ });
59
+ }
60
+ /**
61
+ * Reset a store to its initial values
62
+ */
63
+ function reset(storeInstance, initial) {
64
+ batch(() => {
65
+ for (const key in initial) {
66
+ if (!Object.hasOwn(initial, key)) continue;
67
+ const value = initial[key];
68
+ const node = storeInstance[key];
69
+ if (typeof node === "object" && node !== null && $STORE in node && !("_value" in node)) reset(node, value);
70
+ else if (typeof node === "object" && node !== null && "_value" in node) set(node, value);
71
+ }
72
+ });
73
+ }
74
+ /**
75
+ * Create a plain snapshot of a store node
76
+ */
77
+ function snap(storeNode) {
78
+ const result = {};
79
+ for (const key in storeNode) {
80
+ if (!Object.hasOwn(storeNode, key)) continue;
81
+ const value = storeNode[key];
82
+ if (typeof value === "object" && value !== null && $STORE in value && !("_value" in value)) result[key] = snap(value);
83
+ else if (typeof value === "object" && value !== null && "_value" in value) result[key] = val(value);
84
+ else result[key] = value;
85
+ }
86
+ return result;
87
+ }
88
+ //#endregion
89
+ export { patch, reset, snap, store };
90
+
91
+ //# sourceMappingURL=store.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.mjs","names":[],"sources":["../../src/store/store.ts"],"sourcesContent":["/**\n * Global store system for @hedystia/view\n *\n * Provides reactive state management with nested path access.\n * Uses Proxy for fine-grained reactivity on nested properties.\n */\n\nimport { $STORE } from \"../constants\";\nimport { batch, set as setSignal, sig, val } from \"../signal\";\nimport type { Signal, Store, StoreValue } from \"../types\";\n\n/**\n * Create a reactive store from an initial state object\n */\nexport function store<T extends Record<string, StoreValue>>(initial: T): Store<T> {\n const signals = createSignals(initial);\n const proxy = new Proxy(signals, {\n get(target, prop) {\n if (prop === $STORE) {\n return true;\n }\n const value = target[prop as keyof typeof target];\n if (typeof value === \"object\" && value !== null && $STORE in value) {\n return value;\n }\n return value;\n },\n }) as Store<T>;\n return proxy;\n}\n\n/** @internal */\nfunction createSignals(obj: Record<string, StoreValue>): any {\n const result: any = {};\n\n for (const key in obj) {\n if (!Object.hasOwn(obj, key)) {\n continue;\n }\n const value = obj[key];\n\n if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n result[key] = createSignals(value as Record<string, StoreValue>);\n Object.defineProperty(result[key], $STORE, { value: true, enumerable: false });\n } else if (Array.isArray(value)) {\n const arraySignals = value.map((item) => {\n if (typeof item === \"object\" && item !== null) {\n return createSignals(item as Record<string, StoreValue>);\n }\n return sig(item);\n });\n result[key] = sig(arraySignals);\n } else {\n result[key] = sig(value);\n }\n }\n\n Object.defineProperty(result, $STORE, { value: true, enumerable: false });\n return result;\n}\n\n/**\n * Deep partial update of a store node\n */\nexport function patch(storeNode: any, partial: Record<string, any>): void {\n batch(() => {\n for (const key in partial) {\n if (!Object.hasOwn(partial, key)) {\n continue;\n }\n const value = partial[key];\n const node = storeNode[key];\n if (typeof node === \"object\" && node !== null && $STORE in node && !(\"_value\" in node)) {\n patch(node, value);\n } else if (typeof node === \"object\" && node !== null && \"_value\" in node) {\n setSignal(node as Signal<any>, value);\n }\n }\n });\n}\n\n/**\n * Reset a store to its initial values\n */\nexport function reset(storeInstance: any, initial: Record<string, StoreValue>): void {\n batch(() => {\n for (const key in initial) {\n if (!Object.hasOwn(initial, key)) {\n continue;\n }\n const value = initial[key];\n const node = storeInstance[key];\n if (typeof node === \"object\" && node !== null && $STORE in node && !(\"_value\" in node)) {\n reset(node, value as Record<string, StoreValue>);\n } else if (typeof node === \"object\" && node !== null && \"_value\" in node) {\n setSignal(node as Signal<any>, value);\n }\n }\n });\n}\n\n/**\n * Create a plain snapshot of a store node\n */\nexport function snap(storeNode: any): any {\n const result: any = {};\n\n for (const key in storeNode) {\n if (!Object.hasOwn(storeNode, key)) {\n continue;\n }\n const value = storeNode[key];\n if (typeof value === \"object\" && value !== null && $STORE in value && !(\"_value\" in value)) {\n result[key] = snap(value);\n } else if (typeof value === \"object\" && value !== null && \"_value\" in value) {\n result[key] = val(value as Signal<any>);\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,MAA4C,SAAsB;CAChF,MAAM,UAAU,cAAc,QAAQ;AAatC,QAZc,IAAI,MAAM,SAAS,EAC/B,IAAI,QAAQ,MAAM;AAChB,MAAI,SAAS,OACX,QAAO;EAET,MAAM,QAAQ,OAAO;AACrB,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,MAC3D,QAAO;AAET,SAAO;IAEV,CAAC;;;AAKJ,SAAS,cAAc,KAAsC;CAC3D,MAAM,SAAc,EAAE;AAEtB,MAAK,MAAM,OAAO,KAAK;AACrB,MAAI,CAAC,OAAO,OAAO,KAAK,IAAI,CAC1B;EAEF,MAAM,QAAQ,IAAI;AAElB,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM,EAAE;AACxE,UAAO,OAAO,cAAc,MAAoC;AAChE,UAAO,eAAe,OAAO,MAAM,QAAQ;IAAE,OAAO;IAAM,YAAY;IAAO,CAAC;aACrE,MAAM,QAAQ,MAAM,CAO7B,QAAO,OAAO,IANO,MAAM,KAAK,SAAS;AACvC,OAAI,OAAO,SAAS,YAAY,SAAS,KACvC,QAAO,cAAc,KAAmC;AAE1D,UAAO,IAAI,KAAK;IAChB,CAC6B;MAE/B,QAAO,OAAO,IAAI,MAAM;;AAI5B,QAAO,eAAe,QAAQ,QAAQ;EAAE,OAAO;EAAM,YAAY;EAAO,CAAC;AACzE,QAAO;;;;;AAMT,SAAgB,MAAM,WAAgB,SAAoC;AACxE,aAAY;AACV,OAAK,MAAM,OAAO,SAAS;AACzB,OAAI,CAAC,OAAO,OAAO,SAAS,IAAI,CAC9B;GAEF,MAAM,QAAQ,QAAQ;GACtB,MAAM,OAAO,UAAU;AACvB,OAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,UAAU,QAAQ,EAAE,YAAY,MAC/E,OAAM,MAAM,MAAM;YACT,OAAO,SAAS,YAAY,SAAS,QAAQ,YAAY,KAClE,KAAU,MAAqB,MAAM;;GAGzC;;;;;AAMJ,SAAgB,MAAM,eAAoB,SAA2C;AACnF,aAAY;AACV,OAAK,MAAM,OAAO,SAAS;AACzB,OAAI,CAAC,OAAO,OAAO,SAAS,IAAI,CAC9B;GAEF,MAAM,QAAQ,QAAQ;GACtB,MAAM,OAAO,cAAc;AAC3B,OAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,UAAU,QAAQ,EAAE,YAAY,MAC/E,OAAM,MAAM,MAAoC;YACvC,OAAO,SAAS,YAAY,SAAS,QAAQ,YAAY,KAClE,KAAU,MAAqB,MAAM;;GAGzC;;;;;AAMJ,SAAgB,KAAK,WAAqB;CACxC,MAAM,SAAc,EAAE;AAEtB,MAAK,MAAM,OAAO,WAAW;AAC3B,MAAI,CAAC,OAAO,OAAO,WAAW,IAAI,CAChC;EAEF,MAAM,QAAQ,UAAU;AACxB,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,EAAE,YAAY,OAClF,QAAO,OAAO,KAAK,MAAM;WAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY,MACpE,QAAO,OAAO,IAAI,MAAqB;MAEvC,QAAO,OAAO;;AAIlB,QAAO"}