mutts 1.0.9 → 1.0.11

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 (206) hide show
  1. package/README.md +60 -35
  2. package/dist/browser.cjs +1333 -1760
  3. package/dist/browser.cjs.map +1 -1
  4. package/dist/browser.d.ts +2 -1392
  5. package/dist/browser.dev.cjs +114 -0
  6. package/dist/browser.dev.cjs.map +1 -0
  7. package/dist/browser.dev.d.ts +2 -0
  8. package/dist/browser.dev.esm.js +5 -0
  9. package/dist/browser.dev.esm.js.map +1 -0
  10. package/dist/browser.esm.js +18 -97
  11. package/dist/browser.esm.js.map +1 -1
  12. package/dist/chunks/{async-browser-lvzLOCgk.cjs → async-browser-Dgr5CreQ.cjs} +16 -95
  13. package/dist/chunks/async-browser-Dgr5CreQ.cjs.map +1 -0
  14. package/dist/chunks/{async-node-C3DeIb0y.cjs → async-node-3PrbVAbB.cjs} +3 -1
  15. package/dist/chunks/async-node-3PrbVAbB.cjs.map +1 -0
  16. package/dist/chunks/index-Sf74wXTV.esm.js +2577 -0
  17. package/dist/chunks/index-Sf74wXTV.esm.js.map +1 -0
  18. package/dist/chunks/node-Bo7WU5S2.esm.js +96 -0
  19. package/dist/chunks/node-Bo7WU5S2.esm.js.map +1 -0
  20. package/dist/chunks/{index-VTO-b2vR.cjs → proxy-Cc79Lrzj.cjs} +2593 -3216
  21. package/dist/chunks/proxy-Cc79Lrzj.cjs.map +1 -0
  22. package/dist/chunks/{index-CtA2AWl3.esm.js → proxy-D2C49sXH.esm.js} +2570 -3174
  23. package/dist/chunks/proxy-D2C49sXH.esm.js.map +1 -0
  24. package/dist/debug.cjs +987 -28
  25. package/dist/debug.cjs.map +1 -1
  26. package/dist/debug.d.ts +37 -38
  27. package/dist/debug.esm.js +963 -1
  28. package/dist/debug.esm.js.map +1 -1
  29. package/dist/devtools/manifest.json +1 -1
  30. package/dist/devtools/panel.html +1 -1
  31. package/dist/devtools/panel.js +107 -94
  32. package/dist/devtools/panel.js.map +1 -1
  33. package/dist/index.d.ts +1322 -1
  34. package/dist/mutts.umd.js +6647 -1
  35. package/dist/mutts.umd.js.map +1 -1
  36. package/dist/mutts.umd.min.js +1 -1
  37. package/dist/mutts.umd.min.js.map +1 -1
  38. package/dist/node.cjs +69 -63
  39. package/dist/node.cjs.map +1 -1
  40. package/dist/node.d.ts +2 -2
  41. package/dist/node.dev.cjs +114 -0
  42. package/dist/node.dev.cjs.map +1 -0
  43. package/dist/node.dev.d.ts +2 -0
  44. package/dist/node.dev.esm.js +6 -0
  45. package/dist/node.dev.esm.js.map +1 -0
  46. package/dist/node.esm.js +4 -97
  47. package/dist/node.esm.js.map +1 -1
  48. package/dist/{types-DaHFfhlN.d.ts → types-Bx2PhORg.d.ts} +134 -88
  49. package/docs/ai/api-reference.md +11 -32
  50. package/docs/ai/manual.md +297 -239
  51. package/docs/reactive/advanced.md +318 -9
  52. package/docs/reactive/attend.md +2 -4
  53. package/docs/reactive/collections.md +22 -187
  54. package/docs/reactive/core.md +223 -131
  55. package/docs/reactive/debugging.md +119 -12
  56. package/docs/reactive/error-handling.md +10 -10
  57. package/docs/reactive/resource.md +125 -0
  58. package/docs/reactive.md +3 -4
  59. package/docs/utils.md +70 -0
  60. package/docs/zone.md +1 -1
  61. package/package.json +76 -38
  62. package/dist/chunks/async-browser-lvzLOCgk.cjs.map +0 -1
  63. package/dist/chunks/async-node-C3DeIb0y.cjs.map +0 -1
  64. package/dist/chunks/index-2vea86wD.esm.js +0 -3011
  65. package/dist/chunks/index-2vea86wD.esm.js.map +0 -1
  66. package/dist/chunks/index-CtA2AWl3.esm.js.map +0 -1
  67. package/dist/chunks/index-VTO-b2vR.cjs.map +0 -1
  68. package/dist/debug/debug.d.ts +0 -122
  69. package/dist/debug/debug.d.ts.map +0 -1
  70. package/dist/debug/index.d.ts +0 -4
  71. package/dist/debug/index.d.ts.map +0 -1
  72. package/dist/debug/lineage-panel.d.ts +0 -5
  73. package/dist/debug/lineage-panel.d.ts.map +0 -1
  74. package/dist/debug/lineage.d.ts +0 -79
  75. package/dist/debug/lineage.d.ts.map +0 -1
  76. package/dist/src/async/browser.d.ts +0 -2
  77. package/dist/src/async/browser.d.ts.map +0 -1
  78. package/dist/src/async/index.d.ts +0 -19
  79. package/dist/src/async/index.d.ts.map +0 -1
  80. package/dist/src/async/node.d.ts +0 -2
  81. package/dist/src/async/node.d.ts.map +0 -1
  82. package/dist/src/decorator.d.ts +0 -106
  83. package/dist/src/decorator.d.ts.map +0 -1
  84. package/dist/src/destroyable.d.ts +0 -87
  85. package/dist/src/destroyable.d.ts.map +0 -1
  86. package/dist/src/entry-browser.d.ts +0 -3
  87. package/dist/src/entry-browser.d.ts.map +0 -1
  88. package/dist/src/entry-node.d.ts +0 -3
  89. package/dist/src/entry-node.d.ts.map +0 -1
  90. package/dist/src/eventful.d.ts +0 -20
  91. package/dist/src/eventful.d.ts.map +0 -1
  92. package/dist/src/flavored.d.ts +0 -33
  93. package/dist/src/flavored.d.ts.map +0 -1
  94. package/dist/src/index.d.ts +0 -14
  95. package/dist/src/index.d.ts.map +0 -1
  96. package/dist/src/indexable.d.ts +0 -243
  97. package/dist/src/indexable.d.ts.map +0 -1
  98. package/dist/src/introspection.d.ts +0 -27
  99. package/dist/src/introspection.d.ts.map +0 -1
  100. package/dist/src/iterableWeak.d.ts +0 -53
  101. package/dist/src/iterableWeak.d.ts.map +0 -1
  102. package/dist/src/mixins.d.ts +0 -25
  103. package/dist/src/mixins.d.ts.map +0 -1
  104. package/dist/src/promiseChain.d.ts +0 -20
  105. package/dist/src/promiseChain.d.ts.map +0 -1
  106. package/dist/src/reactive/array.d.ts +0 -48
  107. package/dist/src/reactive/array.d.ts.map +0 -1
  108. package/dist/src/reactive/buffer.d.ts +0 -120
  109. package/dist/src/reactive/buffer.d.ts.map +0 -1
  110. package/dist/src/reactive/change.d.ts +0 -29
  111. package/dist/src/reactive/change.d.ts.map +0 -1
  112. package/dist/src/reactive/deep-touch.d.ts +0 -28
  113. package/dist/src/reactive/deep-touch.d.ts.map +0 -1
  114. package/dist/src/reactive/deep-watch-state.d.ts +0 -25
  115. package/dist/src/reactive/deep-watch-state.d.ts.map +0 -1
  116. package/dist/src/reactive/deep-watch.d.ts +0 -20
  117. package/dist/src/reactive/deep-watch.d.ts.map +0 -1
  118. package/dist/src/reactive/describe.d.ts +0 -12
  119. package/dist/src/reactive/describe.d.ts.map +0 -1
  120. package/dist/src/reactive/effect-context.d.ts +0 -34
  121. package/dist/src/reactive/effect-context.d.ts.map +0 -1
  122. package/dist/src/reactive/effects.d.ts +0 -164
  123. package/dist/src/reactive/effects.d.ts.map +0 -1
  124. package/dist/src/reactive/index.d.ts +0 -19
  125. package/dist/src/reactive/index.d.ts.map +0 -1
  126. package/dist/src/reactive/map.d.ts +0 -28
  127. package/dist/src/reactive/map.d.ts.map +0 -1
  128. package/dist/src/reactive/memoize.d.ts +0 -28
  129. package/dist/src/reactive/memoize.d.ts.map +0 -1
  130. package/dist/src/reactive/non-reactive-state.d.ts +0 -9
  131. package/dist/src/reactive/non-reactive-state.d.ts.map +0 -1
  132. package/dist/src/reactive/non-reactive.d.ts +0 -11
  133. package/dist/src/reactive/non-reactive.d.ts.map +0 -1
  134. package/dist/src/reactive/project.d.ts +0 -40
  135. package/dist/src/reactive/project.d.ts.map +0 -1
  136. package/dist/src/reactive/proxy-state.d.ts +0 -8
  137. package/dist/src/reactive/proxy-state.d.ts.map +0 -1
  138. package/dist/src/reactive/proxy.d.ts +0 -23
  139. package/dist/src/reactive/proxy.d.ts.map +0 -1
  140. package/dist/src/reactive/record.d.ts +0 -115
  141. package/dist/src/reactive/record.d.ts.map +0 -1
  142. package/dist/src/reactive/register.d.ts +0 -125
  143. package/dist/src/reactive/register.d.ts.map +0 -1
  144. package/dist/src/reactive/registry.d.ts +0 -21
  145. package/dist/src/reactive/registry.d.ts.map +0 -1
  146. package/dist/src/reactive/set.d.ts +0 -26
  147. package/dist/src/reactive/set.d.ts.map +0 -1
  148. package/dist/src/reactive/tracking.d.ts +0 -7
  149. package/dist/src/reactive/tracking.d.ts.map +0 -1
  150. package/dist/src/reactive/types.d.ts +0 -424
  151. package/dist/src/reactive/types.d.ts.map +0 -1
  152. package/dist/src/reactive/watch.d.ts +0 -48
  153. package/dist/src/reactive/watch.d.ts.map +0 -1
  154. package/dist/src/std-decorators.d.ts +0 -45
  155. package/dist/src/std-decorators.d.ts.map +0 -1
  156. package/dist/src/utils.d.ts +0 -49
  157. package/dist/src/utils.d.ts.map +0 -1
  158. package/dist/src/zone.d.ts +0 -40
  159. package/dist/src/zone.d.ts.map +0 -1
  160. package/docs/reactive/describe.md +0 -85
  161. package/docs/reactive/project.md +0 -93
  162. package/docs/reactive/scan.md +0 -293
  163. package/src/async/browser.ts +0 -323
  164. package/src/async/index.ts +0 -27
  165. package/src/async/node.ts +0 -92
  166. package/src/decorator.ts +0 -272
  167. package/src/destroyable.ts +0 -199
  168. package/src/entry-browser.ts +0 -5
  169. package/src/entry-node.ts +0 -5
  170. package/src/eventful.ts +0 -110
  171. package/src/flavored.ts +0 -106
  172. package/src/index.d.ts +0 -12
  173. package/src/index.ts +0 -64
  174. package/src/indexable.ts +0 -526
  175. package/src/introspection.ts +0 -59
  176. package/src/iterableWeak.ts +0 -233
  177. package/src/mixins.ts +0 -123
  178. package/src/promiseChain.ts +0 -110
  179. package/src/reactive/array.ts +0 -500
  180. package/src/reactive/buffer.ts +0 -328
  181. package/src/reactive/change.ts +0 -131
  182. package/src/reactive/deep-touch.ts +0 -273
  183. package/src/reactive/deep-watch-state.ts +0 -82
  184. package/src/reactive/deep-watch.ts +0 -171
  185. package/src/reactive/describe.ts +0 -39
  186. package/src/reactive/effect-context.ts +0 -83
  187. package/src/reactive/effects.ts +0 -1434
  188. package/src/reactive/index.ts +0 -72
  189. package/src/reactive/map.ts +0 -142
  190. package/src/reactive/memoize.ts +0 -186
  191. package/src/reactive/non-reactive-state.ts +0 -49
  192. package/src/reactive/non-reactive.ts +0 -43
  193. package/src/reactive/project.md +0 -107
  194. package/src/reactive/project.ts +0 -430
  195. package/src/reactive/proxy-state.ts +0 -27
  196. package/src/reactive/proxy.ts +0 -282
  197. package/src/reactive/record.ts +0 -181
  198. package/src/reactive/register.ts +0 -538
  199. package/src/reactive/registry.ts +0 -72
  200. package/src/reactive/set.ts +0 -117
  201. package/src/reactive/tracking.ts +0 -41
  202. package/src/reactive/types.ts +0 -520
  203. package/src/reactive/watch.ts +0 -180
  204. package/src/std-decorators.ts +0 -256
  205. package/src/utils.ts +0 -300
  206. package/src/zone.ts +0 -142
package/dist/browser.cjs CHANGED
@@ -1,11 +1,12 @@
1
1
  'use strict';
