@solidjs/signals 2.0.0-beta.22 → 2.0.0-beta.24
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 +199 -68
- package/dist/node.cjs +1138 -996
- package/dist/prod/core/async.js +27 -11
- package/dist/prod/core/core.js +33 -30
- package/dist/prod/core/effect.js +3 -3
- package/dist/prod/core/error.js +9 -0
- package/dist/prod/core/graph.js +7 -2
- package/dist/prod/core/heap.js +12 -12
- package/dist/prod/core/lanes.js +2 -2
- package/dist/prod/core/optimistic.js +5 -5
- package/dist/prod/core/owner.js +1 -1
- package/dist/prod/core/scheduler.js +11 -11
- package/dist/prod/core/verdict.js +30 -30
- package/dist/prod/map.js +53 -29
- package/dist/prod/store/optimistic.js +31 -29
- package/dist/prod/store/reconcile.js +92 -61
- package/dist/prod/store/store.js +143 -103
- package/dist/prod/store/utils.js +12 -0
- package/dist/types/core/error.d.ts +1 -1
- package/dist/types/store/reconcile.d.ts +17 -8
- package/dist/types-cjs/core/error.d.cts +1 -1
- package/dist/types-cjs/store/reconcile.d.cts +17 -8
- package/package.json +1 -1
package/dist/node.cjs
CHANGED
|
@@ -26,7 +26,16 @@
|
|
|
26
26
|
*/ class NotReadyError extends Error {
|
|
27
27
|
source;
|
|
28
28
|
constructor(e) {
|
|
29
|
+
// Control-flow throw: it happens on every read of a pending source, so in
|
|
30
|
+
// production skip V8's eager stack capture (proportional to stack depth —
|
|
31
|
+
// real cost under SSR) by zeroing the V8-specific stackTraceLimit around
|
|
32
|
+
// super(). Dev keeps the stack for debuggability; non-V8 engines (no
|
|
33
|
+
// stackTraceLimit) take the plain path.
|
|
34
|
+
const t = Error;
|
|
35
|
+
const n = t.stackTraceLimit;
|
|
36
|
+
if (n !== undefined) t.stackTraceLimit = 0;
|
|
29
37
|
super();
|
|
38
|
+
if (n !== undefined) t.stackTraceLimit = n;
|
|
30
39
|
this.source = e;
|
|
31
40
|
}
|
|
32
41
|
}
|
|
@@ -214,7 +223,7 @@ const activeLanes = new Set;
|
|
|
214
223
|
l: [ [], [] ],
|
|
215
224
|
S: null,
|
|
216
225
|
T: activeTransition,
|
|
217
|
-
|
|
226
|
+
_: r
|
|
218
227
|
};
|
|
219
228
|
signalLanes.set(e, t);
|
|
220
229
|
activeLanes.add(t);
|
|
@@ -224,8 +233,8 @@ const activeLanes = new Set;
|
|
|
224
233
|
// parent-child is a property of the nodes, not of write order — otherwise
|
|
225
234
|
// the owner's write merges the companion's subscribers into this lane and
|
|
226
235
|
// their effects wait on its async instead of flushing immediately.
|
|
227
|
-
adoptCompanionLane(e.
|
|
228
|
-
adoptCompanionLane(e.
|
|
236
|
+
adoptCompanionLane(e.O, t);
|
|
237
|
+
adoptCompanionLane(e.p, t);
|
|
229
238
|
return t;
|
|
230
239
|
}
|
|
231
240
|
|
|
@@ -236,7 +245,7 @@ function adoptCompanionLane(e, t) {
|
|
|
236
245
|
const r = findLane(n);
|
|
237
246
|
// Only the companion's own unmerged root is safely re-parentable: a root
|
|
238
247
|
// that absorbed other lanes carries work that is not a child of this owner.
|
|
239
|
-
if (r !== t && r.o === e && !r.
|
|
248
|
+
if (r !== t && r.o === e && !r._) r._ = t;
|
|
240
249
|
}
|
|
241
250
|
|
|
242
251
|
/**
|
|
@@ -315,9 +324,9 @@ function resolveTransition(e) {
|
|
|
315
324
|
if (i !== n && !hasActiveOverride(e)) {
|
|
316
325
|
// Parent-child lanes stay independent so isPending resolves without
|
|
317
326
|
// waiting for the parent's async. The child keeps ownership.
|
|
318
|
-
if (n.
|
|
327
|
+
if (n._ && findLane(n._) === i) {
|
|
319
328
|
e.i = t;
|
|
320
|
-
} else if (i.
|
|
329
|
+
} else if (i._ && findLane(i._) === n) ; else mergeLanes(n, i);
|
|
321
330
|
}
|
|
322
331
|
return;
|
|
323
332
|
}
|
|
@@ -330,15 +339,15 @@ const transitions = new Set;
|
|
|
330
339
|
const dirtyQueue = {
|
|
331
340
|
h: new Array(2e3).fill(undefined),
|
|
332
341
|
N: false,
|
|
333
|
-
|
|
334
|
-
|
|
342
|
+
P: 0,
|
|
343
|
+
C: 0
|
|
335
344
|
};
|
|
336
345
|
|
|
337
346
|
const zombieQueue = {
|
|
338
347
|
h: new Array(2e3).fill(undefined),
|
|
339
348
|
N: false,
|
|
340
|
-
|
|
341
|
-
|
|
349
|
+
P: 0,
|
|
350
|
+
C: 0
|
|
342
351
|
};
|
|
343
352
|
|
|
344
353
|
let clock = 0;
|
|
@@ -367,13 +376,13 @@ function registerTransientStoreNode(e) {
|
|
|
367
376
|
|
|
368
377
|
function canUseSimpleSyncFlush(e) {
|
|
369
378
|
const t = e.D;
|
|
370
|
-
return transitions.size === 0 && activeLanes.size === 0 && e.m.length === 0 && t.
|
|
379
|
+
return transitions.size === 0 && activeLanes.size === 0 && e.m.length === 0 && t.v.length === 0 && t.G.length === 0 && t.L.size === 0 && transientStoreNodes.size === 0;
|
|
371
380
|
}
|
|
372
381
|
|
|
373
382
|
function sweepTransientStoreNodes() {
|
|
374
383
|
if (transientStoreNodes.size === 0) return;
|
|
375
384
|
for (const e of transientStoreNodes) {
|
|
376
|
-
if (e.
|
|
385
|
+
if (e.U !== null) {
|
|
377
386
|
transientStoreNodes.delete(e);
|
|
378
387
|
continue;
|
|
379
388
|
}
|
|
@@ -382,9 +391,9 @@ function sweepTransientStoreNodes() {
|
|
|
382
391
|
// A live affects() mark keeps the node addressable: sweeping it would
|
|
383
392
|
// detach the refcount from the slot (a fresh probe would upsert a new,
|
|
384
393
|
// unmarked node for the same property).
|
|
385
|
-
if (e.
|
|
394
|
+
if (e.k) continue;
|
|
386
395
|
transientStoreNodes.delete(e);
|
|
387
|
-
e.
|
|
396
|
+
e.F?.();
|
|
388
397
|
}
|
|
389
398
|
}
|
|
390
399
|
|
|
@@ -411,19 +420,19 @@ function setProjectionWriteActive(e) {
|
|
|
411
420
|
* land there directly — no per-field aliasing.
|
|
412
421
|
*/ function createBatch() {
|
|
413
422
|
return {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
423
|
+
W: clock,
|
|
424
|
+
M: [],
|
|
425
|
+
H: new Map,
|
|
426
|
+
v: [],
|
|
417
427
|
G: [],
|
|
418
|
-
L:
|
|
419
|
-
U: new Set,
|
|
428
|
+
L: new Set,
|
|
420
429
|
$: [],
|
|
421
|
-
|
|
422
|
-
|
|
430
|
+
j: {
|
|
431
|
+
K: [ [], [] ],
|
|
423
432
|
m: []
|
|
424
433
|
},
|
|
425
434
|
I: false,
|
|
426
|
-
|
|
435
|
+
Y: new Set
|
|
427
436
|
};
|
|
428
437
|
}
|
|
429
438
|
|
|
@@ -431,27 +440,27 @@ function mergeTransitionState(e, t) {
|
|
|
431
440
|
t.I = e;
|
|
432
441
|
e.$.push(...t.$);
|
|
433
442
|
for (const n of activeLanes) if (n.T === t) n.T = e;
|
|
434
|
-
if (t.
|
|
443
|
+
if (t.v.length) {
|
|
435
444
|
// Move (don't copy): the global queue's batch may still be the outgoing
|
|
436
445
|
// transition, and the adoption pass in initTransition would re-push its
|
|
437
446
|
// contents into the target — duplicating every entry.
|
|
438
|
-
e.
|
|
439
|
-
t.
|
|
447
|
+
e.v.push(...t.v);
|
|
448
|
+
t.v.length = 0;
|
|
440
449
|
}
|
|
441
|
-
if (t.
|
|
450
|
+
if (t.G.length) {
|
|
442
451
|
// Move (don't copy): the global queue's batch may still be the outgoing
|
|
443
452
|
// transition, and the adoption pass in initTransition would re-push its
|
|
444
453
|
// contents into the target — double-releasing every mark.
|
|
445
|
-
e.
|
|
446
|
-
t.
|
|
454
|
+
e.G.push(...t.G);
|
|
455
|
+
t.G.length = 0;
|
|
447
456
|
}
|
|
448
|
-
for (const n of t.
|
|
449
|
-
for (const [n, r] of t.
|
|
450
|
-
let t = e.
|
|
451
|
-
if (!t) e.
|
|
457
|
+
for (const n of t.L) e.L.add(n);
|
|
458
|
+
for (const [n, r] of t.H) {
|
|
459
|
+
let t = e.H.get(n);
|
|
460
|
+
if (!t) e.H.set(n, t = new Set);
|
|
452
461
|
for (const e of r) t.add(e);
|
|
453
462
|
}
|
|
454
|
-
for (const n of t.
|
|
463
|
+
for (const n of t.Y) e.Y.add(n);
|
|
455
464
|
}
|
|
456
465
|
|
|
457
466
|
function schedule() {
|
|
@@ -461,7 +470,7 @@ function schedule() {
|
|
|
461
470
|
}
|
|
462
471
|
if (scheduled) return;
|
|
463
472
|
scheduled = true;
|
|
464
|
-
if (!syncDepth && !globalQueue.
|
|
473
|
+
if (!syncDepth && !globalQueue.q && !projectionWriteActive) queueMicrotask(flush);
|
|
465
474
|
}
|
|
466
475
|
|
|
467
476
|
/**
|
|
@@ -491,29 +500,29 @@ function notifyHalted() {
|
|
|
491
500
|
}
|
|
492
501
|
|
|
493
502
|
class Queue {
|
|
494
|
-
|
|
495
|
-
|
|
503
|
+
B=null;
|
|
504
|
+
K=[ [], [] ];
|
|
496
505
|
m=[];
|
|
497
506
|
created=clock;
|
|
498
507
|
addChild(e) {
|
|
499
508
|
this.m.push(e);
|
|
500
|
-
e.
|
|
509
|
+
e.B = this;
|
|
501
510
|
}
|
|
502
511
|
removeChild(e) {
|
|
503
512
|
const t = this.m.indexOf(e);
|
|
504
513
|
if (t >= 0) {
|
|
505
514
|
this.m.splice(t, 1);
|
|
506
|
-
e.
|
|
515
|
+
e.B = null;
|
|
507
516
|
}
|
|
508
517
|
}
|
|
509
518
|
notify(e, t, n, r) {
|
|
510
|
-
if (this.
|
|
519
|
+
if (this.B) return this.B.notify(e, t, n, r);
|
|
511
520
|
return false;
|
|
512
521
|
}
|
|
513
522
|
run(e) {
|
|
514
|
-
if (this.
|
|
515
|
-
const t = this.
|
|
516
|
-
this.
|
|
523
|
+
if (this.K[e - 1].length) {
|
|
524
|
+
const t = this.K[e - 1];
|
|
525
|
+
this.K[e - 1] = [];
|
|
517
526
|
runQueue$1(t, e);
|
|
518
527
|
}
|
|
519
528
|
for (let t = 0; t < this.m.length; t++) this.m[t].run?.(e);
|
|
@@ -525,21 +534,21 @@ class Queue {
|
|
|
525
534
|
const n = findLane(currentOptimisticLane);
|
|
526
535
|
n.l[e - 1].push(t);
|
|
527
536
|
} else {
|
|
528
|
-
this.
|
|
537
|
+
this.K[e - 1].push(t);
|
|
529
538
|
}
|
|
530
539
|
}
|
|
531
540
|
schedule();
|
|
532
541
|
}
|
|
533
542
|
stashQueues(e) {
|
|
534
|
-
e.
|
|
535
|
-
e.
|
|
536
|
-
this.
|
|
543
|
+
e.K[0].push(...this.K[0]);
|
|
544
|
+
e.K[1].push(...this.K[1]);
|
|
545
|
+
this.K = [ [], [] ];
|
|
537
546
|
for (let t = 0; t < this.m.length; t++) {
|
|
538
547
|
let n = this.m[t];
|
|
539
548
|
let r = e.m[t];
|
|
540
549
|
if (!r) {
|
|
541
550
|
r = {
|
|
542
|
-
|
|
551
|
+
K: [ [], [] ],
|
|
543
552
|
m: []
|
|
544
553
|
};
|
|
545
554
|
e.m[t] = r;
|
|
@@ -548,8 +557,8 @@ class Queue {
|
|
|
548
557
|
}
|
|
549
558
|
}
|
|
550
559
|
restoreQueues(e) {
|
|
551
|
-
this.
|
|
552
|
-
this.
|
|
560
|
+
this.K[0].push(...e.K[0]);
|
|
561
|
+
this.K[1].push(...e.K[1]);
|
|
553
562
|
for (let t = 0; t < e.m.length; t++) {
|
|
554
563
|
const n = e.m[t];
|
|
555
564
|
let r = this.m[t];
|
|
@@ -559,44 +568,44 @@ class Queue {
|
|
|
559
568
|
}
|
|
560
569
|
|
|
561
570
|
class GlobalQueue extends Queue {
|
|
562
|
-
|
|
571
|
+
q=false;
|
|
563
572
|
// The current transaction-shaped batch: a plain ambient batch while no
|
|
564
573
|
// transition is active, the active transition itself after initTransition.
|
|
565
574
|
D=createBatch();
|
|
575
|
+
static Z;
|
|
566
576
|
static X;
|
|
567
577
|
static J;
|
|
568
|
-
static ee;
|
|
569
|
-
static te=null;
|
|
578
|
+
static ee=null;
|
|
570
579
|
// Store-side hook: drops a keyless affects() mark's identity scope when the
|
|
571
580
|
// carrier node's last registration releases (wired by store.ts, mirroring
|
|
572
581
|
// _clearOptimisticStore).
|
|
573
|
-
static
|
|
582
|
+
static te=null;
|
|
574
583
|
// affects()-side hooks (wired by affects.ts, mirroring _update): the mark
|
|
575
584
|
// engine — count/register/release — lives with the feature. Every call site
|
|
576
585
|
// is gated by state only that module creates, so `!` invocations are safe
|
|
577
586
|
// once the gate holds.
|
|
587
|
+
static ne=null;
|
|
578
588
|
static re=null;
|
|
579
589
|
static ie=null;
|
|
580
|
-
static oe=null;
|
|
581
590
|
// External-source bridge (wired by enableExternalSource(); null while no
|
|
582
591
|
// config is active — including after _resetExternalSourceConfig()).
|
|
592
|
+
static oe=null;
|
|
583
593
|
static se=null;
|
|
584
|
-
static ue=null;
|
|
585
594
|
// Verdict-layer hooks (wired by verdict.ts when isPending()/latest() are
|
|
586
595
|
// imported; null in apps that never use them). Call sites either guard for
|
|
587
596
|
// null or sit behind state only the verdict layer can create (`!` is safe
|
|
588
597
|
// there: `_pendingSignal`/`_latestValueComputed` are only ever assigned by
|
|
589
598
|
// verdict.ts, and `pendingCheckActive`/`latestReadActive` only flip inside
|
|
590
599
|
// isPending()/latest()).
|
|
600
|
+
static ue=null;
|
|
591
601
|
static le=null;
|
|
592
602
|
static ce=null;
|
|
593
603
|
static ae=null;
|
|
594
604
|
static fe=null;
|
|
595
605
|
static Ee=null;
|
|
596
|
-
static Se=null;
|
|
597
606
|
static de=null;
|
|
607
|
+
static Se=null;
|
|
598
608
|
static Te=null;
|
|
599
|
-
static pe=null;
|
|
600
609
|
static _e=null;
|
|
601
610
|
// Optimistic-engine hooks (wired by core/optimistic.ts via
|
|
602
611
|
// installOptimisticEngine(), called from verdict.ts / createOptimistic /
|
|
@@ -606,28 +615,28 @@ class GlobalQueue extends Queue {
|
|
|
606
615
|
// entry, or a non-null `currentOptimisticLane`, so `!` invocations are safe
|
|
607
616
|
// once the gate holds.
|
|
608
617
|
static Oe=null;
|
|
618
|
+
static pe=null;
|
|
609
619
|
static Re=null;
|
|
610
620
|
static Ie=null;
|
|
611
621
|
static Ae=null;
|
|
612
622
|
static he=null;
|
|
613
623
|
static Ne=null;
|
|
614
624
|
static ye=null;
|
|
615
|
-
static Ce=null;
|
|
616
625
|
static Pe=null;
|
|
626
|
+
static Ce=null;
|
|
617
627
|
static ge=null;
|
|
618
628
|
static be=null;
|
|
619
|
-
static De=null;
|
|
620
629
|
flush() {
|
|
621
|
-
if (this.
|
|
622
|
-
this.
|
|
630
|
+
if (this.q) return;
|
|
631
|
+
this.q = true;
|
|
623
632
|
try {
|
|
624
633
|
if (false) ;
|
|
625
|
-
runHeap(dirtyQueue, GlobalQueue.
|
|
634
|
+
runHeap(dirtyQueue, GlobalQueue.Z);
|
|
626
635
|
if (activeTransition) {
|
|
627
636
|
const e = transitionComplete(activeTransition);
|
|
628
637
|
if (!e) {
|
|
629
638
|
const e = activeTransition;
|
|
630
|
-
runHeap(zombieQueue, GlobalQueue.
|
|
639
|
+
runHeap(zombieQueue, GlobalQueue.Z);
|
|
631
640
|
// Detach: the stashed transition keeps its batch; ambient work that
|
|
632
641
|
// follows lands in a fresh one. If the batch is already a separate
|
|
633
642
|
// ambient one — action done() restored activeTransition without
|
|
@@ -637,80 +646,80 @@ class GlobalQueue extends Queue {
|
|
|
637
646
|
if (this.D === e) currentBatch = this.D = createBatch();
|
|
638
647
|
// Run lane effects immediately (before stashing) - lanes with no pending async
|
|
639
648
|
if (activeLanes.size) {
|
|
640
|
-
GlobalQueue.
|
|
641
|
-
GlobalQueue.
|
|
649
|
+
GlobalQueue.Ae(EFFECT_RENDER);
|
|
650
|
+
GlobalQueue.Ae(EFFECT_USER);
|
|
642
651
|
}
|
|
643
|
-
this.stashQueues(e.
|
|
652
|
+
this.stashQueues(e.j);
|
|
644
653
|
clock++;
|
|
645
654
|
// A kept ambient batch may hold pending nodes (#2916): stay
|
|
646
655
|
// scheduled so the outer drain loop commits them via the plain
|
|
647
656
|
// flush path instead of leaving them until the next natural flush.
|
|
648
|
-
scheduled = dirtyQueue.
|
|
649
|
-
reassignPendingTransition(e.
|
|
657
|
+
scheduled = dirtyQueue.C >= dirtyQueue.P || this.D.M.length > 0;
|
|
658
|
+
reassignPendingTransition(e.M);
|
|
650
659
|
activeTransition = null;
|
|
651
660
|
finalizePureQueue(null, true);
|
|
652
661
|
return;
|
|
653
662
|
}
|
|
654
663
|
const t = activeTransition;
|
|
655
664
|
const n = this.D;
|
|
656
|
-
n !== t && n.
|
|
657
|
-
this.restoreQueues(t.
|
|
665
|
+
n !== t && n.M.push(...t.M);
|
|
666
|
+
this.restoreQueues(t.j);
|
|
658
667
|
transitions.delete(t);
|
|
659
668
|
activeTransition = null;
|
|
660
|
-
reassignPendingTransition(n.
|
|
669
|
+
reassignPendingTransition(n.M);
|
|
661
670
|
finalizePureQueue(t);
|
|
662
671
|
if (n === t) {
|
|
663
672
|
// Drop the dead Transition wrapper but keep its (drained) containers
|
|
664
673
|
// as the ambient batch — late registrations during finalization live
|
|
665
674
|
// there and must survive to the next flush.
|
|
666
675
|
const e = createBatch();
|
|
667
|
-
e.
|
|
676
|
+
e.M = n.M;
|
|
677
|
+
e.v = n.v;
|
|
668
678
|
e.G = n.G;
|
|
669
679
|
e.L = n.L;
|
|
670
|
-
e.U = n.U;
|
|
671
680
|
currentBatch = this.D = e;
|
|
672
681
|
}
|
|
673
682
|
} else {
|
|
674
683
|
if (canUseSimpleSyncFlush(this)) {
|
|
675
684
|
commitPendingNodes();
|
|
676
|
-
if (dirtyQueue.
|
|
677
|
-
runHeap(dirtyQueue, GlobalQueue.
|
|
685
|
+
if (dirtyQueue.C >= dirtyQueue.P) {
|
|
686
|
+
runHeap(dirtyQueue, GlobalQueue.Z);
|
|
678
687
|
commitPendingNodes();
|
|
679
688
|
}
|
|
680
689
|
} else {
|
|
681
|
-
if (transitions.size) runHeap(zombieQueue, GlobalQueue.
|
|
690
|
+
if (transitions.size) runHeap(zombieQueue, GlobalQueue.Z);
|
|
682
691
|
finalizePureQueue();
|
|
683
692
|
}
|
|
684
693
|
}
|
|
685
694
|
clock++;
|
|
686
695
|
// Check if finalization added items to the heap (from optimistic reversion)
|
|
687
|
-
scheduled = dirtyQueue.
|
|
696
|
+
scheduled = dirtyQueue.C >= dirtyQueue.P;
|
|
688
697
|
// Run lane effects first (for ready lanes), then regular effects
|
|
689
|
-
activeLanes.size && GlobalQueue.
|
|
698
|
+
activeLanes.size && GlobalQueue.Ae(EFFECT_RENDER);
|
|
690
699
|
this.run(EFFECT_RENDER);
|
|
691
|
-
activeLanes.size && GlobalQueue.
|
|
700
|
+
activeLanes.size && GlobalQueue.Ae(EFFECT_USER);
|
|
692
701
|
this.run(EFFECT_USER);
|
|
693
702
|
if (false) ;
|
|
694
703
|
if (false && !scheduled && !activeTransition && transitions.size === 0 && activeLanes.size === 0) ;
|
|
695
704
|
if (false) ;
|
|
696
705
|
} finally {
|
|
697
|
-
this.
|
|
706
|
+
this.q = false;
|
|
698
707
|
}
|
|
699
708
|
}
|
|
700
709
|
notify(e, t, n, r) {
|
|
701
710
|
// Only track async if the boundary is propagating STATUS_PENDING (not caught by boundary)
|
|
702
711
|
if (t & STATUS_PENDING) {
|
|
703
712
|
if (n & STATUS_PENDING) {
|
|
704
|
-
const t = r !== undefined ? r : e.
|
|
713
|
+
const t = r !== undefined ? r : e.De;
|
|
705
714
|
// A visibility-only mark notification (the affects() boundary
|
|
706
715
|
// channel) updates display state on its way up but must be invisible
|
|
707
716
|
// to completion accounting BY CONSTRUCTION: it never registers a
|
|
708
717
|
// reporter and never counts toward the loading-boundary diagnostic.
|
|
709
|
-
if (t?.
|
|
718
|
+
if (t?.me) return true;
|
|
710
719
|
if (activeTransition && t) {
|
|
711
720
|
const n = t.source;
|
|
712
|
-
let r = activeTransition.
|
|
713
|
-
if (!r) activeTransition.
|
|
721
|
+
let r = activeTransition.H.get(n);
|
|
722
|
+
if (!r) activeTransition.H.set(n, r = new Set);
|
|
714
723
|
const i = r.size;
|
|
715
724
|
r.add(e);
|
|
716
725
|
if (r.size !== i) schedule();
|
|
@@ -723,7 +732,7 @@ class GlobalQueue extends Queue {
|
|
|
723
732
|
initTransition(e) {
|
|
724
733
|
if (e) e = currentTransition(e);
|
|
725
734
|
if (e && e === activeTransition) return;
|
|
726
|
-
if (!e && activeTransition && activeTransition.
|
|
735
|
+
if (!e && activeTransition && activeTransition.W === clock) return;
|
|
727
736
|
if (!activeTransition) {
|
|
728
737
|
activeTransition = e ?? createBatch();
|
|
729
738
|
} else if (e) {
|
|
@@ -733,7 +742,7 @@ class GlobalQueue extends Queue {
|
|
|
733
742
|
activeTransition = e;
|
|
734
743
|
}
|
|
735
744
|
transitions.add(activeTransition);
|
|
736
|
-
activeTransition.
|
|
745
|
+
activeTransition.W = clock;
|
|
737
746
|
const t = this.D;
|
|
738
747
|
if (t !== activeTransition) {
|
|
739
748
|
// Adopt the ambient batch into the transaction, then make the
|
|
@@ -743,18 +752,18 @@ class GlobalQueue extends Queue {
|
|
|
743
752
|
// must not entangle unrelated writes to it; the same rule holds one hop
|
|
744
753
|
// downstream: propagation never queues pended subscribers as pending
|
|
745
754
|
// nodes, see propagateAffectsMark, #2893.
|
|
746
|
-
for (let e = 0; e < t.
|
|
747
|
-
const n = t.
|
|
755
|
+
for (let e = 0; e < t.M.length; e++) {
|
|
756
|
+
const n = t.M[e];
|
|
748
757
|
n.T = activeTransition;
|
|
749
|
-
activeTransition.
|
|
758
|
+
activeTransition.M.push(n);
|
|
750
759
|
}
|
|
751
|
-
for (let e = 0; e < t.
|
|
752
|
-
const n = t.
|
|
760
|
+
for (let e = 0; e < t.v.length; e++) {
|
|
761
|
+
const n = t.v[e];
|
|
753
762
|
n.T = activeTransition;
|
|
754
|
-
activeTransition.
|
|
763
|
+
activeTransition.v.push(n);
|
|
755
764
|
}
|
|
756
|
-
if (t.
|
|
757
|
-
for (const e of t.
|
|
765
|
+
if (t.G.length) activeTransition.G.push(...t.G);
|
|
766
|
+
for (const e of t.L) activeTransition.L.add(e);
|
|
758
767
|
currentBatch = this.D = activeTransition;
|
|
759
768
|
}
|
|
760
769
|
for (const e of activeLanes) {
|
|
@@ -764,7 +773,7 @@ class GlobalQueue extends Queue {
|
|
|
764
773
|
}
|
|
765
774
|
|
|
766
775
|
function queuePendingNode(e) {
|
|
767
|
-
currentBatch.
|
|
776
|
+
currentBatch.M.push(e);
|
|
768
777
|
}
|
|
769
778
|
|
|
770
779
|
// Sticky: flips true on the first refresh() ever (the only setter of
|
|
@@ -780,25 +789,25 @@ function insertSubs(e, t = false) {
|
|
|
780
789
|
// Get source lane: prefer node's own lane over current context
|
|
781
790
|
// This is important for isPending signals which need their own lane to flush immediately
|
|
782
791
|
const n = e.i || currentOptimisticLane;
|
|
783
|
-
const r = e.
|
|
792
|
+
const r = e.ve !== undefined;
|
|
784
793
|
const i = reaskArmed;
|
|
785
|
-
for (let o = e.
|
|
794
|
+
for (let o = e.U; o !== null; o = o.we) {
|
|
786
795
|
// A value-change notification is a new question for the subscriber: any
|
|
787
796
|
// pending re-ask mark (refresh) it carried is superseded.
|
|
788
|
-
if (i) o.
|
|
789
|
-
if (r && o.Ue
|
|
790
|
-
o.
|
|
797
|
+
if (i) o.Le.Ge &= ~REACTIVE_REASK;
|
|
798
|
+
if (r && o.Le.Ue & CONFIG_IN_SNAPSHOT_SCOPE) {
|
|
799
|
+
o.Le.Ge |= REACTIVE_SNAPSHOT_STALE;
|
|
791
800
|
continue;
|
|
792
801
|
}
|
|
793
802
|
if (t && n) {
|
|
794
|
-
o.
|
|
795
|
-
assignOrMergeLane(o.
|
|
803
|
+
o.Le.Ge |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
804
|
+
assignOrMergeLane(o.Le, n);
|
|
796
805
|
} else if (t) {
|
|
797
|
-
o.
|
|
806
|
+
o.Le.Ge |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
798
807
|
// No source lane means reversion - clear subscriber's lane so effects go to regular queue
|
|
799
|
-
o.
|
|
808
|
+
o.Le.i = undefined;
|
|
800
809
|
}
|
|
801
|
-
enqueueSub(o.
|
|
810
|
+
enqueueSub(o.Le);
|
|
802
811
|
}
|
|
803
812
|
}
|
|
804
813
|
|
|
@@ -806,26 +815,26 @@ function commitPendingNode(e) {
|
|
|
806
815
|
const t = e;
|
|
807
816
|
if (!t.Ve) {
|
|
808
817
|
if (e.V !== NOT_PENDING) {
|
|
809
|
-
e.
|
|
818
|
+
e.ke = e.V;
|
|
810
819
|
e.V = NOT_PENDING;
|
|
811
820
|
}
|
|
812
|
-
if (e.
|
|
821
|
+
if (e.O || e.p) GlobalQueue.ae(e);
|
|
813
822
|
return;
|
|
814
823
|
}
|
|
815
824
|
if (e.V !== NOT_PENDING) {
|
|
816
|
-
e.
|
|
825
|
+
e.ke = e.V;
|
|
817
826
|
e.V = NOT_PENDING;
|
|
818
827
|
// Set _modified for effects, but not for tracked effects (they handle their own scheduling)
|
|
819
|
-
if (e.
|
|
828
|
+
if (e.Fe && e.Fe !== EFFECT_TRACKED) e.xe = true;
|
|
820
829
|
}
|
|
821
|
-
t.
|
|
822
|
-
if (!(t.
|
|
823
|
-
if (t.
|
|
824
|
-
if (e.
|
|
830
|
+
t.Ge &= ~REACTIVE_MANUAL_WRITE;
|
|
831
|
+
if (!(t.Qe & STATUS_PENDING)) t.Qe &= ~STATUS_UNINITIALIZED;
|
|
832
|
+
if (t.We !== null || t.Me !== null) GlobalQueue.X(t, false, true);
|
|
833
|
+
if (e.O || e.p) GlobalQueue.ae(e);
|
|
825
834
|
}
|
|
826
835
|
|
|
827
836
|
function commitPendingNodes() {
|
|
828
|
-
const e = currentBatch.
|
|
837
|
+
const e = currentBatch.M;
|
|
829
838
|
for (let t = 0; t < e.length; t++) {
|
|
830
839
|
commitPendingNode(e[t]);
|
|
831
840
|
}
|
|
@@ -838,23 +847,23 @@ function finalizePureQueue(e = null, t = false) {
|
|
|
838
847
|
const n = !t;
|
|
839
848
|
if (n) commitPendingNodes();
|
|
840
849
|
if (!t && globalQueue.m.length) checkBoundaryChildren(globalQueue);
|
|
841
|
-
const r = dirtyQueue.
|
|
842
|
-
if (r) runHeap(dirtyQueue, GlobalQueue.
|
|
850
|
+
const r = dirtyQueue.C >= dirtyQueue.P;
|
|
851
|
+
if (r) runHeap(dirtyQueue, GlobalQueue.Z);
|
|
843
852
|
if (n) {
|
|
844
853
|
if (r) commitPendingNodes();
|
|
845
854
|
// The settling batch: the completing transaction's, or the ambient one.
|
|
846
855
|
const t = e ?? globalQueue.D;
|
|
847
856
|
// Optimistic reversion: a non-empty batch means _optimisticWrite ran,
|
|
848
857
|
// which installed the engine's hooks.
|
|
849
|
-
if (t.
|
|
858
|
+
if (t.v.length) GlobalQueue.pe(t.v);
|
|
850
859
|
// Replay entanglement: subs recorded by the read-time gate get rescheduled
|
|
851
860
|
// so they re-run with the now-committed values visible.
|
|
852
|
-
if (e && e.
|
|
853
|
-
for (const t of e.
|
|
854
|
-
if (t.
|
|
861
|
+
if (e && e.Y.size) {
|
|
862
|
+
for (const t of e.Y) {
|
|
863
|
+
if (t.Ge & REACTIVE_DISPOSED) continue;
|
|
855
864
|
enqueueSub(t);
|
|
856
865
|
}
|
|
857
|
-
e.
|
|
866
|
+
e.Y.clear();
|
|
858
867
|
}
|
|
859
868
|
// Declared motion ends with the transaction: settle (or plain flush end
|
|
860
869
|
// for ambient marks) releases each registration's refcount. A non-empty
|
|
@@ -862,24 +871,24 @@ function finalizePureQueue(e = null, t = false) {
|
|
|
862
871
|
// held boundary display state through the visual channel, and their
|
|
863
872
|
// release is the display-state update point — re-run the boundary sweep
|
|
864
873
|
// (the earlier sweep above ran while the marks were still live).
|
|
865
|
-
if (t.
|
|
866
|
-
GlobalQueue.
|
|
874
|
+
if (t.G.length) {
|
|
875
|
+
GlobalQueue.ne(t.G);
|
|
867
876
|
if (globalQueue.m.length) checkBoundaryChildren(globalQueue);
|
|
868
877
|
}
|
|
869
878
|
// A non-empty set means trackOptimisticStore ran, which installed the
|
|
870
879
|
// hook; the hook iterates, clears, and schedules (keeping the loop out of
|
|
871
880
|
// core lets esbuild shake it — rollup already folds the null guard). The
|
|
872
881
|
// completing transition scopes the clear to its own layer keys (#2899).
|
|
873
|
-
if (t.
|
|
882
|
+
if (t.L.size) GlobalQueue.ee(t.L, e);
|
|
874
883
|
sweepTransientStoreNodes();
|
|
875
884
|
// Lanes only enter activeLanes through the engine's getOrCreateLane.
|
|
876
|
-
if (activeLanes.size) GlobalQueue.
|
|
885
|
+
if (activeLanes.size) GlobalQueue.Ie(e);
|
|
877
886
|
}
|
|
878
887
|
}
|
|
879
888
|
|
|
880
889
|
function checkBoundaryChildren(e) {
|
|
881
890
|
for (const t of e.m) {
|
|
882
|
-
t.
|
|
891
|
+
t.He?.();
|
|
883
892
|
checkBoundaryChildren(t);
|
|
884
893
|
}
|
|
885
894
|
}
|
|
@@ -930,7 +939,7 @@ function flush(e) {
|
|
|
930
939
|
}
|
|
931
940
|
}
|
|
932
941
|
}
|
|
933
|
-
if (globalQueue.
|
|
942
|
+
if (globalQueue.q) {
|
|
934
943
|
return;
|
|
935
944
|
}
|
|
936
945
|
if (halted) return;
|
|
@@ -946,23 +955,23 @@ function runQueue$1(e, t) {
|
|
|
946
955
|
}
|
|
947
956
|
|
|
948
957
|
function reporterBlocksSource(e, t) {
|
|
949
|
-
if (e.
|
|
958
|
+
if (e.Ge & (REACTIVE_ZOMBIE | REACTIVE_DISPOSED)) return false;
|
|
950
959
|
if (e.$e?.has(t)) return true;
|
|
951
|
-
for (let n = e.
|
|
952
|
-
let e = n.
|
|
960
|
+
for (let n = e.je; n; n = n.Ke) {
|
|
961
|
+
let e = n.Ye;
|
|
953
962
|
while (e) {
|
|
954
|
-
if (e === t || e.
|
|
963
|
+
if (e === t || e.qe === t) return true;
|
|
955
964
|
e = e.t;
|
|
956
965
|
}
|
|
957
966
|
}
|
|
958
|
-
return !!(e.
|
|
967
|
+
return !!(e.Qe & STATUS_PENDING && e.De instanceof NotReadyError && e.De.source === t);
|
|
959
968
|
}
|
|
960
969
|
|
|
961
970
|
function transitionComplete(e) {
|
|
962
971
|
if (e.I) return true;
|
|
963
972
|
if (e.$.length) return false;
|
|
964
973
|
let t = true;
|
|
965
|
-
for (const [n, r] of e.
|
|
974
|
+
for (const [n, r] of e.H) {
|
|
966
975
|
let i = false;
|
|
967
976
|
for (const e of r) {
|
|
968
977
|
if (reporterBlocksSource(e, n)) {
|
|
@@ -971,7 +980,7 @@ function transitionComplete(e) {
|
|
|
971
980
|
}
|
|
972
981
|
r.delete(e);
|
|
973
982
|
}
|
|
974
|
-
if (!i) e.
|
|
983
|
+
if (!i) e.H.delete(n); else if (n.Qe & STATUS_PENDING && n.De?.source === n) {
|
|
975
984
|
t = false;
|
|
976
985
|
break;
|
|
977
986
|
}
|
|
@@ -979,7 +988,7 @@ function transitionComplete(e) {
|
|
|
979
988
|
// Override blockage lives with the engine. Absent hook = "no optimistic
|
|
980
989
|
// blockage", which is exact: only _optimisticWrite (engine) pushes to
|
|
981
990
|
// _optimisticNodes, so without the engine the loop was vacuous anyway.
|
|
982
|
-
if (t && e.
|
|
991
|
+
if (t && e.v.length && GlobalQueue.Re(e)) t = false;
|
|
983
992
|
t && (e.I = true);
|
|
984
993
|
return t;
|
|
985
994
|
}
|
|
@@ -1004,7 +1013,7 @@ function runInTransition(e, t) {
|
|
|
1004
1013
|
}
|
|
1005
1014
|
|
|
1006
1015
|
/** The queue a node belongs to, picked from its own zombie flag. */ function queueFor(e) {
|
|
1007
|
-
return e.
|
|
1016
|
+
return e.Ge & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
|
|
1008
1017
|
}
|
|
1009
1018
|
|
|
1010
1019
|
/**
|
|
@@ -1012,40 +1021,40 @@ function runInTransition(e, t) {
|
|
|
1012
1021
|
* the heap and go directly to their effect queue; everything else is inserted
|
|
1013
1022
|
* into its own (zombie-flag-routed) heap with the `_min` cursor pulled down.
|
|
1014
1023
|
*/ function enqueueSub(e) {
|
|
1015
|
-
if (e.
|
|
1024
|
+
if (e.Fe === EFFECT_TRACKED) {
|
|
1016
1025
|
const t = e;
|
|
1017
|
-
if (!t.
|
|
1018
|
-
t.
|
|
1019
|
-
t.
|
|
1026
|
+
if (!t.xe) {
|
|
1027
|
+
t.xe = true;
|
|
1028
|
+
t.Be.enqueue(EFFECT_USER, t.Ze);
|
|
1020
1029
|
}
|
|
1021
1030
|
return;
|
|
1022
1031
|
}
|
|
1023
1032
|
const t = queueFor(e);
|
|
1024
|
-
if (t.
|
|
1033
|
+
if (t.P > e.Xe) t.P = e.Xe;
|
|
1025
1034
|
insertIntoHeap(e, t);
|
|
1026
1035
|
}
|
|
1027
1036
|
|
|
1028
1037
|
function actualInsertIntoHeap(e, t) {
|
|
1029
|
-
const n = (e.
|
|
1030
|
-
if (n >= e.
|
|
1031
|
-
const r = e.
|
|
1038
|
+
const n = (e.B?.ze ? e.B.Je?.Xe : e.B?.Xe) ?? -1;
|
|
1039
|
+
if (n >= e.Xe) e.Xe = n + 1;
|
|
1040
|
+
const r = e.Xe;
|
|
1032
1041
|
const i = t.h[r];
|
|
1033
1042
|
if (i === undefined) t.h[r] = e; else {
|
|
1034
|
-
const t = i.
|
|
1035
|
-
t.
|
|
1036
|
-
e.
|
|
1037
|
-
i.
|
|
1043
|
+
const t = i.et;
|
|
1044
|
+
t.tt = e;
|
|
1045
|
+
e.et = t;
|
|
1046
|
+
i.et = e;
|
|
1038
1047
|
}
|
|
1039
|
-
if (r > t.
|
|
1048
|
+
if (r > t.C) t.C = r;
|
|
1040
1049
|
}
|
|
1041
1050
|
|
|
1042
1051
|
function insertIntoHeap(e, t) {
|
|
1043
|
-
let n = e.
|
|
1052
|
+
let n = e.Ge;
|
|
1044
1053
|
if (n & (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_MANUAL_WRITE)) return;
|
|
1045
1054
|
if (n & REACTIVE_CHECK) {
|
|
1046
|
-
e.
|
|
1055
|
+
e.Ge = n & -4 | REACTIVE_DIRTY | REACTIVE_IN_HEAP;
|
|
1047
1056
|
} else {
|
|
1048
|
-
e.
|
|
1057
|
+
e.Ge = n | REACTIVE_IN_HEAP;
|
|
1049
1058
|
// An unmarked node entering a marked heap invalidates the markHeap memo:
|
|
1050
1059
|
// `_marked` is only reset by runHeap, so a write between two mid-tick
|
|
1051
1060
|
// pulls (read-time markHeap + updateIfNecessary) would otherwise leave
|
|
@@ -1057,49 +1066,49 @@ function insertIntoHeap(e, t) {
|
|
|
1057
1066
|
}
|
|
1058
1067
|
|
|
1059
1068
|
function insertIntoHeapHeight(e, t) {
|
|
1060
|
-
let n = e.
|
|
1069
|
+
let n = e.Ge;
|
|
1061
1070
|
if (n & (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_IN_HEAP_HEIGHT | REACTIVE_MANUAL_WRITE)) return;
|
|
1062
|
-
e.
|
|
1071
|
+
e.Ge = n | REACTIVE_IN_HEAP_HEIGHT;
|
|
1063
1072
|
actualInsertIntoHeap(e, t);
|
|
1064
1073
|
}
|
|
1065
1074
|
|
|
1066
1075
|
function deleteFromHeap(e, t) {
|
|
1067
|
-
const n = e.
|
|
1076
|
+
const n = e.Ge;
|
|
1068
1077
|
if (!(n & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
|
|
1069
|
-
e.
|
|
1070
|
-
const r = e.
|
|
1071
|
-
if (e.
|
|
1072
|
-
const n = e.
|
|
1078
|
+
e.Ge = n & -25;
|
|
1079
|
+
const r = e.Xe;
|
|
1080
|
+
if (e.et === e) t.h[r] = undefined; else {
|
|
1081
|
+
const n = e.tt;
|
|
1073
1082
|
const i = t.h[r];
|
|
1074
1083
|
const o = n ?? i;
|
|
1075
|
-
if (e === i) t.h[r] = n; else e.tt
|
|
1076
|
-
o.
|
|
1084
|
+
if (e === i) t.h[r] = n; else e.et.tt = n;
|
|
1085
|
+
o.et = e.et;
|
|
1077
1086
|
}
|
|
1078
|
-
e.
|
|
1079
|
-
e.
|
|
1087
|
+
e.et = e;
|
|
1088
|
+
e.tt = undefined;
|
|
1080
1089
|
}
|
|
1081
1090
|
|
|
1082
1091
|
function markHeap(e) {
|
|
1083
1092
|
if (e.N) return;
|
|
1084
1093
|
e.N = true;
|
|
1085
|
-
for (let t = 0; t <= e.
|
|
1086
|
-
for (let n = e.h[t]; n !== undefined; n = n.
|
|
1087
|
-
if (n.
|
|
1094
|
+
for (let t = 0; t <= e.C; t++) {
|
|
1095
|
+
for (let n = e.h[t]; n !== undefined; n = n.tt) {
|
|
1096
|
+
if (n.Ge & REACTIVE_IN_HEAP) markNode(n);
|
|
1088
1097
|
}
|
|
1089
1098
|
}
|
|
1090
1099
|
}
|
|
1091
1100
|
|
|
1092
1101
|
function markNode(e, t = REACTIVE_DIRTY) {
|
|
1093
|
-
const n = e.
|
|
1102
|
+
const n = e.Ge;
|
|
1094
1103
|
if ((n & (REACTIVE_CHECK | REACTIVE_DIRTY)) >= t) return;
|
|
1095
|
-
e.
|
|
1096
|
-
for (let t = e.
|
|
1097
|
-
markNode(t.
|
|
1098
|
-
}
|
|
1099
|
-
if (e.
|
|
1100
|
-
for (let t = e.
|
|
1101
|
-
for (let e = t.
|
|
1102
|
-
markNode(e.
|
|
1104
|
+
e.Ge = n & -4 | t;
|
|
1105
|
+
for (let t = e.U; t !== null; t = t.we) {
|
|
1106
|
+
markNode(t.Le, REACTIVE_CHECK);
|
|
1107
|
+
}
|
|
1108
|
+
if (e.nt !== null) {
|
|
1109
|
+
for (let t = e.nt; t !== null; t = t.rt) {
|
|
1110
|
+
for (let e = t.U; e !== null; e = e.we) {
|
|
1111
|
+
markNode(e.Le, REACTIVE_CHECK);
|
|
1103
1112
|
}
|
|
1104
1113
|
}
|
|
1105
1114
|
}
|
|
@@ -1107,33 +1116,33 @@ function markNode(e, t = REACTIVE_DIRTY) {
|
|
|
1107
1116
|
|
|
1108
1117
|
function runHeap(e, t) {
|
|
1109
1118
|
e.N = false;
|
|
1110
|
-
for (e.
|
|
1111
|
-
let n = e.h[e.
|
|
1119
|
+
for (e.P = 0; e.P <= e.C; e.P++) {
|
|
1120
|
+
let n = e.h[e.P];
|
|
1112
1121
|
while (n !== undefined) {
|
|
1113
|
-
if (n.
|
|
1114
|
-
n = e.h[e.
|
|
1122
|
+
if (n.Ge & REACTIVE_IN_HEAP) t(n); else adjustHeight(n, e);
|
|
1123
|
+
n = e.h[e.P];
|
|
1115
1124
|
}
|
|
1116
1125
|
}
|
|
1117
|
-
e.
|
|
1126
|
+
e.C = 0;
|
|
1118
1127
|
}
|
|
1119
1128
|
|
|
1120
1129
|
function adjustHeight(e, t) {
|
|
1121
1130
|
deleteFromHeap(e, t);
|
|
1122
|
-
let n = e.
|
|
1123
|
-
for (let t = e.
|
|
1124
|
-
const e = t.
|
|
1125
|
-
const r = e.
|
|
1126
|
-
if (r.Ve && r.
|
|
1127
|
-
}
|
|
1128
|
-
if (e.
|
|
1129
|
-
e.
|
|
1130
|
-
for (let t = e.
|
|
1131
|
+
let n = e.Xe;
|
|
1132
|
+
for (let t = e.je; t; t = t.Ke) {
|
|
1133
|
+
const e = t.Ye;
|
|
1134
|
+
const r = e.qe || e;
|
|
1135
|
+
if (r.Ve && r.Xe >= n) n = r.Xe + 1;
|
|
1136
|
+
}
|
|
1137
|
+
if (e.Xe !== n) {
|
|
1138
|
+
e.Xe = n;
|
|
1139
|
+
for (let t = e.U; t !== null; t = t.we) {
|
|
1131
1140
|
// Route each subscriber by its own zombie flag, mirroring the
|
|
1132
1141
|
// post-recompute height-adjust path. Inserting into the running `heap`
|
|
1133
1142
|
// unconditionally can park a zombie in `dirtyQueue` (or a live node in
|
|
1134
1143
|
// `zombieQueue`), breaking the flag/queue invariant `deleteFromHeap`
|
|
1135
1144
|
// relies on — the same corruption class as #2759.
|
|
1136
|
-
insertIntoHeapHeight(t.
|
|
1145
|
+
insertIntoHeapHeight(t.Le, queueFor(t.Le));
|
|
1137
1146
|
}
|
|
1138
1147
|
}
|
|
1139
1148
|
}
|
|
@@ -1142,10 +1151,10 @@ const PENDING_OWNER = {};
|
|
|
1142
1151
|
|
|
1143
1152
|
// Dummy owner to trigger store's read() path
|
|
1144
1153
|
function markDisposal(e) {
|
|
1145
|
-
let t = e.
|
|
1154
|
+
let t = e.it;
|
|
1146
1155
|
while (t) {
|
|
1147
|
-
const e = t.
|
|
1148
|
-
t.
|
|
1156
|
+
const e = t.Ge;
|
|
1157
|
+
t.Ge = e | REACTIVE_ZOMBIE;
|
|
1149
1158
|
// migrate height-adjust entries too, not just recompute entries: every
|
|
1150
1159
|
// `deleteFromHeap` call site picks the queue from the zombie flag, so a
|
|
1151
1160
|
// node left physically linked in `dirtyQueue` after being zombified gets
|
|
@@ -1156,79 +1165,79 @@ function markDisposal(e) {
|
|
|
1156
1165
|
if (e & REACTIVE_IN_HEAP) insertIntoHeap(t, zombieQueue); else insertIntoHeapHeight(t, zombieQueue);
|
|
1157
1166
|
}
|
|
1158
1167
|
markDisposal(t);
|
|
1159
|
-
t = t.
|
|
1168
|
+
t = t.ot;
|
|
1160
1169
|
}
|
|
1161
1170
|
}
|
|
1162
1171
|
|
|
1163
1172
|
function dispose(e) {
|
|
1164
|
-
let t = e.
|
|
1173
|
+
let t = e.je;
|
|
1165
1174
|
while (t !== null) {
|
|
1166
1175
|
t = unlinkSubs(t);
|
|
1167
1176
|
}
|
|
1168
|
-
e.
|
|
1169
|
-
e.
|
|
1177
|
+
e.je = null;
|
|
1178
|
+
e.st = null;
|
|
1170
1179
|
disposeChildren(e, true);
|
|
1171
1180
|
}
|
|
1172
1181
|
|
|
1173
1182
|
function disposeChildren(e, t = false, n) {
|
|
1174
|
-
const r = e.
|
|
1183
|
+
const r = e.Ge;
|
|
1175
1184
|
if (r & REACTIVE_DISPOSED) return;
|
|
1176
1185
|
if (t) {
|
|
1177
|
-
e.
|
|
1186
|
+
e.Ge = r | REACTIVE_DISPOSED;
|
|
1178
1187
|
// Companions are created detached and outlive their owner, but a verdict
|
|
1179
1188
|
// must not: a disposed source can never settle, so an isPending companion
|
|
1180
1189
|
// latched `true` here would hold a spinner forever (INV-9, the PR #2845
|
|
1181
1190
|
// edge). Snap runs after the DISPOSED flag is set so the oracle reads
|
|
1182
1191
|
// false, and notifies subscribers still watching the companion.
|
|
1183
1192
|
const t = e;
|
|
1184
|
-
if (t.
|
|
1193
|
+
if (t.O || t.p) GlobalQueue.ae(t);
|
|
1185
1194
|
}
|
|
1186
|
-
if (t && e.Ve) e.
|
|
1187
|
-
let i = n ? e.
|
|
1195
|
+
if (t && e.Ve) e.ut = null;
|
|
1196
|
+
let i = n ? e.We : e.it;
|
|
1188
1197
|
while (i) {
|
|
1189
|
-
const e = i.
|
|
1190
|
-
if (i.
|
|
1198
|
+
const e = i.ot;
|
|
1199
|
+
if (i.je) {
|
|
1191
1200
|
const e = i;
|
|
1192
1201
|
deleteFromHeap(e, queueFor(e));
|
|
1193
|
-
let t = e.
|
|
1202
|
+
let t = e.je;
|
|
1194
1203
|
do {
|
|
1195
1204
|
t = unlinkSubs(t);
|
|
1196
1205
|
} while (t !== null);
|
|
1197
|
-
e.
|
|
1198
|
-
e.
|
|
1206
|
+
e.je = null;
|
|
1207
|
+
e.st = null;
|
|
1199
1208
|
}
|
|
1200
1209
|
disposeChildren(i, true);
|
|
1201
1210
|
i = e;
|
|
1202
1211
|
}
|
|
1203
1212
|
if (n) {
|
|
1204
|
-
e.
|
|
1213
|
+
e.We = null;
|
|
1205
1214
|
} else {
|
|
1206
|
-
e.
|
|
1207
|
-
e.
|
|
1215
|
+
e.it = null;
|
|
1216
|
+
e.lt = 0;
|
|
1208
1217
|
}
|
|
1209
1218
|
// O(1) splice out of parent's chain on individual dispose. Skipped during
|
|
1210
1219
|
// batch dispose (parent already disposed) and zombie disposal (node sits on
|
|
1211
1220
|
// parent's _pendingFirstChild). We leave node._nextSibling intact so outer
|
|
1212
1221
|
// walks that already advanced past us still reach later siblings.
|
|
1213
|
-
if (t && !n && !(r & REACTIVE_ZOMBIE) && e.
|
|
1214
|
-
const t = e.
|
|
1215
|
-
const n = e.
|
|
1216
|
-
if (t !== null) t.
|
|
1217
|
-
if (n !== null) n.
|
|
1218
|
-
e.
|
|
1222
|
+
if (t && !n && !(r & REACTIVE_ZOMBIE) && e.B !== null && !(e.B.Ge & REACTIVE_DISPOSED)) {
|
|
1223
|
+
const t = e.ct;
|
|
1224
|
+
const n = e.ot;
|
|
1225
|
+
if (t !== null) t.ot = n; else e.B.it = n;
|
|
1226
|
+
if (n !== null) n.ct = t;
|
|
1227
|
+
e.ct = null;
|
|
1219
1228
|
}
|
|
1220
1229
|
runDisposal(e, n);
|
|
1221
1230
|
// Final effect-returned cleanup fires at true disposal, after `_disposal`
|
|
1222
1231
|
// to mirror rerun ordering (compute-phase teardown first, cleanup last).
|
|
1223
|
-
if (t && e.
|
|
1224
|
-
const t = e.
|
|
1225
|
-
e.
|
|
1232
|
+
if (t && e.ft) {
|
|
1233
|
+
const t = e.ft;
|
|
1234
|
+
e.ft = undefined;
|
|
1226
1235
|
t();
|
|
1227
1236
|
}
|
|
1228
1237
|
}
|
|
1229
1238
|
|
|
1230
1239
|
function runDisposal(e, t) {
|
|
1231
|
-
let n = t ? e.
|
|
1240
|
+
let n = t ? e.Me : e.Et;
|
|
1232
1241
|
if (!n) return;
|
|
1233
1242
|
if (Array.isArray(n)) {
|
|
1234
1243
|
for (let e = 0; e < n.length; e++) {
|
|
@@ -1238,13 +1247,13 @@ function runDisposal(e, t) {
|
|
|
1238
1247
|
} else {
|
|
1239
1248
|
n.call(n);
|
|
1240
1249
|
}
|
|
1241
|
-
t ? e.
|
|
1250
|
+
t ? e.Me = null : e.Et = null;
|
|
1242
1251
|
}
|
|
1243
1252
|
|
|
1244
1253
|
function childId(e, t) {
|
|
1245
1254
|
let n = e;
|
|
1246
|
-
while (n.
|
|
1247
|
-
if (n.id != null) return formatId(n.id, t ? n.
|
|
1255
|
+
while (n.Ue & CONFIG_TRANSPARENT && n.B) n = n.B;
|
|
1256
|
+
if (n.id != null) return formatId(n.id, t ? n.lt++ : n.lt);
|
|
1248
1257
|
throw new Error("");
|
|
1249
1258
|
}
|
|
1250
1259
|
|
|
@@ -1325,7 +1334,7 @@ function formatId(e, t) {
|
|
|
1325
1334
|
* checks. `cleanup()` is the unchecked primitive used by internals.
|
|
1326
1335
|
*/ function cleanup(e) {
|
|
1327
1336
|
if (!context) return e;
|
|
1328
|
-
if (!context.
|
|
1337
|
+
if (!context.Et) context.Et = e; else if (Array.isArray(context.Et)) context.Et.push(e); else context.Et = [ context.Et, e ];
|
|
1329
1338
|
return e;
|
|
1330
1339
|
}
|
|
1331
1340
|
|
|
@@ -1345,7 +1354,7 @@ function formatId(e, t) {
|
|
|
1345
1354
|
* }
|
|
1346
1355
|
* ```
|
|
1347
1356
|
*/ function isDisposed(e) {
|
|
1348
|
-
return !!(e.
|
|
1357
|
+
return !!(e.Ge & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
|
|
1349
1358
|
}
|
|
1350
1359
|
|
|
1351
1360
|
function disposeRootSelf(e = true) {
|
|
@@ -1364,29 +1373,29 @@ function disposeRootSelf(e = true) {
|
|
|
1364
1373
|
const n = e?.transparent ?? false;
|
|
1365
1374
|
const r = {
|
|
1366
1375
|
id: inheritId(e, n, t),
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1376
|
+
Ue: n ? CONFIG_TRANSPARENT : 0,
|
|
1377
|
+
ze: true,
|
|
1378
|
+
Je: t?.ze ? t.Je : t,
|
|
1379
|
+
it: null,
|
|
1370
1380
|
ot: null,
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
Ze: t?.Ze ?? globalQueue,
|
|
1381
|
+
ct: null,
|
|
1382
|
+
Et: null,
|
|
1383
|
+
Be: t?.Be ?? globalQueue,
|
|
1375
1384
|
dt: t?.dt || defaultContext,
|
|
1376
|
-
|
|
1377
|
-
He: null,
|
|
1385
|
+
lt: 0,
|
|
1378
1386
|
Me: null,
|
|
1379
|
-
|
|
1387
|
+
We: null,
|
|
1388
|
+
B: t,
|
|
1380
1389
|
dispose: disposeRootSelf
|
|
1381
1390
|
};
|
|
1382
1391
|
if (t) {
|
|
1383
|
-
const e = t.
|
|
1392
|
+
const e = t.it;
|
|
1384
1393
|
if (e === null) {
|
|
1385
|
-
t.
|
|
1394
|
+
t.it = r;
|
|
1386
1395
|
} else {
|
|
1387
|
-
r.
|
|
1388
|
-
e.
|
|
1389
|
-
t.
|
|
1396
|
+
r.ot = e;
|
|
1397
|
+
e.ct = r;
|
|
1398
|
+
t.it = r;
|
|
1390
1399
|
}
|
|
1391
1400
|
}
|
|
1392
1401
|
return r;
|
|
@@ -1422,42 +1431,47 @@ function disposeRootSelf(e = true) {
|
|
|
1422
1431
|
|
|
1423
1432
|
// https://github.com/stackblitz/alien-signals/blob/v2.0.3/src/system.ts#L100
|
|
1424
1433
|
function unlinkSubs(e) {
|
|
1425
|
-
const t = e.
|
|
1426
|
-
const n = e.
|
|
1427
|
-
const r = e.
|
|
1428
|
-
const i = e.
|
|
1429
|
-
if (r !== null) r.
|
|
1430
|
-
if (i !== null) i.
|
|
1431
|
-
t.
|
|
1434
|
+
const t = e.Ye;
|
|
1435
|
+
const n = e.Ke;
|
|
1436
|
+
const r = e.we;
|
|
1437
|
+
const i = e.St;
|
|
1438
|
+
if (r !== null) r.St = i; else t.Tt = i;
|
|
1439
|
+
if (i !== null) i.we = r; else {
|
|
1440
|
+
t.U = r;
|
|
1432
1441
|
if (r === null) {
|
|
1433
|
-
t.
|
|
1442
|
+
t.F?.();
|
|
1434
1443
|
// No more subscribers; only tear down if CONFIG_AUTO_DISPOSE is set.
|
|
1444
|
+
// A pending node is exempt: its in-flight async work (or the
|
|
1445
|
+
// transition holding it) is an observer — tearing down would orphan
|
|
1446
|
+
// the work and re-execute it on the next read. The settle path runs
|
|
1447
|
+
// this same last-one-out check when that observer releases (the
|
|
1448
|
+
// untracked-read dispose in core.ts guards on pending identically).
|
|
1435
1449
|
const e = t;
|
|
1436
|
-
e.Ve && e.
|
|
1450
|
+
e.Ve && e.Ue & CONFIG_AUTO_DISPOSE && !(e.Ge & REACTIVE_ZOMBIE) && !(e.Qe & STATUS_PENDING) && unobserved(e);
|
|
1437
1451
|
}
|
|
1438
1452
|
}
|
|
1439
1453
|
return n;
|
|
1440
1454
|
}
|
|
1441
1455
|
|
|
1442
1456
|
function trimStaleDeps(e) {
|
|
1443
|
-
const t = e.
|
|
1444
|
-
let n = t !== null ? t.
|
|
1457
|
+
const t = e.st;
|
|
1458
|
+
let n = t !== null ? t.Ke : e.je;
|
|
1445
1459
|
if (n !== null) {
|
|
1446
1460
|
do {
|
|
1447
1461
|
n = unlinkSubs(n);
|
|
1448
1462
|
} while (n !== null);
|
|
1449
|
-
if (t !== null) t.
|
|
1463
|
+
if (t !== null) t.Ke = null; else e.je = null;
|
|
1450
1464
|
}
|
|
1451
1465
|
}
|
|
1452
1466
|
|
|
1453
1467
|
function unobserved(e) {
|
|
1454
1468
|
deleteFromHeap(e, queueFor(e));
|
|
1455
|
-
let t = e.
|
|
1469
|
+
let t = e.je;
|
|
1456
1470
|
while (t !== null) {
|
|
1457
1471
|
t = unlinkSubs(t);
|
|
1458
1472
|
}
|
|
1459
|
-
e.
|
|
1460
|
-
e.
|
|
1473
|
+
e.je = null;
|
|
1474
|
+
e.st = null;
|
|
1461
1475
|
disposeChildren(e, true);
|
|
1462
1476
|
}
|
|
1463
1477
|
|
|
@@ -1468,20 +1482,20 @@ function link(e, t, n = false) {
|
|
|
1468
1482
|
// not relabel the value dependency as probe-only — the value read is what
|
|
1469
1483
|
// real-error propagation and affects() coverage key off, regardless of
|
|
1470
1484
|
// read order within the computation.
|
|
1471
|
-
const r = t.
|
|
1472
|
-
if (r !== null && r.
|
|
1473
|
-
r.
|
|
1485
|
+
const r = t.st;
|
|
1486
|
+
if (r !== null && r.Ye === e) {
|
|
1487
|
+
r._t &&= n;
|
|
1474
1488
|
return;
|
|
1475
1489
|
}
|
|
1476
1490
|
let i = null;
|
|
1477
|
-
const o = t.
|
|
1491
|
+
const o = t.Ge & REACTIVE_RECOMPUTING_DEPS;
|
|
1478
1492
|
if (o) {
|
|
1479
|
-
i = r !== null ? r.
|
|
1480
|
-
if (i !== null && i.
|
|
1481
|
-
i.
|
|
1482
|
-
t.
|
|
1493
|
+
i = r !== null ? r.Ke : t.je;
|
|
1494
|
+
if (i !== null && i.Ye === e) {
|
|
1495
|
+
i.Ot = t.Rt;
|
|
1496
|
+
t.st = i;
|
|
1483
1497
|
// First touch of this pass: the previous pass's label is stale.
|
|
1484
|
-
i.
|
|
1498
|
+
i._t = n;
|
|
1485
1499
|
return;
|
|
1486
1500
|
}
|
|
1487
1501
|
}
|
|
@@ -1490,24 +1504,24 @@ function link(e, t, n = false) {
|
|
|
1490
1504
|
// [deps.._depsTail] prefix — the O(1) equivalent of scanning the dep list
|
|
1491
1505
|
// (the old alien-signals `isValidLink` walk, O(n²) when a computation
|
|
1492
1506
|
// re-reads earlier deps non-consecutively, e.g. store leaf reads).
|
|
1493
|
-
const s = e.
|
|
1494
|
-
if (s !== null && s.
|
|
1507
|
+
const s = e.Tt;
|
|
1508
|
+
if (s !== null && s.Le === t && (!o || s.Ot === t.Rt)) {
|
|
1495
1509
|
// Gen-matched during a recompute = repeat touch this pass (AND); outside
|
|
1496
1510
|
// a recompute there is no pass boundary, so the latest read labels it.
|
|
1497
|
-
if (o) s.
|
|
1511
|
+
if (o) s._t &&= n; else s._t = n;
|
|
1498
1512
|
return;
|
|
1499
1513
|
}
|
|
1500
|
-
const u = t.
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1514
|
+
const u = t.st = e.Tt = {
|
|
1515
|
+
Ye: e,
|
|
1516
|
+
Le: t,
|
|
1517
|
+
Ke: i,
|
|
1518
|
+
St: s,
|
|
1519
|
+
we: null,
|
|
1520
|
+
Ot: t.Rt,
|
|
1521
|
+
_t: n
|
|
1508
1522
|
};
|
|
1509
|
-
if (r !== null) r.
|
|
1510
|
-
if (s !== null) s.
|
|
1523
|
+
if (r !== null) r.Ke = u; else t.je = u;
|
|
1524
|
+
if (s !== null) s.we = u; else e.U = u;
|
|
1511
1525
|
}
|
|
1512
1526
|
|
|
1513
1527
|
// The lazily-created Set is the ONE container for pending sources. Its
|
|
@@ -1534,24 +1548,24 @@ function clearPendingSources(e) {
|
|
|
1534
1548
|
|
|
1535
1549
|
function setPendingError(e, t, n) {
|
|
1536
1550
|
if (!t) {
|
|
1537
|
-
e.
|
|
1551
|
+
e.De = null;
|
|
1538
1552
|
return;
|
|
1539
1553
|
}
|
|
1540
1554
|
if (n instanceof NotReadyError && n.source === t) {
|
|
1541
|
-
e.
|
|
1555
|
+
e.De = n;
|
|
1542
1556
|
return;
|
|
1543
1557
|
}
|
|
1544
|
-
const r = e.
|
|
1558
|
+
const r = e.De;
|
|
1545
1559
|
if (!(r instanceof NotReadyError) || r.source !== t) {
|
|
1546
|
-
e.
|
|
1560
|
+
e.De = new NotReadyError(t);
|
|
1547
1561
|
}
|
|
1548
1562
|
}
|
|
1549
1563
|
|
|
1550
1564
|
function forEachDependent(e, t) {
|
|
1551
|
-
for (let n = e.
|
|
1565
|
+
for (let n = e.U; n !== null; n = n.we) t(n.Le, n);
|
|
1552
1566
|
// `?? null`: affects() marks route plain signals (no `_child` slot) through here.
|
|
1553
|
-
for (let n = e.
|
|
1554
|
-
for (let e = n.
|
|
1567
|
+
for (let n = e.nt ?? null; n !== null; n = n.rt) {
|
|
1568
|
+
for (let e = n.U; e !== null; e = e.we) t(e.Le, e);
|
|
1555
1569
|
}
|
|
1556
1570
|
}
|
|
1557
1571
|
|
|
@@ -1562,24 +1576,24 @@ function settlePendingSource(e) {
|
|
|
1562
1576
|
let t = false;
|
|
1563
1577
|
const n = new Set;
|
|
1564
1578
|
// Companion updates no-op without the verdict layer (null hook).
|
|
1565
|
-
const r = GlobalQueue.
|
|
1579
|
+
const r = GlobalQueue.le;
|
|
1566
1580
|
const settle = i => {
|
|
1567
1581
|
if (n.has(i) || !removePendingSource(i, e)) return;
|
|
1568
1582
|
n.add(i);
|
|
1569
|
-
i.
|
|
1583
|
+
i.W = clock;
|
|
1570
1584
|
const o = i.$e?.values().next().value;
|
|
1571
1585
|
if (o) {
|
|
1572
1586
|
setPendingError(i, o);
|
|
1573
1587
|
r !== null && r(i);
|
|
1574
1588
|
} else {
|
|
1575
|
-
i.
|
|
1589
|
+
i.Qe &= ~STATUS_PENDING;
|
|
1576
1590
|
setPendingError(i);
|
|
1577
1591
|
r !== null && r(i);
|
|
1578
|
-
if (i.
|
|
1592
|
+
if (i.It) {
|
|
1579
1593
|
enqueueSub(i);
|
|
1580
1594
|
t = true;
|
|
1581
1595
|
}
|
|
1582
|
-
i.
|
|
1596
|
+
i.It = false;
|
|
1583
1597
|
}
|
|
1584
1598
|
forEachDependent(i, settle);
|
|
1585
1599
|
};
|
|
@@ -1602,26 +1616,26 @@ function handleAsync(e, t, n) {
|
|
|
1602
1616
|
});
|
|
1603
1617
|
}
|
|
1604
1618
|
if (!i && !r) {
|
|
1605
|
-
e.
|
|
1619
|
+
e.ut = null;
|
|
1606
1620
|
return t;
|
|
1607
1621
|
}
|
|
1608
|
-
e.
|
|
1622
|
+
e.ut = t;
|
|
1609
1623
|
let o;
|
|
1610
1624
|
const handleError = n => {
|
|
1611
|
-
if (e.
|
|
1625
|
+
if (e.ut !== t) return;
|
|
1612
1626
|
globalQueue.initTransition(resolveTransition(e));
|
|
1613
1627
|
// NotReadyError from rejected promises should be treated as pending, not error
|
|
1614
1628
|
notifyStatus(e, n instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, n);
|
|
1615
|
-
e.
|
|
1629
|
+
e.W = clock;
|
|
1616
1630
|
};
|
|
1617
1631
|
const asyncWrite = (r, i) => {
|
|
1618
|
-
if (e.
|
|
1632
|
+
if (e.ut !== t) return;
|
|
1619
1633
|
// If the node was dirtied by a newer write (optimistic override or regular),
|
|
1620
1634
|
// skip this stale async result — the upcoming flush will recompute the node
|
|
1621
1635
|
// with the new value, creating a fresh Promise that supersedes this one.
|
|
1622
|
-
if (e.
|
|
1636
|
+
if (e.Ge & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY)) return;
|
|
1623
1637
|
globalQueue.initTransition(resolveTransition(e));
|
|
1624
|
-
const o = !!(e.
|
|
1638
|
+
const o = !!(e.Qe & STATUS_UNINITIALIZED);
|
|
1625
1639
|
trimStaleDeps(e);
|
|
1626
1640
|
clearStatus(e);
|
|
1627
1641
|
const s = resolveLane(e);
|
|
@@ -1648,22 +1662,22 @@ function handleAsync(e, t, n) {
|
|
|
1648
1662
|
// only notified when the hold is visible to them: under an active
|
|
1649
1663
|
// override every reader sees the override (A17), so waking subs would
|
|
1650
1664
|
// re-show an unchanged view — the revert is the notification point.
|
|
1651
|
-
GlobalQueue.
|
|
1665
|
+
GlobalQueue.ue !== null && GlobalQueue.ue(e, r);
|
|
1652
1666
|
if (!hasActiveOverride(e)) insertSubs(e);
|
|
1653
|
-
e.
|
|
1667
|
+
e.W = clock;
|
|
1654
1668
|
} else if (s) {
|
|
1655
1669
|
// Route through lane's effect queue for independent flushing
|
|
1656
|
-
const t = e.
|
|
1657
|
-
const n = e.
|
|
1658
|
-
const i = e.
|
|
1670
|
+
const t = e.Fe;
|
|
1671
|
+
const n = e.ke;
|
|
1672
|
+
const i = e.At;
|
|
1659
1673
|
try {
|
|
1660
1674
|
if (!t && o || !i || !i(r, n)) {
|
|
1661
|
-
e.
|
|
1662
|
-
e.
|
|
1675
|
+
e.ke = r;
|
|
1676
|
+
e.W = clock;
|
|
1663
1677
|
// The latest() shadow write gives latest() effects independent lanes; the
|
|
1664
1678
|
// _pendingSignal update is a no-op repeat of the clearStatus() call above
|
|
1665
1679
|
// (computePendingState doesn't read _value).
|
|
1666
|
-
GlobalQueue.
|
|
1680
|
+
GlobalQueue.ue !== null && GlobalQueue.ue(e, r);
|
|
1667
1681
|
insertSubs(e, true);
|
|
1668
1682
|
}
|
|
1669
1683
|
} catch (t) {
|
|
@@ -1687,18 +1701,34 @@ function handleAsync(e, t, n) {
|
|
|
1687
1701
|
flush();
|
|
1688
1702
|
i?.();
|
|
1689
1703
|
};
|
|
1704
|
+
// A pending node's in-flight promise is an observer: `unlinkSubs` skips
|
|
1705
|
+
// autodispose while STATUS_PENDING so subscriber churn can't orphan the
|
|
1706
|
+
// work (a lazy async memo would otherwise tear down and re-execute — one
|
|
1707
|
+
// fetch per suspended re-read). Settling is that observer's release, so
|
|
1708
|
+
// it runs the same last-one-out check the other release sites run.
|
|
1709
|
+
const settleAutodispose = () => {
|
|
1710
|
+
if (e.Ue & CONFIG_AUTO_DISPOSE && !e.U && !(e.Qe & STATUS_PENDING)) {
|
|
1711
|
+
unobserved(e);
|
|
1712
|
+
}
|
|
1713
|
+
};
|
|
1690
1714
|
if (i) {
|
|
1691
1715
|
let n = false, r = false, i, s = true;
|
|
1692
1716
|
t.then(e => {
|
|
1693
1717
|
if (s) {
|
|
1694
1718
|
o = e;
|
|
1695
1719
|
n = true;
|
|
1696
|
-
} else
|
|
1720
|
+
} else {
|
|
1721
|
+
asyncWrite(e);
|
|
1722
|
+
settleAutodispose();
|
|
1723
|
+
}
|
|
1697
1724
|
}, e => {
|
|
1698
1725
|
if (s) {
|
|
1699
1726
|
i = e;
|
|
1700
1727
|
r = true;
|
|
1701
|
-
} else
|
|
1728
|
+
} else {
|
|
1729
|
+
handleError(e);
|
|
1730
|
+
settleAutodispose();
|
|
1731
|
+
}
|
|
1702
1732
|
});
|
|
1703
1733
|
s = false;
|
|
1704
1734
|
if (r) {
|
|
@@ -1732,7 +1762,7 @@ function handleAsync(e, t, n) {
|
|
|
1732
1762
|
u = n;
|
|
1733
1763
|
c = true;
|
|
1734
1764
|
if (n.done) i = true;
|
|
1735
|
-
} else if (e.
|
|
1765
|
+
} else if (e.ut !== t) {
|
|
1736
1766
|
return;
|
|
1737
1767
|
} else if (!n.done) {
|
|
1738
1768
|
r = true;
|
|
@@ -1751,7 +1781,7 @@ function handleAsync(e, t, n) {
|
|
|
1751
1781
|
if (f) {
|
|
1752
1782
|
l = n;
|
|
1753
1783
|
a = true;
|
|
1754
|
-
} else if (e.
|
|
1784
|
+
} else if (e.ut === t) {
|
|
1755
1785
|
i = true;
|
|
1756
1786
|
handleError(n);
|
|
1757
1787
|
}
|
|
@@ -1784,18 +1814,18 @@ function handleAsync(e, t, n) {
|
|
|
1784
1814
|
|
|
1785
1815
|
function clearStatus(e, t = false) {
|
|
1786
1816
|
if (e.$e) clearPendingSources(e);
|
|
1787
|
-
if (e.
|
|
1817
|
+
if (e.It) e.It = false;
|
|
1788
1818
|
// The pending window is over; its quiet classification dies with it.
|
|
1789
1819
|
// (Unconditional: _reask is baked into the node literals, so this is a
|
|
1790
1820
|
// plain store to an existing slot — no shape change.)
|
|
1791
|
-
e.
|
|
1792
|
-
e.
|
|
1793
|
-
if (e.
|
|
1821
|
+
e.ht = false;
|
|
1822
|
+
e.Qe = t ? 0 : e.Qe & STATUS_UNINITIALIZED;
|
|
1823
|
+
if (e.De) setPendingError(e);
|
|
1794
1824
|
// Update pending signal for isPending() reactivity (companions only exist
|
|
1795
1825
|
// once the verdict layer created them, which installs the hooks).
|
|
1796
|
-
if (e.
|
|
1797
|
-
if (e.
|
|
1798
|
-
if (e.
|
|
1826
|
+
if (e.O || e.p) GlobalQueue.le(e);
|
|
1827
|
+
if (e.nt && GlobalQueue.ce !== null) GlobalQueue.ce(e);
|
|
1828
|
+
if (e.Nt) e.Nt();
|
|
1799
1829
|
}
|
|
1800
1830
|
|
|
1801
1831
|
function notifyStatus(e, t, n, r, i) {
|
|
@@ -1808,43 +1838,43 @@ function notifyStatus(e, t, n, r, i) {
|
|
|
1808
1838
|
if (!r) {
|
|
1809
1839
|
if (t === STATUS_PENDING && o) {
|
|
1810
1840
|
addPendingSource(e, o);
|
|
1811
|
-
e.
|
|
1841
|
+
e.Qe = STATUS_PENDING | e.Qe & STATUS_UNINITIALIZED;
|
|
1812
1842
|
// Preserve the current source on this propagation so render-effect notification
|
|
1813
1843
|
// can register every distinct pending source with the transition.
|
|
1814
1844
|
setPendingError(e, o, n);
|
|
1815
1845
|
} else {
|
|
1816
1846
|
clearPendingSources(e);
|
|
1817
|
-
e.
|
|
1818
|
-
e.
|
|
1847
|
+
e.Qe = t | (t !== STATUS_ERROR ? e.Qe & STATUS_UNINITIALIZED : 0);
|
|
1848
|
+
e.De = n;
|
|
1819
1849
|
}
|
|
1820
|
-
GlobalQueue.
|
|
1821
|
-
if (e.
|
|
1850
|
+
GlobalQueue.le !== null && GlobalQueue.le(e);
|
|
1851
|
+
if (e.nt && GlobalQueue.ce !== null) GlobalQueue.ce(e);
|
|
1822
1852
|
}
|
|
1823
1853
|
if (i && !r) {
|
|
1824
1854
|
assignOrMergeLane(e, i);
|
|
1825
1855
|
}
|
|
1826
1856
|
const c = r || l;
|
|
1827
1857
|
const a = r || u ? undefined : i;
|
|
1828
|
-
if (e.
|
|
1858
|
+
if (e.Nt) {
|
|
1829
1859
|
if (r && t === STATUS_PENDING) {
|
|
1830
1860
|
return;
|
|
1831
1861
|
}
|
|
1832
1862
|
if (c) {
|
|
1833
|
-
e.
|
|
1863
|
+
e.Nt(t, n);
|
|
1834
1864
|
} else {
|
|
1835
|
-
e.
|
|
1865
|
+
e.Nt();
|
|
1836
1866
|
}
|
|
1837
1867
|
return;
|
|
1838
1868
|
}
|
|
1839
1869
|
forEachDependent(e, (e, r) => {
|
|
1840
|
-
e.
|
|
1841
|
-
if (t === STATUS_PENDING && o && !e.$e?.has(o) || t !== STATUS_PENDING && (e.
|
|
1870
|
+
e.W = clock;
|
|
1871
|
+
if (t === STATUS_PENDING && o && !e.$e?.has(o) || t !== STATUS_PENDING && (e.De !== n || e.$e)) {
|
|
1842
1872
|
// A pending-observer link is the subscription an `isPending` read created.
|
|
1843
1873
|
// It exists so the observer re-runs when the source settles, but it must
|
|
1844
1874
|
// not carry a real (non-NotReadyError) error — the synchronous `isPending`
|
|
1845
1875
|
// read swallows those, and the async path must match. Re-run the observer
|
|
1846
1876
|
// so `isPending` re-evaluates (to not-pending) instead of forwarding.
|
|
1847
|
-
if (r.
|
|
1877
|
+
if (r._t && t !== STATUS_PENDING && !(n instanceof NotReadyError)) {
|
|
1848
1878
|
enqueueSub(e);
|
|
1849
1879
|
schedule();
|
|
1850
1880
|
return;
|
|
@@ -1855,9 +1885,9 @@ function notifyStatus(e, t, n, r, i) {
|
|
|
1855
1885
|
});
|
|
1856
1886
|
}
|
|
1857
1887
|
|
|
1858
|
-
GlobalQueue.
|
|
1888
|
+
GlobalQueue.Z = recompute;
|
|
1859
1889
|
|
|
1860
|
-
GlobalQueue.
|
|
1890
|
+
GlobalQueue.X = disposeChildren;
|
|
1861
1891
|
|
|
1862
1892
|
let tracking = false;
|
|
1863
1893
|
|
|
@@ -1889,8 +1919,8 @@ let snapshotSources = null;
|
|
|
1889
1919
|
|
|
1890
1920
|
function ownerInSnapshotScope(e) {
|
|
1891
1921
|
while (e) {
|
|
1892
|
-
if (e.
|
|
1893
|
-
e = e.
|
|
1922
|
+
if (e.yt) return true;
|
|
1923
|
+
e = e.B;
|
|
1894
1924
|
}
|
|
1895
1925
|
return false;
|
|
1896
1926
|
}
|
|
@@ -1901,42 +1931,45 @@ function setSnapshotCapture(e) {
|
|
|
1901
1931
|
}
|
|
1902
1932
|
|
|
1903
1933
|
function markSnapshotScope(e) {
|
|
1904
|
-
e.
|
|
1934
|
+
e.yt = true;
|
|
1905
1935
|
}
|
|
1906
1936
|
|
|
1907
1937
|
function releaseSnapshotScope(e) {
|
|
1908
|
-
e.
|
|
1938
|
+
e.yt = false;
|
|
1909
1939
|
releaseSubtree(e);
|
|
1910
1940
|
schedule();
|
|
1911
1941
|
}
|
|
1912
1942
|
|
|
1913
1943
|
function releaseSubtree(e) {
|
|
1914
|
-
let t = e.
|
|
1944
|
+
let t = e.it;
|
|
1915
1945
|
while (t) {
|
|
1916
|
-
if (t.
|
|
1917
|
-
t = t.
|
|
1946
|
+
if (t.yt) {
|
|
1947
|
+
t = t.ot;
|
|
1918
1948
|
continue;
|
|
1919
1949
|
}
|
|
1920
1950
|
if (t.Ve) {
|
|
1921
1951
|
const e = t;
|
|
1922
|
-
e.
|
|
1923
|
-
if (e.
|
|
1924
|
-
e.
|
|
1925
|
-
e.
|
|
1926
|
-
if (dirtyQueue.
|
|
1952
|
+
e.Ue &= ~CONFIG_IN_SNAPSHOT_SCOPE;
|
|
1953
|
+
if (e.Ge & REACTIVE_SNAPSHOT_STALE) {
|
|
1954
|
+
e.Ge &= ~REACTIVE_SNAPSHOT_STALE;
|
|
1955
|
+
e.Ge |= REACTIVE_DIRTY;
|
|
1956
|
+
if (dirtyQueue.P > e.Xe) dirtyQueue.P = e.Xe;
|
|
1927
1957
|
insertIntoHeap(e, dirtyQueue);
|
|
1928
1958
|
}
|
|
1929
1959
|
}
|
|
1930
1960
|
releaseSubtree(t);
|
|
1931
|
-
t = t.
|
|
1961
|
+
t = t.ot;
|
|
1932
1962
|
}
|
|
1933
1963
|
}
|
|
1934
1964
|
|
|
1935
1965
|
function clearSnapshots() {
|
|
1936
1966
|
if (snapshotSources) {
|
|
1937
1967
|
for (const e of snapshotSources) {
|
|
1938
|
-
delete e.
|
|
1939
|
-
|
|
1968
|
+
delete e.ve;
|
|
1969
|
+
// StoreNode targets share one pre-initialized hidden class (see
|
|
1970
|
+
// createStoreProxy) — assign undefined instead of deleting, and only
|
|
1971
|
+
// when present so signal-node sources don't grow the field.
|
|
1972
|
+
if (e[STORE_SNAPSHOT_PROPS] !== undefined) e[STORE_SNAPSHOT_PROPS] = undefined;
|
|
1940
1973
|
}
|
|
1941
1974
|
snapshotSources = null;
|
|
1942
1975
|
}
|
|
@@ -1944,35 +1977,35 @@ function clearSnapshots() {
|
|
|
1944
1977
|
}
|
|
1945
1978
|
|
|
1946
1979
|
function recompute(e, t = false) {
|
|
1947
|
-
const n = e.
|
|
1980
|
+
const n = e.Fe;
|
|
1948
1981
|
if (!t) {
|
|
1949
1982
|
if (e.T && (!n || activeTransition) && activeTransition !== e.T) globalQueue.initTransition(e.T);
|
|
1950
1983
|
deleteFromHeap(e, queueFor(e));
|
|
1951
|
-
e.
|
|
1984
|
+
e.ut = null;
|
|
1952
1985
|
// Tracked effects run after finalizePureQueue, so dispose immediately instead of deferring
|
|
1953
|
-
if (e.T || n === EFFECT_TRACKED) disposeChildren(e); else if (e.
|
|
1986
|
+
if (e.T || n === EFFECT_TRACKED) disposeChildren(e); else if (e.it !== null || e.Et !== null) {
|
|
1954
1987
|
markDisposal(e);
|
|
1955
|
-
e.
|
|
1956
|
-
e.
|
|
1957
|
-
e.
|
|
1958
|
-
e.
|
|
1959
|
-
e.
|
|
1988
|
+
e.Me = e.Et;
|
|
1989
|
+
e.We = e.it;
|
|
1990
|
+
e.Et = null;
|
|
1991
|
+
e.it = null;
|
|
1992
|
+
e.lt = 0;
|
|
1960
1993
|
} else ;
|
|
1961
1994
|
}
|
|
1962
|
-
let r = !!(e.
|
|
1995
|
+
let r = !!(e.Ge & REACTIVE_OPTIMISTIC_DIRTY);
|
|
1963
1996
|
const i = e.A !== undefined && e.A !== NOT_PENDING;
|
|
1964
|
-
const o = !!(e.
|
|
1997
|
+
const o = !!(e.Qe & STATUS_UNINITIALIZED);
|
|
1965
1998
|
// Re-ask classification lives in the verdict module; capture the flag before
|
|
1966
1999
|
// the recompute wipes _flags below.
|
|
1967
|
-
const s = (e.
|
|
2000
|
+
const s = (e.Ge & REACTIVE_REASK) !== 0;
|
|
1968
2001
|
const u = context;
|
|
1969
2002
|
context = e;
|
|
1970
|
-
e.
|
|
1971
|
-
e.
|
|
1972
|
-
e.
|
|
1973
|
-
e.
|
|
1974
|
-
let l = e.V === NOT_PENDING ? e.
|
|
1975
|
-
let c = e.
|
|
2003
|
+
e.st = null;
|
|
2004
|
+
e.Rt++;
|
|
2005
|
+
e.Ge = REACTIVE_RECOMPUTING_DEPS;
|
|
2006
|
+
e.W = clock;
|
|
2007
|
+
let l = e.V === NOT_PENDING ? e.ke : e.V;
|
|
2008
|
+
let c = e.Xe;
|
|
1976
2009
|
let a = tracking;
|
|
1977
2010
|
let f = currentOptimisticLane;
|
|
1978
2011
|
tracking = true;
|
|
@@ -1990,7 +2023,7 @@ function recompute(e, t = false) {
|
|
|
1990
2023
|
if (r) {
|
|
1991
2024
|
const t = GlobalQueue.Pe(e, true);
|
|
1992
2025
|
if (t) currentOptimisticLane = t;
|
|
1993
|
-
} else if (activeTransition && !t && activeTransition.
|
|
2026
|
+
} else if (activeTransition && !t && activeTransition.v.length) {
|
|
1994
2027
|
// Lane adoption: parent-deeper-than-owned-child can run before its OPT-dirty
|
|
1995
2028
|
// child propagates. Walk deps once and inherit the OPT lane so this node
|
|
1996
2029
|
// recomputes under the right posture and propagates correctly.
|
|
@@ -2000,53 +2033,53 @@ function recompute(e, t = false) {
|
|
|
2000
2033
|
currentOptimisticLane = t;
|
|
2001
2034
|
}
|
|
2002
2035
|
}
|
|
2003
|
-
const
|
|
2004
|
-
const
|
|
2005
|
-
if (
|
|
2036
|
+
const d = n && n !== EFFECT_USER;
|
|
2037
|
+
const S = stale;
|
|
2038
|
+
if (d) stale = true;
|
|
2006
2039
|
try {
|
|
2007
|
-
if (!false && e.
|
|
2040
|
+
if (!false && e.Ue & CONFIG_SYNC) {
|
|
2008
2041
|
l = e.Ve(l);
|
|
2009
|
-
e.
|
|
2042
|
+
e.ut = null;
|
|
2010
2043
|
} else {
|
|
2011
2044
|
// Snapshot `_inFlight` so we can detect whether `_fn` self-registered an async
|
|
2012
2045
|
// subscription (e.g. `createProjection` calls `handleAsync` from inside its body
|
|
2013
2046
|
// with a setter callback). In that case, the outer `handleAsync` call below would
|
|
2014
2047
|
// clobber the fresh subscription, so we skip it and let the internally-registered
|
|
2015
2048
|
// iteration drive updates.
|
|
2016
|
-
const t = e.
|
|
2049
|
+
const t = e.ut;
|
|
2017
2050
|
const n = e.Ve(l);
|
|
2018
2051
|
const r = typeof n === "object" && n !== null;
|
|
2019
|
-
const i = e.
|
|
2052
|
+
const i = e.ut !== t;
|
|
2020
2053
|
l = i || !r ? n : handleAsync(e, n);
|
|
2021
|
-
if (!i && !r) e.
|
|
2054
|
+
if (!i && !r) e.ut = null;
|
|
2022
2055
|
}
|
|
2023
2056
|
clearStatus(e, t);
|
|
2024
2057
|
// _optimisticLane is only ever assigned by engine paths.
|
|
2025
|
-
if (e.i) GlobalQueue.
|
|
2058
|
+
if (e.i) GlobalQueue.ge(e);
|
|
2026
2059
|
} catch (t) {
|
|
2027
2060
|
// Track pending async in the lane (not the lane's source — it creates the lane
|
|
2028
2061
|
// but doesn't belong to it). Set lane BEFORE notifyStatus for downstream propagation.
|
|
2029
|
-
if (t instanceof NotReadyError && currentOptimisticLane) GlobalQueue.
|
|
2062
|
+
if (t instanceof NotReadyError && currentOptimisticLane) GlobalQueue.Ce(e);
|
|
2030
2063
|
let n = false;
|
|
2031
2064
|
if (t instanceof NotReadyError) {
|
|
2032
|
-
e.
|
|
2033
|
-
if (GlobalQueue.
|
|
2065
|
+
e.It = true;
|
|
2066
|
+
if (GlobalQueue.Se !== null) n = GlobalQueue.Se(e, s);
|
|
2034
2067
|
}
|
|
2035
2068
|
notifyStatus(e, t instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, t, undefined, t instanceof NotReadyError ? e.i : undefined);
|
|
2036
|
-
if (n) GlobalQueue.
|
|
2069
|
+
if (n) GlobalQueue.Te(e);
|
|
2037
2070
|
} finally {
|
|
2038
2071
|
tracking = a;
|
|
2039
2072
|
latestReadActive = E;
|
|
2040
|
-
if (
|
|
2041
|
-
e.
|
|
2073
|
+
if (d) stale = S;
|
|
2074
|
+
e.Ge = REACTIVE_NONE | (t ? e.Ge & REACTIVE_SNAPSHOT_STALE : 0);
|
|
2042
2075
|
context = u;
|
|
2043
2076
|
}
|
|
2044
|
-
if (!e.
|
|
2077
|
+
if (!e.De) {
|
|
2045
2078
|
trimStaleDeps(e);
|
|
2046
|
-
const s = i ? unwrapOverride(e.A) : e.V === NOT_PENDING ? e.
|
|
2079
|
+
const s = i ? unwrapOverride(e.A) : e.V === NOT_PENDING ? e.ke : e.V;
|
|
2047
2080
|
let u = false;
|
|
2048
2081
|
try {
|
|
2049
|
-
u = !n && o || !e.
|
|
2082
|
+
u = !n && o || !e.At || !e.At(s, l);
|
|
2050
2083
|
} catch (t) {
|
|
2051
2084
|
// A throwing user comparator is an error of this node's computation.
|
|
2052
2085
|
// Route it through the same status path as a compute-phase throw so
|
|
@@ -2060,15 +2093,15 @@ function recompute(e, t = false) {
|
|
|
2060
2093
|
// gate: the explicit recompute(node, true) inside effect() does not enqueue, so
|
|
2061
2094
|
// effect() can call its runner synchronously for the first run.
|
|
2062
2095
|
if (n && u) {
|
|
2063
|
-
e.
|
|
2096
|
+
e.xe = !e.De;
|
|
2064
2097
|
// Reuse one bound runner per effect — runEffect no-ops on a stale
|
|
2065
2098
|
// `_modified`, so re-enqueueing the same function is harmless.
|
|
2066
|
-
if (!t) e.
|
|
2099
|
+
if (!t) e.Be.enqueue(n, e.Pt ??= GlobalQueue.J.bind(null, e));
|
|
2067
2100
|
}
|
|
2068
|
-
if (e.
|
|
2101
|
+
if (e.De) ; else if (u) {
|
|
2069
2102
|
const o = i ? e.A : undefined;
|
|
2070
2103
|
if (t || n && activeTransition !== e.T || r) {
|
|
2071
|
-
e.
|
|
2104
|
+
e.ke = l;
|
|
2072
2105
|
// Lane-propagated correction: upstream data is fresh, correct the
|
|
2073
2106
|
// override unconditionally. The direct _value commit is the lane's
|
|
2074
2107
|
// own reveal schedule; drop any superseded older hold so its queued
|
|
@@ -2084,7 +2117,7 @@ function recompute(e, t = false) {
|
|
|
2084
2117
|
// (#2831). Both companion writes are transition-scoped (optimistic) and
|
|
2085
2118
|
// auto-revert/re-derive at commit. Skipped for plain flushes where the
|
|
2086
2119
|
// pending value commits before effects run.
|
|
2087
|
-
if ((activeTransition || e.T) && GlobalQueue.
|
|
2120
|
+
if ((activeTransition || e.T) && GlobalQueue.ue !== null) GlobalQueue.ue(e, l);
|
|
2088
2121
|
}
|
|
2089
2122
|
if (!i || r || e.A !== o) insertSubs(e, r || i);
|
|
2090
2123
|
} else if (i) {
|
|
@@ -2093,77 +2126,77 @@ function recompute(e, t = false) {
|
|
|
2093
2126
|
// for commit on its own transition's schedule — invisibly (A17/A18).
|
|
2094
2127
|
if (e.V === NOT_PENDING) queuePendingNode(e);
|
|
2095
2128
|
e.V = l;
|
|
2096
|
-
} else if (e.
|
|
2097
|
-
for (let t = e.
|
|
2098
|
-
insertIntoHeapHeight(t.
|
|
2129
|
+
} else if (e.Xe != c) {
|
|
2130
|
+
for (let t = e.U; t !== null; t = t.we) {
|
|
2131
|
+
insertIntoHeapHeight(t.Le, queueFor(t.Le));
|
|
2099
2132
|
}
|
|
2100
2133
|
}
|
|
2101
2134
|
}
|
|
2102
2135
|
currentOptimisticLane = f;
|
|
2103
|
-
const T = e.V !== NOT_PENDING || e.
|
|
2136
|
+
const T = e.V !== NOT_PENDING || e.We !== null || e.Me !== null || (e.Qe & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
|
|
2104
2137
|
// Override-covered holds (hasOverride) always queue: their commit belongs
|
|
2105
2138
|
// to their own transition's schedule (A18 re-rule) and is unobservable
|
|
2106
2139
|
// under the override (A17). Revert no longer commits anything, so an
|
|
2107
2140
|
// unqueued covered hold would leak (INV-7) once the revert clears
|
|
2108
2141
|
// _transition.
|
|
2109
|
-
T && (!t || e.
|
|
2142
|
+
T && (!t || e.Qe & STATUS_PENDING) && (!e.T || i) && queuePendingNode(e);
|
|
2110
2143
|
e.T && n && activeTransition !== e.T && runInTransition(e.T, () => recompute(e));
|
|
2111
2144
|
}
|
|
2112
2145
|
|
|
2113
2146
|
function updateIfNecessary(e) {
|
|
2114
|
-
if (e.
|
|
2115
|
-
for (let t = e.
|
|
2116
|
-
const n = t.
|
|
2117
|
-
const r = n.
|
|
2147
|
+
if (e.Ge & REACTIVE_CHECK) {
|
|
2148
|
+
for (let t = e.je; t; t = t.Ke) {
|
|
2149
|
+
const n = t.Ye;
|
|
2150
|
+
const r = n.qe || n;
|
|
2118
2151
|
if (r.Ve) {
|
|
2119
2152
|
updateIfNecessary(r);
|
|
2120
2153
|
}
|
|
2121
|
-
if (e.
|
|
2154
|
+
if (e.Ge & REACTIVE_DIRTY) {
|
|
2122
2155
|
break;
|
|
2123
2156
|
}
|
|
2124
2157
|
}
|
|
2125
2158
|
}
|
|
2126
|
-
if (e.
|
|
2159
|
+
if (e.Ge & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY) || e.De && e.W < clock && !e.ut) {
|
|
2127
2160
|
recompute(e);
|
|
2128
2161
|
}
|
|
2129
|
-
e.
|
|
2162
|
+
e.Ge = e.Ge & (REACTIVE_SNAPSHOT_STALE | REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT);
|
|
2130
2163
|
}
|
|
2131
2164
|
|
|
2132
2165
|
function computed(e, t) {
|
|
2133
2166
|
const n = t?.transparent ?? false;
|
|
2134
2167
|
const r = {
|
|
2135
2168
|
id: inheritId(t, n, context),
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2169
|
+
Ue: (n ? CONFIG_TRANSPARENT : 0) | (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (!context || t?.lazy ? CONFIG_AUTO_DISPOSE : 0) | (t?.sync ? CONFIG_SYNC : 0) | (t?.Ct ? CONFIG_NO_SNAPSHOT : 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
|
|
2170
|
+
At: t?.equals != null ? t.equals : isEqual,
|
|
2171
|
+
F: t?.unobserved,
|
|
2172
|
+
Et: null,
|
|
2173
|
+
Be: context?.Be ?? globalQueue,
|
|
2141
2174
|
dt: context?.dt ?? defaultContext,
|
|
2142
|
-
|
|
2175
|
+
lt: 0,
|
|
2143
2176
|
Ve: e,
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
ut: null,
|
|
2151
|
-
It: 0,
|
|
2152
|
-
k: null,
|
|
2153
|
-
_t: null,
|
|
2154
|
-
Z: context,
|
|
2177
|
+
ke: undefined,
|
|
2178
|
+
Xe: 0,
|
|
2179
|
+
nt: null,
|
|
2180
|
+
tt: undefined,
|
|
2181
|
+
et: null,
|
|
2182
|
+
je: null,
|
|
2155
2183
|
st: null,
|
|
2156
|
-
|
|
2184
|
+
Rt: 0,
|
|
2185
|
+
U: null,
|
|
2186
|
+
Tt: null,
|
|
2187
|
+
B: context,
|
|
2157
2188
|
ot: null,
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2189
|
+
ct: null,
|
|
2190
|
+
it: null,
|
|
2191
|
+
Ge: t?.lazy ? REACTIVE_LAZY : REACTIVE_NONE,
|
|
2192
|
+
Qe: STATUS_UNINITIALIZED,
|
|
2193
|
+
W: clock,
|
|
2161
2194
|
V: NOT_PENDING,
|
|
2162
|
-
He: null,
|
|
2163
2195
|
Me: null,
|
|
2164
|
-
|
|
2196
|
+
We: null,
|
|
2197
|
+
ut: null,
|
|
2165
2198
|
T: null,
|
|
2166
|
-
|
|
2199
|
+
ht: false
|
|
2167
2200
|
};
|
|
2168
2201
|
setupComputedNode(r, t);
|
|
2169
2202
|
return r;
|
|
@@ -2178,44 +2211,44 @@ function computed(e, t) {
|
|
|
2178
2211
|
const s = o?.transparent ?? false;
|
|
2179
2212
|
const u = {
|
|
2180
2213
|
id: inheritId(o, s, context),
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2214
|
+
Ue: (s ? CONFIG_TRANSPARENT : 0) | (o?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (o?.sync ? CONFIG_SYNC : 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
|
|
2215
|
+
At: false,
|
|
2216
|
+
F: o?.unobserved,
|
|
2217
|
+
Et: null,
|
|
2218
|
+
Be: context?.Be ?? globalQueue,
|
|
2186
2219
|
dt: context?.dt ?? defaultContext,
|
|
2187
|
-
|
|
2220
|
+
lt: 0,
|
|
2188
2221
|
Ve: e,
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
ut: null,
|
|
2196
|
-
It: 0,
|
|
2197
|
-
k: null,
|
|
2198
|
-
_t: null,
|
|
2199
|
-
Z: context,
|
|
2222
|
+
ke: undefined,
|
|
2223
|
+
Xe: 0,
|
|
2224
|
+
nt: null,
|
|
2225
|
+
tt: undefined,
|
|
2226
|
+
et: null,
|
|
2227
|
+
je: null,
|
|
2200
2228
|
st: null,
|
|
2201
|
-
|
|
2229
|
+
Rt: 0,
|
|
2230
|
+
U: null,
|
|
2231
|
+
Tt: null,
|
|
2232
|
+
B: context,
|
|
2202
2233
|
ot: null,
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2234
|
+
ct: null,
|
|
2235
|
+
it: null,
|
|
2236
|
+
Ge: REACTIVE_LAZY,
|
|
2237
|
+
Qe: STATUS_UNINITIALIZED,
|
|
2238
|
+
W: clock,
|
|
2206
2239
|
V: NOT_PENDING,
|
|
2207
|
-
He: null,
|
|
2208
2240
|
Me: null,
|
|
2209
|
-
|
|
2241
|
+
We: null,
|
|
2242
|
+
ut: null,
|
|
2210
2243
|
T: null,
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2244
|
+
ht: false,
|
|
2245
|
+
xe: false,
|
|
2246
|
+
gt: undefined,
|
|
2247
|
+
bt: t,
|
|
2248
|
+
Dt: n,
|
|
2249
|
+
ft: undefined,
|
|
2250
|
+
Fe: r,
|
|
2251
|
+
Nt: i
|
|
2219
2252
|
};
|
|
2220
2253
|
setupComputedNode(u, lazyOptions);
|
|
2221
2254
|
return u;
|
|
@@ -2226,24 +2259,24 @@ const lazyOptions = {
|
|
|
2226
2259
|
};
|
|
2227
2260
|
|
|
2228
2261
|
function setupComputedNode(e, t) {
|
|
2229
|
-
e.
|
|
2230
|
-
const n = context?.
|
|
2262
|
+
e.et = e;
|
|
2263
|
+
const n = context?.ze ? context.Je : context;
|
|
2231
2264
|
if (context) {
|
|
2232
|
-
const t = context.
|
|
2265
|
+
const t = context.it;
|
|
2233
2266
|
if (t === null) {
|
|
2234
|
-
context.
|
|
2267
|
+
context.it = e;
|
|
2235
2268
|
} else {
|
|
2236
|
-
e.
|
|
2237
|
-
t.
|
|
2238
|
-
context.
|
|
2269
|
+
e.ot = t;
|
|
2270
|
+
t.ct = e;
|
|
2271
|
+
context.it = e;
|
|
2239
2272
|
}
|
|
2240
2273
|
}
|
|
2241
|
-
if (n) e.
|
|
2242
|
-
if (GlobalQueue.
|
|
2274
|
+
if (n) e.Xe = n.Xe + 1;
|
|
2275
|
+
if (GlobalQueue.oe !== null) GlobalQueue.oe(e);
|
|
2243
2276
|
!t?.lazy && recompute(e, true);
|
|
2244
2277
|
if (snapshotCaptureActive && !t?.lazy) {
|
|
2245
|
-
if (!(e.
|
|
2246
|
-
e.
|
|
2278
|
+
if (!(e.Qe & STATUS_PENDING) && !(e.Ue & CONFIG_NO_SNAPSHOT)) {
|
|
2279
|
+
e.ve = e.ke === undefined ? NO_SNAPSHOT : e.ke;
|
|
2247
2280
|
snapshotSources.add(e);
|
|
2248
2281
|
}
|
|
2249
2282
|
}
|
|
@@ -2251,20 +2284,20 @@ function setupComputedNode(e, t) {
|
|
|
2251
2284
|
|
|
2252
2285
|
function signal(e, t, n = null) {
|
|
2253
2286
|
const r = {
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2287
|
+
At: t?.equals != null ? t.equals : isEqual,
|
|
2288
|
+
Ue: (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (t?.Ct ? CONFIG_NO_SNAPSHOT : 0),
|
|
2289
|
+
F: t?.unobserved,
|
|
2290
|
+
ke: e,
|
|
2291
|
+
U: null,
|
|
2292
|
+
Tt: null,
|
|
2293
|
+
W: clock,
|
|
2294
|
+
qe: n,
|
|
2295
|
+
rt: n?.nt || null,
|
|
2263
2296
|
V: NOT_PENDING
|
|
2264
2297
|
};
|
|
2265
|
-
n && (n.
|
|
2266
|
-
if (snapshotCaptureActive && !(r.
|
|
2267
|
-
r.
|
|
2298
|
+
n && (n.nt = r);
|
|
2299
|
+
if (snapshotCaptureActive && !(r.Ue & CONFIG_NO_SNAPSHOT) && !((n?.Qe ?? 0) & STATUS_PENDING)) {
|
|
2300
|
+
r.ve = e === undefined ? NO_SNAPSHOT : e;
|
|
2268
2301
|
snapshotSources.add(r);
|
|
2269
2302
|
}
|
|
2270
2303
|
return r;
|
|
@@ -2308,11 +2341,11 @@ function isEqual(e, t) {
|
|
|
2308
2341
|
* );
|
|
2309
2342
|
* ```
|
|
2310
2343
|
*/ function untrack(e, t) {
|
|
2311
|
-
if (GlobalQueue.
|
|
2344
|
+
if (GlobalQueue.se === null && !tracking && true) return e();
|
|
2312
2345
|
const n = tracking;
|
|
2313
2346
|
tracking = false;
|
|
2314
2347
|
try {
|
|
2315
|
-
if (GlobalQueue.
|
|
2348
|
+
if (GlobalQueue.se !== null) return GlobalQueue.se(e);
|
|
2316
2349
|
return e();
|
|
2317
2350
|
} finally {
|
|
2318
2351
|
tracking = n;
|
|
@@ -2324,10 +2357,10 @@ function isEqual(e, t) {
|
|
|
2324
2357
|
* an isPending() probe (`refresh`) additionally pulls the node fully up to
|
|
2325
2358
|
* date so its status flags reflect the current graph.
|
|
2326
2359
|
*/ function prepareComputed(e, t) {
|
|
2327
|
-
if (e.
|
|
2328
|
-
e.
|
|
2360
|
+
if (e.Ge & REACTIVE_LAZY) {
|
|
2361
|
+
e.Ge &= ~REACTIVE_LAZY;
|
|
2329
2362
|
recompute(e, true);
|
|
2330
|
-
} else if (e.
|
|
2363
|
+
} else if (e.Ge & REACTIVE_DISPOSED) {
|
|
2331
2364
|
recompute(e, true);
|
|
2332
2365
|
} else if (t) {
|
|
2333
2366
|
updateIfNecessary(e);
|
|
@@ -2339,72 +2372,72 @@ function read(e) {
|
|
|
2339
2372
|
// Checked before isPending so that isPending(() => latest(x)) checks
|
|
2340
2373
|
// the _pendingSignal of _latestValueComputed (async in flight) rather
|
|
2341
2374
|
// than the original node (which stays "pending" while held in a transition).
|
|
2342
|
-
if (latestReadActive) return GlobalQueue.
|
|
2375
|
+
if (latestReadActive) return GlobalQueue.fe(e);
|
|
2343
2376
|
let t = context;
|
|
2344
|
-
if (t?.
|
|
2377
|
+
if (t?.ze) t = t.Je;
|
|
2345
2378
|
const n = e;
|
|
2346
|
-
const r = e.
|
|
2379
|
+
const r = e.qe;
|
|
2347
2380
|
const i = r || e;
|
|
2348
2381
|
// Handle isPending() mode: collect pending state while preserving normal read semantics.
|
|
2349
2382
|
// Probe mode is suspended while preparing the node so nested reads during a
|
|
2350
2383
|
// recompute don't collect into the probe.
|
|
2351
2384
|
if (pendingCheckActive) {
|
|
2352
|
-
GlobalQueue.
|
|
2385
|
+
GlobalQueue.Ee(e, t, i, r);
|
|
2353
2386
|
} else if (typeof n.Ve === "function") {
|
|
2354
2387
|
prepareComputed(e, false);
|
|
2355
2388
|
}
|
|
2356
|
-
if (!n.Ve && i === e && e.A === undefined && e.
|
|
2389
|
+
if (!n.Ve && i === e && e.A === undefined && e.ve === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
|
|
2357
2390
|
if (t && tracking) link(e, t);
|
|
2358
|
-
return !t || e.V === NOT_PENDING ? e.
|
|
2391
|
+
return !t || e.V === NOT_PENDING ? e.ke : e.V;
|
|
2359
2392
|
}
|
|
2360
2393
|
if (t && tracking) {
|
|
2361
2394
|
link(e, t, pendingCheckActive);
|
|
2362
2395
|
if (i.Ve) {
|
|
2363
2396
|
const n = queueFor(e);
|
|
2364
|
-
if (i.
|
|
2397
|
+
if (i.Xe >= n.P) {
|
|
2365
2398
|
markNode(t);
|
|
2366
2399
|
markHeap(n);
|
|
2367
2400
|
updateIfNecessary(i);
|
|
2368
2401
|
}
|
|
2369
|
-
const r = i.
|
|
2402
|
+
const r = i.Xe;
|
|
2370
2403
|
// parent check is shallow, might need to be recursive
|
|
2371
|
-
if (r >= t.
|
|
2372
|
-
t.
|
|
2404
|
+
if (r >= t.Xe && e.B !== t) {
|
|
2405
|
+
t.Xe = r + 1;
|
|
2373
2406
|
}
|
|
2374
2407
|
}
|
|
2375
2408
|
}
|
|
2376
|
-
if (i.
|
|
2409
|
+
if (i.Qe & STATUS_PENDING) {
|
|
2377
2410
|
if (t && !(stale && i.T && activeTransition !== i.T)) {
|
|
2378
2411
|
// Per-lane suspension lives with the engine (a non-null lane implies it
|
|
2379
2412
|
// is installed): under a lane, only same-lane pending async without an
|
|
2380
2413
|
// active override throws.
|
|
2381
|
-
if (currentOptimisticLane === null || GlobalQueue.
|
|
2414
|
+
if (currentOptimisticLane === null || GlobalQueue.Ne(i)) {
|
|
2382
2415
|
if (!tracking && e !== t) link(e, t);
|
|
2383
|
-
throw i.
|
|
2416
|
+
throw i.De;
|
|
2384
2417
|
}
|
|
2385
|
-
} else if (t && i !== e && i.
|
|
2418
|
+
} else if (t && i !== e && i.Qe & STATUS_UNINITIALIZED) {
|
|
2386
2419
|
if (!tracking && e !== t) link(e, t);
|
|
2387
|
-
throw i.
|
|
2388
|
-
} else if (!t && i.
|
|
2389
|
-
throw i.
|
|
2420
|
+
throw i.De;
|
|
2421
|
+
} else if (!t && i.Qe & STATUS_UNINITIALIZED) {
|
|
2422
|
+
throw i.De;
|
|
2390
2423
|
}
|
|
2391
2424
|
}
|
|
2392
|
-
if (e.Ve && e.
|
|
2425
|
+
if (e.Ve && e.Qe & STATUS_ERROR) {
|
|
2393
2426
|
// Only a genuine reactive re-read may retry an errored async source:
|
|
2394
2427
|
// - tracking: owned/tracked scope only (never events / `untrack` / effect side-effect phase)
|
|
2395
2428
|
// - !pendingCheckActive: an `isPending` probe observes the error, never refetches
|
|
2396
2429
|
// - el._time < clock: only on a later cycle than the one the error was found
|
|
2397
|
-
if (tracking && !pendingCheckActive && e.
|
|
2430
|
+
if (tracking && !pendingCheckActive && e.W < clock) {
|
|
2398
2431
|
recompute(e);
|
|
2399
2432
|
return read(e);
|
|
2400
|
-
} else throw e.
|
|
2433
|
+
} else throw e.De;
|
|
2401
2434
|
}
|
|
2402
|
-
if (snapshotCaptureActive && t && t.
|
|
2403
|
-
const n = e.
|
|
2435
|
+
if (snapshotCaptureActive && t && t.Ue & CONFIG_IN_SNAPSHOT_SCOPE) {
|
|
2436
|
+
const n = e.ve;
|
|
2404
2437
|
if (n !== undefined) {
|
|
2405
2438
|
const r = n === NO_SNAPSHOT ? undefined : n;
|
|
2406
|
-
const i = e.V !== NOT_PENDING ? e.V : e.
|
|
2407
|
-
if (i !== r) t.
|
|
2439
|
+
const i = e.V !== NOT_PENDING ? e.V : e.ke;
|
|
2440
|
+
if (i !== r) t.Ge |= REACTIVE_SNAPSHOT_STALE;
|
|
2408
2441
|
return r;
|
|
2409
2442
|
}
|
|
2410
2443
|
}
|
|
@@ -2419,18 +2452,18 @@ function read(e) {
|
|
|
2419
2452
|
// _pendingValue for correct fetching. The sub is recorded for replay at commit
|
|
2420
2453
|
// so it re-runs with the new committed view. (Gate details live with the
|
|
2421
2454
|
// engine — a non-null lane implies it is installed.)
|
|
2422
|
-
if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.
|
|
2423
|
-
return e.
|
|
2455
|
+
if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.he(e, i, t)) {
|
|
2456
|
+
return e.ke;
|
|
2424
2457
|
}
|
|
2425
2458
|
// In optimistic lane context, return _value for optimistic/lane-assigned signals
|
|
2426
2459
|
// and for regular signals in stale mode (render effects). Non-stale readers (user
|
|
2427
2460
|
// effects) see _pendingValue so that latest() and direct reads stay consistent.
|
|
2428
2461
|
// (The lane-context clause lives with the engine.)
|
|
2429
|
-
const o = !t || currentOptimisticLane !== null && GlobalQueue.
|
|
2462
|
+
const o = !t || currentOptimisticLane !== null && GlobalQueue.ye(e, i, t) || e.V === NOT_PENDING || stale && e.T && activeTransition !== e.T ? e.ke : e.V;
|
|
2430
2463
|
// Record that this isPending() probe observed the fresh pending value, so
|
|
2431
2464
|
// the probe doesn't pair "pending" with the new value (#2831).
|
|
2432
2465
|
if (pendingCheckActive) GlobalQueue.de(e, o);
|
|
2433
|
-
if (!t && i === e && typeof n.Ve === "function" && e.
|
|
2466
|
+
if (!t && i === e && typeof n.Ve === "function" && e.Ue & CONFIG_AUTO_DISPOSE && !(i.Qe & STATUS_PENDING) && !e.U) {
|
|
2434
2467
|
unobserved(e);
|
|
2435
2468
|
}
|
|
2436
2469
|
return o;
|
|
@@ -2443,16 +2476,16 @@ function setSignal(e, t) {
|
|
|
2443
2476
|
// _overrideValue slot, and every module that creates one installs the
|
|
2444
2477
|
// engine first.
|
|
2445
2478
|
if (e.A !== undefined && !projectionWriteActive) return GlobalQueue.Oe(e, t);
|
|
2446
|
-
const n = e.V === NOT_PENDING ? e.
|
|
2479
|
+
const n = e.V === NOT_PENDING ? e.ke : e.V;
|
|
2447
2480
|
if (typeof t === "function") t = t(n);
|
|
2448
2481
|
// Uninitialized check first: the first commit has no previous value, so the
|
|
2449
2482
|
// user comparator must not run against `undefined` (matches recompute).
|
|
2450
|
-
const r = !!(e.
|
|
2483
|
+
const r = !!(e.Qe & STATUS_UNINITIALIZED) || !e.At || !e.At(n, t);
|
|
2451
2484
|
if (!r) return t;
|
|
2452
2485
|
if (e.V === NOT_PENDING) queuePendingNode(e);
|
|
2453
2486
|
e.V = t;
|
|
2454
|
-
GlobalQueue.
|
|
2455
|
-
e.
|
|
2487
|
+
GlobalQueue.ue !== null && GlobalQueue.ue(e, t);
|
|
2488
|
+
e.W = clock;
|
|
2456
2489
|
insertSubs(e);
|
|
2457
2490
|
schedule();
|
|
2458
2491
|
return t;
|
|
@@ -2466,11 +2499,11 @@ function setSignal(e, t) {
|
|
|
2466
2499
|
* cleanup point.
|
|
2467
2500
|
*/ function suppressComputedRecompute(e) {
|
|
2468
2501
|
deleteFromHeap(e, queueFor(e));
|
|
2469
|
-
if (!(e.
|
|
2502
|
+
if (!(e.Ge & REACTIVE_MANUAL_WRITE) && e.V === NOT_PENDING) {
|
|
2470
2503
|
queuePendingNode(e);
|
|
2471
2504
|
schedule();
|
|
2472
2505
|
}
|
|
2473
|
-
e.
|
|
2506
|
+
e.Ge = e.Ge & -4 | REACTIVE_MANUAL_WRITE;
|
|
2474
2507
|
}
|
|
2475
2508
|
|
|
2476
2509
|
/**
|
|
@@ -2549,7 +2582,7 @@ function staleValues(e, t = true) {
|
|
|
2549
2582
|
if (!t) {
|
|
2550
2583
|
return;
|
|
2551
2584
|
}
|
|
2552
|
-
if (typeof t.Ve === "function" && !(t.
|
|
2585
|
+
if (typeof t.Ve === "function" && !(t.Ge & (REACTIVE_DISPOSED | REACTIVE_MANUAL_WRITE))) {
|
|
2553
2586
|
// A refresh with no value-change dirt already queued is a re-ask of the
|
|
2554
2587
|
// same question: mark it so the recompute classifies any resulting
|
|
2555
2588
|
// pending window as quiet (not pending). If the node is already dirty
|
|
@@ -2557,11 +2590,11 @@ function staleValues(e, t = true) {
|
|
|
2557
2590
|
// REACTIVE_IN_HEAP counts as dirt: insertSubs schedules subscribers by
|
|
2558
2591
|
// heap insertion alone (no DIRTY/CHECK flag), so a same-batch value
|
|
2559
2592
|
// change followed by refresh() must not be laundered into a quiet re-ask.
|
|
2560
|
-
if (!(t.
|
|
2561
|
-
t.
|
|
2593
|
+
if (!(t.Ge & (REACTIVE_DIRTY | REACTIVE_CHECK | REACTIVE_IN_HEAP))) {
|
|
2594
|
+
t.Ge |= REACTIVE_REASK;
|
|
2562
2595
|
armReaskClear();
|
|
2563
2596
|
}
|
|
2564
|
-
t.
|
|
2597
|
+
t.Ge = t.Ge & ~REACTIVE_CHECK | REACTIVE_DIRTY;
|
|
2565
2598
|
insertIntoHeap(t, queueFor(t));
|
|
2566
2599
|
schedule();
|
|
2567
2600
|
}
|
|
@@ -2627,8 +2660,8 @@ function externalUntrack(e) {
|
|
|
2627
2660
|
// removed on reset) so core's null checks stay equivalent to the old
|
|
2628
2661
|
// `externalSourceConfig` truthiness checks.
|
|
2629
2662
|
function syncExternalHooks() {
|
|
2630
|
-
GlobalQueue.
|
|
2631
|
-
GlobalQueue.
|
|
2663
|
+
GlobalQueue.oe = externalSourceConfig ? wireExternalSource : null;
|
|
2664
|
+
GlobalQueue.se = externalSourceConfig ? externalUntrack : null;
|
|
2632
2665
|
}
|
|
2633
2666
|
|
|
2634
2667
|
function enableExternalSource(e) {
|
|
@@ -2735,9 +2768,9 @@ function isUndefined(e) {
|
|
|
2735
2768
|
*/
|
|
2736
2769
|
/** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, t) {
|
|
2737
2770
|
const n = e.A !== NOT_PENDING;
|
|
2738
|
-
const r = n ? unwrapOverride(e.A) : e.
|
|
2771
|
+
const r = n ? unwrapOverride(e.A) : e.ke;
|
|
2739
2772
|
if (typeof t === "function") t = t(r);
|
|
2740
|
-
const i = !!(e.
|
|
2773
|
+
const i = !!(e.Qe & STATUS_UNINITIALIZED) || !e.At || !e.At(r, t);
|
|
2741
2774
|
if (!i) {
|
|
2742
2775
|
// Same-value write with an active override still entangles the current
|
|
2743
2776
|
// action's transition — the hold must outlast all overlapping actions.
|
|
@@ -2751,7 +2784,7 @@ function isUndefined(e) {
|
|
|
2751
2784
|
// No revert target is stashed: while the override is active every reader
|
|
2752
2785
|
// sees it (A17), so authoritative arrivals commit silently into _value and
|
|
2753
2786
|
// reverting is just dropping the override — _value is already correct.
|
|
2754
|
-
else globalQueue.D.
|
|
2787
|
+
else globalQueue.D.v.push(e);
|
|
2755
2788
|
// Stamp ownership on the node (post-merge, so entangled writers share the
|
|
2756
2789
|
// joint root). resolveTransition prefers this over the lane's _transition,
|
|
2757
2790
|
// which a shared subscriber can merge across transactions (#2912).
|
|
@@ -2762,8 +2795,8 @@ function isUndefined(e) {
|
|
|
2762
2795
|
// brand, and erasing it makes the write invisible and routes follow-up
|
|
2763
2796
|
// writes off the optimistic path into permanent commits (#2898).
|
|
2764
2797
|
e.A = t === undefined ? OVERRIDE_UNDEFINED : t;
|
|
2765
|
-
GlobalQueue.
|
|
2766
|
-
e.
|
|
2798
|
+
GlobalQueue.ue !== null && GlobalQueue.ue(e, t);
|
|
2799
|
+
e.W = clock;
|
|
2767
2800
|
insertSubs(e, true);
|
|
2768
2801
|
schedule();
|
|
2769
2802
|
return t;
|
|
@@ -2774,9 +2807,9 @@ function isUndefined(e) {
|
|
|
2774
2807
|
* while one of its optimistic nodes holds an active override that is still
|
|
2775
2808
|
* pending on real (non-affects-sentinel) async.
|
|
2776
2809
|
*/ function transitionBlocked(e) {
|
|
2777
|
-
for (let t = 0; t < e.
|
|
2778
|
-
const n = e.
|
|
2779
|
-
if (hasActiveOverride(n) && "
|
|
2810
|
+
for (let t = 0; t < e.v.length; t++) {
|
|
2811
|
+
const n = e.v[t];
|
|
2812
|
+
if (hasActiveOverride(n) && "Qe" in n && n.Qe & STATUS_PENDING && n.De instanceof NotReadyError) {
|
|
2780
2813
|
return true;
|
|
2781
2814
|
}
|
|
2782
2815
|
}
|
|
@@ -2794,10 +2827,10 @@ function resolveOptimisticNodes(e) {
|
|
|
2794
2827
|
// Revert is a pure drop: there is no revert target to commit —
|
|
2795
2828
|
// override-covered authoritative values hold in _pendingValue and
|
|
2796
2829
|
// elevate on their OWN transition's schedule (A18 as re-ruled 2026-07-07).
|
|
2797
|
-
if (!(t.
|
|
2830
|
+
if (!(t.Qe & STATUS_PENDING)) t.Qe &= ~STATUS_UNINITIALIZED;
|
|
2798
2831
|
const r = t.A;
|
|
2799
2832
|
t.A = NOT_PENDING;
|
|
2800
|
-
if (r !== NOT_PENDING && t.
|
|
2833
|
+
if (r !== NOT_PENDING && t.ke !== unwrapOverride(r)) insertSubs(t, true);
|
|
2801
2834
|
t.T = null;
|
|
2802
2835
|
t.R = null;
|
|
2803
2836
|
}
|
|
@@ -2806,9 +2839,9 @@ function resolveOptimisticNodes(e) {
|
|
|
2806
2839
|
// transition that produced them (A19 — pending is a property of the data).
|
|
2807
2840
|
for (let n = 0; n < t; n++) {
|
|
2808
2841
|
const t = e[n];
|
|
2809
|
-
if (t.
|
|
2842
|
+
if (t.O || t.p) GlobalQueue.ae(t);
|
|
2810
2843
|
const r = t.t;
|
|
2811
|
-
if (r && (r.
|
|
2844
|
+
if (r && (r.O === t || r.p === t)) GlobalQueue.ae(r);
|
|
2812
2845
|
}
|
|
2813
2846
|
e.splice(0, t);
|
|
2814
2847
|
}
|
|
@@ -2861,10 +2894,10 @@ function cleanupCompletedLanes(e) {
|
|
|
2861
2894
|
* that reads a pending mid-transition write sees the committed value; the sub
|
|
2862
2895
|
* is recorded for replay at commit.
|
|
2863
2896
|
*/ function gatedRead(e, t, n) {
|
|
2864
|
-
if (latestReadActive || e.V === NOT_PENDING || e.Ve || t !== e && !(t.
|
|
2897
|
+
if (latestReadActive || e.V === NOT_PENDING || e.Ve || t !== e && !(t.Ge & REACTIVE_MANUAL_WRITE)) {
|
|
2865
2898
|
return false;
|
|
2866
2899
|
}
|
|
2867
|
-
activeTransition.
|
|
2900
|
+
activeTransition.Y.add(n);
|
|
2868
2901
|
return true;
|
|
2869
2902
|
}
|
|
2870
2903
|
|
|
@@ -2872,7 +2905,7 @@ function cleanupCompletedLanes(e) {
|
|
|
2872
2905
|
* read()'s value selection under a lane: return the committed `_value` for
|
|
2873
2906
|
* optimistic/lane-assigned signals, stale-mode reads, and pending owners.
|
|
2874
2907
|
*/ function laneReadsCommitted(e, t, n) {
|
|
2875
|
-
return e.A !== undefined || !!e.i || t === e && stale && n.t !== e || !!(t.
|
|
2908
|
+
return e.A !== undefined || !!e.i || t === e && stale && n.t !== e || !!(t.Qe & STATUS_PENDING);
|
|
2876
2909
|
}
|
|
2877
2910
|
|
|
2878
2911
|
/**
|
|
@@ -2881,12 +2914,12 @@ function cleanupCompletedLanes(e) {
|
|
|
2881
2914
|
* can run before its OPT-dirty child propagates).
|
|
2882
2915
|
*/ function recomputeLane(e, t) {
|
|
2883
2916
|
if (t) return resolveLane(e) ?? null;
|
|
2884
|
-
for (let t = e.
|
|
2885
|
-
const n = t.
|
|
2886
|
-
if (n.
|
|
2917
|
+
for (let t = e.je; t; t = t.Ke) {
|
|
2918
|
+
const n = t.Ye;
|
|
2919
|
+
if (n.Ge & REACTIVE_OPTIMISTIC_DIRTY) {
|
|
2887
2920
|
const t = resolveLane(n);
|
|
2888
2921
|
if (t) {
|
|
2889
|
-
e.
|
|
2922
|
+
e.Ge |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
2890
2923
|
assignOrMergeLane(e, t);
|
|
2891
2924
|
return t;
|
|
2892
2925
|
}
|
|
@@ -2900,7 +2933,7 @@ function cleanupCompletedLanes(e) {
|
|
|
2900
2933
|
if (t.o !== e) {
|
|
2901
2934
|
t.u.add(e);
|
|
2902
2935
|
e.i = t;
|
|
2903
|
-
GlobalQueue.
|
|
2936
|
+
GlobalQueue.le !== null && GlobalQueue.le(t.o);
|
|
2904
2937
|
}
|
|
2905
2938
|
}
|
|
2906
2939
|
|
|
@@ -2908,13 +2941,13 @@ function cleanupCompletedLanes(e) {
|
|
|
2908
2941
|
const t = resolveLane(e);
|
|
2909
2942
|
if (t) {
|
|
2910
2943
|
t.u.delete(e);
|
|
2911
|
-
GlobalQueue.
|
|
2944
|
+
GlobalQueue.le !== null && GlobalQueue.le(t.o);
|
|
2912
2945
|
}
|
|
2913
2946
|
}
|
|
2914
2947
|
|
|
2915
2948
|
function trackOptimisticStore(e) {
|
|
2916
2949
|
// After initTransition, globalQueue._batch IS activeTransition (same reference)
|
|
2917
|
-
globalQueue.D.
|
|
2950
|
+
globalQueue.D.L.add(e);
|
|
2918
2951
|
schedule();
|
|
2919
2952
|
}
|
|
2920
2953
|
|
|
@@ -2925,17 +2958,17 @@ function trackOptimisticStore(e) {
|
|
|
2925
2958
|
*/ function installOptimisticEngine() {
|
|
2926
2959
|
if (GlobalQueue.Oe !== null) return;
|
|
2927
2960
|
GlobalQueue.Oe = optimisticWrite;
|
|
2928
|
-
GlobalQueue.
|
|
2929
|
-
GlobalQueue.
|
|
2930
|
-
GlobalQueue.
|
|
2931
|
-
GlobalQueue.
|
|
2932
|
-
GlobalQueue.
|
|
2933
|
-
GlobalQueue.
|
|
2934
|
-
GlobalQueue.
|
|
2961
|
+
GlobalQueue.pe = resolveOptimisticNodes;
|
|
2962
|
+
GlobalQueue.Re = transitionBlocked;
|
|
2963
|
+
GlobalQueue.Ie = cleanupCompletedLanes;
|
|
2964
|
+
GlobalQueue.Ae = runLaneEffects;
|
|
2965
|
+
GlobalQueue.he = gatedRead;
|
|
2966
|
+
GlobalQueue.Ne = laneSuspends;
|
|
2967
|
+
GlobalQueue.ye = laneReadsCommitted;
|
|
2935
2968
|
GlobalQueue.Pe = recomputeLane;
|
|
2936
|
-
GlobalQueue.
|
|
2937
|
-
GlobalQueue.
|
|
2938
|
-
GlobalQueue.
|
|
2969
|
+
GlobalQueue.Ce = laneAsyncPending;
|
|
2970
|
+
GlobalQueue.ge = laneAsyncSettled;
|
|
2971
|
+
GlobalQueue.be = trackOptimisticStore;
|
|
2939
2972
|
}
|
|
2940
2973
|
|
|
2941
2974
|
/**
|
|
@@ -2954,21 +2987,21 @@ let pendingProbe = null;
|
|
|
2954
2987
|
* Get or create the pending signal for a node (lazy).
|
|
2955
2988
|
* Used by isPending() to track pending state reactively.
|
|
2956
2989
|
*/ function getPendingSignal(e) {
|
|
2957
|
-
if (!e.
|
|
2990
|
+
if (!e.O) {
|
|
2958
2991
|
// Start false, write true if pending - ensures reversion returns to false
|
|
2959
|
-
e.
|
|
2992
|
+
e.O = optimisticSignal(false, {
|
|
2960
2993
|
ownedWrite: true
|
|
2961
2994
|
});
|
|
2962
|
-
e.
|
|
2963
|
-
if (computePendingState(e)) setSignal(e.
|
|
2995
|
+
e.O.t = e;
|
|
2996
|
+
if (computePendingState(e)) setSignal(e.O, true);
|
|
2964
2997
|
}
|
|
2965
|
-
return e.
|
|
2998
|
+
return e.O;
|
|
2966
2999
|
}
|
|
2967
3000
|
|
|
2968
3001
|
function collectPendingSources(e) {
|
|
2969
3002
|
if (!pendingProbe) return;
|
|
2970
3003
|
pendingProbe.sources.add(e);
|
|
2971
|
-
const t = e.
|
|
3004
|
+
const t = e.qe || e;
|
|
2972
3005
|
if (t !== e) pendingProbe.sources.add(t);
|
|
2973
3006
|
}
|
|
2974
3007
|
|
|
@@ -2992,26 +3025,26 @@ function collectPendingSources(e) {
|
|
|
2992
3025
|
* (`_pendingObserver`) are skipped so an `isPending` wrapper memo never
|
|
2993
3026
|
* inherits the coverage it reports on.
|
|
2994
3027
|
*/ function markWalk(e, t) {
|
|
2995
|
-
if (e.
|
|
3028
|
+
if (e.k) return true;
|
|
2996
3029
|
// A real error outranks an inherited mark (A16/A24c): an errored node
|
|
2997
3030
|
// answers probes with its error, not a coverage verdict, and coverage does
|
|
2998
3031
|
// not flow through it — matching the rails' behavior, where propagation
|
|
2999
3032
|
// stopped at errored nodes. A DIRECT mark on an errored node still reads
|
|
3000
3033
|
// pending (the count check above), also matching.
|
|
3001
|
-
if (e.
|
|
3034
|
+
if (e.Qe & STATUS_ERROR) return false;
|
|
3002
3035
|
if (t.has(e)) return false;
|
|
3003
3036
|
t.add(e);
|
|
3004
|
-
const n = e.
|
|
3037
|
+
const n = e.qe;
|
|
3005
3038
|
if (n && markWalk(n, t)) return true;
|
|
3006
3039
|
// Mid-recompute (the clearStatus companion poke runs before
|
|
3007
3040
|
// trimStaleDeps), only the validated prefix [_deps.._depsTail] is this
|
|
3008
3041
|
// pass's dependency set — walking past it would read dropped deps and
|
|
3009
3042
|
// latch a stale verdict on the companion.
|
|
3010
3043
|
const r = e;
|
|
3011
|
-
const i = r.
|
|
3044
|
+
const i = r.Ge & REACTIVE_RECOMPUTING_DEPS ? r.st : undefined;
|
|
3012
3045
|
if (i !== null) {
|
|
3013
|
-
for (let e = r.
|
|
3014
|
-
if (!e.
|
|
3046
|
+
for (let e = r.je ?? null; e !== null; e = e.Ke) {
|
|
3047
|
+
if (!e._t && markWalk(e.Ye, t)) return true;
|
|
3015
3048
|
if (e === i) break;
|
|
3016
3049
|
}
|
|
3017
3050
|
}
|
|
@@ -3024,54 +3057,54 @@ function collectPendingSources(e) {
|
|
|
3024
3057
|
|
|
3025
3058
|
function quietPending(e) {
|
|
3026
3059
|
if (e.$e) {
|
|
3027
|
-
for (const t of e.$e) if (!t.
|
|
3060
|
+
for (const t of e.$e) if (!t.ht) return false;
|
|
3028
3061
|
return true;
|
|
3029
3062
|
}
|
|
3030
|
-
return e.
|
|
3063
|
+
return e.ht;
|
|
3031
3064
|
}
|
|
3032
3065
|
|
|
3033
3066
|
function newQuestionInFlight(e) {
|
|
3034
|
-
return !!(e.
|
|
3067
|
+
return !!(e.Qe & STATUS_PENDING) && !(e.Qe & STATUS_UNINITIALIZED) && !quietPending(e);
|
|
3035
3068
|
}
|
|
3036
3069
|
|
|
3037
3070
|
function computePendingState(e) {
|
|
3038
3071
|
const t = e;
|
|
3039
|
-
if (t.
|
|
3072
|
+
if (t.Ge & REACTIVE_DISPOSED) return false;
|
|
3040
3073
|
// Mark coverage is transitive by dep-graph reachability: a latest() shadow
|
|
3041
3074
|
// reaches its owner (and a store leaf its firewall) through its own deps,
|
|
3042
3075
|
// so the one walk covers direct marks, derivation, and companion chains.
|
|
3043
3076
|
if (markCovered(e)) return true;
|
|
3044
|
-
const n = e.
|
|
3077
|
+
const n = e.qe;
|
|
3045
3078
|
if (e.t) {
|
|
3046
3079
|
const t = e.t;
|
|
3047
|
-
const n = t.
|
|
3080
|
+
const n = t.qe || t;
|
|
3048
3081
|
return newQuestionInFlight(n);
|
|
3049
3082
|
}
|
|
3050
3083
|
if (n && e.V !== NOT_PENDING && !hasActiveOverride(e)) {
|
|
3051
|
-
return !!(n.
|
|
3084
|
+
return !!(n.Ge & REACTIVE_MANUAL_WRITE) || !n.ut && !(n.Qe & STATUS_PENDING) || !!(n.Qe & STATUS_PENDING) && quietPending(n);
|
|
3052
3085
|
}
|
|
3053
|
-
if (e.V !== NOT_PENDING && !(t.
|
|
3054
|
-
if (hasActiveOverride(e)) return !e.
|
|
3086
|
+
if (e.V !== NOT_PENDING && !(t.Qe & STATUS_UNINITIALIZED)) {
|
|
3087
|
+
if (hasActiveOverride(e)) return !e.At || !e.At(e.V, unwrapOverride(e.A));
|
|
3055
3088
|
return true;
|
|
3056
3089
|
}
|
|
3057
3090
|
return newQuestionInFlight(t);
|
|
3058
3091
|
}
|
|
3059
3092
|
|
|
3060
3093
|
function syncCompanions(e, t) {
|
|
3061
|
-
if (e.
|
|
3062
|
-
if (e.
|
|
3094
|
+
if (e.O) updatePendingSignal(e);
|
|
3095
|
+
if (e.p) setSignal(e.p, t);
|
|
3063
3096
|
}
|
|
3064
3097
|
|
|
3065
3098
|
function updatePendingSignal(e) {
|
|
3066
|
-
if (e.
|
|
3067
|
-
setSignal(e.
|
|
3099
|
+
if (e.O) {
|
|
3100
|
+
setSignal(e.O, computePendingState(e));
|
|
3068
3101
|
}
|
|
3069
|
-
if (e.
|
|
3102
|
+
if (e.p) updatePendingSignal(e.p);
|
|
3070
3103
|
}
|
|
3071
3104
|
|
|
3072
3105
|
function updateChildCompanions(e) {
|
|
3073
|
-
for (let t = e.
|
|
3074
|
-
if (t.
|
|
3106
|
+
for (let t = e.nt; t !== null; t = t.rt) {
|
|
3107
|
+
if (t.O || t.p) updatePendingSignal(t);
|
|
3075
3108
|
}
|
|
3076
3109
|
}
|
|
3077
3110
|
|
|
@@ -3089,9 +3122,9 @@ function updateChildCompanions(e) {
|
|
|
3089
3122
|
const visit = e => {
|
|
3090
3123
|
if (r.has(e)) return;
|
|
3091
3124
|
r.add(e);
|
|
3092
|
-
if (e.
|
|
3093
|
-
for (let t = e.
|
|
3094
|
-
for (let t = e.
|
|
3125
|
+
if (e.O || e.p) n(e);
|
|
3126
|
+
for (let t = e.U; t !== null; t = t.we) visit(t.Le);
|
|
3127
|
+
for (let t = e.nt ?? null; t !== null; t = t.rt) {
|
|
3095
3128
|
visit(t);
|
|
3096
3129
|
}
|
|
3097
3130
|
};
|
|
@@ -3099,21 +3132,21 @@ function updateChildCompanions(e) {
|
|
|
3099
3132
|
}
|
|
3100
3133
|
|
|
3101
3134
|
function snapCompanionsToState(e) {
|
|
3102
|
-
const t = e.
|
|
3135
|
+
const t = e.O;
|
|
3103
3136
|
if (t && (t.A === undefined || t.A === NOT_PENDING)) {
|
|
3104
3137
|
const n = computePendingState(e);
|
|
3105
|
-
if (t.
|
|
3106
|
-
t.
|
|
3138
|
+
if (t.ke !== n || t.V !== NOT_PENDING) {
|
|
3139
|
+
t.ke = n;
|
|
3107
3140
|
t.V = NOT_PENDING;
|
|
3108
|
-
t.
|
|
3141
|
+
t.W = clock;
|
|
3109
3142
|
insertSubs(t);
|
|
3110
3143
|
schedule();
|
|
3111
3144
|
}
|
|
3112
3145
|
}
|
|
3113
|
-
const n = e.
|
|
3114
|
-
if (n && !(n.
|
|
3115
|
-
if ((n.A === undefined || n.A === NOT_PENDING) && n.V === NOT_PENDING && !Object.is(n.
|
|
3116
|
-
n.
|
|
3146
|
+
const n = e.p;
|
|
3147
|
+
if (n && !(n.Ge & REACTIVE_DISPOSED)) {
|
|
3148
|
+
if ((n.A === undefined || n.A === NOT_PENDING) && n.V === NOT_PENDING && !Object.is(n.ke, e.ke) && !(n.Ge & (REACTIVE_DIRTY | REACTIVE_CHECK))) {
|
|
3149
|
+
n.Ge |= REACTIVE_DIRTY;
|
|
3117
3150
|
insertIntoHeap(n, queueFor(n));
|
|
3118
3151
|
insertSubs(n);
|
|
3119
3152
|
schedule();
|
|
@@ -3123,7 +3156,7 @@ function snapCompanionsToState(e) {
|
|
|
3123
3156
|
}
|
|
3124
3157
|
|
|
3125
3158
|
function getLatestValueComputed(e) {
|
|
3126
|
-
if (!e.
|
|
3159
|
+
if (!e.p) {
|
|
3127
3160
|
const t = latestReadActive;
|
|
3128
3161
|
setLatestReadActive(false);
|
|
3129
3162
|
const n = pendingCheckActive;
|
|
@@ -3131,21 +3164,21 @@ function getLatestValueComputed(e) {
|
|
|
3131
3164
|
const r = context;
|
|
3132
3165
|
setContextInternal(null);
|
|
3133
3166
|
// Detach from owner so it isn't disposed with effects
|
|
3134
|
-
e.
|
|
3135
|
-
e.
|
|
3167
|
+
e.p = optimisticComputed(() => read(e));
|
|
3168
|
+
e.p.t = e;
|
|
3136
3169
|
// Parent-child lane relationship
|
|
3137
3170
|
setContextInternal(r);
|
|
3138
3171
|
setPendingCheckActive(n);
|
|
3139
3172
|
setLatestReadActive(t);
|
|
3140
3173
|
}
|
|
3141
|
-
return e.
|
|
3174
|
+
return e.p;
|
|
3142
3175
|
}
|
|
3143
3176
|
|
|
3144
3177
|
/** The latest()-mode read path, installed as GlobalQueue._latestRead. */ function latestRead(e) {
|
|
3145
3178
|
const t = getLatestValueComputed(e);
|
|
3146
3179
|
const n = latestReadActive;
|
|
3147
3180
|
setLatestReadActive(false);
|
|
3148
|
-
const r = e.A !== undefined && e.A !== NOT_PENDING ? unwrapOverride(e.A) : e.
|
|
3181
|
+
const r = e.A !== undefined && e.A !== NOT_PENDING ? unwrapOverride(e.A) : e.ke;
|
|
3149
3182
|
let i;
|
|
3150
3183
|
try {
|
|
3151
3184
|
// An untracked latest() read has no reading context, so read() never
|
|
@@ -3154,18 +3187,18 @@ function getLatestValueComputed(e) {
|
|
|
3154
3187
|
// until the flush (#2922). Mirror the tracked-read pull here: mark the
|
|
3155
3188
|
// queued staleness through the graph, then bring the shadow up to date.
|
|
3156
3189
|
const e = queueFor(t);
|
|
3157
|
-
if (t.
|
|
3190
|
+
if (t.Xe >= e.P && !(t.Ge & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE))) {
|
|
3158
3191
|
markHeap(e);
|
|
3159
3192
|
prepareComputed(t, true);
|
|
3160
3193
|
}
|
|
3161
3194
|
i = read(t);
|
|
3162
3195
|
} catch (t) {
|
|
3163
|
-
if (t instanceof NotReadyError && (!context || !(e.
|
|
3196
|
+
if (t instanceof NotReadyError && (!context || !(e.Qe & STATUS_UNINITIALIZED))) return r;
|
|
3164
3197
|
throw t;
|
|
3165
3198
|
} finally {
|
|
3166
3199
|
setLatestReadActive(n);
|
|
3167
3200
|
}
|
|
3168
|
-
if (t.
|
|
3201
|
+
if (t.Qe & STATUS_PENDING) return r;
|
|
3169
3202
|
if (stale && currentOptimisticLane && t.i) {
|
|
3170
3203
|
const e = findLane(t.i);
|
|
3171
3204
|
const n = findLane(currentOptimisticLane);
|
|
@@ -3184,11 +3217,11 @@ function getLatestValueComputed(e) {
|
|
|
3184
3217
|
/** The isPending()-probe read path, installed as GlobalQueue._pendingCheck. */ function pendingCheckRead(e, t, n, r) {
|
|
3185
3218
|
setPendingCheckActive(false);
|
|
3186
3219
|
if (typeof e.Ve === "function") prepareComputed(e, true);
|
|
3187
|
-
const i = n.
|
|
3220
|
+
const i = n.Qe;
|
|
3188
3221
|
if (t && i & STATUS_PENDING && i & STATUS_UNINITIALIZED) {
|
|
3189
3222
|
if (tracking && e !== t) link(e, t);
|
|
3190
3223
|
setPendingCheckActive(true);
|
|
3191
|
-
throw n.
|
|
3224
|
+
throw n.De;
|
|
3192
3225
|
}
|
|
3193
3226
|
collectPendingSources(e);
|
|
3194
3227
|
if (r) collectPendingSources(r);
|
|
@@ -3200,10 +3233,10 @@ function recordFreshRead(e, t) {
|
|
|
3200
3233
|
}
|
|
3201
3234
|
|
|
3202
3235
|
function applyReask(e, t) {
|
|
3203
|
-
const n = !!(e.
|
|
3204
|
-
const r = t && !(n && !e.
|
|
3205
|
-
const i = n && e.
|
|
3206
|
-
e.
|
|
3236
|
+
const n = !!(e.Qe & STATUS_PENDING);
|
|
3237
|
+
const r = t && !(n && !e.ht);
|
|
3238
|
+
const i = n && e.ht !== r;
|
|
3239
|
+
e.ht = r;
|
|
3207
3240
|
return i;
|
|
3208
3241
|
}
|
|
3209
3242
|
|
|
@@ -3243,7 +3276,7 @@ function isPending(e) {
|
|
|
3243
3276
|
} catch (e) {
|
|
3244
3277
|
collectPending();
|
|
3245
3278
|
if (e instanceof NotReadyError) {
|
|
3246
|
-
const t = !!(e.source?.
|
|
3279
|
+
const t = !!(e.source?.Qe & STATUS_UNINITIALIZED);
|
|
3247
3280
|
if (r.found && !t) return true;
|
|
3248
3281
|
if (context && t) throw e;
|
|
3249
3282
|
}
|
|
@@ -3257,23 +3290,23 @@ function isPending(e) {
|
|
|
3257
3290
|
// Hook installation (same late-binding pattern as GlobalQueue._update /
|
|
3258
3291
|
// _propagateAffects): core call sites fire these behind the same guards the
|
|
3259
3292
|
// direct calls used, so behavior is identical once this module loads.
|
|
3260
|
-
GlobalQueue.
|
|
3293
|
+
GlobalQueue.ue = syncCompanions;
|
|
3261
3294
|
|
|
3262
|
-
GlobalQueue.
|
|
3295
|
+
GlobalQueue.le = updatePendingSignal;
|
|
3263
3296
|
|
|
3264
|
-
GlobalQueue.
|
|
3297
|
+
GlobalQueue.ce = updateChildCompanions;
|
|
3265
3298
|
|
|
3266
|
-
GlobalQueue.
|
|
3299
|
+
GlobalQueue.ae = snapCompanionsToState;
|
|
3267
3300
|
|
|
3268
|
-
GlobalQueue.
|
|
3301
|
+
GlobalQueue.fe = latestRead;
|
|
3269
3302
|
|
|
3270
|
-
GlobalQueue.
|
|
3303
|
+
GlobalQueue.Ee = pendingCheckRead;
|
|
3271
3304
|
|
|
3272
3305
|
GlobalQueue.de = recordFreshRead;
|
|
3273
3306
|
|
|
3274
|
-
GlobalQueue.
|
|
3307
|
+
GlobalQueue.Se = applyReask;
|
|
3275
3308
|
|
|
3276
|
-
GlobalQueue.
|
|
3309
|
+
GlobalQueue.Te = repollDownstreamVerdicts;
|
|
3277
3310
|
|
|
3278
3311
|
GlobalQueue._e = witnessAffects;
|
|
3279
3312
|
|
|
@@ -3285,16 +3318,16 @@ GlobalQueue._e = witnessAffects;
|
|
|
3285
3318
|
const i = !!r?.user;
|
|
3286
3319
|
const o = createEffectNode(e, t, n, i ? EFFECT_USER : EFFECT_RENDER, notifyEffectStatus, r);
|
|
3287
3320
|
recompute(o, true);
|
|
3288
|
-
!r?.defer && (o.
|
|
3321
|
+
!r?.defer && (o.Fe === EFFECT_USER || r?.schedule ? o.Be.enqueue(o.Fe, runEffect.bind(null, o)) : runEffect(o));
|
|
3289
3322
|
}
|
|
3290
3323
|
|
|
3291
3324
|
function notifyEffectStatus(e, t) {
|
|
3292
3325
|
// Use passed values if provided, otherwise read from node
|
|
3293
|
-
const n = e !== undefined ? e : this.
|
|
3294
|
-
const r = t !== undefined ? t : this.
|
|
3326
|
+
const n = e !== undefined ? e : this.Qe;
|
|
3327
|
+
const r = t !== undefined ? t : this.De;
|
|
3295
3328
|
if (n & STATUS_ERROR) {
|
|
3296
|
-
this.
|
|
3297
|
-
if (this.
|
|
3329
|
+
this.Be.notify(this, STATUS_PENDING, 0);
|
|
3330
|
+
if (this.Fe === EFFECT_USER) {
|
|
3298
3331
|
// The error handler is the error arm of the effect phase (#2840 ruling):
|
|
3299
3332
|
// queue it like the effect function. It runs in the same imperative,
|
|
3300
3333
|
// writable scope, throws escalate the same way, and a held transition
|
|
@@ -3304,23 +3337,23 @@ function notifyEffectStatus(e, t) {
|
|
|
3304
3337
|
// phase takes the success arm instead. Blocked forwards (explicit
|
|
3305
3338
|
// `status` arg without node-state writes) don't queue: the status
|
|
3306
3339
|
// re-propagates unblocked at commit.
|
|
3307
|
-
if (this.
|
|
3308
|
-
this.
|
|
3309
|
-
this.
|
|
3340
|
+
if (this.Qe & STATUS_ERROR) {
|
|
3341
|
+
this.xe = true;
|
|
3342
|
+
this.Be.enqueue(this.Fe, this.Pt ??= runEffect.bind(null, this));
|
|
3310
3343
|
}
|
|
3311
3344
|
return;
|
|
3312
3345
|
}
|
|
3313
|
-
if (!this.
|
|
3346
|
+
if (!this.Be.notify(this, STATUS_ERROR, STATUS_ERROR)) {
|
|
3314
3347
|
haltReactivity(unwrapStatusError(r));
|
|
3315
3348
|
throw r;
|
|
3316
3349
|
}
|
|
3317
|
-
} else if (this.
|
|
3318
|
-
this.
|
|
3350
|
+
} else if (this.Fe === EFFECT_RENDER) {
|
|
3351
|
+
this.Be.notify(this, STATUS_PENDING | STATUS_ERROR, n, r);
|
|
3319
3352
|
}
|
|
3320
3353
|
}
|
|
3321
3354
|
|
|
3322
3355
|
function runEffect(e) {
|
|
3323
|
-
if (!e.
|
|
3356
|
+
if (!e.xe || e.Ge & REACTIVE_DISPOSED) return;
|
|
3324
3357
|
// Error arm (#2840), user effects only: a compute-phase error that is still
|
|
3325
3358
|
// the node's settled state at effect time runs the bundle's error handler in
|
|
3326
3359
|
// this same imperative, writable scope. Unwrap the StatusError used for
|
|
@@ -3331,46 +3364,46 @@ function runEffect(e) {
|
|
|
3331
3364
|
// Render effects bypass: their errors route to boundaries synchronously in
|
|
3332
3365
|
// notifyEffectStatus, and a runner queued by an earlier valueChanged in the
|
|
3333
3366
|
// same flush must not be hijacked by a later-arriving error status.
|
|
3334
|
-
if (e.
|
|
3335
|
-
const t = unwrapStatusError(e.
|
|
3336
|
-
e.
|
|
3337
|
-
e.
|
|
3367
|
+
if (e.Qe & STATUS_ERROR && e.Fe === EFFECT_USER) {
|
|
3368
|
+
const t = unwrapStatusError(e.De);
|
|
3369
|
+
e.gt = e.ke;
|
|
3370
|
+
e.xe = false;
|
|
3338
3371
|
try {
|
|
3339
|
-
e.
|
|
3340
|
-
const t = e.
|
|
3341
|
-
e.
|
|
3372
|
+
e.Dt ? e.Dt(t, () => {
|
|
3373
|
+
const t = e.ft;
|
|
3374
|
+
e.ft = undefined;
|
|
3342
3375
|
t?.();
|
|
3343
3376
|
}) : console.error(t);
|
|
3344
3377
|
} catch (t) {
|
|
3345
|
-
if (!e.
|
|
3378
|
+
if (!e.Be.notify(e, STATUS_ERROR, STATUS_ERROR)) {
|
|
3346
3379
|
haltReactivity(t);
|
|
3347
3380
|
throw t;
|
|
3348
3381
|
}
|
|
3349
3382
|
}
|
|
3350
3383
|
return;
|
|
3351
3384
|
}
|
|
3352
|
-
const t = e.
|
|
3353
|
-
e.
|
|
3385
|
+
const t = e.ft;
|
|
3386
|
+
e.ft = undefined;
|
|
3354
3387
|
try {
|
|
3355
3388
|
t?.();
|
|
3356
|
-
const n = e.
|
|
3389
|
+
const n = e.bt(e.ke, e.gt);
|
|
3357
3390
|
if (false && n !== undefined && typeof n !== "function") ;
|
|
3358
3391
|
// The final cleanup is invoked by disposeChildren at true disposal.
|
|
3359
|
-
e.
|
|
3392
|
+
e.ft = n;
|
|
3360
3393
|
} catch (t) {
|
|
3361
|
-
e.
|
|
3362
|
-
e.
|
|
3363
|
-
if (!e.
|
|
3394
|
+
e.De = new StatusError(e, t);
|
|
3395
|
+
e.Qe |= STATUS_ERROR;
|
|
3396
|
+
if (!e.Be.notify(e, STATUS_ERROR, STATUS_ERROR)) {
|
|
3364
3397
|
haltReactivity(t);
|
|
3365
3398
|
throw t;
|
|
3366
3399
|
}
|
|
3367
3400
|
} finally {
|
|
3368
|
-
e.
|
|
3369
|
-
e.
|
|
3401
|
+
e.gt = e.ke;
|
|
3402
|
+
e.xe = false;
|
|
3370
3403
|
}
|
|
3371
3404
|
}
|
|
3372
3405
|
|
|
3373
|
-
GlobalQueue.
|
|
3406
|
+
GlobalQueue.J = runEffect;
|
|
3374
3407
|
|
|
3375
3408
|
/**
|
|
3376
3409
|
* Internal tracked effect - bypasses heap, goes directly to effect queue.
|
|
@@ -3378,39 +3411,39 @@ GlobalQueue.ee = runEffect;
|
|
|
3378
3411
|
* Uses stale reads.
|
|
3379
3412
|
*/ function trackedEffect(e, t) {
|
|
3380
3413
|
const run = () => {
|
|
3381
|
-
if (!n.
|
|
3414
|
+
if (!n.xe || n.Ge & REACTIVE_DISPOSED) return;
|
|
3382
3415
|
try {
|
|
3383
|
-
n.
|
|
3416
|
+
n.xe = false;
|
|
3384
3417
|
recompute(n);
|
|
3385
3418
|
} finally {}
|
|
3386
3419
|
};
|
|
3387
3420
|
const n = computed(() => {
|
|
3388
|
-
const t = n.
|
|
3389
|
-
n.
|
|
3421
|
+
const t = n.ft;
|
|
3422
|
+
n.ft = undefined;
|
|
3390
3423
|
t?.();
|
|
3391
3424
|
const r = staleValues(e);
|
|
3392
|
-
n.
|
|
3425
|
+
n.ft = r;
|
|
3393
3426
|
}, {
|
|
3394
3427
|
...t,
|
|
3395
3428
|
lazy: true
|
|
3396
3429
|
});
|
|
3397
|
-
n.
|
|
3398
|
-
n.
|
|
3399
|
-
n.
|
|
3400
|
-
n.
|
|
3401
|
-
n.
|
|
3402
|
-
const r = e !== undefined ? e : n.
|
|
3430
|
+
n.ft = undefined;
|
|
3431
|
+
n.Ue = n.Ue & ~CONFIG_AUTO_DISPOSE | CONFIG_CHILDREN_FORBIDDEN;
|
|
3432
|
+
n.xe = true;
|
|
3433
|
+
n.Fe = EFFECT_TRACKED;
|
|
3434
|
+
n.Nt = (e, t) => {
|
|
3435
|
+
const r = e !== undefined ? e : n.Qe;
|
|
3403
3436
|
if (r & STATUS_ERROR) {
|
|
3404
|
-
n.
|
|
3405
|
-
const e = t !== undefined ? t : n.
|
|
3406
|
-
if (!n.
|
|
3437
|
+
n.Be.notify(n, STATUS_PENDING, 0);
|
|
3438
|
+
const e = t !== undefined ? t : n.De;
|
|
3439
|
+
if (!n.Be.notify(n, STATUS_ERROR, STATUS_ERROR)) {
|
|
3407
3440
|
haltReactivity(unwrapStatusError(e));
|
|
3408
3441
|
throw e;
|
|
3409
3442
|
}
|
|
3410
3443
|
}
|
|
3411
3444
|
};
|
|
3412
|
-
n.
|
|
3413
|
-
n.
|
|
3445
|
+
n.Ze = run;
|
|
3446
|
+
n.Be.enqueue(EFFECT_USER, run);
|
|
3414
3447
|
}
|
|
3415
3448
|
|
|
3416
3449
|
function restoreTransition(e, t) {
|
|
@@ -3591,7 +3624,7 @@ function accessor(e) {
|
|
|
3591
3624
|
function createSignal(e, t) {
|
|
3592
3625
|
if (typeof e === "function") {
|
|
3593
3626
|
const n = computed(e, t);
|
|
3594
|
-
n.
|
|
3627
|
+
n.Ue &= ~CONFIG_AUTO_DISPOSE;
|
|
3595
3628
|
return [ accessor(n), setMemo.bind(null, n) ];
|
|
3596
3629
|
}
|
|
3597
3630
|
const n = signal(e, t);
|
|
@@ -3803,9 +3836,9 @@ function createEffect(e, t, n) {
|
|
|
3803
3836
|
// route through the inherited queue.
|
|
3804
3837
|
const i = getOwner();
|
|
3805
3838
|
const o = new MicrotaskQueue;
|
|
3806
|
-
o.
|
|
3839
|
+
o.B = i.Be;
|
|
3807
3840
|
// notify() forwards up the normal chain
|
|
3808
|
-
i.
|
|
3841
|
+
i.Be = o;
|
|
3809
3842
|
// A user effect rather than a bare computed: computeds are pull-based and
|
|
3810
3843
|
// are only re-enqueued when a pending source *resolves* — a rejection just
|
|
3811
3844
|
// marks them errored, so nothing would re-run and the promise would never
|
|
@@ -3832,7 +3865,7 @@ function createOptimistic(e, t) {
|
|
|
3832
3865
|
installOptimisticEngine();
|
|
3833
3866
|
if (typeof e === "function") {
|
|
3834
3867
|
const n = optimisticComputed(e, t);
|
|
3835
|
-
n.
|
|
3868
|
+
n.Ue &= ~CONFIG_AUTO_DISPOSE;
|
|
3836
3869
|
return [ accessor(n), setSignal.bind(null, n) ];
|
|
3837
3870
|
}
|
|
3838
3871
|
const n = optimisticSignal(e, t);
|
|
@@ -3921,7 +3954,7 @@ function createOptimistic(e, t) {
|
|
|
3921
3954
|
* on owner disposal
|
|
3922
3955
|
*/ function onSettled(e) {
|
|
3923
3956
|
const t = getOwner();
|
|
3924
|
-
t && !(t.
|
|
3957
|
+
t && !(t.Ue & CONFIG_CHILDREN_FORBIDDEN) ? createTrackedEffect(() => untrack(e), undefined) : globalQueue.enqueue(EFFECT_USER, () => {
|
|
3925
3958
|
// Unowned, out-of-band fire (no owner, or a children-forbidden one this
|
|
3926
3959
|
// one-shot must not bind to): a returned cleanup has no lifecycle to
|
|
3927
3960
|
// attach to. Reject it in dev; in production the return is simply
|
|
@@ -4075,9 +4108,9 @@ function applyArrayItem(e, t, n, r, i) {
|
|
|
4075
4108
|
if (!isWrappable(f)) continue;
|
|
4076
4109
|
const E = (u.get(f) ?? storeLookup.get(f))?.[$TARGET];
|
|
4077
4110
|
if (!E?.[STORE_DESC]) continue;
|
|
4078
|
-
const
|
|
4079
|
-
if (f ===
|
|
4080
|
-
applyState(
|
|
4111
|
+
const d = unwrap(t[a]);
|
|
4112
|
+
if (f === d || !isWrappable(d) || Array.isArray(f) !== Array.isArray(d) || i(f) != null && i(f) !== i(d)) continue;
|
|
4113
|
+
applyState(d, wrap(f, n), i);
|
|
4081
4114
|
}
|
|
4082
4115
|
}
|
|
4083
4116
|
|
|
@@ -4111,11 +4144,11 @@ function applyStateFast(e, t, n) {
|
|
|
4111
4144
|
let o = false;
|
|
4112
4145
|
const s = r.length;
|
|
4113
4146
|
if (e.length && s && isWrappable(e[0]) && n(e[0]) != null) {
|
|
4114
|
-
let u, l, c, a, f, E,
|
|
4147
|
+
let u, l, c, a, f, E, d, S;
|
|
4115
4148
|
for (c = 0, a = Math.min(s, e.length); c < a && keyedMatch(E = r[c], e[c], n); c++) {
|
|
4116
4149
|
isWrappable(E) && isWrappable(e[c]) && applyState(e[c], wrap(E, t), n);
|
|
4117
4150
|
}
|
|
4118
|
-
const T = new Array(e.length),
|
|
4151
|
+
const T = new Array(e.length), _ = new Map;
|
|
4119
4152
|
for (a = s - 1, f = e.length - 1; a >= c && f >= c && keyedMatch(E = r[a], e[f], n); a--,
|
|
4120
4153
|
f--) {
|
|
4121
4154
|
T[f] = E;
|
|
@@ -4134,22 +4167,22 @@ function applyStateFast(e, t, n) {
|
|
|
4134
4167
|
s !== e.length && i?.length && setSignal(i.length, e.length);
|
|
4135
4168
|
return;
|
|
4136
4169
|
}
|
|
4137
|
-
|
|
4170
|
+
d = new Array(f + 1);
|
|
4138
4171
|
for (l = f; l >= c; l--) {
|
|
4139
4172
|
E = e[l];
|
|
4140
|
-
|
|
4141
|
-
u =
|
|
4142
|
-
|
|
4143
|
-
|
|
4173
|
+
S = itemKey(E, n);
|
|
4174
|
+
u = _.get(S);
|
|
4175
|
+
d[l] = u === undefined ? -1 : u;
|
|
4176
|
+
_.set(S, l);
|
|
4144
4177
|
}
|
|
4145
4178
|
for (u = c; u <= a; u++) {
|
|
4146
4179
|
E = r[u];
|
|
4147
|
-
|
|
4148
|
-
l =
|
|
4180
|
+
S = itemKey(E, n);
|
|
4181
|
+
l = _.get(S);
|
|
4149
4182
|
if (l !== undefined && l !== -1) {
|
|
4150
4183
|
T[l] = E;
|
|
4151
|
-
l =
|
|
4152
|
-
|
|
4184
|
+
l = d[l];
|
|
4185
|
+
_.set(S, l);
|
|
4153
4186
|
}
|
|
4154
4187
|
}
|
|
4155
4188
|
for (l = c; l < e.length; l++) {
|
|
@@ -4180,17 +4213,18 @@ function applyStateFast(e, t, n) {
|
|
|
4180
4213
|
let s;
|
|
4181
4214
|
if (o) {
|
|
4182
4215
|
s = o[$TRACK];
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4216
|
+
if (s || symbolKeyedRecords.has(o)) {
|
|
4217
|
+
const i = s ? getAllKeys(r, undefined, e) : nodeKeys(o);
|
|
4218
|
+
for (let u = 0, l = i.length; u < l; u++) {
|
|
4219
|
+
diffNodeKey(i[u], o, r, e, t, s, n);
|
|
4220
|
+
}
|
|
4221
|
+
} else {
|
|
4222
|
+
// Untracked, string-only node records (the overwhelmingly common case)
|
|
4223
|
+
// iterate in place — nodeKeys() allocated a fresh key array per object
|
|
4224
|
+
// per pass, which dominates allocation on large-graph reconciles.
|
|
4225
|
+
for (const i in o) {
|
|
4226
|
+
diffNodeKey(i, o, r, e, t, s, n);
|
|
4227
|
+
}
|
|
4194
4228
|
}
|
|
4195
4229
|
}
|
|
4196
4230
|
if (!s && t[STORE_DESC]) applyDescendants(r, e, t, o, n);
|
|
@@ -4204,6 +4238,19 @@ function applyStateFast(e, t, n) {
|
|
|
4204
4238
|
}
|
|
4205
4239
|
}
|
|
4206
4240
|
|
|
4241
|
+
// One node-key step of the fast object diff — shared by the array-iterating
|
|
4242
|
+
// (tracked / symbol-keyed) and for-in (plain) loops in applyStateFast.
|
|
4243
|
+
function diffNodeKey(e, t, n, r, i, o, s) {
|
|
4244
|
+
const u = t[e];
|
|
4245
|
+
const l = unwrap(n[e]);
|
|
4246
|
+
let c = unwrap(r[e]);
|
|
4247
|
+
if (l === c) return;
|
|
4248
|
+
if (!l || !isWrappable(l) || !isWrappable(c) || Array.isArray(l) !== Array.isArray(c) || s(l) != null && s(l) !== s(c)) {
|
|
4249
|
+
o && setSignal(o, void 0);
|
|
4250
|
+
u && setSignal(u, isWrappable(c) ? wrap(c, i) : c);
|
|
4251
|
+
} else applyState(c, wrap(l, i), s);
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4207
4254
|
function applyStateSlow(e, t, n) {
|
|
4208
4255
|
const r = t[STORE_VALUE];
|
|
4209
4256
|
const i = t[STORE_OVERRIDE];
|
|
@@ -4218,23 +4265,23 @@ function applyStateSlow(e, t, n) {
|
|
|
4218
4265
|
let u = false;
|
|
4219
4266
|
const l = getOverrideValue(r, i, "length", o);
|
|
4220
4267
|
if (e.length && l && isWrappable(e[0]) && n(e[0]) != null) {
|
|
4221
|
-
let c, a, f, E,
|
|
4222
|
-
for (f = 0, E = Math.min(l, e.length); f < E && keyedMatch(
|
|
4223
|
-
isWrappable(
|
|
4268
|
+
let c, a, f, E, d, S, T, _;
|
|
4269
|
+
for (f = 0, E = Math.min(l, e.length); f < E && keyedMatch(S = getOverrideValue(r, i, f, o), e[f], n); f++) {
|
|
4270
|
+
isWrappable(S) && isWrappable(e[f]) && applyState(e[f], wrap(S, t), n);
|
|
4224
4271
|
}
|
|
4225
|
-
const
|
|
4226
|
-
for (E = l - 1,
|
|
4227
|
-
|
|
4228
|
-
|
|
4272
|
+
const O = new Array(e.length), p = new Map;
|
|
4273
|
+
for (E = l - 1, d = e.length - 1; E >= f && d >= f && keyedMatch(S = getOverrideValue(r, i, E, o), e[d], n); E--,
|
|
4274
|
+
d--) {
|
|
4275
|
+
O[d] = S;
|
|
4229
4276
|
}
|
|
4230
|
-
if (f >
|
|
4231
|
-
for (a = f; a <=
|
|
4277
|
+
if (f > d || f > E) {
|
|
4278
|
+
for (a = f; a <= d; a++) {
|
|
4232
4279
|
u = true;
|
|
4233
4280
|
s?.[a] && setSignal(s[a], wrapValue(e[a], t));
|
|
4234
4281
|
}
|
|
4235
4282
|
for (;a < e.length; a++) {
|
|
4236
4283
|
u = true;
|
|
4237
|
-
applyArrayItem(e[a],
|
|
4284
|
+
applyArrayItem(e[a], O[a], t, s?.[a], n);
|
|
4238
4285
|
}
|
|
4239
4286
|
const r = e.length;
|
|
4240
4287
|
syncArrayNodeMembership(t, e);
|
|
@@ -4242,27 +4289,27 @@ function applyStateSlow(e, t, n) {
|
|
|
4242
4289
|
l !== r && s?.length && setSignal(s.length, r);
|
|
4243
4290
|
return;
|
|
4244
4291
|
}
|
|
4245
|
-
T = new Array(
|
|
4246
|
-
for (a =
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
c =
|
|
4292
|
+
T = new Array(d + 1);
|
|
4293
|
+
for (a = d; a >= f; a--) {
|
|
4294
|
+
S = e[a];
|
|
4295
|
+
_ = itemKey(S, n);
|
|
4296
|
+
c = p.get(_);
|
|
4250
4297
|
T[a] = c === undefined ? -1 : c;
|
|
4251
|
-
|
|
4298
|
+
p.set(_, a);
|
|
4252
4299
|
}
|
|
4253
4300
|
for (c = f; c <= E; c++) {
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
a =
|
|
4301
|
+
S = getOverrideValue(r, i, c, o);
|
|
4302
|
+
_ = itemKey(S, n);
|
|
4303
|
+
a = p.get(_);
|
|
4257
4304
|
if (a !== undefined && a !== -1) {
|
|
4258
|
-
|
|
4305
|
+
O[a] = S;
|
|
4259
4306
|
a = T[a];
|
|
4260
|
-
|
|
4307
|
+
p.set(_, a);
|
|
4261
4308
|
}
|
|
4262
4309
|
}
|
|
4263
4310
|
for (a = f; a < e.length; a++) {
|
|
4264
|
-
if (a in
|
|
4265
|
-
applyArrayItem(e[a],
|
|
4311
|
+
if (a in O) {
|
|
4312
|
+
applyArrayItem(e[a], O[a], t, s?.[a], n);
|
|
4266
4313
|
} else s?.[a] && setSignal(s[a], wrapValue(e[a], t));
|
|
4267
4314
|
}
|
|
4268
4315
|
if (f < e.length) u = true;
|
|
@@ -4293,12 +4340,12 @@ function applyStateSlow(e, t, n) {
|
|
|
4293
4340
|
const a = l[c];
|
|
4294
4341
|
const f = s[a];
|
|
4295
4342
|
const E = unwrap(getOverrideValue(r, i, a, o));
|
|
4296
|
-
let
|
|
4297
|
-
if (E ===
|
|
4298
|
-
if (!E || !isWrappable(E) || !isWrappable(
|
|
4343
|
+
let d = unwrap(e[a]);
|
|
4344
|
+
if (E === d) continue;
|
|
4345
|
+
if (!E || !isWrappable(E) || !isWrappable(d) || Array.isArray(E) !== Array.isArray(d) || n(E) != null && n(E) !== n(d)) {
|
|
4299
4346
|
u && setSignal(u, void 0);
|
|
4300
|
-
f && setSignal(f, isWrappable(
|
|
4301
|
-
} else applyState(
|
|
4347
|
+
f && setSignal(f, isWrappable(d) ? wrap(d, t) : d);
|
|
4348
|
+
} else applyState(d, wrap(E, t), n);
|
|
4302
4349
|
}
|
|
4303
4350
|
}
|
|
4304
4351
|
if (!u && t[STORE_DESC]) applyDescendants(r, e, t, s, n, i, o);
|
|
@@ -4312,17 +4359,27 @@ function applyStateSlow(e, t, n) {
|
|
|
4312
4359
|
}
|
|
4313
4360
|
}
|
|
4314
4361
|
|
|
4362
|
+
// No-key reconcile: every item reports "no key", which routes array diffs to
|
|
4363
|
+
// the positional branch and object descent to plain per-property merging.
|
|
4364
|
+
const NOKEY = () => null;
|
|
4365
|
+
|
|
4315
4366
|
/**
|
|
4316
4367
|
* Returns a draft-mutating function that smart-merges `value` into a store,
|
|
4317
|
-
* preserving
|
|
4318
|
-
* new states. Useful when applying server payloads or full-replacement data
|
|
4319
|
-
* onto an existing store without losing fine-grained reactivity.
|
|
4368
|
+
* preserving fine-grained reactivity: only changed leaves trigger updates.
|
|
4320
4369
|
*
|
|
4321
|
-
*
|
|
4322
|
-
*
|
|
4370
|
+
* With a `key` (default `"id"`), array items whose key matches between old
|
|
4371
|
+
* and new states keep their identity (updated in place, moves and removals
|
|
4372
|
+
* update the corresponding signals) — the shape for keyed server payloads.
|
|
4373
|
+
* Items without the key field fall back to positional matching.
|
|
4374
|
+
*
|
|
4375
|
+
* With `key: null`, matching is purely positional: index N of the new array
|
|
4376
|
+
* merges into index N of the old, and object properties merge recursively —
|
|
4377
|
+
* the classic pattern for fixed-shape data that churns in place (dashboards,
|
|
4378
|
+
* monitors), where no keyed diff pass is needed or wanted.
|
|
4323
4379
|
*
|
|
4324
4380
|
* @param value the next state to merge in
|
|
4325
|
-
* @param key property name (string) or extractor function for stable
|
|
4381
|
+
* @param key property name (string) or extractor function for stable
|
|
4382
|
+
* identity (default `"id"`); pass `null` for positional merging
|
|
4326
4383
|
*
|
|
4327
4384
|
* @example
|
|
4328
4385
|
* ```ts
|
|
@@ -4330,12 +4387,19 @@ function applyStateSlow(e, t, n) {
|
|
|
4330
4387
|
*
|
|
4331
4388
|
* async function refresh() {
|
|
4332
4389
|
* const fresh = await api.getTodos();
|
|
4333
|
-
* setTodos(reconcile(fresh
|
|
4390
|
+
* setTodos(reconcile(fresh)); // diff-merge by `id`
|
|
4334
4391
|
* }
|
|
4392
|
+
*
|
|
4393
|
+
* // fixed-shape polling data — positional merge
|
|
4394
|
+
* setStats(reconcile(nextStats, null));
|
|
4335
4395
|
* ```
|
|
4336
|
-
*/ function reconcile(e, t) {
|
|
4396
|
+
*/ function reconcile(e, t = "id") {
|
|
4337
4397
|
return n => {
|
|
4338
4398
|
if (n == null) throw new Error("");
|
|
4399
|
+
if (t === null) {
|
|
4400
|
+
applyState(e, n, NOKEY);
|
|
4401
|
+
return;
|
|
4402
|
+
}
|
|
4339
4403
|
const r = typeof t === "string" ? e => e[t] : t;
|
|
4340
4404
|
const i = r(n);
|
|
4341
4405
|
if (i !== undefined && r(e) !== i) throw new Error("");
|
|
@@ -4368,7 +4432,7 @@ function createProjectionInternal(e, t, n) {
|
|
|
4368
4432
|
if (!r) r = getOwner();
|
|
4369
4433
|
runProjectionComputed(o, e, n?.key || "id");
|
|
4370
4434
|
}, undefined);
|
|
4371
|
-
r.
|
|
4435
|
+
r.Ue &= ~CONFIG_AUTO_DISPOSE;
|
|
4372
4436
|
return {
|
|
4373
4437
|
store: o,
|
|
4374
4438
|
node: r
|
|
@@ -4437,7 +4501,7 @@ function createProjectionInternal(e, t, n) {
|
|
|
4437
4501
|
const o = getOwner();
|
|
4438
4502
|
let s = false;
|
|
4439
4503
|
let u;
|
|
4440
|
-
const l = new Proxy(e, createWriteTraps(() => !s || o.
|
|
4504
|
+
const l = new Proxy(e, createWriteTraps(() => !s || o.ut === u, i));
|
|
4441
4505
|
storeSetter(l, i => {
|
|
4442
4506
|
u = t(i);
|
|
4443
4507
|
s = true;
|
|
@@ -4522,15 +4586,40 @@ const STORE_VALUE = "v", STORE_OVERRIDE = "o", STORE_OPTIMISTIC_OVERRIDE = "x",
|
|
|
4522
4586
|
|
|
4523
4587
|
const STORE_SELF_PENDING = Symbol(0);
|
|
4524
4588
|
|
|
4589
|
+
// Every StoreNode field is initialized up front, in one fixed order, so all
|
|
4590
|
+
// targets share a single hidden class. The traps and reconcile read these
|
|
4591
|
+
// fields on their hottest paths; fields added lazily in varying orders made
|
|
4592
|
+
// those loads megamorphic across a large store graph (dictionary-mode probes
|
|
4593
|
+
// on every trap hit). Assignments elsewhere must never `delete` a field —
|
|
4594
|
+
// write `undefined` instead, or the shape degrades again.
|
|
4595
|
+
function initStoreFields(e) {
|
|
4596
|
+
e[STORE_OVERRIDE] = undefined;
|
|
4597
|
+
e[STORE_OPTIMISTIC_OVERRIDE] = undefined;
|
|
4598
|
+
e[STORE_OPTIMISTIC_OWNERS] = undefined;
|
|
4599
|
+
e[STORE_NODE] = undefined;
|
|
4600
|
+
e[STORE_HAS] = undefined;
|
|
4601
|
+
e[STORE_CUSTOM_PROTO] = undefined;
|
|
4602
|
+
e[STORE_WRAP] = undefined;
|
|
4603
|
+
e[STORE_LOOKUP] = undefined;
|
|
4604
|
+
e[STORE_FIREWALL] = undefined;
|
|
4605
|
+
e[STORE_OPTIMISTIC] = undefined;
|
|
4606
|
+
e[STORE_SNAPSHOT_PROPS] = undefined;
|
|
4607
|
+
e[STORE_PARENT] = undefined;
|
|
4608
|
+
e[STORE_DESC] = undefined;
|
|
4609
|
+
e[$PROXY] = null;
|
|
4610
|
+
}
|
|
4611
|
+
|
|
4525
4612
|
function createStoreProxy(e, t = storeTraps, n) {
|
|
4526
4613
|
let r;
|
|
4527
4614
|
if (Array.isArray(e)) {
|
|
4528
4615
|
r = [];
|
|
4529
|
-
r
|
|
4616
|
+
r[STORE_VALUE] = e;
|
|
4617
|
+
initStoreFields(r);
|
|
4530
4618
|
} else {
|
|
4531
4619
|
r = {
|
|
4532
|
-
|
|
4620
|
+
[STORE_VALUE]: e
|
|
4533
4621
|
};
|
|
4622
|
+
initStoreFields(r);
|
|
4534
4623
|
const t = e?.[$TARGET]?.[STORE_VALUE] ?? e;
|
|
4535
4624
|
const n = Object.getPrototypeOf(t);
|
|
4536
4625
|
if (n !== null && n !== Object.prototype) {
|
|
@@ -4644,7 +4733,7 @@ function ownEnumerableKeysPlain(e) {
|
|
|
4644
4733
|
* The value a store leaf's backing signal currently shows to readers: active
|
|
4645
4734
|
* override, else held pending value, else committed value.
|
|
4646
4735
|
*/ function visibleNodeValue(e) {
|
|
4647
|
-
return e.A !== undefined && e.A !== NOT_PENDING ? unwrapOverride(e.A) : e.V !== NOT_PENDING ? e.V : e.
|
|
4736
|
+
return e.A !== undefined && e.A !== NOT_PENDING ? unwrapOverride(e.A) : e.V !== NOT_PENDING ? e.V : e.ke;
|
|
4648
4737
|
}
|
|
4649
4738
|
|
|
4650
4739
|
function hasOwnStoreProperty(e, t) {
|
|
@@ -4699,7 +4788,7 @@ function getNode(e, t, n, r, i = isEqual, o) {
|
|
|
4699
4788
|
}
|
|
4700
4789
|
if (o && n in o) {
|
|
4701
4790
|
const e = o[n];
|
|
4702
|
-
s.
|
|
4791
|
+
s.ve = e === undefined ? NO_SNAPSHOT : e;
|
|
4703
4792
|
snapshotSources?.add(s);
|
|
4704
4793
|
}
|
|
4705
4794
|
if (typeof n === "symbol" && n !== $TRACK && n !== $AFFECTS) symbolKeyedRecords.add(t);
|
|
@@ -4728,8 +4817,8 @@ function getNode(e, t, n, r, i = isEqual, o) {
|
|
|
4728
4817
|
*/ function inheritAffectsMarks(e, t, n) {
|
|
4729
4818
|
// A live scope exists, so affects.ts already installed the mark engine.
|
|
4730
4819
|
for (const [r, i] of affectsScopes) {
|
|
4731
|
-
if (r.
|
|
4732
|
-
GlobalQueue.
|
|
4820
|
+
if (r.k && i.scope.has(t) && (i.key === undefined || i.key === n)) {
|
|
4821
|
+
GlobalQueue.re(e);
|
|
4733
4822
|
i.inherited.push(e);
|
|
4734
4823
|
}
|
|
4735
4824
|
}
|
|
@@ -4817,11 +4906,11 @@ i) {
|
|
|
4817
4906
|
// Callers guard on `pendingCheckActive`, which only flips inside
|
|
4818
4907
|
// isPending() — the verdict layer is loaded and its hook installed.
|
|
4819
4908
|
const n = e[STORE_NODE]?.[$AFFECTS];
|
|
4820
|
-
if (n?.
|
|
4909
|
+
if (n?.k) GlobalQueue._e(n);
|
|
4821
4910
|
if (affectsScopes.size) {
|
|
4822
4911
|
const r = e[STORE_VALUE];
|
|
4823
4912
|
for (const [e, i] of affectsScopes) {
|
|
4824
|
-
if (e !== n && e.
|
|
4913
|
+
if (e !== n && e.k && i.scope.has(r) && (i.key === undefined || i.key === t)) GlobalQueue._e(e);
|
|
4825
4914
|
}
|
|
4826
4915
|
}
|
|
4827
4916
|
}
|
|
@@ -4838,11 +4927,11 @@ i) {
|
|
|
4838
4927
|
* @internal
|
|
4839
4928
|
*/ function getStoreAffectsNodes(e, t) {
|
|
4840
4929
|
const n = getNodes(e, STORE_NODE);
|
|
4841
|
-
GlobalQueue.
|
|
4930
|
+
GlobalQueue.te ||= e => {
|
|
4842
4931
|
const t = affectsScopes.get(e);
|
|
4843
4932
|
if (!t) return;
|
|
4844
4933
|
affectsScopes.delete(e);
|
|
4845
|
-
for (let e = 0; e < t.inherited.length; e++) GlobalQueue.
|
|
4934
|
+
for (let e = 0; e < t.inherited.length; e++) GlobalQueue.ie(t.inherited[e]);
|
|
4846
4935
|
};
|
|
4847
4936
|
if (t === undefined) {
|
|
4848
4937
|
const t = getNode(e, n, $AFFECTS, undefined, false);
|
|
@@ -4969,7 +5058,7 @@ function prepareStoreWrite(e, t, n) {
|
|
|
4969
5058
|
}
|
|
4970
5059
|
const r = e[STORE_VALUE];
|
|
4971
5060
|
const i = r[n];
|
|
4972
|
-
if (snapshotCaptureActive && typeof n !== "symbol" && !((e[STORE_FIREWALL]?.
|
|
5061
|
+
if (snapshotCaptureActive && typeof n !== "symbol" && !((e[STORE_FIREWALL]?.Qe ?? 0) & STATUS_PENDING)) {
|
|
4973
5062
|
if (!e[STORE_SNAPSHOT_PROPS]) {
|
|
4974
5063
|
e[STORE_SNAPSHOT_PROPS] = Object.create(null);
|
|
4975
5064
|
snapshotSources?.add(e);
|
|
@@ -4997,7 +5086,7 @@ function prepareStoreWrite(e, t, n) {
|
|
|
4997
5086
|
// STORE_OPTIMISTIC is only set by createOptimisticStore, which installs the
|
|
4998
5087
|
// optimistic engine before wrapping.
|
|
4999
5088
|
if (e[STORE_OPTIMISTIC] && !projectionWriteActive) {
|
|
5000
|
-
GlobalQueue.
|
|
5089
|
+
GlobalQueue.be(t);
|
|
5001
5090
|
}
|
|
5002
5091
|
}
|
|
5003
5092
|
|
|
@@ -5070,7 +5159,7 @@ let Writing = null;
|
|
|
5070
5159
|
* itself (the derive function works its own draft while uninitialized).
|
|
5071
5160
|
*/ function throwIfUninitialized(e) {
|
|
5072
5161
|
const t = e[STORE_FIREWALL];
|
|
5073
|
-
if (t && t.
|
|
5162
|
+
if (t && t.Qe & STATUS_UNINITIALIZED) throw t.De ?? new NotReadyError(t);
|
|
5074
5163
|
}
|
|
5075
5164
|
|
|
5076
5165
|
const storeTraps = {
|
|
@@ -5083,6 +5172,21 @@ const storeTraps = {
|
|
|
5083
5172
|
trackSelf(e);
|
|
5084
5173
|
return n;
|
|
5085
5174
|
}
|
|
5175
|
+
// Hot path: an existing node on a plain target — no firewall (so neither
|
|
5176
|
+
// selfRead nor the uninitialized guard can apply), no override layers,
|
|
5177
|
+
// no write scope, and a raw (non-proxy) source. This is the shape of
|
|
5178
|
+
// every effect re-read of a settled store; it pays one node read and the
|
|
5179
|
+
// wrap check, nothing else. Any exotic bit falls through to the full
|
|
5180
|
+
// resolution below, and dev strictRead keeps its warning path.
|
|
5181
|
+
if (e[STORE_FIREWALL] === undefined && e[STORE_OVERRIDE] === undefined && e[STORE_OPTIMISTIC_OVERRIDE] === undefined && !writeOverride && (Writing === null || !Writing.has(n))) {
|
|
5182
|
+
const n = e[STORE_NODE];
|
|
5183
|
+
const r = n && n[t];
|
|
5184
|
+
if (r !== undefined && e[STORE_VALUE][$TARGET] === undefined) {
|
|
5185
|
+
let t = read(r);
|
|
5186
|
+
if (t === $DELETED) t = undefined;
|
|
5187
|
+
return isWrappable(t) ? wrap(t, e) : t;
|
|
5188
|
+
}
|
|
5189
|
+
}
|
|
5086
5190
|
const r = getObserver() === e[STORE_FIREWALL];
|
|
5087
5191
|
const i = getNodes(e, STORE_NODE);
|
|
5088
5192
|
const o = r ? undefined : i[t];
|
|
@@ -5163,9 +5267,9 @@ const storeTraps = {
|
|
|
5163
5267
|
// throws). #2769
|
|
5164
5268
|
const f = typeof t === "string" ? Number(t) : -1;
|
|
5165
5269
|
const E = Array.isArray(s) && Number.isInteger(f) && f >= 0 && f < 4294967295 && String(f) === t;
|
|
5166
|
-
const
|
|
5167
|
-
const
|
|
5168
|
-
const T = E &&
|
|
5270
|
+
const d = E ? f + 1 : 0;
|
|
5271
|
+
const S = E && (getOverlayLayer(e, "length") ?? s).length;
|
|
5272
|
+
const T = E && d > S ? d : undefined;
|
|
5169
5273
|
if (l === a && T === undefined) return true;
|
|
5170
5274
|
armOptimisticStoreWrite(e, r);
|
|
5171
5275
|
if (a !== undefined && a === i && T === undefined) {
|
|
@@ -5201,7 +5305,7 @@ const storeTraps = {
|
|
|
5201
5305
|
if (t.length) {
|
|
5202
5306
|
setSignal(t.length, T);
|
|
5203
5307
|
} else if (!projectionWriteActive && !e[STORE_OPTIMISTIC]) {
|
|
5204
|
-
const n = upsertStoreNode(e, t, "length",
|
|
5308
|
+
const n = upsertStoreNode(e, t, "length", S, e[STORE_SNAPSHOT_PROPS]);
|
|
5205
5309
|
setSignal(n, T);
|
|
5206
5310
|
}
|
|
5207
5311
|
}
|
|
@@ -5365,7 +5469,7 @@ function createStore(e, t, n) {
|
|
|
5365
5469
|
* nothing is stored downstream and nothing can be stranded or stripped by
|
|
5366
5470
|
* mid-window recomputes.
|
|
5367
5471
|
*/ function markAffects(e) {
|
|
5368
|
-
e.
|
|
5472
|
+
e.k = (e.k || 0) + 1;
|
|
5369
5473
|
shiftAffectsMarks(1);
|
|
5370
5474
|
}
|
|
5371
5475
|
|
|
@@ -5381,17 +5485,17 @@ function createStore(e, t, n) {
|
|
|
5381
5485
|
* flush that would surface them, before effects run — verdict-only, netting
|
|
5382
5486
|
* no visual change.
|
|
5383
5487
|
*/ function notifyMarkBoundaries(e) {
|
|
5384
|
-
if (!e.
|
|
5488
|
+
if (!e.U && !e.nt) return;
|
|
5385
5489
|
const t = new NotReadyError(e);
|
|
5386
|
-
t.
|
|
5490
|
+
t.me = true;
|
|
5387
5491
|
const n = new Set;
|
|
5388
5492
|
const visit = e => {
|
|
5389
5493
|
if (n.has(e)) return;
|
|
5390
5494
|
n.add(e);
|
|
5391
5495
|
// Display consumers (render effects, boundary computeds) act on the
|
|
5392
5496
|
// notification; descent stops there, exactly like the status rails.
|
|
5393
|
-
if (e.
|
|
5394
|
-
e.
|
|
5497
|
+
if (e.Nt) {
|
|
5498
|
+
e.Nt(STATUS_PENDING, t);
|
|
5395
5499
|
return;
|
|
5396
5500
|
}
|
|
5397
5501
|
forEachDependent(e, visit);
|
|
@@ -5409,10 +5513,10 @@ function createStore(e, t, n) {
|
|
|
5409
5513
|
* earlier overlapping registration get covered, and dedup stops re-descent.
|
|
5410
5514
|
*/ function registerAffectsMark(e) {
|
|
5411
5515
|
markAffects(e);
|
|
5412
|
-
globalQueue.D.
|
|
5516
|
+
globalQueue.D.G.push(e);
|
|
5413
5517
|
// Companions only exist once the verdict layer (isPending/latest) loaded;
|
|
5414
5518
|
// without them there is no materialized verdict to poke.
|
|
5415
|
-
GlobalQueue.
|
|
5519
|
+
GlobalQueue.Te !== null && GlobalQueue.Te(e);
|
|
5416
5520
|
notifyMarkBoundaries(e);
|
|
5417
5521
|
schedule();
|
|
5418
5522
|
}
|
|
@@ -5424,10 +5528,10 @@ function createStore(e, t, n) {
|
|
|
5424
5528
|
* setSignal would open a fresh override window that nothing settles).
|
|
5425
5529
|
*/ function releaseAffectsMark(e) {
|
|
5426
5530
|
shiftAffectsMarks(-1);
|
|
5427
|
-
e.
|
|
5428
|
-
if (!e.
|
|
5429
|
-
GlobalQueue.
|
|
5430
|
-
GlobalQueue.
|
|
5531
|
+
e.k--;
|
|
5532
|
+
if (!e.k) {
|
|
5533
|
+
GlobalQueue.Te !== null && GlobalQueue.Te(e, true);
|
|
5534
|
+
GlobalQueue.te?.(e);
|
|
5431
5535
|
}
|
|
5432
5536
|
}
|
|
5433
5537
|
|
|
@@ -5444,11 +5548,11 @@ function createStore(e, t, n) {
|
|
|
5444
5548
|
// Each call site is gated by state only this module creates (a non-empty
|
|
5445
5549
|
// `_affectsNodes` batch, a live scope in the store's `affectsScopes`), so the
|
|
5446
5550
|
// hooks are installed before the first time any of them can fire.
|
|
5447
|
-
GlobalQueue.
|
|
5551
|
+
GlobalQueue.ne = releaseAffectsMarks;
|
|
5448
5552
|
|
|
5449
|
-
GlobalQueue.
|
|
5553
|
+
GlobalQueue.re = markAffects;
|
|
5450
5554
|
|
|
5451
|
-
GlobalQueue.
|
|
5555
|
+
GlobalQueue.ie = releaseAffectsMark;
|
|
5452
5556
|
|
|
5453
5557
|
function affects(e, t) {
|
|
5454
5558
|
const n = e?.[$TARGET];
|
|
@@ -5469,7 +5573,7 @@ function createOptimisticStore(e, t, n) {
|
|
|
5469
5573
|
// STORE_OPTIMISTIC take the engine's write path, so install it before any
|
|
5470
5574
|
// node can be created.
|
|
5471
5575
|
installOptimisticEngine();
|
|
5472
|
-
GlobalQueue.
|
|
5576
|
+
GlobalQueue.ee ||= clearOptimisticStores;
|
|
5473
5577
|
const r = typeof e === "function";
|
|
5474
5578
|
const i = r ? t : e;
|
|
5475
5579
|
const o = r ? e : undefined;
|
|
@@ -5548,16 +5652,18 @@ function clearOptimisticStores(e, t) {
|
|
|
5548
5652
|
c.A = NOT_PENDING;
|
|
5549
5653
|
c.R = null;
|
|
5550
5654
|
c.V = NOT_PENDING;
|
|
5551
|
-
c.
|
|
5552
|
-
if (!c.
|
|
5655
|
+
c.ke = i;
|
|
5656
|
+
if (!c.At || !c.At(o, i)) {
|
|
5553
5657
|
insertSubs(c, true);
|
|
5554
5658
|
schedule();
|
|
5555
5659
|
}
|
|
5556
5660
|
}
|
|
5557
5661
|
}
|
|
5558
5662
|
if (!u) {
|
|
5559
|
-
delete
|
|
5560
|
-
delete
|
|
5663
|
+
// Assignment, not delete: StoreNode targets share one pre-initialized
|
|
5664
|
+
// hidden class (see createStoreProxy) and a delete would demote it.
|
|
5665
|
+
e[STORE_OPTIMISTIC_OVERRIDE] = undefined;
|
|
5666
|
+
e[STORE_OPTIMISTIC_OWNERS] = undefined;
|
|
5561
5667
|
}
|
|
5562
5668
|
// Notify $TRACK
|
|
5563
5669
|
if (s && r?.[$TRACK]) {
|
|
@@ -5621,7 +5727,7 @@ function createOptimisticProjectionInternal(e, t, n) {
|
|
|
5621
5727
|
setProjectionWriteActive(false);
|
|
5622
5728
|
}
|
|
5623
5729
|
}, undefined);
|
|
5624
|
-
r.
|
|
5730
|
+
r.Ue &= ~CONFIG_AUTO_DISPOSE;
|
|
5625
5731
|
}
|
|
5626
5732
|
return {
|
|
5627
5733
|
store: o,
|
|
@@ -5742,6 +5848,18 @@ function snapshotImpl(e, t, n, r) {
|
|
|
5742
5848
|
if (pendingCheckActive) witnessAffectsMark(i);
|
|
5743
5849
|
}
|
|
5744
5850
|
s = mergedOverlay(i);
|
|
5851
|
+
// A derived store's STORE_VALUE is the inner store's live proxy
|
|
5852
|
+
// (store-in-store: createOptimisticStore/createProjection over a store).
|
|
5853
|
+
// Without an overlay of its own, the fast path below would map to — and
|
|
5854
|
+
// could return — that proxy verbatim. Recurse instead so the
|
|
5855
|
+
// inner store's own target branch unwraps it (chains of any depth).
|
|
5856
|
+
// With an overlay, a fresh `result` is always built, so the walk over the
|
|
5857
|
+
// inner proxy already copies plain values.
|
|
5858
|
+
if (!s && i[STORE_VALUE][$TARGET]) {
|
|
5859
|
+
l = snapshotImpl(i[STORE_VALUE], t, n, r);
|
|
5860
|
+
n.set(e, l);
|
|
5861
|
+
return l;
|
|
5862
|
+
}
|
|
5745
5863
|
o = Array.isArray(i[STORE_VALUE]);
|
|
5746
5864
|
n.set(e, s ? u = o ? [] : Object.create(Object.getPrototypeOf(i[STORE_VALUE])) : i[STORE_VALUE]);
|
|
5747
5865
|
e = i[STORE_VALUE];
|
|
@@ -6033,24 +6151,24 @@ function mapArray(e, t, n) {
|
|
|
6033
6151
|
const i = t.length > 1;
|
|
6034
6152
|
const o = t;
|
|
6035
6153
|
const s = {
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6154
|
+
vt: createOwner(),
|
|
6155
|
+
wt: 0,
|
|
6156
|
+
Gt: e,
|
|
6157
|
+
Lt: [],
|
|
6158
|
+
Ut: o,
|
|
6041
6159
|
Vt: [],
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6160
|
+
kt: [],
|
|
6161
|
+
Ft: r,
|
|
6162
|
+
xt: r || n?.keyed === false ? [] : undefined,
|
|
6163
|
+
Qt: i && n?.keyed !== false ? [] : undefined,
|
|
6164
|
+
Wt: n?.keyed === false,
|
|
6165
|
+
Mt: n?.fallback
|
|
6048
6166
|
};
|
|
6049
6167
|
const u = computed(updateKeyedMap.bind(s));
|
|
6050
6168
|
// Untracked reads inside the internal owner resolve via _parentComputed; routing
|
|
6051
6169
|
// them through node lets store-proxy lookups see pending writes (not stale _value).
|
|
6052
|
-
s.
|
|
6053
|
-
u.
|
|
6170
|
+
s.vt.Je = u;
|
|
6171
|
+
u.Ue &= ~CONFIG_AUTO_DISPOSE;
|
|
6054
6172
|
return accessor(u);
|
|
6055
6173
|
}
|
|
6056
6174
|
|
|
@@ -6068,52 +6186,52 @@ const pureOptions = {
|
|
|
6068
6186
|
// strong-abort ordering: removed rows now dispose AFTER the pass's new rows
|
|
6069
6187
|
// are created (you cannot destroy state before knowing the pass will land).
|
|
6070
6188
|
function updateKeyedMap() {
|
|
6071
|
-
const e = this.
|
|
6189
|
+
const e = this.Gt() || [], t = e.length;
|
|
6072
6190
|
e[$TRACK];
|
|
6073
6191
|
// top level tracking
|
|
6074
|
-
runWithOwner(this.
|
|
6192
|
+
runWithOwner(this.vt, () => {
|
|
6075
6193
|
let n, r, i, o,
|
|
6076
6194
|
// Mappers write freshly-created row/index signals into the STAGE
|
|
6077
6195
|
// arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
|
|
6078
|
-
s = this.
|
|
6196
|
+
s = this.xt ? this.Wt ? () => {
|
|
6079
6197
|
i[r] = signal(e[r], pureOptions);
|
|
6080
|
-
return this.
|
|
6198
|
+
return this.Ut(accessor(i[r]), r);
|
|
6081
6199
|
} : () => {
|
|
6082
6200
|
i[r] = signal(e[r], pureOptions);
|
|
6083
6201
|
o && (o[r] = signal(r, pureOptions));
|
|
6084
|
-
return this.
|
|
6085
|
-
} : this.
|
|
6202
|
+
return this.Ut(accessor(i[r]), o ? accessor(o[r]) : undefined);
|
|
6203
|
+
} : this.Qt ? () => {
|
|
6086
6204
|
const t = e[r];
|
|
6087
6205
|
o[r] = signal(r, pureOptions);
|
|
6088
|
-
return this.
|
|
6206
|
+
return this.Ut(t, accessor(o[r]));
|
|
6089
6207
|
} : () => {
|
|
6090
6208
|
const t = e[r];
|
|
6091
|
-
return this.
|
|
6209
|
+
return this.Ut(t);
|
|
6092
6210
|
};
|
|
6093
6211
|
// fast path for empty arrays
|
|
6094
6212
|
if (t === 0) {
|
|
6095
|
-
if (this.
|
|
6096
|
-
this.
|
|
6097
|
-
this.
|
|
6098
|
-
this.
|
|
6213
|
+
if (this.wt !== 0) {
|
|
6214
|
+
this.vt.dispose(false);
|
|
6215
|
+
this.kt = [];
|
|
6216
|
+
this.Lt = [];
|
|
6099
6217
|
this.Vt = [];
|
|
6100
|
-
this.
|
|
6101
|
-
this.
|
|
6102
|
-
this.
|
|
6218
|
+
this.wt = 0;
|
|
6219
|
+
this.xt && (this.xt = []);
|
|
6220
|
+
this.Qt && (this.Qt = []);
|
|
6103
6221
|
}
|
|
6104
|
-
if (this.
|
|
6222
|
+
if (this.Mt && !this.Vt[0]) {
|
|
6105
6223
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
6106
6224
|
// dispose it before re-creating
|
|
6107
|
-
this.
|
|
6108
|
-
this.Vt[0] = runWithOwner(this.
|
|
6225
|
+
this.kt[0]?.dispose();
|
|
6226
|
+
this.Vt[0] = runWithOwner(this.kt[0] = createOwner(), this.Mt);
|
|
6109
6227
|
}
|
|
6110
6228
|
}
|
|
6111
6229
|
// fast path for new create
|
|
6112
|
-
else if (this.
|
|
6230
|
+
else if (this.wt === 0) {
|
|
6113
6231
|
const u = new Array(t);
|
|
6114
6232
|
const l = new Array(t);
|
|
6115
|
-
i = this.
|
|
6116
|
-
o = this.
|
|
6233
|
+
i = this.xt && new Array(t);
|
|
6234
|
+
o = this.Qt && new Array(t);
|
|
6117
6235
|
try {
|
|
6118
6236
|
for (r = 0; r < t; r++) u[r] = runWithOwner(l[r] = createOwner(), s);
|
|
6119
6237
|
} catch (e) {
|
|
@@ -6121,83 +6239,107 @@ function updateKeyedMap() {
|
|
|
6121
6239
|
throw e;
|
|
6122
6240
|
}
|
|
6123
6241
|
// commit
|
|
6124
|
-
if (this.
|
|
6242
|
+
if (this.kt[0]) this.kt[0].dispose();
|
|
6125
6243
|
// previous fallback
|
|
6126
6244
|
this.Vt = u;
|
|
6127
|
-
this.
|
|
6128
|
-
i && (this.
|
|
6129
|
-
o && (this.
|
|
6130
|
-
this.
|
|
6131
|
-
this.
|
|
6245
|
+
this.kt = l;
|
|
6246
|
+
i && (this.xt = i);
|
|
6247
|
+
o && (this.Qt = o);
|
|
6248
|
+
this.Lt = e.slice(0);
|
|
6249
|
+
this.wt = t;
|
|
6132
6250
|
} else {
|
|
6133
|
-
let u, l, c, a, f, E,
|
|
6134
|
-
i = this.Ft ? new Array(t) : undefined;
|
|
6135
|
-
o = this.Wt ? new Array(t) : undefined;
|
|
6251
|
+
let u, l, c, a, f, E, d, S, T;
|
|
6136
6252
|
// skip common prefix
|
|
6137
|
-
for (u = 0, l = Math.min(this.
|
|
6138
|
-
if (this.
|
|
6253
|
+
for (u = 0, l = Math.min(this.wt, t); u < l && (this.Lt[u] === e[u] || this.xt && compare(this.Ft, this.Lt[u], e[u])); u++) {
|
|
6254
|
+
if (this.xt) setSignal(this.xt[u], e[u]);
|
|
6139
6255
|
}
|
|
6140
|
-
// common suffix
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6256
|
+
// skip common suffix — counted only; retained entries land in one pass
|
|
6257
|
+
// at commit instead of being staged and copied twice
|
|
6258
|
+
for (l = this.wt - 1, c = t - 1; l >= u && c >= u && (this.Lt[l] === e[c] || this.xt && compare(this.Ft, this.Lt[l], e[c])); l--,
|
|
6259
|
+
c--) ;
|
|
6260
|
+
// no structural change (every position matched in place at equal
|
|
6261
|
+
// length — the common post-reconcile shape): keep the same mapped
|
|
6262
|
+
// array identity so downstream consumers don't re-run at all
|
|
6263
|
+
if (u === t && this.wt === t) {
|
|
6264
|
+
this.Lt = e.slice(0);
|
|
6265
|
+
return;
|
|
6147
6266
|
}
|
|
6148
|
-
|
|
6267
|
+
const _ = t - this.wt;
|
|
6268
|
+
const O = new Array(t);
|
|
6269
|
+
const p = new Array(t);
|
|
6270
|
+
i = this.xt ? new Array(t) : undefined;
|
|
6271
|
+
o = this.Qt ? new Array(t) : undefined;
|
|
6272
|
+
// 0) prepare a map of all indices in the changed window of newItems,
|
|
6273
|
+
// scanning backwards so we encounter them in natural order
|
|
6149
6274
|
E = new Map;
|
|
6150
|
-
|
|
6275
|
+
d = new Array(c + 1);
|
|
6151
6276
|
for (r = c; r >= u; r--) {
|
|
6152
6277
|
a = e[r];
|
|
6153
|
-
f = this.
|
|
6278
|
+
f = this.Ft ? this.Ft(a) : a;
|
|
6154
6279
|
n = E.get(f);
|
|
6155
|
-
|
|
6280
|
+
d[r] = n === undefined ? -1 : n;
|
|
6156
6281
|
E.set(f, r);
|
|
6157
6282
|
}
|
|
6158
|
-
// 1) step through
|
|
6283
|
+
// 1) step through the old changed window and see if items can be found
|
|
6284
|
+
// in the new set; if so, stage them at their new positions; if not,
|
|
6285
|
+
// queue them for disposal at commit
|
|
6159
6286
|
for (n = u; n <= l; n++) {
|
|
6160
|
-
a = this.
|
|
6161
|
-
f = this.
|
|
6287
|
+
a = this.Lt[n];
|
|
6288
|
+
f = this.Ft ? this.Ft(a) : a;
|
|
6162
6289
|
r = E.get(f);
|
|
6163
6290
|
if (r !== undefined && r !== -1) {
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
i && (i[r] = this.
|
|
6167
|
-
o && (o[r] = this.
|
|
6168
|
-
r =
|
|
6291
|
+
O[r] = this.Vt[n];
|
|
6292
|
+
p[r] = this.kt[n];
|
|
6293
|
+
i && (i[r] = this.xt[n]);
|
|
6294
|
+
o && (o[r] = this.Qt[n]);
|
|
6295
|
+
r = d[r];
|
|
6169
6296
|
E.set(f, r);
|
|
6170
|
-
} else (
|
|
6297
|
+
} else (S ??= []).push(this.kt[n]);
|
|
6171
6298
|
}
|
|
6172
6299
|
// 2) create new rows into the temp arrays; an abort disposes only these
|
|
6173
6300
|
try {
|
|
6174
|
-
for (r = u; r
|
|
6175
|
-
if (r
|
|
6176
|
-
(T ??= []).push(
|
|
6177
|
-
|
|
6301
|
+
for (r = u; r <= c; r++) {
|
|
6302
|
+
if (p[r] !== undefined) continue;
|
|
6303
|
+
(T ??= []).push(p[r] = createOwner());
|
|
6304
|
+
O[r] = runWithOwner(p[r], s);
|
|
6178
6305
|
}
|
|
6179
6306
|
} catch (e) {
|
|
6180
6307
|
if (T) for (n = 0; n < T.length; n++) T[n].dispose();
|
|
6181
6308
|
throw e;
|
|
6182
6309
|
}
|
|
6183
|
-
// 3) commit: land
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6310
|
+
// 3) commit: land the retained prefix and suffix plus the staged window
|
|
6311
|
+
// into the fresh arrays, swap them in (new identity for downstream
|
|
6312
|
+
// change propagation), then dispose exited rows
|
|
6313
|
+
for (n = 0; n < u; n++) {
|
|
6314
|
+
O[n] = this.Vt[n];
|
|
6315
|
+
p[n] = this.kt[n];
|
|
6316
|
+
i && (i[n] = this.xt[n]);
|
|
6317
|
+
o && (o[n] = this.Qt[n]);
|
|
6318
|
+
}
|
|
6319
|
+
for (r = u; r <= c; r++) {
|
|
6320
|
+
if (i) setSignal(i[r], e[r]);
|
|
6321
|
+
if (o) setSignal(o[r], r);
|
|
6322
|
+
}
|
|
6323
|
+
for (r = c + 1; r < t; r++) {
|
|
6324
|
+
O[r] = this.Vt[r - _];
|
|
6325
|
+
p[r] = this.kt[r - _];
|
|
6187
6326
|
if (i) {
|
|
6188
|
-
|
|
6189
|
-
setSignal(
|
|
6327
|
+
i[r] = this.xt[r - _];
|
|
6328
|
+
setSignal(i[r], e[r]);
|
|
6190
6329
|
}
|
|
6191
6330
|
if (o) {
|
|
6192
|
-
|
|
6193
|
-
setSignal(
|
|
6331
|
+
o[r] = this.Qt[r - _];
|
|
6332
|
+
if (_ !== 0) setSignal(o[r], r);
|
|
6194
6333
|
}
|
|
6195
6334
|
}
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6335
|
+
this.Vt = O;
|
|
6336
|
+
this.kt = p;
|
|
6337
|
+
i && (this.xt = i);
|
|
6338
|
+
o && (this.Qt = o);
|
|
6339
|
+
this.wt = t;
|
|
6340
|
+
// save a copy of the mapped items for the next update
|
|
6341
|
+
this.Lt = e.slice(0);
|
|
6342
|
+
if (S) for (n = 0; n < S.length; n++) S[n].dispose();
|
|
6201
6343
|
}
|
|
6202
6344
|
});
|
|
6203
6345
|
return this.Vt;
|
|
@@ -6220,22 +6362,22 @@ function updateKeyedMap() {
|
|
|
6220
6362
|
*/ function repeat(e, t, n) {
|
|
6221
6363
|
const r = t;
|
|
6222
6364
|
const i = {
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6365
|
+
vt: createOwner(),
|
|
6366
|
+
wt: 0,
|
|
6367
|
+
Ht: 0,
|
|
6226
6368
|
$t: e,
|
|
6227
|
-
|
|
6228
|
-
|
|
6369
|
+
Ut: r,
|
|
6370
|
+
kt: [],
|
|
6229
6371
|
Vt: [],
|
|
6230
|
-
|
|
6231
|
-
|
|
6372
|
+
jt: n?.from,
|
|
6373
|
+
Mt: n?.fallback
|
|
6232
6374
|
};
|
|
6233
6375
|
const o = computed(updateRepeat.bind(i));
|
|
6234
6376
|
// Same as mapArray: untracked reads inside the internal owner resolve via
|
|
6235
6377
|
// _parentComputed, so async reads in row callbacks register with the node
|
|
6236
6378
|
// (pending tracking + post-settle retry) instead of vanishing.
|
|
6237
|
-
i.
|
|
6238
|
-
o.
|
|
6379
|
+
i.vt.Je = o;
|
|
6380
|
+
o.Ue &= ~CONFIG_AUTO_DISPOSE;
|
|
6239
6381
|
return accessor(o);
|
|
6240
6382
|
}
|
|
6241
6383
|
|
|
@@ -6248,52 +6390,52 @@ function updateKeyedMap() {
|
|
|
6248
6390
|
// disjoint-window/front-clear/end-clear/shift special cases.
|
|
6249
6391
|
function updateRepeat() {
|
|
6250
6392
|
const e = this.$t();
|
|
6251
|
-
const t = this.
|
|
6252
|
-
runWithOwner(this.
|
|
6393
|
+
const t = this.jt?.() || 0;
|
|
6394
|
+
runWithOwner(this.vt, () => {
|
|
6253
6395
|
if (e === 0) {
|
|
6254
|
-
if (this.
|
|
6255
|
-
this.
|
|
6256
|
-
this.
|
|
6396
|
+
if (this.wt !== 0) {
|
|
6397
|
+
this.vt.dispose(false);
|
|
6398
|
+
this.kt = [];
|
|
6257
6399
|
this.Vt = [];
|
|
6258
|
-
this.
|
|
6400
|
+
this.wt = 0;
|
|
6259
6401
|
// Reset offset to match the cleared data (#2767, repro 2).
|
|
6260
|
-
this.
|
|
6402
|
+
this.Ht = 0;
|
|
6261
6403
|
}
|
|
6262
|
-
if (this.
|
|
6404
|
+
if (this.Mt && !this.Vt[0]) {
|
|
6263
6405
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
6264
6406
|
// dispose it before re-creating
|
|
6265
|
-
this.
|
|
6266
|
-
this.Vt[0] = runWithOwner(this.
|
|
6407
|
+
this.kt[0]?.dispose();
|
|
6408
|
+
this.Vt[0] = runWithOwner(this.kt[0] = createOwner(), this.Mt);
|
|
6267
6409
|
}
|
|
6268
6410
|
return;
|
|
6269
6411
|
}
|
|
6270
6412
|
const n = t + e;
|
|
6271
|
-
const r = this.
|
|
6413
|
+
const r = this.Ht + this.wt;
|
|
6272
6414
|
// Retained overlap [keepStart, keepEnd) in global indexes; empty when the
|
|
6273
6415
|
// windows are disjoint or when coming from empty/fallback.
|
|
6274
|
-
const i = Math.max(t, this.
|
|
6416
|
+
const i = Math.max(t, this.Ht);
|
|
6275
6417
|
const o = Math.min(n, r);
|
|
6276
6418
|
const s = new Array(e);
|
|
6277
6419
|
const u = new Array(e);
|
|
6278
6420
|
for (let e = i; e < o; e++) {
|
|
6279
|
-
u[e - t] = this.
|
|
6280
|
-
s[e - t] = this.Vt[e - this.
|
|
6421
|
+
u[e - t] = this.kt[e - this.Ht];
|
|
6422
|
+
s[e - t] = this.Vt[e - this.Ht];
|
|
6281
6423
|
}
|
|
6282
6424
|
try {
|
|
6283
6425
|
for (let e = t; e < n; e++) {
|
|
6284
6426
|
if (e >= i && e < o) continue;
|
|
6285
|
-
s[e - t] = runWithOwner(u[e - t] = createOwner(), () => this.
|
|
6427
|
+
s[e - t] = runWithOwner(u[e - t] = createOwner(), () => this.Ut(e));
|
|
6286
6428
|
}
|
|
6287
6429
|
} catch (e) {
|
|
6288
6430
|
for (let e = t; e < n; e++) if ((e < i || e >= o) && u[e - t]) u[e - t].dispose();
|
|
6289
6431
|
throw e;
|
|
6290
6432
|
}
|
|
6291
6433
|
// commit: dispose the previous fallback or the rows leaving the window
|
|
6292
|
-
if (this.
|
|
6434
|
+
if (this.wt === 0) this.kt[0]?.dispose(); else for (let e = this.Ht; e < r; e++) if (e < t || e >= n) this.kt[e - this.Ht].dispose();
|
|
6293
6435
|
this.Vt = s;
|
|
6294
|
-
this.
|
|
6295
|
-
this.
|
|
6296
|
-
this.
|
|
6436
|
+
this.kt = u;
|
|
6437
|
+
this.Ht = t;
|
|
6438
|
+
this.wt = e;
|
|
6297
6439
|
});
|
|
6298
6440
|
return this.Vt;
|
|
6299
6441
|
}
|
|
@@ -6306,23 +6448,23 @@ function boundaryComputed(e, t) {
|
|
|
6306
6448
|
const n = computed(e, {
|
|
6307
6449
|
lazy: true
|
|
6308
6450
|
});
|
|
6309
|
-
n.
|
|
6451
|
+
n.Nt = (e, t) => {
|
|
6310
6452
|
// Use passed values if provided, otherwise read from node
|
|
6311
|
-
const r = e !== undefined ? e : n.
|
|
6312
|
-
const i = t !== undefined ? t : n.
|
|
6453
|
+
const r = e !== undefined ? e : n.Qe;
|
|
6454
|
+
const i = t !== undefined ? t : n.De;
|
|
6313
6455
|
// Notify both status dimensions like a render effect does; the queue chain
|
|
6314
6456
|
// consumes this boundary's own type and forwards the remainder upward until
|
|
6315
6457
|
// a boundary that handles it is found.
|
|
6316
|
-
n.
|
|
6317
|
-
const o = n.
|
|
6458
|
+
n.Qe &= ~n.Kt;
|
|
6459
|
+
const o = n.Be.notify(n, STATUS_PENDING | STATUS_ERROR, r, i);
|
|
6318
6460
|
// The queue is the only propagation channel: a foreign status must not stay
|
|
6319
6461
|
// reader-visible on the tree, or reads re-throw it across the boundary and
|
|
6320
6462
|
// link unrelated ambient contexts (the #2809 nested-boundary loop). Deps are
|
|
6321
6463
|
// untouched, so the tree still recomputes when the foreign source settles.
|
|
6322
|
-
const s = r & ~n.
|
|
6464
|
+
const s = r & ~n.Kt & (STATUS_PENDING | STATUS_ERROR);
|
|
6323
6465
|
if (s) {
|
|
6324
|
-
n.
|
|
6325
|
-
if (n.
|
|
6466
|
+
n.Qe &= ~s;
|
|
6467
|
+
if (n.De === i && !(n.Qe & (STATUS_PENDING | STATUS_ERROR))) n.De = undefined;
|
|
6326
6468
|
}
|
|
6327
6469
|
// An ERROR the chain could not deliver to any boundary is uncaught. The
|
|
6328
6470
|
// scrub above already removed it from reader-visible state, so without
|
|
@@ -6333,16 +6475,16 @@ function boundaryComputed(e, t) {
|
|
|
6333
6475
|
throw i;
|
|
6334
6476
|
}
|
|
6335
6477
|
};
|
|
6336
|
-
n.
|
|
6337
|
-
n.
|
|
6478
|
+
n.Kt = t;
|
|
6479
|
+
n.Ue &= ~CONFIG_AUTO_DISPOSE;
|
|
6338
6480
|
recompute(n, true);
|
|
6339
6481
|
return n;
|
|
6340
6482
|
}
|
|
6341
6483
|
|
|
6342
6484
|
function createBoundChildren(e, t, n, r) {
|
|
6343
|
-
const i = e.
|
|
6344
|
-
i.addChild(e.
|
|
6345
|
-
cleanup(() => i.removeChild(e.
|
|
6485
|
+
const i = e.Be;
|
|
6486
|
+
i.addChild(e.Be = n);
|
|
6487
|
+
cleanup(() => i.removeChild(e.Be));
|
|
6346
6488
|
return runWithOwner(e, () => {
|
|
6347
6489
|
const e = computed(t);
|
|
6348
6490
|
return boundaryComputed(() => flatten(read(e)), r);
|
|
@@ -6364,53 +6506,53 @@ function isRevealController(e) {
|
|
|
6364
6506
|
}
|
|
6365
6507
|
|
|
6366
6508
|
function isSlotReady(e) {
|
|
6367
|
-
return isRevealController(e) ? e.
|
|
6509
|
+
return isRevealController(e) ? e.Yt() : e.qt.size === 0 && !e.Bt;
|
|
6368
6510
|
}
|
|
6369
6511
|
|
|
6370
6512
|
function isSlotMinimallyReady(e) {
|
|
6371
|
-
return isRevealController(e) ? e.
|
|
6513
|
+
return isRevealController(e) ? e.Zt() : isSlotReady(e);
|
|
6372
6514
|
}
|
|
6373
6515
|
|
|
6374
6516
|
function setSlotState(e, t, n, r) {
|
|
6375
|
-
setSignal(e.
|
|
6376
|
-
setSignal(e.
|
|
6517
|
+
setSignal(e.Xt, n);
|
|
6518
|
+
setSignal(e.zt, r);
|
|
6377
6519
|
if (isRevealController(e)) {
|
|
6378
|
-
if (!n && e.
|
|
6379
|
-
return e.
|
|
6520
|
+
if (!n && e.Jt === t) e.Jt = undefined;
|
|
6521
|
+
return e.en(n, r);
|
|
6380
6522
|
}
|
|
6381
|
-
if (!n && e.
|
|
6523
|
+
if (!n && e.tn === t && e.nn) e.tn = undefined;
|
|
6382
6524
|
}
|
|
6383
6525
|
|
|
6384
6526
|
class RevealController {
|
|
6527
|
+
rn;
|
|
6385
6528
|
sn;
|
|
6386
|
-
un;
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
zt=signal(false, {
|
|
6529
|
+
un=[];
|
|
6530
|
+
Jt;
|
|
6531
|
+
Xt=signal(false, {
|
|
6390
6532
|
ownedWrite: true,
|
|
6391
|
-
|
|
6533
|
+
Ct: true
|
|
6392
6534
|
});
|
|
6393
|
-
|
|
6535
|
+
zt=signal(false, {
|
|
6394
6536
|
ownedWrite: true,
|
|
6395
|
-
|
|
6537
|
+
Ct: true
|
|
6396
6538
|
});
|
|
6539
|
+
ln=true;
|
|
6397
6540
|
cn=true;
|
|
6398
|
-
an=
|
|
6399
|
-
fn=false;
|
|
6541
|
+
an=false;
|
|
6400
6542
|
constructor(e, t) {
|
|
6401
|
-
this.
|
|
6402
|
-
this.
|
|
6543
|
+
this.rn = e;
|
|
6544
|
+
this.sn = t;
|
|
6403
6545
|
}
|
|
6404
|
-
|
|
6405
|
-
for (let t = 0; t < this.
|
|
6406
|
-
const n = this.
|
|
6407
|
-
if ((isRevealController(n) ? n.
|
|
6546
|
+
fn(e) {
|
|
6547
|
+
for (let t = 0; t < this.un.length; t++) {
|
|
6548
|
+
const n = this.un[t];
|
|
6549
|
+
if ((isRevealController(n) ? n.Jt : n.tn) !== this) continue;
|
|
6408
6550
|
if (e(n) === false) return false;
|
|
6409
6551
|
}
|
|
6410
6552
|
return true;
|
|
6411
6553
|
}
|
|
6412
|
-
|
|
6413
|
-
return this.
|
|
6554
|
+
Yt() {
|
|
6555
|
+
return this.fn(isSlotReady);
|
|
6414
6556
|
}
|
|
6415
6557
|
/**
|
|
6416
6558
|
* "Minimally ready" = this group has something visible to show under its own policy.
|
|
@@ -6418,13 +6560,13 @@ class RevealController {
|
|
|
6418
6560
|
* - `together`: every direct slot is minimally ready.
|
|
6419
6561
|
* - `sequential`: the first owned slot is minimally ready (frontier can advance).
|
|
6420
6562
|
* - `natural`: any owned slot is minimally ready.
|
|
6421
|
-
*/
|
|
6422
|
-
const e = untrack(this.
|
|
6423
|
-
if (e === "together") return this.
|
|
6563
|
+
*/ Zt() {
|
|
6564
|
+
const e = untrack(this.rn);
|
|
6565
|
+
if (e === "together") return this.fn(isSlotMinimallyReady);
|
|
6424
6566
|
if (e === "natural") {
|
|
6425
6567
|
let e = false;
|
|
6426
6568
|
let t = false;
|
|
6427
|
-
this.
|
|
6569
|
+
this.fn(n => {
|
|
6428
6570
|
e = true;
|
|
6429
6571
|
if (isSlotMinimallyReady(n)) {
|
|
6430
6572
|
t = true;
|
|
@@ -6435,45 +6577,45 @@ class RevealController {
|
|
|
6435
6577
|
}
|
|
6436
6578
|
// sequential: only the first owned slot matters.
|
|
6437
6579
|
let t = true;
|
|
6438
|
-
this.
|
|
6580
|
+
this.fn(e => {
|
|
6439
6581
|
t = isSlotMinimallyReady(e);
|
|
6440
6582
|
return false;
|
|
6441
6583
|
});
|
|
6442
6584
|
return t;
|
|
6443
6585
|
}
|
|
6444
|
-
|
|
6445
|
-
if (this.
|
|
6446
|
-
this.
|
|
6447
|
-
const t = untrack(this.
|
|
6448
|
-
setSignal(e.
|
|
6449
|
-
untrack(() => this.
|
|
6586
|
+
En(e) {
|
|
6587
|
+
if (this.un.includes(e)) return;
|
|
6588
|
+
this.un.push(e);
|
|
6589
|
+
const t = untrack(this.rn);
|
|
6590
|
+
setSignal(e.Xt, true), setSignal(e.zt, t === "sequential" ? !!untrack(this.sn) : false);
|
|
6591
|
+
untrack(() => this.en());
|
|
6450
6592
|
}
|
|
6451
6593
|
dn(e) {
|
|
6452
|
-
const t = this.
|
|
6453
|
-
if (t >= 0) this.
|
|
6454
|
-
untrack(() => this.
|
|
6455
|
-
}
|
|
6456
|
-
|
|
6457
|
-
if (this.
|
|
6458
|
-
this.
|
|
6459
|
-
const n = this.
|
|
6460
|
-
const r = this.
|
|
6594
|
+
const t = this.un.indexOf(e);
|
|
6595
|
+
if (t >= 0) this.un.splice(t, 1);
|
|
6596
|
+
untrack(() => this.en());
|
|
6597
|
+
}
|
|
6598
|
+
en(e, t) {
|
|
6599
|
+
if (this.an) return;
|
|
6600
|
+
this.an = true;
|
|
6601
|
+
const n = this.ln;
|
|
6602
|
+
const r = this.cn;
|
|
6461
6603
|
try {
|
|
6462
|
-
const n = e ?? read(this.
|
|
6604
|
+
const n = e ?? read(this.Xt), r = untrack(this.rn), i = r === "sequential" && !!untrack(this.sn), o = t ?? i;
|
|
6463
6605
|
if (n) {
|
|
6464
6606
|
// Held by an outer group. Propagate the hold (and whatever collapsed policy
|
|
6465
6607
|
// the outer asked for) down the whole subtree. Inner order is ignored while
|
|
6466
6608
|
// held; it resumes once the outer releases us.
|
|
6467
|
-
this.
|
|
6609
|
+
this.fn(e => setSlotState(e, this, true, o));
|
|
6468
6610
|
} else if (r === "natural") {
|
|
6469
6611
|
// Each child reveals based on its own readiness. A nested controller slot
|
|
6470
6612
|
// is released to run its own order locally — we bypass setSlotState for it
|
|
6471
6613
|
// so the parent backpointer survives for upward readiness notifications.
|
|
6472
|
-
this.
|
|
6614
|
+
this.fn(e => {
|
|
6473
6615
|
if (isRevealController(e)) {
|
|
6474
|
-
setSignal(e.Jt, false);
|
|
6475
6616
|
setSignal(e.zt, false);
|
|
6476
|
-
e.
|
|
6617
|
+
setSignal(e.Xt, false);
|
|
6618
|
+
e.en(false, false);
|
|
6477
6619
|
} else {
|
|
6478
6620
|
setSlotState(e, this, !isSlotReady(e), false);
|
|
6479
6621
|
}
|
|
@@ -6484,11 +6626,11 @@ class RevealController {
|
|
|
6484
6626
|
// sequential's first slot being ready is minimally ready; natural having any
|
|
6485
6627
|
// ready child is minimally ready. This lets `together` guarantee a single
|
|
6486
6628
|
// cohesive reveal without waiting for every grandchild.
|
|
6487
|
-
const e = this.
|
|
6488
|
-
this.
|
|
6629
|
+
const e = this.fn(isSlotMinimallyReady);
|
|
6630
|
+
this.fn(t => setSlotState(t, this, !e, false));
|
|
6489
6631
|
} else {
|
|
6490
6632
|
let e = false;
|
|
6491
|
-
this.
|
|
6633
|
+
this.fn(t => {
|
|
6492
6634
|
if (e) return setSlotState(t, this, true, i);
|
|
6493
6635
|
if (isSlotReady(t)) return setSlotState(t, this, false, false);
|
|
6494
6636
|
e = true;
|
|
@@ -6499,52 +6641,52 @@ class RevealController {
|
|
|
6499
6641
|
// advancing past this slot, and we bypass setSlotState so the parent
|
|
6500
6642
|
// backpointer survives for upward readiness notifications.
|
|
6501
6643
|
if (isRevealController(t)) {
|
|
6502
|
-
setSignal(t.Jt, false);
|
|
6503
6644
|
setSignal(t.zt, false);
|
|
6504
|
-
t.
|
|
6645
|
+
setSignal(t.Xt, false);
|
|
6646
|
+
t.en(false, false);
|
|
6505
6647
|
} else {
|
|
6506
6648
|
setSlotState(t, this, true, false);
|
|
6507
6649
|
}
|
|
6508
6650
|
});
|
|
6509
6651
|
}
|
|
6510
6652
|
} finally {
|
|
6511
|
-
this.
|
|
6512
|
-
this.
|
|
6513
|
-
this.
|
|
6653
|
+
this.ln = this.Yt();
|
|
6654
|
+
this.cn = this.Zt();
|
|
6655
|
+
this.an = false;
|
|
6514
6656
|
}
|
|
6515
|
-
if (this.
|
|
6657
|
+
if (this.Jt && (n !== this.ln || r !== this.cn)) this.Jt.en();
|
|
6516
6658
|
}
|
|
6517
6659
|
}
|
|
6518
6660
|
|
|
6519
6661
|
class CollectionQueue extends Queue {
|
|
6662
|
+
Sn;
|
|
6663
|
+
qt=new Set;
|
|
6520
6664
|
Tn;
|
|
6521
|
-
Bt=
|
|
6522
|
-
|
|
6523
|
-
Zt=true;
|
|
6524
|
-
zt=signal(false, {
|
|
6665
|
+
Bt=true;
|
|
6666
|
+
Xt=signal(false, {
|
|
6525
6667
|
ownedWrite: true,
|
|
6526
|
-
|
|
6668
|
+
Ct: true
|
|
6527
6669
|
});
|
|
6528
|
-
|
|
6529
|
-
|
|
6670
|
+
De;
|
|
6671
|
+
zt=signal(false, {
|
|
6530
6672
|
ownedWrite: true,
|
|
6531
|
-
|
|
6673
|
+
Ct: true
|
|
6532
6674
|
});
|
|
6533
|
-
|
|
6534
|
-
|
|
6675
|
+
tn;
|
|
6676
|
+
nn=false;
|
|
6535
6677
|
_n;
|
|
6536
6678
|
On=ON_INIT;
|
|
6537
6679
|
constructor(e) {
|
|
6538
6680
|
super();
|
|
6539
|
-
this.
|
|
6681
|
+
this.Sn = e;
|
|
6540
6682
|
}
|
|
6541
6683
|
run(e) {
|
|
6542
|
-
if (!e || read(this.
|
|
6684
|
+
if (!e || read(this.Xt) && (!_revealUsed || read(this.zt))) return;
|
|
6543
6685
|
return super.run(e);
|
|
6544
6686
|
}
|
|
6545
6687
|
notify(e, t, n, r) {
|
|
6546
|
-
if (!(t & this.
|
|
6547
|
-
if (this.
|
|
6688
|
+
if (!(t & this.Sn)) return super.notify(e, t, n, r);
|
|
6689
|
+
if (this.nn && this._n) {
|
|
6548
6690
|
const e = untrack(() => {
|
|
6549
6691
|
try {
|
|
6550
6692
|
return this._n();
|
|
@@ -6554,8 +6696,8 @@ class CollectionQueue extends Queue {
|
|
|
6554
6696
|
});
|
|
6555
6697
|
if (e !== this.On) {
|
|
6556
6698
|
this.On = e;
|
|
6557
|
-
this.
|
|
6558
|
-
this.
|
|
6699
|
+
this.nn = false;
|
|
6700
|
+
this.qt.clear();
|
|
6559
6701
|
}
|
|
6560
6702
|
}
|
|
6561
6703
|
// Routing is dimension-independent: each boundary consumes only its own
|
|
@@ -6568,38 +6710,38 @@ class CollectionQueue extends Queue {
|
|
|
6568
6710
|
// dimension, while a status already caught by an inner boundary arrives with
|
|
6569
6711
|
// its dimension consumed from the mask and is correctly not re-routed
|
|
6570
6712
|
// (the Loading > Errored > content composition escape, #2856).
|
|
6571
|
-
if (this.
|
|
6572
|
-
if (n & this.
|
|
6573
|
-
this.
|
|
6574
|
-
const t = r?.source || e.
|
|
6713
|
+
if (this.Sn & STATUS_PENDING && this.nn) return super.notify(e, t, n, r);
|
|
6714
|
+
if (n & this.Sn) {
|
|
6715
|
+
this.Bt = true;
|
|
6716
|
+
const t = r?.source || e.De?.source;
|
|
6575
6717
|
if (t) {
|
|
6576
|
-
const e = this.
|
|
6577
|
-
this.
|
|
6578
|
-
if (e) setSignal(this.
|
|
6579
|
-
if (this.
|
|
6580
|
-
setSignal(this.
|
|
6718
|
+
const e = this.qt.size === 0;
|
|
6719
|
+
this.qt.add(t);
|
|
6720
|
+
if (e) setSignal(this.Xt, true);
|
|
6721
|
+
if (this.Sn & STATUS_ERROR) {
|
|
6722
|
+
setSignal(this.De, unwrapStatusError(t.De));
|
|
6581
6723
|
}
|
|
6582
6724
|
}
|
|
6583
6725
|
}
|
|
6584
|
-
t &= ~this.
|
|
6726
|
+
t &= ~this.Sn;
|
|
6585
6727
|
return t ? super.notify(e, t, n, r) : true;
|
|
6586
6728
|
}
|
|
6587
|
-
|
|
6588
|
-
for (const e of this.
|
|
6729
|
+
He() {
|
|
6730
|
+
for (const e of this.qt) {
|
|
6589
6731
|
// A source with a live affects() mark holds display state for the
|
|
6590
6732
|
// mark's lifetime (the visual channel): the marked node carries no
|
|
6591
6733
|
// status of its own, so the count is the liveness test. The release
|
|
6592
6734
|
// sweep (finalizePureQueue after mark release) re-runs this check.
|
|
6593
|
-
if (e.
|
|
6735
|
+
if (e.Ge & REACTIVE_DISPOSED || !e.k && !(e.Qe & this.Sn) && !(this.Sn & STATUS_ERROR && e.Qe & STATUS_PENDING)) this.qt.delete(e);
|
|
6594
6736
|
}
|
|
6595
|
-
if (!this.
|
|
6596
|
-
if (this.
|
|
6597
|
-
this.
|
|
6737
|
+
if (!this.qt.size) {
|
|
6738
|
+
if (this.Sn & STATUS_PENDING && this.Bt && !this.nn && this.Tn) {
|
|
6739
|
+
this.Bt = !!(this.Tn.Qe & this.Sn);
|
|
6598
6740
|
} else {
|
|
6599
|
-
this.
|
|
6741
|
+
this.Bt = false;
|
|
6600
6742
|
}
|
|
6601
|
-
if (!this.
|
|
6602
|
-
setSignal(this.
|
|
6743
|
+
if (!this.Bt) {
|
|
6744
|
+
setSignal(this.Xt, false);
|
|
6603
6745
|
if (this._n) {
|
|
6604
6746
|
try {
|
|
6605
6747
|
this.On = untrack(() => this._n());
|
|
@@ -6608,7 +6750,7 @@ class CollectionQueue extends Queue {
|
|
|
6608
6750
|
}
|
|
6609
6751
|
}
|
|
6610
6752
|
}
|
|
6611
|
-
if (_revealUsed) this.
|
|
6753
|
+
if (_revealUsed) this.tn?.en();
|
|
6612
6754
|
}
|
|
6613
6755
|
}
|
|
6614
6756
|
|
|
@@ -6616,12 +6758,12 @@ function createCollectionBoundary(e, t, n, r) {
|
|
|
6616
6758
|
const i = createOwner();
|
|
6617
6759
|
if (_revealUsed) setContext(RevealControllerContext, null, i);
|
|
6618
6760
|
const o = new CollectionQueue(e);
|
|
6619
|
-
if (e === STATUS_ERROR) o.
|
|
6761
|
+
if (e === STATUS_ERROR) o.De = signal(undefined, {
|
|
6620
6762
|
ownedWrite: true,
|
|
6621
|
-
|
|
6763
|
+
Ct: true
|
|
6622
6764
|
});
|
|
6623
6765
|
if (r) o._n = r;
|
|
6624
|
-
const s = o.
|
|
6766
|
+
const s = o.Tn = createBoundChildren(i, t, o, e);
|
|
6625
6767
|
// Prime source tracking so reveal registration sees pending sources.
|
|
6626
6768
|
untrack(() => {
|
|
6627
6769
|
let t = false;
|
|
@@ -6630,23 +6772,23 @@ function createCollectionBoundary(e, t, n, r) {
|
|
|
6630
6772
|
} catch (e) {
|
|
6631
6773
|
if (e instanceof NotReadyError) t = true; else throw e;
|
|
6632
6774
|
}
|
|
6633
|
-
o.
|
|
6775
|
+
o.Bt = t || !!(s.Qe & e) || s.De instanceof NotReadyError;
|
|
6634
6776
|
});
|
|
6635
6777
|
const u = _revealUsed && e === STATUS_PENDING ? getContext(RevealControllerContext) : null;
|
|
6636
6778
|
if (u) {
|
|
6637
|
-
o.
|
|
6638
|
-
u.
|
|
6779
|
+
o.tn = u;
|
|
6780
|
+
u.En(o);
|
|
6639
6781
|
cleanup(() => u.dn(o));
|
|
6640
6782
|
}
|
|
6641
6783
|
return accessor(computed(() => {
|
|
6642
|
-
if (!read(o.
|
|
6784
|
+
if (!read(o.Xt)) {
|
|
6643
6785
|
const e = read(s);
|
|
6644
|
-
if (!untrack(() => read(o.
|
|
6786
|
+
if (!untrack(() => read(o.Xt))) return o.nn = true, e;
|
|
6645
6787
|
}
|
|
6646
6788
|
// Collapsed reveal slots suppress their own output entirely; the
|
|
6647
6789
|
// renderer treats the hole as empty, so the cast never leaks to users
|
|
6648
6790
|
// outside a `createRevealOrder` scope.
|
|
6649
|
-
if (_revealUsed && read(o.
|
|
6791
|
+
if (_revealUsed && read(o.zt)) return undefined;
|
|
6650
6792
|
return n(o);
|
|
6651
6793
|
},
|
|
6652
6794
|
// Boundary structure, not a user source: its value is fallback-or-content and
|
|
@@ -6654,7 +6796,7 @@ function createCollectionBoundary(e, t, n, r) {
|
|
|
6654
6796
|
// by snapshot capture. The tree no longer carries foreign status flags, so
|
|
6655
6797
|
// capture can't rely on PENDING to skip this node the way it used to.
|
|
6656
6798
|
{
|
|
6657
|
-
|
|
6799
|
+
Ct: true
|
|
6658
6800
|
}));
|
|
6659
6801
|
}
|
|
6660
6802
|
|
|
@@ -6707,8 +6849,8 @@ function createCollectionBoundary(e, t, n, r) {
|
|
|
6707
6849
|
* }
|
|
6708
6850
|
* ```
|
|
6709
6851
|
*/ function createErrorBoundary(e, t) {
|
|
6710
|
-
return createCollectionBoundary(STATUS_ERROR, e, e => t(accessor(e.
|
|
6711
|
-
for (const t of e.
|
|
6852
|
+
return createCollectionBoundary(STATUS_ERROR, e, e => t(accessor(e.De), () => {
|
|
6853
|
+
for (const t of e.qt) recompute(t);
|
|
6712
6854
|
schedule();
|
|
6713
6855
|
}));
|
|
6714
6856
|
}
|
|
@@ -6765,11 +6907,11 @@ function createCollectionBoundary(e, t, n, r) {
|
|
|
6765
6907
|
computed(() => {
|
|
6766
6908
|
i();
|
|
6767
6909
|
o();
|
|
6768
|
-
s.
|
|
6910
|
+
s.en();
|
|
6769
6911
|
});
|
|
6770
6912
|
if (r) {
|
|
6771
|
-
s.
|
|
6772
|
-
r.
|
|
6913
|
+
s.Jt = r;
|
|
6914
|
+
r.En(s);
|
|
6773
6915
|
cleanup(() => r.dn(s));
|
|
6774
6916
|
}
|
|
6775
6917
|
return t;
|