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