2
2
 
3
- require('./chunks/async-browser-lvzLOCgk.cjs');
4
- var debug = require('./chunks/index-VTO-b2vR.cjs');
3
+ require('./chunks/async-browser-Dgr5CreQ.cjs');
4
+ var proxy = require('./chunks/proxy-Cc79Lrzj.cjs');
5
5
  var asyncCore = require('./chunks/async-core-CRLKP3l-.cjs');
6
- require('./chunks/async-node-C3DeIb0y.cjs');
6
+ require('./chunks/async-node-3PrbVAbB.cjs');
7
7
  require('node:async_hooks');
8
8
 
9
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
10
  // Integrated with `using` statement via Symbol.dispose
10
11
  const fr = new FinalizationRegistry((f) => f());
11
12
  /**
@@ -86,7 +87,7 @@ function Destroyable(base, destructorObj) {
86
87
  * Decorator that marks properties to be stored in the allocated object and passed to the destructor
87
88
  * Use with accessor properties or explicit get/set pairs
88
89
  */
89
- const allocated = debug.decorator({
90
+ const allocated = proxy.decorator({
90
91
  setter(original, _target, propertyKey) {
91
92
  return function (value) {
92
93
  this[allocatedValues][propertyKey] = value;
@@ -111,6 +112,154 @@ function callOnGC(cb) {
111
112
  return forward;
112
113
  }
113
114
 
115
+ /** Max edit distance before bailing out to a single "replace all" patch */
116
+ const BAILOUT_D = 256;
117
+ /**
118
+ * Myers' diff producing grouped patches: `{indexA, indexB, sliceA, sliceB}[]`.
119
+ * - O(N) for identical or prefix/suffix-only differences
120
+ * - O(ND) for small D, with a hard bailout at D=BAILOUT_D → single replacement patch
121
+ */
122
+ function arrayDiff(A, B) {
123
+ let start = 0;
124
+ let endA = A.length;
125
+ let endB = B.length;
126
+ // Trim common prefix
127
+ while (start < endA && start < endB && A[start] === B[start])
128
+ start++;
129
+ // Trim common suffix
130
+ while (endA > start && endB > start && A[endA - 1] === B[endB - 1]) {
131
+ endA--;
132
+ endB--;
133
+ }
134
+ const lenA = endA - start;
135
+ const lenB = endB - start;
136
+ if (lenA === 0 && lenB === 0)
137
+ return [];
138
+ if (lenA === 0)
139
+ return [{ indexA: start, indexB: start, sliceA: [], sliceB: B.slice(start, endB) }];
140
+ if (lenB === 0)
141
+ return [{ indexA: start, indexB: start, sliceA: A.slice(start, endA), sliceB: [] }];
142
+ // Myers with bailout
143
+ const maxD = Math.min(lenA + lenB, BAILOUT_D);
144
+ const vSize = 2 * maxD + 1;
145
+ const vOffset = maxD;
146
+ const V = new Int32Array(vSize);
147
+ V[vOffset + 1] = 0;
148
+ const history = [];
149
+ for (let d = 0; d <= maxD; d++) {
150
+ for (let k = -d; k <= d; k += 2) {
151
+ let x;
152
+ if (k === -d || (k !== d && V[vOffset + k - 1] < V[vOffset + k + 1])) {
153
+ x = V[vOffset + k + 1];
154
+ }
155
+ else {
156
+ x = V[vOffset + k - 1] + 1;
157
+ }
158
+ let y = x - k;
159
+ while (x < lenA && y < lenB && A[start + x] === B[start + y]) {
160
+ x++;
161
+ y++;
162
+ }
163
+ V[vOffset + k] = x;
164
+ if (x >= lenA && y >= lenB)
165
+ return buildPatches(history, A, B, start, x, y, d, k, vOffset);
166
+ }
167
+ history.push(new Int32Array(V));
168
+ }
169
+ // Bailout: too many differences
170
+ return [
171
+ { indexA: start, indexB: start, sliceA: A.slice(start, endA), sliceB: B.slice(start, endB) },
172
+ ];
173
+ }
174
+ function buildPatches(history, A, B, offset, finalX, finalY, finalD, finalK, vOffset) {
175
+ // Backtrack from (finalX, finalY) at step finalD to step 0, collecting ops in reverse
176
+ const ops = []; // 0=eq, 1=ins, 2=del
177
+ let x = finalX;
178
+ let y = finalY;
179
+ let k = finalK;
180
+ for (let d = finalD; d > 0; d--) {
181
+ const prev = history[d - 1];
182
+ let prevK;
183
+ let down;
184
+ if (k === -d) {
185
+ prevK = k + 1;
186
+ down = true;
187
+ }
188
+ else if (k === d) {
189
+ prevK = k - 1;
190
+ down = false;
191
+ }
192
+ else if (prev[vOffset + k - 1] < prev[vOffset + k + 1]) {
193
+ prevK = k + 1;
194
+ down = true;
195
+ }
196
+ else {
197
+ prevK = k - 1;
198
+ down = false;
199
+ }
200
+ const prevXEnd = prev[vOffset + prevK];
201
+ const prevYEnd = prevXEnd - prevK;
202
+ const xStart = down ? prevXEnd : prevXEnd + 1;
203
+ const yStart = down ? prevYEnd + 1 : prevXEnd + 1 - k;
204
+ // Diagonal matches (pushed in reverse)
205
+ while (x > xStart && y > yStart) {
206
+ ops.push(0);
207
+ x--;
208
+ y--;
209
+ }
210
+ // The edit step
211
+ if (down) {
212
+ ops.push(1); // ins
213
+ y--;
214
+ }
215
+ else {
216
+ ops.push(2); // del
217
+ x--;
218
+ }
219
+ k = prevK;
220
+ }
221
+ // Walk ops forward (they were pushed in reverse), grouping contiguous edits
222
+ const patches = [];
223
+ let currA = offset;
224
+ let currB = offset;
225
+ let sliceA = [];
226
+ let sliceB = [];
227
+ let patchA = -1;
228
+ let patchB = -1;
229
+ const flush = () => {
230
+ if (patchA !== -1) {
231
+ patches.push({ indexA: patchA, indexB: patchB, sliceA, sliceB });
232
+ sliceA = [];
233
+ sliceB = [];
234
+ patchA = -1;
235
+ }
236
+ };
237
+ for (let i = ops.length - 1; i >= 0; i--) {
238
+ const op = ops[i];
239
+ if (op === 0) {
240
+ flush();
241
+ currA++;
242
+ currB++;
243
+ }
244
+ else if (op === 1) {
245
+ if (patchA === -1) {
246
+ patchA = currA;
247
+ patchB = currB;
248
+ }
249
+ sliceB.push(B[currB++]);
250
+ }
251
+ else {
252
+ if (patchA === -1) {
253
+ patchA = currA;
254
+ patchB = currB;
255
+ }
256
+ sliceA.push(A[currA++]);
257
+ }
258
+ }
259
+ flush();
260
+ return patches;
261
+ }
262
+
114
263
  var _a, _b;
115
264
  const events = Symbol('events');
116
265
  const hooks = Symbol('hooks');
@@ -602,151 +751,6 @@ function chainPromise(given) {
602
751
  return chained;
603
752
  }
604
753
 
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
754
  function attend(source, callback) {
751
755
  const enumerate = typeof source === 'function'
752
756
  ? source
@@ -758,14 +762,14 @@ function attend(source, callback) {
758
762
  ? () => source.values()
759
763
  : () => Object.keys(source);
760
764
  const keyEffects = new Map();
761
- const outer = debug.effect(({ ascend }) => {
765
+ const outer = proxy.effect.named('attend')(({ ascend }) => {
762
766
  const keys = new Set();
763
767
  for (const key of enumerate())
764
768
  keys.add(key);
765
769
  for (const key of keys) {
766
770
  if (keyEffects.has(key))
767
771
  continue;
768
- keyEffects.set(key, ascend(() => debug.effect(() => callback(key))));
772
+ keyEffects.set(key, ascend(() => proxy.effect.named(`attend:${key}`)((access) => callback(key, access))));
769
773
  }
770
774
  for (const key of Array.from(keyEffects.keys())) {
771
775
  if (!keys.has(key)) {
@@ -774,189 +778,404 @@ function attend(source, callback) {
774
778
  }
775
779
  }
776
780
  });
777
- return () => {
778
- outer();
781
+ return (reason) => {
782
+ outer(reason);
779
783
  for (const stop of keyEffects.values())
780
- stop();
784
+ stop(reason);
781
785
  keyEffects.clear();
782
786
  };
783
787
  }
788
+ function lift(cb) {
789
+ let result;
790
+ let rawResult;
791
+ const liftCleanup = proxy.effect.named(`lift:${cb.name}`)(proxy.markWithRoot((access) => {
792
+ const source = cb(access);
793
+ if (!source || typeof source !== 'object')
794
+ throw new Error('lift callback must return an array or object');
795
+ const sourceProto = Object.getPrototypeOf(source);
796
+ if (!result) {
797
+ rawResult = Array.isArray(source) ? [] : Object.create(sourceProto);
798
+ result = proxy.reactive(rawResult);
799
+ }
800
+ if (sourceProto !== Object.getPrototypeOf(result))
801
+ throw new Error('lift callback must return the same type as the previous result');
802
+ if (Array.isArray(source)) {
803
+ const res = result;
804
+ for (const { indexA, sliceA, sliceB } of arrayDiff(res, source).sort((a, b) => a.indexA - b.indexA))
805
+ res.splice(indexA, sliceA.length, ...sliceB);
806
+ }
807
+ else {
808
+ for (const key of Object.keys(source)) {
809
+ const had = key in rawResult;
810
+ const newDesc = Object.getOwnPropertyDescriptor(source, key);
811
+ if (had) {
812
+ const oldDesc = Object.getOwnPropertyDescriptor(rawResult, key);
813
+ const sameAccessor = oldDesc && newDesc.get && oldDesc.get === newDesc.get;
814
+ Object.defineProperty(rawResult, key, newDesc);
815
+ if (!sameAccessor &&
816
+ rawResult[key] !==
817
+ (oldDesc ? (oldDesc.get ? oldDesc.get() : oldDesc.value) : undefined))
818
+ proxy.touched1(rawResult, { type: 'set', prop: key }, key);
819
+ }
820
+ else {
821
+ Object.defineProperty(rawResult, key, newDesc);
822
+ proxy.touched1(rawResult, { type: 'add', prop: key }, key);
823
+ }
824
+ }
825
+ for (const key of Object.keys(rawResult))
826
+ if (!(key in source)) {
827
+ delete rawResult[key];
828
+ proxy.touched1(rawResult, { type: 'del', prop: key }, key);
829
+ }
830
+ }
831
+ }, cb));
832
+ return proxy.link(result, liftCleanup);
833
+ }
784
834
  /**
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.
835
+ * Reactively maps an array source through `fn`, producing a lazy reactive output array.
796
836
  *
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)
837
+ * Each source item gets its own isolated effect (via `root()`) so that changes to one item
838
+ * only recompute that item's projection. Structural changes (push, splice, reorder) are detected
839
+ * via `arrayDiff` and surgically applied to the output cache.
801
840
  *
802
- * expect([...sum]).toEqual([1, 3, 6])
841
+ * The source can be a reactive array or a function returning an array. When a function is provided,
842
+ * the function is re-evaluated inside an effect whenever its dependencies change.
803
843
  *
804
- * // Modifying an item only re-computes subsequent sums
805
- * source[1].val = 10
806
- * expect([...sum]).toEqual([1, 11, 14])
807
- * ```
844
+ * Output elements are computed lazily accessing `result[i]` triggers computation if not yet cached.
808
845
  *
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
846
+ * @param source - A reactive array or a function returning an array
847
+ * @param fn - Mapping function applied to each element
848
+ * @param options - Optional purity hints to skip per-item effects
849
+ * @returns A readonly reactive array with a `[cleanup]` method to dispose all effects
813
850
  */
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);
851
+ function morphArray(source, fn, options) {
852
+ if (typeof source !== 'function' && !proxy.isReactive(source) && options?.pure === true) {
853
+ return source.map((i) => fn(i));
854
+ }
855
+ let track;
856
+ const itemEffects = new Map();
857
+ const cache = [];
858
+ let input = [];
859
+ function stopItem(key) {
860
+ const entry = itemEffects.get(key);
861
+ if (entry) {
862
+ entry.stop({ type: 'stopped' });
863
+ itemEffects.delete(key);
864
+ }
865
+ }
866
+ function computeItem(key, input) {
867
+ const isPure = options?.pure === true || (typeof options?.pure === 'function' && options.pure(input));
868
+ if (isPure) {
869
+ track(() => {
870
+ cache[key] = fn(input);
871
+ });
872
+ }
873
+ else {
874
+ const indexRef = { value: key };
875
+ const stop = track(() => proxy.effect.named(`morph:${fn.name}:${key}`).opaque((access) => {
876
+ cache[indexRef.value] = fn(input, access);
877
+ return (reason) => {
878
+ delete cache[indexRef.value];
879
+ proxy.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
880
+ stop?.({ type: 'invalidate', cause: reason });
881
+ };
882
+ }));
883
+ itemEffects.set(key, { stop, index: indexRef });
884
+ }
885
+ }
886
+ const proxy$1 = proxy.reactive(cache, {
887
+ get(cache, prop) {
888
+ const n = typeof prop === 'string' ? Number(prop) : NaN;
889
+ if (Number.isNaN(n))
890
+ return cache[prop];
891
+ if (!(n in cache))
892
+ computeItem(n, input[n]);
893
+ return cache[n];
894
+ },
895
+ has(_cache, prop) {
896
+ return Reflect.has(input, prop);
897
+ },
898
+ });
899
+ const stopMain = proxy.effect.named(`morph:${fn.name}`)(({ ascend }) => {
900
+ track = ascend;
901
+ const newInput = [...(typeof source === 'function' ? source() : source)];
902
+ const diffs = arrayDiff(input, newInput).toSorted((a, b) => b.indexA - a.indexA);
903
+ if (diffs.length > 0) {
904
+ for (const diff of diffs) {
905
+ // Stop items in removed range
906
+ for (let i = diff.indexA; i < diff.indexA + diff.sliceA.length; i++)
907
+ stopItem(i);
908
+ // Shift existing itemEffects in the Map to match the new indices
909
+ const shift = diff.sliceB.length - diff.sliceA.length;
910
+ if (shift !== 0) {
911
+ // We need to move entries in the Map.
912
+ const entries = Array.from(itemEffects.entries()).sort((a, b) => a[0] - b[0]);
913
+ // Remove entries that will be shifted
914
+ for (const [idx, _entry] of entries) {
915
+ if (idx >= diff.indexA + diff.sliceA.length) {
916
+ itemEffects.delete(idx);
917
+ }
918
+ }
919
+ // Re-add them with shifted indices
920
+ for (const [idx, entry] of entries) {
921
+ if (idx >= diff.indexA + diff.sliceA.length) {
922
+ const newIdx = idx + shift;
923
+ entry.index.value = newIdx;
924
+ itemEffects.set(newIdx, entry);
925
+ }
926
+ }
834
927
  }
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);
928
+ // Splice the cache
929
+ cache.splice(diff.indexA, diff.sliceA.length, ...new Array(diff.sliceB.length).fill(undefined));
930
+ // Make holes for lazy computation
931
+ for (let i = diff.indexA; i < diff.indexA + diff.sliceB.length; i++)
932
+ delete cache[i];
933
+ }
934
+ const invalidates = new Set([proxy.keysOf]);
935
+ if (input.length !== newInput.length)
936
+ invalidates.add('length');
937
+ for (const diff of diffs) {
938
+ const max = Math.max(diff.sliceA.length, diff.sliceB.length);
939
+ for (let i = 0; i < max; i++)
940
+ invalidates.add(String(diff.indexA + i));
941
+ }
942
+ proxy.touched(cache, { type: 'bunch', method: 'morph-input' }, invalidates);
943
+ }
944
+ input = newInput;
945
+ });
946
+ return proxy.link(proxy$1, (reason) => {
947
+ stopMain(reason);
948
+ for (const entry of itemEffects.values())
949
+ entry.stop(reason);
950
+ itemEffects.clear();
951
+ });
952
+ }
953
+ /**
954
+ * Reactively maps a `Map` source through `fn`, producing a reactive output Map.
955
+ *
956
+ * Each key gets its own isolated effect so that value changes for one key only recompute
957
+ * that key's projection. Key additions and removals are tracked via `keysOf` dependency.
958
+ *
959
+ * @param source - A reactive Map
960
+ * @param fn - Mapping function applied to each value
961
+ * @param options - Optional purity hints to skip per-key effects
962
+ * @returns A reactive Map with a `[cleanup]` method to dispose all effects
963
+ */
964
+ function morphMap(source, fn, options) {
965
+ if (!proxy.isReactive(source) && options?.pure === true) {
966
+ const res = new Map();
967
+ for (const [k, v] of source)
968
+ res.set(k, fn(v, k));
969
+ return res;
970
+ }
971
+ let track;
972
+ const itemEffects = new Map();
973
+ const cache = new Map();
974
+ Object.defineProperty(cache, 'constructor', { value: Object, enumerable: false });
975
+ function stopItem(key) {
976
+ const stop = itemEffects.get(key);
846
977
  if (stop) {
847
- stop();
848
- indexEffects.delete(index);
849
- debug.untracked(() => {
850
- Reflect.deleteProperty(indexToIntermediate, index);
851
- Reflect.deleteProperty(result, index);
852
- });
978
+ stop({ type: 'stopped' });
979
+ itemEffects.delete(key);
853
980
  }
854
981
  }
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;
982
+ function computeItem(key, val) {
983
+ const isPure = options?.pure === true || (typeof options?.pure === 'function' && options.pure(val));
984
+ if (isPure) {
985
+ cache.set(key, track(() => fn(val, key)));
903
986
  }
904
- // Cleanup trailing indices
905
- for (const index of Array.from(indexEffects.keys())) {
906
- if (index >= length)
907
- disposeIndex(index);
987
+ else {
988
+ const stop = track(() => proxy.effect.named(`morph:${fn.name}:${key}`).opaque((access) => {
989
+ cache.set(key, fn(source.get(key), key, access));
990
+ return (reason) => {
991
+ cache.delete(key);
992
+ proxy.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
993
+ stop?.({ type: 'invalidate', cause: reason });
994
+ };
995
+ }));
996
+ itemEffects.set(key, stop);
908
997
  }
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
- });
998
+ }
999
+ const proxy$1 = proxy.reactive(cache, {
1000
+ get(cache, prop) {
1001
+ if (prop === 'get')
1002
+ return (key) => {
1003
+ if (!cache.has(key) && source.has(key))
1004
+ computeItem(key, source.get(key));
1005
+ return cache.get(key);
1006
+ };
1007
+ if (prop === 'has')
1008
+ return (key) => {
1009
+ return source.has(key);
1010
+ };
1011
+ if (prop === 'keys')
1012
+ return () => {
1013
+ return source.keys();
1014
+ };
1015
+ if (prop === 'values')
1016
+ return function* () {
1017
+ for (const key of source.keys()) {
1018
+ yield proxy$1.get(key);
1019
+ }
1020
+ };
1021
+ if (prop === 'entries')
1022
+ return function* () {
1023
+ for (const key of source.keys()) {
1024
+ yield [key, proxy$1.get(key)];
1025
+ }
1026
+ };
1027
+ if (prop === Symbol.iterator)
1028
+ return function* () {
1029
+ for (const key of source.keys()) {
1030
+ yield [key, proxy$1.get(key)];
1031
+ }
1032
+ };
1033
+ return cache[prop];
1034
+ },
915
1035
  });
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({});
1036
+ let stateSnapshot = proxy.getState(source);
1037
+ const stopMain = proxy.effect.named(`morph:${fn.name}`)(({ ascend }) => {
1038
+ track = ascend;
1039
+ proxy.dependant(source, proxy.keysOf);
1040
+ while ('evolution' in stateSnapshot) {
1041
+ const { evolution } = stateSnapshot;
1042
+ stateSnapshot = stateSnapshot.next;
1043
+ if (evolution.type === 'add') {
1044
+ proxy.touched1(cache, evolution, evolution.prop);
1045
+ }
1046
+ else if (evolution.type === 'del') {
1047
+ stopItem(evolution.prop);
1048
+ cache.delete(evolution.prop);
1049
+ proxy.touched1(cache, evolution, evolution.prop);
935
1050
  }
936
1051
  }
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];
1052
+ });
1053
+ return proxy.link(proxy$1, (reason) => {
1054
+ stopMain(reason);
1055
+ for (const stop of itemEffects.values())
1056
+ stop(reason);
1057
+ itemEffects.clear();
1058
+ });
1059
+ }
1060
+ /**
1061
+ * Reactively maps a record/object source through `fn`, producing a reactive output record.
1062
+ *
1063
+ * Each key gets its own isolated effect so that value changes for one key only recompute
1064
+ * that key's projection. Key additions and removals are tracked automatically.
1065
+ *
1066
+ * @param source - A reactive record
1067
+ * @param fn - Mapping function applied to each value
1068
+ * @param options - Optional purity hints to skip per-key effects
1069
+ * @returns A reactive record with a `[cleanup]` method to dispose all effects
1070
+ */
1071
+ function morphRecord(source, fn, options) {
1072
+ if (!proxy.isReactive(source) && options?.pure === true) {
1073
+ const res = {};
1074
+ for (const k of Object.keys(source))
1075
+ res[k] = fn(source[k], k);
1076
+ return res;
1077
+ }
1078
+ let track;
1079
+ const itemEffects = new Map();
1080
+ const cache = {};
1081
+ function stopItem(key) {
1082
+ const stop = itemEffects.get(key);
1083
+ if (stop) {
1084
+ stop({ type: 'stopped' });
1085
+ itemEffects.delete(key);
943
1086
  }
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];
1087
+ }
1088
+ function computeItem(key, val) {
1089
+ const isPure = options?.pure === true || (typeof options?.pure === 'function' && options.pure(val));
1090
+ if (isPure) {
1091
+ cache[key] = track(() => fn(val, key));
949
1092
  }
950
1093
  else {
951
- throw new Error('lift callback must return the same type as the previous result');
1094
+ const stop = track(() => proxy.effect.named(`morph:${fn.name}:${key}`).opaque((access) => {
1095
+ cache[key] = fn(source[key], key, access);
1096
+ return (reason) => {
1097
+ delete cache[key];
1098
+ proxy.touched1(cache, { type: 'invalidate', prop: 'morph' }, String(key));
1099
+ stop?.({ type: 'invalidate', cause: reason });
1100
+ };
1101
+ }));
1102
+ itemEffects.set(key, stop);
1103
+ }
1104
+ }
1105
+ function get(prop) {
1106
+ if (!(prop in cache) && prop in source)
1107
+ computeItem(prop, source[prop]);
1108
+ return cache[prop];
1109
+ }
1110
+ const proxy$1 = proxy.reactive(cache, {
1111
+ get(_, prop) {
1112
+ return get(prop);
1113
+ },
1114
+ has(_, prop) {
1115
+ return prop in source;
1116
+ },
1117
+ ownKeys() {
1118
+ return Reflect.ownKeys(source);
1119
+ },
1120
+ getOwnPropertyDescriptor(_cache, prop) {
1121
+ if (prop in source)
1122
+ return { configurable: true, enumerable: true, get: () => get(prop) };
1123
+ },
1124
+ });
1125
+ let stateSnapshot = proxy.getState(source);
1126
+ const stopMain = proxy.effect.named(`morph:${fn.name}`)(({ ascend }) => {
1127
+ track = ascend;
1128
+ // Track only structural changes on source
1129
+ proxy.dependant(source, proxy.keysOf);
1130
+ while ('evolution' in stateSnapshot) {
1131
+ const { evolution } = stateSnapshot;
1132
+ stateSnapshot = stateSnapshot.next;
1133
+ if (evolution.type === 'add') {
1134
+ proxy.touched1(cache, evolution, evolution.prop);
1135
+ }
1136
+ else if (evolution.type === 'del') {
1137
+ stopItem(evolution.prop);
1138
+ delete cache[evolution.prop];
1139
+ proxy.touched1(cache, evolution, evolution.prop);
1140
+ }
952
1141
  }
953
1142
  });
954
- return debug.cleanedBy(result, liftCleanup);
1143
+ return proxy.link(proxy$1, (reason) => {
1144
+ stopMain(reason);
1145
+ for (const stop of itemEffects.values())
1146
+ stop(reason);
1147
+ itemEffects.clear();
1148
+ });
955
1149
  }
1150
+ /**
1151
+ * Reactively maps a collection (array, Map, or record) through a per-entry function.
1152
+ *
1153
+ * Each entry in the source gets its own reactive context — when only one entry's dependencies
1154
+ * change, only that entry's projection recomputes. Structural changes (additions, removals,
1155
+ * reorders) are detected via diffing and applied surgically.
1156
+ *
1157
+ * Use `morph.pure(source, fn)` when `fn` has no reactive reads (skips per-item effects).
1158
+ *
1159
+ * @example
1160
+ * ```ts
1161
+ * const users = reactive([{ name: 'John' }, { name: 'Jane' }])
1162
+ * const names = morph(users, u => u.name.toUpperCase())
1163
+ * // names[0] = 'JOHN', names[1] = 'JANE'
1164
+ * // Changing users[0].name only recomputes names[0]
1165
+ * ```
1166
+ */
1167
+ const morph = proxy.flavored(function morph(source, fn, options) {
1168
+ if (Array.isArray(source) || typeof source === 'function')
1169
+ return morphArray(source, fn, options);
1170
+ if (source instanceof Map)
1171
+ return morphMap(source, fn, options);
1172
+ return morphRecord(source, fn, options);
1173
+ }, {
1174
+ get pure() {
1175
+ return (source, fn, _opt) => this(source, fn, { pure: true });
1176
+ },
1177
+ });
956
1178
 
957
- function isObject(value) {
958
- return typeof value === 'object' && value !== null;
959
- }
960
1179
  /**
961
1180
  * Deep watch an object and all its nested properties
962
1181
  * @param target - The object to watch deeply
@@ -977,16 +1196,17 @@ function deepWatch(target, callback, { immediate = false } = {}) {
977
1196
  if (typeof target !== 'object')
978
1197
  throw new Error('Target of deep watching must be an object');
979
1198
  // Create a wrapper callback that matches EffectTrigger signature
980
- const wrappedCallback = debug.markWithRoot((() => callback(target)), callback);
1199
+ const wrappedCallback = proxy.markWithRoot((() => callback(target)), callback);
1200
+ proxy.registerDeepWatcher();
981
1201
  // Use the existing effect system to register dependencies
982
- return debug.effect(() => {
1202
+ return proxy.effect.named('deepWatch')(() => {
983
1203
  // Mark the target object as having deep watchers
984
- debug.objectsWithDeepWatchers.add(target);
1204
+ proxy.objectsWithDeepWatchers.add(target);
985
1205
  // Track which objects this effect is watching for cleanup
986
- let effectObjects = debug.effectToDeepWatchedObjects.get(wrappedCallback);
1206
+ let effectObjects = proxy.effectToDeepWatchedObjects.get(wrappedCallback);
987
1207
  if (!effectObjects) {
988
1208
  effectObjects = new Set();
989
- debug.effectToDeepWatchedObjects.set(wrappedCallback, effectObjects);
1209
+ proxy.effectToDeepWatchedObjects.set(wrappedCallback, effectObjects);
990
1210
  }
991
1211
  effectObjects.add(target);
992
1212
  // Traverse the object graph and register dependencies
@@ -994,56 +1214,45 @@ function deepWatch(target, callback, { immediate = false } = {}) {
994
1214
  const visited = new WeakSet();
995
1215
  function traverseAndTrack(obj, depth = 0) {
996
1216
  // Prevent infinite recursion and excessive depth
997
- if (!obj || visited.has(obj) || !isObject(obj) || depth > debug.options.maxDeepWatchDepth)
1217
+ if (!obj || visited.has(obj) || typeof obj !== 'object' || depth > proxy.options.maxDeepWatchDepth)
998
1218
  return;
999
1219
  // Do not traverse into unreactive objects
1000
- if (debug.isNonReactive(obj))
1220
+ if (proxy.isNonReactive(obj))
1001
1221
  return;
1002
1222
  visited.add(obj);
1003
1223
  // Mark this object as having deep watchers
1004
- debug.objectsWithDeepWatchers.add(obj);
1224
+ proxy.objectsWithDeepWatchers.add(obj);
1005
1225
  effectObjects.add(obj);
1006
1226
  // Traverse all properties to register dependencies
1007
1227
  // unwrap to avoid kicking dependency
1008
- for (const key in debug.unwrap(obj)) {
1228
+ for (const key in proxy.unwrap(obj)) {
1009
1229
  if (Object.hasOwn(obj, key)) {
1010
1230
  // Access the property to register dependency
1011
1231
  const value = obj[key];
1012
1232
  // Make the value reactive if it's an object
1013
- const reactiveValue = typeof value === 'object' && value !== null ? debug.reactive(value) : value;
1233
+ const reactiveValue = typeof value === 'object' && value !== null ? proxy.reactive(value) : value;
1014
1234
  traverseAndTrack(reactiveValue, depth + 1);
1015
1235
  }
1016
1236
  }
1017
1237
  // 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
1238
+ // Handle arrays and collections using iterators to ensure proxy tracking is triggered
1239
+ if (typeof obj[Symbol.iterator] === 'function') {
1240
+ // Access the iterator to track additions/removals/collection changes
1034
1241
  for (const value of obj) {
1035
1242
  // Make the value reactive if it's an object
1036
- const reactiveValue = typeof value === 'object' && value !== null ? debug.reactive(value) : value;
1243
+ const reactiveValue = typeof value === 'object' && value !== null ? proxy.reactive(value) : value;
1037
1244
  traverseAndTrack(reactiveValue, depth + 1);
1038
1245
  }
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);
1246
+ // Explicitly depend on length so array mutations changing count trigger re-evaluation
1247
+ if ('length' in obj) {
1248
+ proxy.dependant(obj, 'length');
1249
+ }
1250
+ // For Maps, also ensure we track values explicitly if the iterator yields entries
1251
+ if (obj instanceof Map) {
1252
+ for (const value of obj.values()) {
1253
+ const reactiveValue = typeof value === 'object' && value !== null ? proxy.reactive(value) : value;
1254
+ traverseAndTrack(reactiveValue, depth + 1);
1255
+ }
1047
1256
  }
1048
1257
  }
1049
1258
  // Note: WeakSet and WeakMap cannot be iterated, so we can't deep watch their contents
@@ -1053,911 +1262,243 @@ function deepWatch(target, callback, { immediate = false } = {}) {
1053
1262
  // This will register dependencies on all current properties and array elements
1054
1263
  traverseAndTrack(target);
1055
1264
  // Only call the callback if immediate is true or if it's not the first run
1056
- if (immediate)
1057
- callback(target);
1265
+ if (immediate) {
1266
+ proxy.untracked(() => callback(target));
1267
+ }
1058
1268
  immediate = true;
1059
1269
  // Return a cleanup function that properly removes deep watcher tracking
1060
1270
  return () => {
1061
1271
  // Get the objects this effect was watching
1062
- const effectObjects = debug.effectToDeepWatchedObjects.get(wrappedCallback);
1272
+ const effectObjects = proxy.effectToDeepWatchedObjects.get(wrappedCallback);
1063
1273
  if (effectObjects) {
1064
1274
  // Remove deep watcher tracking from all objects this effect was watching
1065
1275
  for (const obj of effectObjects) {
1066
1276
  // Check if this object still has other deep watchers
1067
- const watchers = debug.deepWatchers.get(obj);
1277
+ const watchers = proxy.deepWatchers.get(obj);
1068
1278
  if (watchers) {
1069
1279
  // Remove this effect's callback from the watchers
1070
1280
  watchers.delete(wrappedCallback);
1071
1281
  // If no more watchers, remove the object from deep watchers tracking
1072
1282
  if (watchers.size === 0) {
1073
- debug.deepWatchers.delete(obj);
1074
- debug.objectsWithDeepWatchers.delete(obj);
1283
+ proxy.deepWatchers.delete(obj);
1284
+ proxy.objectsWithDeepWatchers.delete(obj);
1075
1285
  }
1076
1286
  }
1077
1287
  else {
1078
1288
  // No watchers found, remove from deep watchers tracking
1079
- debug.objectsWithDeepWatchers.delete(obj);
1289
+ proxy.objectsWithDeepWatchers.delete(obj);
1080
1290
  }
1081
1291
  }
1082
1292
  // Clean up the tracking data
1083
- debug.effectToDeepWatchedObjects.delete(wrappedCallback);
1293
+ proxy.effectToDeepWatchedObjects.delete(wrappedCallback);
1084
1294
  }
1085
1295
  };
1086
1296
  });
1087
1297
  }
1088
1298
 
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();
1299
+ const memoizedRegistry = new WeakMap();
1300
+ const wrapperRegistry = new WeakMap();
1301
+ function getBranch(tree, key) {
1302
+ tree.branches ?? (tree.branches = new WeakMap());
1303
+ let branch = tree.branches.get(key);
1304
+ if (!branch) {
1305
+ branch = {};
1306
+ tree.branches.set(key, branch);
1097
1307
  }
1308
+ return branch;
1098
1309
  }
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
- }
1310
+ function memoizeFunction(fn, opts) {
1311
+ const fnRoot = proxy.getRoot(fn);
1312
+ const existing = memoizedRegistry.get(fnRoot);
1313
+ if (existing)
1314
+ return existing;
1315
+ const cacheRoot = {};
1316
+ const memoized = proxy.markWithRoot(function memoized(...args) {
1317
+ if (args.some((arg) => !(arg && ['object', 'symbol', 'function'].includes(typeof arg)))) {
1318
+ if (opts?.lenient)
1319
+ return fn.apply(this, args);
1320
+ throw new Error('memoize expects non-null object arguments');
1365
1321
  }
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;
1322
+ let node = cacheRoot;
1323
+ // Note: decorators add `this` as first argument
1324
+ for (const arg of args) {
1325
+ node = getBranch(node, arg);
1380
1326
  }
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);
1327
+ proxy.dependant(node, 'memoize');
1328
+ if ('result' in node) {
1329
+ if (proxy.options.onMemoizationDiscrepancy) {
1330
+ const wasVerification = proxy.options.isVerificationRun;
1331
+ proxy.options.isVerificationRun = true;
1332
+ try {
1333
+ const fresh = proxy.untracked(() => fn.apply(this, args));
1334
+ if (!proxy.deepCompare(node.result, fresh)) {
1335
+ proxy.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'calculation');
1336
+ }
1388
1337
  }
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;
1338
+ finally {
1339
+ proxy.options.isVerificationRun = wasVerification;
1436
1340
  }
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
1341
  }
1342
+ return node.result;
1528
1343
  }
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;
1344
+ // Create memoize internal effect to track dependencies and invalidate cache
1345
+ // Use untracked to prevent the effect creation from being affected by parent effects
1346
+ node.cleanup = proxy.root(() => proxy.effect.named('memoize')(() => {
1347
+ // Execute the function and track its dependencies
1348
+ // The function execution will automatically track dependencies on reactive objects
1349
+ node.result = fn.apply(this, args);
1350
+ return (reason) => {
1351
+ // When dependencies change, clear the cache and notify consumers
1352
+ delete node.result;
1353
+ proxy.touched1(node, { type: 'invalidate', prop: args }, 'memoize');
1354
+ // Lazy memoization: stop the effect so it doesn't re-run immediately.
1355
+ // It will be re-created on next access.
1356
+ if (node.cleanup) {
1357
+ node.cleanup({ type: 'invalidate', cause: reason });
1358
+ node.cleanup = undefined;
1551
1359
  }
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);
1360
+ };
1361
+ }, { opaque: true }));
1362
+ if (proxy.options.onMemoizationDiscrepancy) {
1363
+ const wasVerification = proxy.options.isVerificationRun;
1364
+ proxy.options.isVerificationRun = true;
1365
+ try {
1366
+ const fresh = proxy.untracked(() => fn.apply(this, args));
1367
+ if (!proxy.deepCompare(node.result, fresh)) {
1368
+ proxy.optionCall('onMemoizationDiscrepancy', node.result, fresh, fn, args, 'comparison');
1574
1369
  }
1575
1370
  }
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
- }
1371
+ finally {
1372
+ proxy.options.isVerificationRun = wasVerification;
1594
1373
  }
1595
- return iterator();
1596
1374
  }
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;
1375
+ return node.result;
1376
+ }, fn);
1377
+ memoizedRegistry.set(fnRoot, memoized);
1378
+ memoizedRegistry.set(memoized, memoized);
1379
+ return memoized;
1380
+ }
1381
+ function memoizeObject(target, opts) {
1382
+ const existing = memoizedRegistry.get(target);
1383
+ if (existing)
1384
+ return existing;
1385
+ const proxy$1 = new Proxy(target, {
1386
+ get(source, prop, receiver) {
1387
+ // 1. Walk prototype chain to find descriptor
1388
+ let current = source;
1389
+ let desc;
1390
+ while (current) {
1391
+ desc = Object.getOwnPropertyDescriptor(current, prop);
1392
+ if (desc)
1393
+ break;
1394
+ current = Object.getPrototypeOf(current);
1395
+ }
1396
+ if (!desc)
1397
+ return Reflect.get(source, prop, receiver);
1398
+ // 2. If getter, memoize
1399
+ if (desc.get) {
1400
+ const originalGetter = desc.get;
1401
+ let wrapper = wrapperRegistry.get(originalGetter);
1402
+ if (!wrapper) {
1403
+ wrapper = proxy.markWithRoot(proxy.named(`${String(source?.constructor?.name ?? 'Object')}.${String(prop)}`, (that) => {
1404
+ return originalGetter.call(that);
1405
+ }), {
1406
+ propertyKey: prop,
1407
+ });
1408
+ const origRoot = originalGetter[proxy.rootFunctionSymbol];
1409
+ if (origRoot)
1410
+ wrapper[proxy.rootFunctionSymbol] = origRoot;
1411
+ wrapperRegistry.set(originalGetter, wrapper);
1604
1412
  }
1413
+ const memoized = memoizeFunction(wrapper, opts);
1414
+ return memoized(receiver);
1605
1415
  }
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;
1416
+ // 3. Otherwise forward
1417
+ return Reflect.get(source, prop, receiver);
1418
+ },
1419
+ // Forward set to the target (source) to ensure it acts as the receiver for reactivity notifications
1420
+ set(source, prop, value, _receiver) {
1421
+ // By strictly passing `source` as receiver, we ensure that if `source` is a reactive proxy,
1422
+ // it recognizes itself and triggers change notifications.
1423
+ return Reflect.set(source, prop, value, source);
1424
+ },
1425
+ });
1426
+ proxy.proxyToObject.set(proxy$1, target);
1427
+ memoizedRegistry.set(target, proxy$1);
1428
+ return proxy$1;
1429
+ }
1652
1430
  /**
1653
- * Creates a reactive Register - an ordered, array-like collection with stable key-based identity.
1431
+ * Decorator and function wrapper for memoizing computed values based on reactive dependencies.
1654
1432
  *
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.
1433
+ * When used as a decorator on getters or methods, it caches the result and automatically
1434
+ * invalidates the cache when reactive dependencies change.
1658
1435
  *
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
1436
+ * When used as a function wrapper, it memoizes based on object arguments (WeakMap-based cache).
1662
1437
  *
1663
1438
  * @example
1664
1439
  * ```typescript
1665
- * const users = register(
1666
- * (user: User) => user.id,
1667
- * [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
1668
- * )
1440
+ * class User {
1441
+ * @memoize
1442
+ * get fullName() {
1443
+ * return `${this.firstName} ${this.lastName}`
1444
+ * }
1445
+ * }
1669
1446
  *
1670
- * users.push({ id: 3, name: 'Charlie' })
1671
- * const bob = users.get(2) // Get by key
1447
+ * // Or as a function wrapper
1448
+ * const expensive = memoize((obj: SomeObject) => {
1449
+ * return heavyComputation(obj)
1450
+ * })
1672
1451
  * ```
1673
1452
  */
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,
1453
+ function makeMemoizeDecorator(memoizeOpts) {
1454
+ return proxy.decorator({
1455
+ getter(original, target, propertyKey) {
1456
+ return function () {
1457
+ let wrapper = wrapperRegistry.get(original);
1458
+ if (!wrapper) {
1459
+ wrapper = proxy.markWithRoot(proxy.named(`${String(target?.constructor?.name ?? target?.name ?? 'Object')}.${String(propertyKey)}`, (that) => {
1460
+ return original.call(that);
1461
+ }), {
1462
+ method: original,
1463
+ propertyKey,
1464
+ });
1465
+ const origRoot = original[proxy.rootFunctionSymbol];
1466
+ if (origRoot)
1467
+ wrapper[proxy.rootFunctionSymbol] = origRoot;
1468
+ wrapperRegistry.set(original, wrapper);
1469
+ }
1470
+ const memoized = memoizeFunction(wrapper, memoizeOpts);
1471
+ return memoized(this);
1472
+ };
1473
+ },
1474
+ method(original, target, name) {
1475
+ return function (...args) {
1476
+ let wrapper = wrapperRegistry.get(original);
1477
+ if (!wrapper) {
1478
+ wrapper = proxy.markWithRoot(proxy.named(`${String(target?.constructor?.name ?? target?.name ?? 'Object')}.${String(name)}`, (that, ...args) => {
1479
+ return original.call(that, ...args);
1480
+ }), {
1481
+ method: original,
1482
+ propertyKey: name,
1483
+ });
1484
+ const origRoot = original[proxy.rootFunctionSymbol];
1485
+ if (origRoot)
1486
+ wrapper[proxy.rootFunctionSymbol] = origRoot;
1487
+ wrapperRegistry.set(original, wrapper);
1488
+ }
1489
+ const memoized = memoizeFunction(wrapper, memoizeOpts);
1490
+ return memoized(this, ...args);
1491
+ };
1492
+ },
1493
+ default: (target) => typeof target === 'object'
1494
+ ? memoizeObject(target, memoizeOpts)
1495
+ : memoizeFunction(target, memoizeOpts),
1943
1496
  });
1944
1497
  }
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,
1498
+ const memoize = proxy.flavored(makeMemoizeDecorator(), {
1499
+ get lenient() {
1500
+ return makeMemoizeDecorator({ lenient: true });
1501
+ },
1961
1502
  });
1962
1503
 
1963
1504
  /**
@@ -2012,8 +1553,8 @@ const project = Object.assign(projectCore, {
2012
1553
  * });
2013
1554
  */
2014
1555
  function organized(source, apply, baseTarget = {}) {
2015
- const observedSource = debug.reactive(source);
2016
- const target = debug.reactive(baseTarget);
1556
+ const observedSource = proxy.reactive(source);
1557
+ const target = proxy.reactive(baseTarget);
2017
1558
  const stop = attend(() => {
2018
1559
  const keys = [];
2019
1560
  for (const key in observedSource)
@@ -2023,8 +1564,8 @@ function organized(source, apply, baseTarget = {}) {
2023
1564
  const sourceKey = key;
2024
1565
  const accessBase = {
2025
1566
  key: sourceKey,
2026
- get: () => debug.FoolProof.get(observedSource, sourceKey, observedSource),
2027
- set: (value) => debug.FoolProof.set(observedSource, sourceKey, value, observedSource),
1567
+ get: () => proxy.FoolProof.get(observedSource, sourceKey, observedSource),
1568
+ set: (value) => proxy.FoolProof.set(observedSource, sourceKey, value, observedSource),
2028
1569
  };
2029
1570
  Object.defineProperty(accessBase, 'value', {
2030
1571
  get: accessBase.get,
@@ -2034,7 +1575,7 @@ function organized(source, apply, baseTarget = {}) {
2034
1575
  });
2035
1576
  return apply(accessBase, target);
2036
1577
  });
2037
- return debug.cleanedBy(target, stop);
1578
+ return proxy.link(target, (reason) => stop(reason));
2038
1579
  }
2039
1580
  /**
2040
1581
  * Organizes a property on a target object
@@ -2051,35 +1592,246 @@ function organize(target, property, access) {
2051
1592
  configurable: true,
2052
1593
  enumerable: true,
2053
1594
  });
2054
- debug.touched1(target, { type: 'set', prop: property }, property);
1595
+ proxy.touched1(target, { type: 'set', prop: property }, property);
2055
1596
  return () => delete target[property];
2056
1597
  }
2057
1598
 
1599
+ //#region watch
1600
+ const unsetYet = Symbol('unset-yet');
1601
+ const watch = proxy.flavored(function watch(value, //object | ((dep: DependencyAccess) => object),
1602
+ changed, options = {}) {
1603
+ return typeof value === 'function'
1604
+ ? watchCallBack(value, changed, options)
1605
+ : typeof value === 'object' && value !== null
1606
+ ? watchObject(value, changed, options)
1607
+ : (() => {
1608
+ throw new Error('watch: value must be a function or an object');
1609
+ })();
1610
+ }, {
1611
+ get deep() {
1612
+ return proxy.flavorOptions(this, { deep: true });
1613
+ },
1614
+ get immediate() {
1615
+ return proxy.flavorOptions(this, { immediate: true });
1616
+ },
1617
+ });
1618
+ function watchObject(value, changed, { immediate = false, deep = false } = {}) {
1619
+ if (deep)
1620
+ return deepWatch(value, changed, { immediate });
1621
+ return proxy.effect.named('watch:object')(() => {
1622
+ proxy.dependant(value);
1623
+ if (immediate)
1624
+ changed(value);
1625
+ immediate = true;
1626
+ });
1627
+ }
1628
+ function watchCallBack(value, changed, { immediate = false, deep = false } = {}) {
1629
+ let oldValue = unsetYet;
1630
+ let deepCleanup;
1631
+ const cbCleanup = proxy.effect.named('watch:callback')(proxy.markWithRoot((access) => {
1632
+ const newValue = value(access);
1633
+ if (oldValue !== newValue) {
1634
+ const old = oldValue;
1635
+ if (old === unsetYet) {
1636
+ if (immediate)
1637
+ proxy.untracked(() => changed(newValue));
1638
+ }
1639
+ else
1640
+ proxy.untracked(() => changed(newValue, old));
1641
+ }
1642
+ oldValue = newValue;
1643
+ if (deep) {
1644
+ if (deepCleanup)
1645
+ deepCleanup();
1646
+ deepCleanup = deepWatch(newValue, (value) => changed(value, value));
1647
+ }
1648
+ }, value));
1649
+ return (() => {
1650
+ cbCleanup();
1651
+ if (deepCleanup)
1652
+ deepCleanup();
1653
+ });
1654
+ }
1655
+ //#endregion
1656
+ //#region when
2058
1657
  /**
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.
1658
+ * Returns a promise that resolves when the predicate returns a truthy value.
1659
+ * The predicate is evaluated reactively — it re-runs whenever its dependencies change.
1660
+ * @param predicate - Reactive function that returns a value; resolves when truthy
1661
+ * @param timeout - Optional timeout in milliseconds — rejects if condition is not met within this duration
1662
+ * @returns Promise that resolves with the first truthy return value
2067
1663
  */
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);
1664
+ function when(predicate, timeout) {
1665
+ return new Promise((resolve, reject) => {
1666
+ let timer;
1667
+ const stop = proxy.effect.named('watch:when')((access) => {
1668
+ try {
1669
+ const value = predicate(access);
1670
+ if (value) {
1671
+ if (timer !== undefined)
1672
+ clearTimeout(timer);
1673
+ timer = undefined;
1674
+ queueMicrotask(() => stop());
1675
+ resolve(value);
1676
+ }
1677
+ }
1678
+ catch (error) {
1679
+ if (timer !== undefined)
1680
+ clearTimeout(timer);
1681
+ timer = undefined;
1682
+ reject(error);
1683
+ }
1684
+ });
1685
+ if (timeout !== undefined) {
1686
+ timer = setTimeout(() => {
1687
+ stop();
1688
+ timer = undefined;
1689
+ reject(new Error(`when: timed out after ${timeout}ms`));
1690
+ }, timeout);
2079
1691
  }
2080
- return () => Reflect.deleteProperty(target, key);
2081
1692
  });
2082
- return debug.cleanedBy(target, stop);
1693
+ }
1694
+ //#endregion
1695
+ //#region nonReactive
1696
+ /**
1697
+ * Mark an object as non-reactive. This object and all its properties will never be made reactive.
1698
+ * @param obj - The object to mark as non-reactive
1699
+ */
1700
+ function shallowNonReactive(obj) {
1701
+ obj = proxy.unwrap(obj);
1702
+ if (proxy.isNonReactive(obj))
1703
+ return obj;
1704
+ obj[proxy.unreactiveProperties] = true;
1705
+ return obj;
1706
+ }
1707
+ function unreactiveApplication(arg1, ...args) {
1708
+ return typeof arg1 === 'object'
1709
+ ? shallowNonReactive(arg1)
1710
+ : ((original) => {
1711
+ // Copy the parent's unreactive properties if they exist
1712
+ const parentMarker = original.prototype[proxy.unreactiveProperties];
1713
+ // If parent is fully unreactive, child is too
1714
+ if (parentMarker === true) {
1715
+ original.prototype[proxy.unreactiveProperties] = true;
1716
+ }
1717
+ else {
1718
+ const set = new Set(parentMarker || []);
1719
+ // Add all arguments (including the first one)
1720
+ set.add(arg1);
1721
+ for (const arg of args)
1722
+ set.add(arg);
1723
+ proxy.addUnreactiveProps(original.prototype, set);
1724
+ }
1725
+ return original; // Return the class
1726
+ });
1727
+ }
1728
+ /**
1729
+ * Decorator that marks classes or properties as non-reactive
1730
+ * Prevents objects from being made reactive
1731
+ */
1732
+ const unreactive = proxy.decorator({
1733
+ class(original) {
1734
+ original.prototype[proxy.unreactiveProperties] = true;
1735
+ },
1736
+ default: unreactiveApplication,
1737
+ });
1738
+ //#endregion
1739
+ //#region resource
1740
+ function lazyInit(resource, load) {
1741
+ const creation = proxy.effectHistory.active;
1742
+ let fresh = true;
1743
+ return new Proxy(resource, {
1744
+ [Symbol.toStringTag]: 'LazyInit',
1745
+ get(target, prop) {
1746
+ if (fresh) {
1747
+ proxy.captured(creation, load)();
1748
+ fresh = false;
1749
+ }
1750
+ return target[prop];
1751
+ },
1752
+ });
1753
+ }
1754
+ /**
1755
+ * Creates a reactive resource that automatically tracks async state.
1756
+ * @param fetcher - Async function that returns the value. Reactive dependencies are tracked.
1757
+ * @param options - Resource options (initialValue)
1758
+ * @returns Reactive Resource object with value, loading, error, latest properties
1759
+ */
1760
+ function resource(fetcher, options = {}) {
1761
+ const resource = proxy.reactive({
1762
+ value: options.initialValue,
1763
+ loading: true,
1764
+ error: undefined,
1765
+ latest: options.initialValue,
1766
+ reload() {
1767
+ reloadSignal.value++;
1768
+ },
1769
+ });
1770
+ const reloadSignal = proxy.reactive({ value: 0 });
1771
+ // Solve race conditions: make sure a new fast request is not overloaded by a slow old one
1772
+ let counter = 0;
1773
+ return lazyInit(resource, () => {
1774
+ proxy.link(resource, proxy.effect.named('watch:resource')((access) => {
1775
+ // Track reload signal to enable manual reloading
1776
+ void reloadSignal.value;
1777
+ const id = ++counter;
1778
+ resource.loading = true;
1779
+ resource.error = undefined;
1780
+ try {
1781
+ const result = fetcher(access);
1782
+ if (result instanceof Promise) {
1783
+ resource.promise = result
1784
+ .then((val) => {
1785
+ if (id === counter) {
1786
+ resource.value = val;
1787
+ resource.latest = val;
1788
+ resource.loading = false;
1789
+ }
1790
+ })
1791
+ .catch((err) => {
1792
+ if (id === counter) {
1793
+ resource.error = err;
1794
+ resource.loading = false;
1795
+ }
1796
+ });
1797
+ }
1798
+ else {
1799
+ resource.promise = Promise.resolve();
1800
+ resource.value = result;
1801
+ resource.latest = result;
1802
+ resource.loading = false;
1803
+ }
1804
+ }
1805
+ catch (err) {
1806
+ resource.promise = Promise.reject(err);
1807
+ resource.error = err;
1808
+ resource.loading = false;
1809
+ }
1810
+ }));
1811
+ });
1812
+ }
1813
+ //#endregion
1814
+
1815
+ /**
1816
+ * Converts an iterator to a generator that yields reactive values
1817
+ */
1818
+ function* makeReactiveIterator(iterator) {
1819
+ let result = iterator.next();
1820
+ while (!result.done) {
1821
+ yield proxy.reactive(result.value);
1822
+ result = iterator.next();
1823
+ }
1824
+ }
1825
+ /**
1826
+ * Converts an iterator of key-value pairs to a generator that yields reactive key-value pairs
1827
+ */
1828
+ function* makeReactiveEntriesIterator(iterator) {
1829
+ let result = iterator.next();
1830
+ while (!result.done) {
1831
+ const [key, value] = result.value;
1832
+ yield [proxy.reactive(key), proxy.reactive(value)];
1833
+ result = iterator.next();
1834
+ }
2083
1835
  }
2084
1836
 
2085
1837
  function* index(i, { length = true } = {}) {
@@ -2087,42 +1839,42 @@ function* index(i, { length = true } = {}) {
2087
1839
  yield 'length';
2088
1840
  yield i;
2089
1841
  }
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
1842
  class Indexer extends Array {
2099
1843
  get(i) {
2100
- debug.dependant(this, i);
2101
- return debug.reactive(this[i]);
1844
+ proxy.dependant(this, i);
1845
+ return proxy.reactive(this[i]);
2102
1846
  }
2103
1847
  // Returns undefined intentionally: signals the proxy handler that notifications
2104
1848
  // were already dispatched via touched(), preventing double notification
2105
1849
  set(i, value) {
2106
1850
  const added = i >= this.length;
2107
1851
  this[i] = value;
2108
- debug.touched(this, { type: 'set', prop: i }, index(i, { length: added }));
1852
+ proxy.touched(this, { type: 'set', prop: i }, index(i, { length: added }));
2109
1853
  }
2110
1854
  }
2111
- const indexLess = { get: debug.FoolProof.get, set: debug.FoolProof.set };
2112
- Object.assign(debug.FoolProof, {
1855
+ const indexLess = { get: proxy.FoolProof.get, set: proxy.FoolProof.set };
1856
+ // Fast numeric-string check: first char is a digit (0-9)
1857
+ function asIndex(prop) {
1858
+ const c = prop.charCodeAt(0);
1859
+ if (c < 48 || c > 57)
1860
+ return -1; // not 0-9
1861
+ const n = +prop; // coerce — faster than parseInt, handles "0", "12", etc.
1862
+ return n === (n | 0) && n >= 0 ? n : -1;
1863
+ }
1864
+ Object.assign(proxy.FoolProof, {
2113
1865
  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);
1866
+ if (Array.isArray(obj) && typeof prop === 'string') {
1867
+ const i = asIndex(prop);
1868
+ if (i >= 0)
1869
+ return Indexer.prototype.get.call(obj, i);
2118
1870
  }
2119
1871
  return indexLess.get(obj, prop, receiver);
2120
1872
  },
2121
1873
  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);
1874
+ if (Array.isArray(obj) && typeof prop === 'string') {
1875
+ const i = asIndex(prop);
1876
+ if (i >= 0)
1877
+ return Indexer.prototype.set.call(obj, i, value);
2126
1878
  }
2127
1879
  return indexLess.set(obj, prop, value, receiver);
2128
1880
  },
@@ -2131,374 +1883,190 @@ class ReactiveArray extends Array {
2131
1883
  toJSON() {
2132
1884
  return this;
2133
1885
  }
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;
1886
+ }
1887
+ /**
1888
+ * This is a wrapper class for Array that adds reactive behavior.
1889
+ * It extends Array and overrides methods to add reactive behavior, while making sure that the internal representation is not reactive.
1890
+ */
1891
+ let ReactiveArrayWrapper = (() => {
1892
+ var _a;
1893
+ let _classSuper = Array;
1894
+ let _instanceExtraInitializers = [];
1895
+ let _fill_decorators;
1896
+ let _copyWithin_decorators;
1897
+ let _pop_decorators;
1898
+ let _push_decorators;
1899
+ let _reverse_decorators;
1900
+ let _shift_decorators;
1901
+ let _sort_decorators;
1902
+ let _splice_decorators;
1903
+ let _unshift_decorators;
1904
+ return _a = class ReactiveArrayWrapper extends _classSuper {
1905
+ at(index) {
1906
+ return proxy.reactive(super.at(index));
2219
1907
  }
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;
1908
+ concat(...items) {
1909
+ return proxy.reactive(super.concat(...items.map(proxy.unwrap)));
2237
1910
  }
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
- }
1911
+ entries() {
1912
+ proxy.dependant(this, proxy.keysOf);
1913
+ return makeReactiveEntriesIterator(super.entries());
1914
+ }
1915
+ every(predicate, thisArg) {
1916
+ return super.every((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg);
1917
+ }
1918
+ fill(value, start, end) {
1919
+ return super.fill(proxy.unwrap(value), start, end);
1920
+ }
1921
+ copyWithin(target, start, end) {
1922
+ return super.copyWithin(target, start, end);
1923
+ }
1924
+ filter(predicate, thisArg) {
1925
+ return proxy.reactive(super.filter((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg));
1926
+ }
1927
+ find(predicate, thisArg) {
1928
+ return proxy.reactive(super.find((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg));
1929
+ }
1930
+ findIndex(predicate, thisArg) {
1931
+ return super.findIndex((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg);
1932
+ }
1933
+ findLast(predicate, thisArg) {
1934
+ return proxy.reactive(super.findLast((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg));
1935
+ }
1936
+ findLastIndex(predicate, thisArg) {
1937
+ return super.findLastIndex((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg);
1938
+ }
1939
+ flat(depth) {
1940
+ return proxy.reactive(super.flat(depth));
1941
+ }
1942
+ flatMap(callbackfn, thisArg) {
1943
+ return proxy.reactive(super.flatMap((v, i, a) => proxy.unwrap(callbackfn.call(thisArg, proxy.reactive(v), i, a)), thisArg));
1944
+ }
1945
+ forEach(callbackfn, thisArg) {
1946
+ super.forEach((v, i, a) => {
1947
+ callbackfn.call(thisArg, proxy.reactive(v), i, a);
1948
+ }, thisArg);
1949
+ }
1950
+ includes(searchElement, fromIndex) {
1951
+ return arguments.length > 1
1952
+ ? super.includes(proxy.unwrap(searchElement), fromIndex)
1953
+ : super.includes(proxy.unwrap(searchElement));
1954
+ }
1955
+ indexOf(searchElement, fromIndex) {
1956
+ return arguments.length > 1
1957
+ ? super.indexOf(proxy.unwrap(searchElement), fromIndex)
1958
+ : super.indexOf(proxy.unwrap(searchElement));
1959
+ }
1960
+ join(separator) {
1961
+ return super.join(separator);
1962
+ }
1963
+ keys() {
1964
+ proxy.dependant(this, 'length');
1965
+ return super.keys();
1966
+ }
1967
+ lastIndexOf(searchElement, fromIndex) {
1968
+ return arguments.length > 1
1969
+ ? super.lastIndexOf(proxy.unwrap(searchElement), fromIndex)
1970
+ : super.lastIndexOf(proxy.unwrap(searchElement));
1971
+ }
1972
+ map(callbackfn, thisArg) {
1973
+ return proxy.reactive(super.map((v, i, a) => proxy.unwrap(callbackfn.call(thisArg, proxy.reactive(v), i, a)), thisArg));
1974
+ }
1975
+ pop() {
1976
+ return proxy.reactive(super.pop());
1977
+ }
1978
+ push(...items) {
1979
+ return super.push(...items.map(proxy.unwrap));
1980
+ }
1981
+ reduce(callbackfn, initialValue) {
1982
+ return proxy.reactive(arguments.length > 1
1983
+ ? super.reduce((acc, v, i, a) => proxy.unwrap(callbackfn(acc, proxy.reactive(v), i, a)), initialValue)
1984
+ : super.reduce((acc, v, i, a) => proxy.unwrap(callbackfn(acc, proxy.reactive(v), i, a))));
1985
+ }
1986
+ reduceRight(callbackfn, initialValue) {
1987
+ return proxy.reactive(arguments.length > 1
1988
+ ? super.reduceRight((acc, v, i, a) => proxy.unwrap(callbackfn(acc, proxy.reactive(v), i, a)), initialValue)
1989
+ : super.reduceRight((acc, v, i, a) => proxy.unwrap(callbackfn(acc, proxy.reactive(v), i, a))));
1990
+ }
1991
+ reverse() {
1992
+ return proxy.reactive(super.reverse());
1993
+ }
1994
+ shift() {
1995
+ return proxy.reactive(super.shift());
1996
+ }
1997
+ slice(start, end) {
1998
+ return proxy.reactive(super.slice(start, end));
2261
1999
  }
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
- }
2000
+ some(predicate, thisArg) {
2001
+ return super.some((v, i, a) => predicate.call(thisArg, proxy.reactive(v), i, a), thisArg);
2281
2002
  }
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;
2003
+ sort(compareFn) {
2004
+ const wrappedCompare = compareFn
2005
+ ? (a, b) => compareFn(proxy.reactive(a), proxy.reactive(b))
2006
+ : undefined;
2007
+ return super.sort(wrappedCompare);
2347
2008
  }
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;
2009
+ splice(start, deleteCount, ...items) {
2010
+ if (arguments.length > 2)
2011
+ return proxy.reactive(super.splice(start, deleteCount, ...items.map(proxy.unwrap)));
2012
+ if (arguments.length === 2)
2013
+ return proxy.reactive(super.splice(start, deleteCount));
2014
+ if (arguments.length === 1)
2015
+ return proxy.reactive(super.splice(start));
2016
+ return proxy.reactive([]);
2358
2017
  }
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));
2018
+ unshift(...items) {
2019
+ return super.unshift(...items.map(proxy.unwrap));
2469
2020
  }
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));
2021
+ values() {
2022
+ proxy.dependant(this, proxy.keysOf);
2023
+ return makeReactiveIterator(super.values());
2498
2024
  }
2499
- }
2500
- }
2501
- }
2025
+ [(_fill_decorators = [proxy.atomic], _copyWithin_decorators = [proxy.atomic], _pop_decorators = [proxy.atomic], _push_decorators = [proxy.atomic], _reverse_decorators = [proxy.atomic], _shift_decorators = [proxy.atomic], _sort_decorators = [proxy.atomic], _splice_decorators = [proxy.atomic], _unshift_decorators = [proxy.atomic], Symbol.iterator)]() {
2026
+ proxy.dependant(this, proxy.keysOf);
2027
+ return makeReactiveIterator(super[Symbol.iterator]());
2028
+ }
2029
+ toReversed() {
2030
+ return proxy.reactive(super.toReversed());
2031
+ }
2032
+ toSorted(compareFn) {
2033
+ const wrappedCompare = compareFn
2034
+ ? (a, b) => compareFn(proxy.reactive(a), proxy.reactive(b))
2035
+ : undefined;
2036
+ return proxy.reactive(super.toSorted(wrappedCompare));
2037
+ }
2038
+ toSpliced(start, deleteCount, ...items) {
2039
+ if (arguments.length > 2)
2040
+ return proxy.reactive(super.toSpliced(start, deleteCount, ...items.map(proxy.unwrap)));
2041
+ if (arguments.length === 2)
2042
+ return proxy.reactive(super.toSpliced(start, deleteCount));
2043
+ if (arguments.length === 1)
2044
+ return proxy.reactive(super.toSpliced(start));
2045
+ return proxy.reactive([...this]);
2046
+ }
2047
+ with(index, value) {
2048
+ return proxy.reactive(super.with(index, proxy.unwrap(value)));
2049
+ }
2050
+ constructor() {
2051
+ super(...arguments);
2052
+ proxy.__runInitializers(this, _instanceExtraInitializers);
2053
+ }
2054
+ },
2055
+ (() => {
2056
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
2057
+ proxy.__esDecorate(_a, null, _fill_decorators, { kind: "method", name: "fill", static: false, private: false, access: { has: obj => "fill" in obj, get: obj => obj.fill }, metadata: _metadata }, null, _instanceExtraInitializers);
2058
+ proxy.__esDecorate(_a, null, _copyWithin_decorators, { kind: "method", name: "copyWithin", static: false, private: false, access: { has: obj => "copyWithin" in obj, get: obj => obj.copyWithin }, metadata: _metadata }, null, _instanceExtraInitializers);
2059
+ proxy.__esDecorate(_a, null, _pop_decorators, { kind: "method", name: "pop", static: false, private: false, access: { has: obj => "pop" in obj, get: obj => obj.pop }, metadata: _metadata }, null, _instanceExtraInitializers);
2060
+ proxy.__esDecorate(_a, null, _push_decorators, { kind: "method", name: "push", static: false, private: false, access: { has: obj => "push" in obj, get: obj => obj.push }, metadata: _metadata }, null, _instanceExtraInitializers);
2061
+ proxy.__esDecorate(_a, null, _reverse_decorators, { kind: "method", name: "reverse", static: false, private: false, access: { has: obj => "reverse" in obj, get: obj => obj.reverse }, metadata: _metadata }, null, _instanceExtraInitializers);
2062
+ proxy.__esDecorate(_a, null, _shift_decorators, { kind: "method", name: "shift", static: false, private: false, access: { has: obj => "shift" in obj, get: obj => obj.shift }, metadata: _metadata }, null, _instanceExtraInitializers);
2063
+ proxy.__esDecorate(_a, null, _sort_decorators, { kind: "method", name: "sort", static: false, private: false, access: { has: obj => "sort" in obj, get: obj => obj.sort }, metadata: _metadata }, null, _instanceExtraInitializers);
2064
+ proxy.__esDecorate(_a, null, _splice_decorators, { kind: "method", name: "splice", static: false, private: false, access: { has: obj => "splice" in obj, get: obj => obj.splice }, metadata: _metadata }, null, _instanceExtraInitializers);
2065
+ proxy.__esDecorate(_a, null, _unshift_decorators, { kind: "method", name: "unshift", static: false, private: false, access: { has: obj => "unshift" in obj, get: obj => obj.unshift }, metadata: _metadata }, null, _instanceExtraInitializers);
2066
+ if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
2067
+ })(),
2068
+ _a;
2069
+ })();
2502
2070
 
2503
2071
  /**
2504
2072
  * Reactive wrapper around JavaScript's WeakMap class
@@ -2508,26 +2076,26 @@ class ReactiveWeakMap extends WeakMap {
2508
2076
  // Implement WeakMap interface methods with reactivity
2509
2077
  delete(key) {
2510
2078
  const hadKey = this.has(key);
2511
- const result = this.delete(key);
2079
+ const result = super.delete(key);
2512
2080
  if (hadKey)
2513
- debug.touched1(debug.contentRef(this), { type: 'del', prop: key }, key);
2081
+ proxy.touched1(proxy.contentRef(this), { type: 'del', prop: key }, key);
2514
2082
  return result;
2515
2083
  }
2516
2084
  get(key) {
2517
- debug.dependant(debug.contentRef(this), key);
2518
- return debug.reactive(this.get(key));
2085
+ proxy.dependant(proxy.contentRef(this), key);
2086
+ return proxy.reactive(super.get(key));
2519
2087
  }
2520
2088
  has(key) {
2521
- debug.dependant(debug.contentRef(this), key);
2522
- return this.has(key);
2089
+ proxy.dependant(proxy.contentRef(this), key);
2090
+ return super.has(key);
2523
2091
  }
2524
2092
  set(key, value) {
2525
2093
  const hadKey = this.has(key);
2526
2094
  const oldValue = this.get(key);
2527
- const reactiveValue = debug.reactive(value);
2095
+ const reactiveValue = proxy.reactive(value);
2528
2096
  this.set(key, reactiveValue);
2529
2097
  if (!hadKey || oldValue !== reactiveValue) {
2530
- debug.notifyPropertyChange(debug.contentRef(this), key, oldValue, reactiveValue, hadKey);
2098
+ proxy.notifyPropertyChange(proxy.contentRef(this), key, oldValue, reactiveValue, hadKey);
2531
2099
  }
2532
2100
  return this;
2533
2101
  }
@@ -2539,37 +2107,39 @@ class ReactiveWeakMap extends WeakMap {
2539
2107
  class ReactiveMap extends Map {
2540
2108
  // Implement Map interface methods with reactivity
2541
2109
  get size() {
2542
- debug.dependant(this, 'size'); // The ReactiveMap instance still goes through proxy
2543
- return this.size;
2110
+ proxy.dependant(this, 'size'); // The ReactiveMap instance still goes through proxy
2111
+ return super.size;
2544
2112
  }
2545
2113
  clear() {
2546
2114
  const hadEntries = this.size > 0;
2547
- this.clear();
2115
+ super.clear();
2548
2116
  if (hadEntries) {
2549
2117
  const evolution = { type: 'bunch', method: 'clear' };
2550
2118
  // Clear triggers all effects since all keys are affected
2551
- debug.touched1(this, evolution, 'size');
2552
- debug.touched(debug.contentRef(this), evolution);
2119
+ proxy.batch(() => {
2120
+ proxy.touched1(this, evolution, 'size');
2121
+ proxy.touched(proxy.contentRef(this), evolution);
2122
+ });
2553
2123
  }
2554
2124
  }
2555
2125
  entries() {
2556
- debug.dependant(debug.contentRef(this));
2126
+ proxy.dependant(proxy.contentRef(this));
2557
2127
  return makeReactiveEntriesIterator(this.entries());
2558
2128
  }
2559
2129
  forEach(callbackfn, thisArg) {
2560
- debug.dependant(debug.contentRef(this));
2130
+ proxy.dependant(proxy.contentRef(this));
2561
2131
  this.forEach(callbackfn, thisArg);
2562
2132
  }
2563
2133
  keys() {
2564
- debug.dependant(debug.contentRef(this));
2134
+ proxy.dependant(proxy.contentRef(this), proxy.keysOf);
2565
2135
  return this.keys();
2566
2136
  }
2567
2137
  values() {
2568
- debug.dependant(debug.contentRef(this));
2138
+ proxy.dependant(proxy.contentRef(this));
2569
2139
  return makeReactiveIterator(this.values());
2570
2140
  }
2571
2141
  [Symbol.iterator]() {
2572
- debug.dependant(debug.contentRef(this));
2142
+ proxy.dependant(proxy.contentRef(this));
2573
2143
  const it = Map.prototype[Symbol.iterator].call(this);
2574
2144
  const nativeNext = it.next.bind(it);
2575
2145
  it.next = () => {
@@ -2577,39 +2147,43 @@ class ReactiveMap extends Map {
2577
2147
  if (result.done)
2578
2148
  return result;
2579
2149
  const [key, value] = result.value;
2580
- return { value: [debug.reactive(key), debug.reactive(value)], done: false };
2150
+ return { value: [proxy.reactive(key), proxy.reactive(value)], done: false };
2581
2151
  };
2582
2152
  return it;
2583
2153
  }
2584
2154
  // Implement Map methods with reactivity
2585
2155
  delete(key) {
2586
2156
  const hadKey = this.has(key);
2587
- const result = this.delete(key);
2157
+ const result = super.delete(key);
2588
2158
  if (hadKey) {
2589
2159
  const evolution = { type: 'del', prop: key };
2590
- debug.touched1(debug.contentRef(this), evolution, key);
2591
- debug.touched1(this, evolution, 'size');
2160
+ proxy.batch(() => {
2161
+ proxy.touched1(proxy.contentRef(this), evolution, key);
2162
+ proxy.touched1(this, evolution, 'size');
2163
+ });
2592
2164
  }
2593
2165
  return result;
2594
2166
  }
2595
2167
  get(key) {
2596
- debug.dependant(debug.contentRef(this), key);
2597
- return debug.reactive(this.get(key));
2168
+ proxy.dependant(proxy.contentRef(this), key);
2169
+ return proxy.reactive(super.get(key));
2598
2170
  }
2599
2171
  has(key) {
2600
- debug.dependant(debug.contentRef(this), key);
2601
- return this.has(key);
2172
+ proxy.dependant(proxy.contentRef(this), key);
2173
+ return super.has(key);
2602
2174
  }
2603
2175
  set(key, value) {
2604
2176
  const hadKey = this.has(key);
2605
2177
  const oldValue = this.get(key);
2606
- const reactiveValue = debug.reactive(value);
2607
- this.set(key, reactiveValue);
2178
+ const reactiveValue = proxy.reactive(value);
2179
+ super.set(key, reactiveValue);
2608
2180
  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');
2181
+ proxy.batch(() => {
2182
+ proxy.notifyPropertyChange(proxy.contentRef(this), key, oldValue, reactiveValue, hadKey);
2183
+ // Also notify size change for Map (WeakMap doesn't track size)
2184
+ const evolution = { type: hadKey ? 'set' : 'add', prop: key };
2185
+ proxy.touched1(this, evolution, 'size');
2186
+ });
2613
2187
  }
2614
2188
  return this;
2615
2189
  }
@@ -2622,24 +2196,24 @@ class ReactiveMap extends Map {
2622
2196
  class ReactiveWeakSet extends WeakSet {
2623
2197
  add(value) {
2624
2198
  const had = this.has(value);
2625
- this.add(value);
2199
+ super.add(value);
2626
2200
  if (!had) {
2627
2201
  // touch the specific value and the collection view
2628
- debug.touched1(debug.contentRef(this), { type: 'add', prop: value }, value);
2202
+ proxy.touched1(proxy.contentRef(this), { type: 'add', prop: value }, value);
2629
2203
  // no size/allProps for WeakSet
2630
2204
  }
2631
2205
  return this;
2632
2206
  }
2633
2207
  delete(value) {
2634
2208
  const had = this.has(value);
2635
- const res = this.delete(value);
2209
+ const res = super.delete(value);
2636
2210
  if (had)
2637
- debug.touched1(debug.contentRef(this), { type: 'del', prop: value }, value);
2211
+ proxy.touched1(proxy.contentRef(this), { type: 'del', prop: value }, value);
2638
2212
  return res;
2639
2213
  }
2640
2214
  has(value) {
2641
- debug.dependant(debug.contentRef(this), value);
2642
- return this.has(value);
2215
+ proxy.dependant(proxy.contentRef(this), value);
2216
+ return super.has(value);
2643
2217
  }
2644
2218
  }
2645
2219
  /**
@@ -2649,93 +2223,99 @@ class ReactiveWeakSet extends WeakSet {
2649
2223
  class ReactiveSet extends Set {
2650
2224
  get size() {
2651
2225
  // size depends on the wrapper instance, like Map counterpart
2652
- debug.dependant(this, 'size');
2226
+ proxy.dependant(this, 'size');
2653
2227
  return this.size;
2654
2228
  }
2655
2229
  add(value) {
2656
2230
  const had = this.has(value);
2657
- const reactiveValue = debug.reactive(value);
2658
- this.add(reactiveValue);
2231
+ const reactiveValue = proxy.reactive(value);
2232
+ super.add(reactiveValue);
2659
2233
  if (!had) {
2660
2234
  const evolution = { type: 'add', prop: reactiveValue };
2661
2235
  // touch for value-specific and aggregate dependencies
2662
- debug.touched1(debug.contentRef(this), evolution, reactiveValue);
2663
- debug.touched1(this, evolution, 'size');
2236
+ proxy.batch(() => {
2237
+ proxy.touched1(proxy.contentRef(this), evolution, reactiveValue);
2238
+ proxy.touched1(this, evolution, 'size');
2239
+ });
2664
2240
  }
2665
2241
  return this;
2666
2242
  }
2667
2243
  clear() {
2668
2244
  const hadEntries = this.size > 0;
2669
- this.clear();
2245
+ super.clear();
2670
2246
  if (hadEntries) {
2671
2247
  const evolution = { type: 'bunch', method: 'clear' };
2672
- debug.touched1(this, evolution, 'size');
2673
- debug.touched(debug.contentRef(this), evolution);
2248
+ proxy.batch(() => {
2249
+ proxy.touched1(this, evolution, 'size');
2250
+ proxy.touched(proxy.contentRef(this), evolution);
2251
+ });
2674
2252
  }
2675
2253
  }
2676
2254
  delete(value) {
2677
2255
  const had = this.has(value);
2678
- const res = this.delete(value);
2256
+ const res = super.delete(value);
2679
2257
  if (had) {
2680
2258
  const evolution = { type: 'del', prop: value };
2681
- debug.touched1(debug.contentRef(this), evolution, value);
2682
- debug.touched1(this, evolution, 'size');
2259
+ proxy.batch(() => {
2260
+ proxy.touched1(proxy.contentRef(this), evolution, value);
2261
+ proxy.touched1(this, evolution, 'size');
2262
+ });
2683
2263
  }
2684
2264
  return res;
2685
2265
  }
2686
2266
  has(value) {
2687
- debug.dependant(debug.contentRef(this), value);
2267
+ proxy.dependant(proxy.contentRef(this), value);
2688
2268
  return this.has(value);
2689
2269
  }
2690
2270
  entries() {
2691
- debug.dependant(debug.contentRef(this));
2271
+ proxy.dependant(proxy.contentRef(this));
2692
2272
  return makeReactiveEntriesIterator(this.entries());
2693
2273
  }
2694
2274
  forEach(callbackfn, thisArg) {
2695
- debug.dependant(debug.contentRef(this));
2275
+ proxy.dependant(proxy.contentRef(this));
2696
2276
  this.forEach(callbackfn, thisArg);
2697
2277
  }
2698
2278
  keys() {
2699
- debug.dependant(debug.contentRef(this));
2279
+ proxy.dependant(proxy.contentRef(this));
2700
2280
  return makeReactiveIterator(this.keys());
2701
2281
  }
2702
2282
  values() {
2703
- debug.dependant(debug.contentRef(this));
2283
+ proxy.dependant(proxy.contentRef(this));
2704
2284
  return makeReactiveIterator(this.values());
2705
2285
  }
2706
2286
  [Symbol.iterator]() {
2707
- debug.dependant(debug.contentRef(this));
2287
+ proxy.dependant(proxy.contentRef(this));
2708
2288
  const it = Set.prototype[Symbol.iterator].call(this);
2709
2289
  const nativeNext = it.next.bind(it);
2710
2290
  it.next = () => {
2711
2291
  const result = nativeNext();
2712
2292
  if (result.done)
2713
2293
  return result;
2714
- return { value: debug.reactive(result.value), done: false };
2294
+ return { value: proxy.reactive(result.value), done: false };
2715
2295
  };
2716
2296
  return it;
2717
2297
  }
2718
2298
  }
2719
2299
 
2720
2300
  // 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);
2301
+ proxy.metaProtos.set(Array, ReactiveArray.prototype);
2302
+ proxy.metaProtos.set(Set, ReactiveSet.prototype);
2303
+ proxy.metaProtos.set(WeakSet, ReactiveWeakSet.prototype);
2304
+ proxy.metaProtos.set(Map, ReactiveMap.prototype);
2305
+ proxy.metaProtos.set(WeakMap, ReactiveWeakMap.prototype);
2306
+ proxy.wrapProtos.set(Array, ReactiveArrayWrapper.prototype);
2726
2307
  /**
2727
2308
  * Object containing internal reactive system state for debugging and profiling
2728
2309
  */
2729
2310
  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,
2311
+ objectToProxy: proxy.objectToProxy,
2312
+ proxyToObject: proxy.proxyToObject,
2313
+ effectToReactiveObjects: proxy.effectToReactiveObjects,
2314
+ watchers: proxy.watchers,
2315
+ objectParents: proxy.objectParents,
2316
+ objectsWithDeepWatchers: proxy.objectsWithDeepWatchers,
2317
+ deepWatchers: proxy.deepWatchers,
2318
+ effectToDeepWatchedObjects: proxy.effectToDeepWatchedObjects,
2739
2319
  };
2740
2320
 
2741
2321
  // In order to avoid async re-entrance, we could use zone.js or something like that.
@@ -2744,7 +2324,7 @@ const syncCalculating = [];
2744
2324
  * Decorator that caches the result of a getter method and only recomputes when dependencies change
2745
2325
  * Prevents circular dependencies and provides automatic cache invalidation
2746
2326
  */
2747
- const cached = debug.decorator({
2327
+ const cached = proxy.decorator({
2748
2328
  getter(original, _target, propertyKey) {
2749
2329
  return function () {
2750
2330
  const alreadyCalculating = syncCalculating.findIndex((c) => c.object === this && c.prop === propertyKey);
@@ -2788,7 +2368,7 @@ function cache(object, propertyKey, value) {
2788
2368
  * @param descriptor - The descriptor properties to apply
2789
2369
  * @returns A class decorator that applies the descriptor to specified properties
2790
2370
  */
2791
- const descriptor = debug.flavored(function descriptor(descriptor) {
2371
+ const descriptor = proxy.flavored(function descriptor(descriptor) {
2792
2372
  return (...properties) => (Base) => {
2793
2373
  return class extends Base {
2794
2374
  constructor(...args) {
@@ -2842,7 +2422,7 @@ const descriptor = debug.flavored(function descriptor(descriptor) {
2842
2422
  * Decorator that marks methods, properties, or classes as deprecated
2843
2423
  * Provides warning messages when deprecated items are used
2844
2424
  */
2845
- const deprecated = Object.assign(debug.decorator({
2425
+ const deprecated = Object.assign(proxy.decorator({
2846
2426
  method(original, _target, propertyKey) {
2847
2427
  return function (...args) {
2848
2428
  deprecated.warn(this, propertyKey);
@@ -2870,7 +2450,7 @@ const deprecated = Object.assign(debug.decorator({
2870
2450
  };
2871
2451
  },
2872
2452
  default(message) {
2873
- return debug.decorator({
2453
+ return proxy.decorator({
2874
2454
  method(original, _target, propertyKey) {
2875
2455
  return function (...args) {
2876
2456
  deprecated.warn(this, propertyKey, message);
@@ -2901,8 +2481,7 @@ const deprecated = Object.assign(debug.decorator({
2901
2481
  },
2902
2482
  }), {
2903
2483
  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}` : ''}`);
2484
+ proxy.options.warn(`${target.constructor.name}.${String(propertyKey)} is deprecated${message ? `: ${message}` : ''}`);
2906
2485
  },
2907
2486
  });
2908
2487
  /**
@@ -2911,7 +2490,7 @@ const deprecated = Object.assign(debug.decorator({
2911
2490
  * @returns A method decorator that debounces method calls
2912
2491
  */
2913
2492
  function debounce(delay) {
2914
- return debug.decorator({
2493
+ return proxy.decorator({
2915
2494
  method(original, _target, _propertyKey) {
2916
2495
  let timeoutId = null;
2917
2496
  return function (...args) {
@@ -2934,7 +2513,7 @@ function debounce(delay) {
2934
2513
  * @returns A method decorator that throttles method calls
2935
2514
  */
2936
2515
  function throttle(delay) {
2937
- return debug.decorator({
2516
+ return proxy.decorator({
2938
2517
  method(original, _target, _propertyKey) {
2939
2518
  let lastCallTime = 0;
2940
2519
  let timeoutId = null;
@@ -2965,12 +2544,11 @@ function throttle(delay) {
2965
2544
  });
2966
2545
  }
2967
2546
 
2968
- var version$1 = "1.0.9";
2547
+ var version$1 = "1.0.11";
2969
2548
  var pkg = {
2970
2549
  version: version$1};
2971
2550
 
2972
2551
  const { version } = pkg;
2973
- // Singleton verification
2974
2552
  const GLOBAL_MUTTS_KEY = '__MUTTS_INSTANCE__';
2975
2553
  const globalScope = (typeof globalThis !== 'undefined'
2976
2554
  ? globalThis
@@ -2980,27 +2558,16 @@ const globalScope = (typeof globalThis !== 'undefined'
2980
2558
  ? global
2981
2559
  : false);
2982
2560
  if (globalScope) {
2983
- // Detect the source of this instance safely across different environments
2984
2561
  let source = 'mutts/index';
2985
- const viteEval = eval;
2986
2562
  try {
2987
2563
  if (typeof __filename !== 'undefined')
2988
2564
  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;
2565
+ else if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('browser.cjs', document.baseURI).href)) }) !== 'undefined' && (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('browser.cjs', document.baseURI).href))) {
2566
+ source = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('browser.cjs', document.baseURI).href));
2994
2567
  }
2995
2568
  }
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
- };
2569
+ catch (_e) { }
2570
+ const currentSourceInfo = { version, source, timestamp: Date.now() };
3004
2571
  if (globalScope[GLOBAL_MUTTS_KEY]) {
3005
2572
  const existing = globalScope[GLOBAL_MUTTS_KEY];
3006
2573
  throw new Error(`[Mutts] Multiple instances detected!\n` +
@@ -3013,63 +2580,70 @@ if (globalScope) {
3013
2580
  globalScope[GLOBAL_MUTTS_KEY] = currentSourceInfo;
3014
2581
  }
3015
2582
 
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;
2583
+ exports.AZone = proxy.AZone;
2584
+ exports.DecoratorError = proxy.DecoratorError;
2585
+ exports.IterableWeakMap = proxy.IterableWeakMap;
2586
+ exports.IterableWeakSet = proxy.IterableWeakSet;
2587
+ exports.ReactiveBase = proxy.ReactiveBase;
2588
+ exports.ReactiveError = proxy.ReactiveError;
3023
2589
  Object.defineProperty(exports, "ReactiveErrorCode", {
3024
2590
  enumerable: true,
3025
- get: function () { return debug.ReactiveErrorCode; }
2591
+ get: function () { return proxy.ReactiveErrorCode; }
3026
2592
  });
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;
2593
+ exports.Zone = proxy.Zone;
2594
+ exports.ZoneAggregator = proxy.ZoneAggregator;
2595
+ exports.ZoneHistory = proxy.ZoneHistory;
2596
+ exports.addBatchCleanup = proxy.addBatchCleanup;
2597
+ exports.addUnreactiveProps = proxy.addUnreactiveProps;
2598
+ exports.arrayEquals = proxy.arrayEquals;
2599
+ exports.assertUntracked = proxy.assertUntracked;
2600
+ exports.asyncZone = proxy.asyncZone;
2601
+ exports.atom = proxy.atom;
2602
+ exports.atomic = proxy.atomic;
2603
+ exports.biDi = proxy.biDi;
2604
+ exports.captured = proxy.captured;
2605
+ exports.caught = proxy.caught;
2606
+ exports.createFlavor = proxy.createFlavor;
2607
+ exports.debugPreset = proxy.debugPreset;
2608
+ exports.decorator = proxy.decorator;
2609
+ exports.deepCompare = proxy.deepCompare;
2610
+ exports.defer = proxy.defer;
2611
+ exports.devPreset = proxy.devPreset;
2612
+ exports.effect = proxy.effect;
2613
+ exports.effectAggregator = proxy.effectAggregator;
2614
+ exports.flavorOptions = proxy.flavorOptions;
2615
+ exports.flavored = proxy.flavored;
2616
+ exports.formatCleanupReason = proxy.formatCleanupReason;
2617
+ exports.getActivationLog = proxy.getActivationLog;
2618
+ exports.getActiveEffect = proxy.getActiveEffect;
2619
+ exports.getState = proxy.getState;
2620
+ exports.isConstructor = proxy.isConstructor;
2621
+ exports.isDev = proxy.isDev;
2622
+ exports.isNonReactive = proxy.isNonReactive;
2623
+ exports.isObject = proxy.isObject;
2624
+ exports.isProd = proxy.isProd;
2625
+ exports.isReactive = proxy.isReactive;
2626
+ exports.isTest = proxy.isTest;
2627
+ exports.legacyDecorator = proxy.legacyDecorator;
2628
+ exports.link = proxy.link;
2629
+ exports.mixin = proxy.mixin;
2630
+ exports.modernDecorator = proxy.modernDecorator;
2631
+ exports.named = proxy.named;
2632
+ exports.objectToProxy = proxy.objectToProxy;
2633
+ exports.onEffectThrow = proxy.onEffectThrow;
2634
+ exports.prodPreset = proxy.prodPreset;
2635
+ exports.proxyToObject = proxy.proxyToObject;
2636
+ exports.reactive = proxy.reactive;
2637
+ exports.reactiveOptions = proxy.options;
2638
+ exports.reset = proxy.reset;
2639
+ exports.root = proxy.root;
2640
+ exports.tag = proxy.tag;
2641
+ exports.touched = proxy.touched;
2642
+ exports.touched1 = proxy.touched1;
2643
+ exports.unlink = proxy.unlink;
2644
+ exports.untracked = proxy.untracked;
2645
+ exports.unwrap = proxy.unwrap;
2646
+ exports.zip = proxy.zip;
3073
2647
  exports.asyncHook = asyncCore.asyncHook;
3074
2648
  exports.asyncHooks = asyncCore.asyncHooks;
3075
2649
  exports.hooks = asyncCore.hooks;
@@ -3078,9 +2652,9 @@ exports.Destroyable = Destroyable;
3078
2652
  exports.DestructionError = DestructionError;
3079
2653
  exports.Eventful = Eventful;
3080
2654
  exports.Indexable = Indexable;
3081
- exports.Register = Register;
3082
2655
  exports.allocated = allocated;
3083
2656
  exports.allocatedValues = allocatedValues;
2657
+ exports.arrayDiff = arrayDiff;
3084
2658
  exports.attend = attend;
3085
2659
  exports.cache = cache;
3086
2660
  exports.cached = cached;
@@ -3089,23 +2663,22 @@ exports.chainPromise = chainPromise;
3089
2663
  exports.debounce = debounce;
3090
2664
  exports.deepWatch = deepWatch;
3091
2665
  exports.deprecated = deprecated;
3092
- exports.describe = describe;
3093
2666
  exports.descriptor = descriptor;
3094
2667
  exports.destructor = destructor;
3095
2668
  exports.forwardArray = forwardArray;
3096
- exports.getActiveProjection = getActiveProjection;
3097
2669
  exports.getAt = getAt;
3098
2670
  exports.isCached = isCached;
3099
2671
  exports.lift = lift;
3100
2672
  exports.memoize = memoize;
2673
+ exports.morph = morph;
3101
2674
  exports.organize = organize;
3102
2675
  exports.organized = organized;
3103
2676
  exports.profileInfo = profileInfo;
3104
- exports.project = project;
3105
- exports.register = register;
3106
- exports.scan = scan;
2677
+ exports.project = morph;
2678
+ exports.resource = resource;
3107
2679
  exports.setAt = setAt;
3108
2680
  exports.throttle = throttle;
3109
2681
  exports.unreactive = unreactive;
3110
2682
  exports.watch = watch;
2683
+ exports.when = when;
3111
2684
  //# sourceMappingURL=browser.cjs.map