mutts 1.0.7 → 1.0.9

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 (191) hide show
  1. package/README.md +72 -17
  2. package/dist/browser.cjs +3111 -0
  3. package/dist/browser.cjs.map +1 -0
  4. package/dist/browser.d.ts +1391 -1
  5. package/dist/browser.esm.js +264 -35
  6. package/dist/browser.esm.js.map +1 -1
  7. package/dist/chunks/async-browser-lvzLOCgk.cjs +297 -0
  8. package/dist/chunks/async-browser-lvzLOCgk.cjs.map +1 -0
  9. package/dist/chunks/async-core-CRLKP3l-.cjs +29 -0
  10. package/dist/chunks/async-core-CRLKP3l-.cjs.map +1 -0
  11. package/dist/chunks/async-node-C3DeIb0y.cjs +96 -0
  12. package/dist/chunks/async-node-C3DeIb0y.cjs.map +1 -0
  13. package/dist/chunks/index-2vea86wD.esm.js +3011 -0
  14. package/dist/chunks/index-2vea86wD.esm.js.map +1 -0
  15. package/dist/chunks/index-CtA2AWl3.esm.js +4376 -0
  16. package/dist/chunks/index-CtA2AWl3.esm.js.map +1 -0
  17. package/dist/chunks/index-VTO-b2vR.cjs +4461 -0
  18. package/dist/chunks/index-VTO-b2vR.cjs.map +1 -0
  19. package/dist/debug/debug.d.ts +122 -0
  20. package/dist/debug/debug.d.ts.map +1 -0
  21. package/dist/debug/index.d.ts +4 -0
  22. package/dist/debug/index.d.ts.map +1 -0
  23. package/dist/debug/lineage-panel.d.ts +5 -0
  24. package/dist/debug/lineage-panel.d.ts.map +1 -0
  25. package/dist/debug/lineage.d.ts +79 -0
  26. package/dist/debug/lineage.d.ts.map +1 -0
  27. package/dist/debug.cjs +35 -0
  28. package/dist/debug.cjs.map +1 -0
  29. package/dist/debug.d.ts +209 -0
  30. package/dist/debug.esm.js +2 -0
  31. package/dist/debug.esm.js.map +1 -0
  32. package/dist/devtools/devtool/devtools.d.ts +1 -0
  33. package/dist/devtools/devtool/devtools.d.ts.map +1 -0
  34. package/dist/devtools/devtool/panel.d.ts +2 -0
  35. package/dist/devtools/devtool/panel.d.ts.map +1 -0
  36. package/dist/index.d.ts +1 -0
  37. package/dist/mutts.umd.js +1 -1
  38. package/dist/mutts.umd.js.map +1 -1
  39. package/dist/mutts.umd.min.js +1 -1
  40. package/dist/mutts.umd.min.js.map +1 -1
  41. package/dist/node.cjs +107 -0
  42. package/dist/node.cjs.map +1 -0
  43. package/dist/node.d.ts +2 -2
  44. package/dist/node.esm.js +86 -33
  45. package/dist/node.esm.js.map +1 -1
  46. package/dist/src/async/browser.d.ts +2 -0
  47. package/dist/src/async/browser.d.ts.map +1 -0
  48. package/dist/src/async/index.d.ts +19 -0
  49. package/dist/src/async/index.d.ts.map +1 -0
  50. package/dist/src/async/node.d.ts +2 -0
  51. package/dist/src/async/node.d.ts.map +1 -0
  52. package/dist/src/decorator.d.ts +106 -0
  53. package/dist/src/decorator.d.ts.map +1 -0
  54. package/dist/src/destroyable.d.ts +87 -0
  55. package/dist/src/destroyable.d.ts.map +1 -0
  56. package/dist/src/entry-browser.d.ts +3 -0
  57. package/dist/src/entry-browser.d.ts.map +1 -0
  58. package/dist/src/entry-node.d.ts +3 -0
  59. package/dist/src/entry-node.d.ts.map +1 -0
  60. package/dist/src/eventful.d.ts +20 -0
  61. package/dist/src/eventful.d.ts.map +1 -0
  62. package/dist/src/flavored.d.ts +33 -0
  63. package/dist/src/flavored.d.ts.map +1 -0
  64. package/dist/src/index.d.ts +14 -0
  65. package/dist/src/index.d.ts.map +1 -0
  66. package/dist/src/indexable.d.ts +243 -0
  67. package/dist/src/indexable.d.ts.map +1 -0
  68. package/dist/src/introspection.d.ts +27 -0
  69. package/dist/src/introspection.d.ts.map +1 -0
  70. package/dist/src/iterableWeak.d.ts +53 -0
  71. package/dist/src/iterableWeak.d.ts.map +1 -0
  72. package/dist/src/mixins.d.ts +25 -0
  73. package/dist/src/mixins.d.ts.map +1 -0
  74. package/dist/src/promiseChain.d.ts +20 -0
  75. package/dist/src/promiseChain.d.ts.map +1 -0
  76. package/dist/src/reactive/array.d.ts +48 -0
  77. package/dist/src/reactive/array.d.ts.map +1 -0
  78. package/dist/src/reactive/buffer.d.ts +120 -0
  79. package/dist/src/reactive/buffer.d.ts.map +1 -0
  80. package/dist/src/reactive/change.d.ts +29 -0
  81. package/dist/src/reactive/change.d.ts.map +1 -0
  82. package/dist/src/reactive/deep-touch.d.ts +28 -0
  83. package/dist/src/reactive/deep-touch.d.ts.map +1 -0
  84. package/dist/src/reactive/deep-watch-state.d.ts +25 -0
  85. package/dist/src/reactive/deep-watch-state.d.ts.map +1 -0
  86. package/dist/src/reactive/deep-watch.d.ts +20 -0
  87. package/dist/src/reactive/deep-watch.d.ts.map +1 -0
  88. package/dist/src/reactive/describe.d.ts +12 -0
  89. package/dist/src/reactive/describe.d.ts.map +1 -0
  90. package/dist/src/reactive/effect-context.d.ts +34 -0
  91. package/dist/src/reactive/effect-context.d.ts.map +1 -0
  92. package/dist/src/reactive/effects.d.ts +164 -0
  93. package/dist/src/reactive/effects.d.ts.map +1 -0
  94. package/dist/src/reactive/index.d.ts +19 -0
  95. package/dist/src/reactive/index.d.ts.map +1 -0
  96. package/dist/src/reactive/map.d.ts +28 -0
  97. package/dist/src/reactive/map.d.ts.map +1 -0
  98. package/dist/src/reactive/memoize.d.ts +28 -0
  99. package/dist/src/reactive/memoize.d.ts.map +1 -0
  100. package/dist/src/reactive/non-reactive-state.d.ts +9 -0
  101. package/dist/src/reactive/non-reactive-state.d.ts.map +1 -0
  102. package/dist/src/reactive/non-reactive.d.ts +11 -0
  103. package/dist/src/reactive/non-reactive.d.ts.map +1 -0
  104. package/dist/src/reactive/project.d.ts +40 -0
  105. package/dist/src/reactive/project.d.ts.map +1 -0
  106. package/dist/src/reactive/proxy-state.d.ts +8 -0
  107. package/dist/src/reactive/proxy-state.d.ts.map +1 -0
  108. package/dist/src/reactive/proxy.d.ts +23 -0
  109. package/dist/src/reactive/proxy.d.ts.map +1 -0
  110. package/dist/src/reactive/record.d.ts +115 -0
  111. package/dist/src/reactive/record.d.ts.map +1 -0
  112. package/dist/src/reactive/register.d.ts +125 -0
  113. package/dist/src/reactive/register.d.ts.map +1 -0
  114. package/dist/src/reactive/registry.d.ts +21 -0
  115. package/dist/src/reactive/registry.d.ts.map +1 -0
  116. package/dist/src/reactive/set.d.ts +26 -0
  117. package/dist/src/reactive/set.d.ts.map +1 -0
  118. package/dist/src/reactive/tracking.d.ts +7 -0
  119. package/dist/src/reactive/tracking.d.ts.map +1 -0
  120. package/dist/src/reactive/types.d.ts +424 -0
  121. package/dist/src/reactive/types.d.ts.map +1 -0
  122. package/dist/src/reactive/watch.d.ts +48 -0
  123. package/dist/src/reactive/watch.d.ts.map +1 -0
  124. package/dist/src/std-decorators.d.ts +45 -0
  125. package/dist/src/std-decorators.d.ts.map +1 -0
  126. package/dist/src/utils.d.ts +49 -0
  127. package/dist/src/utils.d.ts.map +1 -0
  128. package/dist/src/zone.d.ts +40 -0
  129. package/dist/src/zone.d.ts.map +1 -0
  130. package/dist/types-DaHFfhlN.d.ts +414 -0
  131. package/docs/ai/api-reference.md +1 -1
  132. package/docs/ai/manual.md +443 -17
  133. package/docs/events.md +57 -2
  134. package/docs/flavored.md +210 -0
  135. package/docs/reactive/advanced.md +2 -3
  136. package/docs/reactive/attend.md +143 -0
  137. package/docs/reactive/collections.md +55 -0
  138. package/docs/reactive/core.md +120 -4
  139. package/docs/reactive/debugging.md +8 -10
  140. package/docs/reactive/describe.md +85 -0
  141. package/docs/reactive/error-handling.md +121 -0
  142. package/docs/reactive/project.md +1 -1
  143. package/docs/reactive/scan.md +215 -0
  144. package/docs/reactive.md +2 -0
  145. package/docs/std-decorators.md +171 -52
  146. package/docs/zone.md +9 -6
  147. package/package.json +44 -27
  148. package/src/async/browser.ts +277 -41
  149. package/src/async/index.ts +23 -4
  150. package/src/async/node.ts +78 -32
  151. package/src/entry-browser.ts +5 -0
  152. package/src/entry-node.ts +5 -0
  153. package/src/eventful.ts +82 -49
  154. package/src/flavored.ts +106 -0
  155. package/src/index.d.ts +12 -9
  156. package/src/index.ts +2 -1
  157. package/src/introspection.ts +1 -1
  158. package/src/reactive/array.ts +160 -80
  159. package/src/reactive/buffer.ts +187 -27
  160. package/src/reactive/change.ts +16 -23
  161. package/src/reactive/deep-touch.ts +19 -14
  162. package/src/reactive/deep-watch-state.ts +3 -3
  163. package/src/reactive/deep-watch.ts +7 -4
  164. package/src/reactive/describe.ts +39 -0
  165. package/src/reactive/effect-context.ts +71 -6
  166. package/src/reactive/effects.ts +445 -393
  167. package/src/reactive/index.ts +12 -14
  168. package/src/reactive/map.ts +8 -24
  169. package/src/reactive/memoize.ts +26 -3
  170. package/src/reactive/project.md +107 -0
  171. package/src/reactive/project.ts +48 -71
  172. package/src/reactive/proxy.ts +21 -3
  173. package/src/reactive/record.ts +30 -45
  174. package/src/reactive/register.ts +138 -19
  175. package/src/reactive/registry.ts +22 -9
  176. package/src/reactive/set.ts +7 -20
  177. package/src/reactive/tracking.ts +9 -12
  178. package/src/reactive/types.ts +104 -24
  179. package/src/reactive/{interface.ts → watch.ts} +29 -59
  180. package/src/std-decorators.ts +56 -17
  181. package/src/utils.ts +3 -4
  182. package/src/zone.ts +43 -28
  183. package/dist/browser.js +0 -161
  184. package/dist/browser.js.map +0 -1
  185. package/dist/chunks/index-BFYK02LG.js +0 -6378
  186. package/dist/chunks/index-BFYK02LG.js.map +0 -1
  187. package/dist/chunks/index-CNR6QRUl.esm.js +0 -6291
  188. package/dist/chunks/index-CNR6QRUl.esm.js.map +0 -1
  189. package/dist/node.js +0 -136
  190. package/dist/node.js.map +0 -1
  191. package/src/reactive/debug.ts +0 -517
