@solidjs/signals 2.0.0-beta.14 → 2.0.0-beta.16
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 +2 -3
- package/dist/dev.js +966 -550
- package/dist/node.cjs +2153 -1821
- package/dist/prod.js +1848 -1530
- package/dist/types/boundaries.d.ts +3 -3
- package/dist/types/core/async.d.ts +1 -0
- package/dist/types/core/core.d.ts +27 -15
- package/dist/types/core/dev.d.ts +10 -2
- package/dist/types/core/effect.d.ts +1 -3
- package/dist/types/core/graph.d.ts +1 -1
- package/dist/types/core/index.d.ts +2 -2
- package/dist/types/core/invariants.d.ts +49 -0
- package/dist/types/core/scheduler.d.ts +8 -0
- package/dist/types/core/types.d.ts +19 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/signals.d.ts +39 -2
- package/dist/types/store/projection.d.ts +4 -4
- package/dist/types/store/store.d.ts +29 -1
- package/dist/types-cjs/boundaries.d.cts +3 -3
- package/dist/types-cjs/core/async.d.cts +1 -0
- package/dist/types-cjs/core/core.d.cts +27 -15
- package/dist/types-cjs/core/dev.d.cts +10 -2
- package/dist/types-cjs/core/effect.d.cts +1 -3
- package/dist/types-cjs/core/graph.d.cts +1 -1
- package/dist/types-cjs/core/index.d.cts +2 -2
- package/dist/types-cjs/core/invariants.d.cts +49 -0
- package/dist/types-cjs/core/scheduler.d.cts +8 -0
- package/dist/types-cjs/core/types.d.cts +19 -0
- package/dist/types-cjs/index.d.cts +1 -1
- package/dist/types-cjs/signals.d.cts +39 -2
- package/dist/types-cjs/store/projection.d.cts +4 -4
- package/dist/types-cjs/store/store.d.cts +29 -1
- package/package.json +1 -1
- package/dist/types/src/boundaries.d.ts +0 -173
- package/dist/types/src/core/action.d.ts +0 -35
- package/dist/types/src/core/async.d.ts +0 -6
- package/dist/types/src/core/constants.d.ts +0 -51
- package/dist/types/src/core/context.d.ts +0 -36
- package/dist/types/src/core/core.d.ts +0 -174
- package/dist/types/src/core/dev.d.ts +0 -49
- package/dist/types/src/core/effect.d.ts +0 -32
- package/dist/types/src/core/error.d.ts +0 -38
- package/dist/types/src/core/external.d.ts +0 -45
- package/dist/types/src/core/graph.d.ts +0 -5
- package/dist/types/src/core/heap.d.ts +0 -14
- package/dist/types/src/core/index.d.ts +0 -12
- package/dist/types/src/core/lanes.d.ts +0 -54
- package/dist/types/src/core/owner.d.ts +0 -116
- package/dist/types/src/core/scheduler.d.ts +0 -122
- package/dist/types/src/core/types.d.ts +0 -85
- package/dist/types/src/index.d.ts +0 -9
- package/dist/types/src/map.d.ts +0 -53
- package/dist/types/src/signals.d.ts +0 -512
- package/dist/types/src/store/index.d.ts +0 -9
- package/dist/types/src/store/optimistic.d.ts +0 -45
- package/dist/types/src/store/projection.d.ts +0 -66
- package/dist/types/src/store/reconcile.d.ts +0 -23
- package/dist/types/src/store/store.d.ts +0 -125
- package/dist/types/src/store/storePath.d.ts +0 -58
- package/dist/types/src/store/utils.d.ts +0 -114
- package/dist/types-cjs/src/boundaries.d.cts +0 -173
- package/dist/types-cjs/src/core/action.d.cts +0 -35
- package/dist/types-cjs/src/core/async.d.cts +0 -6
- package/dist/types-cjs/src/core/constants.d.cts +0 -51
- package/dist/types-cjs/src/core/context.d.cts +0 -36
- package/dist/types-cjs/src/core/core.d.cts +0 -174
- package/dist/types-cjs/src/core/dev.d.cts +0 -49
- package/dist/types-cjs/src/core/effect.d.cts +0 -32
- package/dist/types-cjs/src/core/error.d.cts +0 -38
- package/dist/types-cjs/src/core/external.d.cts +0 -45
- package/dist/types-cjs/src/core/graph.d.cts +0 -5
- package/dist/types-cjs/src/core/heap.d.cts +0 -14
- package/dist/types-cjs/src/core/index.d.cts +0 -12
- package/dist/types-cjs/src/core/lanes.d.cts +0 -54
- package/dist/types-cjs/src/core/owner.d.cts +0 -116
- package/dist/types-cjs/src/core/scheduler.d.cts +0 -122
- package/dist/types-cjs/src/core/types.d.cts +0 -85
- package/dist/types-cjs/src/index.d.cts +0 -9
- package/dist/types-cjs/src/map.d.cts +0 -53
- package/dist/types-cjs/src/signals.d.cts +0 -512
- package/dist/types-cjs/src/store/index.d.cts +0 -9
- package/dist/types-cjs/src/store/optimistic.d.cts +0 -45
- package/dist/types-cjs/src/store/projection.d.cts +0 -66
- package/dist/types-cjs/src/store/reconcile.d.cts +0 -23
- package/dist/types-cjs/src/store/store.d.cts +0 -125
- package/dist/types-cjs/src/store/storePath.d.cts +0 -58
- package/dist/types-cjs/src/store/utils.d.cts +0 -114
package/dist/dev.js
CHANGED
|
@@ -140,106 +140,21 @@ function getObservers(node) {
|
|
|
140
140
|
}
|
|
141
141
|
return observers;
|
|
142
142
|
}
|
|
143
|
-
function
|
|
144
|
-
|
|
145
|
-
(n._parent?._root ? n._parent._parentComputed?._height : n._parent?._height) ?? -1;
|
|
146
|
-
if (parentHeight >= n._height) n._height = parentHeight + 1;
|
|
147
|
-
const height = n._height;
|
|
148
|
-
const heapAtHeight = heap._heap[height];
|
|
149
|
-
if (heapAtHeight === undefined) heap._heap[height] = n;
|
|
150
|
-
else {
|
|
151
|
-
const tail = heapAtHeight._prevHeap;
|
|
152
|
-
tail._nextHeap = n;
|
|
153
|
-
n._prevHeap = tail;
|
|
154
|
-
heapAtHeight._prevHeap = n;
|
|
155
|
-
}
|
|
156
|
-
if (height > heap._max) heap._max = height;
|
|
157
|
-
}
|
|
158
|
-
function insertIntoHeap(n, heap) {
|
|
159
|
-
let flags = n._flags;
|
|
160
|
-
if (flags & (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_MANUAL_WRITE)) return;
|
|
161
|
-
if (flags & REACTIVE_CHECK) {
|
|
162
|
-
n._flags = (flags & -4) | REACTIVE_DIRTY | REACTIVE_IN_HEAP;
|
|
163
|
-
} else n._flags = flags | REACTIVE_IN_HEAP;
|
|
164
|
-
if (!(flags & REACTIVE_IN_HEAP_HEIGHT)) actualInsertIntoHeap(n, heap);
|
|
143
|
+
function createAsyncReporters() {
|
|
144
|
+
return new Map();
|
|
165
145
|
}
|
|
166
|
-
function
|
|
167
|
-
|
|
168
|
-
if (
|
|
169
|
-
flags &
|
|
170
|
-
(REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_IN_HEAP_HEIGHT | REACTIVE_MANUAL_WRITE)
|
|
171
|
-
)
|
|
172
|
-
return;
|
|
173
|
-
n._flags = flags | REACTIVE_IN_HEAP_HEIGHT;
|
|
174
|
-
actualInsertIntoHeap(n, heap);
|
|
146
|
+
function devCheckActiveOverrides(isRegisteredForRevert) {
|
|
147
|
+
return;
|
|
175
148
|
}
|
|
176
|
-
function
|
|
177
|
-
|
|
178
|
-
if (!(flags & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
|
|
179
|
-
n._flags = flags & -25;
|
|
180
|
-
const height = n._height;
|
|
181
|
-
if (n._prevHeap === n) heap._heap[height] = undefined;
|
|
182
|
-
else {
|
|
183
|
-
const next = n._nextHeap;
|
|
184
|
-
const dhh = heap._heap[height];
|
|
185
|
-
const end = next ?? dhh;
|
|
186
|
-
if (n === dhh) heap._heap[height] = next;
|
|
187
|
-
else n._prevHeap._nextHeap = next;
|
|
188
|
-
end._prevHeap = n._prevHeap;
|
|
189
|
-
}
|
|
190
|
-
n._prevHeap = n;
|
|
191
|
-
n._nextHeap = undefined;
|
|
192
|
-
}
|
|
193
|
-
function markHeap(heap) {
|
|
194
|
-
if (heap._marked) return;
|
|
195
|
-
heap._marked = true;
|
|
196
|
-
for (let i = 0; i <= heap._max; i++) {
|
|
197
|
-
for (let el = heap._heap[i]; el !== undefined; el = el._nextHeap) {
|
|
198
|
-
if (el._flags & REACTIVE_IN_HEAP) markNode(el);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function markNode(el, newState = REACTIVE_DIRTY) {
|
|
203
|
-
const flags = el._flags;
|
|
204
|
-
if ((flags & (REACTIVE_CHECK | REACTIVE_DIRTY)) >= newState) return;
|
|
205
|
-
el._flags = (flags & -4) | newState;
|
|
206
|
-
for (let link = el._subs; link !== null; link = link._nextSub) {
|
|
207
|
-
markNode(link._sub, REACTIVE_CHECK);
|
|
208
|
-
}
|
|
209
|
-
if (el._child !== null) {
|
|
210
|
-
for (let child = el._child; child !== null; child = child._nextChild) {
|
|
211
|
-
for (let link = child._subs; link !== null; link = link._nextSub) {
|
|
212
|
-
markNode(link._sub, REACTIVE_CHECK);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
149
|
+
function devCheckFlushStart() {
|
|
150
|
+
return;
|
|
216
151
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
let el = heap._heap[heap._min];
|
|
221
|
-
while (el !== undefined) {
|
|
222
|
-
if (el._flags & REACTIVE_IN_HEAP) recompute(el);
|
|
223
|
-
else adjustHeight(el, heap);
|
|
224
|
-
el = heap._heap[heap._min];
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
heap._max = 0;
|
|
152
|
+
typeof globalThis !== "undefined" && !!globalThis.process?.env?.COMPANION_CENSUS;
|
|
153
|
+
function devCensusCompanions(isQueuedForCommit) {
|
|
154
|
+
return;
|
|
228
155
|
}
|
|
229
|
-
function
|
|
230
|
-
|
|
231
|
-
let newHeight = el._height;
|
|
232
|
-
for (let d = el._deps; d; d = d._nextDep) {
|
|
233
|
-
const dep1 = d._dep;
|
|
234
|
-
const dep = dep1._firewall || dep1;
|
|
235
|
-
if (dep._fn && dep._height >= newHeight) newHeight = dep._height + 1;
|
|
236
|
-
}
|
|
237
|
-
if (el._height !== newHeight) {
|
|
238
|
-
el._height = newHeight;
|
|
239
|
-
for (let s = el._subs; s !== null; s = s._nextSub) {
|
|
240
|
-
insertIntoHeapHeight(s._sub, heap);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
156
|
+
function devCheckQuiescent(isQueuedForCommit) {
|
|
157
|
+
return;
|
|
243
158
|
}
|
|
244
159
|
const signalLanes = new WeakMap();
|
|
245
160
|
const activeLanes = new Set();
|
|
@@ -260,7 +175,6 @@ function getOrCreateLane(signal) {
|
|
|
260
175
|
};
|
|
261
176
|
signalLanes.set(signal, lane);
|
|
262
177
|
activeLanes.add(lane);
|
|
263
|
-
signal._overrideSinceLane = false;
|
|
264
178
|
return lane;
|
|
265
179
|
}
|
|
266
180
|
function findLane(lane) {
|
|
@@ -273,8 +187,11 @@ function mergeLanes(lane1, lane2) {
|
|
|
273
187
|
if (lane1 === lane2) return lane1;
|
|
274
188
|
lane2._mergedInto = lane1;
|
|
275
189
|
for (const node of lane2._pendingAsync) lane1._pendingAsync.add(node);
|
|
190
|
+
lane2._pendingAsync.clear();
|
|
276
191
|
lane1._effectQueues[0].push(...lane2._effectQueues[0]);
|
|
277
192
|
lane1._effectQueues[1].push(...lane2._effectQueues[1]);
|
|
193
|
+
lane2._effectQueues[0].length = 0;
|
|
194
|
+
lane2._effectQueues[1].length = 0;
|
|
278
195
|
return lane1;
|
|
279
196
|
}
|
|
280
197
|
function resolveLane(el) {
|
|
@@ -318,6 +235,8 @@ const zombieQueue = { _heap: new Array(2e3).fill(undefined), _marked: false, _mi
|
|
|
318
235
|
let clock = 0;
|
|
319
236
|
let activeTransition = null;
|
|
320
237
|
let scheduled = false;
|
|
238
|
+
let halted = false;
|
|
239
|
+
let haltNotified = false;
|
|
321
240
|
let syncDepth = 0;
|
|
322
241
|
let projectionWriteActive = false;
|
|
323
242
|
let inTrackedQueueCallback = false;
|
|
@@ -406,19 +325,24 @@ function mergeTransitionState(target, outgoing) {
|
|
|
406
325
|
for (const sub of outgoing._gatedSubs) target._gatedSubs.add(sub);
|
|
407
326
|
}
|
|
408
327
|
function resolveOptimisticNodes(nodes) {
|
|
409
|
-
|
|
328
|
+
const len = nodes.length;
|
|
329
|
+
for (let i = 0; i < len; i++) {
|
|
410
330
|
const node = nodes[i];
|
|
411
331
|
node._optimisticLane = undefined;
|
|
412
|
-
if (node.
|
|
413
|
-
node._value = node._pendingValue;
|
|
414
|
-
node._pendingValue = NOT_PENDING;
|
|
415
|
-
}
|
|
332
|
+
if (!(node._statusFlags & STATUS_PENDING)) node._statusFlags &= ~STATUS_UNINITIALIZED;
|
|
416
333
|
const prevOverride = node._overrideValue;
|
|
417
334
|
node._overrideValue = NOT_PENDING;
|
|
418
335
|
if (prevOverride !== NOT_PENDING && node._value !== prevOverride) insertSubs(node, true);
|
|
419
336
|
node._transition = null;
|
|
420
337
|
}
|
|
421
|
-
|
|
338
|
+
for (let i = 0; i < len; i++) {
|
|
339
|
+
const node = nodes[i];
|
|
340
|
+
if (node._pendingSignal || node._latestValueComputed) snapCompanionsToState(node);
|
|
341
|
+
const owner = node._parentSource;
|
|
342
|
+
if (owner && (owner._pendingSignal === node || owner._latestValueComputed === node))
|
|
343
|
+
snapCompanionsToState(owner);
|
|
344
|
+
}
|
|
345
|
+
nodes.splice(0, len);
|
|
422
346
|
}
|
|
423
347
|
function cleanupCompletedLanes(completingTransition) {
|
|
424
348
|
for (const lane of activeLanes) {
|
|
@@ -439,10 +363,41 @@ function cleanupCompletedLanes(completingTransition) {
|
|
|
439
363
|
}
|
|
440
364
|
}
|
|
441
365
|
function schedule() {
|
|
366
|
+
if (halted) {
|
|
367
|
+
notifyHalted();
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
442
370
|
if (scheduled) return;
|
|
443
371
|
scheduled = true;
|
|
444
372
|
if (!syncDepth && !globalQueue._running && !projectionWriteActive) queueMicrotask(flush);
|
|
445
373
|
}
|
|
374
|
+
function haltReactivity() {
|
|
375
|
+
if (halted) return;
|
|
376
|
+
halted = true;
|
|
377
|
+
let message = "[REACTIVITY_HALTED] An uncaught error halted the reactive system.";
|
|
378
|
+
{
|
|
379
|
+
message +=
|
|
380
|
+
" No further updates will be processed. Handle errors with createErrorBoundary/<Errored> or treat this as a crash.";
|
|
381
|
+
emitDiagnostic({
|
|
382
|
+
code: "REACTIVITY_HALTED",
|
|
383
|
+
kind: "error",
|
|
384
|
+
severity: "error",
|
|
385
|
+
message: message
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
console.error(message);
|
|
389
|
+
}
|
|
390
|
+
function notifyHalted() {
|
|
391
|
+
if (haltNotified) return;
|
|
392
|
+
haltNotified = true;
|
|
393
|
+
console.error(
|
|
394
|
+
"[REACTIVITY_HALTED] Update ignored: the reactive system was halted by an earlier uncaught error."
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
function resetErrorHalt() {
|
|
398
|
+
halted = false;
|
|
399
|
+
haltNotified = false;
|
|
400
|
+
}
|
|
446
401
|
class Queue {
|
|
447
402
|
_parent = null;
|
|
448
403
|
_queues = [[], []];
|
|
@@ -520,6 +475,7 @@ class GlobalQueue extends Queue {
|
|
|
520
475
|
if (this._running) return;
|
|
521
476
|
this._running = true;
|
|
522
477
|
try {
|
|
478
|
+
if (true) devCheckFlushStart();
|
|
523
479
|
runHeap(dirtyQueue, GlobalQueue._update);
|
|
524
480
|
if (activeTransition) {
|
|
525
481
|
const isComplete = transitionComplete(activeTransition);
|
|
@@ -583,6 +539,24 @@ class GlobalQueue extends Queue {
|
|
|
583
539
|
this.run(EFFECT_RENDER);
|
|
584
540
|
activeLanes.size && runLaneEffects(EFFECT_USER);
|
|
585
541
|
this.run(EFFECT_USER);
|
|
542
|
+
if (true) {
|
|
543
|
+
devCheckActiveOverrides(n => {
|
|
544
|
+
if (this._optimisticNodes.includes(n)) return true;
|
|
545
|
+
if (activeTransition?._optimisticNodes.includes(n)) return true;
|
|
546
|
+
for (const t of transitions) if (t._optimisticNodes.includes(n)) return true;
|
|
547
|
+
return false;
|
|
548
|
+
});
|
|
549
|
+
devCensusCompanions(n => n === this._pendingNode || this._pendingNodes.includes(n));
|
|
550
|
+
}
|
|
551
|
+
if (
|
|
552
|
+
true &&
|
|
553
|
+
!scheduled &&
|
|
554
|
+
!activeTransition &&
|
|
555
|
+
transitions.size === 0 &&
|
|
556
|
+
activeLanes.size === 0
|
|
557
|
+
) {
|
|
558
|
+
devCheckQuiescent(n => n === this._pendingNode || this._pendingNodes.includes(n));
|
|
559
|
+
}
|
|
586
560
|
if (true) DEV$1.hooks.onUpdate?.();
|
|
587
561
|
} finally {
|
|
588
562
|
this._running = false;
|
|
@@ -614,7 +588,7 @@ class GlobalQueue extends Queue {
|
|
|
614
588
|
activeTransition = transition ?? {
|
|
615
589
|
_time: clock,
|
|
616
590
|
_pendingNodes: [],
|
|
617
|
-
_asyncReporters:
|
|
591
|
+
_asyncReporters: createAsyncReporters(),
|
|
618
592
|
_optimisticNodes: [],
|
|
619
593
|
_optimisticStores: new Set(),
|
|
620
594
|
_actions: [],
|
|
@@ -710,6 +684,7 @@ function commitPendingNode(n) {
|
|
|
710
684
|
n._value = n._pendingValue;
|
|
711
685
|
n._pendingValue = NOT_PENDING;
|
|
712
686
|
}
|
|
687
|
+
if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
|
|
713
688
|
return;
|
|
714
689
|
}
|
|
715
690
|
if (n._pendingValue !== NOT_PENDING) {
|
|
@@ -721,6 +696,7 @@ function commitPendingNode(n) {
|
|
|
721
696
|
if (!(c._statusFlags & STATUS_PENDING)) c._statusFlags &= ~STATUS_UNINITIALIZED;
|
|
722
697
|
if (c._pendingFirstChild !== null || c._pendingDisposal !== null)
|
|
723
698
|
GlobalQueue._dispose(c, false, true);
|
|
699
|
+
if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
|
|
724
700
|
}
|
|
725
701
|
function commitPendingNodes() {
|
|
726
702
|
if (globalQueue._pendingNode !== null) {
|
|
@@ -796,8 +772,11 @@ function flush(fn) {
|
|
|
796
772
|
try {
|
|
797
773
|
return fn();
|
|
798
774
|
} finally {
|
|
799
|
-
|
|
800
|
-
|
|
775
|
+
try {
|
|
776
|
+
flush();
|
|
777
|
+
} finally {
|
|
778
|
+
syncDepth--;
|
|
779
|
+
}
|
|
801
780
|
}
|
|
802
781
|
}
|
|
803
782
|
if (globalQueue._running) {
|
|
@@ -808,6 +787,7 @@ function flush(fn) {
|
|
|
808
787
|
}
|
|
809
788
|
return;
|
|
810
789
|
}
|
|
790
|
+
if (halted) return;
|
|
811
791
|
let count = 0;
|
|
812
792
|
while (scheduled || activeTransition) {
|
|
813
793
|
if (++count === 1e5) throw new Error("Potential Infinite Loop Detected.");
|
|
@@ -859,8 +839,7 @@ function transitionComplete(transition) {
|
|
|
859
839
|
hasActiveOverride(node) &&
|
|
860
840
|
"_statusFlags" in node &&
|
|
861
841
|
node._statusFlags & STATUS_PENDING &&
|
|
862
|
-
node._error instanceof NotReadyError
|
|
863
|
-
node._error.source !== node
|
|
842
|
+
node._error instanceof NotReadyError
|
|
864
843
|
) {
|
|
865
844
|
done = false;
|
|
866
845
|
break;
|
|
@@ -886,24 +865,127 @@ function runInTransition(transition, fn) {
|
|
|
886
865
|
activeTransition = prevTransition;
|
|
887
866
|
}
|
|
888
867
|
}
|
|
868
|
+
function actualInsertIntoHeap(n, heap) {
|
|
869
|
+
const parentHeight =
|
|
870
|
+
(n._parent?._root ? n._parent._parentComputed?._height : n._parent?._height) ?? -1;
|
|
871
|
+
if (parentHeight >= n._height) n._height = parentHeight + 1;
|
|
872
|
+
const height = n._height;
|
|
873
|
+
const heapAtHeight = heap._heap[height];
|
|
874
|
+
if (heapAtHeight === undefined) heap._heap[height] = n;
|
|
875
|
+
else {
|
|
876
|
+
const tail = heapAtHeight._prevHeap;
|
|
877
|
+
tail._nextHeap = n;
|
|
878
|
+
n._prevHeap = tail;
|
|
879
|
+
heapAtHeight._prevHeap = n;
|
|
880
|
+
}
|
|
881
|
+
if (height > heap._max) heap._max = height;
|
|
882
|
+
}
|
|
883
|
+
function insertIntoHeap(n, heap) {
|
|
884
|
+
let flags = n._flags;
|
|
885
|
+
if (flags & (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_MANUAL_WRITE)) return;
|
|
886
|
+
if (flags & REACTIVE_CHECK) {
|
|
887
|
+
n._flags = (flags & -4) | REACTIVE_DIRTY | REACTIVE_IN_HEAP;
|
|
888
|
+
} else n._flags = flags | REACTIVE_IN_HEAP;
|
|
889
|
+
if (!(flags & REACTIVE_IN_HEAP_HEIGHT)) actualInsertIntoHeap(n, heap);
|
|
890
|
+
}
|
|
891
|
+
function insertIntoHeapHeight(n, heap) {
|
|
892
|
+
let flags = n._flags;
|
|
893
|
+
if (
|
|
894
|
+
flags &
|
|
895
|
+
(REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_IN_HEAP_HEIGHT | REACTIVE_MANUAL_WRITE)
|
|
896
|
+
)
|
|
897
|
+
return;
|
|
898
|
+
n._flags = flags | REACTIVE_IN_HEAP_HEIGHT;
|
|
899
|
+
actualInsertIntoHeap(n, heap);
|
|
900
|
+
}
|
|
901
|
+
function deleteFromHeap(n, heap) {
|
|
902
|
+
const flags = n._flags;
|
|
903
|
+
if (!(flags & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
|
|
904
|
+
n._flags = flags & -25;
|
|
905
|
+
const height = n._height;
|
|
906
|
+
if (n._prevHeap === n) heap._heap[height] = undefined;
|
|
907
|
+
else {
|
|
908
|
+
const next = n._nextHeap;
|
|
909
|
+
const dhh = heap._heap[height];
|
|
910
|
+
const end = next ?? dhh;
|
|
911
|
+
if (n === dhh) heap._heap[height] = next;
|
|
912
|
+
else n._prevHeap._nextHeap = next;
|
|
913
|
+
end._prevHeap = n._prevHeap;
|
|
914
|
+
}
|
|
915
|
+
n._prevHeap = n;
|
|
916
|
+
n._nextHeap = undefined;
|
|
917
|
+
}
|
|
918
|
+
function markHeap(heap) {
|
|
919
|
+
if (heap._marked) return;
|
|
920
|
+
heap._marked = true;
|
|
921
|
+
for (let i = 0; i <= heap._max; i++) {
|
|
922
|
+
for (let el = heap._heap[i]; el !== undefined; el = el._nextHeap) {
|
|
923
|
+
if (el._flags & REACTIVE_IN_HEAP) markNode(el);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
function markNode(el, newState = REACTIVE_DIRTY) {
|
|
928
|
+
const flags = el._flags;
|
|
929
|
+
if ((flags & (REACTIVE_CHECK | REACTIVE_DIRTY)) >= newState) return;
|
|
930
|
+
el._flags = (flags & -4) | newState;
|
|
931
|
+
for (let link = el._subs; link !== null; link = link._nextSub) {
|
|
932
|
+
markNode(link._sub, REACTIVE_CHECK);
|
|
933
|
+
}
|
|
934
|
+
if (el._child !== null) {
|
|
935
|
+
for (let child = el._child; child !== null; child = child._nextChild) {
|
|
936
|
+
for (let link = child._subs; link !== null; link = link._nextSub) {
|
|
937
|
+
markNode(link._sub, REACTIVE_CHECK);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
function runHeap(heap, recompute) {
|
|
943
|
+
heap._marked = false;
|
|
944
|
+
for (heap._min = 0; heap._min <= heap._max; heap._min++) {
|
|
945
|
+
let el = heap._heap[heap._min];
|
|
946
|
+
while (el !== undefined) {
|
|
947
|
+
if (el._flags & REACTIVE_IN_HEAP) recompute(el);
|
|
948
|
+
else adjustHeight(el, heap);
|
|
949
|
+
el = heap._heap[heap._min];
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
heap._max = 0;
|
|
953
|
+
}
|
|
954
|
+
function adjustHeight(el, heap) {
|
|
955
|
+
deleteFromHeap(el, heap);
|
|
956
|
+
let newHeight = el._height;
|
|
957
|
+
for (let d = el._deps; d; d = d._nextDep) {
|
|
958
|
+
const dep1 = d._dep;
|
|
959
|
+
const dep = dep1._firewall || dep1;
|
|
960
|
+
if (dep._fn && dep._height >= newHeight) newHeight = dep._height + 1;
|
|
961
|
+
}
|
|
962
|
+
if (el._height !== newHeight) {
|
|
963
|
+
el._height = newHeight;
|
|
964
|
+
for (let s = el._subs; s !== null; s = s._nextSub) {
|
|
965
|
+
insertIntoHeapHeight(s._sub, s._sub._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
889
969
|
const PENDING_OWNER = {};
|
|
890
970
|
function markDisposal(el) {
|
|
891
971
|
let child = el._firstChild;
|
|
892
972
|
while (child) {
|
|
893
|
-
child._flags
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
973
|
+
const flags = child._flags;
|
|
974
|
+
child._flags = flags | REACTIVE_ZOMBIE;
|
|
975
|
+
if (flags & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT)) {
|
|
976
|
+
deleteFromHeap(child, flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
977
|
+
if (flags & REACTIVE_IN_HEAP) insertIntoHeap(child, zombieQueue);
|
|
978
|
+
else insertIntoHeapHeight(child, zombieQueue);
|
|
897
979
|
}
|
|
898
980
|
markDisposal(child);
|
|
899
981
|
child = child._nextSibling;
|
|
900
982
|
}
|
|
901
983
|
}
|
|
902
984
|
function dispose(node) {
|
|
903
|
-
let toRemove = node._deps
|
|
904
|
-
|
|
985
|
+
let toRemove = node._deps;
|
|
986
|
+
while (toRemove !== null) {
|
|
905
987
|
toRemove = unlinkSubs(toRemove);
|
|
906
|
-
}
|
|
988
|
+
}
|
|
907
989
|
node._deps = null;
|
|
908
990
|
node._depsTail = null;
|
|
909
991
|
disposeChildren(node, true);
|
|
@@ -911,7 +993,11 @@ function dispose(node) {
|
|
|
911
993
|
function disposeChildren(node, self = false, zombie) {
|
|
912
994
|
const flags = node._flags;
|
|
913
995
|
if (flags & REACTIVE_DISPOSED) return;
|
|
914
|
-
if (self)
|
|
996
|
+
if (self) {
|
|
997
|
+
node._flags = flags | REACTIVE_DISPOSED;
|
|
998
|
+
const n = node;
|
|
999
|
+
if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
|
|
1000
|
+
}
|
|
915
1001
|
if (self && true) clearSignals(node);
|
|
916
1002
|
if (self && node._fn) node._inFlight = null;
|
|
917
1003
|
let child = zombie ? node._pendingFirstChild : node._firstChild;
|
|
@@ -951,6 +1037,11 @@ function disposeChildren(node, self = false, zombie) {
|
|
|
951
1037
|
node._prevSibling = null;
|
|
952
1038
|
}
|
|
953
1039
|
runDisposal(node, zombie);
|
|
1040
|
+
if (self && node._cleanup) {
|
|
1041
|
+
const effectCleanup = node._cleanup;
|
|
1042
|
+
node._cleanup = undefined;
|
|
1043
|
+
effectCleanup();
|
|
1044
|
+
}
|
|
954
1045
|
}
|
|
955
1046
|
function runDisposal(node, zombie) {
|
|
956
1047
|
let disposal = zombie ? node._pendingDisposal : node._disposal;
|
|
@@ -1092,42 +1183,49 @@ function unobserved(el) {
|
|
|
1092
1183
|
el._depsTail = null;
|
|
1093
1184
|
disposeChildren(el, true);
|
|
1094
1185
|
}
|
|
1095
|
-
function link(dep, sub) {
|
|
1186
|
+
function link(dep, sub, pendingObserver = false) {
|
|
1096
1187
|
const prevDep = sub._depsTail;
|
|
1097
|
-
if (prevDep !== null && prevDep._dep === dep)
|
|
1188
|
+
if (prevDep !== null && prevDep._dep === dep) {
|
|
1189
|
+
prevDep._pendingObserver = pendingObserver;
|
|
1190
|
+
return;
|
|
1191
|
+
}
|
|
1098
1192
|
let nextDep = null;
|
|
1099
1193
|
const isRecomputing = sub._flags & REACTIVE_RECOMPUTING_DEPS;
|
|
1100
1194
|
if (isRecomputing) {
|
|
1101
1195
|
nextDep = prevDep !== null ? prevDep._nextDep : sub._deps;
|
|
1102
1196
|
if (nextDep !== null && nextDep._dep === dep) {
|
|
1197
|
+
nextDep._gen = sub._depGen;
|
|
1103
1198
|
sub._depsTail = nextDep;
|
|
1199
|
+
nextDep._pendingObserver = pendingObserver;
|
|
1104
1200
|
return;
|
|
1105
1201
|
}
|
|
1106
1202
|
}
|
|
1107
1203
|
const prevSub = dep._subsTail;
|
|
1108
|
-
if (
|
|
1204
|
+
if (
|
|
1205
|
+
prevSub !== null &&
|
|
1206
|
+
prevSub._sub === sub &&
|
|
1207
|
+
(!isRecomputing || prevSub._gen === sub._depGen)
|
|
1208
|
+
) {
|
|
1209
|
+
prevSub._pendingObserver = pendingObserver;
|
|
1109
1210
|
return;
|
|
1211
|
+
}
|
|
1110
1212
|
const newLink =
|
|
1111
1213
|
(sub._depsTail =
|
|
1112
1214
|
dep._subsTail =
|
|
1113
|
-
{
|
|
1215
|
+
{
|
|
1216
|
+
_dep: dep,
|
|
1217
|
+
_sub: sub,
|
|
1218
|
+
_nextDep: nextDep,
|
|
1219
|
+
_prevSub: prevSub,
|
|
1220
|
+
_nextSub: null,
|
|
1221
|
+
_gen: sub._depGen,
|
|
1222
|
+
_pendingObserver: pendingObserver
|
|
1223
|
+
});
|
|
1114
1224
|
if (prevDep !== null) prevDep._nextDep = newLink;
|
|
1115
1225
|
else sub._deps = newLink;
|
|
1116
1226
|
if (prevSub !== null) prevSub._nextSub = newLink;
|
|
1117
1227
|
else dep._subs = newLink;
|
|
1118
1228
|
}
|
|
1119
|
-
function isValidLink(checkLink, sub) {
|
|
1120
|
-
const depsTail = sub._depsTail;
|
|
1121
|
-
if (depsTail !== null) {
|
|
1122
|
-
let link = sub._deps;
|
|
1123
|
-
do {
|
|
1124
|
-
if (link === checkLink) return true;
|
|
1125
|
-
if (link === depsTail) break;
|
|
1126
|
-
link = link._nextDep;
|
|
1127
|
-
} while (link !== null);
|
|
1128
|
-
}
|
|
1129
|
-
return false;
|
|
1130
|
-
}
|
|
1131
1229
|
function addPendingSource(el, source) {
|
|
1132
1230
|
if (el._pendingSource === source || el._pendingSources?.has(source)) return false;
|
|
1133
1231
|
if (!el._pendingSource) {
|
|
@@ -1177,9 +1275,22 @@ function setPendingError(el, source, error) {
|
|
|
1177
1275
|
}
|
|
1178
1276
|
}
|
|
1179
1277
|
function forEachDependent(el, fn) {
|
|
1180
|
-
for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub);
|
|
1278
|
+
for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub, s);
|
|
1181
1279
|
for (let child = el._child; child !== null; child = child._nextChild) {
|
|
1182
|
-
for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub);
|
|
1280
|
+
for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub, s);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
function enqueueForRerun(node) {
|
|
1284
|
+
if (node._type === EFFECT_TRACKED) {
|
|
1285
|
+
const tracked = node;
|
|
1286
|
+
if (!tracked._modified) {
|
|
1287
|
+
tracked._modified = true;
|
|
1288
|
+
tracked._queue.enqueue(EFFECT_USER, tracked._run);
|
|
1289
|
+
}
|
|
1290
|
+
} else {
|
|
1291
|
+
const queue = node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
|
|
1292
|
+
if (queue._min > node._height) queue._min = node._height;
|
|
1293
|
+
insertIntoHeap(node, queue);
|
|
1183
1294
|
}
|
|
1184
1295
|
}
|
|
1185
1296
|
function settlePendingSource(el) {
|
|
@@ -1198,17 +1309,7 @@ function settlePendingSource(el) {
|
|
|
1198
1309
|
setPendingError(node);
|
|
1199
1310
|
updatePendingSignal(node);
|
|
1200
1311
|
if (node._blocked) {
|
|
1201
|
-
|
|
1202
|
-
const tracked = node;
|
|
1203
|
-
if (!tracked._modified) {
|
|
1204
|
-
tracked._modified = true;
|
|
1205
|
-
tracked._queue.enqueue(EFFECT_USER, tracked._run);
|
|
1206
|
-
}
|
|
1207
|
-
} else {
|
|
1208
|
-
const queue = node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
|
|
1209
|
-
if (queue._min > node._height) queue._min = node._height;
|
|
1210
|
-
insertIntoHeap(node, queue);
|
|
1211
|
-
}
|
|
1312
|
+
enqueueForRerun(node);
|
|
1212
1313
|
scheduled = true;
|
|
1213
1314
|
}
|
|
1214
1315
|
node._blocked = false;
|
|
@@ -1218,23 +1319,26 @@ function settlePendingSource(el) {
|
|
|
1218
1319
|
forEachDependent(el, settle);
|
|
1219
1320
|
if (scheduled) schedule();
|
|
1220
1321
|
}
|
|
1322
|
+
function isThenable(value) {
|
|
1323
|
+
return value != null && typeof value === "object" && typeof value.then === "function";
|
|
1324
|
+
}
|
|
1221
1325
|
function handleAsync(el, result, setter) {
|
|
1222
1326
|
let iterator = false;
|
|
1223
|
-
let
|
|
1327
|
+
let thenable = false;
|
|
1224
1328
|
if (typeof result === "object" && result !== null) {
|
|
1225
1329
|
untrack(() => {
|
|
1226
1330
|
iterator = result[Symbol.asyncIterator];
|
|
1227
|
-
|
|
1331
|
+
thenable = !iterator && isThenable(result);
|
|
1228
1332
|
});
|
|
1229
1333
|
}
|
|
1230
|
-
if (!
|
|
1334
|
+
if (!thenable && !iterator) {
|
|
1231
1335
|
el._inFlight = null;
|
|
1232
1336
|
return result;
|
|
1233
1337
|
}
|
|
1234
1338
|
if (el._config & CONFIG_SYNC) {
|
|
1235
1339
|
const message =
|
|
1236
1340
|
`[SYNC_NODE_RECEIVED_ASYNC] A computed/effect created with \`sync: true\` returned ` +
|
|
1237
|
-
`${
|
|
1341
|
+
`${thenable ? "a Promise" : "an AsyncIterable"}. The value would be stored as-is and ` +
|
|
1238
1342
|
`never awaited in production; remove \`sync: true\` to use async-aware behavior, or ` +
|
|
1239
1343
|
`unwrap the value before returning.`;
|
|
1240
1344
|
emitDiagnostic({
|
|
@@ -1264,37 +1368,45 @@ function handleAsync(el, result, setter) {
|
|
|
1264
1368
|
clearStatus(el);
|
|
1265
1369
|
const lane = resolveLane(el);
|
|
1266
1370
|
if (lane) lane._pendingAsync.delete(el);
|
|
1267
|
-
if (setter)
|
|
1268
|
-
|
|
1269
|
-
if (
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1371
|
+
if (setter) {
|
|
1372
|
+
setter(value);
|
|
1373
|
+
if (wasUninitialized) clearStatus(el, true);
|
|
1374
|
+
} else if (el._overrideValue !== undefined) {
|
|
1375
|
+
if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
|
|
1376
|
+
el._pendingValue = value;
|
|
1377
|
+
syncCompanions(el, value);
|
|
1378
|
+
if (!hasActiveOverride(el)) insertSubs(el);
|
|
1275
1379
|
el._time = clock;
|
|
1276
1380
|
} else if (lane) {
|
|
1277
1381
|
const isEffect = el._type;
|
|
1278
1382
|
const prevValue = el._value;
|
|
1279
1383
|
const equals = el._equals;
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1384
|
+
try {
|
|
1385
|
+
if ((!isEffect && wasUninitialized) || !equals || !equals(value, prevValue)) {
|
|
1386
|
+
el._value = value;
|
|
1387
|
+
el._time = clock;
|
|
1388
|
+
syncCompanions(el, value);
|
|
1389
|
+
insertSubs(el, true);
|
|
1285
1390
|
}
|
|
1286
|
-
|
|
1391
|
+
} catch (e) {
|
|
1392
|
+
notifyStatus(el, STATUS_ERROR, e);
|
|
1287
1393
|
}
|
|
1288
1394
|
} else {
|
|
1289
|
-
|
|
1395
|
+
try {
|
|
1396
|
+
setSignal(el, () => value);
|
|
1397
|
+
} catch (e) {
|
|
1398
|
+
notifyStatus(el, STATUS_ERROR, e);
|
|
1399
|
+
}
|
|
1290
1400
|
}
|
|
1291
1401
|
settlePendingSource(el);
|
|
1292
1402
|
schedule();
|
|
1293
1403
|
flush();
|
|
1294
1404
|
then?.();
|
|
1295
1405
|
};
|
|
1296
|
-
if (
|
|
1406
|
+
if (thenable) {
|
|
1297
1407
|
let resolved = false,
|
|
1408
|
+
rejected = false,
|
|
1409
|
+
syncError,
|
|
1298
1410
|
isSync = true;
|
|
1299
1411
|
result.then(
|
|
1300
1412
|
v => {
|
|
@@ -1304,11 +1416,17 @@ function handleAsync(el, result, setter) {
|
|
|
1304
1416
|
} else asyncWrite(v);
|
|
1305
1417
|
},
|
|
1306
1418
|
e => {
|
|
1307
|
-
if (
|
|
1419
|
+
if (isSync) {
|
|
1420
|
+
syncError = e;
|
|
1421
|
+
rejected = true;
|
|
1422
|
+
} else handleError(e);
|
|
1308
1423
|
}
|
|
1309
1424
|
);
|
|
1310
1425
|
isSync = false;
|
|
1311
|
-
if (
|
|
1426
|
+
if (rejected) {
|
|
1427
|
+
handleError(syncError);
|
|
1428
|
+
throw syncError;
|
|
1429
|
+
} else if (!resolved) {
|
|
1312
1430
|
globalQueue.initTransition(resolveTransition(el));
|
|
1313
1431
|
throw new NotReadyError(context);
|
|
1314
1432
|
}
|
|
@@ -1322,9 +1440,7 @@ function handleAsync(el, result, setter) {
|
|
|
1322
1440
|
completed = true;
|
|
1323
1441
|
try {
|
|
1324
1442
|
const returned = it.return?.();
|
|
1325
|
-
if (returned
|
|
1326
|
-
returned.then(undefined, () => {});
|
|
1327
|
-
}
|
|
1443
|
+
if (isThenable(returned)) returned.then(undefined, () => {});
|
|
1328
1444
|
} catch {}
|
|
1329
1445
|
});
|
|
1330
1446
|
const iterate = () => {
|
|
@@ -1374,7 +1490,8 @@ function clearStatus(el, clearUninitialized = false) {
|
|
|
1374
1490
|
if (el._blocked) el._blocked = false;
|
|
1375
1491
|
el._statusFlags = clearUninitialized ? 0 : el._statusFlags & STATUS_UNINITIALIZED;
|
|
1376
1492
|
if (el._error) setPendingError(el);
|
|
1377
|
-
if (el._pendingSignal) updatePendingSignal(el);
|
|
1493
|
+
if (el._pendingSignal || el._latestValueComputed) updatePendingSignal(el);
|
|
1494
|
+
if (el._child) updateChildCompanions(el);
|
|
1378
1495
|
if (el._notifyStatus) el._notifyStatus();
|
|
1379
1496
|
}
|
|
1380
1497
|
function notifyStatus(el, status, error, blockStatus, lane) {
|
|
@@ -1402,6 +1519,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
1402
1519
|
el._error = error;
|
|
1403
1520
|
}
|
|
1404
1521
|
updatePendingSignal(el);
|
|
1522
|
+
if (el._child) updateChildCompanions(el);
|
|
1405
1523
|
}
|
|
1406
1524
|
if (lane && !blockStatus) {
|
|
1407
1525
|
assignOrMergeLane(el, lane);
|
|
@@ -1419,7 +1537,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
1419
1537
|
}
|
|
1420
1538
|
return;
|
|
1421
1539
|
}
|
|
1422
|
-
forEachDependent(el, sub => {
|
|
1540
|
+
forEachDependent(el, (sub, link) => {
|
|
1423
1541
|
sub._time = clock;
|
|
1424
1542
|
if (
|
|
1425
1543
|
(status === STATUS_PENDING &&
|
|
@@ -1429,6 +1547,11 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
1429
1547
|
(status !== STATUS_PENDING &&
|
|
1430
1548
|
(sub._error !== error || sub._pendingSource || sub._pendingSources))
|
|
1431
1549
|
) {
|
|
1550
|
+
if (link._pendingObserver && status !== STATUS_PENDING && !(error instanceof NotReadyError)) {
|
|
1551
|
+
enqueueForRerun(sub);
|
|
1552
|
+
schedule();
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1432
1555
|
if (!downstreamBlockStatus && !sub._transition) queuePendingNode(sub);
|
|
1433
1556
|
notifyStatus(sub, status, error, downstreamBlockStatus, downstreamLane);
|
|
1434
1557
|
}
|
|
@@ -1461,15 +1584,19 @@ GlobalQueue._update = recompute;
|
|
|
1461
1584
|
GlobalQueue._dispose = disposeChildren;
|
|
1462
1585
|
const PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE =
|
|
1463
1586
|
"[PRIMITIVE_IN_FORBIDDEN_SCOPE] Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled";
|
|
1587
|
+
const REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE =
|
|
1588
|
+
"[REACTIVE_WRITE_IN_OWNED_SCOPE] Writing to reactive state inside an owned scope (component, computation) is not allowed. " +
|
|
1589
|
+
"Move the write outside or set the `ownedWrite` option if this is intentional.";
|
|
1590
|
+
const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE =
|
|
1591
|
+
"[REACTIVE_WRITE_IN_OWNED_SCOPE] Calling refresh() inside an owned scope (component, computation) is not allowed. " +
|
|
1592
|
+
"Move the invalidation outside pure computation.";
|
|
1464
1593
|
let tracking = false;
|
|
1465
1594
|
let stale = false;
|
|
1466
|
-
let refreshing = false;
|
|
1467
1595
|
let pendingCheckActive = false;
|
|
1468
|
-
let foundPending = false;
|
|
1469
1596
|
let latestReadActive = false;
|
|
1470
1597
|
let context = null;
|
|
1471
1598
|
let currentOptimisticLane = null;
|
|
1472
|
-
let
|
|
1599
|
+
let pendingProbe = null;
|
|
1473
1600
|
let snapshotCaptureActive = false;
|
|
1474
1601
|
let snapshotSources = null;
|
|
1475
1602
|
function ownerInSnapshotScope(owner) {
|
|
@@ -1542,11 +1669,12 @@ function recompute(el, create = false) {
|
|
|
1542
1669
|
}
|
|
1543
1670
|
let isOptimisticDirty = !!(el._flags & REACTIVE_OPTIMISTIC_DIRTY);
|
|
1544
1671
|
const hasOverride = el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING;
|
|
1545
|
-
|
|
1672
|
+
!!(el._statusFlags & STATUS_PENDING);
|
|
1546
1673
|
const wasUninitialized = !!(el._statusFlags & STATUS_UNINITIALIZED);
|
|
1547
1674
|
const oldcontext = context;
|
|
1548
1675
|
context = el;
|
|
1549
1676
|
el._depsTail = null;
|
|
1677
|
+
el._depGen++;
|
|
1550
1678
|
el._flags = REACTIVE_RECOMPUTING_DEPS;
|
|
1551
1679
|
el._time = clock;
|
|
1552
1680
|
let value = el._pendingValue === NOT_PENDING ? el._value : el._pendingValue;
|
|
@@ -1629,26 +1757,35 @@ function recompute(el, create = false) {
|
|
|
1629
1757
|
: el._pendingValue === NOT_PENDING
|
|
1630
1758
|
? el._value
|
|
1631
1759
|
: el._pendingValue;
|
|
1632
|
-
|
|
1633
|
-
|
|
1760
|
+
let valueChanged = false;
|
|
1761
|
+
try {
|
|
1762
|
+
valueChanged =
|
|
1763
|
+
(!isEffect && wasUninitialized) || !el._equals || !el._equals(compareValue, value);
|
|
1764
|
+
} catch (e) {
|
|
1765
|
+
notifyStatus(el, STATUS_ERROR, e);
|
|
1766
|
+
}
|
|
1634
1767
|
if (isEffect && valueChanged) {
|
|
1635
1768
|
el._modified = !el._error;
|
|
1636
|
-
if (!create)
|
|
1769
|
+
if (!create)
|
|
1770
|
+
el._queue.enqueue(isEffect, (el._boundRunEffect ??= GlobalQueue._runEffect.bind(null, el)));
|
|
1637
1771
|
}
|
|
1638
|
-
if (
|
|
1772
|
+
if (el._error);
|
|
1773
|
+
else if (valueChanged) {
|
|
1639
1774
|
const prevVisible = hasOverride ? el._overrideValue : undefined;
|
|
1640
1775
|
if (create || (isEffect && activeTransition !== el._transition) || isOptimisticDirty) {
|
|
1641
1776
|
el._value = value;
|
|
1642
1777
|
if (hasOverride && isOptimisticDirty) {
|
|
1643
1778
|
el._overrideValue = value;
|
|
1644
|
-
el._pendingValue =
|
|
1779
|
+
el._pendingValue = NOT_PENDING;
|
|
1645
1780
|
}
|
|
1646
|
-
} else
|
|
1647
|
-
|
|
1648
|
-
el.
|
|
1781
|
+
} else {
|
|
1782
|
+
el._pendingValue = value;
|
|
1783
|
+
if (activeTransition || el._transition) syncCompanions(el, value);
|
|
1784
|
+
}
|
|
1649
1785
|
if (!hasOverride || isOptimisticDirty || el._overrideValue !== prevVisible)
|
|
1650
1786
|
insertSubs(el, isOptimisticDirty || hasOverride);
|
|
1651
1787
|
} else if (hasOverride) {
|
|
1788
|
+
if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
|
|
1652
1789
|
el._pendingValue = value;
|
|
1653
1790
|
} else if (el._height != oldHeight) {
|
|
1654
1791
|
for (let s = el._subs; s !== null; s = s._nextSub) {
|
|
@@ -1664,8 +1801,7 @@ function recompute(el, create = false) {
|
|
|
1664
1801
|
!!(el._statusFlags & (STATUS_PENDING | STATUS_UNINITIALIZED));
|
|
1665
1802
|
needsPendingCommit &&
|
|
1666
1803
|
(!create || el._statusFlags & STATUS_PENDING) &&
|
|
1667
|
-
!el._transition &&
|
|
1668
|
-
!(activeTransition && hasOverride) &&
|
|
1804
|
+
(!el._transition || hasOverride) &&
|
|
1669
1805
|
queuePendingNode(el);
|
|
1670
1806
|
el._transition &&
|
|
1671
1807
|
isEffect &&
|
|
@@ -1704,6 +1840,7 @@ function computed(fn, options) {
|
|
|
1704
1840
|
(options?.ownedWrite ? CONFIG_OWNED_WRITE : 0) |
|
|
1705
1841
|
(!context || options?.lazy ? CONFIG_AUTO_DISPOSE : 0) |
|
|
1706
1842
|
(options?.sync ? CONFIG_SYNC : 0) |
|
|
1843
|
+
(options?._noSnapshot ? CONFIG_NO_SNAPSHOT : 0) |
|
|
1707
1844
|
(snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
|
|
1708
1845
|
_equals: options?.equals != null ? options.equals : isEqual,
|
|
1709
1846
|
_unobserved: options?.unobserved,
|
|
@@ -1719,6 +1856,7 @@ function computed(fn, options) {
|
|
|
1719
1856
|
_prevHeap: null,
|
|
1720
1857
|
_deps: null,
|
|
1721
1858
|
_depsTail: null,
|
|
1859
|
+
_depGen: 0,
|
|
1722
1860
|
_subs: null,
|
|
1723
1861
|
_subsTail: null,
|
|
1724
1862
|
_parent: context,
|
|
@@ -1763,6 +1901,7 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
|
|
|
1763
1901
|
_prevHeap: null,
|
|
1764
1902
|
_deps: null,
|
|
1765
1903
|
_depsTail: null,
|
|
1904
|
+
_depGen: 0,
|
|
1766
1905
|
_subs: null,
|
|
1767
1906
|
_subsTail: null,
|
|
1768
1907
|
_parent: context,
|
|
@@ -1782,7 +1921,6 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
|
|
|
1782
1921
|
_effectFn: effectFn,
|
|
1783
1922
|
_errorFn: errorFn,
|
|
1784
1923
|
_cleanup: undefined,
|
|
1785
|
-
_cleanupRegistered: false,
|
|
1786
1924
|
_type: type,
|
|
1787
1925
|
_notifyStatus: notifyStatus
|
|
1788
1926
|
};
|
|
@@ -1830,7 +1968,7 @@ function setupComputedNode(self, options) {
|
|
|
1830
1968
|
}
|
|
1831
1969
|
!options?.lazy && recompute(self, true);
|
|
1832
1970
|
if (snapshotCaptureActive && !options?.lazy) {
|
|
1833
|
-
if (!(self._statusFlags & STATUS_PENDING)) {
|
|
1971
|
+
if (!(self._statusFlags & STATUS_PENDING) && !(self._config & CONFIG_NO_SNAPSHOT)) {
|
|
1834
1972
|
self._snapshotValue = self._value === undefined ? NO_SNAPSHOT : self._value;
|
|
1835
1973
|
snapshotSources.add(self);
|
|
1836
1974
|
}
|
|
@@ -1899,6 +2037,16 @@ function untrack(fn, strictReadLabel) {
|
|
|
1899
2037
|
strictRead = prevStrictRead;
|
|
1900
2038
|
}
|
|
1901
2039
|
}
|
|
2040
|
+
function prepareComputed(comp, refresh) {
|
|
2041
|
+
if (comp._flags & REACTIVE_LAZY) {
|
|
2042
|
+
comp._flags &= ~REACTIVE_LAZY;
|
|
2043
|
+
recompute(comp, true);
|
|
2044
|
+
} else if (comp._flags & REACTIVE_DISPOSED) {
|
|
2045
|
+
recompute(comp, true);
|
|
2046
|
+
} else if (refresh) {
|
|
2047
|
+
updateIfNecessary(comp);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
1902
2050
|
function read(el) {
|
|
1903
2051
|
if (latestReadActive) {
|
|
1904
2052
|
const pendingComputed = getLatestValueComputed(el);
|
|
@@ -1912,7 +2060,8 @@ function read(el) {
|
|
|
1912
2060
|
try {
|
|
1913
2061
|
value = read(pendingComputed);
|
|
1914
2062
|
} catch (e) {
|
|
1915
|
-
if (!context
|
|
2063
|
+
if (e instanceof NotReadyError && (!context || !(el._statusFlags & STATUS_UNINITIALIZED)))
|
|
2064
|
+
return visibleValue;
|
|
1916
2065
|
throw e;
|
|
1917
2066
|
} finally {
|
|
1918
2067
|
latestReadActive = prevPending;
|
|
@@ -1927,59 +2076,25 @@ function read(el) {
|
|
|
1927
2076
|
}
|
|
1928
2077
|
return value;
|
|
1929
2078
|
}
|
|
2079
|
+
let c = context;
|
|
2080
|
+
if (c?._root) c = c._parentComputed;
|
|
2081
|
+
const computed = el;
|
|
2082
|
+
const firewall = el._firewall;
|
|
2083
|
+
const owner = firewall || el;
|
|
1930
2084
|
if (pendingCheckActive) {
|
|
1931
|
-
const firewall = el._firewall;
|
|
1932
|
-
const prevCheck = pendingCheckActive;
|
|
1933
2085
|
pendingCheckActive = false;
|
|
1934
|
-
|
|
1935
|
-
if (c?._root) c = c._parentComputed;
|
|
1936
|
-
const owner = firewall || el;
|
|
1937
|
-
const pendingComputed = el;
|
|
1938
|
-
if (typeof pendingComputed._fn === "function") {
|
|
1939
|
-
const comp = el;
|
|
1940
|
-
if (comp._flags & REACTIVE_LAZY) {
|
|
1941
|
-
comp._flags &= ~REACTIVE_LAZY;
|
|
1942
|
-
recompute(comp, true);
|
|
1943
|
-
} else if (comp._flags & REACTIVE_DISPOSED) {
|
|
1944
|
-
recompute(comp, true);
|
|
1945
|
-
} else {
|
|
1946
|
-
updateIfNecessary(comp);
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
2086
|
+
if (typeof computed._fn === "function") prepareComputed(el, true);
|
|
1949
2087
|
if (c && owner._statusFlags & STATUS_PENDING && owner._statusFlags & STATUS_UNINITIALIZED) {
|
|
1950
2088
|
if (tracking && el !== c) link(el, c);
|
|
1951
|
-
pendingCheckActive =
|
|
2089
|
+
pendingCheckActive = true;
|
|
1952
2090
|
throw owner._error;
|
|
1953
2091
|
}
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
foundPending = true;
|
|
1960
|
-
}
|
|
1961
|
-
collectPendingSources(el);
|
|
1962
|
-
collectPendingSources(firewall);
|
|
1963
|
-
if (c && tracking) link(el, c);
|
|
1964
|
-
} else {
|
|
1965
|
-
collectPendingSources(el);
|
|
1966
|
-
if (firewall) collectPendingSources(firewall);
|
|
1967
|
-
}
|
|
1968
|
-
pendingCheckActive = prevCheck;
|
|
2092
|
+
collectPendingSources(el);
|
|
2093
|
+
if (firewall) collectPendingSources(firewall);
|
|
2094
|
+
pendingCheckActive = true;
|
|
2095
|
+
} else if (typeof computed._fn === "function") {
|
|
2096
|
+
prepareComputed(el, false);
|
|
1969
2097
|
}
|
|
1970
|
-
let c = context;
|
|
1971
|
-
if (c?._root) c = c._parentComputed;
|
|
1972
|
-
const computed = el;
|
|
1973
|
-
if (typeof computed._fn === "function") {
|
|
1974
|
-
const comp = el;
|
|
1975
|
-
if (comp._flags & REACTIVE_LAZY) {
|
|
1976
|
-
comp._flags &= ~REACTIVE_LAZY;
|
|
1977
|
-
recompute(comp, true);
|
|
1978
|
-
} else if (comp._flags & REACTIVE_DISPOSED) {
|
|
1979
|
-
recompute(comp, true);
|
|
1980
|
-
}
|
|
1981
|
-
}
|
|
1982
|
-
const owner = el._firewall || el;
|
|
1983
2098
|
if (
|
|
1984
2099
|
!computed._fn &&
|
|
1985
2100
|
owner === el &&
|
|
@@ -2010,7 +2125,7 @@ function read(el) {
|
|
|
2010
2125
|
throw new Error(message);
|
|
2011
2126
|
}
|
|
2012
2127
|
if (c && tracking) {
|
|
2013
|
-
link(el, c);
|
|
2128
|
+
link(el, c, pendingCheckActive);
|
|
2014
2129
|
if (owner._fn) {
|
|
2015
2130
|
const isZombie = el._flags & REACTIVE_ZOMBIE;
|
|
2016
2131
|
if (owner._height >= (isZombie ? zombieQueue._min : dirtyQueue._min)) {
|
|
@@ -2060,7 +2175,7 @@ function read(el) {
|
|
|
2060
2175
|
}
|
|
2061
2176
|
}
|
|
2062
2177
|
if (el._fn && el._statusFlags & STATUS_ERROR) {
|
|
2063
|
-
if (el._time < clock) {
|
|
2178
|
+
if (tracking && !pendingCheckActive && el._time < clock) {
|
|
2064
2179
|
recompute(el);
|
|
2065
2180
|
return read(el);
|
|
2066
2181
|
} else throw el._error;
|
|
@@ -2099,7 +2214,7 @@ function read(el) {
|
|
|
2099
2214
|
currentOptimisticLane !== null &&
|
|
2100
2215
|
!latestReadActive &&
|
|
2101
2216
|
el._pendingValue !== NOT_PENDING &&
|
|
2102
|
-
owner === el &&
|
|
2217
|
+
(owner === el || !!(owner._flags & REACTIVE_MANUAL_WRITE)) &&
|
|
2103
2218
|
!el._fn &&
|
|
2104
2219
|
c
|
|
2105
2220
|
) {
|
|
@@ -2111,12 +2226,19 @@ function read(el) {
|
|
|
2111
2226
|
(currentOptimisticLane !== null &&
|
|
2112
2227
|
(el._overrideValue !== undefined ||
|
|
2113
2228
|
el._optimisticLane ||
|
|
2114
|
-
(owner === el && stale) ||
|
|
2229
|
+
(owner === el && stale && c._parentSource !== el) ||
|
|
2115
2230
|
!!(owner._statusFlags & STATUS_PENDING))) ||
|
|
2116
2231
|
el._pendingValue === NOT_PENDING ||
|
|
2117
2232
|
(stale && el._transition && activeTransition !== el._transition)
|
|
2118
2233
|
? el._value
|
|
2119
2234
|
: el._pendingValue;
|
|
2235
|
+
if (
|
|
2236
|
+
pendingCheckActive &&
|
|
2237
|
+
pendingProbe !== null &&
|
|
2238
|
+
el._pendingValue !== NOT_PENDING &&
|
|
2239
|
+
value === el._pendingValue
|
|
2240
|
+
)
|
|
2241
|
+
pendingProbe.freshReads.add(el);
|
|
2120
2242
|
if (
|
|
2121
2243
|
!c &&
|
|
2122
2244
|
owner === el &&
|
|
@@ -2136,19 +2258,17 @@ function setSignal(el, v) {
|
|
|
2136
2258
|
context &&
|
|
2137
2259
|
el._firewall !== context
|
|
2138
2260
|
) {
|
|
2139
|
-
const message =
|
|
2140
|
-
"[SIGNAL_WRITE_IN_OWNED_SCOPE] Writing to a Signal inside an owned scope (component, computation) is not allowed. " +
|
|
2141
|
-
"Move the write outside or set the `ownedWrite` option if this is intentional.";
|
|
2142
2261
|
emitDiagnostic({
|
|
2143
|
-
code: "
|
|
2262
|
+
code: "REACTIVE_WRITE_IN_OWNED_SCOPE",
|
|
2144
2263
|
kind: "write",
|
|
2145
2264
|
severity: "error",
|
|
2146
|
-
message:
|
|
2265
|
+
message: REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE,
|
|
2147
2266
|
ownerId: context.id,
|
|
2148
2267
|
ownerName: context._name,
|
|
2149
|
-
nodeName: el._name
|
|
2268
|
+
nodeName: el._name,
|
|
2269
|
+
data: { operation: "setSignal" }
|
|
2150
2270
|
});
|
|
2151
|
-
throw new Error(
|
|
2271
|
+
throw new Error(REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE);
|
|
2152
2272
|
}
|
|
2153
2273
|
if (el._transition && activeTransition !== el._transition)
|
|
2154
2274
|
globalQueue.initTransition(el._transition);
|
|
@@ -2163,22 +2283,18 @@ function setSignal(el, v) {
|
|
|
2163
2283
|
: el._pendingValue;
|
|
2164
2284
|
if (typeof v === "function") v = v(currentValue);
|
|
2165
2285
|
const valueChanged =
|
|
2166
|
-
!el._equals || !el._equals(currentValue, v)
|
|
2286
|
+
!!(el._statusFlags & STATUS_UNINITIALIZED) || !el._equals || !el._equals(currentValue, v);
|
|
2167
2287
|
if (!valueChanged) {
|
|
2168
|
-
if (isOptimistic && hasOverride
|
|
2169
|
-
|
|
2170
|
-
|
|
2288
|
+
if (isOptimistic && hasOverride) {
|
|
2289
|
+
const transition = resolveTransition(el);
|
|
2290
|
+
if (transition && activeTransition !== transition) globalQueue.initTransition(transition);
|
|
2171
2291
|
}
|
|
2172
2292
|
return v;
|
|
2173
2293
|
}
|
|
2174
2294
|
if (isOptimistic) {
|
|
2175
2295
|
const firstOverride = el._overrideValue === NOT_PENDING;
|
|
2176
2296
|
if (!firstOverride) globalQueue.initTransition(resolveTransition(el));
|
|
2177
|
-
if (firstOverride)
|
|
2178
|
-
el._pendingValue = el._value;
|
|
2179
|
-
globalQueue._optimisticNodes.push(el);
|
|
2180
|
-
}
|
|
2181
|
-
el._overrideSinceLane = true;
|
|
2297
|
+
if (firstOverride) globalQueue._optimisticNodes.push(el);
|
|
2182
2298
|
const lane = getOrCreateLane(el);
|
|
2183
2299
|
el._optimisticLane = lane;
|
|
2184
2300
|
el._overrideValue = v;
|
|
@@ -2186,10 +2302,7 @@ function setSignal(el, v) {
|
|
|
2186
2302
|
if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
|
|
2187
2303
|
el._pendingValue = v;
|
|
2188
2304
|
}
|
|
2189
|
-
|
|
2190
|
-
if (el._latestValueComputed) {
|
|
2191
|
-
setSignal(el._latestValueComputed, v);
|
|
2192
|
-
}
|
|
2305
|
+
syncCompanions(el, v);
|
|
2193
2306
|
el._time = clock;
|
|
2194
2307
|
insertSubs(el, isOptimistic);
|
|
2195
2308
|
schedule();
|
|
@@ -2197,8 +2310,10 @@ function setSignal(el, v) {
|
|
|
2197
2310
|
}
|
|
2198
2311
|
function suppressComputedRecompute(el) {
|
|
2199
2312
|
deleteFromHeap(el, el._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
2200
|
-
if (!(el._flags & REACTIVE_MANUAL_WRITE) && el._pendingValue === NOT_PENDING)
|
|
2313
|
+
if (!(el._flags & REACTIVE_MANUAL_WRITE) && el._pendingValue === NOT_PENDING) {
|
|
2201
2314
|
queuePendingNode(el);
|
|
2315
|
+
schedule();
|
|
2316
|
+
}
|
|
2202
2317
|
el._flags = (el._flags & -4) | REACTIVE_MANUAL_WRITE;
|
|
2203
2318
|
}
|
|
2204
2319
|
function setMemo(el, v) {
|
|
@@ -2234,61 +2349,82 @@ function runWithOwner(owner, fn) {
|
|
|
2234
2349
|
function getPendingSignal(el) {
|
|
2235
2350
|
if (!el._pendingSignal) {
|
|
2236
2351
|
el._pendingSignal = optimisticSignal(false, { ownedWrite: true });
|
|
2237
|
-
|
|
2238
|
-
el._pendingSignal._parentSource = el;
|
|
2239
|
-
}
|
|
2352
|
+
el._pendingSignal._parentSource = el;
|
|
2240
2353
|
if (computePendingState(el)) setSignal(el._pendingSignal, true);
|
|
2241
2354
|
}
|
|
2242
2355
|
return el._pendingSignal;
|
|
2243
2356
|
}
|
|
2244
2357
|
function collectPendingSources(el) {
|
|
2245
|
-
|
|
2358
|
+
if (!pendingProbe) return;
|
|
2359
|
+
pendingProbe.sources.add(el);
|
|
2246
2360
|
const owner = el._firewall || el;
|
|
2247
|
-
if (owner !== el)
|
|
2361
|
+
if (owner !== el) pendingProbe.sources.add(owner);
|
|
2248
2362
|
}
|
|
2249
2363
|
function computePendingState(el) {
|
|
2250
2364
|
const comp = el;
|
|
2365
|
+
if (comp._flags & REACTIVE_DISPOSED) return false;
|
|
2251
2366
|
const firewall = el._firewall;
|
|
2367
|
+
if ((firewall || comp)._optimisticMask) return false;
|
|
2252
2368
|
if (el._parentSource) {
|
|
2253
|
-
const
|
|
2254
|
-
if (
|
|
2255
|
-
|
|
2256
|
-
|
|
2369
|
+
const parentNode = el._parentSource;
|
|
2370
|
+
if (hasActiveOverride(parentNode)) return false;
|
|
2371
|
+
const parent = parentNode._firewall || parentNode;
|
|
2372
|
+
if (parent._optimisticMask) return false;
|
|
2373
|
+
return !!(
|
|
2374
|
+
parent._statusFlags & STATUS_PENDING && !(parent._statusFlags & STATUS_UNINITIALIZED)
|
|
2375
|
+
);
|
|
2257
2376
|
}
|
|
2377
|
+
if (hasActiveOverride(el)) return false;
|
|
2258
2378
|
if (firewall && el._pendingValue !== NOT_PENDING) {
|
|
2259
|
-
return
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
return true;
|
|
2264
|
-
if (el._parentSource) {
|
|
2265
|
-
const lane = el._optimisticLane ? findLane(el._optimisticLane) : null;
|
|
2266
|
-
return !!(lane && lane._pendingAsync.size > 0);
|
|
2267
|
-
}
|
|
2268
|
-
return true;
|
|
2269
|
-
}
|
|
2270
|
-
if (el._overrideValue !== undefined && el._overrideValue === NOT_PENDING && !el._parentSource) {
|
|
2271
|
-
return false;
|
|
2379
|
+
return (
|
|
2380
|
+
!!(firewall._flags & REACTIVE_MANUAL_WRITE) ||
|
|
2381
|
+
(!firewall._inFlight && !(firewall._statusFlags & STATUS_PENDING))
|
|
2382
|
+
);
|
|
2272
2383
|
}
|
|
2273
2384
|
if (el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED)) return true;
|
|
2274
2385
|
return !!(comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED));
|
|
2275
2386
|
}
|
|
2387
|
+
function syncCompanions(el, value) {
|
|
2388
|
+
if (el._pendingSignal) updatePendingSignal(el);
|
|
2389
|
+
if (el._latestValueComputed) setSignal(el._latestValueComputed, value);
|
|
2390
|
+
}
|
|
2276
2391
|
function updatePendingSignal(el) {
|
|
2277
2392
|
if (el._pendingSignal) {
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2393
|
+
setSignal(el._pendingSignal, computePendingState(el));
|
|
2394
|
+
}
|
|
2395
|
+
if (el._latestValueComputed) updatePendingSignal(el._latestValueComputed);
|
|
2396
|
+
}
|
|
2397
|
+
function updateChildCompanions(el) {
|
|
2398
|
+
for (let child = el._child; child !== null; child = child._nextChild) {
|
|
2399
|
+
if (child._pendingSignal || child._latestValueComputed) updatePendingSignal(child);
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
function snapCompanionsToState(owner) {
|
|
2403
|
+
const sig = owner._pendingSignal;
|
|
2404
|
+
if (sig && (sig._overrideValue === undefined || sig._overrideValue === NOT_PENDING)) {
|
|
2405
|
+
const pending = computePendingState(owner);
|
|
2406
|
+
if (sig._value !== pending || sig._pendingValue !== NOT_PENDING) {
|
|
2407
|
+
sig._value = pending;
|
|
2408
|
+
sig._pendingValue = NOT_PENDING;
|
|
2409
|
+
sig._time = clock;
|
|
2410
|
+
insertSubs(sig);
|
|
2411
|
+
schedule();
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
const shadow = owner._latestValueComputed;
|
|
2415
|
+
if (shadow && !(shadow._flags & REACTIVE_DISPOSED)) {
|
|
2416
|
+
if (
|
|
2417
|
+
(shadow._overrideValue === undefined || shadow._overrideValue === NOT_PENDING) &&
|
|
2418
|
+
shadow._pendingValue === NOT_PENDING &&
|
|
2419
|
+
!Object.is(shadow._value, owner._value) &&
|
|
2420
|
+
!(shadow._flags & (REACTIVE_DIRTY | REACTIVE_CHECK))
|
|
2421
|
+
) {
|
|
2422
|
+
shadow._flags |= REACTIVE_DIRTY;
|
|
2423
|
+
insertIntoHeap(shadow, shadow._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
2424
|
+
insertSubs(shadow);
|
|
2425
|
+
schedule();
|
|
2291
2426
|
}
|
|
2427
|
+
snapCompanionsToState(shadow);
|
|
2292
2428
|
}
|
|
2293
2429
|
}
|
|
2294
2430
|
function getLatestValueComputed(el) {
|
|
@@ -2327,18 +2463,16 @@ function latest(fn) {
|
|
|
2327
2463
|
}
|
|
2328
2464
|
function isPending(fn) {
|
|
2329
2465
|
const prevPendingCheck = pendingCheckActive;
|
|
2330
|
-
const
|
|
2331
|
-
const prevPendingCheckSources = pendingCheckSources;
|
|
2466
|
+
const prevProbe = pendingProbe;
|
|
2332
2467
|
pendingCheckActive = true;
|
|
2333
|
-
|
|
2334
|
-
pendingCheckSources = new Set();
|
|
2468
|
+
const probe = (pendingProbe = { found: false, sources: new Set(), freshReads: new Set() });
|
|
2335
2469
|
const collectPending = () => {
|
|
2336
2470
|
pendingCheckActive = false;
|
|
2337
2471
|
const prevStrictRead = strictRead;
|
|
2338
2472
|
strictRead = false;
|
|
2339
2473
|
try {
|
|
2340
|
-
|
|
2341
|
-
if (read(getPendingSignal(source)))
|
|
2474
|
+
probe.sources.forEach(source => {
|
|
2475
|
+
if (read(getPendingSignal(source)) && !probe.freshReads.has(source)) probe.found = true;
|
|
2342
2476
|
});
|
|
2343
2477
|
} finally {
|
|
2344
2478
|
strictRead = prevStrictRead;
|
|
@@ -2348,26 +2482,23 @@ function isPending(fn) {
|
|
|
2348
2482
|
try {
|
|
2349
2483
|
fn();
|
|
2350
2484
|
collectPending();
|
|
2351
|
-
return
|
|
2485
|
+
return probe.found;
|
|
2352
2486
|
} catch (e) {
|
|
2353
2487
|
collectPending();
|
|
2354
2488
|
if (e instanceof NotReadyError) {
|
|
2355
|
-
if (
|
|
2489
|
+
if (probe.found && !(e.source?._statusFlags & STATUS_UNINITIALIZED)) return true;
|
|
2356
2490
|
if (context) throw e;
|
|
2357
2491
|
}
|
|
2358
|
-
return
|
|
2492
|
+
return probe.found;
|
|
2359
2493
|
} finally {
|
|
2360
2494
|
pendingCheckActive = prevPendingCheck;
|
|
2361
|
-
|
|
2362
|
-
pendingCheckSources = prevPendingCheckSources;
|
|
2495
|
+
pendingProbe = prevProbe;
|
|
2363
2496
|
}
|
|
2364
2497
|
}
|
|
2365
2498
|
function refresh(target) {
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
const node = target?.[$REFRESH];
|
|
2370
|
-
if (true && !node) {
|
|
2499
|
+
const node = target?.[$REFRESH];
|
|
2500
|
+
if (!node) {
|
|
2501
|
+
{
|
|
2371
2502
|
const message =
|
|
2372
2503
|
"[INVALID_REFRESH_TARGET] refresh() expects a Solid source accessor or refreshable store. " +
|
|
2373
2504
|
"Pass the original source target, not a wrapper function or derived property read.";
|
|
@@ -2379,18 +2510,32 @@ function refresh(target) {
|
|
|
2379
2510
|
});
|
|
2380
2511
|
throw new Error(message);
|
|
2381
2512
|
}
|
|
2382
|
-
if (node && typeof node._fn === "function" && !(node._flags & REACTIVE_DISPOSED)) {
|
|
2383
|
-
recompute(node);
|
|
2384
|
-
}
|
|
2385
|
-
} finally {
|
|
2386
|
-
refreshing = prevRefreshing;
|
|
2387
|
-
if (!prevRefreshing) {
|
|
2388
|
-
schedule();
|
|
2389
|
-
}
|
|
2390
2513
|
}
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2514
|
+
if (
|
|
2515
|
+
context &&
|
|
2516
|
+
!((node._config ?? 0) & CONFIG_OWNED_WRITE) &&
|
|
2517
|
+
!(context._config & CONFIG_CHILDREN_FORBIDDEN)
|
|
2518
|
+
) {
|
|
2519
|
+
emitDiagnostic({
|
|
2520
|
+
code: "REACTIVE_WRITE_IN_OWNED_SCOPE",
|
|
2521
|
+
kind: "write",
|
|
2522
|
+
severity: "error",
|
|
2523
|
+
message: REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE,
|
|
2524
|
+
ownerId: context.id,
|
|
2525
|
+
ownerName: context._name,
|
|
2526
|
+
nodeName: node._name,
|
|
2527
|
+
data: { operation: "refresh" }
|
|
2528
|
+
});
|
|
2529
|
+
throw new Error(REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE);
|
|
2530
|
+
}
|
|
2531
|
+
if (
|
|
2532
|
+
typeof node._fn === "function" &&
|
|
2533
|
+
!(node._flags & (REACTIVE_DISPOSED | REACTIVE_MANUAL_WRITE))
|
|
2534
|
+
) {
|
|
2535
|
+
node._flags = (node._flags & ~REACTIVE_CHECK) | REACTIVE_DIRTY;
|
|
2536
|
+
insertIntoHeap(node, node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
2537
|
+
schedule();
|
|
2538
|
+
}
|
|
2394
2539
|
}
|
|
2395
2540
|
function createContext(defaultValue, description) {
|
|
2396
2541
|
return { id: Symbol(description), defaultValue: defaultValue };
|
|
@@ -2454,50 +2599,67 @@ function notifyEffectStatus(status, error) {
|
|
|
2454
2599
|
const actualStatus = status !== undefined ? status : this._statusFlags;
|
|
2455
2600
|
const actualError = error !== undefined ? error : this._error;
|
|
2456
2601
|
if (actualStatus & STATUS_ERROR) {
|
|
2457
|
-
let err = actualError;
|
|
2458
2602
|
this._queue.notify(this, STATUS_PENDING, 0);
|
|
2459
2603
|
if (this._type === EFFECT_USER) {
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
this._cleanup?.();
|
|
2464
|
-
this._cleanup = undefined;
|
|
2465
|
-
})
|
|
2466
|
-
: console.error(err);
|
|
2467
|
-
} catch (e) {
|
|
2468
|
-
err = e;
|
|
2604
|
+
if (this._statusFlags & STATUS_ERROR) {
|
|
2605
|
+
this._modified = true;
|
|
2606
|
+
this._queue.enqueue(this._type, (this._boundRunEffect ??= runEffect.bind(null, this)));
|
|
2469
2607
|
}
|
|
2608
|
+
return;
|
|
2609
|
+
}
|
|
2610
|
+
if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) {
|
|
2611
|
+
haltReactivity();
|
|
2612
|
+
throw actualError;
|
|
2470
2613
|
}
|
|
2471
|
-
if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) throw err;
|
|
2472
2614
|
} else if (this._type === EFFECT_RENDER) {
|
|
2473
2615
|
this._queue.notify(this, STATUS_PENDING | STATUS_ERROR, actualStatus, actualError);
|
|
2474
2616
|
if (_hitUnhandledAsync) {
|
|
2475
2617
|
resetUnhandledAsync();
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
console.warn(message);
|
|
2488
|
-
}
|
|
2618
|
+
const message =
|
|
2619
|
+
"[ASYNC_OUTSIDE_LOADING_BOUNDARY] An async value was read outside a Loading boundary. The root mount will be deferred until all pending async settles.";
|
|
2620
|
+
emitDiagnostic({
|
|
2621
|
+
code: "ASYNC_OUTSIDE_LOADING_BOUNDARY",
|
|
2622
|
+
kind: "async",
|
|
2623
|
+
severity: "warn",
|
|
2624
|
+
message: message,
|
|
2625
|
+
ownerId: this.id,
|
|
2626
|
+
ownerName: this._name
|
|
2627
|
+
});
|
|
2628
|
+
console.warn(message);
|
|
2489
2629
|
}
|
|
2490
2630
|
}
|
|
2491
2631
|
}
|
|
2492
2632
|
function runEffect(node) {
|
|
2493
2633
|
if (!node._modified || node._flags & REACTIVE_DISPOSED) return;
|
|
2634
|
+
if (node._statusFlags & STATUS_ERROR && node._type === EFFECT_USER) {
|
|
2635
|
+
const err =
|
|
2636
|
+
node._error instanceof StatusError ? (node._error.cause ?? node._error) : node._error;
|
|
2637
|
+
node._prevValue = node._value;
|
|
2638
|
+
node._modified = false;
|
|
2639
|
+
try {
|
|
2640
|
+
node._errorFn
|
|
2641
|
+
? node._errorFn(err, () => {
|
|
2642
|
+
const prevCleanup = node._cleanup;
|
|
2643
|
+
node._cleanup = undefined;
|
|
2644
|
+
prevCleanup?.();
|
|
2645
|
+
})
|
|
2646
|
+
: console.error(err);
|
|
2647
|
+
} catch (error) {
|
|
2648
|
+
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
|
|
2649
|
+
haltReactivity();
|
|
2650
|
+
throw error;
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2494
2655
|
let prevStrictRead = false;
|
|
2495
2656
|
{
|
|
2496
2657
|
prevStrictRead = setStrictRead("an effect callback");
|
|
2497
2658
|
}
|
|
2498
|
-
node._cleanup
|
|
2659
|
+
const prevCleanup = node._cleanup;
|
|
2499
2660
|
node._cleanup = undefined;
|
|
2500
2661
|
try {
|
|
2662
|
+
prevCleanup?.();
|
|
2501
2663
|
const nextCleanup = node._effectFn(node._value, node._prevValue);
|
|
2502
2664
|
if (true && nextCleanup !== undefined && typeof nextCleanup !== "function") {
|
|
2503
2665
|
throw new Error(
|
|
@@ -2505,14 +2667,13 @@ function runEffect(node) {
|
|
|
2505
2667
|
);
|
|
2506
2668
|
}
|
|
2507
2669
|
node._cleanup = nextCleanup;
|
|
2508
|
-
if (node._cleanup && !node._cleanupRegistered) {
|
|
2509
|
-
node._cleanupRegistered = true;
|
|
2510
|
-
runWithOwner(node._parent, () => cleanup(() => node._cleanup?.()));
|
|
2511
|
-
}
|
|
2512
2670
|
} catch (error) {
|
|
2513
2671
|
node._error = new StatusError(node, error);
|
|
2514
2672
|
node._statusFlags |= STATUS_ERROR;
|
|
2515
|
-
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR))
|
|
2673
|
+
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
|
|
2674
|
+
haltReactivity();
|
|
2675
|
+
throw error;
|
|
2676
|
+
}
|
|
2516
2677
|
} finally {
|
|
2517
2678
|
setStrictRead(prevStrictRead);
|
|
2518
2679
|
node._prevValue = node._value;
|
|
@@ -2533,8 +2694,9 @@ function trackedEffect(fn, options) {
|
|
|
2533
2694
|
};
|
|
2534
2695
|
const node = computed(
|
|
2535
2696
|
() => {
|
|
2536
|
-
node._cleanup
|
|
2697
|
+
const prevCleanup = node._cleanup;
|
|
2537
2698
|
node._cleanup = undefined;
|
|
2699
|
+
prevCleanup?.();
|
|
2538
2700
|
const cleanup = staleValues(fn);
|
|
2539
2701
|
if (cleanup !== undefined && typeof cleanup !== "function") {
|
|
2540
2702
|
throw new Error(
|
|
@@ -2554,12 +2716,14 @@ function trackedEffect(fn, options) {
|
|
|
2554
2716
|
if (actualStatus & STATUS_ERROR) {
|
|
2555
2717
|
node._queue.notify(node, STATUS_PENDING, 0);
|
|
2556
2718
|
const err = error !== undefined ? error : node._error;
|
|
2557
|
-
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR))
|
|
2719
|
+
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
|
|
2720
|
+
haltReactivity();
|
|
2721
|
+
throw err;
|
|
2722
|
+
}
|
|
2558
2723
|
}
|
|
2559
2724
|
};
|
|
2560
2725
|
node._run = run;
|
|
2561
2726
|
node._queue.enqueue(EFFECT_USER, run);
|
|
2562
|
-
cleanup(() => node._cleanup?.());
|
|
2563
2727
|
if (!node._parent) {
|
|
2564
2728
|
const message =
|
|
2565
2729
|
"[NO_OWNER_EFFECT] Effects created outside a reactive context will never be disposed";
|
|
@@ -2603,13 +2767,12 @@ function action(genFn) {
|
|
|
2603
2767
|
} catch (e) {
|
|
2604
2768
|
return done(undefined, e);
|
|
2605
2769
|
}
|
|
2606
|
-
if (r
|
|
2607
|
-
return void r.then(run, e => restoreTransition(ctx, () => step(e, true)));
|
|
2770
|
+
if (isThenable(r)) return void r.then(run, e => done(undefined, e));
|
|
2608
2771
|
run(r);
|
|
2609
2772
|
};
|
|
2610
2773
|
const run = r => {
|
|
2611
2774
|
if (r.done) return done(r.value);
|
|
2612
|
-
if (r.value
|
|
2775
|
+
if (isThenable(r.value))
|
|
2613
2776
|
return void r.value.then(
|
|
2614
2777
|
v => restoreTransition(ctx, () => step(v)),
|
|
2615
2778
|
e => restoreTransition(ctx, () => step(e, true))
|
|
@@ -2729,15 +2892,18 @@ function resolve(fn) {
|
|
|
2729
2892
|
}
|
|
2730
2893
|
return new Promise((res, rej) => {
|
|
2731
2894
|
createRoot(dispose => {
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2895
|
+
effect(
|
|
2896
|
+
fn,
|
|
2897
|
+
value => {
|
|
2898
|
+
res(value);
|
|
2899
|
+
dispose();
|
|
2900
|
+
},
|
|
2901
|
+
err => {
|
|
2737
2902
|
rej(err);
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2903
|
+
dispose();
|
|
2904
|
+
},
|
|
2905
|
+
{ user: true }
|
|
2906
|
+
);
|
|
2741
2907
|
});
|
|
2742
2908
|
});
|
|
2743
2909
|
}
|
|
@@ -2757,27 +2923,110 @@ function onSettled(callback) {
|
|
|
2757
2923
|
? createTrackedEffect(() => untrack(callback), { name: "onSettled" })
|
|
2758
2924
|
: globalQueue.enqueue(EFFECT_USER, () => {
|
|
2759
2925
|
const cleanup = callback();
|
|
2760
|
-
if (cleanup !== undefined
|
|
2761
|
-
|
|
2762
|
-
"onSettled
|
|
2763
|
-
|
|
2926
|
+
if (cleanup !== undefined) {
|
|
2927
|
+
const message =
|
|
2928
|
+
"[SETTLED_CLEANUP_UNOWNED] onSettled returned a cleanup in an unowned scope; a cleanup can only be honored under an owner. Call your setup helper from an owned scope (e.g. the component body) instead of from inside an event handler, tracked effect, or another onSettled.";
|
|
2929
|
+
emitDiagnostic({
|
|
2930
|
+
code: "SETTLED_CLEANUP_UNOWNED",
|
|
2931
|
+
kind: "lifecycle",
|
|
2932
|
+
severity: "error",
|
|
2933
|
+
message: message
|
|
2934
|
+
});
|
|
2935
|
+
throw new Error(message);
|
|
2764
2936
|
}
|
|
2765
|
-
cleanup?.();
|
|
2766
2937
|
});
|
|
2767
2938
|
}
|
|
2939
|
+
function nodeKeys(nodes) {
|
|
2940
|
+
const keys = Object.keys(nodes);
|
|
2941
|
+
if (symbolKeyedRecords.has(nodes)) {
|
|
2942
|
+
const syms = Object.getOwnPropertySymbols(nodes);
|
|
2943
|
+
for (let i = 0, len = syms.length; i < len; i++) {
|
|
2944
|
+
if (syms[i] !== $TRACK) keys.push(syms[i]);
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2947
|
+
return keys;
|
|
2948
|
+
}
|
|
2768
2949
|
function unwrap(value) {
|
|
2769
|
-
|
|
2950
|
+
if (value === null || typeof value !== "object") return value;
|
|
2951
|
+
return value[$TARGET]?.[STORE_VALUE] ?? value;
|
|
2770
2952
|
}
|
|
2771
2953
|
function getOverrideValue(value, override, key, optOverride) {
|
|
2772
2954
|
if (optOverride && key in optOverride) return optOverride[key];
|
|
2773
2955
|
return override && key in override ? override[key] : value[key];
|
|
2774
2956
|
}
|
|
2957
|
+
function addEnumSymbols(o, syms, keys) {
|
|
2958
|
+
for (let i = 0, len = syms.length; i < len; i++) {
|
|
2959
|
+
if (Object.prototype.propertyIsEnumerable.call(o, syms[i])) keys.add(syms[i]);
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2775
2962
|
function getAllKeys(value, override, next) {
|
|
2776
2963
|
const keys = getKeys(value, override);
|
|
2777
2964
|
const nextKeys = Object.keys(next);
|
|
2778
|
-
|
|
2965
|
+
const valueSyms = value[$TARGET]
|
|
2966
|
+
? untrack(() => Object.getOwnPropertySymbols(value))
|
|
2967
|
+
: Object.getOwnPropertySymbols(value);
|
|
2968
|
+
const nextSyms = Object.getOwnPropertySymbols(next);
|
|
2969
|
+
if (valueSyms.length === 0 && nextSyms.length === 0) {
|
|
2970
|
+
if (keys.length === nextKeys.length) {
|
|
2971
|
+
let same = true;
|
|
2972
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2973
|
+
if (keys[i] !== nextKeys[i]) {
|
|
2974
|
+
same = false;
|
|
2975
|
+
break;
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
if (same) return keys;
|
|
2979
|
+
}
|
|
2980
|
+
const set = new Set(keys);
|
|
2981
|
+
for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
|
|
2982
|
+
return Array.from(set);
|
|
2983
|
+
}
|
|
2984
|
+
const set = new Set(keys);
|
|
2985
|
+
addEnumSymbols(value, valueSyms, set);
|
|
2986
|
+
if (override) {
|
|
2987
|
+
for (const key of Reflect.ownKeys(override)) {
|
|
2988
|
+
override[key] === $DELETED ? set.delete(key) : set.add(key);
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
|
|
2992
|
+
addEnumSymbols(next, nextSyms, set);
|
|
2993
|
+
return Array.from(set);
|
|
2994
|
+
}
|
|
2995
|
+
function wrapValue(value, target) {
|
|
2996
|
+
return isWrappable(value) ? wrap(value, target) : value;
|
|
2997
|
+
}
|
|
2998
|
+
function itemKey(item, keyFn) {
|
|
2999
|
+
return isWrappable(item) ? keyFn(item) : item;
|
|
3000
|
+
}
|
|
3001
|
+
function keyedMatch(a, b, keyFn) {
|
|
3002
|
+
return a === b || (isWrappable(a) && isWrappable(b) && keyFn(a) === keyFn(b));
|
|
3003
|
+
}
|
|
3004
|
+
function syncArrayNodeMembership(target, next) {
|
|
3005
|
+
let nodes = target[STORE_NODE];
|
|
3006
|
+
if (nodes) {
|
|
3007
|
+
const keys = nodeKeys(nodes);
|
|
3008
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3009
|
+
const key = keys[i];
|
|
3010
|
+
key in next || setSignal(nodes[key], undefined);
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
if ((nodes = target[STORE_HAS])) {
|
|
3014
|
+
const keys = nodeKeys(nodes);
|
|
3015
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3016
|
+
const key = keys[i];
|
|
3017
|
+
setSignal(nodes[key], key in next);
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
function applyArrayItem(next, previous, target, node, keyFn) {
|
|
3022
|
+
if (isWrappable(next) && isWrappable(previous)) {
|
|
3023
|
+
const wrapped = wrap(previous, target);
|
|
3024
|
+
node && setSignal(node, wrapped);
|
|
3025
|
+
applyState(next, wrapped, keyFn);
|
|
3026
|
+
} else node && setSignal(node, wrapValue(next, target));
|
|
2779
3027
|
}
|
|
2780
3028
|
function applyState(next, state, keyFn) {
|
|
3029
|
+
next = unwrap(next);
|
|
2781
3030
|
const target = state?.[$TARGET];
|
|
2782
3031
|
if (!target) return;
|
|
2783
3032
|
if (target[STORE_OVERRIDE] || target[STORE_OPTIMISTIC_OVERRIDE]) {
|
|
@@ -2789,30 +3038,28 @@ function applyState(next, state, keyFn) {
|
|
|
2789
3038
|
function applyStateFast(next, target, keyFn) {
|
|
2790
3039
|
const previous = target[STORE_VALUE];
|
|
2791
3040
|
if (next === previous) return;
|
|
3041
|
+
const arrayNodes = target[STORE_NODE];
|
|
2792
3042
|
(target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
|
|
2793
3043
|
target[STORE_VALUE] = next;
|
|
2794
3044
|
if (Array.isArray(previous)) {
|
|
2795
3045
|
let changed = false;
|
|
2796
3046
|
const prevLength = previous.length;
|
|
2797
|
-
if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
|
|
3047
|
+
if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
|
|
2798
3048
|
let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
|
|
2799
3049
|
for (
|
|
2800
3050
|
start = 0, end = Math.min(prevLength, next.length);
|
|
2801
|
-
start < end &&
|
|
2802
|
-
((item = previous[start]) === next[start] ||
|
|
2803
|
-
(item && next[start] && keyFn(item) === keyFn(next[start])));
|
|
3051
|
+
start < end && keyedMatch((item = previous[start]), next[start], keyFn);
|
|
2804
3052
|
start++
|
|
2805
3053
|
) {
|
|
2806
|
-
|
|
3054
|
+
isWrappable(item) &&
|
|
3055
|
+
isWrappable(next[start]) &&
|
|
3056
|
+
applyState(next[start], wrap(item, target), keyFn);
|
|
2807
3057
|
}
|
|
2808
3058
|
const temp = new Array(next.length),
|
|
2809
3059
|
newIndices = new Map();
|
|
2810
3060
|
for (
|
|
2811
3061
|
end = prevLength - 1, newEnd = next.length - 1;
|
|
2812
|
-
end >= start &&
|
|
2813
|
-
newEnd >= start &&
|
|
2814
|
-
((item = previous[end]) === next[newEnd] ||
|
|
2815
|
-
(item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])));
|
|
3062
|
+
end >= start && newEnd >= start && keyedMatch((item = previous[end]), next[newEnd], keyFn);
|
|
2816
3063
|
end--, newEnd--
|
|
2817
3064
|
) {
|
|
2818
3065
|
temp[newEnd] = item;
|
|
@@ -2820,31 +3067,30 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2820
3067
|
if (start > newEnd || start > end) {
|
|
2821
3068
|
for (j = start; j <= newEnd; j++) {
|
|
2822
3069
|
changed = true;
|
|
2823
|
-
|
|
3070
|
+
arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
|
|
2824
3071
|
}
|
|
2825
3072
|
for (; j < next.length; j++) {
|
|
2826
3073
|
changed = true;
|
|
2827
|
-
|
|
2828
|
-
target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrapped);
|
|
2829
|
-
applyState(next[j], wrapped, keyFn);
|
|
3074
|
+
applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
|
|
2830
3075
|
}
|
|
2831
|
-
|
|
3076
|
+
syncArrayNodeMembership(target, next);
|
|
3077
|
+
(changed || prevLength !== next.length) && notifySelf(target);
|
|
2832
3078
|
prevLength !== next.length &&
|
|
2833
|
-
|
|
2834
|
-
setSignal(
|
|
3079
|
+
arrayNodes?.length &&
|
|
3080
|
+
setSignal(arrayNodes.length, next.length);
|
|
2835
3081
|
return;
|
|
2836
3082
|
}
|
|
2837
3083
|
newIndicesNext = new Array(newEnd + 1);
|
|
2838
3084
|
for (j = newEnd; j >= start; j--) {
|
|
2839
3085
|
item = next[j];
|
|
2840
|
-
keyVal = item
|
|
3086
|
+
keyVal = itemKey(item, keyFn);
|
|
2841
3087
|
i = newIndices.get(keyVal);
|
|
2842
3088
|
newIndicesNext[j] = i === undefined ? -1 : i;
|
|
2843
3089
|
newIndices.set(keyVal, j);
|
|
2844
3090
|
}
|
|
2845
3091
|
for (i = start; i <= end; i++) {
|
|
2846
3092
|
item = previous[i];
|
|
2847
|
-
keyVal = item
|
|
3093
|
+
keyVal = itemKey(item, keyFn);
|
|
2848
3094
|
j = newIndices.get(keyVal);
|
|
2849
3095
|
if (j !== undefined && j !== -1) {
|
|
2850
3096
|
temp[j] = item;
|
|
@@ -2854,31 +3100,33 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2854
3100
|
}
|
|
2855
3101
|
for (j = start; j < next.length; j++) {
|
|
2856
3102
|
if (j in temp) {
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
applyState(next[j], wrapped, keyFn);
|
|
2860
|
-
} else target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrap(next[j], target));
|
|
3103
|
+
applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
|
|
3104
|
+
} else arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
|
|
2861
3105
|
}
|
|
2862
3106
|
if (start < next.length) changed = true;
|
|
2863
3107
|
} else if (next.length) {
|
|
2864
3108
|
for (let i = 0, len = next.length; i < len; i++) {
|
|
2865
3109
|
const item = previous[i];
|
|
2866
|
-
isWrappable(item)
|
|
2867
|
-
|
|
2868
|
-
|
|
3110
|
+
if (isWrappable(item) && isWrappable(next[i]))
|
|
3111
|
+
applyState(next[i], wrap(item, target), keyFn);
|
|
3112
|
+
else {
|
|
3113
|
+
if (item !== next[i]) changed = true;
|
|
3114
|
+
arrayNodes?.[i] && setSignal(arrayNodes[i], wrapValue(next[i], target));
|
|
3115
|
+
}
|
|
2869
3116
|
}
|
|
2870
3117
|
}
|
|
3118
|
+
syncArrayNodeMembership(target, next);
|
|
2871
3119
|
if (prevLength !== next.length) {
|
|
2872
3120
|
changed = true;
|
|
2873
|
-
|
|
3121
|
+
arrayNodes?.length && setSignal(arrayNodes.length, next.length);
|
|
2874
3122
|
}
|
|
2875
|
-
changed &&
|
|
3123
|
+
changed && notifySelf(target);
|
|
2876
3124
|
return;
|
|
2877
3125
|
}
|
|
2878
3126
|
let nodes = target[STORE_NODE];
|
|
2879
3127
|
if (nodes) {
|
|
2880
3128
|
const tracked = nodes[$TRACK];
|
|
2881
|
-
const keys = tracked ? getAllKeys(previous, undefined, next) :
|
|
3129
|
+
const keys = tracked ? getAllKeys(previous, undefined, next) : nodeKeys(nodes);
|
|
2882
3130
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
2883
3131
|
const key = keys[i];
|
|
2884
3132
|
const node = nodes[key];
|
|
@@ -2889,6 +3137,7 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2889
3137
|
!previousValue ||
|
|
2890
3138
|
!isWrappable(previousValue) ||
|
|
2891
3139
|
!isWrappable(nextValue) ||
|
|
3140
|
+
Array.isArray(previousValue) !== Array.isArray(nextValue) ||
|
|
2892
3141
|
(keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
|
|
2893
3142
|
) {
|
|
2894
3143
|
tracked && setSignal(tracked, void 0);
|
|
@@ -2897,7 +3146,7 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2897
3146
|
}
|
|
2898
3147
|
}
|
|
2899
3148
|
if ((nodes = target[STORE_HAS])) {
|
|
2900
|
-
const keys =
|
|
3149
|
+
const keys = nodeKeys(nodes);
|
|
2901
3150
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
2902
3151
|
const key = keys[i];
|
|
2903
3152
|
setSignal(nodes[key], key in next);
|
|
@@ -2915,16 +3164,21 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
2915
3164
|
if (Array.isArray(previous)) {
|
|
2916
3165
|
let changed = false;
|
|
2917
3166
|
const prevLength = getOverrideValue(previous, override, "length", optOverride);
|
|
2918
|
-
if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
|
|
3167
|
+
if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
|
|
2919
3168
|
let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
|
|
2920
3169
|
for (
|
|
2921
3170
|
start = 0, end = Math.min(prevLength, next.length);
|
|
2922
3171
|
start < end &&
|
|
2923
|
-
(
|
|
2924
|
-
(item
|
|
3172
|
+
keyedMatch(
|
|
3173
|
+
(item = getOverrideValue(previous, override, start, optOverride)),
|
|
3174
|
+
next[start],
|
|
3175
|
+
keyFn
|
|
3176
|
+
);
|
|
2925
3177
|
start++
|
|
2926
3178
|
) {
|
|
2927
|
-
|
|
3179
|
+
isWrappable(item) &&
|
|
3180
|
+
isWrappable(next[start]) &&
|
|
3181
|
+
applyState(next[start], wrap(item, target), keyFn);
|
|
2928
3182
|
}
|
|
2929
3183
|
const temp = new Array(next.length),
|
|
2930
3184
|
newIndices = new Map();
|
|
@@ -2932,8 +3186,11 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
2932
3186
|
end = prevLength - 1, newEnd = next.length - 1;
|
|
2933
3187
|
end >= start &&
|
|
2934
3188
|
newEnd >= start &&
|
|
2935
|
-
(
|
|
2936
|
-
(item
|
|
3189
|
+
keyedMatch(
|
|
3190
|
+
(item = getOverrideValue(previous, override, end, optOverride)),
|
|
3191
|
+
next[newEnd],
|
|
3192
|
+
keyFn
|
|
3193
|
+
);
|
|
2937
3194
|
end--, newEnd--
|
|
2938
3195
|
) {
|
|
2939
3196
|
temp[newEnd] = item;
|
|
@@ -2941,31 +3198,29 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
2941
3198
|
if (start > newEnd || start > end) {
|
|
2942
3199
|
for (j = start; j <= newEnd; j++) {
|
|
2943
3200
|
changed = true;
|
|
2944
|
-
|
|
3201
|
+
nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
|
|
2945
3202
|
}
|
|
2946
3203
|
for (; j < next.length; j++) {
|
|
2947
3204
|
changed = true;
|
|
2948
|
-
|
|
2949
|
-
target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrapped);
|
|
2950
|
-
applyState(next[j], wrapped, keyFn);
|
|
3205
|
+
applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
|
|
2951
3206
|
}
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
3207
|
+
const nextLength = next.length;
|
|
3208
|
+
syncArrayNodeMembership(target, next);
|
|
3209
|
+
(changed || prevLength !== nextLength) && notifySelf(target);
|
|
3210
|
+
prevLength !== nextLength && nodes?.length && setSignal(nodes.length, nextLength);
|
|
2956
3211
|
return;
|
|
2957
3212
|
}
|
|
2958
3213
|
newIndicesNext = new Array(newEnd + 1);
|
|
2959
3214
|
for (j = newEnd; j >= start; j--) {
|
|
2960
3215
|
item = next[j];
|
|
2961
|
-
keyVal = item
|
|
3216
|
+
keyVal = itemKey(item, keyFn);
|
|
2962
3217
|
i = newIndices.get(keyVal);
|
|
2963
3218
|
newIndicesNext[j] = i === undefined ? -1 : i;
|
|
2964
3219
|
newIndices.set(keyVal, j);
|
|
2965
3220
|
}
|
|
2966
3221
|
for (i = start; i <= end; i++) {
|
|
2967
3222
|
item = getOverrideValue(previous, override, i, optOverride);
|
|
2968
|
-
keyVal = item
|
|
3223
|
+
keyVal = itemKey(item, keyFn);
|
|
2969
3224
|
j = newIndices.get(keyVal);
|
|
2970
3225
|
if (j !== undefined && j !== -1) {
|
|
2971
3226
|
temp[j] = item;
|
|
@@ -2975,30 +3230,33 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
2975
3230
|
}
|
|
2976
3231
|
for (j = start; j < next.length; j++) {
|
|
2977
3232
|
if (j in temp) {
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
applyState(next[j], wrapped, keyFn);
|
|
2981
|
-
} else target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrap(next[j], target));
|
|
3233
|
+
applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
|
|
3234
|
+
} else nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
|
|
2982
3235
|
}
|
|
2983
3236
|
if (start < next.length) changed = true;
|
|
2984
3237
|
} else if (next.length) {
|
|
2985
3238
|
for (let i = 0, len = next.length; i < len; i++) {
|
|
2986
3239
|
const item = getOverrideValue(previous, override, i, optOverride);
|
|
2987
|
-
isWrappable(item)
|
|
2988
|
-
|
|
2989
|
-
|
|
3240
|
+
if (isWrappable(item) && isWrappable(next[i]))
|
|
3241
|
+
applyState(next[i], wrap(item, target), keyFn);
|
|
3242
|
+
else {
|
|
3243
|
+
if (item !== next[i]) changed = true;
|
|
3244
|
+
nodes?.[i] && setSignal(nodes[i], wrapValue(next[i], target));
|
|
3245
|
+
}
|
|
2990
3246
|
}
|
|
2991
3247
|
}
|
|
2992
|
-
|
|
3248
|
+
const nextLength = next.length;
|
|
3249
|
+
syncArrayNodeMembership(target, next);
|
|
3250
|
+
if (prevLength !== nextLength) {
|
|
2993
3251
|
changed = true;
|
|
2994
|
-
|
|
3252
|
+
nodes?.length && setSignal(nodes.length, nextLength);
|
|
2995
3253
|
}
|
|
2996
|
-
changed &&
|
|
3254
|
+
changed && notifySelf(target);
|
|
2997
3255
|
return;
|
|
2998
3256
|
}
|
|
2999
3257
|
if (nodes) {
|
|
3000
3258
|
const tracked = nodes[$TRACK];
|
|
3001
|
-
const keys = tracked ? getAllKeys(previous, override, next) :
|
|
3259
|
+
const keys = tracked ? getAllKeys(previous, override, next) : nodeKeys(nodes);
|
|
3002
3260
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3003
3261
|
const key = keys[i];
|
|
3004
3262
|
const node = nodes[key];
|
|
@@ -3009,6 +3267,7 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
3009
3267
|
!previousValue ||
|
|
3010
3268
|
!isWrappable(previousValue) ||
|
|
3011
3269
|
!isWrappable(nextValue) ||
|
|
3270
|
+
Array.isArray(previousValue) !== Array.isArray(nextValue) ||
|
|
3012
3271
|
(keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
|
|
3013
3272
|
) {
|
|
3014
3273
|
tracked && setSignal(tracked, void 0);
|
|
@@ -3017,7 +3276,7 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
3017
3276
|
}
|
|
3018
3277
|
}
|
|
3019
3278
|
if ((nodes = target[STORE_HAS])) {
|
|
3020
|
-
const keys =
|
|
3279
|
+
const keys = nodeKeys(nodes);
|
|
3021
3280
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3022
3281
|
const key = keys[i];
|
|
3023
3282
|
setSignal(nodes[key], key in next);
|
|
@@ -3029,7 +3288,7 @@ function reconcile(value, key) {
|
|
|
3029
3288
|
if (state == null) throw new Error("Cannot reconcile null or undefined state");
|
|
3030
3289
|
const keyFn = typeof key === "string" ? item => item[key] : key;
|
|
3031
3290
|
const eq = keyFn(state);
|
|
3032
|
-
if (eq !== undefined && keyFn(value) !==
|
|
3291
|
+
if (eq !== undefined && keyFn(value) !== eq)
|
|
3033
3292
|
throw new Error("Cannot reconcile states with different identity");
|
|
3034
3293
|
applyState(value, state, keyFn);
|
|
3035
3294
|
};
|
|
@@ -3068,13 +3327,13 @@ function createProjectionInternal(fn, seed, options) {
|
|
|
3068
3327
|
function createProjection(fn, seed, options) {
|
|
3069
3328
|
return createProjectionInternal(fn, seed, options).store;
|
|
3070
3329
|
}
|
|
3071
|
-
function runProjectionComputed(wrappedStore, fn, key, wrapCommit) {
|
|
3330
|
+
function runProjectionComputed(wrappedStore, fn, key, wrapCommit, onDraftWrite) {
|
|
3072
3331
|
const owner = getOwner();
|
|
3073
3332
|
let settled = false;
|
|
3074
3333
|
let result;
|
|
3075
3334
|
const draft = new Proxy(
|
|
3076
3335
|
wrappedStore,
|
|
3077
|
-
createWriteTraps(() => !settled || owner._inFlight === result)
|
|
3336
|
+
createWriteTraps(() => !settled || owner._inFlight === result, onDraftWrite)
|
|
3078
3337
|
);
|
|
3079
3338
|
storeSetter(draft, s => {
|
|
3080
3339
|
result = fn(s);
|
|
@@ -3088,7 +3347,7 @@ function runProjectionComputed(wrappedStore, fn, key, wrapCommit) {
|
|
|
3088
3347
|
});
|
|
3089
3348
|
return owner;
|
|
3090
3349
|
}
|
|
3091
|
-
function createWriteTraps(isActive) {
|
|
3350
|
+
function createWriteTraps(isActive, onDraftWrite) {
|
|
3092
3351
|
const traps = {
|
|
3093
3352
|
get(_, prop) {
|
|
3094
3353
|
let value;
|
|
@@ -3100,6 +3359,7 @@ function createWriteTraps(isActive) {
|
|
|
3100
3359
|
setWriteOverride(false);
|
|
3101
3360
|
setProjectionWriteActive(false);
|
|
3102
3361
|
}
|
|
3362
|
+
if (prop === $TARGET) return value;
|
|
3103
3363
|
return typeof value === "object" && value !== null ? new Proxy(value, traps) : value;
|
|
3104
3364
|
},
|
|
3105
3365
|
has(_, prop) {
|
|
@@ -3120,6 +3380,7 @@ function createWriteTraps(isActive) {
|
|
|
3120
3380
|
setProjectionWriteActive(true);
|
|
3121
3381
|
try {
|
|
3122
3382
|
_[prop] = value;
|
|
3383
|
+
onDraftWrite?.();
|
|
3123
3384
|
} finally {
|
|
3124
3385
|
setWriteOverride(false);
|
|
3125
3386
|
setProjectionWriteActive(false);
|
|
@@ -3132,6 +3393,7 @@ function createWriteTraps(isActive) {
|
|
|
3132
3393
|
setProjectionWriteActive(true);
|
|
3133
3394
|
try {
|
|
3134
3395
|
delete _[prop];
|
|
3396
|
+
onDraftWrite?.();
|
|
3135
3397
|
} finally {
|
|
3136
3398
|
setWriteOverride(false);
|
|
3137
3399
|
setProjectionWriteActive(false);
|
|
@@ -3154,7 +3416,9 @@ const STORE_VALUE = "v",
|
|
|
3154
3416
|
STORE_WRAP = "w",
|
|
3155
3417
|
STORE_LOOKUP = "l",
|
|
3156
3418
|
STORE_FIREWALL = "f",
|
|
3157
|
-
STORE_OPTIMISTIC = "p"
|
|
3419
|
+
STORE_OPTIMISTIC = "p",
|
|
3420
|
+
STORE_MASKED = "m";
|
|
3421
|
+
const STORE_SELF_PENDING = Symbol("STORE_SELF_PENDING");
|
|
3158
3422
|
function createStoreProxy(value, traps = storeTraps, extend) {
|
|
3159
3423
|
let newTarget;
|
|
3160
3424
|
if (Array.isArray(value)) {
|
|
@@ -3172,6 +3436,7 @@ function createStoreProxy(value, traps = storeTraps, extend) {
|
|
|
3172
3436
|
return (newTarget[$PROXY] = new Proxy(newTarget, traps));
|
|
3173
3437
|
}
|
|
3174
3438
|
const storeLookup = new WeakMap();
|
|
3439
|
+
const symbolKeyedRecords = new WeakSet();
|
|
3175
3440
|
function wrap(value, target) {
|
|
3176
3441
|
if (target?.[STORE_WRAP]) return target[STORE_WRAP](value, target);
|
|
3177
3442
|
let p = value[$PROXY] || storeLookup.get(value);
|
|
@@ -3189,27 +3454,49 @@ function setWriteOverride(value) {
|
|
|
3189
3454
|
function writeOnly(proxy) {
|
|
3190
3455
|
return writeOverride || !!Writing?.has(proxy);
|
|
3191
3456
|
}
|
|
3192
|
-
function unwrapStoreValue(value) {
|
|
3193
|
-
|
|
3457
|
+
function unwrapStoreValue(value, map, lookup) {
|
|
3458
|
+
const target = value?.[$TARGET] || lookup?.get(value)?.[$TARGET];
|
|
3459
|
+
if (!target) return value;
|
|
3460
|
+
const override = target[STORE_OVERRIDE];
|
|
3461
|
+
if (!override) return target[STORE_VALUE];
|
|
3462
|
+
if (!map) map = new Map();
|
|
3463
|
+
if (map.has(value)) return map.get(value);
|
|
3464
|
+
const source = target[STORE_VALUE];
|
|
3465
|
+
const isArray = Array.isArray(source);
|
|
3466
|
+
const result = isArray ? [] : Object.create(Object.getPrototypeOf(source));
|
|
3467
|
+
map.set(value, result);
|
|
3468
|
+
lookup = target[STORE_LOOKUP] ?? storeLookup;
|
|
3469
|
+
for (const key of getKeys(source, override)) {
|
|
3470
|
+
if (isArray && key === "length") continue;
|
|
3471
|
+
const next = key in override ? override[key] : source[key];
|
|
3472
|
+
if (next !== $DELETED) result[key] = unwrapStoreValue(next, map, lookup);
|
|
3473
|
+
}
|
|
3474
|
+
if (isArray) result.length = override.length ?? source.length;
|
|
3475
|
+
return result;
|
|
3194
3476
|
}
|
|
3195
3477
|
function isPrototypePollutionKey$1(property) {
|
|
3196
3478
|
return property === "__proto__" || property === "constructor" || property === "prototype";
|
|
3197
3479
|
}
|
|
3198
|
-
function
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
)
|
|
3205
|
-
return true;
|
|
3480
|
+
function ownEnumerableKeys(o) {
|
|
3481
|
+
return Reflect.ownKeys(o).filter(k => Object.prototype.propertyIsEnumerable.call(o, k));
|
|
3482
|
+
}
|
|
3483
|
+
function getOverlayLayer(target, property) {
|
|
3484
|
+
const opt = target[STORE_OPTIMISTIC_OVERRIDE];
|
|
3485
|
+
if (opt && property in opt) return opt;
|
|
3206
3486
|
const override = target[STORE_OVERRIDE];
|
|
3207
|
-
if (
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3487
|
+
if (override && property in override) return override;
|
|
3488
|
+
return undefined;
|
|
3489
|
+
}
|
|
3490
|
+
function visibleNodeValue(node) {
|
|
3491
|
+
return node._overrideValue !== undefined && node._overrideValue !== NOT_PENDING
|
|
3492
|
+
? node._overrideValue
|
|
3493
|
+
: node._pendingValue !== NOT_PENDING
|
|
3494
|
+
? node._pendingValue
|
|
3495
|
+
: node._value;
|
|
3496
|
+
}
|
|
3497
|
+
function hasOwnStoreProperty(target, property) {
|
|
3498
|
+
const layer = getOverlayLayer(target, property);
|
|
3499
|
+
if (layer) return layer[property] !== $DELETED;
|
|
3213
3500
|
return Object.prototype.hasOwnProperty.call(unwrapStoreValue(target[STORE_VALUE]), property);
|
|
3214
3501
|
}
|
|
3215
3502
|
function hasInheritedAccessor(source, property) {
|
|
@@ -3233,7 +3520,24 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
|
|
|
3233
3520
|
{
|
|
3234
3521
|
equals: equals,
|
|
3235
3522
|
unobserved() {
|
|
3236
|
-
if (nodes[property] === s)
|
|
3523
|
+
if (nodes[property] === s) {
|
|
3524
|
+
delete nodes[property];
|
|
3525
|
+
if (
|
|
3526
|
+
typeof property === "symbol" &&
|
|
3527
|
+
property !== $TRACK &&
|
|
3528
|
+
symbolKeyedRecords.has(nodes)
|
|
3529
|
+
) {
|
|
3530
|
+
const syms = Object.getOwnPropertySymbols(nodes);
|
|
3531
|
+
let hasUserSymbol = false;
|
|
3532
|
+
for (let i = 0, len = syms.length; i < len; i++) {
|
|
3533
|
+
if (syms[i] !== $TRACK) {
|
|
3534
|
+
hasUserSymbol = true;
|
|
3535
|
+
break;
|
|
3536
|
+
}
|
|
3537
|
+
}
|
|
3538
|
+
if (!hasUserSymbol) symbolKeyedRecords.delete(nodes);
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3237
3541
|
}
|
|
3238
3542
|
},
|
|
3239
3543
|
firewall
|
|
@@ -3246,6 +3550,7 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
|
|
|
3246
3550
|
s._snapshotValue = sv === undefined ? NO_SNAPSHOT : sv;
|
|
3247
3551
|
snapshotSources?.add(s);
|
|
3248
3552
|
}
|
|
3553
|
+
if (typeof property === "symbol" && property !== $TRACK) symbolKeyedRecords.add(nodes);
|
|
3249
3554
|
return (nodes[property] = s);
|
|
3250
3555
|
}
|
|
3251
3556
|
function trackSelf(target, symbol = $TRACK) {
|
|
@@ -3261,8 +3566,20 @@ function trackSelf(target, symbol = $TRACK) {
|
|
|
3261
3566
|
)
|
|
3262
3567
|
);
|
|
3263
3568
|
}
|
|
3569
|
+
function notifySelf(target) {
|
|
3570
|
+
const node = target[STORE_NODE]?.[$TRACK];
|
|
3571
|
+
node &&
|
|
3572
|
+
setSignal(
|
|
3573
|
+
node,
|
|
3574
|
+
target[STORE_OPTIMISTIC] && !projectionWriteActive ? STORE_SELF_PENDING : undefined
|
|
3575
|
+
);
|
|
3576
|
+
}
|
|
3264
3577
|
function getKeys(source, override, enumerable = true) {
|
|
3265
|
-
const baseKeys =
|
|
3578
|
+
const baseKeys = source[$TARGET]
|
|
3579
|
+
? untrack(() => (enumerable ? Object.keys(source) : Reflect.ownKeys(source)))
|
|
3580
|
+
: enumerable
|
|
3581
|
+
? Object.keys(source)
|
|
3582
|
+
: Reflect.ownKeys(source);
|
|
3266
3583
|
if (!override) return baseKeys;
|
|
3267
3584
|
const keys = new Set(baseKeys);
|
|
3268
3585
|
const overrides = Reflect.ownKeys(override);
|
|
@@ -3276,10 +3593,26 @@ function getPropertyDescriptor(source, override, property) {
|
|
|
3276
3593
|
if (override && property in override) {
|
|
3277
3594
|
if (override[property] === $DELETED) return void 0;
|
|
3278
3595
|
const overrideDesc = Reflect.getOwnPropertyDescriptor(override, property);
|
|
3279
|
-
if (overrideDesc?.get || overrideDesc?.set
|
|
3596
|
+
if (overrideDesc?.get || overrideDesc?.set) return overrideDesc;
|
|
3597
|
+
const baseDesc = Reflect.getOwnPropertyDescriptor(source, property);
|
|
3598
|
+
if (!baseDesc) return overrideDesc;
|
|
3599
|
+
if (baseDesc.get || baseDesc.set) return baseDesc;
|
|
3600
|
+
baseDesc.value = override[property];
|
|
3601
|
+
return baseDesc;
|
|
3280
3602
|
}
|
|
3281
3603
|
return Reflect.getOwnPropertyDescriptor(source, property);
|
|
3282
3604
|
}
|
|
3605
|
+
function maskStoreTarget(target, on) {
|
|
3606
|
+
const firewall = target[STORE_FIREWALL];
|
|
3607
|
+
if (!firewall) return;
|
|
3608
|
+
if (!!target[STORE_MASKED] === on) return;
|
|
3609
|
+
target[STORE_MASKED] = on;
|
|
3610
|
+
const count = (firewall._optimisticMask = (firewall._optimisticMask || 0) + (on ? 1 : -1));
|
|
3611
|
+
if ((on && count === 1) || (!on && count === 0)) {
|
|
3612
|
+
updatePendingSignal(firewall);
|
|
3613
|
+
updateChildCompanions(firewall);
|
|
3614
|
+
}
|
|
3615
|
+
}
|
|
3283
3616
|
function prepareStoreWrite(target, store, property) {
|
|
3284
3617
|
if (target[STORE_OPTIMISTIC]) {
|
|
3285
3618
|
const firewall = target[STORE_FIREWALL];
|
|
@@ -3304,9 +3637,14 @@ function prepareStoreWrite(target, store, property) {
|
|
|
3304
3637
|
}
|
|
3305
3638
|
const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
|
|
3306
3639
|
const overrideKey = useOptimistic ? STORE_OPTIMISTIC_OVERRIDE : STORE_OVERRIDE;
|
|
3307
|
-
if (useOptimistic) trackOptimisticStore(store);
|
|
3308
3640
|
return { base: base, overrideKey: overrideKey, state: state };
|
|
3309
3641
|
}
|
|
3642
|
+
function armOptimisticStoreWrite(target, store) {
|
|
3643
|
+
if (target[STORE_OPTIMISTIC] && !projectionWriteActive) {
|
|
3644
|
+
trackOptimisticStore(store);
|
|
3645
|
+
maskStoreTarget(target, true);
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3310
3648
|
function upsertStoreNode(target, nodes, property, prev, snapshotProps) {
|
|
3311
3649
|
if (nodes[property]) return nodes[property];
|
|
3312
3650
|
const initial = isWrappable(prev) ? wrap(prev, target) : prev;
|
|
@@ -3353,7 +3691,7 @@ function notifyStoreProperty(target, property, mode, value, prev, prevHas) {
|
|
|
3353
3691
|
setSignal(node, undefined);
|
|
3354
3692
|
}
|
|
3355
3693
|
}
|
|
3356
|
-
|
|
3694
|
+
notifySelf(target);
|
|
3357
3695
|
}
|
|
3358
3696
|
let Writing = null;
|
|
3359
3697
|
const storeTraps = {
|
|
@@ -3365,8 +3703,9 @@ const storeTraps = {
|
|
|
3365
3703
|
trackSelf(target);
|
|
3366
3704
|
return receiver;
|
|
3367
3705
|
}
|
|
3706
|
+
const selfRead = getObserver() === target[STORE_FIREWALL];
|
|
3368
3707
|
const nodes = getNodes(target, STORE_NODE);
|
|
3369
|
-
const tracked = nodes[property];
|
|
3708
|
+
const tracked = selfRead ? undefined : nodes[property];
|
|
3370
3709
|
const source = target[STORE_VALUE];
|
|
3371
3710
|
if (
|
|
3372
3711
|
!tracked &&
|
|
@@ -3378,20 +3717,15 @@ const storeTraps = {
|
|
|
3378
3717
|
!source[$TARGET] &&
|
|
3379
3718
|
!(property in source) &&
|
|
3380
3719
|
getObserver() &&
|
|
3720
|
+
!selfRead &&
|
|
3381
3721
|
!writeOnly(receiver)
|
|
3382
3722
|
) {
|
|
3383
3723
|
return read(getNode(nodes, property, undefined, target[STORE_FIREWALL]));
|
|
3384
3724
|
}
|
|
3385
|
-
const
|
|
3386
|
-
|
|
3387
|
-
const overridden =
|
|
3388
|
-
optOverridden || (target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]);
|
|
3725
|
+
const overlay = getOverlayLayer(target, property);
|
|
3726
|
+
const overridden = !!overlay;
|
|
3389
3727
|
const proxySource = !!target[STORE_VALUE][$TARGET];
|
|
3390
|
-
const storeValue =
|
|
3391
|
-
? target[STORE_OPTIMISTIC_OVERRIDE]
|
|
3392
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3393
|
-
? target[STORE_OVERRIDE]
|
|
3394
|
-
: target[STORE_VALUE];
|
|
3728
|
+
const storeValue = overlay ?? target[STORE_VALUE];
|
|
3395
3729
|
if (!tracked) {
|
|
3396
3730
|
const desc = Object.getOwnPropertyDescriptor(storeValue, property);
|
|
3397
3731
|
if (desc && desc.get) return desc.get.call(receiver);
|
|
@@ -3406,13 +3740,7 @@ const storeTraps = {
|
|
|
3406
3740
|
if (isPrototypePollutionKey$1(property) && !hasOwnStoreProperty(target, property))
|
|
3407
3741
|
return undefined;
|
|
3408
3742
|
let value =
|
|
3409
|
-
tracked && (overridden || !proxySource)
|
|
3410
|
-
? tracked._overrideValue !== undefined && tracked._overrideValue !== NOT_PENDING
|
|
3411
|
-
? tracked._overrideValue
|
|
3412
|
-
: tracked._pendingValue !== NOT_PENDING
|
|
3413
|
-
? tracked._pendingValue
|
|
3414
|
-
: tracked._value
|
|
3415
|
-
: storeValue[property];
|
|
3743
|
+
tracked && (overridden || !proxySource) ? visibleNodeValue(tracked) : storeValue[property];
|
|
3416
3744
|
value === $DELETED && (value = undefined);
|
|
3417
3745
|
if (!isWrappable(value)) return value;
|
|
3418
3746
|
const wrapped = wrap(value, target);
|
|
@@ -3426,14 +3754,18 @@ const storeTraps = {
|
|
|
3426
3754
|
: storeValue[property];
|
|
3427
3755
|
value === $DELETED && (value = undefined);
|
|
3428
3756
|
if (!tracked) {
|
|
3429
|
-
if (
|
|
3757
|
+
if (
|
|
3758
|
+
!overridden &&
|
|
3759
|
+
typeof value === "function" &&
|
|
3760
|
+
!Object.prototype.hasOwnProperty.call(storeValue, property)
|
|
3761
|
+
) {
|
|
3430
3762
|
let proto;
|
|
3431
3763
|
return !Array.isArray(target[STORE_VALUE]) &&
|
|
3432
3764
|
(proto = Object.getPrototypeOf(target[STORE_VALUE])) &&
|
|
3433
3765
|
proto !== Object.prototype
|
|
3434
3766
|
? value.bind(storeValue)
|
|
3435
3767
|
: value;
|
|
3436
|
-
} else if (getObserver()) {
|
|
3768
|
+
} else if (getObserver() && !selfRead) {
|
|
3437
3769
|
return read(
|
|
3438
3770
|
getNode(
|
|
3439
3771
|
nodes,
|
|
@@ -3465,13 +3797,9 @@ const storeTraps = {
|
|
|
3465
3797
|
},
|
|
3466
3798
|
has(target, property) {
|
|
3467
3799
|
if (property === $PROXY || property === $TRACK || property === "__proto__") return true;
|
|
3468
|
-
const
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3472
|
-
? target[STORE_OVERRIDE][property] !== $DELETED
|
|
3473
|
-
: property in target[STORE_VALUE];
|
|
3474
|
-
if (writeOnly(target[$PROXY])) return has;
|
|
3800
|
+
const hasLayer = getOverlayLayer(target, property);
|
|
3801
|
+
const has = hasLayer ? hasLayer[property] !== $DELETED : property in target[STORE_VALUE];
|
|
3802
|
+
if (writeOnly(target[$PROXY]) || getObserver() === target[STORE_FIREWALL]) return has;
|
|
3475
3803
|
const nodes = getNodes(target, STORE_HAS);
|
|
3476
3804
|
if (nodes[property]) return read(nodes[property]);
|
|
3477
3805
|
if (getObserver()) {
|
|
@@ -3491,30 +3819,19 @@ const storeTraps = {
|
|
|
3491
3819
|
overrideKey: overrideKey,
|
|
3492
3820
|
state: state
|
|
3493
3821
|
} = prepareStoreWrite(target, store, property);
|
|
3494
|
-
const
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
: base;
|
|
3500
|
-
const prevHas =
|
|
3501
|
-
target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
|
|
3502
|
-
? target[STORE_OPTIMISTIC_OVERRIDE][property] !== $DELETED
|
|
3503
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3504
|
-
? target[STORE_OVERRIDE][property] !== $DELETED
|
|
3505
|
-
: property in target[STORE_VALUE];
|
|
3822
|
+
const prevLayer = getOverlayLayer(target, property);
|
|
3823
|
+
const prev = prevLayer ? prevLayer[property] : base;
|
|
3824
|
+
const prevHas = prevLayer
|
|
3825
|
+
? prevLayer[property] !== $DELETED
|
|
3826
|
+
: property in target[STORE_VALUE];
|
|
3506
3827
|
const value = unwrapStoreValue(rawValue);
|
|
3507
|
-
const isArrayIndexWrite =
|
|
3828
|
+
const isArrayIndexWrite =
|
|
3829
|
+
Array.isArray(state) && property !== "length" && typeof property !== "symbol";
|
|
3508
3830
|
const nextIndex = isArrayIndexWrite ? parseInt(property) + 1 : 0;
|
|
3509
|
-
const len =
|
|
3510
|
-
isArrayIndexWrite &&
|
|
3511
|
-
(target[STORE_OPTIMISTIC_OVERRIDE] && "length" in target[STORE_OPTIMISTIC_OVERRIDE]
|
|
3512
|
-
? target[STORE_OPTIMISTIC_OVERRIDE].length
|
|
3513
|
-
: target[STORE_OVERRIDE] && "length" in target[STORE_OVERRIDE]
|
|
3514
|
-
? target[STORE_OVERRIDE].length
|
|
3515
|
-
: state.length);
|
|
3831
|
+
const len = isArrayIndexWrite && (getOverlayLayer(target, "length") ?? state).length;
|
|
3516
3832
|
const nextLength = isArrayIndexWrite && nextIndex > len ? nextIndex : undefined;
|
|
3517
3833
|
if (prev === value && nextLength === undefined) return true;
|
|
3834
|
+
armOptimisticStoreWrite(target, store);
|
|
3518
3835
|
if (value !== undefined && value === base && nextLength === undefined)
|
|
3519
3836
|
delete target[overrideKey]?.[property];
|
|
3520
3837
|
else {
|
|
@@ -3523,6 +3840,22 @@ const storeTraps = {
|
|
|
3523
3840
|
if (nextLength !== undefined) override.length = nextLength;
|
|
3524
3841
|
}
|
|
3525
3842
|
notifyStoreProperty(target, property, "set", value, prev, prevHas);
|
|
3843
|
+
if (
|
|
3844
|
+
Array.isArray(state) &&
|
|
3845
|
+
property === "length" &&
|
|
3846
|
+
typeof value === "number" &&
|
|
3847
|
+
typeof prev === "number" &&
|
|
3848
|
+
value < prev
|
|
3849
|
+
) {
|
|
3850
|
+
const override = target[overrideKey] || (target[overrideKey] = Object.create(null));
|
|
3851
|
+
for (let i = value; i < prev; i++) {
|
|
3852
|
+
if (override[i] === $DELETED) continue;
|
|
3853
|
+
const prevIndex = i in override ? override[i] : state[i];
|
|
3854
|
+
if (!(i in override) && !(i in state)) continue;
|
|
3855
|
+
override[i] = $DELETED;
|
|
3856
|
+
notifyStoreProperty(target, i, "delete", undefined, prevIndex, true);
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3526
3859
|
if (Array.isArray(state) && property !== "length" && nextLength !== undefined) {
|
|
3527
3860
|
const nodes = getNodes(target, STORE_NODE);
|
|
3528
3861
|
if (nodes.length) {
|
|
@@ -3549,6 +3882,7 @@ const storeTraps = {
|
|
|
3549
3882
|
if (writeOnly(store)) {
|
|
3550
3883
|
untrack(() => {
|
|
3551
3884
|
const { base: base, overrideKey: overrideKey } = prepareStoreWrite(target, store, property);
|
|
3885
|
+
armOptimisticStoreWrite(target, store);
|
|
3552
3886
|
const normalizedDescriptor =
|
|
3553
3887
|
"value" in descriptor
|
|
3554
3888
|
? { ...descriptor, value: unwrapStoreValue(descriptor.value) }
|
|
@@ -3578,19 +3912,16 @@ const storeTraps = {
|
|
|
3578
3912
|
untrack(() => {
|
|
3579
3913
|
const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
|
|
3580
3914
|
const overrideKey = useOptimistic ? STORE_OPTIMISTIC_OVERRIDE : STORE_OVERRIDE;
|
|
3581
|
-
|
|
3582
|
-
const prev =
|
|
3583
|
-
target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
|
|
3584
|
-
? target[STORE_OPTIMISTIC_OVERRIDE][property]
|
|
3585
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3586
|
-
? target[STORE_OVERRIDE][property]
|
|
3587
|
-
: target[STORE_VALUE][property];
|
|
3915
|
+
const prevLayer = getOverlayLayer(target, property);
|
|
3916
|
+
const prev = prevLayer ? prevLayer[property] : target[STORE_VALUE][property];
|
|
3588
3917
|
if (
|
|
3589
3918
|
property in target[STORE_VALUE] ||
|
|
3590
3919
|
(target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE])
|
|
3591
3920
|
) {
|
|
3921
|
+
armOptimisticStoreWrite(target, target[$PROXY]);
|
|
3592
3922
|
(target[overrideKey] || (target[overrideKey] = Object.create(null)))[property] = $DELETED;
|
|
3593
3923
|
} else if (target[overrideKey] && property in target[overrideKey]) {
|
|
3924
|
+
armOptimisticStoreWrite(target, target[$PROXY]);
|
|
3594
3925
|
delete target[overrideKey][property];
|
|
3595
3926
|
} else return true;
|
|
3596
3927
|
notifyStoreProperty(target, property, "delete", undefined, prev, true);
|
|
@@ -3599,7 +3930,7 @@ const storeTraps = {
|
|
|
3599
3930
|
return true;
|
|
3600
3931
|
},
|
|
3601
3932
|
ownKeys(target) {
|
|
3602
|
-
trackSelf(target);
|
|
3933
|
+
if (getObserver() !== target[STORE_FIREWALL]) trackSelf(target);
|
|
3603
3934
|
let keys = getKeys(target[STORE_VALUE], target[STORE_OVERRIDE], false);
|
|
3604
3935
|
if (target[STORE_OPTIMISTIC_OVERRIDE]) {
|
|
3605
3936
|
const keySet = new Set(keys);
|
|
@@ -3619,7 +3950,13 @@ const storeTraps = {
|
|
|
3619
3950
|
if (optDesc?.get || optDesc?.set || !(property in target[STORE_VALUE])) return optDesc;
|
|
3620
3951
|
const baseDesc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
|
|
3621
3952
|
if (baseDesc) {
|
|
3622
|
-
|
|
3953
|
+
const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
|
|
3954
|
+
const configurable = !targetDesc || targetDesc.configurable ? true : baseDesc.configurable;
|
|
3955
|
+
return {
|
|
3956
|
+
...baseDesc,
|
|
3957
|
+
configurable: configurable,
|
|
3958
|
+
value: target[STORE_OPTIMISTIC_OVERRIDE][property]
|
|
3959
|
+
};
|
|
3623
3960
|
}
|
|
3624
3961
|
return {
|
|
3625
3962
|
value: target[STORE_OPTIMISTIC_OVERRIDE][property],
|
|
@@ -3628,7 +3965,12 @@ const storeTraps = {
|
|
|
3628
3965
|
configurable: true
|
|
3629
3966
|
};
|
|
3630
3967
|
}
|
|
3631
|
-
|
|
3968
|
+
const desc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
|
|
3969
|
+
if (desc && !desc.configurable) {
|
|
3970
|
+
const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
|
|
3971
|
+
if (!targetDesc || targetDesc.configurable) return { ...desc, configurable: true };
|
|
3972
|
+
}
|
|
3973
|
+
return desc;
|
|
3632
3974
|
},
|
|
3633
3975
|
getPrototypeOf(target) {
|
|
3634
3976
|
return Object.getPrototypeOf(target[STORE_VALUE]);
|
|
@@ -3645,7 +3987,7 @@ function storeSetter(store, fn) {
|
|
|
3645
3987
|
for (let i = 0, len = value.length; i < len; i++) store[i] = value[i];
|
|
3646
3988
|
store.length = value.length;
|
|
3647
3989
|
} else {
|
|
3648
|
-
const keys = new Set([...
|
|
3990
|
+
const keys = new Set([...ownEnumerableKeys(store), ...ownEnumerableKeys(value)]);
|
|
3649
3991
|
keys.forEach(key => {
|
|
3650
3992
|
if (key in value) store[key] = value[key];
|
|
3651
3993
|
else delete store[key];
|
|
@@ -3664,7 +4006,10 @@ function createStore(first, second, options) {
|
|
|
3664
4006
|
return [
|
|
3665
4007
|
wrappedStore,
|
|
3666
4008
|
derived
|
|
3667
|
-
? fn =>
|
|
4009
|
+
? fn => {
|
|
4010
|
+
suppressComputedRecompute(wrappedStore[$REFRESH]);
|
|
4011
|
+
storeSetter(wrappedStore, fn);
|
|
4012
|
+
}
|
|
3668
4013
|
: fn => storeSetter(wrappedStore, fn)
|
|
3669
4014
|
];
|
|
3670
4015
|
}
|
|
@@ -3678,32 +4023,47 @@ function createOptimisticStore(first, second, options) {
|
|
|
3678
4023
|
}
|
|
3679
4024
|
function clearOptimisticStore(store) {
|
|
3680
4025
|
const target = store[$TARGET];
|
|
3681
|
-
if (!target
|
|
4026
|
+
if (!target) return;
|
|
4027
|
+
maskStoreTarget(target, false);
|
|
4028
|
+
if (!target[STORE_OPTIMISTIC_OVERRIDE]) return;
|
|
4029
|
+
clearOptimisticOverride(target);
|
|
4030
|
+
}
|
|
4031
|
+
function clearOptimisticOverride(target) {
|
|
3682
4032
|
const override = target[STORE_OPTIMISTIC_OVERRIDE];
|
|
4033
|
+
if (!override) return;
|
|
4034
|
+
maskStoreTarget(target, false);
|
|
3683
4035
|
const nodes = target[STORE_NODE];
|
|
4036
|
+
delete target[STORE_OPTIMISTIC_OVERRIDE];
|
|
4037
|
+
const wasProjectionWriteActive = projectionWriteActive;
|
|
3684
4038
|
setProjectionWriteActive(true);
|
|
3685
4039
|
try {
|
|
3686
4040
|
if (nodes) {
|
|
3687
4041
|
for (const key of Reflect.ownKeys(override)) {
|
|
3688
4042
|
if (nodes[key]) {
|
|
3689
|
-
nodes[key]
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
: target[STORE_VALUE][key];
|
|
4043
|
+
const node = nodes[key];
|
|
4044
|
+
node._optimisticLane = undefined;
|
|
4045
|
+
const layer = getOverlayLayer(target, key);
|
|
4046
|
+
const baseValue = layer ? layer[key] : target[STORE_VALUE][key];
|
|
3694
4047
|
const value = baseValue === $DELETED ? undefined : baseValue;
|
|
3695
|
-
|
|
4048
|
+
const next = isWrappable(value) ? wrap(value, target) : value;
|
|
4049
|
+
const prev = visibleNodeValue(node);
|
|
4050
|
+
node._overrideValue = NOT_PENDING;
|
|
4051
|
+
node._pendingValue = NOT_PENDING;
|
|
4052
|
+
node._value = next;
|
|
4053
|
+
if (!node._equals || !node._equals(prev, next)) {
|
|
4054
|
+
insertSubs(node, true);
|
|
4055
|
+
schedule();
|
|
4056
|
+
}
|
|
3696
4057
|
}
|
|
3697
4058
|
}
|
|
3698
4059
|
if (nodes[$TRACK]) {
|
|
3699
4060
|
nodes[$TRACK]._optimisticLane = undefined;
|
|
3700
|
-
|
|
4061
|
+
notifySelf(target);
|
|
3701
4062
|
}
|
|
3702
4063
|
}
|
|
3703
4064
|
} finally {
|
|
3704
|
-
setProjectionWriteActive(
|
|
4065
|
+
setProjectionWriteActive(wasProjectionWriteActive);
|
|
3705
4066
|
}
|
|
3706
|
-
delete target[STORE_OPTIMISTIC_OVERRIDE];
|
|
3707
4067
|
}
|
|
3708
4068
|
function createOptimisticProjectionInternal(fn, initialValue, options) {
|
|
3709
4069
|
let node;
|
|
@@ -3728,19 +4088,31 @@ function createOptimisticProjectionInternal(fn, initialValue, options) {
|
|
|
3728
4088
|
};
|
|
3729
4089
|
const wrappedStore = wrapProjection(initialValue);
|
|
3730
4090
|
if (fn) {
|
|
4091
|
+
const clearProjectionOverride = () => {
|
|
4092
|
+
const target = wrappedStore[$TARGET];
|
|
4093
|
+
if (target?.[STORE_OPTIMISTIC_OVERRIDE]) clearOptimisticOverride(target);
|
|
4094
|
+
};
|
|
3731
4095
|
const wrapCommit = write => {
|
|
4096
|
+
const wasProjectionWriteActive = projectionWriteActive;
|
|
3732
4097
|
setProjectionWriteActive(true);
|
|
3733
4098
|
try {
|
|
3734
4099
|
write();
|
|
4100
|
+
clearProjectionOverride();
|
|
3735
4101
|
} finally {
|
|
3736
|
-
setProjectionWriteActive(
|
|
4102
|
+
setProjectionWriteActive(wasProjectionWriteActive);
|
|
3737
4103
|
}
|
|
3738
4104
|
};
|
|
3739
4105
|
node = computed(
|
|
3740
4106
|
() => {
|
|
3741
4107
|
setProjectionWriteActive(true);
|
|
3742
4108
|
try {
|
|
3743
|
-
runProjectionComputed(
|
|
4109
|
+
runProjectionComputed(
|
|
4110
|
+
wrappedStore,
|
|
4111
|
+
fn,
|
|
4112
|
+
options?.key || "id",
|
|
4113
|
+
wrapCommit,
|
|
4114
|
+
clearProjectionOverride
|
|
4115
|
+
);
|
|
3744
4116
|
} finally {
|
|
3745
4117
|
setProjectionWriteActive(false);
|
|
3746
4118
|
}
|
|
@@ -3806,10 +4178,10 @@ function updatePath(current, args, i = 0) {
|
|
|
3806
4178
|
(isWrappable(prev) && isWrappable(value) && !Array.isArray(value))
|
|
3807
4179
|
) {
|
|
3808
4180
|
const target = part !== undefined ? current[part] : current;
|
|
3809
|
-
const keys =
|
|
4181
|
+
const keys = ownEnumerableKeys(value);
|
|
3810
4182
|
for (let i = 0; i < keys.length; i++) {
|
|
3811
4183
|
const key = keys[i];
|
|
3812
|
-
if (isPrototypePollutionKey(key)) continue;
|
|
4184
|
+
if (typeof key === "string" && isPrototypePollutionKey(key)) continue;
|
|
3813
4185
|
const desc = Object.getOwnPropertyDescriptor(value, key);
|
|
3814
4186
|
if (desc.get || desc.set) Object.defineProperty(target, key, desc);
|
|
3815
4187
|
else target[key] = desc.value;
|
|
@@ -3826,6 +4198,11 @@ const storePath = Object.assign(
|
|
|
3826
4198
|
},
|
|
3827
4199
|
{ DELETE: DELETE }
|
|
3828
4200
|
);
|
|
4201
|
+
function mergedOverlay(target) {
|
|
4202
|
+
const override = target[STORE_OVERRIDE];
|
|
4203
|
+
const opt = target[STORE_OPTIMISTIC_OVERRIDE];
|
|
4204
|
+
return override && opt ? { ...override, ...opt } : (opt ?? override);
|
|
4205
|
+
}
|
|
3829
4206
|
function snapshotImpl(item, track, map, lookup) {
|
|
3830
4207
|
let target, isArray, override, result, unwrapped, v;
|
|
3831
4208
|
if (!isWrappable(item)) return item;
|
|
@@ -3833,7 +4210,7 @@ function snapshotImpl(item, track, map, lookup) {
|
|
|
3833
4210
|
if (!map) map = new Map();
|
|
3834
4211
|
if ((target = item[$TARGET] || lookup?.get(item)?.[$TARGET])) {
|
|
3835
4212
|
if (track) trackSelf(target, $TRACK);
|
|
3836
|
-
override = target
|
|
4213
|
+
override = mergedOverlay(target);
|
|
3837
4214
|
isArray = Array.isArray(target[STORE_VALUE]);
|
|
3838
4215
|
map.set(
|
|
3839
4216
|
item,
|
|
@@ -3842,13 +4219,13 @@ function snapshotImpl(item, track, map, lookup) {
|
|
|
3842
4219
|
: target[STORE_VALUE]
|
|
3843
4220
|
);
|
|
3844
4221
|
item = target[STORE_VALUE];
|
|
3845
|
-
lookup = storeLookup;
|
|
4222
|
+
lookup = target[STORE_LOOKUP] ?? storeLookup;
|
|
3846
4223
|
} else {
|
|
3847
4224
|
isArray = Array.isArray(item);
|
|
3848
4225
|
map.set(item, item);
|
|
3849
4226
|
}
|
|
3850
4227
|
if (isArray) {
|
|
3851
|
-
const len = override?.length
|
|
4228
|
+
const len = override?.length ?? item.length;
|
|
3852
4229
|
for (let i = 0; i < len; i++) {
|
|
3853
4230
|
v = override && i in override ? override[i] : item[i];
|
|
3854
4231
|
if (v === $DELETED) continue;
|
|
@@ -3858,13 +4235,30 @@ function snapshotImpl(item, track, map, lookup) {
|
|
|
3858
4235
|
result[i] = unwrapped;
|
|
3859
4236
|
}
|
|
3860
4237
|
}
|
|
4238
|
+
if (result) result.length = len;
|
|
4239
|
+
} else if (!override) {
|
|
4240
|
+
const keys = getKeys(item, undefined);
|
|
4241
|
+
for (let i = 0, l = keys.length; i < l; i++) {
|
|
4242
|
+
const prop = keys[i];
|
|
4243
|
+
const desc = Object.getOwnPropertyDescriptor(item, prop);
|
|
4244
|
+
if (desc.get) continue;
|
|
4245
|
+
v = desc.value;
|
|
4246
|
+
if (track && isWrappable(v)) wrap(v, target);
|
|
4247
|
+
if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== v || result) {
|
|
4248
|
+
if (!result) {
|
|
4249
|
+
result = Object.create(Object.getPrototypeOf(item));
|
|
4250
|
+
Object.assign(result, item);
|
|
4251
|
+
}
|
|
4252
|
+
result[prop] = unwrapped;
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
3861
4255
|
} else {
|
|
3862
4256
|
const keys = getKeys(item, override);
|
|
3863
4257
|
for (let i = 0, l = keys.length; i < l; i++) {
|
|
3864
4258
|
let prop = keys[i];
|
|
3865
4259
|
const desc = getPropertyDescriptor(item, override, prop);
|
|
3866
4260
|
if (desc.get) continue;
|
|
3867
|
-
v =
|
|
4261
|
+
v = prop in override ? override[prop] : item[prop];
|
|
3868
4262
|
if (track && isWrappable(v)) wrap(v, target);
|
|
3869
4263
|
if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== item[prop] || result) {
|
|
3870
4264
|
if (!result) {
|
|
@@ -3947,7 +4341,7 @@ function merge(...sources) {
|
|
|
3947
4341
|
keys() {
|
|
3948
4342
|
const keys = new Set();
|
|
3949
4343
|
for (let i = 0; i < flattened.length; i++) {
|
|
3950
|
-
const sourceKeys =
|
|
4344
|
+
const sourceKeys = ownEnumerableKeys(resolveSource(flattened[i]));
|
|
3951
4345
|
for (let j = 0; j < sourceKeys.length; j++) keys.add(sourceKeys[j]);
|
|
3952
4346
|
}
|
|
3953
4347
|
return [...keys];
|
|
@@ -4001,7 +4395,7 @@ function omit(props, ...keys) {
|
|
|
4001
4395
|
return !keys.includes(property) && property in props;
|
|
4002
4396
|
},
|
|
4003
4397
|
keys() {
|
|
4004
|
-
return
|
|
4398
|
+
return ownEnumerableKeys(props).filter(k => !keys.includes(k));
|
|
4005
4399
|
}
|
|
4006
4400
|
},
|
|
4007
4401
|
propTraps
|
|
@@ -4220,6 +4614,7 @@ function updateRepeat() {
|
|
|
4220
4614
|
this._nodes = [];
|
|
4221
4615
|
this._mappings = [];
|
|
4222
4616
|
this._len = 0;
|
|
4617
|
+
this._offset = 0;
|
|
4223
4618
|
}
|
|
4224
4619
|
if (this._fallback && !this._mappings[0]) {
|
|
4225
4620
|
this._mappings[0] = runWithOwner((this._nodes[0] = createOwner()), this._fallback);
|
|
@@ -4229,12 +4624,24 @@ function updateRepeat() {
|
|
|
4229
4624
|
const to = from + newLen;
|
|
4230
4625
|
const prevTo = this._offset + this._len;
|
|
4231
4626
|
if (this._len === 0 && this._nodes[0]) this._nodes[0].dispose();
|
|
4627
|
+
if (from >= prevTo || to <= this._offset) {
|
|
4628
|
+
for (let i = 0; i < this._len; i++) this._nodes[i].dispose();
|
|
4629
|
+
this._nodes = new Array(newLen);
|
|
4630
|
+
this._mappings = new Array(newLen);
|
|
4631
|
+
for (let i = 0; i < newLen; i++)
|
|
4632
|
+
this._mappings[i] = runWithOwner((this._nodes[i] = createOwner()), () =>
|
|
4633
|
+
this._map(from + i)
|
|
4634
|
+
);
|
|
4635
|
+
this._offset = from;
|
|
4636
|
+
this._len = newLen;
|
|
4637
|
+
return;
|
|
4638
|
+
}
|
|
4232
4639
|
for (let i = to; i < prevTo; i++) this._nodes[i - this._offset].dispose();
|
|
4233
4640
|
if (this._offset < from) {
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
this._nodes.splice(0,
|
|
4237
|
-
this._mappings.splice(0,
|
|
4641
|
+
const removed = from - this._offset;
|
|
4642
|
+
for (let i = 0; i < removed && i < this._len; i++) this._nodes[i].dispose();
|
|
4643
|
+
this._nodes.splice(0, removed);
|
|
4644
|
+
this._mappings.splice(0, removed);
|
|
4238
4645
|
} else if (this._offset > from) {
|
|
4239
4646
|
let i = prevTo - this._offset - 1;
|
|
4240
4647
|
let difference = this._offset - from;
|
|
@@ -4270,7 +4677,13 @@ function boundaryComputed(fn, propagationMask) {
|
|
|
4270
4677
|
const flags = status !== undefined ? status : node._statusFlags;
|
|
4271
4678
|
const actualError = error !== undefined ? error : node._error;
|
|
4272
4679
|
node._statusFlags &= ~node._propagationMask;
|
|
4273
|
-
node._queue.notify(node,
|
|
4680
|
+
node._queue.notify(node, STATUS_PENDING | STATUS_ERROR, flags, actualError);
|
|
4681
|
+
const foreign = flags & ~node._propagationMask & (STATUS_PENDING | STATUS_ERROR);
|
|
4682
|
+
if (foreign) {
|
|
4683
|
+
node._statusFlags &= ~foreign;
|
|
4684
|
+
if (node._error === actualError && !(node._statusFlags & (STATUS_PENDING | STATUS_ERROR)))
|
|
4685
|
+
node._error = undefined;
|
|
4686
|
+
}
|
|
4274
4687
|
};
|
|
4275
4688
|
node._propagationMask = propagationMask;
|
|
4276
4689
|
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
@@ -4462,11 +4875,11 @@ class CollectionQueue extends Queue {
|
|
|
4462
4875
|
this._sources.clear();
|
|
4463
4876
|
}
|
|
4464
4877
|
}
|
|
4465
|
-
if (this._collectionType & STATUS_PENDING && this._initialized)
|
|
4466
|
-
return super.notify(node, type, flags, error);
|
|
4467
4878
|
if (this._collectionType & STATUS_PENDING && flags & STATUS_ERROR) {
|
|
4468
4879
|
return super.notify(node, STATUS_ERROR, flags, error);
|
|
4469
4880
|
}
|
|
4881
|
+
if (this._collectionType & STATUS_PENDING && this._initialized)
|
|
4882
|
+
return super.notify(node, type, flags, error);
|
|
4470
4883
|
if (flags & this._collectionType) {
|
|
4471
4884
|
this._pending = true;
|
|
4472
4885
|
const source = error?.source || node._error?.source;
|
|
@@ -4553,14 +4966,17 @@ function createCollectionBoundary(type, fn, fallback, onFn) {
|
|
|
4553
4966
|
cleanup(() => controller.unregister(queue));
|
|
4554
4967
|
}
|
|
4555
4968
|
return accessor(
|
|
4556
|
-
computed(
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4969
|
+
computed(
|
|
4970
|
+
() => {
|
|
4971
|
+
if (!read(queue._disabled)) {
|
|
4972
|
+
const resolved = read(tree);
|
|
4973
|
+
if (!untrack(() => read(queue._disabled))) return ((queue._initialized = true), resolved);
|
|
4974
|
+
}
|
|
4975
|
+
if (_revealUsed && read(queue._collapsed)) return undefined;
|
|
4976
|
+
return fallback(queue);
|
|
4977
|
+
},
|
|
4978
|
+
{ _noSnapshot: true }
|
|
4979
|
+
)
|
|
4564
4980
|
);
|
|
4565
4981
|
}
|
|
4566
4982
|
function createLoadingBoundary(fn, fallback, options) {
|
|
@@ -4694,7 +5110,6 @@ export {
|
|
|
4694
5110
|
isDisposed,
|
|
4695
5111
|
isEqual,
|
|
4696
5112
|
isPending,
|
|
4697
|
-
isRefreshing,
|
|
4698
5113
|
isWrappable,
|
|
4699
5114
|
latest,
|
|
4700
5115
|
mapArray,
|
|
@@ -4708,6 +5123,7 @@ export {
|
|
|
4708
5123
|
refresh,
|
|
4709
5124
|
releaseSnapshotScope,
|
|
4710
5125
|
repeat,
|
|
5126
|
+
resetErrorHalt,
|
|
4711
5127
|
resolve,
|
|
4712
5128
|
runWithOwner,
|
|
4713
5129
|
setContext,
|