@solidjs/signals 2.0.0-beta.15 → 2.0.0-beta.17
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/dist/dev.js +782 -413
- package/dist/node.cjs +1927 -1625
- package/dist/prod.js +1525 -1227
- package/dist/types/boundaries.d.ts +3 -3
- package/dist/types/core/async.d.ts +1 -0
- package/dist/types/core/core.d.ts +25 -1
- package/dist/types/core/dev.d.ts +10 -2
- package/dist/types/core/effect.d.ts +1 -3
- package/dist/types/core/error.d.ts +2 -0
- 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 +2 -2
- package/dist/types/store/store.d.ts +28 -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 +25 -1
- 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/error.d.cts +2 -0
- 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 +2 -2
- package/dist/types-cjs/store/store.d.cts +28 -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
|
@@ -12,6 +12,9 @@ class StatusError extends Error {
|
|
|
12
12
|
this.source = source;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
function unwrapStatusError(error) {
|
|
16
|
+
return error instanceof StatusError ? error.cause : error;
|
|
17
|
+
}
|
|
15
18
|
class NoOwnerError extends Error {
|
|
16
19
|
constructor() {
|
|
17
20
|
super("Context can only be accessed under a reactive root.");
|
|
@@ -140,6 +143,22 @@ function getObservers(node) {
|
|
|
140
143
|
}
|
|
141
144
|
return observers;
|
|
142
145
|
}
|
|
146
|
+
function createAsyncReporters() {
|
|
147
|
+
return new Map();
|
|
148
|
+
}
|
|
149
|
+
function devCheckActiveOverrides(isRegisteredForRevert) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
function devCheckFlushStart() {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
typeof globalThis !== "undefined" && !!globalThis.process?.env?.COMPANION_CENSUS;
|
|
156
|
+
function devCensusCompanions(isQueuedForCommit) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
function devCheckQuiescent(isQueuedForCommit) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
143
162
|
const signalLanes = new WeakMap();
|
|
144
163
|
const activeLanes = new Set();
|
|
145
164
|
function getOrCreateLane(signal) {
|
|
@@ -159,7 +178,6 @@ function getOrCreateLane(signal) {
|
|
|
159
178
|
};
|
|
160
179
|
signalLanes.set(signal, lane);
|
|
161
180
|
activeLanes.add(lane);
|
|
162
|
-
signal._overrideSinceLane = false;
|
|
163
181
|
return lane;
|
|
164
182
|
}
|
|
165
183
|
function findLane(lane) {
|
|
@@ -172,8 +190,11 @@ function mergeLanes(lane1, lane2) {
|
|
|
172
190
|
if (lane1 === lane2) return lane1;
|
|
173
191
|
lane2._mergedInto = lane1;
|
|
174
192
|
for (const node of lane2._pendingAsync) lane1._pendingAsync.add(node);
|
|
193
|
+
lane2._pendingAsync.clear();
|
|
175
194
|
lane1._effectQueues[0].push(...lane2._effectQueues[0]);
|
|
176
195
|
lane1._effectQueues[1].push(...lane2._effectQueues[1]);
|
|
196
|
+
lane2._effectQueues[0].length = 0;
|
|
197
|
+
lane2._effectQueues[1].length = 0;
|
|
177
198
|
return lane1;
|
|
178
199
|
}
|
|
179
200
|
function resolveLane(el) {
|
|
@@ -217,6 +238,8 @@ const zombieQueue = { _heap: new Array(2e3).fill(undefined), _marked: false, _mi
|
|
|
217
238
|
let clock = 0;
|
|
218
239
|
let activeTransition = null;
|
|
219
240
|
let scheduled = false;
|
|
241
|
+
let halted = false;
|
|
242
|
+
let haltNotified = false;
|
|
220
243
|
let syncDepth = 0;
|
|
221
244
|
let projectionWriteActive = false;
|
|
222
245
|
let inTrackedQueueCallback = false;
|
|
@@ -305,19 +328,24 @@ function mergeTransitionState(target, outgoing) {
|
|
|
305
328
|
for (const sub of outgoing._gatedSubs) target._gatedSubs.add(sub);
|
|
306
329
|
}
|
|
307
330
|
function resolveOptimisticNodes(nodes) {
|
|
308
|
-
|
|
331
|
+
const len = nodes.length;
|
|
332
|
+
for (let i = 0; i < len; i++) {
|
|
309
333
|
const node = nodes[i];
|
|
310
334
|
node._optimisticLane = undefined;
|
|
311
|
-
if (node.
|
|
312
|
-
node._value = node._pendingValue;
|
|
313
|
-
node._pendingValue = NOT_PENDING;
|
|
314
|
-
}
|
|
335
|
+
if (!(node._statusFlags & STATUS_PENDING)) node._statusFlags &= ~STATUS_UNINITIALIZED;
|
|
315
336
|
const prevOverride = node._overrideValue;
|
|
316
337
|
node._overrideValue = NOT_PENDING;
|
|
317
338
|
if (prevOverride !== NOT_PENDING && node._value !== prevOverride) insertSubs(node, true);
|
|
318
339
|
node._transition = null;
|
|
319
340
|
}
|
|
320
|
-
|
|
341
|
+
for (let i = 0; i < len; i++) {
|
|
342
|
+
const node = nodes[i];
|
|
343
|
+
if (node._pendingSignal || node._latestValueComputed) snapCompanionsToState(node);
|
|
344
|
+
const owner = node._parentSource;
|
|
345
|
+
if (owner && (owner._pendingSignal === node || owner._latestValueComputed === node))
|
|
346
|
+
snapCompanionsToState(owner);
|
|
347
|
+
}
|
|
348
|
+
nodes.splice(0, len);
|
|
321
349
|
}
|
|
322
350
|
function cleanupCompletedLanes(completingTransition) {
|
|
323
351
|
for (const lane of activeLanes) {
|
|
@@ -338,10 +366,41 @@ function cleanupCompletedLanes(completingTransition) {
|
|
|
338
366
|
}
|
|
339
367
|
}
|
|
340
368
|
function schedule() {
|
|
369
|
+
if (halted) {
|
|
370
|
+
notifyHalted();
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
341
373
|
if (scheduled) return;
|
|
342
374
|
scheduled = true;
|
|
343
375
|
if (!syncDepth && !globalQueue._running && !projectionWriteActive) queueMicrotask(flush);
|
|
344
376
|
}
|
|
377
|
+
function haltReactivity() {
|
|
378
|
+
if (halted) return;
|
|
379
|
+
halted = true;
|
|
380
|
+
let message = "[REACTIVITY_HALTED] An uncaught error halted the reactive system.";
|
|
381
|
+
{
|
|
382
|
+
message +=
|
|
383
|
+
" No further updates will be processed. Handle errors with createErrorBoundary/<Errored> or treat this as a crash.";
|
|
384
|
+
emitDiagnostic({
|
|
385
|
+
code: "REACTIVITY_HALTED",
|
|
386
|
+
kind: "error",
|
|
387
|
+
severity: "error",
|
|
388
|
+
message: message
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
console.error(message);
|
|
392
|
+
}
|
|
393
|
+
function notifyHalted() {
|
|
394
|
+
if (haltNotified) return;
|
|
395
|
+
haltNotified = true;
|
|
396
|
+
console.error(
|
|
397
|
+
"[REACTIVITY_HALTED] Update ignored: the reactive system was halted by an earlier uncaught error."
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
function resetErrorHalt() {
|
|
401
|
+
halted = false;
|
|
402
|
+
haltNotified = false;
|
|
403
|
+
}
|
|
345
404
|
class Queue {
|
|
346
405
|
_parent = null;
|
|
347
406
|
_queues = [[], []];
|
|
@@ -419,6 +478,7 @@ class GlobalQueue extends Queue {
|
|
|
419
478
|
if (this._running) return;
|
|
420
479
|
this._running = true;
|
|
421
480
|
try {
|
|
481
|
+
if (true) devCheckFlushStart();
|
|
422
482
|
runHeap(dirtyQueue, GlobalQueue._update);
|
|
423
483
|
if (activeTransition) {
|
|
424
484
|
const isComplete = transitionComplete(activeTransition);
|
|
@@ -482,6 +542,24 @@ class GlobalQueue extends Queue {
|
|
|
482
542
|
this.run(EFFECT_RENDER);
|
|
483
543
|
activeLanes.size && runLaneEffects(EFFECT_USER);
|
|
484
544
|
this.run(EFFECT_USER);
|
|
545
|
+
if (true) {
|
|
546
|
+
devCheckActiveOverrides(n => {
|
|
547
|
+
if (this._optimisticNodes.includes(n)) return true;
|
|
548
|
+
if (activeTransition?._optimisticNodes.includes(n)) return true;
|
|
549
|
+
for (const t of transitions) if (t._optimisticNodes.includes(n)) return true;
|
|
550
|
+
return false;
|
|
551
|
+
});
|
|
552
|
+
devCensusCompanions(n => n === this._pendingNode || this._pendingNodes.includes(n));
|
|
553
|
+
}
|
|
554
|
+
if (
|
|
555
|
+
true &&
|
|
556
|
+
!scheduled &&
|
|
557
|
+
!activeTransition &&
|
|
558
|
+
transitions.size === 0 &&
|
|
559
|
+
activeLanes.size === 0
|
|
560
|
+
) {
|
|
561
|
+
devCheckQuiescent(n => n === this._pendingNode || this._pendingNodes.includes(n));
|
|
562
|
+
}
|
|
485
563
|
if (true) DEV$1.hooks.onUpdate?.();
|
|
486
564
|
} finally {
|
|
487
565
|
this._running = false;
|
|
@@ -513,7 +591,7 @@ class GlobalQueue extends Queue {
|
|
|
513
591
|
activeTransition = transition ?? {
|
|
514
592
|
_time: clock,
|
|
515
593
|
_pendingNodes: [],
|
|
516
|
-
_asyncReporters:
|
|
594
|
+
_asyncReporters: createAsyncReporters(),
|
|
517
595
|
_optimisticNodes: [],
|
|
518
596
|
_optimisticStores: new Set(),
|
|
519
597
|
_actions: [],
|
|
@@ -609,6 +687,7 @@ function commitPendingNode(n) {
|
|
|
609
687
|
n._value = n._pendingValue;
|
|
610
688
|
n._pendingValue = NOT_PENDING;
|
|
611
689
|
}
|
|
690
|
+
if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
|
|
612
691
|
return;
|
|
613
692
|
}
|
|
614
693
|
if (n._pendingValue !== NOT_PENDING) {
|
|
@@ -620,6 +699,7 @@ function commitPendingNode(n) {
|
|
|
620
699
|
if (!(c._statusFlags & STATUS_PENDING)) c._statusFlags &= ~STATUS_UNINITIALIZED;
|
|
621
700
|
if (c._pendingFirstChild !== null || c._pendingDisposal !== null)
|
|
622
701
|
GlobalQueue._dispose(c, false, true);
|
|
702
|
+
if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
|
|
623
703
|
}
|
|
624
704
|
function commitPendingNodes() {
|
|
625
705
|
if (globalQueue._pendingNode !== null) {
|
|
@@ -710,6 +790,7 @@ function flush(fn) {
|
|
|
710
790
|
}
|
|
711
791
|
return;
|
|
712
792
|
}
|
|
793
|
+
if (halted) return;
|
|
713
794
|
let count = 0;
|
|
714
795
|
while (scheduled || activeTransition) {
|
|
715
796
|
if (++count === 1e5) throw new Error("Potential Infinite Loop Detected.");
|
|
@@ -761,8 +842,7 @@ function transitionComplete(transition) {
|
|
|
761
842
|
hasActiveOverride(node) &&
|
|
762
843
|
"_statusFlags" in node &&
|
|
763
844
|
node._statusFlags & STATUS_PENDING &&
|
|
764
|
-
node._error instanceof NotReadyError
|
|
765
|
-
node._error.source !== node
|
|
845
|
+
node._error instanceof NotReadyError
|
|
766
846
|
) {
|
|
767
847
|
done = false;
|
|
768
848
|
break;
|
|
@@ -916,7 +996,11 @@ function dispose(node) {
|
|
|
916
996
|
function disposeChildren(node, self = false, zombie) {
|
|
917
997
|
const flags = node._flags;
|
|
918
998
|
if (flags & REACTIVE_DISPOSED) return;
|
|
919
|
-
if (self)
|
|
999
|
+
if (self) {
|
|
1000
|
+
node._flags = flags | REACTIVE_DISPOSED;
|
|
1001
|
+
const n = node;
|
|
1002
|
+
if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
|
|
1003
|
+
}
|
|
920
1004
|
if (self && true) clearSignals(node);
|
|
921
1005
|
if (self && node._fn) node._inFlight = null;
|
|
922
1006
|
let child = zombie ? node._pendingFirstChild : node._firstChild;
|
|
@@ -956,6 +1040,11 @@ function disposeChildren(node, self = false, zombie) {
|
|
|
956
1040
|
node._prevSibling = null;
|
|
957
1041
|
}
|
|
958
1042
|
runDisposal(node, zombie);
|
|
1043
|
+
if (self && node._cleanup) {
|
|
1044
|
+
const effectCleanup = node._cleanup;
|
|
1045
|
+
node._cleanup = undefined;
|
|
1046
|
+
effectCleanup();
|
|
1047
|
+
}
|
|
959
1048
|
}
|
|
960
1049
|
function runDisposal(node, zombie) {
|
|
961
1050
|
let disposal = zombie ? node._pendingDisposal : node._disposal;
|
|
@@ -1097,42 +1186,49 @@ function unobserved(el) {
|
|
|
1097
1186
|
el._depsTail = null;
|
|
1098
1187
|
disposeChildren(el, true);
|
|
1099
1188
|
}
|
|
1100
|
-
function link(dep, sub) {
|
|
1189
|
+
function link(dep, sub, pendingObserver = false) {
|
|
1101
1190
|
const prevDep = sub._depsTail;
|
|
1102
|
-
if (prevDep !== null && prevDep._dep === dep)
|
|
1191
|
+
if (prevDep !== null && prevDep._dep === dep) {
|
|
1192
|
+
prevDep._pendingObserver = pendingObserver;
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1103
1195
|
let nextDep = null;
|
|
1104
1196
|
const isRecomputing = sub._flags & REACTIVE_RECOMPUTING_DEPS;
|
|
1105
1197
|
if (isRecomputing) {
|
|
1106
1198
|
nextDep = prevDep !== null ? prevDep._nextDep : sub._deps;
|
|
1107
1199
|
if (nextDep !== null && nextDep._dep === dep) {
|
|
1200
|
+
nextDep._gen = sub._depGen;
|
|
1108
1201
|
sub._depsTail = nextDep;
|
|
1202
|
+
nextDep._pendingObserver = pendingObserver;
|
|
1109
1203
|
return;
|
|
1110
1204
|
}
|
|
1111
1205
|
}
|
|
1112
1206
|
const prevSub = dep._subsTail;
|
|
1113
|
-
if (
|
|
1207
|
+
if (
|
|
1208
|
+
prevSub !== null &&
|
|
1209
|
+
prevSub._sub === sub &&
|
|
1210
|
+
(!isRecomputing || prevSub._gen === sub._depGen)
|
|
1211
|
+
) {
|
|
1212
|
+
prevSub._pendingObserver = pendingObserver;
|
|
1114
1213
|
return;
|
|
1214
|
+
}
|
|
1115
1215
|
const newLink =
|
|
1116
1216
|
(sub._depsTail =
|
|
1117
1217
|
dep._subsTail =
|
|
1118
|
-
{
|
|
1218
|
+
{
|
|
1219
|
+
_dep: dep,
|
|
1220
|
+
_sub: sub,
|
|
1221
|
+
_nextDep: nextDep,
|
|
1222
|
+
_prevSub: prevSub,
|
|
1223
|
+
_nextSub: null,
|
|
1224
|
+
_gen: sub._depGen,
|
|
1225
|
+
_pendingObserver: pendingObserver
|
|
1226
|
+
});
|
|
1119
1227
|
if (prevDep !== null) prevDep._nextDep = newLink;
|
|
1120
1228
|
else sub._deps = newLink;
|
|
1121
1229
|
if (prevSub !== null) prevSub._nextSub = newLink;
|
|
1122
1230
|
else dep._subs = newLink;
|
|
1123
1231
|
}
|
|
1124
|
-
function isValidLink(checkLink, sub) {
|
|
1125
|
-
const depsTail = sub._depsTail;
|
|
1126
|
-
if (depsTail !== null) {
|
|
1127
|
-
let link = sub._deps;
|
|
1128
|
-
do {
|
|
1129
|
-
if (link === checkLink) return true;
|
|
1130
|
-
if (link === depsTail) break;
|
|
1131
|
-
link = link._nextDep;
|
|
1132
|
-
} while (link !== null);
|
|
1133
|
-
}
|
|
1134
|
-
return false;
|
|
1135
|
-
}
|
|
1136
1232
|
function addPendingSource(el, source) {
|
|
1137
1233
|
if (el._pendingSource === source || el._pendingSources?.has(source)) return false;
|
|
1138
1234
|
if (!el._pendingSource) {
|
|
@@ -1182,9 +1278,22 @@ function setPendingError(el, source, error) {
|
|
|
1182
1278
|
}
|
|
1183
1279
|
}
|
|
1184
1280
|
function forEachDependent(el, fn) {
|
|
1185
|
-
for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub);
|
|
1281
|
+
for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub, s);
|
|
1186
1282
|
for (let child = el._child; child !== null; child = child._nextChild) {
|
|
1187
|
-
for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub);
|
|
1283
|
+
for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub, s);
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
function enqueueForRerun(node) {
|
|
1287
|
+
if (node._type === EFFECT_TRACKED) {
|
|
1288
|
+
const tracked = node;
|
|
1289
|
+
if (!tracked._modified) {
|
|
1290
|
+
tracked._modified = true;
|
|
1291
|
+
tracked._queue.enqueue(EFFECT_USER, tracked._run);
|
|
1292
|
+
}
|
|
1293
|
+
} else {
|
|
1294
|
+
const queue = node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
|
|
1295
|
+
if (queue._min > node._height) queue._min = node._height;
|
|
1296
|
+
insertIntoHeap(node, queue);
|
|
1188
1297
|
}
|
|
1189
1298
|
}
|
|
1190
1299
|
function settlePendingSource(el) {
|
|
@@ -1203,17 +1312,7 @@ function settlePendingSource(el) {
|
|
|
1203
1312
|
setPendingError(node);
|
|
1204
1313
|
updatePendingSignal(node);
|
|
1205
1314
|
if (node._blocked) {
|
|
1206
|
-
|
|
1207
|
-
const tracked = node;
|
|
1208
|
-
if (!tracked._modified) {
|
|
1209
|
-
tracked._modified = true;
|
|
1210
|
-
tracked._queue.enqueue(EFFECT_USER, tracked._run);
|
|
1211
|
-
}
|
|
1212
|
-
} else {
|
|
1213
|
-
const queue = node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
|
|
1214
|
-
if (queue._min > node._height) queue._min = node._height;
|
|
1215
|
-
insertIntoHeap(node, queue);
|
|
1216
|
-
}
|
|
1315
|
+
enqueueForRerun(node);
|
|
1217
1316
|
scheduled = true;
|
|
1218
1317
|
}
|
|
1219
1318
|
node._blocked = false;
|
|
@@ -1223,23 +1322,26 @@ function settlePendingSource(el) {
|
|
|
1223
1322
|
forEachDependent(el, settle);
|
|
1224
1323
|
if (scheduled) schedule();
|
|
1225
1324
|
}
|
|
1325
|
+
function isThenable(value) {
|
|
1326
|
+
return value != null && typeof value === "object" && typeof value.then === "function";
|
|
1327
|
+
}
|
|
1226
1328
|
function handleAsync(el, result, setter) {
|
|
1227
1329
|
let iterator = false;
|
|
1228
|
-
let
|
|
1330
|
+
let thenable = false;
|
|
1229
1331
|
if (typeof result === "object" && result !== null) {
|
|
1230
1332
|
untrack(() => {
|
|
1231
1333
|
iterator = result[Symbol.asyncIterator];
|
|
1232
|
-
|
|
1334
|
+
thenable = !iterator && isThenable(result);
|
|
1233
1335
|
});
|
|
1234
1336
|
}
|
|
1235
|
-
if (!
|
|
1337
|
+
if (!thenable && !iterator) {
|
|
1236
1338
|
el._inFlight = null;
|
|
1237
1339
|
return result;
|
|
1238
1340
|
}
|
|
1239
1341
|
if (el._config & CONFIG_SYNC) {
|
|
1240
1342
|
const message =
|
|
1241
1343
|
`[SYNC_NODE_RECEIVED_ASYNC] A computed/effect created with \`sync: true\` returned ` +
|
|
1242
|
-
`${
|
|
1344
|
+
`${thenable ? "a Promise" : "an AsyncIterable"}. The value would be stored as-is and ` +
|
|
1243
1345
|
`never awaited in production; remove \`sync: true\` to use async-aware behavior, or ` +
|
|
1244
1346
|
`unwrap the value before returning.`;
|
|
1245
1347
|
emitDiagnostic({
|
|
@@ -1273,35 +1375,41 @@ function handleAsync(el, result, setter) {
|
|
|
1273
1375
|
setter(value);
|
|
1274
1376
|
if (wasUninitialized) clearStatus(el, true);
|
|
1275
1377
|
} else if (el._overrideValue !== undefined) {
|
|
1276
|
-
if (el.
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
insertSubs(el);
|
|
1281
|
-
}
|
|
1378
|
+
if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
|
|
1379
|
+
el._pendingValue = value;
|
|
1380
|
+
syncCompanions(el, value);
|
|
1381
|
+
if (!hasActiveOverride(el)) insertSubs(el);
|
|
1282
1382
|
el._time = clock;
|
|
1283
1383
|
} else if (lane) {
|
|
1284
1384
|
const isEffect = el._type;
|
|
1285
1385
|
const prevValue = el._value;
|
|
1286
1386
|
const equals = el._equals;
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1387
|
+
try {
|
|
1388
|
+
if ((!isEffect && wasUninitialized) || !equals || !equals(value, prevValue)) {
|
|
1389
|
+
el._value = value;
|
|
1390
|
+
el._time = clock;
|
|
1391
|
+
syncCompanions(el, value);
|
|
1392
|
+
insertSubs(el, true);
|
|
1292
1393
|
}
|
|
1293
|
-
|
|
1394
|
+
} catch (e) {
|
|
1395
|
+
notifyStatus(el, STATUS_ERROR, e);
|
|
1294
1396
|
}
|
|
1295
1397
|
} else {
|
|
1296
|
-
|
|
1398
|
+
try {
|
|
1399
|
+
setSignal(el, () => value);
|
|
1400
|
+
} catch (e) {
|
|
1401
|
+
notifyStatus(el, STATUS_ERROR, e);
|
|
1402
|
+
}
|
|
1297
1403
|
}
|
|
1298
1404
|
settlePendingSource(el);
|
|
1299
1405
|
schedule();
|
|
1300
1406
|
flush();
|
|
1301
1407
|
then?.();
|
|
1302
1408
|
};
|
|
1303
|
-
if (
|
|
1409
|
+
if (thenable) {
|
|
1304
1410
|
let resolved = false,
|
|
1411
|
+
rejected = false,
|
|
1412
|
+
syncError,
|
|
1305
1413
|
isSync = true;
|
|
1306
1414
|
result.then(
|
|
1307
1415
|
v => {
|
|
@@ -1311,32 +1419,39 @@ function handleAsync(el, result, setter) {
|
|
|
1311
1419
|
} else asyncWrite(v);
|
|
1312
1420
|
},
|
|
1313
1421
|
e => {
|
|
1314
|
-
if (
|
|
1422
|
+
if (isSync) {
|
|
1423
|
+
syncError = e;
|
|
1424
|
+
rejected = true;
|
|
1425
|
+
} else handleError(e);
|
|
1315
1426
|
}
|
|
1316
1427
|
);
|
|
1317
1428
|
isSync = false;
|
|
1318
|
-
if (
|
|
1429
|
+
if (rejected) {
|
|
1430
|
+
handleError(syncError);
|
|
1431
|
+
throw syncError;
|
|
1432
|
+
} else if (!resolved) {
|
|
1319
1433
|
globalQueue.initTransition(resolveTransition(el));
|
|
1320
1434
|
throw new NotReadyError(context);
|
|
1321
1435
|
}
|
|
1322
1436
|
}
|
|
1323
1437
|
if (iterator) {
|
|
1324
1438
|
const it = result[Symbol.asyncIterator]();
|
|
1325
|
-
let
|
|
1439
|
+
let hadValue = false;
|
|
1326
1440
|
let completed = false;
|
|
1441
|
+
let initialRead = true;
|
|
1327
1442
|
cleanup(() => {
|
|
1328
1443
|
if (completed) return;
|
|
1329
1444
|
completed = true;
|
|
1330
1445
|
try {
|
|
1331
1446
|
const returned = it.return?.();
|
|
1332
|
-
if (returned
|
|
1333
|
-
returned.then(undefined, () => {});
|
|
1334
|
-
}
|
|
1447
|
+
if (isThenable(returned)) returned.then(undefined, () => {});
|
|
1335
1448
|
} catch {}
|
|
1336
1449
|
});
|
|
1337
1450
|
const iterate = () => {
|
|
1338
1451
|
let syncResult,
|
|
1452
|
+
syncError,
|
|
1339
1453
|
resolved = false,
|
|
1454
|
+
rejected = false,
|
|
1340
1455
|
isSync = true;
|
|
1341
1456
|
it.next().then(
|
|
1342
1457
|
r => {
|
|
@@ -1346,30 +1461,46 @@ function handleAsync(el, result, setter) {
|
|
|
1346
1461
|
if (r.done) completed = true;
|
|
1347
1462
|
} else if (el._inFlight !== result) {
|
|
1348
1463
|
return;
|
|
1349
|
-
} else if (!r.done)
|
|
1350
|
-
|
|
1464
|
+
} else if (!r.done) {
|
|
1465
|
+
hadValue = true;
|
|
1466
|
+
asyncWrite(r.value, iterate);
|
|
1467
|
+
} else {
|
|
1351
1468
|
completed = true;
|
|
1352
|
-
|
|
1353
|
-
|
|
1469
|
+
if (hadValue) {
|
|
1470
|
+
schedule();
|
|
1471
|
+
flush();
|
|
1472
|
+
} else {
|
|
1473
|
+
asyncWrite(undefined);
|
|
1474
|
+
}
|
|
1354
1475
|
}
|
|
1355
1476
|
},
|
|
1356
1477
|
e => {
|
|
1357
|
-
if (
|
|
1478
|
+
if (isSync) {
|
|
1479
|
+
syncError = e;
|
|
1480
|
+
rejected = true;
|
|
1481
|
+
} else if (el._inFlight === result) {
|
|
1358
1482
|
completed = true;
|
|
1359
1483
|
handleError(e);
|
|
1360
1484
|
}
|
|
1361
1485
|
}
|
|
1362
1486
|
);
|
|
1363
1487
|
isSync = false;
|
|
1488
|
+
if (rejected) {
|
|
1489
|
+
completed = true;
|
|
1490
|
+
handleError(syncError);
|
|
1491
|
+
if (initialRead) throw syncError;
|
|
1492
|
+
return true;
|
|
1493
|
+
}
|
|
1364
1494
|
if (resolved && !syncResult.done) {
|
|
1365
1495
|
syncValue = syncResult.value;
|
|
1366
|
-
|
|
1496
|
+
hadValue = true;
|
|
1367
1497
|
return iterate();
|
|
1368
1498
|
}
|
|
1369
1499
|
return resolved && syncResult.done;
|
|
1370
1500
|
};
|
|
1371
1501
|
const immediatelyDone = iterate();
|
|
1372
|
-
|
|
1502
|
+
initialRead = false;
|
|
1503
|
+
if (!hadValue && !immediatelyDone) {
|
|
1373
1504
|
globalQueue.initTransition(resolveTransition(el));
|
|
1374
1505
|
throw new NotReadyError(context);
|
|
1375
1506
|
}
|
|
@@ -1381,7 +1512,8 @@ function clearStatus(el, clearUninitialized = false) {
|
|
|
1381
1512
|
if (el._blocked) el._blocked = false;
|
|
1382
1513
|
el._statusFlags = clearUninitialized ? 0 : el._statusFlags & STATUS_UNINITIALIZED;
|
|
1383
1514
|
if (el._error) setPendingError(el);
|
|
1384
|
-
if (el._pendingSignal) updatePendingSignal(el);
|
|
1515
|
+
if (el._pendingSignal || el._latestValueComputed) updatePendingSignal(el);
|
|
1516
|
+
if (el._child) updateChildCompanions(el);
|
|
1385
1517
|
if (el._notifyStatus) el._notifyStatus();
|
|
1386
1518
|
}
|
|
1387
1519
|
function notifyStatus(el, status, error, blockStatus, lane) {
|
|
@@ -1409,6 +1541,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
1409
1541
|
el._error = error;
|
|
1410
1542
|
}
|
|
1411
1543
|
updatePendingSignal(el);
|
|
1544
|
+
if (el._child) updateChildCompanions(el);
|
|
1412
1545
|
}
|
|
1413
1546
|
if (lane && !blockStatus) {
|
|
1414
1547
|
assignOrMergeLane(el, lane);
|
|
@@ -1426,7 +1559,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
1426
1559
|
}
|
|
1427
1560
|
return;
|
|
1428
1561
|
}
|
|
1429
|
-
forEachDependent(el, sub => {
|
|
1562
|
+
forEachDependent(el, (sub, link) => {
|
|
1430
1563
|
sub._time = clock;
|
|
1431
1564
|
if (
|
|
1432
1565
|
(status === STATUS_PENDING &&
|
|
@@ -1436,6 +1569,11 @@ function notifyStatus(el, status, error, blockStatus, lane) {
|
|
|
1436
1569
|
(status !== STATUS_PENDING &&
|
|
1437
1570
|
(sub._error !== error || sub._pendingSource || sub._pendingSources))
|
|
1438
1571
|
) {
|
|
1572
|
+
if (link._pendingObserver && status !== STATUS_PENDING && !(error instanceof NotReadyError)) {
|
|
1573
|
+
enqueueForRerun(sub);
|
|
1574
|
+
schedule();
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1439
1577
|
if (!downstreamBlockStatus && !sub._transition) queuePendingNode(sub);
|
|
1440
1578
|
notifyStatus(sub, status, error, downstreamBlockStatus, downstreamLane);
|
|
1441
1579
|
}
|
|
@@ -1477,11 +1615,10 @@ const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE =
|
|
|
1477
1615
|
let tracking = false;
|
|
1478
1616
|
let stale = false;
|
|
1479
1617
|
let pendingCheckActive = false;
|
|
1480
|
-
let foundPending = false;
|
|
1481
1618
|
let latestReadActive = false;
|
|
1482
1619
|
let context = null;
|
|
1483
1620
|
let currentOptimisticLane = null;
|
|
1484
|
-
let
|
|
1621
|
+
let pendingProbe = null;
|
|
1485
1622
|
let snapshotCaptureActive = false;
|
|
1486
1623
|
let snapshotSources = null;
|
|
1487
1624
|
function ownerInSnapshotScope(owner) {
|
|
@@ -1554,11 +1691,12 @@ function recompute(el, create = false) {
|
|
|
1554
1691
|
}
|
|
1555
1692
|
let isOptimisticDirty = !!(el._flags & REACTIVE_OPTIMISTIC_DIRTY);
|
|
1556
1693
|
const hasOverride = el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING;
|
|
1557
|
-
|
|
1694
|
+
!!(el._statusFlags & STATUS_PENDING);
|
|
1558
1695
|
const wasUninitialized = !!(el._statusFlags & STATUS_UNINITIALIZED);
|
|
1559
1696
|
const oldcontext = context;
|
|
1560
1697
|
context = el;
|
|
1561
1698
|
el._depsTail = null;
|
|
1699
|
+
el._depGen++;
|
|
1562
1700
|
el._flags = REACTIVE_RECOMPUTING_DEPS;
|
|
1563
1701
|
el._time = clock;
|
|
1564
1702
|
let value = el._pendingValue === NOT_PENDING ? el._value : el._pendingValue;
|
|
@@ -1641,26 +1779,35 @@ function recompute(el, create = false) {
|
|
|
1641
1779
|
: el._pendingValue === NOT_PENDING
|
|
1642
1780
|
? el._value
|
|
1643
1781
|
: el._pendingValue;
|
|
1644
|
-
|
|
1645
|
-
|
|
1782
|
+
let valueChanged = false;
|
|
1783
|
+
try {
|
|
1784
|
+
valueChanged =
|
|
1785
|
+
(!isEffect && wasUninitialized) || !el._equals || !el._equals(compareValue, value);
|
|
1786
|
+
} catch (e) {
|
|
1787
|
+
notifyStatus(el, STATUS_ERROR, e);
|
|
1788
|
+
}
|
|
1646
1789
|
if (isEffect && valueChanged) {
|
|
1647
1790
|
el._modified = !el._error;
|
|
1648
|
-
if (!create)
|
|
1791
|
+
if (!create)
|
|
1792
|
+
el._queue.enqueue(isEffect, (el._boundRunEffect ??= GlobalQueue._runEffect.bind(null, el)));
|
|
1649
1793
|
}
|
|
1650
|
-
if (
|
|
1794
|
+
if (el._error);
|
|
1795
|
+
else if (valueChanged) {
|
|
1651
1796
|
const prevVisible = hasOverride ? el._overrideValue : undefined;
|
|
1652
1797
|
if (create || (isEffect && activeTransition !== el._transition) || isOptimisticDirty) {
|
|
1653
1798
|
el._value = value;
|
|
1654
1799
|
if (hasOverride && isOptimisticDirty) {
|
|
1655
1800
|
el._overrideValue = value;
|
|
1656
|
-
el._pendingValue =
|
|
1801
|
+
el._pendingValue = NOT_PENDING;
|
|
1657
1802
|
}
|
|
1658
|
-
} else
|
|
1659
|
-
|
|
1660
|
-
el.
|
|
1803
|
+
} else {
|
|
1804
|
+
el._pendingValue = value;
|
|
1805
|
+
if (activeTransition || el._transition) syncCompanions(el, value);
|
|
1806
|
+
}
|
|
1661
1807
|
if (!hasOverride || isOptimisticDirty || el._overrideValue !== prevVisible)
|
|
1662
1808
|
insertSubs(el, isOptimisticDirty || hasOverride);
|
|
1663
1809
|
} else if (hasOverride) {
|
|
1810
|
+
if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
|
|
1664
1811
|
el._pendingValue = value;
|
|
1665
1812
|
} else if (el._height != oldHeight) {
|
|
1666
1813
|
for (let s = el._subs; s !== null; s = s._nextSub) {
|
|
@@ -1676,8 +1823,7 @@ function recompute(el, create = false) {
|
|
|
1676
1823
|
!!(el._statusFlags & (STATUS_PENDING | STATUS_UNINITIALIZED));
|
|
1677
1824
|
needsPendingCommit &&
|
|
1678
1825
|
(!create || el._statusFlags & STATUS_PENDING) &&
|
|
1679
|
-
!el._transition &&
|
|
1680
|
-
!(activeTransition && hasOverride) &&
|
|
1826
|
+
(!el._transition || hasOverride) &&
|
|
1681
1827
|
queuePendingNode(el);
|
|
1682
1828
|
el._transition &&
|
|
1683
1829
|
isEffect &&
|
|
@@ -1716,6 +1862,7 @@ function computed(fn, options) {
|
|
|
1716
1862
|
(options?.ownedWrite ? CONFIG_OWNED_WRITE : 0) |
|
|
1717
1863
|
(!context || options?.lazy ? CONFIG_AUTO_DISPOSE : 0) |
|
|
1718
1864
|
(options?.sync ? CONFIG_SYNC : 0) |
|
|
1865
|
+
(options?._noSnapshot ? CONFIG_NO_SNAPSHOT : 0) |
|
|
1719
1866
|
(snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
|
|
1720
1867
|
_equals: options?.equals != null ? options.equals : isEqual,
|
|
1721
1868
|
_unobserved: options?.unobserved,
|
|
@@ -1731,6 +1878,7 @@ function computed(fn, options) {
|
|
|
1731
1878
|
_prevHeap: null,
|
|
1732
1879
|
_deps: null,
|
|
1733
1880
|
_depsTail: null,
|
|
1881
|
+
_depGen: 0,
|
|
1734
1882
|
_subs: null,
|
|
1735
1883
|
_subsTail: null,
|
|
1736
1884
|
_parent: context,
|
|
@@ -1775,6 +1923,7 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
|
|
|
1775
1923
|
_prevHeap: null,
|
|
1776
1924
|
_deps: null,
|
|
1777
1925
|
_depsTail: null,
|
|
1926
|
+
_depGen: 0,
|
|
1778
1927
|
_subs: null,
|
|
1779
1928
|
_subsTail: null,
|
|
1780
1929
|
_parent: context,
|
|
@@ -1794,7 +1943,6 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
|
|
|
1794
1943
|
_effectFn: effectFn,
|
|
1795
1944
|
_errorFn: errorFn,
|
|
1796
1945
|
_cleanup: undefined,
|
|
1797
|
-
_cleanupRegistered: false,
|
|
1798
1946
|
_type: type,
|
|
1799
1947
|
_notifyStatus: notifyStatus
|
|
1800
1948
|
};
|
|
@@ -1842,7 +1990,7 @@ function setupComputedNode(self, options) {
|
|
|
1842
1990
|
}
|
|
1843
1991
|
!options?.lazy && recompute(self, true);
|
|
1844
1992
|
if (snapshotCaptureActive && !options?.lazy) {
|
|
1845
|
-
if (!(self._statusFlags & STATUS_PENDING)) {
|
|
1993
|
+
if (!(self._statusFlags & STATUS_PENDING) && !(self._config & CONFIG_NO_SNAPSHOT)) {
|
|
1846
1994
|
self._snapshotValue = self._value === undefined ? NO_SNAPSHOT : self._value;
|
|
1847
1995
|
snapshotSources.add(self);
|
|
1848
1996
|
}
|
|
@@ -1911,6 +2059,16 @@ function untrack(fn, strictReadLabel) {
|
|
|
1911
2059
|
strictRead = prevStrictRead;
|
|
1912
2060
|
}
|
|
1913
2061
|
}
|
|
2062
|
+
function prepareComputed(comp, refresh) {
|
|
2063
|
+
if (comp._flags & REACTIVE_LAZY) {
|
|
2064
|
+
comp._flags &= ~REACTIVE_LAZY;
|
|
2065
|
+
recompute(comp, true);
|
|
2066
|
+
} else if (comp._flags & REACTIVE_DISPOSED) {
|
|
2067
|
+
recompute(comp, true);
|
|
2068
|
+
} else if (refresh) {
|
|
2069
|
+
updateIfNecessary(comp);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
1914
2072
|
function read(el) {
|
|
1915
2073
|
if (latestReadActive) {
|
|
1916
2074
|
const pendingComputed = getLatestValueComputed(el);
|
|
@@ -1924,7 +2082,8 @@ function read(el) {
|
|
|
1924
2082
|
try {
|
|
1925
2083
|
value = read(pendingComputed);
|
|
1926
2084
|
} catch (e) {
|
|
1927
|
-
if (!context
|
|
2085
|
+
if (e instanceof NotReadyError && (!context || !(el._statusFlags & STATUS_UNINITIALIZED)))
|
|
2086
|
+
return visibleValue;
|
|
1928
2087
|
throw e;
|
|
1929
2088
|
} finally {
|
|
1930
2089
|
latestReadActive = prevPending;
|
|
@@ -1939,59 +2098,25 @@ function read(el) {
|
|
|
1939
2098
|
}
|
|
1940
2099
|
return value;
|
|
1941
2100
|
}
|
|
2101
|
+
let c = context;
|
|
2102
|
+
if (c?._root) c = c._parentComputed;
|
|
2103
|
+
const computed = el;
|
|
2104
|
+
const firewall = el._firewall;
|
|
2105
|
+
const owner = firewall || el;
|
|
1942
2106
|
if (pendingCheckActive) {
|
|
1943
|
-
const firewall = el._firewall;
|
|
1944
|
-
const prevCheck = pendingCheckActive;
|
|
1945
2107
|
pendingCheckActive = false;
|
|
1946
|
-
|
|
1947
|
-
if (c?._root) c = c._parentComputed;
|
|
1948
|
-
const owner = firewall || el;
|
|
1949
|
-
const pendingComputed = el;
|
|
1950
|
-
if (typeof pendingComputed._fn === "function") {
|
|
1951
|
-
const comp = el;
|
|
1952
|
-
if (comp._flags & REACTIVE_LAZY) {
|
|
1953
|
-
comp._flags &= ~REACTIVE_LAZY;
|
|
1954
|
-
recompute(comp, true);
|
|
1955
|
-
} else if (comp._flags & REACTIVE_DISPOSED) {
|
|
1956
|
-
recompute(comp, true);
|
|
1957
|
-
} else {
|
|
1958
|
-
updateIfNecessary(comp);
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
2108
|
+
if (typeof computed._fn === "function") prepareComputed(el, true);
|
|
1961
2109
|
if (c && owner._statusFlags & STATUS_PENDING && owner._statusFlags & STATUS_UNINITIALIZED) {
|
|
1962
2110
|
if (tracking && el !== c) link(el, c);
|
|
1963
|
-
pendingCheckActive =
|
|
2111
|
+
pendingCheckActive = true;
|
|
1964
2112
|
throw owner._error;
|
|
1965
2113
|
}
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
foundPending = true;
|
|
1972
|
-
}
|
|
1973
|
-
collectPendingSources(el);
|
|
1974
|
-
collectPendingSources(firewall);
|
|
1975
|
-
if (c && tracking) link(el, c);
|
|
1976
|
-
} else {
|
|
1977
|
-
collectPendingSources(el);
|
|
1978
|
-
if (firewall) collectPendingSources(firewall);
|
|
1979
|
-
}
|
|
1980
|
-
pendingCheckActive = prevCheck;
|
|
2114
|
+
collectPendingSources(el);
|
|
2115
|
+
if (firewall) collectPendingSources(firewall);
|
|
2116
|
+
pendingCheckActive = true;
|
|
2117
|
+
} else if (typeof computed._fn === "function") {
|
|
2118
|
+
prepareComputed(el, false);
|
|
1981
2119
|
}
|
|
1982
|
-
let c = context;
|
|
1983
|
-
if (c?._root) c = c._parentComputed;
|
|
1984
|
-
const computed = el;
|
|
1985
|
-
if (typeof computed._fn === "function") {
|
|
1986
|
-
const comp = el;
|
|
1987
|
-
if (comp._flags & REACTIVE_LAZY) {
|
|
1988
|
-
comp._flags &= ~REACTIVE_LAZY;
|
|
1989
|
-
recompute(comp, true);
|
|
1990
|
-
} else if (comp._flags & REACTIVE_DISPOSED) {
|
|
1991
|
-
recompute(comp, true);
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
|
-
const owner = el._firewall || el;
|
|
1995
2120
|
if (
|
|
1996
2121
|
!computed._fn &&
|
|
1997
2122
|
owner === el &&
|
|
@@ -2022,7 +2147,7 @@ function read(el) {
|
|
|
2022
2147
|
throw new Error(message);
|
|
2023
2148
|
}
|
|
2024
2149
|
if (c && tracking) {
|
|
2025
|
-
link(el, c);
|
|
2150
|
+
link(el, c, pendingCheckActive);
|
|
2026
2151
|
if (owner._fn) {
|
|
2027
2152
|
const isZombie = el._flags & REACTIVE_ZOMBIE;
|
|
2028
2153
|
if (owner._height >= (isZombie ? zombieQueue._min : dirtyQueue._min)) {
|
|
@@ -2072,7 +2197,7 @@ function read(el) {
|
|
|
2072
2197
|
}
|
|
2073
2198
|
}
|
|
2074
2199
|
if (el._fn && el._statusFlags & STATUS_ERROR) {
|
|
2075
|
-
if (el._time < clock) {
|
|
2200
|
+
if (tracking && !pendingCheckActive && el._time < clock) {
|
|
2076
2201
|
recompute(el);
|
|
2077
2202
|
return read(el);
|
|
2078
2203
|
} else throw el._error;
|
|
@@ -2123,12 +2248,19 @@ function read(el) {
|
|
|
2123
2248
|
(currentOptimisticLane !== null &&
|
|
2124
2249
|
(el._overrideValue !== undefined ||
|
|
2125
2250
|
el._optimisticLane ||
|
|
2126
|
-
(owner === el && stale) ||
|
|
2251
|
+
(owner === el && stale && c._parentSource !== el) ||
|
|
2127
2252
|
!!(owner._statusFlags & STATUS_PENDING))) ||
|
|
2128
2253
|
el._pendingValue === NOT_PENDING ||
|
|
2129
2254
|
(stale && el._transition && activeTransition !== el._transition)
|
|
2130
2255
|
? el._value
|
|
2131
2256
|
: el._pendingValue;
|
|
2257
|
+
if (
|
|
2258
|
+
pendingCheckActive &&
|
|
2259
|
+
pendingProbe !== null &&
|
|
2260
|
+
el._pendingValue !== NOT_PENDING &&
|
|
2261
|
+
value === el._pendingValue
|
|
2262
|
+
)
|
|
2263
|
+
pendingProbe.freshReads.add(el);
|
|
2132
2264
|
if (
|
|
2133
2265
|
!c &&
|
|
2134
2266
|
owner === el &&
|
|
@@ -2173,26 +2305,18 @@ function setSignal(el, v) {
|
|
|
2173
2305
|
: el._pendingValue;
|
|
2174
2306
|
if (typeof v === "function") v = v(currentValue);
|
|
2175
2307
|
const valueChanged =
|
|
2176
|
-
!el._equals || !el._equals(currentValue, v)
|
|
2308
|
+
!!(el._statusFlags & STATUS_UNINITIALIZED) || !el._equals || !el._equals(currentValue, v);
|
|
2177
2309
|
if (!valueChanged) {
|
|
2178
2310
|
if (isOptimistic && hasOverride) {
|
|
2179
2311
|
const transition = resolveTransition(el);
|
|
2180
2312
|
if (transition && activeTransition !== transition) globalQueue.initTransition(transition);
|
|
2181
|
-
if (el._fn) {
|
|
2182
|
-
insertSubs(el, true);
|
|
2183
|
-
schedule();
|
|
2184
|
-
}
|
|
2185
2313
|
}
|
|
2186
2314
|
return v;
|
|
2187
2315
|
}
|
|
2188
2316
|
if (isOptimistic) {
|
|
2189
2317
|
const firstOverride = el._overrideValue === NOT_PENDING;
|
|
2190
2318
|
if (!firstOverride) globalQueue.initTransition(resolveTransition(el));
|
|
2191
|
-
if (firstOverride)
|
|
2192
|
-
el._pendingValue = el._value;
|
|
2193
|
-
globalQueue._optimisticNodes.push(el);
|
|
2194
|
-
}
|
|
2195
|
-
el._overrideSinceLane = true;
|
|
2319
|
+
if (firstOverride) globalQueue._optimisticNodes.push(el);
|
|
2196
2320
|
const lane = getOrCreateLane(el);
|
|
2197
2321
|
el._optimisticLane = lane;
|
|
2198
2322
|
el._overrideValue = v;
|
|
@@ -2200,10 +2324,7 @@ function setSignal(el, v) {
|
|
|
2200
2324
|
if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
|
|
2201
2325
|
el._pendingValue = v;
|
|
2202
2326
|
}
|
|
2203
|
-
|
|
2204
|
-
if (el._latestValueComputed) {
|
|
2205
|
-
setSignal(el._latestValueComputed, v);
|
|
2206
|
-
}
|
|
2327
|
+
syncCompanions(el, v);
|
|
2207
2328
|
el._time = clock;
|
|
2208
2329
|
insertSubs(el, isOptimistic);
|
|
2209
2330
|
schedule();
|
|
@@ -2250,64 +2371,82 @@ function runWithOwner(owner, fn) {
|
|
|
2250
2371
|
function getPendingSignal(el) {
|
|
2251
2372
|
if (!el._pendingSignal) {
|
|
2252
2373
|
el._pendingSignal = optimisticSignal(false, { ownedWrite: true });
|
|
2253
|
-
|
|
2254
|
-
el._pendingSignal._parentSource = el;
|
|
2255
|
-
}
|
|
2374
|
+
el._pendingSignal._parentSource = el;
|
|
2256
2375
|
if (computePendingState(el)) setSignal(el._pendingSignal, true);
|
|
2257
2376
|
}
|
|
2258
2377
|
return el._pendingSignal;
|
|
2259
2378
|
}
|
|
2260
2379
|
function collectPendingSources(el) {
|
|
2261
|
-
|
|
2380
|
+
if (!pendingProbe) return;
|
|
2381
|
+
pendingProbe.sources.add(el);
|
|
2262
2382
|
const owner = el._firewall || el;
|
|
2263
|
-
if (owner !== el)
|
|
2383
|
+
if (owner !== el) pendingProbe.sources.add(owner);
|
|
2264
2384
|
}
|
|
2265
2385
|
function computePendingState(el) {
|
|
2266
2386
|
const comp = el;
|
|
2387
|
+
if (comp._flags & REACTIVE_DISPOSED) return false;
|
|
2267
2388
|
const firewall = el._firewall;
|
|
2389
|
+
if ((firewall || comp)._optimisticMask) return false;
|
|
2268
2390
|
if (el._parentSource) {
|
|
2269
|
-
const
|
|
2270
|
-
if (
|
|
2271
|
-
|
|
2272
|
-
|
|
2391
|
+
const parentNode = el._parentSource;
|
|
2392
|
+
if (hasActiveOverride(parentNode)) return false;
|
|
2393
|
+
const parent = parentNode._firewall || parentNode;
|
|
2394
|
+
if (parent._optimisticMask) return false;
|
|
2395
|
+
return !!(
|
|
2396
|
+
parent._statusFlags & STATUS_PENDING && !(parent._statusFlags & STATUS_UNINITIALIZED)
|
|
2397
|
+
);
|
|
2273
2398
|
}
|
|
2399
|
+
if (hasActiveOverride(el)) return false;
|
|
2274
2400
|
if (firewall && el._pendingValue !== NOT_PENDING) {
|
|
2275
2401
|
return (
|
|
2276
2402
|
!!(firewall._flags & REACTIVE_MANUAL_WRITE) ||
|
|
2277
2403
|
(!firewall._inFlight && !(firewall._statusFlags & STATUS_PENDING))
|
|
2278
2404
|
);
|
|
2279
2405
|
}
|
|
2280
|
-
if (el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING) {
|
|
2281
|
-
if (comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED))
|
|
2282
|
-
return true;
|
|
2283
|
-
if (el._parentSource) {
|
|
2284
|
-
const lane = el._optimisticLane ? findLane(el._optimisticLane) : null;
|
|
2285
|
-
return !!(lane && lane._pendingAsync.size > 0);
|
|
2286
|
-
}
|
|
2287
|
-
return true;
|
|
2288
|
-
}
|
|
2289
|
-
if (el._overrideValue !== undefined && el._overrideValue === NOT_PENDING && !el._parentSource) {
|
|
2290
|
-
return false;
|
|
2291
|
-
}
|
|
2292
2406
|
if (el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED)) return true;
|
|
2293
2407
|
return !!(comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED));
|
|
2294
2408
|
}
|
|
2409
|
+
function syncCompanions(el, value) {
|
|
2410
|
+
if (el._pendingSignal) updatePendingSignal(el);
|
|
2411
|
+
if (el._latestValueComputed) setSignal(el._latestValueComputed, value);
|
|
2412
|
+
}
|
|
2295
2413
|
function updatePendingSignal(el) {
|
|
2296
2414
|
if (el._pendingSignal) {
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2415
|
+
setSignal(el._pendingSignal, computePendingState(el));
|
|
2416
|
+
}
|
|
2417
|
+
if (el._latestValueComputed) updatePendingSignal(el._latestValueComputed);
|
|
2418
|
+
}
|
|
2419
|
+
function updateChildCompanions(el) {
|
|
2420
|
+
for (let child = el._child; child !== null; child = child._nextChild) {
|
|
2421
|
+
if (child._pendingSignal || child._latestValueComputed) updatePendingSignal(child);
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
function snapCompanionsToState(owner) {
|
|
2425
|
+
const sig = owner._pendingSignal;
|
|
2426
|
+
if (sig && (sig._overrideValue === undefined || sig._overrideValue === NOT_PENDING)) {
|
|
2427
|
+
const pending = computePendingState(owner);
|
|
2428
|
+
if (sig._value !== pending || sig._pendingValue !== NOT_PENDING) {
|
|
2429
|
+
sig._value = pending;
|
|
2430
|
+
sig._pendingValue = NOT_PENDING;
|
|
2431
|
+
sig._time = clock;
|
|
2432
|
+
insertSubs(sig);
|
|
2433
|
+
schedule();
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
const shadow = owner._latestValueComputed;
|
|
2437
|
+
if (shadow && !(shadow._flags & REACTIVE_DISPOSED)) {
|
|
2438
|
+
if (
|
|
2439
|
+
(shadow._overrideValue === undefined || shadow._overrideValue === NOT_PENDING) &&
|
|
2440
|
+
shadow._pendingValue === NOT_PENDING &&
|
|
2441
|
+
!Object.is(shadow._value, owner._value) &&
|
|
2442
|
+
!(shadow._flags & (REACTIVE_DIRTY | REACTIVE_CHECK))
|
|
2443
|
+
) {
|
|
2444
|
+
shadow._flags |= REACTIVE_DIRTY;
|
|
2445
|
+
insertIntoHeap(shadow, shadow._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
2446
|
+
insertSubs(shadow);
|
|
2447
|
+
schedule();
|
|
2310
2448
|
}
|
|
2449
|
+
snapCompanionsToState(shadow);
|
|
2311
2450
|
}
|
|
2312
2451
|
}
|
|
2313
2452
|
function getLatestValueComputed(el) {
|
|
@@ -2346,18 +2485,16 @@ function latest(fn) {
|
|
|
2346
2485
|
}
|
|
2347
2486
|
function isPending(fn) {
|
|
2348
2487
|
const prevPendingCheck = pendingCheckActive;
|
|
2349
|
-
const
|
|
2350
|
-
const prevPendingCheckSources = pendingCheckSources;
|
|
2488
|
+
const prevProbe = pendingProbe;
|
|
2351
2489
|
pendingCheckActive = true;
|
|
2352
|
-
|
|
2353
|
-
pendingCheckSources = new Set();
|
|
2490
|
+
const probe = (pendingProbe = { found: false, sources: new Set(), freshReads: new Set() });
|
|
2354
2491
|
const collectPending = () => {
|
|
2355
2492
|
pendingCheckActive = false;
|
|
2356
2493
|
const prevStrictRead = strictRead;
|
|
2357
2494
|
strictRead = false;
|
|
2358
2495
|
try {
|
|
2359
|
-
|
|
2360
|
-
if (read(getPendingSignal(source)))
|
|
2496
|
+
probe.sources.forEach(source => {
|
|
2497
|
+
if (read(getPendingSignal(source)) && !probe.freshReads.has(source)) probe.found = true;
|
|
2361
2498
|
});
|
|
2362
2499
|
} finally {
|
|
2363
2500
|
strictRead = prevStrictRead;
|
|
@@ -2367,18 +2504,17 @@ function isPending(fn) {
|
|
|
2367
2504
|
try {
|
|
2368
2505
|
fn();
|
|
2369
2506
|
collectPending();
|
|
2370
|
-
return
|
|
2507
|
+
return probe.found;
|
|
2371
2508
|
} catch (e) {
|
|
2372
2509
|
collectPending();
|
|
2373
2510
|
if (e instanceof NotReadyError) {
|
|
2374
|
-
if (
|
|
2511
|
+
if (probe.found && !(e.source?._statusFlags & STATUS_UNINITIALIZED)) return true;
|
|
2375
2512
|
if (context) throw e;
|
|
2376
2513
|
}
|
|
2377
|
-
return
|
|
2514
|
+
return probe.found;
|
|
2378
2515
|
} finally {
|
|
2379
2516
|
pendingCheckActive = prevPendingCheck;
|
|
2380
|
-
|
|
2381
|
-
pendingCheckSources = prevPendingCheckSources;
|
|
2517
|
+
pendingProbe = prevProbe;
|
|
2382
2518
|
}
|
|
2383
2519
|
}
|
|
2384
2520
|
function refresh(target) {
|
|
@@ -2485,50 +2621,66 @@ function notifyEffectStatus(status, error) {
|
|
|
2485
2621
|
const actualStatus = status !== undefined ? status : this._statusFlags;
|
|
2486
2622
|
const actualError = error !== undefined ? error : this._error;
|
|
2487
2623
|
if (actualStatus & STATUS_ERROR) {
|
|
2488
|
-
let err = actualError;
|
|
2489
2624
|
this._queue.notify(this, STATUS_PENDING, 0);
|
|
2490
2625
|
if (this._type === EFFECT_USER) {
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
this._cleanup?.();
|
|
2495
|
-
this._cleanup = undefined;
|
|
2496
|
-
})
|
|
2497
|
-
: console.error(err);
|
|
2498
|
-
} catch (e) {
|
|
2499
|
-
err = e;
|
|
2626
|
+
if (this._statusFlags & STATUS_ERROR) {
|
|
2627
|
+
this._modified = true;
|
|
2628
|
+
this._queue.enqueue(this._type, (this._boundRunEffect ??= runEffect.bind(null, this)));
|
|
2500
2629
|
}
|
|
2630
|
+
return;
|
|
2631
|
+
}
|
|
2632
|
+
if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) {
|
|
2633
|
+
haltReactivity();
|
|
2634
|
+
throw actualError;
|
|
2501
2635
|
}
|
|
2502
|
-
if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) throw err;
|
|
2503
2636
|
} else if (this._type === EFFECT_RENDER) {
|
|
2504
2637
|
this._queue.notify(this, STATUS_PENDING | STATUS_ERROR, actualStatus, actualError);
|
|
2505
2638
|
if (_hitUnhandledAsync) {
|
|
2506
2639
|
resetUnhandledAsync();
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
console.warn(message);
|
|
2519
|
-
}
|
|
2640
|
+
const message =
|
|
2641
|
+
"[ASYNC_OUTSIDE_LOADING_BOUNDARY] An async value was read outside a Loading boundary. The root mount will be deferred until all pending async settles.";
|
|
2642
|
+
emitDiagnostic({
|
|
2643
|
+
code: "ASYNC_OUTSIDE_LOADING_BOUNDARY",
|
|
2644
|
+
kind: "async",
|
|
2645
|
+
severity: "warn",
|
|
2646
|
+
message: message,
|
|
2647
|
+
ownerId: this.id,
|
|
2648
|
+
ownerName: this._name
|
|
2649
|
+
});
|
|
2650
|
+
console.warn(message);
|
|
2520
2651
|
}
|
|
2521
2652
|
}
|
|
2522
2653
|
}
|
|
2523
2654
|
function runEffect(node) {
|
|
2524
2655
|
if (!node._modified || node._flags & REACTIVE_DISPOSED) return;
|
|
2656
|
+
if (node._statusFlags & STATUS_ERROR && node._type === EFFECT_USER) {
|
|
2657
|
+
const err = unwrapStatusError(node._error);
|
|
2658
|
+
node._prevValue = node._value;
|
|
2659
|
+
node._modified = false;
|
|
2660
|
+
try {
|
|
2661
|
+
node._errorFn
|
|
2662
|
+
? node._errorFn(err, () => {
|
|
2663
|
+
const prevCleanup = node._cleanup;
|
|
2664
|
+
node._cleanup = undefined;
|
|
2665
|
+
prevCleanup?.();
|
|
2666
|
+
})
|
|
2667
|
+
: console.error(err);
|
|
2668
|
+
} catch (error) {
|
|
2669
|
+
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
|
|
2670
|
+
haltReactivity();
|
|
2671
|
+
throw error;
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2525
2676
|
let prevStrictRead = false;
|
|
2526
2677
|
{
|
|
2527
2678
|
prevStrictRead = setStrictRead("an effect callback");
|
|
2528
2679
|
}
|
|
2529
|
-
node._cleanup
|
|
2680
|
+
const prevCleanup = node._cleanup;
|
|
2530
2681
|
node._cleanup = undefined;
|
|
2531
2682
|
try {
|
|
2683
|
+
prevCleanup?.();
|
|
2532
2684
|
const nextCleanup = node._effectFn(node._value, node._prevValue);
|
|
2533
2685
|
if (true && nextCleanup !== undefined && typeof nextCleanup !== "function") {
|
|
2534
2686
|
throw new Error(
|
|
@@ -2536,14 +2688,13 @@ function runEffect(node) {
|
|
|
2536
2688
|
);
|
|
2537
2689
|
}
|
|
2538
2690
|
node._cleanup = nextCleanup;
|
|
2539
|
-
if (node._cleanup && !node._cleanupRegistered) {
|
|
2540
|
-
node._cleanupRegistered = true;
|
|
2541
|
-
runWithOwner(node._parent, () => cleanup(() => node._cleanup?.()));
|
|
2542
|
-
}
|
|
2543
2691
|
} catch (error) {
|
|
2544
2692
|
node._error = new StatusError(node, error);
|
|
2545
2693
|
node._statusFlags |= STATUS_ERROR;
|
|
2546
|
-
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR))
|
|
2694
|
+
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
|
|
2695
|
+
haltReactivity();
|
|
2696
|
+
throw error;
|
|
2697
|
+
}
|
|
2547
2698
|
} finally {
|
|
2548
2699
|
setStrictRead(prevStrictRead);
|
|
2549
2700
|
node._prevValue = node._value;
|
|
@@ -2564,8 +2715,9 @@ function trackedEffect(fn, options) {
|
|
|
2564
2715
|
};
|
|
2565
2716
|
const node = computed(
|
|
2566
2717
|
() => {
|
|
2567
|
-
node._cleanup
|
|
2718
|
+
const prevCleanup = node._cleanup;
|
|
2568
2719
|
node._cleanup = undefined;
|
|
2720
|
+
prevCleanup?.();
|
|
2569
2721
|
const cleanup = staleValues(fn);
|
|
2570
2722
|
if (cleanup !== undefined && typeof cleanup !== "function") {
|
|
2571
2723
|
throw new Error(
|
|
@@ -2585,12 +2737,14 @@ function trackedEffect(fn, options) {
|
|
|
2585
2737
|
if (actualStatus & STATUS_ERROR) {
|
|
2586
2738
|
node._queue.notify(node, STATUS_PENDING, 0);
|
|
2587
2739
|
const err = error !== undefined ? error : node._error;
|
|
2588
|
-
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR))
|
|
2740
|
+
if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
|
|
2741
|
+
haltReactivity();
|
|
2742
|
+
throw err;
|
|
2743
|
+
}
|
|
2589
2744
|
}
|
|
2590
2745
|
};
|
|
2591
2746
|
node._run = run;
|
|
2592
2747
|
node._queue.enqueue(EFFECT_USER, run);
|
|
2593
|
-
cleanup(() => node._cleanup?.());
|
|
2594
2748
|
if (!node._parent) {
|
|
2595
2749
|
const message =
|
|
2596
2750
|
"[NO_OWNER_EFFECT] Effects created outside a reactive context will never be disposed";
|
|
@@ -2606,6 +2760,9 @@ function trackedEffect(fn, options) {
|
|
|
2606
2760
|
console.warn(message);
|
|
2607
2761
|
}
|
|
2608
2762
|
}
|
|
2763
|
+
const ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE =
|
|
2764
|
+
"[ACTION_CALLED_IN_OWNED_SCOPE] Calling an action inside an owned scope (component, computation) is not allowed. " +
|
|
2765
|
+
"Call it from an event handler or another imperative scope.";
|
|
2609
2766
|
function restoreTransition(transition, fn) {
|
|
2610
2767
|
globalQueue.initTransition(transition);
|
|
2611
2768
|
const result = fn();
|
|
@@ -2613,34 +2770,47 @@ function restoreTransition(transition, fn) {
|
|
|
2613
2770
|
return result;
|
|
2614
2771
|
}
|
|
2615
2772
|
function action(genFn) {
|
|
2616
|
-
return (...args) =>
|
|
2617
|
-
|
|
2773
|
+
return (...args) => {
|
|
2774
|
+
{
|
|
2775
|
+
const owner = getOwner();
|
|
2776
|
+
if (owner && !(owner._config & CONFIG_CHILDREN_FORBIDDEN)) {
|
|
2777
|
+
emitDiagnostic({
|
|
2778
|
+
code: "ACTION_CALLED_IN_OWNED_SCOPE",
|
|
2779
|
+
kind: "write",
|
|
2780
|
+
severity: "error",
|
|
2781
|
+
message: ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE,
|
|
2782
|
+
ownerId: owner.id,
|
|
2783
|
+
ownerName: owner._name
|
|
2784
|
+
});
|
|
2785
|
+
throw new Error(ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
return new Promise((resolve, reject) => {
|
|
2618
2789
|
const it = genFn(...args);
|
|
2619
2790
|
globalQueue.initTransition();
|
|
2620
2791
|
let ctx = activeTransition;
|
|
2621
2792
|
ctx._actions.push(it);
|
|
2622
|
-
const done = (v, e) => {
|
|
2793
|
+
const done = (v, e, failed = false) => {
|
|
2623
2794
|
ctx = currentTransition(ctx);
|
|
2624
2795
|
const i = ctx._actions.indexOf(it);
|
|
2625
2796
|
if (i >= 0) ctx._actions.splice(i, 1);
|
|
2626
2797
|
setActiveTransition(ctx);
|
|
2627
2798
|
schedule();
|
|
2628
|
-
|
|
2799
|
+
failed ? reject(e) : resolve(v);
|
|
2629
2800
|
};
|
|
2630
2801
|
const step = (v, err) => {
|
|
2631
2802
|
let r;
|
|
2632
2803
|
try {
|
|
2633
2804
|
r = err ? it.throw(v) : it.next(v);
|
|
2634
2805
|
} catch (e) {
|
|
2635
|
-
return done(undefined, e);
|
|
2806
|
+
return done(undefined, e, true);
|
|
2636
2807
|
}
|
|
2637
|
-
if (r
|
|
2638
|
-
return void r.then(run, e => restoreTransition(ctx, () => step(e, true)));
|
|
2808
|
+
if (isThenable(r)) return void r.then(run, e => done(undefined, e, true));
|
|
2639
2809
|
run(r);
|
|
2640
2810
|
};
|
|
2641
2811
|
const run = r => {
|
|
2642
2812
|
if (r.done) return done(r.value);
|
|
2643
|
-
if (r.value
|
|
2813
|
+
if (isThenable(r.value))
|
|
2644
2814
|
return void r.value.then(
|
|
2645
2815
|
v => restoreTransition(ctx, () => step(v)),
|
|
2646
2816
|
e => restoreTransition(ctx, () => step(e, true))
|
|
@@ -2649,6 +2819,7 @@ function action(genFn) {
|
|
|
2649
2819
|
};
|
|
2650
2820
|
step();
|
|
2651
2821
|
});
|
|
2822
|
+
};
|
|
2652
2823
|
}
|
|
2653
2824
|
function onCleanup(fn) {
|
|
2654
2825
|
{
|
|
@@ -2727,11 +2898,17 @@ function createReaction(effectFn, options) {
|
|
|
2727
2898
|
let cl = undefined;
|
|
2728
2899
|
cleanup(() => cl?.());
|
|
2729
2900
|
const owner = getOwner();
|
|
2901
|
+
let arm;
|
|
2730
2902
|
return tracking => {
|
|
2903
|
+
if (arm) {
|
|
2904
|
+
dispose(arm);
|
|
2905
|
+
arm = undefined;
|
|
2906
|
+
}
|
|
2731
2907
|
runWithOwner(owner, () => {
|
|
2732
2908
|
effect(
|
|
2733
|
-
() => (tracking(), getOwner()),
|
|
2909
|
+
() => (tracking(), (arm = getOwner())),
|
|
2734
2910
|
node => {
|
|
2911
|
+
arm = undefined;
|
|
2735
2912
|
cl?.();
|
|
2736
2913
|
const cleanup = (effectFn.effect || effectFn)?.();
|
|
2737
2914
|
if (true && cleanup !== undefined && typeof cleanup !== "function") {
|
|
@@ -2760,15 +2937,18 @@ function resolve(fn) {
|
|
|
2760
2937
|
}
|
|
2761
2938
|
return new Promise((res, rej) => {
|
|
2762
2939
|
createRoot(dispose => {
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2940
|
+
effect(
|
|
2941
|
+
fn,
|
|
2942
|
+
value => {
|
|
2943
|
+
res(value);
|
|
2944
|
+
dispose();
|
|
2945
|
+
},
|
|
2946
|
+
err => {
|
|
2768
2947
|
rej(err);
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2948
|
+
dispose();
|
|
2949
|
+
},
|
|
2950
|
+
{ user: true }
|
|
2951
|
+
);
|
|
2772
2952
|
});
|
|
2773
2953
|
});
|
|
2774
2954
|
}
|
|
@@ -2788,27 +2968,110 @@ function onSettled(callback) {
|
|
|
2788
2968
|
? createTrackedEffect(() => untrack(callback), { name: "onSettled" })
|
|
2789
2969
|
: globalQueue.enqueue(EFFECT_USER, () => {
|
|
2790
2970
|
const cleanup = callback();
|
|
2791
|
-
if (cleanup !== undefined
|
|
2792
|
-
|
|
2793
|
-
"onSettled
|
|
2794
|
-
|
|
2971
|
+
if (cleanup !== undefined) {
|
|
2972
|
+
const message =
|
|
2973
|
+
"[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.";
|
|
2974
|
+
emitDiagnostic({
|
|
2975
|
+
code: "SETTLED_CLEANUP_UNOWNED",
|
|
2976
|
+
kind: "lifecycle",
|
|
2977
|
+
severity: "error",
|
|
2978
|
+
message: message
|
|
2979
|
+
});
|
|
2980
|
+
throw new Error(message);
|
|
2795
2981
|
}
|
|
2796
|
-
cleanup?.();
|
|
2797
2982
|
});
|
|
2798
2983
|
}
|
|
2984
|
+
function nodeKeys(nodes) {
|
|
2985
|
+
const keys = Object.keys(nodes);
|
|
2986
|
+
if (symbolKeyedRecords.has(nodes)) {
|
|
2987
|
+
const syms = Object.getOwnPropertySymbols(nodes);
|
|
2988
|
+
for (let i = 0, len = syms.length; i < len; i++) {
|
|
2989
|
+
if (syms[i] !== $TRACK) keys.push(syms[i]);
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
return keys;
|
|
2993
|
+
}
|
|
2799
2994
|
function unwrap(value) {
|
|
2800
|
-
|
|
2995
|
+
if (value === null || typeof value !== "object") return value;
|
|
2996
|
+
return value[$TARGET]?.[STORE_VALUE] ?? value;
|
|
2801
2997
|
}
|
|
2802
2998
|
function getOverrideValue(value, override, key, optOverride) {
|
|
2803
2999
|
if (optOverride && key in optOverride) return optOverride[key];
|
|
2804
3000
|
return override && key in override ? override[key] : value[key];
|
|
2805
3001
|
}
|
|
3002
|
+
function addEnumSymbols(o, syms, keys) {
|
|
3003
|
+
for (let i = 0, len = syms.length; i < len; i++) {
|
|
3004
|
+
if (Object.prototype.propertyIsEnumerable.call(o, syms[i])) keys.add(syms[i]);
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
2806
3007
|
function getAllKeys(value, override, next) {
|
|
2807
3008
|
const keys = getKeys(value, override);
|
|
2808
3009
|
const nextKeys = Object.keys(next);
|
|
2809
|
-
|
|
3010
|
+
const valueSyms = value[$TARGET]
|
|
3011
|
+
? untrack(() => Object.getOwnPropertySymbols(value))
|
|
3012
|
+
: Object.getOwnPropertySymbols(value);
|
|
3013
|
+
const nextSyms = Object.getOwnPropertySymbols(next);
|
|
3014
|
+
if (valueSyms.length === 0 && nextSyms.length === 0) {
|
|
3015
|
+
if (keys.length === nextKeys.length) {
|
|
3016
|
+
let same = true;
|
|
3017
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3018
|
+
if (keys[i] !== nextKeys[i]) {
|
|
3019
|
+
same = false;
|
|
3020
|
+
break;
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
if (same) return keys;
|
|
3024
|
+
}
|
|
3025
|
+
const set = new Set(keys);
|
|
3026
|
+
for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
|
|
3027
|
+
return Array.from(set);
|
|
3028
|
+
}
|
|
3029
|
+
const set = new Set(keys);
|
|
3030
|
+
addEnumSymbols(value, valueSyms, set);
|
|
3031
|
+
if (override) {
|
|
3032
|
+
for (const key of Reflect.ownKeys(override)) {
|
|
3033
|
+
override[key] === $DELETED ? set.delete(key) : set.add(key);
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
|
|
3037
|
+
addEnumSymbols(next, nextSyms, set);
|
|
3038
|
+
return Array.from(set);
|
|
3039
|
+
}
|
|
3040
|
+
function wrapValue(value, target) {
|
|
3041
|
+
return isWrappable(value) ? wrap(value, target) : value;
|
|
3042
|
+
}
|
|
3043
|
+
function itemKey(item, keyFn) {
|
|
3044
|
+
return isWrappable(item) ? keyFn(item) : item;
|
|
3045
|
+
}
|
|
3046
|
+
function keyedMatch(a, b, keyFn) {
|
|
3047
|
+
return a === b || (isWrappable(a) && isWrappable(b) && keyFn(a) === keyFn(b));
|
|
3048
|
+
}
|
|
3049
|
+
function syncArrayNodeMembership(target, next) {
|
|
3050
|
+
let nodes = target[STORE_NODE];
|
|
3051
|
+
if (nodes) {
|
|
3052
|
+
const keys = nodeKeys(nodes);
|
|
3053
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3054
|
+
const key = keys[i];
|
|
3055
|
+
key in next || setSignal(nodes[key], undefined);
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
if ((nodes = target[STORE_HAS])) {
|
|
3059
|
+
const keys = nodeKeys(nodes);
|
|
3060
|
+
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3061
|
+
const key = keys[i];
|
|
3062
|
+
setSignal(nodes[key], key in next);
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
function applyArrayItem(next, previous, target, node, keyFn) {
|
|
3067
|
+
if (isWrappable(next) && isWrappable(previous)) {
|
|
3068
|
+
const wrapped = wrap(previous, target);
|
|
3069
|
+
node && setSignal(node, wrapped);
|
|
3070
|
+
applyState(next, wrapped, keyFn);
|
|
3071
|
+
} else node && setSignal(node, wrapValue(next, target));
|
|
2810
3072
|
}
|
|
2811
3073
|
function applyState(next, state, keyFn) {
|
|
3074
|
+
next = unwrap(next);
|
|
2812
3075
|
const target = state?.[$TARGET];
|
|
2813
3076
|
if (!target) return;
|
|
2814
3077
|
if (target[STORE_OVERRIDE] || target[STORE_OPTIMISTIC_OVERRIDE]) {
|
|
@@ -2826,25 +3089,22 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2826
3089
|
if (Array.isArray(previous)) {
|
|
2827
3090
|
let changed = false;
|
|
2828
3091
|
const prevLength = previous.length;
|
|
2829
|
-
if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
|
|
3092
|
+
if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
|
|
2830
3093
|
let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
|
|
2831
3094
|
for (
|
|
2832
3095
|
start = 0, end = Math.min(prevLength, next.length);
|
|
2833
|
-
start < end &&
|
|
2834
|
-
((item = previous[start]) === next[start] ||
|
|
2835
|
-
(item && next[start] && keyFn(item) === keyFn(next[start])));
|
|
3096
|
+
start < end && keyedMatch((item = previous[start]), next[start], keyFn);
|
|
2836
3097
|
start++
|
|
2837
3098
|
) {
|
|
2838
|
-
|
|
3099
|
+
isWrappable(item) &&
|
|
3100
|
+
isWrappable(next[start]) &&
|
|
3101
|
+
applyState(next[start], wrap(item, target), keyFn);
|
|
2839
3102
|
}
|
|
2840
3103
|
const temp = new Array(next.length),
|
|
2841
3104
|
newIndices = new Map();
|
|
2842
3105
|
for (
|
|
2843
3106
|
end = prevLength - 1, newEnd = next.length - 1;
|
|
2844
|
-
end >= start &&
|
|
2845
|
-
newEnd >= start &&
|
|
2846
|
-
((item = previous[end]) === next[newEnd] ||
|
|
2847
|
-
(item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])));
|
|
3107
|
+
end >= start && newEnd >= start && keyedMatch((item = previous[end]), next[newEnd], keyFn);
|
|
2848
3108
|
end--, newEnd--
|
|
2849
3109
|
) {
|
|
2850
3110
|
temp[newEnd] = item;
|
|
@@ -2852,15 +3112,14 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2852
3112
|
if (start > newEnd || start > end) {
|
|
2853
3113
|
for (j = start; j <= newEnd; j++) {
|
|
2854
3114
|
changed = true;
|
|
2855
|
-
arrayNodes?.[j] && setSignal(arrayNodes[j],
|
|
3115
|
+
arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
|
|
2856
3116
|
}
|
|
2857
3117
|
for (; j < next.length; j++) {
|
|
2858
3118
|
changed = true;
|
|
2859
|
-
|
|
2860
|
-
arrayNodes?.[j] && setSignal(arrayNodes[j], wrapped);
|
|
2861
|
-
applyState(next[j], wrapped, keyFn);
|
|
3119
|
+
applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
|
|
2862
3120
|
}
|
|
2863
|
-
|
|
3121
|
+
syncArrayNodeMembership(target, next);
|
|
3122
|
+
(changed || prevLength !== next.length) && notifySelf(target);
|
|
2864
3123
|
prevLength !== next.length &&
|
|
2865
3124
|
arrayNodes?.length &&
|
|
2866
3125
|
setSignal(arrayNodes.length, next.length);
|
|
@@ -2869,14 +3128,14 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2869
3128
|
newIndicesNext = new Array(newEnd + 1);
|
|
2870
3129
|
for (j = newEnd; j >= start; j--) {
|
|
2871
3130
|
item = next[j];
|
|
2872
|
-
keyVal = item
|
|
3131
|
+
keyVal = itemKey(item, keyFn);
|
|
2873
3132
|
i = newIndices.get(keyVal);
|
|
2874
3133
|
newIndicesNext[j] = i === undefined ? -1 : i;
|
|
2875
3134
|
newIndices.set(keyVal, j);
|
|
2876
3135
|
}
|
|
2877
3136
|
for (i = start; i <= end; i++) {
|
|
2878
3137
|
item = previous[i];
|
|
2879
|
-
keyVal = item
|
|
3138
|
+
keyVal = itemKey(item, keyFn);
|
|
2880
3139
|
j = newIndices.get(keyVal);
|
|
2881
3140
|
if (j !== undefined && j !== -1) {
|
|
2882
3141
|
temp[j] = item;
|
|
@@ -2886,22 +3145,22 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2886
3145
|
}
|
|
2887
3146
|
for (j = start; j < next.length; j++) {
|
|
2888
3147
|
if (j in temp) {
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
applyState(next[j], wrapped, keyFn);
|
|
2892
|
-
} else arrayNodes?.[j] && setSignal(arrayNodes[j], wrap(next[j], target));
|
|
3148
|
+
applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
|
|
3149
|
+
} else arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
|
|
2893
3150
|
}
|
|
2894
3151
|
if (start < next.length) changed = true;
|
|
2895
3152
|
} else if (next.length) {
|
|
2896
3153
|
for (let i = 0, len = next.length; i < len; i++) {
|
|
2897
3154
|
const item = previous[i];
|
|
2898
|
-
if (isWrappable(item)
|
|
3155
|
+
if (isWrappable(item) && isWrappable(next[i]))
|
|
3156
|
+
applyState(next[i], wrap(item, target), keyFn);
|
|
2899
3157
|
else {
|
|
2900
3158
|
if (item !== next[i]) changed = true;
|
|
2901
|
-
arrayNodes?.[i] && setSignal(arrayNodes[i], next[i]);
|
|
3159
|
+
arrayNodes?.[i] && setSignal(arrayNodes[i], wrapValue(next[i], target));
|
|
2902
3160
|
}
|
|
2903
3161
|
}
|
|
2904
3162
|
}
|
|
3163
|
+
syncArrayNodeMembership(target, next);
|
|
2905
3164
|
if (prevLength !== next.length) {
|
|
2906
3165
|
changed = true;
|
|
2907
3166
|
arrayNodes?.length && setSignal(arrayNodes.length, next.length);
|
|
@@ -2912,7 +3171,7 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2912
3171
|
let nodes = target[STORE_NODE];
|
|
2913
3172
|
if (nodes) {
|
|
2914
3173
|
const tracked = nodes[$TRACK];
|
|
2915
|
-
const keys = tracked ? getAllKeys(previous, undefined, next) :
|
|
3174
|
+
const keys = tracked ? getAllKeys(previous, undefined, next) : nodeKeys(nodes);
|
|
2916
3175
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
2917
3176
|
const key = keys[i];
|
|
2918
3177
|
const node = nodes[key];
|
|
@@ -2923,6 +3182,7 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2923
3182
|
!previousValue ||
|
|
2924
3183
|
!isWrappable(previousValue) ||
|
|
2925
3184
|
!isWrappable(nextValue) ||
|
|
3185
|
+
Array.isArray(previousValue) !== Array.isArray(nextValue) ||
|
|
2926
3186
|
(keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
|
|
2927
3187
|
) {
|
|
2928
3188
|
tracked && setSignal(tracked, void 0);
|
|
@@ -2931,7 +3191,7 @@ function applyStateFast(next, target, keyFn) {
|
|
|
2931
3191
|
}
|
|
2932
3192
|
}
|
|
2933
3193
|
if ((nodes = target[STORE_HAS])) {
|
|
2934
|
-
const keys =
|
|
3194
|
+
const keys = nodeKeys(nodes);
|
|
2935
3195
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
2936
3196
|
const key = keys[i];
|
|
2937
3197
|
setSignal(nodes[key], key in next);
|
|
@@ -2949,16 +3209,21 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
2949
3209
|
if (Array.isArray(previous)) {
|
|
2950
3210
|
let changed = false;
|
|
2951
3211
|
const prevLength = getOverrideValue(previous, override, "length", optOverride);
|
|
2952
|
-
if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
|
|
3212
|
+
if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
|
|
2953
3213
|
let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
|
|
2954
3214
|
for (
|
|
2955
3215
|
start = 0, end = Math.min(prevLength, next.length);
|
|
2956
3216
|
start < end &&
|
|
2957
|
-
(
|
|
2958
|
-
(item
|
|
3217
|
+
keyedMatch(
|
|
3218
|
+
(item = getOverrideValue(previous, override, start, optOverride)),
|
|
3219
|
+
next[start],
|
|
3220
|
+
keyFn
|
|
3221
|
+
);
|
|
2959
3222
|
start++
|
|
2960
3223
|
) {
|
|
2961
|
-
|
|
3224
|
+
isWrappable(item) &&
|
|
3225
|
+
isWrappable(next[start]) &&
|
|
3226
|
+
applyState(next[start], wrap(item, target), keyFn);
|
|
2962
3227
|
}
|
|
2963
3228
|
const temp = new Array(next.length),
|
|
2964
3229
|
newIndices = new Map();
|
|
@@ -2966,8 +3231,11 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
2966
3231
|
end = prevLength - 1, newEnd = next.length - 1;
|
|
2967
3232
|
end >= start &&
|
|
2968
3233
|
newEnd >= start &&
|
|
2969
|
-
(
|
|
2970
|
-
(item
|
|
3234
|
+
keyedMatch(
|
|
3235
|
+
(item = getOverrideValue(previous, override, end, optOverride)),
|
|
3236
|
+
next[newEnd],
|
|
3237
|
+
keyFn
|
|
3238
|
+
);
|
|
2971
3239
|
end--, newEnd--
|
|
2972
3240
|
) {
|
|
2973
3241
|
temp[newEnd] = item;
|
|
@@ -2975,30 +3243,29 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
2975
3243
|
if (start > newEnd || start > end) {
|
|
2976
3244
|
for (j = start; j <= newEnd; j++) {
|
|
2977
3245
|
changed = true;
|
|
2978
|
-
nodes?.[j] && setSignal(nodes[j],
|
|
3246
|
+
nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
|
|
2979
3247
|
}
|
|
2980
3248
|
for (; j < next.length; j++) {
|
|
2981
3249
|
changed = true;
|
|
2982
|
-
|
|
2983
|
-
nodes?.[j] && setSignal(nodes[j], wrapped);
|
|
2984
|
-
applyState(next[j], wrapped, keyFn);
|
|
3250
|
+
applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
|
|
2985
3251
|
}
|
|
2986
3252
|
const nextLength = next.length;
|
|
2987
|
-
|
|
3253
|
+
syncArrayNodeMembership(target, next);
|
|
3254
|
+
(changed || prevLength !== nextLength) && notifySelf(target);
|
|
2988
3255
|
prevLength !== nextLength && nodes?.length && setSignal(nodes.length, nextLength);
|
|
2989
3256
|
return;
|
|
2990
3257
|
}
|
|
2991
3258
|
newIndicesNext = new Array(newEnd + 1);
|
|
2992
3259
|
for (j = newEnd; j >= start; j--) {
|
|
2993
3260
|
item = next[j];
|
|
2994
|
-
keyVal = item
|
|
3261
|
+
keyVal = itemKey(item, keyFn);
|
|
2995
3262
|
i = newIndices.get(keyVal);
|
|
2996
3263
|
newIndicesNext[j] = i === undefined ? -1 : i;
|
|
2997
3264
|
newIndices.set(keyVal, j);
|
|
2998
3265
|
}
|
|
2999
3266
|
for (i = start; i <= end; i++) {
|
|
3000
3267
|
item = getOverrideValue(previous, override, i, optOverride);
|
|
3001
|
-
keyVal = item
|
|
3268
|
+
keyVal = itemKey(item, keyFn);
|
|
3002
3269
|
j = newIndices.get(keyVal);
|
|
3003
3270
|
if (j !== undefined && j !== -1) {
|
|
3004
3271
|
temp[j] = item;
|
|
@@ -3008,23 +3275,23 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
3008
3275
|
}
|
|
3009
3276
|
for (j = start; j < next.length; j++) {
|
|
3010
3277
|
if (j in temp) {
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
applyState(next[j], wrapped, keyFn);
|
|
3014
|
-
} else nodes?.[j] && setSignal(nodes[j], wrap(next[j], target));
|
|
3278
|
+
applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
|
|
3279
|
+
} else nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
|
|
3015
3280
|
}
|
|
3016
3281
|
if (start < next.length) changed = true;
|
|
3017
3282
|
} else if (next.length) {
|
|
3018
3283
|
for (let i = 0, len = next.length; i < len; i++) {
|
|
3019
3284
|
const item = getOverrideValue(previous, override, i, optOverride);
|
|
3020
|
-
if (isWrappable(item)
|
|
3285
|
+
if (isWrappable(item) && isWrappable(next[i]))
|
|
3286
|
+
applyState(next[i], wrap(item, target), keyFn);
|
|
3021
3287
|
else {
|
|
3022
3288
|
if (item !== next[i]) changed = true;
|
|
3023
|
-
nodes?.[i] && setSignal(nodes[i], next[i]);
|
|
3289
|
+
nodes?.[i] && setSignal(nodes[i], wrapValue(next[i], target));
|
|
3024
3290
|
}
|
|
3025
3291
|
}
|
|
3026
3292
|
}
|
|
3027
3293
|
const nextLength = next.length;
|
|
3294
|
+
syncArrayNodeMembership(target, next);
|
|
3028
3295
|
if (prevLength !== nextLength) {
|
|
3029
3296
|
changed = true;
|
|
3030
3297
|
nodes?.length && setSignal(nodes.length, nextLength);
|
|
@@ -3034,7 +3301,7 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
3034
3301
|
}
|
|
3035
3302
|
if (nodes) {
|
|
3036
3303
|
const tracked = nodes[$TRACK];
|
|
3037
|
-
const keys = tracked ? getAllKeys(previous, override, next) :
|
|
3304
|
+
const keys = tracked ? getAllKeys(previous, override, next) : nodeKeys(nodes);
|
|
3038
3305
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3039
3306
|
const key = keys[i];
|
|
3040
3307
|
const node = nodes[key];
|
|
@@ -3045,6 +3312,7 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
3045
3312
|
!previousValue ||
|
|
3046
3313
|
!isWrappable(previousValue) ||
|
|
3047
3314
|
!isWrappable(nextValue) ||
|
|
3315
|
+
Array.isArray(previousValue) !== Array.isArray(nextValue) ||
|
|
3048
3316
|
(keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
|
|
3049
3317
|
) {
|
|
3050
3318
|
tracked && setSignal(tracked, void 0);
|
|
@@ -3053,7 +3321,7 @@ function applyStateSlow(next, target, keyFn) {
|
|
|
3053
3321
|
}
|
|
3054
3322
|
}
|
|
3055
3323
|
if ((nodes = target[STORE_HAS])) {
|
|
3056
|
-
const keys =
|
|
3324
|
+
const keys = nodeKeys(nodes);
|
|
3057
3325
|
for (let i = 0, len = keys.length; i < len; i++) {
|
|
3058
3326
|
const key = keys[i];
|
|
3059
3327
|
setSignal(nodes[key], key in next);
|
|
@@ -3193,7 +3461,8 @@ const STORE_VALUE = "v",
|
|
|
3193
3461
|
STORE_WRAP = "w",
|
|
3194
3462
|
STORE_LOOKUP = "l",
|
|
3195
3463
|
STORE_FIREWALL = "f",
|
|
3196
|
-
STORE_OPTIMISTIC = "p"
|
|
3464
|
+
STORE_OPTIMISTIC = "p",
|
|
3465
|
+
STORE_MASKED = "m";
|
|
3197
3466
|
const STORE_SELF_PENDING = Symbol("STORE_SELF_PENDING");
|
|
3198
3467
|
function createStoreProxy(value, traps = storeTraps, extend) {
|
|
3199
3468
|
let newTarget;
|
|
@@ -3212,6 +3481,7 @@ function createStoreProxy(value, traps = storeTraps, extend) {
|
|
|
3212
3481
|
return (newTarget[$PROXY] = new Proxy(newTarget, traps));
|
|
3213
3482
|
}
|
|
3214
3483
|
const storeLookup = new WeakMap();
|
|
3484
|
+
const symbolKeyedRecords = new WeakSet();
|
|
3215
3485
|
function wrap(value, target) {
|
|
3216
3486
|
if (target?.[STORE_WRAP]) return target[STORE_WRAP](value, target);
|
|
3217
3487
|
let p = value[$PROXY] || storeLookup.get(value);
|
|
@@ -3252,21 +3522,26 @@ function unwrapStoreValue(value, map, lookup) {
|
|
|
3252
3522
|
function isPrototypePollutionKey$1(property) {
|
|
3253
3523
|
return property === "__proto__" || property === "constructor" || property === "prototype";
|
|
3254
3524
|
}
|
|
3255
|
-
function
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
)
|
|
3262
|
-
return true;
|
|
3525
|
+
function ownEnumerableKeys(o) {
|
|
3526
|
+
return Reflect.ownKeys(o).filter(k => Object.prototype.propertyIsEnumerable.call(o, k));
|
|
3527
|
+
}
|
|
3528
|
+
function getOverlayLayer(target, property) {
|
|
3529
|
+
const opt = target[STORE_OPTIMISTIC_OVERRIDE];
|
|
3530
|
+
if (opt && property in opt) return opt;
|
|
3263
3531
|
const override = target[STORE_OVERRIDE];
|
|
3264
|
-
if (
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3532
|
+
if (override && property in override) return override;
|
|
3533
|
+
return undefined;
|
|
3534
|
+
}
|
|
3535
|
+
function visibleNodeValue(node) {
|
|
3536
|
+
return node._overrideValue !== undefined && node._overrideValue !== NOT_PENDING
|
|
3537
|
+
? node._overrideValue
|
|
3538
|
+
: node._pendingValue !== NOT_PENDING
|
|
3539
|
+
? node._pendingValue
|
|
3540
|
+
: node._value;
|
|
3541
|
+
}
|
|
3542
|
+
function hasOwnStoreProperty(target, property) {
|
|
3543
|
+
const layer = getOverlayLayer(target, property);
|
|
3544
|
+
if (layer) return layer[property] !== $DELETED;
|
|
3270
3545
|
return Object.prototype.hasOwnProperty.call(unwrapStoreValue(target[STORE_VALUE]), property);
|
|
3271
3546
|
}
|
|
3272
3547
|
function hasInheritedAccessor(source, property) {
|
|
@@ -3290,7 +3565,24 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
|
|
|
3290
3565
|
{
|
|
3291
3566
|
equals: equals,
|
|
3292
3567
|
unobserved() {
|
|
3293
|
-
if (nodes[property] === s)
|
|
3568
|
+
if (nodes[property] === s) {
|
|
3569
|
+
delete nodes[property];
|
|
3570
|
+
if (
|
|
3571
|
+
typeof property === "symbol" &&
|
|
3572
|
+
property !== $TRACK &&
|
|
3573
|
+
symbolKeyedRecords.has(nodes)
|
|
3574
|
+
) {
|
|
3575
|
+
const syms = Object.getOwnPropertySymbols(nodes);
|
|
3576
|
+
let hasUserSymbol = false;
|
|
3577
|
+
for (let i = 0, len = syms.length; i < len; i++) {
|
|
3578
|
+
if (syms[i] !== $TRACK) {
|
|
3579
|
+
hasUserSymbol = true;
|
|
3580
|
+
break;
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
if (!hasUserSymbol) symbolKeyedRecords.delete(nodes);
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3294
3586
|
}
|
|
3295
3587
|
},
|
|
3296
3588
|
firewall
|
|
@@ -3303,20 +3595,28 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
|
|
|
3303
3595
|
s._snapshotValue = sv === undefined ? NO_SNAPSHOT : sv;
|
|
3304
3596
|
snapshotSources?.add(s);
|
|
3305
3597
|
}
|
|
3598
|
+
if (typeof property === "symbol" && property !== $TRACK) symbolKeyedRecords.add(nodes);
|
|
3306
3599
|
return (nodes[property] = s);
|
|
3307
3600
|
}
|
|
3308
3601
|
function trackSelf(target, symbol = $TRACK) {
|
|
3309
|
-
getObserver()
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3602
|
+
if (!getObserver()) return;
|
|
3603
|
+
read(
|
|
3604
|
+
getNode(
|
|
3605
|
+
getNodes(target, STORE_NODE),
|
|
3606
|
+
symbol,
|
|
3607
|
+
undefined,
|
|
3608
|
+
target[STORE_FIREWALL],
|
|
3609
|
+
false,
|
|
3610
|
+
target[STORE_OPTIMISTIC]
|
|
3611
|
+
)
|
|
3612
|
+
);
|
|
3613
|
+
if (
|
|
3614
|
+
symbol === $TRACK &&
|
|
3615
|
+
!target[STORE_OVERRIDE] &&
|
|
3616
|
+
!target[STORE_OPTIMISTIC_OVERRIDE] &&
|
|
3617
|
+
target[STORE_VALUE][$TARGET]
|
|
3618
|
+
)
|
|
3619
|
+
target[STORE_VALUE][$TRACK];
|
|
3320
3620
|
}
|
|
3321
3621
|
function notifySelf(target) {
|
|
3322
3622
|
const node = target[STORE_NODE]?.[$TRACK];
|
|
@@ -3327,7 +3627,11 @@ function notifySelf(target) {
|
|
|
3327
3627
|
);
|
|
3328
3628
|
}
|
|
3329
3629
|
function getKeys(source, override, enumerable = true) {
|
|
3330
|
-
const baseKeys =
|
|
3630
|
+
const baseKeys = source[$TARGET]
|
|
3631
|
+
? untrack(() => (enumerable ? Object.keys(source) : Reflect.ownKeys(source)))
|
|
3632
|
+
: enumerable
|
|
3633
|
+
? Object.keys(source)
|
|
3634
|
+
: Reflect.ownKeys(source);
|
|
3331
3635
|
if (!override) return baseKeys;
|
|
3332
3636
|
const keys = new Set(baseKeys);
|
|
3333
3637
|
const overrides = Reflect.ownKeys(override);
|
|
@@ -3341,10 +3645,26 @@ function getPropertyDescriptor(source, override, property) {
|
|
|
3341
3645
|
if (override && property in override) {
|
|
3342
3646
|
if (override[property] === $DELETED) return void 0;
|
|
3343
3647
|
const overrideDesc = Reflect.getOwnPropertyDescriptor(override, property);
|
|
3344
|
-
if (overrideDesc?.get || overrideDesc?.set
|
|
3648
|
+
if (overrideDesc?.get || overrideDesc?.set) return overrideDesc;
|
|
3649
|
+
const baseDesc = Reflect.getOwnPropertyDescriptor(source, property);
|
|
3650
|
+
if (!baseDesc) return overrideDesc;
|
|
3651
|
+
if (baseDesc.get || baseDesc.set) return baseDesc;
|
|
3652
|
+
baseDesc.value = override[property];
|
|
3653
|
+
return baseDesc;
|
|
3345
3654
|
}
|
|
3346
3655
|
return Reflect.getOwnPropertyDescriptor(source, property);
|
|
3347
3656
|
}
|
|
3657
|
+
function maskStoreTarget(target, on) {
|
|
3658
|
+
const firewall = target[STORE_FIREWALL];
|
|
3659
|
+
if (!firewall) return;
|
|
3660
|
+
if (!!target[STORE_MASKED] === on) return;
|
|
3661
|
+
target[STORE_MASKED] = on;
|
|
3662
|
+
const count = (firewall._optimisticMask = (firewall._optimisticMask || 0) + (on ? 1 : -1));
|
|
3663
|
+
if ((on && count === 1) || (!on && count === 0)) {
|
|
3664
|
+
updatePendingSignal(firewall);
|
|
3665
|
+
updateChildCompanions(firewall);
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3348
3668
|
function prepareStoreWrite(target, store, property) {
|
|
3349
3669
|
if (target[STORE_OPTIMISTIC]) {
|
|
3350
3670
|
const firewall = target[STORE_FIREWALL];
|
|
@@ -3369,9 +3689,14 @@ function prepareStoreWrite(target, store, property) {
|
|
|
3369
3689
|
}
|
|
3370
3690
|
const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
|
|
3371
3691
|
const overrideKey = useOptimistic ? STORE_OPTIMISTIC_OVERRIDE : STORE_OVERRIDE;
|
|
3372
|
-
if (useOptimistic) trackOptimisticStore(store);
|
|
3373
3692
|
return { base: base, overrideKey: overrideKey, state: state };
|
|
3374
3693
|
}
|
|
3694
|
+
function armOptimisticStoreWrite(target, store) {
|
|
3695
|
+
if (target[STORE_OPTIMISTIC] && !projectionWriteActive) {
|
|
3696
|
+
trackOptimisticStore(store);
|
|
3697
|
+
maskStoreTarget(target, true);
|
|
3698
|
+
}
|
|
3699
|
+
}
|
|
3375
3700
|
function upsertStoreNode(target, nodes, property, prev, snapshotProps) {
|
|
3376
3701
|
if (nodes[property]) return nodes[property];
|
|
3377
3702
|
const initial = isWrappable(prev) ? wrap(prev, target) : prev;
|
|
@@ -3449,16 +3774,10 @@ const storeTraps = {
|
|
|
3449
3774
|
) {
|
|
3450
3775
|
return read(getNode(nodes, property, undefined, target[STORE_FIREWALL]));
|
|
3451
3776
|
}
|
|
3452
|
-
const
|
|
3453
|
-
|
|
3454
|
-
const overridden =
|
|
3455
|
-
optOverridden || (target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]);
|
|
3777
|
+
const overlay = getOverlayLayer(target, property);
|
|
3778
|
+
const overridden = !!overlay;
|
|
3456
3779
|
const proxySource = !!target[STORE_VALUE][$TARGET];
|
|
3457
|
-
const storeValue =
|
|
3458
|
-
? target[STORE_OPTIMISTIC_OVERRIDE]
|
|
3459
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3460
|
-
? target[STORE_OVERRIDE]
|
|
3461
|
-
: target[STORE_VALUE];
|
|
3780
|
+
const storeValue = overlay ?? target[STORE_VALUE];
|
|
3462
3781
|
if (!tracked) {
|
|
3463
3782
|
const desc = Object.getOwnPropertyDescriptor(storeValue, property);
|
|
3464
3783
|
if (desc && desc.get) return desc.get.call(receiver);
|
|
@@ -3473,13 +3792,7 @@ const storeTraps = {
|
|
|
3473
3792
|
if (isPrototypePollutionKey$1(property) && !hasOwnStoreProperty(target, property))
|
|
3474
3793
|
return undefined;
|
|
3475
3794
|
let value =
|
|
3476
|
-
tracked && (overridden || !proxySource)
|
|
3477
|
-
? tracked._overrideValue !== undefined && tracked._overrideValue !== NOT_PENDING
|
|
3478
|
-
? tracked._overrideValue
|
|
3479
|
-
: tracked._pendingValue !== NOT_PENDING
|
|
3480
|
-
? tracked._pendingValue
|
|
3481
|
-
: tracked._value
|
|
3482
|
-
: storeValue[property];
|
|
3795
|
+
tracked && (overridden || !proxySource) ? visibleNodeValue(tracked) : storeValue[property];
|
|
3483
3796
|
value === $DELETED && (value = undefined);
|
|
3484
3797
|
if (!isWrappable(value)) return value;
|
|
3485
3798
|
const wrapped = wrap(value, target);
|
|
@@ -3493,7 +3806,11 @@ const storeTraps = {
|
|
|
3493
3806
|
: storeValue[property];
|
|
3494
3807
|
value === $DELETED && (value = undefined);
|
|
3495
3808
|
if (!tracked) {
|
|
3496
|
-
if (
|
|
3809
|
+
if (
|
|
3810
|
+
!overridden &&
|
|
3811
|
+
typeof value === "function" &&
|
|
3812
|
+
!Object.prototype.hasOwnProperty.call(storeValue, property)
|
|
3813
|
+
) {
|
|
3497
3814
|
let proto;
|
|
3498
3815
|
return !Array.isArray(target[STORE_VALUE]) &&
|
|
3499
3816
|
(proto = Object.getPrototypeOf(target[STORE_VALUE])) &&
|
|
@@ -3532,12 +3849,8 @@ const storeTraps = {
|
|
|
3532
3849
|
},
|
|
3533
3850
|
has(target, property) {
|
|
3534
3851
|
if (property === $PROXY || property === $TRACK || property === "__proto__") return true;
|
|
3535
|
-
const
|
|
3536
|
-
|
|
3537
|
-
? target[STORE_OPTIMISTIC_OVERRIDE][property] !== $DELETED
|
|
3538
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3539
|
-
? target[STORE_OVERRIDE][property] !== $DELETED
|
|
3540
|
-
: property in target[STORE_VALUE];
|
|
3852
|
+
const hasLayer = getOverlayLayer(target, property);
|
|
3853
|
+
const has = hasLayer ? hasLayer[property] !== $DELETED : property in target[STORE_VALUE];
|
|
3541
3854
|
if (writeOnly(target[$PROXY]) || getObserver() === target[STORE_FIREWALL]) return has;
|
|
3542
3855
|
const nodes = getNodes(target, STORE_HAS);
|
|
3543
3856
|
if (nodes[property]) return read(nodes[property]);
|
|
@@ -3558,30 +3871,24 @@ const storeTraps = {
|
|
|
3558
3871
|
overrideKey: overrideKey,
|
|
3559
3872
|
state: state
|
|
3560
3873
|
} = prepareStoreWrite(target, store, property);
|
|
3561
|
-
const
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
: base;
|
|
3567
|
-
const prevHas =
|
|
3568
|
-
target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
|
|
3569
|
-
? target[STORE_OPTIMISTIC_OVERRIDE][property] !== $DELETED
|
|
3570
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3571
|
-
? target[STORE_OVERRIDE][property] !== $DELETED
|
|
3572
|
-
: property in target[STORE_VALUE];
|
|
3874
|
+
const prevLayer = getOverlayLayer(target, property);
|
|
3875
|
+
const prev = prevLayer ? prevLayer[property] : base;
|
|
3876
|
+
const prevHas = prevLayer
|
|
3877
|
+
? prevLayer[property] !== $DELETED
|
|
3878
|
+
: property in target[STORE_VALUE];
|
|
3573
3879
|
const value = unwrapStoreValue(rawValue);
|
|
3574
|
-
const
|
|
3575
|
-
const
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3880
|
+
const index = typeof property === "string" ? Number(property) : -1;
|
|
3881
|
+
const isArrayIndexWrite =
|
|
3882
|
+
Array.isArray(state) &&
|
|
3883
|
+
Number.isInteger(index) &&
|
|
3884
|
+
index >= 0 &&
|
|
3885
|
+
index < 4294967295 &&
|
|
3886
|
+
String(index) === property;
|
|
3887
|
+
const nextIndex = isArrayIndexWrite ? index + 1 : 0;
|
|
3888
|
+
const len = isArrayIndexWrite && (getOverlayLayer(target, "length") ?? state).length;
|
|
3583
3889
|
const nextLength = isArrayIndexWrite && nextIndex > len ? nextIndex : undefined;
|
|
3584
3890
|
if (prev === value && nextLength === undefined) return true;
|
|
3891
|
+
armOptimisticStoreWrite(target, store);
|
|
3585
3892
|
if (value !== undefined && value === base && nextLength === undefined)
|
|
3586
3893
|
delete target[overrideKey]?.[property];
|
|
3587
3894
|
else {
|
|
@@ -3590,6 +3897,22 @@ const storeTraps = {
|
|
|
3590
3897
|
if (nextLength !== undefined) override.length = nextLength;
|
|
3591
3898
|
}
|
|
3592
3899
|
notifyStoreProperty(target, property, "set", value, prev, prevHas);
|
|
3900
|
+
if (
|
|
3901
|
+
Array.isArray(state) &&
|
|
3902
|
+
property === "length" &&
|
|
3903
|
+
typeof value === "number" &&
|
|
3904
|
+
typeof prev === "number" &&
|
|
3905
|
+
value < prev
|
|
3906
|
+
) {
|
|
3907
|
+
const override = target[overrideKey] || (target[overrideKey] = Object.create(null));
|
|
3908
|
+
for (let i = value; i < prev; i++) {
|
|
3909
|
+
if (override[i] === $DELETED) continue;
|
|
3910
|
+
const prevIndex = i in override ? override[i] : state[i];
|
|
3911
|
+
if (!(i in override) && !(i in state)) continue;
|
|
3912
|
+
override[i] = $DELETED;
|
|
3913
|
+
notifyStoreProperty(target, i, "delete", undefined, prevIndex, true);
|
|
3914
|
+
}
|
|
3915
|
+
}
|
|
3593
3916
|
if (Array.isArray(state) && property !== "length" && nextLength !== undefined) {
|
|
3594
3917
|
const nodes = getNodes(target, STORE_NODE);
|
|
3595
3918
|
if (nodes.length) {
|
|
@@ -3616,6 +3939,7 @@ const storeTraps = {
|
|
|
3616
3939
|
if (writeOnly(store)) {
|
|
3617
3940
|
untrack(() => {
|
|
3618
3941
|
const { base: base, overrideKey: overrideKey } = prepareStoreWrite(target, store, property);
|
|
3942
|
+
armOptimisticStoreWrite(target, store);
|
|
3619
3943
|
const normalizedDescriptor =
|
|
3620
3944
|
"value" in descriptor
|
|
3621
3945
|
? { ...descriptor, value: unwrapStoreValue(descriptor.value) }
|
|
@@ -3645,19 +3969,16 @@ const storeTraps = {
|
|
|
3645
3969
|
untrack(() => {
|
|
3646
3970
|
const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
|
|
3647
3971
|
const overrideKey = useOptimistic ? STORE_OPTIMISTIC_OVERRIDE : STORE_OVERRIDE;
|
|
3648
|
-
|
|
3649
|
-
const prev =
|
|
3650
|
-
target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
|
|
3651
|
-
? target[STORE_OPTIMISTIC_OVERRIDE][property]
|
|
3652
|
-
: target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
|
|
3653
|
-
? target[STORE_OVERRIDE][property]
|
|
3654
|
-
: target[STORE_VALUE][property];
|
|
3972
|
+
const prevLayer = getOverlayLayer(target, property);
|
|
3973
|
+
const prev = prevLayer ? prevLayer[property] : target[STORE_VALUE][property];
|
|
3655
3974
|
if (
|
|
3656
3975
|
property in target[STORE_VALUE] ||
|
|
3657
3976
|
(target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE])
|
|
3658
3977
|
) {
|
|
3978
|
+
armOptimisticStoreWrite(target, target[$PROXY]);
|
|
3659
3979
|
(target[overrideKey] || (target[overrideKey] = Object.create(null)))[property] = $DELETED;
|
|
3660
3980
|
} else if (target[overrideKey] && property in target[overrideKey]) {
|
|
3981
|
+
armOptimisticStoreWrite(target, target[$PROXY]);
|
|
3661
3982
|
delete target[overrideKey][property];
|
|
3662
3983
|
} else return true;
|
|
3663
3984
|
notifyStoreProperty(target, property, "delete", undefined, prev, true);
|
|
@@ -3686,7 +4007,13 @@ const storeTraps = {
|
|
|
3686
4007
|
if (optDesc?.get || optDesc?.set || !(property in target[STORE_VALUE])) return optDesc;
|
|
3687
4008
|
const baseDesc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
|
|
3688
4009
|
if (baseDesc) {
|
|
3689
|
-
|
|
4010
|
+
const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
|
|
4011
|
+
const configurable = !targetDesc || targetDesc.configurable ? true : baseDesc.configurable;
|
|
4012
|
+
return {
|
|
4013
|
+
...baseDesc,
|
|
4014
|
+
configurable: configurable,
|
|
4015
|
+
value: target[STORE_OPTIMISTIC_OVERRIDE][property]
|
|
4016
|
+
};
|
|
3690
4017
|
}
|
|
3691
4018
|
return {
|
|
3692
4019
|
value: target[STORE_OPTIMISTIC_OVERRIDE][property],
|
|
@@ -3695,7 +4022,12 @@ const storeTraps = {
|
|
|
3695
4022
|
configurable: true
|
|
3696
4023
|
};
|
|
3697
4024
|
}
|
|
3698
|
-
|
|
4025
|
+
const desc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
|
|
4026
|
+
if (desc && !desc.configurable) {
|
|
4027
|
+
const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
|
|
4028
|
+
if (!targetDesc || targetDesc.configurable) return { ...desc, configurable: true };
|
|
4029
|
+
}
|
|
4030
|
+
return desc;
|
|
3699
4031
|
},
|
|
3700
4032
|
getPrototypeOf(target) {
|
|
3701
4033
|
return Object.getPrototypeOf(target[STORE_VALUE]);
|
|
@@ -3712,7 +4044,7 @@ function storeSetter(store, fn) {
|
|
|
3712
4044
|
for (let i = 0, len = value.length; i < len; i++) store[i] = value[i];
|
|
3713
4045
|
store.length = value.length;
|
|
3714
4046
|
} else {
|
|
3715
|
-
const keys = new Set([...
|
|
4047
|
+
const keys = new Set([...ownEnumerableKeys(store), ...ownEnumerableKeys(value)]);
|
|
3716
4048
|
keys.forEach(key => {
|
|
3717
4049
|
if (key in value) store[key] = value[key];
|
|
3718
4050
|
else delete store[key];
|
|
@@ -3748,12 +4080,15 @@ function createOptimisticStore(first, second, options) {
|
|
|
3748
4080
|
}
|
|
3749
4081
|
function clearOptimisticStore(store) {
|
|
3750
4082
|
const target = store[$TARGET];
|
|
3751
|
-
if (!target
|
|
4083
|
+
if (!target) return;
|
|
4084
|
+
maskStoreTarget(target, false);
|
|
4085
|
+
if (!target[STORE_OPTIMISTIC_OVERRIDE]) return;
|
|
3752
4086
|
clearOptimisticOverride(target);
|
|
3753
4087
|
}
|
|
3754
4088
|
function clearOptimisticOverride(target) {
|
|
3755
4089
|
const override = target[STORE_OPTIMISTIC_OVERRIDE];
|
|
3756
4090
|
if (!override) return;
|
|
4091
|
+
maskStoreTarget(target, false);
|
|
3757
4092
|
const nodes = target[STORE_NODE];
|
|
3758
4093
|
delete target[STORE_OPTIMISTIC_OVERRIDE];
|
|
3759
4094
|
const wasProjectionWriteActive = projectionWriteActive;
|
|
@@ -3764,18 +4099,11 @@ function clearOptimisticOverride(target) {
|
|
|
3764
4099
|
if (nodes[key]) {
|
|
3765
4100
|
const node = nodes[key];
|
|
3766
4101
|
node._optimisticLane = undefined;
|
|
3767
|
-
const
|
|
3768
|
-
|
|
3769
|
-
? target[STORE_OVERRIDE][key]
|
|
3770
|
-
: target[STORE_VALUE][key];
|
|
4102
|
+
const layer = getOverlayLayer(target, key);
|
|
4103
|
+
const baseValue = layer ? layer[key] : target[STORE_VALUE][key];
|
|
3771
4104
|
const value = baseValue === $DELETED ? undefined : baseValue;
|
|
3772
4105
|
const next = isWrappable(value) ? wrap(value, target) : value;
|
|
3773
|
-
const prev =
|
|
3774
|
-
node._overrideValue !== undefined && node._overrideValue !== NOT_PENDING
|
|
3775
|
-
? node._overrideValue
|
|
3776
|
-
: node._pendingValue !== NOT_PENDING
|
|
3777
|
-
? node._pendingValue
|
|
3778
|
-
: node._value;
|
|
4106
|
+
const prev = visibleNodeValue(node);
|
|
3779
4107
|
node._overrideValue = NOT_PENDING;
|
|
3780
4108
|
node._pendingValue = NOT_PENDING;
|
|
3781
4109
|
node._value = next;
|
|
@@ -3907,10 +4235,10 @@ function updatePath(current, args, i = 0) {
|
|
|
3907
4235
|
(isWrappable(prev) && isWrappable(value) && !Array.isArray(value))
|
|
3908
4236
|
) {
|
|
3909
4237
|
const target = part !== undefined ? current[part] : current;
|
|
3910
|
-
const keys =
|
|
4238
|
+
const keys = ownEnumerableKeys(value);
|
|
3911
4239
|
for (let i = 0; i < keys.length; i++) {
|
|
3912
4240
|
const key = keys[i];
|
|
3913
|
-
if (isPrototypePollutionKey(key)) continue;
|
|
4241
|
+
if (typeof key === "string" && isPrototypePollutionKey(key)) continue;
|
|
3914
4242
|
const desc = Object.getOwnPropertyDescriptor(value, key);
|
|
3915
4243
|
if (desc.get || desc.set) Object.defineProperty(target, key, desc);
|
|
3916
4244
|
else target[key] = desc.value;
|
|
@@ -3927,6 +4255,11 @@ const storePath = Object.assign(
|
|
|
3927
4255
|
},
|
|
3928
4256
|
{ DELETE: DELETE }
|
|
3929
4257
|
);
|
|
4258
|
+
function mergedOverlay(target) {
|
|
4259
|
+
const override = target[STORE_OVERRIDE];
|
|
4260
|
+
const opt = target[STORE_OPTIMISTIC_OVERRIDE];
|
|
4261
|
+
return override && opt ? { ...override, ...opt } : (opt ?? override);
|
|
4262
|
+
}
|
|
3930
4263
|
function snapshotImpl(item, track, map, lookup) {
|
|
3931
4264
|
let target, isArray, override, result, unwrapped, v;
|
|
3932
4265
|
if (!isWrappable(item)) return item;
|
|
@@ -3934,7 +4267,7 @@ function snapshotImpl(item, track, map, lookup) {
|
|
|
3934
4267
|
if (!map) map = new Map();
|
|
3935
4268
|
if ((target = item[$TARGET] || lookup?.get(item)?.[$TARGET])) {
|
|
3936
4269
|
if (track) trackSelf(target, $TRACK);
|
|
3937
|
-
override = target
|
|
4270
|
+
override = mergedOverlay(target);
|
|
3938
4271
|
isArray = Array.isArray(target[STORE_VALUE]);
|
|
3939
4272
|
map.set(
|
|
3940
4273
|
item,
|
|
@@ -3959,13 +4292,30 @@ function snapshotImpl(item, track, map, lookup) {
|
|
|
3959
4292
|
result[i] = unwrapped;
|
|
3960
4293
|
}
|
|
3961
4294
|
}
|
|
4295
|
+
if (result) result.length = len;
|
|
4296
|
+
} else if (!override) {
|
|
4297
|
+
const keys = getKeys(item, undefined);
|
|
4298
|
+
for (let i = 0, l = keys.length; i < l; i++) {
|
|
4299
|
+
const prop = keys[i];
|
|
4300
|
+
const desc = Object.getOwnPropertyDescriptor(item, prop);
|
|
4301
|
+
if (desc.get) continue;
|
|
4302
|
+
v = desc.value;
|
|
4303
|
+
if (track && isWrappable(v)) wrap(v, target);
|
|
4304
|
+
if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== v || result) {
|
|
4305
|
+
if (!result) {
|
|
4306
|
+
result = Object.create(Object.getPrototypeOf(item));
|
|
4307
|
+
Object.assign(result, item);
|
|
4308
|
+
}
|
|
4309
|
+
result[prop] = unwrapped;
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
3962
4312
|
} else {
|
|
3963
4313
|
const keys = getKeys(item, override);
|
|
3964
4314
|
for (let i = 0, l = keys.length; i < l; i++) {
|
|
3965
4315
|
let prop = keys[i];
|
|
3966
4316
|
const desc = getPropertyDescriptor(item, override, prop);
|
|
3967
4317
|
if (desc.get) continue;
|
|
3968
|
-
v =
|
|
4318
|
+
v = prop in override ? override[prop] : item[prop];
|
|
3969
4319
|
if (track && isWrappable(v)) wrap(v, target);
|
|
3970
4320
|
if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== item[prop] || result) {
|
|
3971
4321
|
if (!result) {
|
|
@@ -4048,7 +4398,7 @@ function merge(...sources) {
|
|
|
4048
4398
|
keys() {
|
|
4049
4399
|
const keys = new Set();
|
|
4050
4400
|
for (let i = 0; i < flattened.length; i++) {
|
|
4051
|
-
const sourceKeys =
|
|
4401
|
+
const sourceKeys = ownEnumerableKeys(resolveSource(flattened[i]));
|
|
4052
4402
|
for (let j = 0; j < sourceKeys.length; j++) keys.add(sourceKeys[j]);
|
|
4053
4403
|
}
|
|
4054
4404
|
return [...keys];
|
|
@@ -4102,7 +4452,7 @@ function omit(props, ...keys) {
|
|
|
4102
4452
|
return !keys.includes(property) && property in props;
|
|
4103
4453
|
},
|
|
4104
4454
|
keys() {
|
|
4105
|
-
return
|
|
4455
|
+
return ownEnumerableKeys(props).filter(k => !keys.includes(k));
|
|
4106
4456
|
}
|
|
4107
4457
|
},
|
|
4108
4458
|
propTraps
|
|
@@ -4331,6 +4681,18 @@ function updateRepeat() {
|
|
|
4331
4681
|
const to = from + newLen;
|
|
4332
4682
|
const prevTo = this._offset + this._len;
|
|
4333
4683
|
if (this._len === 0 && this._nodes[0]) this._nodes[0].dispose();
|
|
4684
|
+
if (from >= prevTo || to <= this._offset) {
|
|
4685
|
+
for (let i = 0; i < this._len; i++) this._nodes[i].dispose();
|
|
4686
|
+
this._nodes = new Array(newLen);
|
|
4687
|
+
this._mappings = new Array(newLen);
|
|
4688
|
+
for (let i = 0; i < newLen; i++)
|
|
4689
|
+
this._mappings[i] = runWithOwner((this._nodes[i] = createOwner()), () =>
|
|
4690
|
+
this._map(from + i)
|
|
4691
|
+
);
|
|
4692
|
+
this._offset = from;
|
|
4693
|
+
this._len = newLen;
|
|
4694
|
+
return;
|
|
4695
|
+
}
|
|
4334
4696
|
for (let i = to; i < prevTo; i++) this._nodes[i - this._offset].dispose();
|
|
4335
4697
|
if (this._offset < from) {
|
|
4336
4698
|
const removed = from - this._offset;
|
|
@@ -4372,7 +4734,13 @@ function boundaryComputed(fn, propagationMask) {
|
|
|
4372
4734
|
const flags = status !== undefined ? status : node._statusFlags;
|
|
4373
4735
|
const actualError = error !== undefined ? error : node._error;
|
|
4374
4736
|
node._statusFlags &= ~node._propagationMask;
|
|
4375
|
-
node._queue.notify(node,
|
|
4737
|
+
node._queue.notify(node, STATUS_PENDING | STATUS_ERROR, flags, actualError);
|
|
4738
|
+
const foreign = flags & ~node._propagationMask & (STATUS_PENDING | STATUS_ERROR);
|
|
4739
|
+
if (foreign) {
|
|
4740
|
+
node._statusFlags &= ~foreign;
|
|
4741
|
+
if (node._error === actualError && !(node._statusFlags & (STATUS_PENDING | STATUS_ERROR)))
|
|
4742
|
+
node._error = undefined;
|
|
4743
|
+
}
|
|
4376
4744
|
};
|
|
4377
4745
|
node._propagationMask = propagationMask;
|
|
4378
4746
|
node._config &= ~CONFIG_AUTO_DISPOSE;
|
|
@@ -4566,9 +4934,6 @@ class CollectionQueue extends Queue {
|
|
|
4566
4934
|
}
|
|
4567
4935
|
if (this._collectionType & STATUS_PENDING && this._initialized)
|
|
4568
4936
|
return super.notify(node, type, flags, error);
|
|
4569
|
-
if (this._collectionType & STATUS_PENDING && flags & STATUS_ERROR) {
|
|
4570
|
-
return super.notify(node, STATUS_ERROR, flags, error);
|
|
4571
|
-
}
|
|
4572
4937
|
if (flags & this._collectionType) {
|
|
4573
4938
|
this._pending = true;
|
|
4574
4939
|
const source = error?.source || node._error?.source;
|
|
@@ -4577,7 +4942,7 @@ class CollectionQueue extends Queue {
|
|
|
4577
4942
|
this._sources.add(source);
|
|
4578
4943
|
if (wasEmpty) setSignal(this._disabled, true);
|
|
4579
4944
|
if (this._collectionType & STATUS_ERROR) {
|
|
4580
|
-
setSignal(this._error, source._error
|
|
4945
|
+
setSignal(this._error, unwrapStatusError(source._error));
|
|
4581
4946
|
}
|
|
4582
4947
|
}
|
|
4583
4948
|
}
|
|
@@ -4655,14 +5020,17 @@ function createCollectionBoundary(type, fn, fallback, onFn) {
|
|
|
4655
5020
|
cleanup(() => controller.unregister(queue));
|
|
4656
5021
|
}
|
|
4657
5022
|
return accessor(
|
|
4658
|
-
computed(
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
5023
|
+
computed(
|
|
5024
|
+
() => {
|
|
5025
|
+
if (!read(queue._disabled)) {
|
|
5026
|
+
const resolved = read(tree);
|
|
5027
|
+
if (!untrack(() => read(queue._disabled))) return ((queue._initialized = true), resolved);
|
|
5028
|
+
}
|
|
5029
|
+
if (_revealUsed && read(queue._collapsed)) return undefined;
|
|
5030
|
+
return fallback(queue);
|
|
5031
|
+
},
|
|
5032
|
+
{ _noSnapshot: true }
|
|
5033
|
+
)
|
|
4666
5034
|
);
|
|
4667
5035
|
}
|
|
4668
5036
|
function createLoadingBoundary(fn, fallback, options) {
|
|
@@ -4809,6 +5177,7 @@ export {
|
|
|
4809
5177
|
refresh,
|
|
4810
5178
|
releaseSnapshotScope,
|
|
4811
5179
|
repeat,
|
|
5180
|
+
resetErrorHalt,
|
|
4812
5181
|
resolve,
|
|
4813
5182
|
runWithOwner,
|
|
4814
5183
|
setContext,
|