@@ -0,0 +1,3111 @@
1
+ 'use strict';
2
+
3
+ require('./chunks/async-browser-lvzLOCgk.cjs');
4
+ var debug = require('./chunks/index-VTO-b2vR.cjs');
5
+ var asyncCore = require('./chunks/async-core-CRLKP3l-.cjs');
6
+ require('./chunks/async-node-C3DeIb0y.cjs');
7
+ require('node:async_hooks');
8
+
9
+ // Integrated with `using` statement via Symbol.dispose
10
+ const fr = new FinalizationRegistry((f) => f());
11
+ /**
12
+ * Symbol for marking destructor methods
13
+ */
14
+ const destructor = Symbol('destructor');
15
+ /**
16
+ * Symbol for accessing allocated values in destroyable objects
17
+ */
18
+ const allocatedValues = Symbol('allocated');
19
+ /**
20
+ * Error thrown when attempting to access a destroyed object
21
+ */
22
+ class DestructionError extends Error {
23
+ static throw(msg) {
24
+ return () => {
25
+ throw new DestructionError(msg);
26
+ };
27
+ }
28
+ constructor(msg) {
29
+ super(`Object is destroyed. ${msg}`);
30
+ this.name = 'DestroyedAccessError';
31
+ }
32
+ }
33
+ const destroyedHandler = {
34
+ [Symbol.toStringTag]: 'MutTs Destroyable',
35
+ get: DestructionError.throw('Cannot access destroyed object'),
36
+ set: DestructionError.throw('Cannot access destroyed object'),
37
+ };
38
+ function Destroyable(base, destructorObj) {
39
+ var _a;
40
+ if (base && typeof base !== 'function') {
41
+ destructorObj = base;
42
+ base = undefined;
43
+ }
44
+ if (!base) {
45
+ base = class {
46
+ };
47
+ }
48
+ return _a = class Destroyable extends base {
49
+ static destroy(obj) {
50
+ const destructor = _a.destructors.get(obj);
51
+ if (!destructor)
52
+ return false;
53
+ fr.unregister(obj[allocatedValues]);
54
+ _a.destructors.delete(obj);
55
+ Object.setPrototypeOf(obj, new Proxy({}, destroyedHandler));
56
+ // Clear all own properties
57
+ for (const key of Object.getOwnPropertyNames(obj)) {
58
+ delete obj[key];
59
+ }
60
+ destructor();
61
+ return true;
62
+ }
63
+ static isDestroyable(obj) {
64
+ return _a.destructors.has(obj);
65
+ }
66
+ constructor(...args) {
67
+ super(...args);
68
+ const allocated = {};
69
+ this[allocatedValues] = allocated;
70
+ // @ts-expect-error `this` is an AbstractDestroyable
71
+ const myDestructor = destructorObj?.destructor ?? this[destructor];
72
+ if (!myDestructor) {
73
+ throw new DestructionError('Destructor is not defined');
74
+ }
75
+ function destruction() {
76
+ myDestructor(allocated);
77
+ }
78
+ _a.destructors.set(this, destruction);
79
+ fr.register(this, destruction, allocated);
80
+ }
81
+ },
82
+ _a.destructors = new WeakMap(),
83
+ _a;
84
+ }
85
+ /**
86
+ * Decorator that marks properties to be stored in the allocated object and passed to the destructor
87
+ * Use with accessor properties or explicit get/set pairs
88
+ */
89
+ const allocated = debug.decorator({
90
+ setter(original, _target, propertyKey) {
91
+ return function (value) {
92
+ this[allocatedValues][propertyKey] = value;
93
+ return original.call(this, value);
94
+ };
95
+ },
96
+ });
97
+ /**
98
+ * Registers a callback to be called when an object is garbage collected
99
+ * @param cb - The callback function to execute on garbage collection
100
+ * @returns The object whose reference can be collected
101
+ */
102
+ function callOnGC(cb) {
103
+ let called = false;
104
+ const forward = () => {
105
+ if (called)
106
+ return;
107
+ called = true;
108
+ cb();
109
+ };
110
+ fr.register(forward, cb, cb);
111
+ return forward;
112
+ }
113
+
114
+ var _a, _b;
115
+ const events = Symbol('events');
116
+ const hooks = Symbol('hooks');
117
+ const eventBehavior = {
118
+ on(eventOrEvents, cb) {
119
+ if (typeof eventOrEvents === 'object') {
120
+ for (const e of Object.keys(eventOrEvents)) {
121
+ this.on(e, eventOrEvents[e]);
122
+ }
123
+ }
124
+ else if (cb !== undefined) {
125
+ const callbacks = this[events].get(eventOrEvents) ?? new Set();
126
+ if (!callbacks.has(cb))
127
+ callbacks.add(cb);
128
+ this[events].set(eventOrEvents, callbacks);
129
+ }
130
+ return () => this.off(eventOrEvents, cb);
131
+ },
132
+ off(eventOrEvents, cb) {
133
+ if (typeof eventOrEvents === 'object') {
134
+ for (const e of Object.keys(eventOrEvents)) {
135
+ this.off(e, eventOrEvents[e]);
136
+ }
137
+ }
138
+ else if (cb !== null && cb !== undefined) {
139
+ const callbacks = this[events].get(eventOrEvents);
140
+ if (callbacks) {
141
+ callbacks.delete(cb);
142
+ if (!callbacks.size)
143
+ this[events].delete(eventOrEvents);
144
+ }
145
+ }
146
+ else {
147
+ // Remove all listeners for this event
148
+ this[events].delete(eventOrEvents);
149
+ }
150
+ },
151
+ emit(event, ...args) {
152
+ const callbacks = this[events].get(event);
153
+ if (callbacks)
154
+ for (const cb of callbacks)
155
+ cb.apply(this, args);
156
+ for (const cb of this[hooks])
157
+ cb.call(this, event, ...args);
158
+ },
159
+ };
160
+ function perEvent(eventful, fct, use) {
161
+ const cache = new Map();
162
+ return new Proxy(fct, {
163
+ get(target, prop) {
164
+ if (typeof prop !== 'string')
165
+ return target[prop];
166
+ if (use && !eventful[events].has(prop) && !eventful[hooks].size)
167
+ return () => { };
168
+ // Return cached function or create and cache
169
+ let cached = cache.get(prop);
170
+ if (!cached) {
171
+ cached = (...args) => fct.apply(eventful, [prop, ...args]);
172
+ cache.set(prop, cached);
173
+ }
174
+ return cached;
175
+ },
176
+ });
177
+ }
178
+ /**
179
+ * A type-safe event system that provides a clean API for event handling
180
+ * @template Events - The event map defining event names and their handler signatures
181
+ */
182
+ class Eventful {
183
+ constructor() {
184
+ this[_a] = new Map();
185
+ this[_b] = new Set();
186
+ this.on = perEvent(this, eventBehavior.on);
187
+ this.off = perEvent(this, eventBehavior.off);
188
+ this.emit = perEvent(this, eventBehavior.emit, 'use');
189
+ }
190
+ hook(cb) {
191
+ this[hooks].add(cb);
192
+ return () => {
193
+ this[hooks].delete(cb);
194
+ };
195
+ }
196
+ }
197
+ _a = events, _b = hooks;
198
+
199
+ /**
200
+ * Symbol for defining custom getter logic for numeric index access
201
+ */
202
+ const getAt = Symbol('getAt');
203
+ /**
204
+ * Symbol for defining custom setter logic for numeric index access
205
+ */
206
+ const setAt = Symbol('setAt');
207
+ function Indexable(base, accessor) {
208
+ if (base && typeof base !== 'function') {
209
+ accessor = base;
210
+ base = undefined;
211
+ }
212
+ if (!base) {
213
+ //@ts-expect-error
214
+ base = class {
215
+ };
216
+ }
217
+ if (!accessor) {
218
+ accessor = {
219
+ get(index) {
220
+ if (typeof this[getAt] !== 'function') {
221
+ throw new Error('Indexable class must have an [getAt] method');
222
+ }
223
+ return this[getAt](index);
224
+ },
225
+ set(index, value) {
226
+ if (typeof this[setAt] !== 'function') {
227
+ throw new Error('Indexable class has read-only numeric index access');
228
+ }
229
+ this[setAt](index, value);
230
+ },
231
+ };
232
+ }
233
+ class Indexable extends base {
234
+ }
235
+ Object.setPrototypeOf(Indexable.prototype, new Proxy(base.prototype, {
236
+ //@ts-expect-error
237
+ [Symbol.toStringTag]: 'MutTs Indexable',
238
+ get(target, prop, receiver) {
239
+ if (prop in target) {
240
+ const getter = Object.getOwnPropertyDescriptor(target, prop)?.get;
241
+ return getter ? getter.call(receiver) : target[prop];
242
+ }
243
+ if (typeof prop === 'string') {
244
+ if (prop === 'length' && accessor.getLength)
245
+ return accessor.getLength.call(receiver);
246
+ const numProp = Number(prop);
247
+ if (!Number.isNaN(numProp)) {
248
+ return accessor.get.call(receiver, numProp);
249
+ }
250
+ }
251
+ return undefined;
252
+ },
253
+ set(target, prop, value, receiver) {
254
+ if (prop in target) {
255
+ const setter = Object.getOwnPropertyDescriptor(target, prop)?.set;
256
+ if (setter)
257
+ setter.call(receiver, value);
258
+ else
259
+ target[prop] = value;
260
+ return true;
261
+ }
262
+ if (typeof prop === 'string') {
263
+ if (prop === 'length' && accessor.setLength) {
264
+ accessor.setLength.call(receiver, value);
265
+ return true;
266
+ }
267
+ const numProp = Number(prop);
268
+ if (!Number.isNaN(numProp)) {
269
+ if (!accessor.set)
270
+ throw new Error('Indexable class has read-only numeric index access');
271
+ accessor.set.call(receiver, numProp, value);
272
+ return true;
273
+ }
274
+ }
275
+ Object.defineProperty(receiver, prop, {
276
+ value,
277
+ writable: true,
278
+ enumerable: true,
279
+ configurable: true,
280
+ });
281
+ return true;
282
+ },
283
+ has(target, prop) {
284
+ if (prop in target)
285
+ return true;
286
+ if (typeof prop === 'string') {
287
+ if (prop === 'length' && accessor.getLength)
288
+ return true;
289
+ const numProp = Number(prop);
290
+ if (!Number.isNaN(numProp))
291
+ return true;
292
+ }
293
+ return false;
294
+ },
295
+ ownKeys(target) {
296
+ const keys = Reflect.ownKeys(target);
297
+ if (accessor.getLength) {
298
+ keys.push('length');
299
+ const len = accessor.getLength.call(this);
300
+ for (let i = 0; i < len; i++)
301
+ keys.push(String(i));
302
+ }
303
+ return keys;
304
+ },
305
+ getOwnPropertyDescriptor(target, prop) {
306
+ if (prop in target)
307
+ return Object.getOwnPropertyDescriptor(target, prop);
308
+ if (typeof prop === 'string') {
309
+ if (prop === 'length' && accessor.getLength) {
310
+ return {
311
+ enumerable: false,
312
+ configurable: true,
313
+ get: () => accessor.getLength.call(this),
314
+ };
315
+ }
316
+ const numProp = Number(prop);
317
+ if (!Number.isNaN(numProp)) {
318
+ return {
319
+ enumerable: true,
320
+ configurable: true,
321
+ get: () => accessor.get.call(this, numProp),
322
+ set: accessor.set
323
+ ? (v) => accessor.set.call(this, numProp, v)
324
+ : undefined,
325
+ };
326
+ }
327
+ }
328
+ return undefined;
329
+ },
330
+ }));
331
+ return Indexable;
332
+ }
333
+ /**
334
+ * Symbol for accessing the forwarded array in ArrayReadForward
335
+ */
336
+ const forwardArray = Symbol('forwardArray');
337
+ /**
338
+ * A read-only array forwarder that implements all reading/iterating methods of Array
339
+ * but does not implement modification methods.
340
+ *
341
+ * The constructor takes a callback that returns an array, and all methods forward
342
+ * their behavior to the result of that callback.
343
+ */
344
+ class ArrayReadForward {
345
+ get [forwardArray]() {
346
+ throw new Error('ArrayReadForward is not implemented');
347
+ }
348
+ /**
349
+ * Get the length of the array
350
+ */
351
+ get length() {
352
+ return this[forwardArray].length;
353
+ }
354
+ /**
355
+ * Iterator protocol support
356
+ */
357
+ [Symbol.iterator]() {
358
+ return this[forwardArray][Symbol.iterator]();
359
+ }
360
+ // Reading/Iterating methods
361
+ /**
362
+ * Creates a new array with the results of calling a provided function on every element
363
+ */
364
+ map(callbackfn, thisArg) {
365
+ return this[forwardArray].map(callbackfn, thisArg);
366
+ }
367
+ filter(predicate, thisArg) {
368
+ return this[forwardArray].filter(predicate, thisArg);
369
+ }
370
+ reduce(callbackfn, initialValue) {
371
+ return initialValue !== undefined
372
+ ? this[forwardArray].reduce(callbackfn, initialValue)
373
+ : this[forwardArray].reduce(callbackfn);
374
+ }
375
+ reduceRight(callbackfn, initialValue) {
376
+ return initialValue !== undefined
377
+ ? this[forwardArray].reduceRight(callbackfn, initialValue)
378
+ : this[forwardArray].reduceRight(callbackfn);
379
+ }
380
+ /**
381
+ * Executes a provided function once for each array element
382
+ */
383
+ forEach(callbackfn, thisArg) {
384
+ this[forwardArray].forEach(callbackfn, thisArg);
385
+ }
386
+ find(predicate, thisArg) {
387
+ return this[forwardArray].find(predicate, thisArg);
388
+ }
389
+ /**
390
+ * Returns the index of the first element in the array that satisfies the provided testing function
391
+ */
392
+ findIndex(predicate, thisArg) {
393
+ return this[forwardArray].findIndex(predicate, thisArg);
394
+ }
395
+ findLast(predicate, thisArg) {
396
+ return this[forwardArray].findLast(predicate, thisArg);
397
+ }
398
+ /**
399
+ * Returns the index of the last element in the array that satisfies the provided testing function
400
+ */
401
+ findLastIndex(predicate, thisArg) {
402
+ return this[forwardArray].findLastIndex(predicate, thisArg);
403
+ }
404
+ /**
405
+ * Determines whether an array includes a certain value among its entries
406
+ */
407
+ includes(searchElement, fromIndex) {
408
+ return this[forwardArray].includes(searchElement, fromIndex);
409
+ }
410
+ /**
411
+ * Returns the first index at which a given element can be found in the array
412
+ */
413
+ indexOf(searchElement, fromIndex) {
414
+ return this[forwardArray].indexOf(searchElement, fromIndex);
415
+ }
416
+ /**
417
+ * Returns the last index at which a given element can be found in the array
418
+ */
419
+ lastIndexOf(searchElement, fromIndex) {
420
+ return this[forwardArray].lastIndexOf(searchElement, fromIndex);
421
+ }
422
+ /**
423
+ * Returns a shallow copy of a portion of an array into a new array object
424
+ */
425
+ slice(start, end) {
426
+ return this[forwardArray].slice(start, end);
427
+ }
428
+ concat(...items) {
429
+ return this[forwardArray].concat(...items);
430
+ }
431
+ /**
432
+ * Tests whether all elements in the array pass the test implemented by the provided function
433
+ */
434
+ every(predicate, thisArg) {
435
+ return this[forwardArray].every(predicate, thisArg);
436
+ }
437
+ /**
438
+ * Tests whether at least one element in the array passes the test implemented by the provided function
439
+ */
440
+ some(predicate, thisArg) {
441
+ return this[forwardArray].some(predicate, thisArg);
442
+ }
443
+ /**
444
+ * Joins all elements of an array into a string
445
+ */
446
+ join(separator) {
447
+ return this[forwardArray].join(separator);
448
+ }
449
+ /**
450
+ * Returns a new array iterator that contains the keys for each index in the array
451
+ */
452
+ keys() {
453
+ return this[forwardArray].keys();
454
+ }
455
+ /**
456
+ * Returns a new array iterator that contains the values for each index in the array
457
+ */
458
+ values() {
459
+ return this[forwardArray].values();
460
+ }
461
+ /**
462
+ * Returns a new array iterator that contains the key/value pairs for each index in the array
463
+ */
464
+ entries() {
465
+ return this[forwardArray].entries();
466
+ }
467
+ /**
468
+ * Returns a string representation of the array
469
+ */
470
+ toString() {
471
+ return this[forwardArray].toString();
472
+ }
473
+ /**
474
+ * Returns a localized string representing the array
475
+ */
476
+ toLocaleString(locales, options) {
477
+ return this[forwardArray].toLocaleString(locales, options);
478
+ }
479
+ /**
480
+ * Returns the element at the specified index, or undefined if the index is out of bounds
481
+ */
482
+ at(index) {
483
+ return this[forwardArray].at(index);
484
+ }
485
+ /**
486
+ * Returns a new array with all sub-array elements concatenated into it recursively up to the specified depth
487
+ */
488
+ flat(depth) {
489
+ return this[forwardArray].flat(depth);
490
+ }
491
+ /**
492
+ * Returns a new array formed by applying a given callback function to each element of the array,
493
+ * and then flattening the result by one level
494
+ */
495
+ flatMap(callback, thisArg) {
496
+ return this[forwardArray].flatMap(callback, thisArg);
497
+ }
498
+ /**
499
+ * Returns a new array with elements in reversed order (ES2023)
500
+ */
501
+ toReversed() {
502
+ return this[forwardArray].toReversed?.() ?? [...this[forwardArray]].reverse();
503
+ }
504
+ /**
505
+ * Returns a new array with elements sorted (ES2023)
506
+ */
507
+ toSorted(compareFn) {
508
+ return this[forwardArray].toSorted?.(compareFn) ?? [...this[forwardArray]].sort(compareFn);
509
+ }
510
+ /**
511
+ * Returns a new array with some elements removed and/or replaced at a given index (ES2023)
512
+ */
513
+ toSpliced(start, deleteCount, ...items) {
514
+ if (deleteCount === undefined)
515
+ return this[forwardArray].toSpliced(start);
516
+ return this[forwardArray].toSpliced(start, deleteCount, ...items);
517
+ }
518
+ /**
519
+ * Returns a new array with the element at the given index replaced with the given value (ES2023)
520
+ */
521
+ with(index, value) {
522
+ return this[forwardArray].with(index, value);
523
+ }
524
+ get [Symbol.unscopables]() {
525
+ return this[forwardArray][Symbol.unscopables];
526
+ }
527
+ }
528
+
529
+ const forward = (name, target) => (...args) => {
530
+ return target[name](...args);
531
+ };
532
+ const alreadyChained = new WeakMap();
533
+ const originals = new WeakMap();
534
+ function cache$1(target, rv) {
535
+ originals.set(rv, target);
536
+ alreadyChained.set(target, rv);
537
+ }
538
+ const promiseProxyHandler = {
539
+ //@ts-expect-error
540
+ [Symbol.toStringTag]: 'MutTs PromiseChain function',
541
+ get(target, prop) {
542
+ if (prop === Symbol.toStringTag)
543
+ return 'PromiseProxy';
544
+ if (typeof prop === 'string' && ['then', 'catch', 'finally'].includes(prop))
545
+ return target[prop];
546
+ return chainPromise(target.then((r) => r[prop]));
547
+ },
548
+ };
549
+ const promiseForward = (target) => ({
550
+ // biome-ignore lint/suspicious/noThenProperty: This one is the whole point
551
+ then: forward('then', target),
552
+ catch: forward('catch', target),
553
+ finally: forward('finally', target),
554
+ });
555
+ const objectProxyHandler = {
556
+ //@ts-expect-error
557
+ [Symbol.toStringTag]: 'MutTs PromiseChain object',
558
+ get(target, prop, receiver) {
559
+ const getter = Object.getOwnPropertyDescriptor(target, prop)?.get;
560
+ const rv = getter ? getter.call(receiver) : target[prop];
561
+ // Allows fct.call or fct.apply to bypass the chain system
562
+ if (typeof target === 'function')
563
+ return rv;
564
+ return chainPromise(rv);
565
+ },
566
+ apply(target, thisArg, args) {
567
+ return chainPromise(target.apply(thisArg, args));
568
+ },
569
+ };
570
+ function chainObject(given) {
571
+ const rv = new Proxy(given, objectProxyHandler);
572
+ cache$1(given, rv);
573
+ return rv;
574
+ }
575
+ function chainable(x) {
576
+ return x && ['function', 'object'].includes(typeof x);
577
+ }
578
+ /**
579
+ * Transforms a promise or value into a chainable object
580
+ * Allows calling methods directly on promise results without awaiting them first
581
+ * @param given - The promise or value to make chainable
582
+ * @returns A chainable version of the input
583
+ */
584
+ function chainPromise(given) {
585
+ if (!chainable(given))
586
+ return given;
587
+ if (alreadyChained.has(given))
588
+ return alreadyChained.get(given);
589
+ if (!(given instanceof Promise))
590
+ return chainObject(given);
591
+ // @ts-expect-error It's ok as we check if it's an object above
592
+ given = given.then((r) => (chainable(r) ? chainObject(r) : r));
593
+ const target = Object.assign(function (...args) {
594
+ return chainPromise(given.then((r) => {
595
+ return this?.then
596
+ ? this.then((t) => r.apply(t, args))
597
+ : r.apply(this, args);
598
+ }));
599
+ }, promiseForward(given));
600
+ const chained = new Proxy(target, promiseProxyHandler);
601
+ cache$1(given, chained);
602
+ return chained;
603
+ }
604
+
605
+ const memoizedRegistry = new WeakMap();
606
+ const wrapperRegistry = new WeakMap();
607
+ function getBranch(tree, key) {
608
+ tree.branches ?? (tree.branches = new WeakMap());
609
+ let branch = tree.branches.get(key);
610
+ if (!branch) {
611
+ branch = {};
612
+ tree.branches.set(key, branch);
613
+ }
614
+ return branch;
615
+ }
616
+ function memoizeFunction(fn) {
617
+ const fnRoot = debug.getRoot(fn);
618
+ const existing = memoizedRegistry.get(fnRoot);
619
+ if (existing)
620
+ return existing;
621
+ const cacheRoot = {};
622
+ const memoized = debug.markWithRoot((...args) => {
623
+ const localArgs = args; //: Args = maxArgs !== undefined ? (args.slice(0, maxArgs) as Args) : args
624
+ if (localArgs.some((arg) => !(arg && ['object', 'symbol', 'function'].includes(typeof arg))))
625
+ throw new Error('memoize expects non-null object arguments');
626
+ let node = cacheRoot;
627
+ // Note: decorators add `this` as first argument
628
+ for (const arg of localArgs) {
629
+ node = getBranch(node, arg);
630
+ }
631
+ debug.dependant(node, 'memoize');
632
+ if ('result' in node) {
633
+ if (debug.options.onMemoizationDiscrepancy) {
634
+ const wasVerification = debug.options.isVerificationRun;
635
+ debug.options.isVerificationRun = true;
636
+ try {
637
+ const fresh = debug.untracked(() => fn(...localArgs));
638
+ if (!debug.deepCompare(node.result, fresh)) {
639
+ debug.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, localArgs, 'calculation');
640
+ }
641
+ }
642
+ finally {
643
+ debug.options.isVerificationRun = wasVerification;
644
+ }
645
+ }
646
+ return node.result;
647
+ }
648
+ // Create memoize internal effect to track dependencies and invalidate cache
649
+ // Use untracked to prevent the effect creation from being affected by parent effects
650
+ node.cleanup = debug.root(() => debug.effect(() => {
651
+ // Execute the function and track its dependencies
652
+ // The function execution will automatically track dependencies on reactive objects
653
+ node.result = fn(...localArgs);
654
+ return () => {
655
+ // When dependencies change, clear the cache and notify consumers
656
+ delete node.result;
657
+ debug.touched1(node, { type: 'invalidate', prop: localArgs }, 'memoize');
658
+ // Lazy memoization: stop the effect so it doesn't re-run immediately.
659
+ // It will be re-created on next access.
660
+ if (node.cleanup) {
661
+ node.cleanup();
662
+ node.cleanup = undefined;
663
+ }
664
+ };
665
+ }, { opaque: true }));
666
+ if (debug.options.onMemoizationDiscrepancy) {
667
+ const wasVerification = debug.options.isVerificationRun;
668
+ debug.options.isVerificationRun = true;
669
+ try {
670
+ const fresh = debug.untracked(() => fn(...localArgs));
671
+ if (!debug.deepCompare(node.result, fresh)) {
672
+ debug.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, localArgs, 'comparison');
673
+ }
674
+ }
675
+ finally {
676
+ debug.options.isVerificationRun = wasVerification;
677
+ }
678
+ }
679
+ return node.result;
680
+ }, fn);
681
+ memoizedRegistry.set(fnRoot, memoized);
682
+ memoizedRegistry.set(memoized, memoized);
683
+ return memoized;
684
+ }
685
+ /**
686
+ * Decorator and function wrapper for memoizing computed values based on reactive dependencies.
687
+ *
688
+ * When used as a decorator on getters or methods, it caches the result and automatically
689
+ * invalidates the cache when reactive dependencies change.
690
+ *
691
+ * When used as a function wrapper, it memoizes based on object arguments (WeakMap-based cache).
692
+ *
693
+ * @example
694
+ * ```typescript
695
+ * class User {
696
+ * @memoize
697
+ * get fullName() {
698
+ * return `${this.firstName} ${this.lastName}`
699
+ * }
700
+ * }
701
+ *
702
+ * // Or as a function wrapper
703
+ * const expensive = memoize((obj: SomeObject) => {
704
+ * return heavyComputation(obj)
705
+ * })
706
+ * ```
707
+ */
708
+ const memoize = debug.decorator({
709
+ getter(original, target, propertyKey) {
710
+ return function () {
711
+ let wrapper = wrapperRegistry.get(original);
712
+ if (!wrapper) {
713
+ wrapper = debug.markWithRoot(debug.renamed((that) => {
714
+ return original.call(that);
715
+ }, `${String(target?.constructor?.name ?? target?.name ?? 'Object')}.${String(propertyKey)}`), {
716
+ method: original,
717
+ propertyKey,
718
+ ...(original[debug.rootFunction]
719
+ ? { [debug.rootFunction]: original[debug.rootFunction] }
720
+ : {}),
721
+ });
722
+ wrapperRegistry.set(original, wrapper);
723
+ }
724
+ const memoized = memoizeFunction(wrapper);
725
+ return memoized(this);
726
+ };
727
+ },
728
+ method(original, target, name) {
729
+ return function (...args) {
730
+ let wrapper = wrapperRegistry.get(original);
731
+ if (!wrapper) {
732
+ wrapper = debug.markWithRoot(debug.renamed((that, ...args) => {
733
+ return original.call(that, ...args);
734
+ }, `${String(target?.constructor?.name ?? target?.name ?? 'Object')}.${String(name)}`), {
735
+ method: original,
736
+ propertyKey: name,
737
+ ...(original[debug.rootFunction]
738
+ ? { [debug.rootFunction]: original[debug.rootFunction] }
739
+ : {}),
740
+ });
741
+ wrapperRegistry.set(original, wrapper);
742
+ }
743
+ const memoized = memoizeFunction(wrapper);
744
+ return memoized(this, ...args);
745
+ };
746
+ },
747
+ default: memoizeFunction,
748
+ });
749
+
750
+ function attend(source, callback) {
751
+ const enumerate = typeof source === 'function'
752
+ ? source
753
+ : Array.isArray(source)
754
+ ? () => Array.from({ length: source.length }, (_, i) => i)
755
+ : source instanceof Map
756
+ ? () => source.keys()
757
+ : source instanceof Set
758
+ ? () => source.values()
759
+ : () => Object.keys(source);
760
+ const keyEffects = new Map();
761
+ const outer = debug.effect(({ ascend }) => {
762
+ const keys = new Set();
763
+ for (const key of enumerate())
764
+ keys.add(key);
765
+ for (const key of keys) {
766
+ if (keyEffects.has(key))
767
+ continue;
768
+ keyEffects.set(key, ascend(() => debug.effect(() => callback(key))));
769
+ }
770
+ for (const key of Array.from(keyEffects.keys())) {
771
+ if (!keys.has(key)) {
772
+ keyEffects.get(key)();
773
+ keyEffects.delete(key);
774
+ }
775
+ }
776
+ });
777
+ return () => {
778
+ outer();
779
+ for (const stop of keyEffects.values())
780
+ stop();
781
+ keyEffects.clear();
782
+ };
783
+ }
784
+ /**
785
+ * Perform a reactive scan over an array of items.
786
+ *
787
+ * This implementation is highly optimized for performance and fine-grained reactivity:
788
+ * - **Incremental Updates**: Changes to an item only trigger re-computation from that
789
+ * point onwards in the result chain.
790
+ * - **Move Optimization**: If items are moved within the array, their accumulated
791
+ * values are reused as long as their predecessor remains the same.
792
+ * - **Duplicate Support**: Correctly handles multiple occurrences of the same object
793
+ * instance using an internal occurrence tracking mechanism.
794
+ * - **Memory Efficient**: Uses `WeakMap` for caching intermediates, which are
795
+ * automatically cleared when source items are garbage collected.
796
+ *
797
+ * @example
798
+ * ```typescript
799
+ * const source = reactive([{ val: 1 }, { val: 2 }, { val: 3 }])
800
+ * const sum = scan(source, (acc, item) => acc + item.val, 0)
801
+ *
802
+ * expect([...sum]).toEqual([1, 3, 6])
803
+ *
804
+ * // Modifying an item only re-computes subsequent sums
805
+ * source[1].val = 10
806
+ * expect([...sum]).toEqual([1, 11, 14])
807
+ * ```
808
+ *
809
+ * @param source The source array of objects (will be made reactive)
810
+ * @param callback The accumulator function called with (accumulator, currentItem)
811
+ * @param initialValue The starting value for the accumulation
812
+ * @returns A reactive array of accumulated values, with a [cleanup] property to stop the tracking
813
+ */
814
+ function scan(source, callback, initialValue) {
815
+ const observedSource = debug.reactive(source);
816
+ const result = debug.reactive([]);
817
+ // Track effects for each index to dispose them when the array shrinks
818
+ const indexEffects = new Map();
819
+ // Mapping from index to its current intermediate object
820
+ const indexToIntermediate = debug.reactive([]);
821
+ const intermediaries = new WeakMap();
822
+ let Intermediate = (() => {
823
+ var _a;
824
+ let _instanceExtraInitializers = [];
825
+ let _get_acc_decorators;
826
+ return _a = class Intermediate {
827
+ constructor(val, prev) {
828
+ this.val = (debug.__runInitializers(this, _instanceExtraInitializers), val);
829
+ this.prev = prev;
830
+ }
831
+ get acc() {
832
+ const prevAcc = this.prev ? this.prev.acc : initialValue;
833
+ return callback(prevAcc, this.val);
834
+ }
835
+ },
836
+ (() => {
837
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
838
+ _get_acc_decorators = [memoize];
839
+ debug.__esDecorate(_a, null, _get_acc_decorators, { kind: "getter", name: "acc", static: false, private: false, access: { has: obj => "acc" in obj, get: obj => obj.acc }, metadata: _metadata }, null, _instanceExtraInitializers);
840
+ if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
841
+ })(),
842
+ _a;
843
+ })();
844
+ function disposeIndex(index) {
845
+ const stop = indexEffects.get(index);
846
+ if (stop) {
847
+ stop();
848
+ indexEffects.delete(index);
849
+ debug.untracked(() => {
850
+ Reflect.deleteProperty(indexToIntermediate, index);
851
+ Reflect.deleteProperty(result, index);
852
+ });
853
+ }
854
+ }
855
+ const mainEffect = debug.effect(function scanMainEffect({ ascend }) {
856
+ const length = observedSource.length;
857
+ const occurrenceCount = new Map();
858
+ let prev;
859
+ for (let i = 0; i < length; i++) {
860
+ const val = debug.FoolProof.get(observedSource, i, observedSource);
861
+ if (!(val && (typeof val === 'object' || typeof val === 'function' || typeof val === 'symbol'))) {
862
+ throw new Error('scan: items must be objects (WeakKey) for intermediate caching');
863
+ }
864
+ const count = occurrenceCount.get(val) ?? 0;
865
+ occurrenceCount.set(val, count + 1);
866
+ let list = intermediaries.get(val);
867
+ if (!list) {
868
+ list = [];
869
+ intermediaries.set(val, list);
870
+ }
871
+ let intermediate = list[count];
872
+ if (!intermediate) {
873
+ intermediate = debug.reactive(new Intermediate(val, prev));
874
+ list[count] = intermediate;
875
+ }
876
+ else {
877
+ // Update the link.
878
+ if (debug.untracked(() => intermediate.prev) !== prev) {
879
+ intermediate.prev = prev;
880
+ }
881
+ }
882
+ // Update the reactive mapping for this index
883
+ if (indexToIntermediate[i] !== intermediate) {
884
+ indexToIntermediate[i] = intermediate;
885
+ }
886
+ // If we don't have an effect for this index yet, create one
887
+ if (!indexEffects.has(i)) {
888
+ ascend(() => {
889
+ const index = i;
890
+ const stop = debug.effect(function scanIndexSyncEffect() {
891
+ const inter = indexToIntermediate[index];
892
+ if (inter) {
893
+ const accValue = inter.acc;
894
+ debug.untracked(() => {
895
+ result[index] = accValue;
896
+ });
897
+ }
898
+ });
899
+ indexEffects.set(index, stop);
900
+ });
901
+ }
902
+ prev = intermediate;
903
+ }
904
+ // Cleanup trailing indices
905
+ for (const index of Array.from(indexEffects.keys())) {
906
+ if (index >= length)
907
+ disposeIndex(index);
908
+ }
909
+ // Ensure result length matches source length
910
+ debug.untracked(() => {
911
+ if (result.length !== length) {
912
+ debug.FoolProof.set(result, 'length', length, result);
913
+ }
914
+ });
915
+ });
916
+ return debug.cleanedBy(result, (() => {
917
+ mainEffect();
918
+ for (const stop of indexEffects.values())
919
+ stop();
920
+ indexEffects.clear();
921
+ }));
922
+ }
923
+ function lift(cb) {
924
+ let result;
925
+ const liftCleanup = debug.effect((access) => {
926
+ const source = cb(access);
927
+ if (!source || typeof source !== 'object')
928
+ throw new Error('lift callback must return an array or object');
929
+ if (!result) {
930
+ if (Array.isArray(source)) {
931
+ result = debug.reactive([]);
932
+ }
933
+ else {
934
+ result = debug.reactive({});
935
+ }
936
+ }
937
+ if (Array.isArray(source) && Array.isArray(result)) {
938
+ if (result.length !== source.length)
939
+ result.length = source.length;
940
+ for (let i = 0; i < source.length; i++)
941
+ if (result[i] !== source[i])
942
+ result[i] = source[i];
943
+ }
944
+ else if (!Array.isArray(source) && !Array.isArray(result)) {
945
+ Object.assign(result, source);
946
+ for (const key of Object.keys(result))
947
+ if (!(key in source))
948
+ delete result[key];
949
+ }
950
+ else {
951
+ throw new Error('lift callback must return the same type as the previous result');
952
+ }
953
+ });
954
+ return debug.cleanedBy(result, liftCleanup);
955
+ }
956
+
957
+ function isObject(value) {
958
+ return typeof value === 'object' && value !== null;
959
+ }
960
+ /**
961
+ * Deep watch an object and all its nested properties
962
+ * @param target - The object to watch deeply
963
+ * @param callback - The callback to call when any nested property changes
964
+ * @param options - Options for the deep watch
965
+ * @returns A cleanup function to stop watching
966
+ */
967
+ /**
968
+ * Sets up deep watching for an object, tracking all nested property changes
969
+ * @param target - The object to watch
970
+ * @param callback - The callback to call when changes occur
971
+ * @param options - Options for deep watching
972
+ * @returns A cleanup function to stop deep watching
973
+ */
974
+ function deepWatch(target, callback, { immediate = false } = {}) {
975
+ if (target === null || target === undefined)
976
+ return undefined;
977
+ if (typeof target !== 'object')
978
+ throw new Error('Target of deep watching must be an object');
979
+ // Create a wrapper callback that matches EffectTrigger signature
980
+ const wrappedCallback = debug.markWithRoot((() => callback(target)), callback);
981
+ // Use the existing effect system to register dependencies
982
+ return debug.effect(() => {
983
+ // Mark the target object as having deep watchers
984
+ debug.objectsWithDeepWatchers.add(target);
985
+ // Track which objects this effect is watching for cleanup
986
+ let effectObjects = debug.effectToDeepWatchedObjects.get(wrappedCallback);
987
+ if (!effectObjects) {
988
+ effectObjects = new Set();
989
+ debug.effectToDeepWatchedObjects.set(wrappedCallback, effectObjects);
990
+ }
991
+ effectObjects.add(target);
992
+ // Traverse the object graph and register dependencies
993
+ // This will re-run every time the effect runs, ensuring we catch all changes
994
+ const visited = new WeakSet();
995
+ function traverseAndTrack(obj, depth = 0) {
996
+ // Prevent infinite recursion and excessive depth
997
+ if (!obj || visited.has(obj) || !isObject(obj) || depth > debug.options.maxDeepWatchDepth)
998
+ return;
999
+ // Do not traverse into unreactive objects
1000
+ if (debug.isNonReactive(obj))
1001
+ return;
1002
+ visited.add(obj);
1003
+ // Mark this object as having deep watchers
1004
+ debug.objectsWithDeepWatchers.add(obj);
1005
+ effectObjects.add(obj);
1006
+ // Traverse all properties to register dependencies
1007
+ // unwrap to avoid kicking dependency
1008
+ for (const key in debug.unwrap(obj)) {
1009
+ if (Object.hasOwn(obj, key)) {
1010
+ // Access the property to register dependency
1011
+ const value = obj[key];
1012
+ // Make the value reactive if it's an object
1013
+ const reactiveValue = typeof value === 'object' && value !== null ? debug.reactive(value) : value;
1014
+ traverseAndTrack(reactiveValue, depth + 1);
1015
+ }
1016
+ }
1017
+ // Also handle array indices and length
1018
+ // biome-ignore lint/suspicious/useIsArray: Check for both native arrays and reactive arrays
1019
+ if (Array.isArray(obj) || obj instanceof Array) {
1020
+ // Access array length to register dependency on length changes
1021
+ const length = obj.length;
1022
+ // Access all current array elements to register dependencies
1023
+ for (let i = 0; i < length; i++) {
1024
+ // Access the array element to register dependency
1025
+ const value = obj[i];
1026
+ // Make the value reactive if it's an object
1027
+ const reactiveValue = typeof value === 'object' && value !== null ? debug.reactive(value) : value;
1028
+ traverseAndTrack(reactiveValue, depth + 1);
1029
+ }
1030
+ }
1031
+ // Handle Set values (deep watch values only, not keys since Sets don't have separate keys)
1032
+ else if (obj instanceof Set) {
1033
+ // Access all Set values to register dependencies
1034
+ for (const value of obj) {
1035
+ // Make the value reactive if it's an object
1036
+ const reactiveValue = typeof value === 'object' && value !== null ? debug.reactive(value) : value;
1037
+ traverseAndTrack(reactiveValue, depth + 1);
1038
+ }
1039
+ }
1040
+ // Handle Map values (deep watch values only, not keys)
1041
+ else if (obj instanceof Map) {
1042
+ // Access all Map values to register dependencies
1043
+ for (const [_key, value] of obj) {
1044
+ // Make the value reactive if it's an object
1045
+ const reactiveValue = typeof value === 'object' && value !== null ? debug.reactive(value) : value;
1046
+ traverseAndTrack(reactiveValue, depth + 1);
1047
+ }
1048
+ }
1049
+ // Note: WeakSet and WeakMap cannot be iterated, so we can't deep watch their contents
1050
+ // They will only trigger when the collection itself is replaced
1051
+ }
1052
+ // Traverse the target object to register all dependencies
1053
+ // This will register dependencies on all current properties and array elements
1054
+ traverseAndTrack(target);
1055
+ // Only call the callback if immediate is true or if it's not the first run
1056
+ if (immediate)
1057
+ callback(target);
1058
+ immediate = true;
1059
+ // Return a cleanup function that properly removes deep watcher tracking
1060
+ return () => {
1061
+ // Get the objects this effect was watching
1062
+ const effectObjects = debug.effectToDeepWatchedObjects.get(wrappedCallback);
1063
+ if (effectObjects) {
1064
+ // Remove deep watcher tracking from all objects this effect was watching
1065
+ for (const obj of effectObjects) {
1066
+ // Check if this object still has other deep watchers
1067
+ const watchers = debug.deepWatchers.get(obj);
1068
+ if (watchers) {
1069
+ // Remove this effect's callback from the watchers
1070
+ watchers.delete(wrappedCallback);
1071
+ // If no more watchers, remove the object from deep watchers tracking
1072
+ if (watchers.size === 0) {
1073
+ debug.deepWatchers.delete(obj);
1074
+ debug.objectsWithDeepWatchers.delete(obj);
1075
+ }
1076
+ }
1077
+ else {
1078
+ // No watchers found, remove from deep watchers tracking
1079
+ debug.objectsWithDeepWatchers.delete(obj);
1080
+ }
1081
+ }
1082
+ // Clean up the tracking data
1083
+ debug.effectToDeepWatchedObjects.delete(wrappedCallback);
1084
+ }
1085
+ };
1086
+ });
1087
+ }
1088
+
1089
+ /**
1090
+ * Converts an iterator to a generator that yields reactive values
1091
+ */
1092
+ function* makeReactiveIterator(iterator) {
1093
+ let result = iterator.next();
1094
+ while (!result.done) {
1095
+ yield debug.reactive(result.value);
1096
+ result = iterator.next();
1097
+ }
1098
+ }
1099
+ /**
1100
+ * Converts an iterator of key-value pairs to a generator that yields reactive key-value pairs
1101
+ */
1102
+ function* makeReactiveEntriesIterator(iterator) {
1103
+ let result = iterator.next();
1104
+ while (!result.done) {
1105
+ const [key, value] = result.value;
1106
+ yield [debug.reactive(key), debug.reactive(value)];
1107
+ result = iterator.next();
1108
+ }
1109
+ }
1110
+
1111
+ //#region watch
1112
+ const unsetYet = Symbol('unset-yet');
1113
+ function watch(value, //object | ((dep: DependencyAccess) => object),
1114
+ changed, options = {}) {
1115
+ return typeof value === 'function'
1116
+ ? watchCallBack(value, changed, options)
1117
+ : typeof value === 'object' && value !== null
1118
+ ? watchObject(value, changed, options)
1119
+ : (() => {
1120
+ throw new Error('watch: value must be a function or an object');
1121
+ })();
1122
+ }
1123
+ function watchObject(value, changed, { immediate = false, deep = false } = {}) {
1124
+ if (deep)
1125
+ return deepWatch(value, changed, { immediate });
1126
+ return debug.effect(function watchObjectEffect() {
1127
+ debug.dependant(value);
1128
+ if (immediate)
1129
+ changed(value);
1130
+ immediate = true;
1131
+ });
1132
+ }
1133
+ function watchCallBack(value, changed, { immediate = false, deep = false } = {}) {
1134
+ let oldValue = unsetYet;
1135
+ let deepCleanup;
1136
+ const cbCleanup = debug.effect(debug.markWithRoot(function watchCallBackEffect(access) {
1137
+ const newValue = value(access);
1138
+ if (oldValue !== newValue)
1139
+ if (oldValue === unsetYet) {
1140
+ if (immediate)
1141
+ changed(newValue);
1142
+ }
1143
+ else
1144
+ changed(newValue, oldValue);
1145
+ oldValue = newValue;
1146
+ if (deep) {
1147
+ if (deepCleanup)
1148
+ deepCleanup();
1149
+ deepCleanup = deepWatch(newValue, (value) => changed(value, value));
1150
+ }
1151
+ }, value));
1152
+ return Object.defineProperties(() => {
1153
+ cbCleanup();
1154
+ if (deepCleanup)
1155
+ deepCleanup();
1156
+ }, {
1157
+ [debug.stopped]: { get: () => cbCleanup[debug.stopped] },
1158
+ });
1159
+ }
1160
+ //#endregion
1161
+ //#region nonReactive
1162
+ /**
1163
+ * Mark an object as non-reactive. This object and all its properties will never be made reactive.
1164
+ * @param obj - The object to mark as non-reactive
1165
+ */
1166
+ function shallowNonReactive(obj) {
1167
+ obj = debug.unwrap(obj);
1168
+ if (debug.isNonReactive(obj))
1169
+ return obj;
1170
+ try {
1171
+ Object.defineProperty(obj, debug.nonReactiveMark, {
1172
+ value: true,
1173
+ writable: false,
1174
+ enumerable: false,
1175
+ configurable: true,
1176
+ });
1177
+ }
1178
+ catch { }
1179
+ if (!(debug.nonReactiveMark in obj))
1180
+ debug.nonReactiveObjects.add(obj);
1181
+ // Finally, not deep
1182
+ //for (const key in obj) deepNonReactive(obj[key])
1183
+ return obj;
1184
+ }
1185
+ function unreactiveApplication(arg1, ...args) {
1186
+ return typeof arg1 === 'object'
1187
+ ? shallowNonReactive(arg1)
1188
+ : ((original) => {
1189
+ // Copy the parent's unreactive properties if they exist
1190
+ original.prototype[debug.unreactiveProperties] = new Set(original.prototype[debug.unreactiveProperties] || []);
1191
+ // Add all arguments (including the first one)
1192
+ original.prototype[debug.unreactiveProperties].add(arg1);
1193
+ for (const arg of args)
1194
+ original.prototype[debug.unreactiveProperties].add(arg);
1195
+ return original; // Return the class
1196
+ });
1197
+ }
1198
+ /**
1199
+ * Decorator that marks classes or properties as non-reactive
1200
+ * Prevents objects from being made reactive
1201
+ */
1202
+ const unreactive = debug.decorator({
1203
+ class(original) {
1204
+ // Called without arguments, mark entire class as non-reactive
1205
+ debug.nonReactiveClass(original);
1206
+ },
1207
+ default: unreactiveApplication,
1208
+ });
1209
+ //#endregion
1210
+
1211
+ // Helper to work around TypeScript limitation: base class expressions cannot reference class type parameters
1212
+ function getRegisterBase() {
1213
+ class RegisterBase extends Indexable(ArrayReadForward, {
1214
+ get(index) {
1215
+ return this[getAt](index);
1216
+ },
1217
+ set(index, value) {
1218
+ this[setAt](index, value);
1219
+ },
1220
+ getLength() {
1221
+ return this.length;
1222
+ },
1223
+ setLength(value) {
1224
+ this.length = value;
1225
+ },
1226
+ }) {
1227
+ toArray() {
1228
+ return Array.from(this);
1229
+ }
1230
+ }
1231
+ return RegisterBase;
1232
+ }
1233
+ let RegisterClass = (() => {
1234
+ var _RegisterClass_instances, _RegisterClass_keyFn, _RegisterClass_keys, _RegisterClass_values, _RegisterClass_usage, _RegisterClass_valueInfo, _RegisterClass_keyEffects, _RegisterClass_ascend, _RegisterClass_events, _RegisterClass_rekeyValue;
1235
+ let _classDecorators = [unreactive];
1236
+ let _classDescriptor;
1237
+ let _classExtraInitializers = [];
1238
+ let _classThis;
1239
+ let _classSuper = getRegisterBase();
1240
+ _classThis = class extends _classSuper {
1241
+ get [(_RegisterClass_keyFn = new WeakMap(), _RegisterClass_keys = new WeakMap(), _RegisterClass_values = new WeakMap(), _RegisterClass_usage = new WeakMap(), _RegisterClass_valueInfo = new WeakMap(), _RegisterClass_keyEffects = new WeakMap(), _RegisterClass_ascend = new WeakMap(), _RegisterClass_events = new WeakMap(), _RegisterClass_instances = new WeakSet(), forwardArray)]() {
1242
+ return this.toArray();
1243
+ }
1244
+ on(eventOrEvents, cb) {
1245
+ // @ts-expect-error Delegate to Eventful
1246
+ return debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").on(eventOrEvents, cb);
1247
+ }
1248
+ off(eventOrEvents, cb) {
1249
+ // @ts-expect-error Delegate to Eventful
1250
+ debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").off(eventOrEvents, cb);
1251
+ }
1252
+ /**
1253
+ * Register a global hook that receives all events
1254
+ */
1255
+ hook(cb) {
1256
+ return debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").hook(cb);
1257
+ }
1258
+ constructor(keyFn, initial) {
1259
+ super();
1260
+ _RegisterClass_instances.add(this);
1261
+ _RegisterClass_keyFn.set(this, void 0);
1262
+ _RegisterClass_keys.set(this, void 0);
1263
+ _RegisterClass_values.set(this, void 0);
1264
+ _RegisterClass_usage.set(this, new Map());
1265
+ _RegisterClass_valueInfo.set(this, new Map());
1266
+ _RegisterClass_keyEffects.set(this, new Set());
1267
+ _RegisterClass_ascend.set(this, void 0);
1268
+ _RegisterClass_events.set(this, new Eventful()
1269
+ /**
1270
+ * Register event listeners for CRUD operations
1271
+ */
1272
+ );
1273
+ /* Moved below initialization */
1274
+ let ascendGet;
1275
+ debug.effect(({ ascend }) => {
1276
+ ascendGet = ascend;
1277
+ });
1278
+ debug.__classPrivateFieldSet(this, _RegisterClass_ascend, ascendGet, "f");
1279
+ if (typeof keyFn !== 'function')
1280
+ throw new Error('Register requires a key function');
1281
+ debug.__classPrivateFieldSet(this, _RegisterClass_keyFn, keyFn, "f");
1282
+ debug.__classPrivateFieldSet(this, _RegisterClass_keys, debug.reactive([]), "f");
1283
+ debug.__classPrivateFieldSet(this, _RegisterClass_values, debug.reactive(new Map()), "f");
1284
+ if (initial)
1285
+ this.push(...initial);
1286
+ }
1287
+ ensureKey(value) {
1288
+ let info = debug.__classPrivateFieldGet(this, _RegisterClass_valueInfo, "f").get(value);
1289
+ if (info)
1290
+ return info.key;
1291
+ info = { key: undefined };
1292
+ debug.__classPrivateFieldGet(this, _RegisterClass_valueInfo, "f").set(value, info);
1293
+ debug.__classPrivateFieldGet(this, _RegisterClass_ascend, "f").call(this, () => {
1294
+ const stop = debug.effect(({ reaction }) => {
1295
+ const nextKey = debug.__classPrivateFieldGet(this, _RegisterClass_keyFn, "f").call(this, value);
1296
+ this.assertValidKey(nextKey);
1297
+ const previousKey = info.key;
1298
+ if (reaction && previousKey !== undefined && !Object.is(nextKey, previousKey))
1299
+ debug.__classPrivateFieldGet(this, _RegisterClass_instances, "m", _RegisterClass_rekeyValue).call(this, value, previousKey, nextKey);
1300
+ info.key = nextKey;
1301
+ });
1302
+ info.stop = stop;
1303
+ debug.__classPrivateFieldGet(this, _RegisterClass_keyEffects, "f").add(stop);
1304
+ });
1305
+ if (info.key === undefined)
1306
+ throw new Error('Register key function must return a property key');
1307
+ return info.key;
1308
+ }
1309
+ assertValidKey(key) {
1310
+ const type = typeof key;
1311
+ if (type !== 'string' && type !== 'number' && type !== 'symbol')
1312
+ throw new Error('Register key function must return a property key');
1313
+ }
1314
+ setKeyValue(key, value, index) {
1315
+ const existing = debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1316
+ if (existing !== undefined && existing !== value) {
1317
+ this.cleanupValue(existing);
1318
+ debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").set(key, value);
1319
+ if (index !== undefined) {
1320
+ debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").emit('update', existing, value, key, index);
1321
+ }
1322
+ }
1323
+ else {
1324
+ debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").set(key, value);
1325
+ }
1326
+ }
1327
+ cleanupValue(value) {
1328
+ const info = debug.__classPrivateFieldGet(this, _RegisterClass_valueInfo, "f").get(value);
1329
+ if (!info)
1330
+ return;
1331
+ const stop = info.stop;
1332
+ if (stop) {
1333
+ info.stop = undefined;
1334
+ debug.__classPrivateFieldGet(this, _RegisterClass_keyEffects, "f").delete(stop);
1335
+ stop();
1336
+ }
1337
+ debug.__classPrivateFieldGet(this, _RegisterClass_valueInfo, "f").delete(value);
1338
+ }
1339
+ disposeKeyEffects() {
1340
+ for (const value of Array.from(debug.__classPrivateFieldGet(this, _RegisterClass_valueInfo, "f").keys()))
1341
+ this.cleanupValue(value);
1342
+ debug.__classPrivateFieldGet(this, _RegisterClass_keyEffects, "f").clear();
1343
+ }
1344
+ incrementUsage(key) {
1345
+ const count = debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").get(key) ?? 0;
1346
+ debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").set(key, count + 1);
1347
+ }
1348
+ decrementUsage(key, index) {
1349
+ const count = debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").get(key);
1350
+ if (!count)
1351
+ return;
1352
+ if (count <= 1) {
1353
+ const value = debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1354
+ debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").delete(key);
1355
+ debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").delete(key);
1356
+ if (value !== undefined) {
1357
+ this.cleanupValue(value);
1358
+ const idx = index ?? debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").indexOf(key);
1359
+ debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").emit('delete', value, key, idx);
1360
+ }
1361
+ }
1362
+ else {
1363
+ debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").set(key, count - 1);
1364
+ }
1365
+ }
1366
+ normalizeIndex(index, allowEnd = false) {
1367
+ const length = this.length;
1368
+ let resolved = index;
1369
+ if (resolved < 0)
1370
+ resolved = Math.max(length + resolved, 0);
1371
+ if (resolved > length) {
1372
+ if (allowEnd)
1373
+ resolved = length;
1374
+ else
1375
+ throw new RangeError('Index out of bounds');
1376
+ }
1377
+ if (!allowEnd && resolved === length)
1378
+ throw new RangeError('Index out of bounds');
1379
+ return resolved;
1380
+ }
1381
+ assignAt(index, key, value) {
1382
+ const oldKey = debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f")[index];
1383
+ if (oldKey !== undefined && Object.is(oldKey, key)) {
1384
+ const oldValue = debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1385
+ this.setKeyValue(key, value);
1386
+ if (oldValue !== undefined && oldValue !== value) {
1387
+ debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").emit('update', oldValue, value, key, index);
1388
+ }
1389
+ return;
1390
+ }
1391
+ if (oldKey !== undefined)
1392
+ this.decrementUsage(oldKey);
1393
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f")[index] = key;
1394
+ this.incrementUsage(key);
1395
+ this.setKeyValue(key, value);
1396
+ debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").emit('add', value, key, index);
1397
+ }
1398
+ insertKeyValue(index, key, value) {
1399
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").splice(index, 0, key);
1400
+ this.incrementUsage(key);
1401
+ this.setKeyValue(key, value);
1402
+ debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").emit('add', value, key, index);
1403
+ }
1404
+ rebuildFrom(values) {
1405
+ this.disposeKeyEffects();
1406
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").splice(0, debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").length);
1407
+ debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").clear();
1408
+ debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").clear();
1409
+ for (const value of values) {
1410
+ const key = this.ensureKey(value);
1411
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").push(key);
1412
+ this.incrementUsage(key);
1413
+ debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").set(key, value);
1414
+ }
1415
+ }
1416
+ get length() {
1417
+ return debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").length;
1418
+ }
1419
+ [(_RegisterClass_rekeyValue = function _RegisterClass_rekeyValue(value, oldKey, newKey) {
1420
+ if (Object.is(oldKey, newKey))
1421
+ return;
1422
+ const existingValue = debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(newKey);
1423
+ if (existingValue !== undefined && existingValue !== value)
1424
+ throw new Error(`Register key collision for key ${String(newKey)}`);
1425
+ const count = debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").get(oldKey);
1426
+ if (!count)
1427
+ return;
1428
+ const existingCount = debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").get(newKey) ?? 0;
1429
+ this.setKeyValue(newKey, value);
1430
+ let index = -1;
1431
+ for (let i = 0; i < debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").length; i++)
1432
+ if (Object.is(debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f")[i], oldKey)) {
1433
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f")[i] = newKey;
1434
+ if (index === -1)
1435
+ index = i;
1436
+ }
1437
+ debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").set(newKey, existingCount + count);
1438
+ debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").delete(oldKey);
1439
+ debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").delete(oldKey);
1440
+ const updatedInfo = debug.__classPrivateFieldGet(this, _RegisterClass_valueInfo, "f").get(value);
1441
+ if (updatedInfo)
1442
+ updatedInfo.key = newKey;
1443
+ if (index !== -1) {
1444
+ debug.__classPrivateFieldGet(this, _RegisterClass_events, "f").emit('rekey', value, oldKey, newKey, index);
1445
+ }
1446
+ }, getAt)](index) {
1447
+ const key = debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f")[index];
1448
+ return key === undefined ? undefined : debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1449
+ }
1450
+ [setAt](index, value) {
1451
+ const key = this.ensureKey(value);
1452
+ if (index === this.length) {
1453
+ this.insertKeyValue(index, key, value);
1454
+ return;
1455
+ }
1456
+ const normalized = this.normalizeIndex(index);
1457
+ this.assignAt(normalized, key, value);
1458
+ }
1459
+ push(...items) {
1460
+ for (const item of items) {
1461
+ const key = this.ensureKey(item);
1462
+ this.insertKeyValue(this.length, key, item);
1463
+ }
1464
+ return this.length;
1465
+ }
1466
+ pop() {
1467
+ if (!this.length)
1468
+ return undefined;
1469
+ return this.removeAt(this.length - 1);
1470
+ }
1471
+ shift() {
1472
+ if (!this.length)
1473
+ return undefined;
1474
+ return this.removeAt(0);
1475
+ }
1476
+ unshift(...items) {
1477
+ let index = 0;
1478
+ for (const item of items) {
1479
+ const key = this.ensureKey(item);
1480
+ this.insertKeyValue(index++, key, item);
1481
+ }
1482
+ return this.length;
1483
+ }
1484
+ splice(start, deleteCount, ...items) {
1485
+ const normalizedStart = this.normalizeIndex(start, true);
1486
+ const maxDeletions = this.length - normalizedStart;
1487
+ const actualDelete = Math.min(deleteCount === undefined ? maxDeletions : Math.max(deleteCount, 0), maxDeletions);
1488
+ const keysToInsert = [];
1489
+ for (const item of items)
1490
+ keysToInsert.push(this.ensureKey(item));
1491
+ const removedKeys = debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").splice(normalizedStart, actualDelete, ...keysToInsert);
1492
+ const removedValues = [];
1493
+ for (let i = 0; i < removedKeys.length; i++) {
1494
+ const key = removedKeys[i];
1495
+ if (key === undefined)
1496
+ continue;
1497
+ const value = debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1498
+ this.decrementUsage(key, normalizedStart + i);
1499
+ removedValues.push(value);
1500
+ }
1501
+ for (let i = 0; i < keysToInsert.length; i++) {
1502
+ const key = keysToInsert[i];
1503
+ const value = items[i];
1504
+ this.incrementUsage(key);
1505
+ this.setKeyValue(key, value);
1506
+ }
1507
+ return removedValues;
1508
+ }
1509
+ clear() {
1510
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").length = 0;
1511
+ debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").clear();
1512
+ debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").clear();
1513
+ this.disposeKeyEffects();
1514
+ }
1515
+ get(key) {
1516
+ return debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1517
+ }
1518
+ set(key, value) {
1519
+ if (debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").has(key))
1520
+ this.setKeyValue(key, value);
1521
+ }
1522
+ remove(key) {
1523
+ let index = this.indexOfKey(key);
1524
+ while (index !== -1) {
1525
+ this.removeAt(index);
1526
+ index = this.indexOfKey(key);
1527
+ }
1528
+ }
1529
+ removeAt(index) {
1530
+ const [key] = debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").splice(index, 1);
1531
+ if (key === undefined)
1532
+ return undefined;
1533
+ const value = debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1534
+ this.decrementUsage(key, index);
1535
+ return value;
1536
+ }
1537
+ /**
1538
+ * Keep only the items for which the predicate returns true.
1539
+ * Items for which the predicate returns false are removed.
1540
+ *
1541
+ * The predicate is evaluated once per distinct key; duplicate keys
1542
+ * will follow the same keep/remove decision.
1543
+ */
1544
+ keep(predicate) {
1545
+ const decisions = new Map();
1546
+ for (const [index, key] of debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").entries()) {
1547
+ if (decisions.has(key)) {
1548
+ if (!decisions.get(key))
1549
+ this.removeAt(index);
1550
+ continue;
1551
+ }
1552
+ const value = debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(key);
1553
+ const shouldKeep = predicate(value);
1554
+ decisions.set(key, shouldKeep);
1555
+ if (!shouldKeep)
1556
+ this.removeAt(index);
1557
+ }
1558
+ }
1559
+ hasKey(key) {
1560
+ return debug.__classPrivateFieldGet(this, _RegisterClass_usage, "f").has(key);
1561
+ }
1562
+ indexOfKey(key) {
1563
+ return debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").indexOf(key);
1564
+ }
1565
+ mapKeys() {
1566
+ return debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").keys();
1567
+ }
1568
+ update(...values) {
1569
+ for (const value of values) {
1570
+ const key = this.ensureKey(value);
1571
+ if (debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").has(key)) {
1572
+ const index = debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").indexOf(key);
1573
+ this.setKeyValue(key, value, index);
1574
+ }
1575
+ }
1576
+ }
1577
+ upsert(insert, ...values) {
1578
+ for (const value of values) {
1579
+ const key = this.ensureKey(value);
1580
+ if (debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").has(key))
1581
+ this.setKeyValue(key, value);
1582
+ else
1583
+ insert(value);
1584
+ }
1585
+ }
1586
+ entries() {
1587
+ const self = this;
1588
+ function* iterator() {
1589
+ for (let i = 0; i < debug.__classPrivateFieldGet(self, _RegisterClass_keys, "f").length; i++) {
1590
+ const val = debug.__classPrivateFieldGet(self, _RegisterClass_values, "f").get(debug.__classPrivateFieldGet(self, _RegisterClass_keys, "f")[i]);
1591
+ if (val !== undefined)
1592
+ yield [i, val];
1593
+ }
1594
+ }
1595
+ return iterator();
1596
+ }
1597
+ [Symbol.iterator]() {
1598
+ const self = this;
1599
+ function* iterator() {
1600
+ for (const key of debug.__classPrivateFieldGet(self, _RegisterClass_keys, "f")) {
1601
+ const value = debug.__classPrivateFieldGet(self, _RegisterClass_values, "f").get(key);
1602
+ if (value !== undefined)
1603
+ yield value;
1604
+ }
1605
+ }
1606
+ return iterator();
1607
+ }
1608
+ toString() {
1609
+ return `[Register length=${this.length}]`;
1610
+ }
1611
+ at(index) {
1612
+ const resolved = index < 0 ? this.length + index : index;
1613
+ if (resolved < 0 || resolved >= this.length)
1614
+ return undefined;
1615
+ return this[getAt](resolved);
1616
+ }
1617
+ reverse() {
1618
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").reverse();
1619
+ return this;
1620
+ }
1621
+ sort(compareFn) {
1622
+ const fwdCompareFn = compareFn
1623
+ ? (a, b) => compareFn(debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(a), debug.__classPrivateFieldGet(this, _RegisterClass_values, "f").get(b))
1624
+ : undefined;
1625
+ debug.__classPrivateFieldGet(this, _RegisterClass_keys, "f").sort(fwdCompareFn);
1626
+ return this;
1627
+ }
1628
+ fill(value, start = 0, end = this.length) {
1629
+ const values = this.toArray();
1630
+ values.fill(value, start, end);
1631
+ this.rebuildFrom(values);
1632
+ return this;
1633
+ }
1634
+ copyWithin(target, start, end) {
1635
+ const values = this.toArray();
1636
+ values.copyWithin(target, start, end);
1637
+ this.rebuildFrom(values);
1638
+ return this;
1639
+ }
1640
+ };
1641
+ debug.__setFunctionName(_classThis, "RegisterClass");
1642
+ (() => {
1643
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
1644
+ debug.__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
1645
+ _classThis = _classDescriptor.value;
1646
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
1647
+ debug.__runInitializers(_classThis, _classExtraInitializers);
1648
+ })();
1649
+ return _classThis;
1650
+ })();
1651
+ const Register = RegisterClass;
1652
+ /**
1653
+ * Creates a reactive Register - an ordered, array-like collection with stable key-based identity.
1654
+ *
1655
+ * Register combines array semantics (indexable access, ordering, iteration) with Map-like
1656
+ * key-based lookups. Items with the same key share the same value instance, making it ideal
1657
+ * for UI lists keyed by IDs or when you need to preserve identity across reorders.
1658
+ *
1659
+ * @param keyFn - Function that extracts the key from each item
1660
+ * @param initial - Optional initial items to populate the register
1661
+ * @returns A reactive Register instance
1662
+ *
1663
+ * @example
1664
+ * ```typescript
1665
+ * const users = register(
1666
+ * (user: User) => user.id,
1667
+ * [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
1668
+ * )
1669
+ *
1670
+ * users.push({ id: 3, name: 'Charlie' })
1671
+ * const bob = users.get(2) // Get by key
1672
+ * ```
1673
+ */
1674
+ function register(keyFn, initial) {
1675
+ return new RegisterClass(keyFn, initial);
1676
+ }
1677
+
1678
+ /**
1679
+ * Maps projection effects (item effects) to their projection context
1680
+ */
1681
+ const effectProjectionMetadata = new WeakMap();
1682
+ /**
1683
+ * Returns the projection context of the currently running effect, if any.
1684
+ */
1685
+ function getActiveProjection() {
1686
+ const active = debug.getActiveEffect();
1687
+ return active ? effectProjectionMetadata.get(active) : undefined;
1688
+ }
1689
+ function setActiveProjection(projection) {
1690
+ const active = debug.getActiveEffect();
1691
+ if (active)
1692
+ effectProjectionMetadata.set(active, projection);
1693
+ }
1694
+ function defineAccessValue(access) {
1695
+ Object.defineProperty(access, 'value', {
1696
+ get: access.get,
1697
+ set: access.set,
1698
+ configurable: true,
1699
+ enumerable: true,
1700
+ });
1701
+ }
1702
+ function makeCleanup(target, effectMap, onDispose, metadata) {
1703
+ if (metadata) {
1704
+ Object.defineProperty(target, debug.projectionInfo, {
1705
+ value: metadata,
1706
+ writable: false,
1707
+ enumerable: false,
1708
+ configurable: true,
1709
+ });
1710
+ }
1711
+ return debug.cleanedBy(target, () => {
1712
+ onDispose();
1713
+ for (const stop of effectMap.values())
1714
+ stop?.();
1715
+ effectMap.clear();
1716
+ });
1717
+ }
1718
+ function projectArray(source, apply) {
1719
+ source = debug.reactive(source);
1720
+ const target = debug.reactive([]);
1721
+ const indexEffects = new Map();
1722
+ function normalizeTargetLength(length) {
1723
+ debug.FoolProof.set(target, 'length', length, target);
1724
+ }
1725
+ function disposeIndex(index) {
1726
+ const stopEffect = indexEffects.get(index);
1727
+ if (stopEffect) {
1728
+ indexEffects.delete(index);
1729
+ stopEffect();
1730
+ Reflect.deleteProperty(target, index);
1731
+ }
1732
+ }
1733
+ const parent = getActiveProjection();
1734
+ const depth = parent ? parent.depth + 1 : 0;
1735
+ const cleanupLength = debug.effect(debug.named(`project:${source[Symbol.toStringTag]}.length`, ({ ascend }) => {
1736
+ const length = source.length;
1737
+ normalizeTargetLength(length);
1738
+ const existing = Array.from(indexEffects.keys());
1739
+ for (let i = 0; i < length; i++) {
1740
+ if (indexEffects.has(i))
1741
+ continue;
1742
+ ascend(function projectArrayIndexAscend() {
1743
+ const index = i;
1744
+ const stop = debug.effect(debug.named(`project:${source[Symbol.toStringTag]}[${index}]`, ({ reaction }) => {
1745
+ if (!reaction)
1746
+ setActiveProjection({ source, key: index, target, depth, parent });
1747
+ const previous = debug.untracked(() => target[index]);
1748
+ const accessBase = {
1749
+ key: index,
1750
+ source,
1751
+ get: () => debug.FoolProof.get(source, index, source),
1752
+ set: (value) => debug.FoolProof.set(source, index, value, source),
1753
+ old: previous,
1754
+ };
1755
+ defineAccessValue(accessBase);
1756
+ target[index] = apply(accessBase, target);
1757
+ }));
1758
+ debug.setEffectName(stop, `project[${depth}]:${index}`);
1759
+ indexEffects.set(i, stop);
1760
+ });
1761
+ }
1762
+ for (const index of existing)
1763
+ if (index >= length)
1764
+ disposeIndex(index);
1765
+ }));
1766
+ return makeCleanup(target, indexEffects, () => cleanupLength(), {
1767
+ source,
1768
+ target,
1769
+ apply,
1770
+ depth,
1771
+ parent,
1772
+ });
1773
+ }
1774
+ function projectRegister(source, apply) {
1775
+ source = debug.reactive(source);
1776
+ const rawTarget = new Map();
1777
+ const target = debug.reactive(rawTarget);
1778
+ const keyEffects = new Map();
1779
+ function disposeKey(key) {
1780
+ const stopEffect = keyEffects.get(key);
1781
+ if (stopEffect) {
1782
+ stopEffect();
1783
+ keyEffects.delete(key);
1784
+ target.delete(key);
1785
+ }
1786
+ }
1787
+ const parent = getActiveProjection();
1788
+ const depth = parent ? parent.depth + 1 : 0;
1789
+ const cleanupKeys = debug.effect(function projectRegisterEffect({ ascend }) {
1790
+ const keys = new Set();
1791
+ for (const key of source.mapKeys())
1792
+ keys.add(key);
1793
+ for (const key of keys) {
1794
+ if (keyEffects.has(key))
1795
+ continue;
1796
+ ascend(() => {
1797
+ const stop = debug.effect(function projectRegisterKeyEffect({ reaction }) {
1798
+ if (!reaction)
1799
+ setActiveProjection({ source, key, target, depth, parent });
1800
+ const previous = debug.untracked(() => target.get(key));
1801
+ const accessBase = {
1802
+ key,
1803
+ source: source,
1804
+ get: () => source.get(key),
1805
+ set: (value) => {
1806
+ source.set(key, value);
1807
+ return true;
1808
+ },
1809
+ old: previous,
1810
+ };
1811
+ defineAccessValue(accessBase);
1812
+ const produced = apply(accessBase, target);
1813
+ target.set(key, produced);
1814
+ });
1815
+ debug.setEffectName(stop, `project[${depth}]:${String(key)}`);
1816
+ keyEffects.set(key, stop);
1817
+ });
1818
+ }
1819
+ for (const key of Array.from(keyEffects.keys()))
1820
+ if (!keys.has(key))
1821
+ disposeKey(key);
1822
+ });
1823
+ return makeCleanup(target, keyEffects, () => cleanupKeys(), {
1824
+ source: source,
1825
+ target,
1826
+ apply,
1827
+ depth,
1828
+ parent,
1829
+ });
1830
+ }
1831
+ function projectRecord(source, apply) {
1832
+ source = debug.reactive(source);
1833
+ const target = debug.reactive({});
1834
+ const keyEffects = new Map();
1835
+ function disposeKey(key) {
1836
+ const stopEffect = keyEffects.get(key);
1837
+ if (stopEffect) {
1838
+ stopEffect();
1839
+ keyEffects.delete(key);
1840
+ Reflect.deleteProperty(target, key);
1841
+ }
1842
+ }
1843
+ const parent = getActiveProjection();
1844
+ const depth = parent ? parent.depth + 1 : 0;
1845
+ const cleanupKeys = debug.effect(function projectRecordEffect({ ascend }) {
1846
+ const keys = new Set();
1847
+ for (const key in source)
1848
+ keys.add(key);
1849
+ const observed = Reflect.ownKeys(source);
1850
+ for (const key of observed)
1851
+ keys.add(key);
1852
+ for (const key of keys) {
1853
+ if (keyEffects.has(key))
1854
+ continue;
1855
+ ascend(() => {
1856
+ const stop = debug.effect(function projectRecordKeyEffect({ reaction }) {
1857
+ if (!reaction)
1858
+ setActiveProjection({ source, key, target, depth, parent });
1859
+ const sourceKey = key;
1860
+ const previous = debug.untracked(() => target[key]);
1861
+ const accessBase = {
1862
+ key: sourceKey,
1863
+ source: source,
1864
+ get: () => debug.FoolProof.get(source, sourceKey, source),
1865
+ set: (value) => debug.FoolProof.set(source, sourceKey, value, source),
1866
+ old: previous,
1867
+ };
1868
+ defineAccessValue(accessBase);
1869
+ const produced = apply(accessBase, target);
1870
+ target[sourceKey] = produced;
1871
+ });
1872
+ debug.setEffectName(stop, `project[${depth}]:${String(key)}`);
1873
+ keyEffects.set(key, stop);
1874
+ });
1875
+ }
1876
+ for (const key of Array.from(keyEffects.keys()))
1877
+ if (!keys.has(key))
1878
+ disposeKey(key);
1879
+ });
1880
+ return makeCleanup(target, keyEffects, () => cleanupKeys(), {
1881
+ source: source,
1882
+ target,
1883
+ apply,
1884
+ depth,
1885
+ parent,
1886
+ });
1887
+ }
1888
+ function projectMap(source, apply) {
1889
+ source = debug.reactive(source);
1890
+ const rawTarget = new Map();
1891
+ const target = debug.reactive(rawTarget);
1892
+ const keyEffects = new Map();
1893
+ function disposeKey(key) {
1894
+ const stopEffect = keyEffects.get(key);
1895
+ if (stopEffect) {
1896
+ stopEffect();
1897
+ keyEffects.delete(key);
1898
+ target.delete(key);
1899
+ }
1900
+ }
1901
+ const parent = getActiveProjection();
1902
+ const depth = parent ? parent.depth + 1 : 0;
1903
+ const cleanupKeys = debug.effect(function projectMapEffect({ ascend }) {
1904
+ const keys = new Set();
1905
+ for (const key of source.keys())
1906
+ keys.add(key);
1907
+ for (const key of keys) {
1908
+ if (keyEffects.has(key))
1909
+ continue;
1910
+ ascend(() => {
1911
+ const stop = debug.effect(function projectMapKeyEffect({ reaction }) {
1912
+ if (!reaction)
1913
+ setActiveProjection({ source, key, target, depth, parent });
1914
+ const previous = debug.untracked(() => target.get(key));
1915
+ const accessBase = {
1916
+ key,
1917
+ source: source,
1918
+ get: () => source.get(key),
1919
+ set: (value) => {
1920
+ source.set(key, value);
1921
+ return true;
1922
+ },
1923
+ old: previous,
1924
+ };
1925
+ defineAccessValue(accessBase);
1926
+ const produced = apply(accessBase, target);
1927
+ target.set(key, produced);
1928
+ });
1929
+ debug.setEffectName(stop, `project[${depth}]:${String(key)}`);
1930
+ keyEffects.set(key, stop);
1931
+ });
1932
+ }
1933
+ for (const key of Array.from(keyEffects.keys()))
1934
+ if (!keys.has(key))
1935
+ disposeKey(key);
1936
+ });
1937
+ return makeCleanup(target, keyEffects, () => cleanupKeys(), {
1938
+ source: source,
1939
+ target,
1940
+ apply,
1941
+ depth,
1942
+ parent,
1943
+ });
1944
+ }
1945
+ function projectCore(source, apply) {
1946
+ if (Array.isArray(source))
1947
+ return projectArray(source, apply);
1948
+ if (source instanceof Map)
1949
+ return projectMap(source, apply);
1950
+ if (source instanceof Register)
1951
+ return projectRegister(source, apply);
1952
+ if (source && (source.constructor === Object || source.constructor === undefined))
1953
+ return projectRecord(source, apply);
1954
+ throw new Error('Unsupported source type');
1955
+ }
1956
+ const project = Object.assign(projectCore, {
1957
+ array: projectArray,
1958
+ register: projectRegister,
1959
+ record: projectRecord,
1960
+ map: projectMap,
1961
+ });
1962
+
1963
+ /**
1964
+ * Organizes a source object's properties into a target object using a callback function.
1965
+ * This creates a reactive mapping between source properties and a target object,
1966
+ * automatically handling property additions, updates, and removals.
1967
+ *
1968
+ * @template Source - The type of the source object
1969
+ * @template Target - The type of the target object (defaults to Record<PropertyKey, any>)
1970
+ *
1971
+ * @param {Source} source - The source object to organize
1972
+ * @param {OrganizedCallback<Source, Target>} apply - Callback function that defines how each source property is mapped to the target
1973
+ * @param {Target} [baseTarget={}] - Optional base target object to use (will be made reactive if not already)
1974
+ *
1975
+ * @returns {OrganizedResult<Target>} The target object with cleanup capability
1976
+ *
1977
+ * @example
1978
+ * // Organize user permissions into role-based access
1979
+ * const user = reactive({ isAdmin: true, canEdit: false });
1980
+ * const permissions = organized(
1981
+ * user,
1982
+ * (access, target) => {
1983
+ * if (access.key === 'isAdmin') {
1984
+ * target.hasFullAccess = access.value;
1985
+ * }
1986
+ * target[`can${access.key.charAt(0).toUpperCase() + access.key.slice(1)}`] = access.value;
1987
+ * }
1988
+ * );
1989
+ *
1990
+ * @example
1991
+ * // Transform object structure with cleanup
1992
+ * const source = reactive({ firstName: 'John', lastName: 'Doe' });
1993
+ * const formatted = organized(
1994
+ * source,
1995
+ * (access, target) => {
1996
+ * if (access.key === 'firstName' || access.key === 'lastName') {
1997
+ * target.fullName = `${source.firstName} ${source.lastName}`.trim();
1998
+ * }
1999
+ * }
2000
+ * );
2001
+ *
2002
+ * @example
2003
+ * // Using with cleanup in a component
2004
+ * effect(() => {
2005
+ * const data = fetchData();
2006
+ * const organizedData = organized(data, (access, target) => {
2007
+ * // Transform data
2008
+ * });
2009
+ *
2010
+ * // The cleanup will be called automatically when the effect is disposed
2011
+ * return () => organizedData[cleanup]();
2012
+ * });
2013
+ */
2014
+ function organized(source, apply, baseTarget = {}) {
2015
+ const observedSource = debug.reactive(source);
2016
+ const target = debug.reactive(baseTarget);
2017
+ const stop = attend(() => {
2018
+ const keys = [];
2019
+ for (const key in observedSource)
2020
+ keys.push(key);
2021
+ return keys;
2022
+ }, (key) => {
2023
+ const sourceKey = key;
2024
+ const accessBase = {
2025
+ key: sourceKey,
2026
+ get: () => debug.FoolProof.get(observedSource, sourceKey, observedSource),
2027
+ set: (value) => debug.FoolProof.set(observedSource, sourceKey, value, observedSource),
2028
+ };
2029
+ Object.defineProperty(accessBase, 'value', {
2030
+ get: accessBase.get,
2031
+ set: accessBase.set,
2032
+ configurable: true,
2033
+ enumerable: true,
2034
+ });
2035
+ return apply(accessBase, target);
2036
+ });
2037
+ return debug.cleanedBy(target, stop);
2038
+ }
2039
+ /**
2040
+ * Organizes a property on a target object
2041
+ * Shortcut for defineProperty/delete with touched signal
2042
+ * @param target - The target object
2043
+ * @param property - The property to organize
2044
+ * @param access - The access object
2045
+ * @returns The property descriptor
2046
+ */
2047
+ function organize(target, property, access) {
2048
+ Object.defineProperty(target, property, {
2049
+ get: access.get,
2050
+ set: access.set,
2051
+ configurable: true,
2052
+ enumerable: true,
2053
+ });
2054
+ debug.touched1(target, { type: 'set', prop: property }, property);
2055
+ return () => delete target[property];
2056
+ }
2057
+
2058
+ /**
2059
+ * Reactively defines properties on a target object based on a descriptors record.
2060
+ *
2061
+ * It tracks the keys of the descriptors record and defines/updates/removes
2062
+ * properties on the target object as they change.
2063
+ *
2064
+ * @param descriptors - A reactive record of property descriptors.
2065
+ * @param target - The object to define properties on (defaults to a new object).
2066
+ * @returns The target object with reactive property definitions.
2067
+ */
2068
+ function describe(descriptors, target = Object.create(null)) {
2069
+ descriptors = debug.reactive(descriptors);
2070
+ const stop = attend(() => Reflect.ownKeys(descriptors), (key) => {
2071
+ const desc = descriptors[key];
2072
+ if (desc) {
2073
+ Object.defineProperty(target, key, {
2074
+ enumerable: true,
2075
+ ...desc,
2076
+ configurable: true,
2077
+ });
2078
+ debug.touched1(target, { type: 'set', prop: key }, key);
2079
+ }
2080
+ return () => Reflect.deleteProperty(target, key);
2081
+ });
2082
+ return debug.cleanedBy(target, stop);
2083
+ }
2084
+
2085
+ function* index(i, { length = true } = {}) {
2086
+ if (length)
2087
+ yield 'length';
2088
+ yield i;
2089
+ }
2090
+ function* range(a, b, { length = false } = {}) {
2091
+ const start = Math.min(a, b);
2092
+ const end = Math.max(a, b);
2093
+ if (length)
2094
+ yield 'length';
2095
+ for (let i = start; i <= end; i++)
2096
+ yield i;
2097
+ }
2098
+ class Indexer extends Array {
2099
+ get(i) {
2100
+ debug.dependant(this, i);
2101
+ return debug.reactive(this[i]);
2102
+ }
2103
+ // Returns undefined intentionally: signals the proxy handler that notifications
2104
+ // were already dispatched via touched(), preventing double notification
2105
+ set(i, value) {
2106
+ const added = i >= this.length;
2107
+ this[i] = value;
2108
+ debug.touched(this, { type: 'set', prop: i }, index(i, { length: added }));
2109
+ }
2110
+ }
2111
+ const indexLess = { get: debug.FoolProof.get, set: debug.FoolProof.set };
2112
+ Object.assign(debug.FoolProof, {
2113
+ get(obj, prop, receiver) {
2114
+ if (obj instanceof Array && typeof prop === 'string') {
2115
+ const index = parseInt(prop);
2116
+ if (!Number.isNaN(index))
2117
+ return Indexer.prototype.get.call(obj, index);
2118
+ }
2119
+ return indexLess.get(obj, prop, receiver);
2120
+ },
2121
+ set(obj, prop, value, receiver) {
2122
+ if (obj instanceof Array && typeof prop === 'string') {
2123
+ const index = parseInt(prop);
2124
+ if (!Number.isNaN(index))
2125
+ return Indexer.prototype.set.call(obj, index, value);
2126
+ }
2127
+ return indexLess.set(obj, prop, value, receiver);
2128
+ },
2129
+ });
2130
+ class ReactiveArray extends Array {
2131
+ toJSON() {
2132
+ return this;
2133
+ }
2134
+ get length() {
2135
+ debug.dependant(this, 'length');
2136
+ return this.length;
2137
+ }
2138
+ set length(value) {
2139
+ const oldLength = this.length;
2140
+ if (oldLength === value)
2141
+ return;
2142
+ try {
2143
+ this.length = value;
2144
+ }
2145
+ finally {
2146
+ debug.touched(this, { type: 'set', prop: 'length' }, range(oldLength, value, { length: true }));
2147
+ }
2148
+ }
2149
+ // Safe array access with negative indices
2150
+ at(index) {
2151
+ const actualIndex = index < 0 ? this.length + index : index;
2152
+ debug.dependant(this, actualIndex);
2153
+ if (index < 0)
2154
+ debug.dependant(this, 'length');
2155
+ if (actualIndex < 0 || actualIndex >= this.length)
2156
+ return undefined;
2157
+ return debug.reactive(this[actualIndex]);
2158
+ }
2159
+ // Immutable versions of mutator methods
2160
+ toReversed() {
2161
+ debug.dependant(this);
2162
+ return debug.reactive(this.toReversed());
2163
+ }
2164
+ toSorted(compareFn) {
2165
+ debug.dependant(this);
2166
+ return debug.reactive(this.toSorted(compareFn));
2167
+ }
2168
+ toSpliced(start, deleteCount, ...items) {
2169
+ debug.dependant(this);
2170
+ return deleteCount === undefined
2171
+ ? this.toSpliced(start)
2172
+ : this.toSpliced(start, deleteCount, ...items);
2173
+ }
2174
+ with(index, value) {
2175
+ debug.dependant(this);
2176
+ return debug.reactive(this.with(index, value));
2177
+ }
2178
+ // Iterator methods with reactivity tracking
2179
+ entries() {
2180
+ debug.dependant(this);
2181
+ return makeReactiveEntriesIterator(this.entries());
2182
+ }
2183
+ keys() {
2184
+ debug.dependant(this, 'length');
2185
+ return this.keys();
2186
+ }
2187
+ values() {
2188
+ debug.dependant(this);
2189
+ return makeReactiveIterator(this.values());
2190
+ }
2191
+ [Symbol.iterator]() {
2192
+ debug.dependant(this);
2193
+ const nativeIterator = this[Symbol.iterator]();
2194
+ return {
2195
+ next() {
2196
+ const result = nativeIterator.next();
2197
+ if (result.done) {
2198
+ return result;
2199
+ }
2200
+ return { value: debug.reactive(result.value), done: false };
2201
+ },
2202
+ [Symbol.iterator]() {
2203
+ return this;
2204
+ },
2205
+ [Symbol.dispose]() { },
2206
+ };
2207
+ }
2208
+ indexOf(searchElement, fromIndex) {
2209
+ const length = this.length;
2210
+ let i = fromIndex === undefined ? 0 : fromIndex;
2211
+ if (i < 0)
2212
+ i = Math.max(length + i, 0);
2213
+ const unwrappedSearch = debug.unwrap(searchElement);
2214
+ for (; i < length; i++) {
2215
+ debug.dependant(this, i);
2216
+ const item = this[i];
2217
+ if (item === searchElement || item === unwrappedSearch || debug.unwrap(item) === unwrappedSearch) {
2218
+ return i;
2219
+ }
2220
+ }
2221
+ debug.dependant(this, 'length');
2222
+ return -1;
2223
+ }
2224
+ lastIndexOf(searchElement, fromIndex) {
2225
+ const length = this.length;
2226
+ let i = fromIndex === undefined ? length - 1 : fromIndex;
2227
+ if (i >= length)
2228
+ i = length - 1;
2229
+ if (i < 0)
2230
+ i = Math.max(length + i, -1); // -1 ensures loop condition i >= 0 works correctly
2231
+ const unwrappedSearch = debug.unwrap(searchElement);
2232
+ for (; i >= 0; i--) {
2233
+ debug.dependant(this, i);
2234
+ const item = this[i];
2235
+ if (item === searchElement || item === unwrappedSearch || debug.unwrap(item) === unwrappedSearch) {
2236
+ return i;
2237
+ }
2238
+ }
2239
+ // If we scanned the whole relevant part and didn't find it, we depend on length
2240
+ // (because adding elements might shift indices or add the element)
2241
+ // Actually for lastIndexOf, if we start from end, length dependency is implicit in the start index calculation?
2242
+ // But if we return -1, it means we didn't find it.
2243
+ // If we push an element, should lastIndexOf update?
2244
+ // Yes, if the new element is the one we are looking for.
2245
+ debug.dependant(this, 'length');
2246
+ return -1;
2247
+ }
2248
+ includes(searchElement, fromIndex) {
2249
+ return this.indexOf(searchElement, fromIndex) !== -1;
2250
+ }
2251
+ find(predicateOrElement, thisArg) {
2252
+ if (typeof predicateOrElement === 'function') {
2253
+ const predicate = predicateOrElement;
2254
+ const length = this.length;
2255
+ for (let i = 0; i < length; i++) {
2256
+ debug.dependant(this, i);
2257
+ const val = debug.reactive(this[i]);
2258
+ if (predicate.call(thisArg, val, i, this)) {
2259
+ return val;
2260
+ }
2261
+ }
2262
+ debug.dependant(this, 'length');
2263
+ return undefined;
2264
+ }
2265
+ const fromIndex = typeof thisArg === 'number' ? thisArg : undefined;
2266
+ const index = this.indexOf(predicateOrElement, fromIndex);
2267
+ if (index === -1)
2268
+ return undefined;
2269
+ return debug.reactive(this[index]);
2270
+ }
2271
+ findIndex(predicateOrElement, thisArg) {
2272
+ if (typeof predicateOrElement === 'function') {
2273
+ const predicate = predicateOrElement;
2274
+ const length = this.length;
2275
+ for (let i = 0; i < length; i++) {
2276
+ debug.dependant(this, i);
2277
+ const val = debug.reactive(this[i]);
2278
+ if (predicate.call(thisArg, val, i, this)) {
2279
+ return i;
2280
+ }
2281
+ }
2282
+ debug.dependant(this, 'length');
2283
+ return -1;
2284
+ }
2285
+ const fromIndex = typeof thisArg === 'number' ? thisArg : undefined;
2286
+ return this.indexOf(predicateOrElement, fromIndex);
2287
+ }
2288
+ flat(depth) {
2289
+ debug.dependant(this);
2290
+ return debug.reactive(depth === undefined ? this.flat() : this.flat(depth));
2291
+ }
2292
+ flatMap(callbackfn, thisArg) {
2293
+ debug.dependant(this);
2294
+ return debug.reactive(this.flatMap((item, index, array) => callbackfn.call(thisArg, debug.reactive(item), index, array), thisArg));
2295
+ }
2296
+ filter(callbackfn, thisArg) {
2297
+ debug.dependant(this);
2298
+ return debug.reactive(this.filter((item, index, array) => callbackfn(debug.reactive(item), index, array), thisArg));
2299
+ }
2300
+ map(callbackfn, thisArg) {
2301
+ debug.dependant(this);
2302
+ return debug.reactive(this.map((item, index, array) => callbackfn(debug.reactive(item), index, array), thisArg));
2303
+ }
2304
+ reduce(callbackfn, initialValue) {
2305
+ debug.dependant(this);
2306
+ const result = initialValue === undefined
2307
+ ? this.reduce(callbackfn)
2308
+ : this.reduce(callbackfn, initialValue);
2309
+ return debug.reactive(result);
2310
+ }
2311
+ reduceRight(callbackfn, initialValue) {
2312
+ debug.dependant(this);
2313
+ const result = initialValue !== undefined
2314
+ ? this.reduceRight(callbackfn, initialValue)
2315
+ : this.reduceRight(callbackfn);
2316
+ return debug.reactive(result);
2317
+ }
2318
+ slice(start, end) {
2319
+ for (const i of range(start || 0, end || this.length - 1))
2320
+ debug.dependant(this, i);
2321
+ return start === undefined
2322
+ ? this.slice()
2323
+ : end === undefined
2324
+ ? this.slice(start)
2325
+ : this.slice(start, end);
2326
+ }
2327
+ concat(...items) {
2328
+ debug.dependant(this);
2329
+ return debug.reactive(this.concat(...items));
2330
+ }
2331
+ join(separator) {
2332
+ debug.dependant(this);
2333
+ return this.join(separator);
2334
+ }
2335
+ forEach(callbackfn, thisArg) {
2336
+ debug.dependant(this);
2337
+ this.forEach((value, index, array) => {
2338
+ callbackfn.call(thisArg, debug.reactive(value), index, array);
2339
+ });
2340
+ }
2341
+ every(callbackfn, thisArg) {
2342
+ const length = this.length;
2343
+ for (let i = 0; i < length; i++) {
2344
+ debug.dependant(this, i);
2345
+ if (!callbackfn.call(thisArg, debug.reactive(this[i]), i, this)) {
2346
+ return false;
2347
+ }
2348
+ }
2349
+ debug.dependant(this, 'length');
2350
+ return true;
2351
+ }
2352
+ some(callbackfn, thisArg) {
2353
+ const length = this.length;
2354
+ for (let i = 0; i < length; i++) {
2355
+ debug.dependant(this, i);
2356
+ if (callbackfn.call(thisArg, debug.reactive(this[i]), i, this)) {
2357
+ return true;
2358
+ }
2359
+ }
2360
+ debug.dependant(this, 'length');
2361
+ return false;
2362
+ }
2363
+ // Side-effectful
2364
+ push(...items) {
2365
+ const oldLength = this.length;
2366
+ try {
2367
+ return this.push(...items);
2368
+ }
2369
+ finally {
2370
+ debug.touched(this, { type: 'bunch', method: 'push' }, range(oldLength, oldLength + items.length - 1, { length: true }));
2371
+ }
2372
+ }
2373
+ pop() {
2374
+ if (this.length === 0)
2375
+ return undefined;
2376
+ try {
2377
+ return debug.reactive(this.pop());
2378
+ }
2379
+ finally {
2380
+ debug.touched(this, { type: 'bunch', method: 'pop' }, index(this.length));
2381
+ }
2382
+ }
2383
+ shift() {
2384
+ if (this.length === 0)
2385
+ return undefined;
2386
+ try {
2387
+ return debug.reactive(this.shift());
2388
+ }
2389
+ finally {
2390
+ debug.touched(this, { type: 'bunch', method: 'shift' }, range(0, this.length + 1, { length: true }));
2391
+ }
2392
+ }
2393
+ unshift(...items) {
2394
+ try {
2395
+ return this.unshift(...items);
2396
+ }
2397
+ finally {
2398
+ debug.touched(this, { type: 'bunch', method: 'unshift' }, range(0, this.length - items.length, { length: true }));
2399
+ }
2400
+ }
2401
+ splice(start, deleteCount, ...items) {
2402
+ const oldLength = this.length;
2403
+ // Normalize start index
2404
+ let actualStart = start;
2405
+ if (actualStart < 0)
2406
+ actualStart = Math.max(oldLength + actualStart, 0);
2407
+ else
2408
+ actualStart = Math.min(actualStart, oldLength);
2409
+ // Normalize deleteCount
2410
+ let actualDeleteCount = deleteCount;
2411
+ if (actualDeleteCount === undefined) {
2412
+ actualDeleteCount = oldLength - actualStart;
2413
+ }
2414
+ else {
2415
+ actualDeleteCount = Math.max(0, Math.min(actualDeleteCount, oldLength - actualStart));
2416
+ }
2417
+ try {
2418
+ if (deleteCount === undefined)
2419
+ return debug.reactive(this.splice(start));
2420
+ return debug.reactive(this.splice(start, deleteCount, ...items));
2421
+ }
2422
+ finally {
2423
+ debug.touched(this, { type: 'bunch', method: 'splice' }, actualDeleteCount === items.length
2424
+ ? range(actualStart, actualStart + actualDeleteCount - 1)
2425
+ : range(actualStart, oldLength + Math.max(items.length - actualDeleteCount, 0), {
2426
+ length: true,
2427
+ }));
2428
+ }
2429
+ }
2430
+ reverse() {
2431
+ try {
2432
+ return this.reverse();
2433
+ }
2434
+ finally {
2435
+ debug.touched(this, { type: 'bunch', method: 'reverse' }, range(0, this.length - 1));
2436
+ }
2437
+ }
2438
+ sort(compareFn) {
2439
+ compareFn = compareFn || ((a, b) => a.toString().localeCompare(b.toString()));
2440
+ try {
2441
+ return this.sort((a, b) => compareFn(debug.reactive(a), debug.reactive(b)));
2442
+ }
2443
+ finally {
2444
+ debug.touched(this, { type: 'bunch', method: 'sort' }, range(0, this.length - 1));
2445
+ }
2446
+ }
2447
+ fill(value, start, end) {
2448
+ const len = this.length;
2449
+ let k = start === undefined ? 0 : start;
2450
+ if (k < 0)
2451
+ k = Math.max(len + k, 0);
2452
+ else
2453
+ k = Math.min(k, len);
2454
+ let final = end === undefined ? len : end;
2455
+ if (final < 0)
2456
+ final = Math.max(len + final, 0);
2457
+ else
2458
+ final = Math.min(final, len);
2459
+ try {
2460
+ if (start === undefined)
2461
+ return this.fill(value);
2462
+ if (end === undefined)
2463
+ return this.fill(value, start);
2464
+ return this.fill(value, start, end);
2465
+ }
2466
+ finally {
2467
+ if (final > k) {
2468
+ debug.touched(this, { type: 'bunch', method: 'fill' }, range(k, final - 1));
2469
+ }
2470
+ }
2471
+ }
2472
+ copyWithin(target, start, end) {
2473
+ try {
2474
+ if (end === undefined)
2475
+ return this.copyWithin(target, start);
2476
+ return this.copyWithin(target, start, end);
2477
+ }
2478
+ finally {
2479
+ const len = this.length;
2480
+ let to = target;
2481
+ if (to < 0)
2482
+ to = Math.max(len + to, 0);
2483
+ else if (to >= len)
2484
+ to = len;
2485
+ let from = start;
2486
+ if (from < 0)
2487
+ from = Math.max(len + from, 0);
2488
+ else if (from >= len)
2489
+ from = len;
2490
+ let final = end === undefined ? len : end;
2491
+ if (final < 0)
2492
+ final = Math.max(len + final, 0);
2493
+ else if (final >= len)
2494
+ final = len;
2495
+ const count = Math.min(final - from, len - to);
2496
+ if (count > 0) {
2497
+ debug.touched(this, { type: 'bunch', method: 'copyWithin' }, range(to, to + count - 1));
2498
+ }
2499
+ }
2500
+ }
2501
+ }
2502
+
2503
+ /**
2504
+ * Reactive wrapper around JavaScript's WeakMap class
2505
+ * Only tracks individual key operations, no size tracking (WeakMap limitation)
2506
+ */
2507
+ class ReactiveWeakMap extends WeakMap {
2508
+ // Implement WeakMap interface methods with reactivity
2509
+ delete(key) {
2510
+ const hadKey = this.has(key);
2511
+ const result = this.delete(key);
2512
+ if (hadKey)
2513
+ debug.touched1(debug.contentRef(this), { type: 'del', prop: key }, key);
2514
+ return result;
2515
+ }
2516
+ get(key) {
2517
+ debug.dependant(debug.contentRef(this), key);
2518
+ return debug.reactive(this.get(key));
2519
+ }
2520
+ has(key) {
2521
+ debug.dependant(debug.contentRef(this), key);
2522
+ return this.has(key);
2523
+ }
2524
+ set(key, value) {
2525
+ const hadKey = this.has(key);
2526
+ const oldValue = this.get(key);
2527
+ const reactiveValue = debug.reactive(value);
2528
+ this.set(key, reactiveValue);
2529
+ if (!hadKey || oldValue !== reactiveValue) {
2530
+ debug.notifyPropertyChange(debug.contentRef(this), key, oldValue, reactiveValue, hadKey);
2531
+ }
2532
+ return this;
2533
+ }
2534
+ }
2535
+ /**
2536
+ * Reactive wrapper around JavaScript's Map class
2537
+ * Tracks size changes, individual key operations, and collection-wide operations
2538
+ */
2539
+ class ReactiveMap extends Map {
2540
+ // Implement Map interface methods with reactivity
2541
+ get size() {
2542
+ debug.dependant(this, 'size'); // The ReactiveMap instance still goes through proxy
2543
+ return this.size;
2544
+ }
2545
+ clear() {
2546
+ const hadEntries = this.size > 0;
2547
+ this.clear();
2548
+ if (hadEntries) {
2549
+ const evolution = { type: 'bunch', method: 'clear' };
2550
+ // Clear triggers all effects since all keys are affected
2551
+ debug.touched1(this, evolution, 'size');
2552
+ debug.touched(debug.contentRef(this), evolution);
2553
+ }
2554
+ }
2555
+ entries() {
2556
+ debug.dependant(debug.contentRef(this));
2557
+ return makeReactiveEntriesIterator(this.entries());
2558
+ }
2559
+ forEach(callbackfn, thisArg) {
2560
+ debug.dependant(debug.contentRef(this));
2561
+ this.forEach(callbackfn, thisArg);
2562
+ }
2563
+ keys() {
2564
+ debug.dependant(debug.contentRef(this));
2565
+ return this.keys();
2566
+ }
2567
+ values() {
2568
+ debug.dependant(debug.contentRef(this));
2569
+ return makeReactiveIterator(this.values());
2570
+ }
2571
+ [Symbol.iterator]() {
2572
+ debug.dependant(debug.contentRef(this));
2573
+ const it = Map.prototype[Symbol.iterator].call(this);
2574
+ const nativeNext = it.next.bind(it);
2575
+ it.next = () => {
2576
+ const result = nativeNext();
2577
+ if (result.done)
2578
+ return result;
2579
+ const [key, value] = result.value;
2580
+ return { value: [debug.reactive(key), debug.reactive(value)], done: false };
2581
+ };
2582
+ return it;
2583
+ }
2584
+ // Implement Map methods with reactivity
2585
+ delete(key) {
2586
+ const hadKey = this.has(key);
2587
+ const result = this.delete(key);
2588
+ if (hadKey) {
2589
+ const evolution = { type: 'del', prop: key };
2590
+ debug.touched1(debug.contentRef(this), evolution, key);
2591
+ debug.touched1(this, evolution, 'size');
2592
+ }
2593
+ return result;
2594
+ }
2595
+ get(key) {
2596
+ debug.dependant(debug.contentRef(this), key);
2597
+ return debug.reactive(this.get(key));
2598
+ }
2599
+ has(key) {
2600
+ debug.dependant(debug.contentRef(this), key);
2601
+ return this.has(key);
2602
+ }
2603
+ set(key, value) {
2604
+ const hadKey = this.has(key);
2605
+ const oldValue = this.get(key);
2606
+ const reactiveValue = debug.reactive(value);
2607
+ this.set(key, reactiveValue);
2608
+ if (!hadKey || oldValue !== reactiveValue) {
2609
+ debug.notifyPropertyChange(debug.contentRef(this), key, oldValue, reactiveValue, hadKey);
2610
+ // Also notify size change for Map (WeakMap doesn't track size)
2611
+ const evolution = { type: hadKey ? 'set' : 'add', prop: key };
2612
+ debug.touched1(this, evolution, 'size');
2613
+ }
2614
+ return this;
2615
+ }
2616
+ }
2617
+
2618
+ /**
2619
+ * Reactive wrapper around JavaScript's WeakSet class
2620
+ * Only tracks individual value operations, no size tracking (WeakSet limitation)
2621
+ */
2622
+ class ReactiveWeakSet extends WeakSet {
2623
+ add(value) {
2624
+ const had = this.has(value);
2625
+ this.add(value);
2626
+ if (!had) {
2627
+ // touch the specific value and the collection view
2628
+ debug.touched1(debug.contentRef(this), { type: 'add', prop: value }, value);
2629
+ // no size/allProps for WeakSet
2630
+ }
2631
+ return this;
2632
+ }
2633
+ delete(value) {
2634
+ const had = this.has(value);
2635
+ const res = this.delete(value);
2636
+ if (had)
2637
+ debug.touched1(debug.contentRef(this), { type: 'del', prop: value }, value);
2638
+ return res;
2639
+ }
2640
+ has(value) {
2641
+ debug.dependant(debug.contentRef(this), value);
2642
+ return this.has(value);
2643
+ }
2644
+ }
2645
+ /**
2646
+ * Reactive wrapper around JavaScript's Set class
2647
+ * Tracks size changes, individual value operations, and collection-wide operations
2648
+ */
2649
+ class ReactiveSet extends Set {
2650
+ get size() {
2651
+ // size depends on the wrapper instance, like Map counterpart
2652
+ debug.dependant(this, 'size');
2653
+ return this.size;
2654
+ }
2655
+ add(value) {
2656
+ const had = this.has(value);
2657
+ const reactiveValue = debug.reactive(value);
2658
+ this.add(reactiveValue);
2659
+ if (!had) {
2660
+ const evolution = { type: 'add', prop: reactiveValue };
2661
+ // touch for value-specific and aggregate dependencies
2662
+ debug.touched1(debug.contentRef(this), evolution, reactiveValue);
2663
+ debug.touched1(this, evolution, 'size');
2664
+ }
2665
+ return this;
2666
+ }
2667
+ clear() {
2668
+ const hadEntries = this.size > 0;
2669
+ this.clear();
2670
+ if (hadEntries) {
2671
+ const evolution = { type: 'bunch', method: 'clear' };
2672
+ debug.touched1(this, evolution, 'size');
2673
+ debug.touched(debug.contentRef(this), evolution);
2674
+ }
2675
+ }
2676
+ delete(value) {
2677
+ const had = this.has(value);
2678
+ const res = this.delete(value);
2679
+ if (had) {
2680
+ const evolution = { type: 'del', prop: value };
2681
+ debug.touched1(debug.contentRef(this), evolution, value);
2682
+ debug.touched1(this, evolution, 'size');
2683
+ }
2684
+ return res;
2685
+ }
2686
+ has(value) {
2687
+ debug.dependant(debug.contentRef(this), value);
2688
+ return this.has(value);
2689
+ }
2690
+ entries() {
2691
+ debug.dependant(debug.contentRef(this));
2692
+ return makeReactiveEntriesIterator(this.entries());
2693
+ }
2694
+ forEach(callbackfn, thisArg) {
2695
+ debug.dependant(debug.contentRef(this));
2696
+ this.forEach(callbackfn, thisArg);
2697
+ }
2698
+ keys() {
2699
+ debug.dependant(debug.contentRef(this));
2700
+ return makeReactiveIterator(this.keys());
2701
+ }
2702
+ values() {
2703
+ debug.dependant(debug.contentRef(this));
2704
+ return makeReactiveIterator(this.values());
2705
+ }
2706
+ [Symbol.iterator]() {
2707
+ debug.dependant(debug.contentRef(this));
2708
+ const it = Set.prototype[Symbol.iterator].call(this);
2709
+ const nativeNext = it.next.bind(it);
2710
+ it.next = () => {
2711
+ const result = nativeNext();
2712
+ if (result.done)
2713
+ return result;
2714
+ return { value: debug.reactive(result.value), done: false };
2715
+ };
2716
+ return it;
2717
+ }
2718
+ }
2719
+
2720
+ // Register native collection types to use specialized reactive wrappers
2721
+ debug.metaProtos.set(Array, ReactiveArray.prototype);
2722
+ debug.metaProtos.set(Set, ReactiveSet.prototype);
2723
+ debug.metaProtos.set(WeakSet, ReactiveWeakSet.prototype);
2724
+ debug.metaProtos.set(Map, ReactiveMap.prototype);
2725
+ debug.metaProtos.set(WeakMap, ReactiveWeakMap.prototype);
2726
+ /**
2727
+ * Object containing internal reactive system state for debugging and profiling
2728
+ */
2729
+ const profileInfo = {
2730
+ objectToProxy: debug.objectToProxy,
2731
+ proxyToObject: debug.proxyToObject,
2732
+ effectToReactiveObjects: debug.effectToReactiveObjects,
2733
+ watchers: debug.watchers,
2734
+ objectParents: debug.objectParents,
2735
+ objectsWithDeepWatchers: debug.objectsWithDeepWatchers,
2736
+ deepWatchers: debug.deepWatchers,
2737
+ effectToDeepWatchedObjects: debug.effectToDeepWatchedObjects,
2738
+ nonReactiveObjects: debug.nonReactiveObjects,
2739
+ };
2740
+
2741
+ // In order to avoid async re-entrance, we could use zone.js or something like that.
2742
+ const syncCalculating = [];
2743
+ /**
2744
+ * Decorator that caches the result of a getter method and only recomputes when dependencies change
2745
+ * Prevents circular dependencies and provides automatic cache invalidation
2746
+ */
2747
+ const cached = debug.decorator({
2748
+ getter(original, _target, propertyKey) {
2749
+ return function () {
2750
+ const alreadyCalculating = syncCalculating.findIndex((c) => c.object === this && c.prop === propertyKey);
2751
+ if (alreadyCalculating > -1)
2752
+ throw new Error(`Circular dependency detected: ${syncCalculating
2753
+ .slice(alreadyCalculating)
2754
+ .map((c) => `${c.object.constructor.name}.${String(c.prop)}`)
2755
+ .join(' -> ')} -> again`);
2756
+ syncCalculating.push({ object: this, prop: propertyKey });
2757
+ try {
2758
+ const rv = original.call(this);
2759
+ cache(this, propertyKey, rv);
2760
+ return rv;
2761
+ }
2762
+ finally {
2763
+ syncCalculating.pop();
2764
+ }
2765
+ };
2766
+ },
2767
+ });
2768
+ /**
2769
+ * Checks if a property is cached (has a cached value)
2770
+ * @param object - The object to check
2771
+ * @param propertyKey - The property key to check
2772
+ * @returns True if the property has a cached value
2773
+ */
2774
+ function isCached(object, propertyKey) {
2775
+ return !!Object.getOwnPropertyDescriptor(object, propertyKey);
2776
+ }
2777
+ /**
2778
+ * Caches a value for a property on an object
2779
+ * @param object - The object to cache the value on
2780
+ * @param propertyKey - The property key to cache
2781
+ * @param value - The value to cache
2782
+ */
2783
+ function cache(object, propertyKey, value) {
2784
+ Object.defineProperty(object, propertyKey, { value });
2785
+ }
2786
+ /**
2787
+ * Creates a decorator that modifies property descriptors for specified properties
2788
+ * @param descriptor - The descriptor properties to apply
2789
+ * @returns A class decorator that applies the descriptor to specified properties
2790
+ */
2791
+ const descriptor = debug.flavored(function descriptor(descriptor) {
2792
+ return (...properties) => (Base) => {
2793
+ return class extends Base {
2794
+ constructor(...args) {
2795
+ super(...args);
2796
+ for (const key of properties) {
2797
+ const existing = Object.getOwnPropertyDescriptor(this, key);
2798
+ Object.defineProperty(this, key, Object.assign(existing || {}, descriptor));
2799
+ }
2800
+ }
2801
+ };
2802
+ };
2803
+ }, {
2804
+ /**
2805
+ * enumerable: true
2806
+ */
2807
+ get enumerable() {
2808
+ return descriptor({ enumerable: true });
2809
+ },
2810
+ /**
2811
+ * enumerable: false
2812
+ */
2813
+ get hidden() {
2814
+ return descriptor({ enumerable: false });
2815
+ },
2816
+ /**
2817
+ * configurable: true
2818
+ */
2819
+ get configurable() {
2820
+ return descriptor({ configurable: true });
2821
+ },
2822
+ /**
2823
+ * configurable: false
2824
+ */
2825
+ get frozen() {
2826
+ return descriptor({ configurable: false });
2827
+ },
2828
+ /**
2829
+ * writable: true
2830
+ */
2831
+ get writable() {
2832
+ return descriptor({ writable: true });
2833
+ },
2834
+ /**
2835
+ * writable: false
2836
+ */
2837
+ get readonly() {
2838
+ return descriptor({ writable: false });
2839
+ },
2840
+ });
2841
+ /**
2842
+ * Decorator that marks methods, properties, or classes as deprecated
2843
+ * Provides warning messages when deprecated items are used
2844
+ */
2845
+ const deprecated = Object.assign(debug.decorator({
2846
+ method(original, _target, propertyKey) {
2847
+ return function (...args) {
2848
+ deprecated.warn(this, propertyKey);
2849
+ return original.apply(this, args);
2850
+ };
2851
+ },
2852
+ getter(original, _target, propertyKey) {
2853
+ return function () {
2854
+ deprecated.warn(this, propertyKey);
2855
+ return original.call(this);
2856
+ };
2857
+ },
2858
+ setter(original, _target, propertyKey) {
2859
+ return function (value) {
2860
+ deprecated.warn(this, propertyKey);
2861
+ return original.call(this, value);
2862
+ };
2863
+ },
2864
+ class(original) {
2865
+ return class extends original {
2866
+ constructor(...args) {
2867
+ super(...args);
2868
+ deprecated.warn(this, 'constructor');
2869
+ }
2870
+ };
2871
+ },
2872
+ default(message) {
2873
+ return debug.decorator({
2874
+ method(original, _target, propertyKey) {
2875
+ return function (...args) {
2876
+ deprecated.warn(this, propertyKey, message);
2877
+ return original.apply(this, args);
2878
+ };
2879
+ },
2880
+ getter(original, _target, propertyKey) {
2881
+ return function () {
2882
+ deprecated.warn(this, propertyKey, message);
2883
+ return original.call(this);
2884
+ };
2885
+ },
2886
+ setter(original, _target, propertyKey) {
2887
+ return function (value) {
2888
+ deprecated.warn(this, propertyKey, message);
2889
+ return original.call(this, value);
2890
+ };
2891
+ },
2892
+ class(original) {
2893
+ return class extends original {
2894
+ constructor(...args) {
2895
+ super(...args);
2896
+ deprecated.warn(this, 'constructor', message);
2897
+ }
2898
+ };
2899
+ },
2900
+ });
2901
+ },
2902
+ }), {
2903
+ warn: (target, propertyKey, message) => {
2904
+ // biome-ignore lint/suspicious/noConsole: To be overridden
2905
+ console.warn(`${target.constructor.name}.${String(propertyKey)} is deprecated${message ? `: ${message}` : ''}`);
2906
+ },
2907
+ });
2908
+ /**
2909
+ * Creates a debounced method decorator that delays execution until after the delay period has passed
2910
+ * @param delay - The delay in milliseconds
2911
+ * @returns A method decorator that debounces method calls
2912
+ */
2913
+ function debounce(delay) {
2914
+ return debug.decorator({
2915
+ method(original, _target, _propertyKey) {
2916
+ let timeoutId = null;
2917
+ return function (...args) {
2918
+ // Clear existing timeout
2919
+ if (timeoutId) {
2920
+ clearTimeout(timeoutId);
2921
+ }
2922
+ // Set new timeout
2923
+ timeoutId = setTimeout(() => {
2924
+ original.apply(this, args);
2925
+ timeoutId = null;
2926
+ }, delay);
2927
+ };
2928
+ },
2929
+ });
2930
+ }
2931
+ /**
2932
+ * Creates a throttled method decorator that limits execution to once per delay period
2933
+ * @param delay - The delay in milliseconds
2934
+ * @returns A method decorator that throttles method calls
2935
+ */
2936
+ function throttle(delay) {
2937
+ return debug.decorator({
2938
+ method(original, _target, _propertyKey) {
2939
+ let lastCallTime = 0;
2940
+ let timeoutId = null;
2941
+ return function (...args) {
2942
+ const now = Date.now();
2943
+ // If enough time has passed since last call, execute immediately
2944
+ if (now - lastCallTime >= delay) {
2945
+ // Clear any pending timeout since we're executing now
2946
+ if (timeoutId) {
2947
+ clearTimeout(timeoutId);
2948
+ timeoutId = null;
2949
+ }
2950
+ lastCallTime = now;
2951
+ return original.apply(this, args);
2952
+ }
2953
+ // Otherwise, schedule execution for when the delay period ends
2954
+ if (!timeoutId) {
2955
+ const remainingTime = delay - (now - lastCallTime);
2956
+ const scheduledArgs = [...args]; // Capture args at scheduling time
2957
+ timeoutId = setTimeout(() => {
2958
+ lastCallTime = Date.now();
2959
+ original.apply(this, scheduledArgs);
2960
+ timeoutId = null;
2961
+ }, remainingTime);
2962
+ }
2963
+ };
2964
+ },
2965
+ });
2966
+ }
2967
+
2968
+ var version$1 = "1.0.9";
2969
+ var pkg = {
2970
+ version: version$1};
2971
+
2972
+ const { version } = pkg;
2973
+ // Singleton verification
2974
+ const GLOBAL_MUTTS_KEY = '__MUTTS_INSTANCE__';
2975
+ const globalScope = (typeof globalThis !== 'undefined'
2976
+ ? globalThis
2977
+ : typeof window !== 'undefined'
2978
+ ? window
2979
+ : typeof global !== 'undefined'
2980
+ ? global
2981
+ : false);
2982
+ if (globalScope) {
2983
+ // Detect the source of this instance safely across different environments
2984
+ let source = 'mutts/index';
2985
+ const viteEval = eval;
2986
+ try {
2987
+ if (typeof __filename !== 'undefined')
2988
+ source = __filename;
2989
+ else {
2990
+ // Using eval to avoid SyntaxError in CJS environments where import.meta is not allowed
2991
+ const meta = viteEval('import.meta');
2992
+ if (meta && meta.url)
2993
+ source = meta.url;
2994
+ }
2995
+ }
2996
+ catch (e) {
2997
+ // Fallback for environments where neither is available or accessible
2998
+ }
2999
+ const currentSourceInfo = {
3000
+ version,
3001
+ source,
3002
+ timestamp: Date.now(),
3003
+ };
3004
+ if (globalScope[GLOBAL_MUTTS_KEY]) {
3005
+ const existing = globalScope[GLOBAL_MUTTS_KEY];
3006
+ throw new Error(`[Mutts] Multiple instances detected!\n` +
3007
+ `Existing instance: ${JSON.stringify(existing, null, 2)}\n` +
3008
+ `New instance: ${JSON.stringify(currentSourceInfo, null, 2)}\n` +
3009
+ `This usually happens when 'mutts' is both installed as a dependency and bundled, ` +
3010
+ `or when different versions are loaded. ` +
3011
+ `Please check your build configuration (aliases, externals) to ensure a single source of truth.`);
3012
+ }
3013
+ globalScope[GLOBAL_MUTTS_KEY] = currentSourceInfo;
3014
+ }
3015
+
3016
+ exports.AZone = debug.AZone;
3017
+ exports.DecoratorError = debug.DecoratorError;
3018
+ exports.FoolProof = debug.FoolProof;
3019
+ exports.IterableWeakMap = debug.IterableWeakMap;
3020
+ exports.IterableWeakSet = debug.IterableWeakSet;
3021
+ exports.ReactiveBase = debug.ReactiveBase;
3022
+ exports.ReactiveError = debug.ReactiveError;
3023
+ Object.defineProperty(exports, "ReactiveErrorCode", {
3024
+ enumerable: true,
3025
+ get: function () { return debug.ReactiveErrorCode; }
3026
+ });
3027
+ exports.Zone = debug.Zone;
3028
+ exports.ZoneAggregator = debug.ZoneAggregator;
3029
+ exports.ZoneHistory = debug.ZoneHistory;
3030
+ exports.addBatchCleanup = debug.addBatchCleanup;
3031
+ exports.arrayEquals = debug.arrayEquals;
3032
+ exports.asyncZone = debug.asyncZone;
3033
+ exports.atomic = debug.atomic;
3034
+ exports.biDi = debug.biDi;
3035
+ exports.cleanedBy = debug.cleanedBy;
3036
+ exports.cleanup = debug.cleanup;
3037
+ exports.contentRef = debug.contentRef;
3038
+ exports.createFlavor = debug.createFlavor;
3039
+ exports.decorator = debug.decorator;
3040
+ exports.deepCompare = debug.deepCompare;
3041
+ exports.defer = debug.defer;
3042
+ exports.derived = debug.derived;
3043
+ exports.effect = debug.effect;
3044
+ exports.effectAggregator = debug.effectAggregator;
3045
+ exports.flavorOptions = debug.flavorOptions;
3046
+ exports.flavored = debug.flavored;
3047
+ exports.getActivationLog = debug.getActivationLog;
3048
+ exports.getActiveEffect = debug.getActiveEffect;
3049
+ exports.getState = debug.getState;
3050
+ exports.immutables = debug.immutables;
3051
+ exports.isConstructor = debug.isConstructor;
3052
+ exports.isNonReactive = debug.isNonReactive;
3053
+ exports.isOwnAccessor = debug.isOwnAccessor;
3054
+ exports.isReactive = debug.isReactive;
3055
+ exports.legacyDecorator = debug.legacyDecorator;
3056
+ exports.mixin = debug.mixin;
3057
+ exports.modernDecorator = debug.modernDecorator;
3058
+ exports.named = debug.named;
3059
+ exports.onEffectThrow = debug.onEffectThrow;
3060
+ exports.onEffectTrigger = debug.onEffectTrigger;
3061
+ exports.reactive = debug.reactive;
3062
+ exports.reactiveOptions = debug.options;
3063
+ exports.registerNativeReactivity = debug.registerNativeReactivity;
3064
+ exports.renamed = debug.renamed;
3065
+ exports.reset = debug.reset;
3066
+ exports.root = debug.root;
3067
+ exports.tag = debug.tag;
3068
+ exports.touched = debug.touched;
3069
+ exports.touched1 = debug.touched1;
3070
+ exports.untracked = debug.untracked;
3071
+ exports.unwrap = debug.unwrap;
3072
+ exports.zip = debug.zip;
3073
+ exports.asyncHook = asyncCore.asyncHook;
3074
+ exports.asyncHooks = asyncCore.asyncHooks;
3075
+ exports.hooks = asyncCore.hooks;
3076
+ exports.ArrayReadForward = ArrayReadForward;
3077
+ exports.Destroyable = Destroyable;
3078
+ exports.DestructionError = DestructionError;
3079
+ exports.Eventful = Eventful;
3080
+ exports.Indexable = Indexable;
3081
+ exports.Register = Register;
3082
+ exports.allocated = allocated;
3083
+ exports.allocatedValues = allocatedValues;
3084
+ exports.attend = attend;
3085
+ exports.cache = cache;
3086
+ exports.cached = cached;
3087
+ exports.callOnGC = callOnGC;
3088
+ exports.chainPromise = chainPromise;
3089
+ exports.debounce = debounce;
3090
+ exports.deepWatch = deepWatch;
3091
+ exports.deprecated = deprecated;
3092
+ exports.describe = describe;
3093
+ exports.descriptor = descriptor;
3094
+ exports.destructor = destructor;
3095
+ exports.forwardArray = forwardArray;
3096
+ exports.getActiveProjection = getActiveProjection;
3097
+ exports.getAt = getAt;
3098
+ exports.isCached = isCached;
3099
+ exports.lift = lift;
3100
+ exports.memoize = memoize;
3101
+ exports.organize = organize;
3102
+ exports.organized = organized;
3103
+ exports.profileInfo = profileInfo;
3104
+ exports.project = project;
3105
+ exports.register = register;
3106
+ exports.scan = scan;
3107
+ exports.setAt = setAt;
3108
+ exports.throttle = throttle;
3109
+ exports.unreactive = unreactive;
3110
+ exports.watch = watch;
3111
+ //# sourceMappingURL=browser.cjs.map