@solidjs/signals 2.0.0-rc.16 → 2.0.0-rc.18
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-shared.js +1972 -1751
- package/dist/dev.attribution.js +16 -16
- package/dist/dev.js +672 -319
- package/dist/observe/boundaries.js +2 -2
- package/dist/observe/core/async.js +151 -116
- package/dist/observe/core/constants.js +3 -1
- package/dist/observe/core/context.js +2 -0
- package/dist/observe/core/core.js +51 -35
- package/dist/observe/core/effect.js +29 -30
- package/dist/observe/core/graph.js +13 -11
- package/dist/observe/core/lanes.js +25 -14
- package/dist/observe/core/owner.js +77 -51
- package/dist/observe/core/scheduler.js +202 -175
- package/dist/observe/core/verdict.js +5 -2
- package/dist/observe/deferred.js +16 -13
- package/dist/observe/from.js +248 -0
- package/dist/observe/index.js +2 -0
- package/dist/observe/map.js +2 -2
- package/dist/observe/signals.js +6 -1
- package/dist/observe/store/affects.js +13 -13
- package/dist/observe/store/optimistic.js +112 -71
- package/dist/observe/store/reconcile.js +137 -121
- package/dist/observe/store/store.js +612 -626
- package/dist/observe/store/target.js +1 -5
- package/dist/prod/boundaries.js +2 -2
- package/dist/prod/core/async.js +211 -176
- package/dist/prod/core/constants.js +3 -1
- package/dist/prod/core/context.js +2 -0
- package/dist/prod/core/core.js +63 -47
- package/dist/prod/core/effect.js +24 -25
- package/dist/prod/core/graph.js +12 -10
- package/dist/prod/core/heap.js +1 -1
- package/dist/prod/core/lanes.js +39 -28
- package/dist/prod/core/owner.js +70 -44
- package/dist/prod/core/scheduler.js +78 -51
- package/dist/prod/core/truth.js +4 -4
- package/dist/prod/core/verdict.js +11 -8
- package/dist/prod/deferred.js +17 -14
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +2 -0
- package/dist/prod/map.js +2 -2
- package/dist/prod/signals.js +18 -13
- package/dist/prod/store/optimistic.js +112 -71
- package/dist/prod/store/reconcile.js +137 -121
- package/dist/prod/store/store.js +109 -121
- package/dist/prod/store/target.js +13 -17
- package/dist/types/core/async.d.ts +12 -2
- package/dist/types/core/constants.d.ts +5 -0
- package/dist/types/core/core.d.ts +29 -6
- package/dist/types/core/dev.d.ts +9 -1
- package/dist/types/core/error.d.ts +9 -1
- package/dist/types/core/owner.d.ts +4 -0
- package/dist/types/core/scheduler.d.ts +38 -7
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -14,6 +14,8 @@ import { runHeap, enqueueSub, deleteFromHeap } from "./heap.js";
|
|
|
14
14
|
|
|
15
15
|
import { devCheckQuiescent } from "./invariants.js";
|
|
16
16
|
|
|
17
|
+
import { rethrowCleanupError } from "./owner.js";
|
|
18
|
+
|
|
17
19
|
// Optional-module hooks: module bindings, not `GlobalQueue` statics, so a
|
|
18
20
|
// bundle that never imports the installing module never assigns them — its
|
|
19
21
|
// minifier folds every guarded call site (and the branch behind it) away.
|
|
@@ -38,12 +40,12 @@ let endLanesHook = null;
|
|
|
38
40
|
|
|
39
41
|
let lanesBlockedHook = null;
|
|
40
42
|
|
|
41
|
-
function installLaneHooks(e, n, o,
|
|
43
|
+
function installLaneHooks(e, n, o, t, l, s, u, i, r) {
|
|
42
44
|
laneReadHook = e;
|
|
43
45
|
laneStageHook = n;
|
|
44
46
|
laneOutcomeHook = o;
|
|
45
|
-
laneWriteHook =
|
|
46
|
-
applyGuessesHook =
|
|
47
|
+
laneWriteHook = t;
|
|
48
|
+
applyGuessesHook = l;
|
|
47
49
|
laneSeamsHook = s;
|
|
48
50
|
laneCorrectionsHook = u;
|
|
49
51
|
endLanesHook = i;
|
|
@@ -73,12 +75,12 @@ let boundarySeamHook = null;
|
|
|
73
75
|
|
|
74
76
|
let heldRunHook = null;
|
|
75
77
|
|
|
76
|
-
function installBoundaryHooks(e, n, o,
|
|
78
|
+
function installBoundaryHooks(e, n, o, t, l) {
|
|
77
79
|
catchHook = e;
|
|
78
80
|
freshHook = n;
|
|
79
81
|
hiddenHook = o;
|
|
80
|
-
boundarySeamHook =
|
|
81
|
-
heldRunHook =
|
|
82
|
+
boundarySeamHook = t;
|
|
83
|
+
heldRunHook = l;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
/** Store (store/store.ts): `park` — the flush parked into `t`: the store
|
|
@@ -287,16 +289,16 @@ let judge = null;
|
|
|
287
289
|
}
|
|
288
290
|
|
|
289
291
|
function blockedBy(e, n, o = false) {
|
|
290
|
-
for (let
|
|
291
|
-
const
|
|
292
|
-
if (!(
|
|
292
|
+
for (let t = 0; t < e.length; t++) {
|
|
293
|
+
const l = e[t];
|
|
294
|
+
if (!(l.m & STATUS_PENDING) || l.R & REACTIVE_DISPOSED || l.l & CONFIG_GUESS || l.T.Re !== null && txOf(l) !== n || o && !ownSource(l, n)) continue;
|
|
293
295
|
// The frame's own pending observer (off screen: this one holds nothing;
|
|
294
296
|
// the next listed node may).
|
|
295
|
-
if (
|
|
296
|
-
if (onScreen(
|
|
297
|
+
if (l.i === EFFECT_RENDER) {
|
|
298
|
+
if (onScreen(l, judge ?? n)) return true;
|
|
297
299
|
continue;
|
|
298
300
|
}
|
|
299
|
-
for (let e =
|
|
301
|
+
for (let e = l.o; e !== null; e = e.t) {
|
|
300
302
|
const o = e.u;
|
|
301
303
|
// A frame reader: a render effect, or a stale reader of the flight
|
|
302
304
|
// (REACTIVE_FRAME_READ — a verdict reader, `observeFlight`; lane work,
|
|
@@ -399,9 +401,9 @@ function deferZombie(e) {
|
|
|
399
401
|
|
|
400
402
|
/** The nodes under `owner` a transaction other than `t` holds (boundaries.ts:
|
|
401
403
|
* what an earlier hold staged under a re-armed boundary). */ function heldUnder(e, n, o) {
|
|
402
|
-
for (let
|
|
403
|
-
if ((
|
|
404
|
-
heldUnder(
|
|
404
|
+
for (let t = e.De; t !== null; t = t.pe) {
|
|
405
|
+
if ((t.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD && txOf(t) !== n) o(t);
|
|
406
|
+
heldUnder(t, n, o);
|
|
405
407
|
}
|
|
406
408
|
}
|
|
407
409
|
|
|
@@ -498,6 +500,8 @@ function schedule() {
|
|
|
498
500
|
function haltReactivity(e) {
|
|
499
501
|
if (halted) return;
|
|
500
502
|
halted = true;
|
|
503
|
+
// A cleanup error collected before the halt is dropped (owner.ts).
|
|
504
|
+
rethrowCleanupError(true);
|
|
501
505
|
let n = "[REACTIVITY_HALTED]";
|
|
502
506
|
// Surface the cause here too: callers rethrow it, but a creation-time throw
|
|
503
507
|
// unwinds through ancestor recomputes that convert it to status instead of
|
|
@@ -513,6 +517,15 @@ function haltReactivity(e) {
|
|
|
513
517
|
o && o(e);
|
|
514
518
|
}
|
|
515
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Dev: `haltReactivity`, located at `subject` — the computation the uncaught
|
|
522
|
+
* error escaped from — for the REACTIVITY_HALTED message's owner path. Call
|
|
523
|
+
* sites pick it in dev builds only (`haltReactivity(e)` in production), so
|
|
524
|
+
* production keeps the one-argument halt and its bytes unchanged.
|
|
525
|
+
*/ function haltReactivityAt(e, n) {
|
|
526
|
+
haltReactivity(e);
|
|
527
|
+
}
|
|
528
|
+
|
|
516
529
|
// Logs on the first write after a halt so a frozen interaction is traceable.
|
|
517
530
|
function notifyHalted() {
|
|
518
531
|
if (haltNotified) return;
|
|
@@ -599,18 +612,18 @@ class GlobalQueue {
|
|
|
599
612
|
// stale stamp was the bridge that entangled unrelated updates
|
|
600
613
|
// with a never-resolving flight). Its observers are held and
|
|
601
614
|
// wait on its flight (`blocked`).
|
|
602
|
-
if (e.
|
|
615
|
+
if (e.ue === NOT_PENDING && e.m & STATUS_UNINITIALIZED && e.i !== EFFECT_RENDER) continue;
|
|
603
616
|
// A34 (2): a tick whose writes net to the committed value made no
|
|
604
617
|
// proposal (`setShow(false); setShow(true)` on a committed true) —
|
|
605
618
|
// not staged, not held, pends nothing; a later write to it is
|
|
606
619
|
// plain mainline. (A node already held stays held when written
|
|
607
620
|
// back: A34 (1).)
|
|
608
|
-
if (e.
|
|
621
|
+
if (e.ue !== NOT_PENDING && !(e.m & (STATUS_PENDING | STATUS_UNINITIALIZED)) && e.T?.Ue == null && e.T?.me == null &&
|
|
609
622
|
// The comparator last: a pass that created children (an object
|
|
610
623
|
// owning a fresh async memo, #4111) must not have it read them.
|
|
611
624
|
// A NotReady read there is a change (`isSame`).
|
|
612
|
-
isSame(e, e.Ie, e.
|
|
613
|
-
e.
|
|
625
|
+
isSame(e, e.Ie, e.ue)) {
|
|
626
|
+
e.ue = NOT_PENDING;
|
|
614
627
|
e.l &= ~CONFIG_STAGED;
|
|
615
628
|
continue;
|
|
616
629
|
}
|
|
@@ -664,7 +677,7 @@ class GlobalQueue {
|
|
|
664
677
|
// This flush's own runs, the lanes' reveals, and the landings' held runs
|
|
665
678
|
// are collected apart and ordered below.
|
|
666
679
|
const o = this.un;
|
|
667
|
-
const
|
|
680
|
+
const t = this.un = [ [], [] ];
|
|
668
681
|
// The passes that read this frame's stagings as the screen read held
|
|
669
682
|
// writes if it parked: the lane seam re-derives them on the committed
|
|
670
683
|
// world (a lane's runs wait this round).
|
|
@@ -691,8 +704,8 @@ class GlobalQueue {
|
|
|
691
704
|
// parked (something async below) — the window is the frame's, the marks
|
|
692
705
|
// are its transaction's; else they release at the seam, verdict-only,
|
|
693
706
|
// nothing to show (affects.ts).
|
|
694
|
-
const
|
|
695
|
-
releaseAmbientMarksHook?.(
|
|
707
|
+
const l = n && liveTx(n);
|
|
708
|
+
releaseAmbientMarksHook?.(l);
|
|
696
709
|
// The effect phase: lane work first (displayed ahead of the frame), then
|
|
697
710
|
// this flush's runs, then the runs the landings held from earlier
|
|
698
711
|
// flushes — as one pass would have queued them (#3540: a shell
|
|
@@ -700,14 +713,14 @@ class GlobalQueue {
|
|
|
700
713
|
// write; #3528: a display-ahead swap before the count it is shown
|
|
701
714
|
// beside). A parked frame's runs wait with its transaction instead: the
|
|
702
715
|
// effect phase applies a committed frame.
|
|
703
|
-
const s =
|
|
716
|
+
const s = l !== null;
|
|
704
717
|
for (let e = 0; e < 2; e++) {
|
|
705
|
-
if (s) append(
|
|
718
|
+
if (s) append(l.un[e], o[e]);
|
|
706
719
|
// The plain flush — no reveal, no landing, not parked — has nothing to
|
|
707
720
|
// order around its own runs: they are the queue as they stand (the
|
|
708
721
|
// same array, not a copy; `run` takes it whole). Every other seam
|
|
709
722
|
// builds the ordered queue above.
|
|
710
|
-
this.un[e] = s ||
|
|
723
|
+
this.un[e] = s || t[e].length || this.un[e].length ? t[e].concat(s ? [] : o[e], this.un[e]) : o[e];
|
|
711
724
|
}
|
|
712
725
|
if (deferredZombies.length !== 0) {
|
|
713
726
|
// Survivors are the displayed frame of a held pass: they rerun for the
|
|
@@ -749,8 +762,8 @@ class GlobalQueue {
|
|
|
749
762
|
*
|
|
750
763
|
* A boundary between the observer and the root (boundaries.ts) is asked
|
|
751
764
|
* first: a fallback catches what is not ready under it, and the root
|
|
752
|
-
* never hears of it. */ notify(e, n, o,
|
|
753
|
-
if (catchHook?.(e, o & n,
|
|
765
|
+
* never hears of it. */ notify(e, n, o, t) {
|
|
766
|
+
if (catchHook?.(e, o & n, t)) return true;
|
|
754
767
|
if (n & STATUS_PENDING) {
|
|
755
768
|
if (o & STATUS_PENDING) {
|
|
756
769
|
// A pass that went pending holds its frame: the async's own
|
|
@@ -783,28 +796,31 @@ class GlobalQueue {
|
|
|
783
796
|
* or without the held read) owes nothing. A run this transaction stashed
|
|
784
797
|
* for it is void (#3322: an effect has one value slot, and the stale pass
|
|
785
798
|
* overwrote the value that run was for) — the re-derivation's run replaces
|
|
786
|
-
* it. */ function reruns(e) {
|
|
787
|
-
|
|
788
|
-
|
|
799
|
+
* it. Truthy when an effect re-derives (`land`). */ function reruns(e) {
|
|
800
|
+
let n;
|
|
801
|
+
for (let o = 0; o < e.En.length; o++) {
|
|
802
|
+
const t = e.En[o];
|
|
789
803
|
// An errored reader's display is its error (D-39): the landing gives it
|
|
790
804
|
// nothing to re-derive, and a re-run would be a read that retries the
|
|
791
805
|
// errored source (#3945).
|
|
792
|
-
if (
|
|
793
|
-
if (
|
|
794
|
-
|
|
795
|
-
|
|
806
|
+
if (t.R & REACTIVE_DISPOSED || t.m & STATUS_ERROR) continue;
|
|
807
|
+
if (t.R & REACTIVE_FRAME_READ || t.l & CONFIG_VERDICT) {
|
|
808
|
+
n ||= t.i;
|
|
809
|
+
t.R &= ~REACTIVE_FRAME_READ;
|
|
810
|
+
t.Ae = false;
|
|
796
811
|
// Its frame is replaced by the re-derivation: a run one of its
|
|
797
812
|
// children queued this flush (re-run by the same landing) is for the
|
|
798
813
|
// frame being replaced — void too (#3404).
|
|
799
|
-
for (let e =
|
|
800
|
-
enqueueSub(
|
|
814
|
+
for (let e = t.De; e !== null; e = e.pe) if (e.i) e.Ae = false;
|
|
815
|
+
enqueueSub(t);
|
|
801
816
|
}
|
|
802
817
|
}
|
|
803
818
|
e.En.length = 0;
|
|
819
|
+
return n;
|
|
804
820
|
}
|
|
805
821
|
|
|
806
822
|
/** The landing: the held frame becomes the frame. */ function land(e) {
|
|
807
|
-
reruns(e);
|
|
823
|
+
const n = reruns(e);
|
|
808
824
|
if (e.I !== null) releaseMarksHook(e.I);
|
|
809
825
|
// Old children die in the commits (cleanups first), then the stashed
|
|
810
826
|
// effects run ahead of this flush's own. A node a lane took over since
|
|
@@ -819,7 +835,15 @@ class GlobalQueue {
|
|
|
819
835
|
// `u`, which has left `transactions`: the write is this landing's, and
|
|
820
836
|
// the next flush must not park in it (#4089).
|
|
821
837
|
if (flushTransaction === e) flushTransaction = null;
|
|
822
|
-
|
|
838
|
+
// An effect re-derives next round (`reruns`): the held runs wait for it
|
|
839
|
+
// (D-9, the A15 reveal corollary, #4071). Its re-derivation can discover a
|
|
840
|
+
// flight — a stale reader whose mainline pass stopped reading it, now
|
|
841
|
+
// reading the landed world — and a landing that showed its runs first
|
|
842
|
+
// would reveal the held write beside a frame that can only show its old
|
|
843
|
+
// value. Queued last in this effect phase, the release hands them to the
|
|
844
|
+
// next round's own runs, ahead of the re-derivation's: they show with it,
|
|
845
|
+
// or park with it in the hold its pending opens. The commits stand.
|
|
846
|
+
if (n) globalQueue.un[1].push(() => releaseQueues(e)); else releaseQueues(e);
|
|
823
847
|
}
|
|
824
848
|
|
|
825
849
|
/** The held runs join this flush's effect phase after its own runs (the
|
|
@@ -922,17 +946,17 @@ function commitPendingNode(e) {
|
|
|
922
946
|
// commits a value.
|
|
923
947
|
if (!n.X) {
|
|
924
948
|
e.l &= -385;
|
|
925
|
-
if (e.
|
|
926
|
-
e.Ie = e.
|
|
927
|
-
e.
|
|
949
|
+
if (e.ue !== NOT_PENDING) {
|
|
950
|
+
e.Ie = e.ue;
|
|
951
|
+
e.ue = NOT_PENDING;
|
|
928
952
|
}
|
|
929
953
|
return;
|
|
930
954
|
}
|
|
931
955
|
// Computeds only from here (`_statusFlags` is not a signal field). A
|
|
932
956
|
// commit beneath a flight publishes its inputs (A15 reveal corollary,
|
|
933
957
|
// #3305): a reveal of it must observe, not show the pre-flight value.
|
|
934
|
-
const o = e.
|
|
935
|
-
const
|
|
958
|
+
const o = e.ue === NOT_PENDING && (n.m & STATUS_PENDING) !== 0;
|
|
959
|
+
const t = e.l & CONFIG_STAGED_ERROR;
|
|
936
960
|
// An answer commits: the error it replaces leaves the display (D-41).
|
|
937
961
|
if (!o && n.T) n.T.de = undefined;
|
|
938
962
|
e.l = o ? e.l & -1048833 | CONFIG_INPUTS_PUBLISHED : e.l & -3147137;
|
|
@@ -940,21 +964,21 @@ function commitPendingNode(e) {
|
|
|
940
964
|
// show, through the ordinary error path (`stageError`). Its readers first
|
|
941
965
|
// see it in the cycle after this seam: a tracked re-read there is not a
|
|
942
966
|
// retry (`read`), or a boundary re-derived by it would retry it forever.
|
|
943
|
-
if (
|
|
944
|
-
const o = e.
|
|
945
|
-
e.
|
|
967
|
+
if (t) {
|
|
968
|
+
const o = e.ue;
|
|
969
|
+
e.ue = NOT_PENDING;
|
|
946
970
|
e.ie = clock + 1;
|
|
947
971
|
notifyStatus(n, STATUS_ERROR, o);
|
|
948
|
-
} else if (e.
|
|
949
|
-
e.Ie = e.
|
|
950
|
-
e.
|
|
972
|
+
} else if (e.ue !== NOT_PENDING) {
|
|
973
|
+
e.Ie = e.ue;
|
|
974
|
+
e.ue = NOT_PENDING;
|
|
951
975
|
// A node born staged (recompute) initializes at this commit.
|
|
952
976
|
n.m &= ~STATUS_UNINITIALIZED;
|
|
953
977
|
// A quiet re-ask's classification survives its landing and dies with
|
|
954
978
|
// the landed value's commit (A19 exc. 2, #3178): verdict-quiet through
|
|
955
979
|
// the reveal. (The sweep of a node still in flight is not a landing.)
|
|
956
980
|
// The A28 stash goes with it.
|
|
957
|
-
if (n.T != null) n.T.Ve = false, n.T.
|
|
981
|
+
if (n.T != null) n.T.Ve = false, n.T.je = NOT_PENDING;
|
|
958
982
|
// An effect with a staged value was born held (L2): its first run is
|
|
959
983
|
// this commit's, not its creation's (A29) — queue it now.
|
|
960
984
|
if (e.i && e.i !== EFFECT_TRACKED) {
|
|
@@ -1018,10 +1042,13 @@ function flush(e) {
|
|
|
1018
1042
|
while (scheduled) {
|
|
1019
1043
|
globalQueue.flush();
|
|
1020
1044
|
}
|
|
1045
|
+
// A cleanup that threw during the drain, now that the drain is complete
|
|
1046
|
+
// (owner.ts).
|
|
1047
|
+
rethrowCleanupError();
|
|
1021
1048
|
}
|
|
1022
1049
|
|
|
1023
1050
|
function runQueue(e, n) {
|
|
1024
1051
|
for (let o = 0; o < e.length; o++) e[o](n);
|
|
1025
1052
|
}
|
|
1026
1053
|
|
|
1027
|
-
export { GlobalQueue, MAINLINE_QUESTION, ROOT_ERROR_HOOK, actionDepth, applyGuessesHook, blocked, boundarySeamHook, bumpNotifyEpoch, catchHook, clock, commitPendingNode, deferZombie, dirtyQueue, endLanesHook, enforceLoadingBoundary, enterAction, exitAction, externalUntrackHook, flush, flushTransaction, freshHook, globalQueue, haltReactivity, heldRunHook, heldTrim, heldUnder, hiddenHook, holdNode, insertSubs, installBoundaryHooks, installLaneHooks, installMarkHooks, installStoreHooks, installVerdictHooks, joinFuture, joinPassTx, laneCorrectionsHook, laneDirty, laneOutcomeHook, laneReadHook, laneSeamsHook, laneStageHook, laneWriteHook, lanesBlockedHook, list, liveTx, merge, newTransaction, nextQuestion, notifyEpoch, observeFlightHook, ownFlights, passLane, passTx, question, queuePendingNode, releaseAmbientMarksHook, releaseMarksHook, releaseQueues, reruns, resetErrorHalt, resolveTx, sameLane, schedule, setExternalHooks, setPassLane, setQuestion, stagedReaders, staleReader, storeCommitHook, storeParkHook, txOf, unhold, wireExternalSourceHook };
|
|
1054
|
+
export { GlobalQueue, MAINLINE_QUESTION, ROOT_ERROR_HOOK, actionDepth, applyGuessesHook, blocked, boundarySeamHook, bumpNotifyEpoch, catchHook, clock, commitPendingNode, deferZombie, dirtyQueue, endLanesHook, enforceLoadingBoundary, enterAction, exitAction, externalUntrackHook, flush, flushTransaction, freshHook, globalQueue, haltReactivity, haltReactivityAt, heldRunHook, heldTrim, heldUnder, hiddenHook, holdNode, insertSubs, installBoundaryHooks, installLaneHooks, installMarkHooks, installStoreHooks, installVerdictHooks, joinFuture, joinPassTx, laneCorrectionsHook, laneDirty, laneOutcomeHook, laneReadHook, laneSeamsHook, laneStageHook, laneWriteHook, lanesBlockedHook, list, liveTx, merge, newTransaction, nextQuestion, notifyEpoch, observeFlightHook, ownFlights, passLane, passTx, question, queuePendingNode, releaseAmbientMarksHook, releaseMarksHook, releaseQueues, reruns, resetErrorHalt, resolveTx, sameLane, schedule, setExternalHooks, setPassLane, setQuestion, stagedReaders, staleReader, storeCommitHook, storeParkHook, txOf, unhold, wireExternalSourceHook };
|
package/dist/prod/core/truth.js
CHANGED
|
@@ -12,7 +12,7 @@ import { enqueueSub } from "./heap.js";
|
|
|
12
12
|
* staging a shown lane holds for its next reveal, else its slot; the
|
|
13
13
|
* committed value while it has none (its first lane pass in flight). */
|
|
14
14
|
function laneValueOf(r) {
|
|
15
|
-
if (!(r.l & CONFIG_GUESS) && r.
|
|
15
|
+
if (!(r.l & CONFIG_GUESS) && r.ue !== NOT_PENDING) return r.ue;
|
|
16
16
|
const t = r.T.v;
|
|
17
17
|
return t !== NOT_PENDING ? t : r.Ie;
|
|
18
18
|
}
|
|
@@ -25,7 +25,7 @@ function laneValueOf(r) {
|
|
|
25
25
|
* value. */ function truthRead(r) {
|
|
26
26
|
if (truth(r)) return laneValueOf(r);
|
|
27
27
|
if (!(r.l & CONFIG_GUESS)) throw new NotReadyError(null);
|
|
28
|
-
return r.
|
|
28
|
+
return r.ue !== NOT_PENDING ? r.ue : r.Ie;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
/** A guess confirmed: its lane's truth readers re-read — of the lane's
|
|
@@ -36,8 +36,8 @@ function laneValueOf(r) {
|
|
|
36
36
|
/** A lane node's value is the truth when every guess beneath it is
|
|
37
37
|
* confirmed — its source staged a value equal to the guess — and nothing
|
|
38
38
|
* beneath it is held in the parent: same inputs, same value. */ function truth(r) {
|
|
39
|
-
if (r.l & CONFIG_GUESS) return r.
|
|
40
|
-
if (r.
|
|
39
|
+
if (r.l & CONFIG_GUESS) return r.ue !== NOT_PENDING && r.xe && r.xe(r.T.v, r.ue);
|
|
40
|
+
if (r.ue !== NOT_PENDING) return;
|
|
41
41
|
if (r.l & CONFIG_OVERRIDE) for (let t = r.C; t; t = t.G) if (!truth(t.S)) return;
|
|
42
42
|
return 1;
|
|
43
43
|
}
|
|
@@ -157,7 +157,7 @@ let probeFound = false;
|
|
|
157
157
|
* flight — a staging equal to what is displayed changes nothing when it
|
|
158
158
|
* lands: final now (maintainer, 2026-10-02). */ function heldNotFinal(e) {
|
|
159
159
|
if ((e.m & STATUS_PENDING) !== 0 && !quietPending(e)) return true;
|
|
160
|
-
return e.
|
|
160
|
+
return e.ue !== NOT_PENDING && !latestActive && !e.T.Ve && !(e.m & STATUS_UNINITIALIZED) && (!!e.T.de || !e.xe || !e.xe(e.Ie, e.ue));
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/** `isPending`'s answer for an unheld node whose flight is up (cause ii). */ function pendingVerdict(e, t) {
|
|
@@ -175,7 +175,7 @@ let probeFound = false;
|
|
|
175
175
|
* a router's link claim probing inside the computation that creates the
|
|
176
176
|
* anchor). A throw still reaches the pass through `untrack`. */ function markVerdictReader(e) {
|
|
177
177
|
let t = context;
|
|
178
|
-
if (t?.
|
|
178
|
+
if (t?.Qe) t = t.Ye;
|
|
179
179
|
if (t !== null && tracking) {
|
|
180
180
|
t.l |= CONFIG_VERDICT;
|
|
181
181
|
t.R |= REACTIVE_PROBED;
|
|
@@ -256,8 +256,8 @@ let probeFound = false;
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
/** The staging, or the staged error thrown (D-41). */ function staged(e) {
|
|
259
|
-
if (e.l & CONFIG_STAGED_ERROR) throw e.
|
|
260
|
-
return e.
|
|
259
|
+
if (e.l & CONFIG_STAGED_ERROR) throw e.ue;
|
|
260
|
+
return e.ue;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
/** `latest()` of a held node: the flushed staging — the proposal — and, for
|
|
@@ -317,7 +317,10 @@ let probeFound = false;
|
|
|
317
317
|
if (i) verdictRead(t, r._parent ?? r);
|
|
318
318
|
const u = (n.m & STATUS_PENDING) !== 0 && !quietPending(n);
|
|
319
319
|
if (e.l & CONFIG_GUESS) {
|
|
320
|
-
if (probing && (u || e.
|
|
320
|
+
if (probing && (u || e.ue !== NOT_PENDING && (!e.xe || !e.xe(e.T.v, e.ue)))) probeFound = true;
|
|
321
|
+
// A lane a correction folded under (D-34): `latest()` shows the hold's
|
|
322
|
+
// world whole — the truth beneath each guess, else what it covered.
|
|
323
|
+
if (latestActive && r.folded) return r.folded(null, e);
|
|
321
324
|
return e.T.v;
|
|
322
325
|
}
|
|
323
326
|
if (probing && u) probeFound = true;
|
|
@@ -338,7 +341,7 @@ let probeFound = false;
|
|
|
338
341
|
}
|
|
339
342
|
if (i) verdictRead(t, r);
|
|
340
343
|
if (probing && heldNotFinal(n)) probeFound = true;
|
|
341
|
-
if (latestActive && e.
|
|
344
|
+
if (latestActive && e.ue !== NOT_PENDING) {
|
|
342
345
|
// An action body reading another transaction's proposal derives
|
|
343
346
|
// from it: the two settle as one (A15; posture C, 2026-09-15). An
|
|
344
347
|
// untracked read elsewhere has no transaction to entangle.
|
|
@@ -351,11 +354,11 @@ let probeFound = false;
|
|
|
351
354
|
// committed value, so no verdict: `isPending` reads it as its read does —
|
|
352
355
|
// the owner joins the hold (held with it, or caught by a boundary that
|
|
353
356
|
// has not shown content) and answers for the commit, where it is final.
|
|
354
|
-
if (e.
|
|
357
|
+
if (e.ue !== NOT_PENDING && !(n.m & STATUS_PENDING)) {
|
|
355
358
|
if (probing && r) joinPass(t, e);
|
|
356
359
|
return staged(e);
|
|
357
360
|
}
|
|
358
|
-
} else if (e.
|
|
361
|
+
} else if (e.ue !== NOT_PENDING) {
|
|
359
362
|
if (n.m & STATUS_PENDING && !u) pendingVerdict(i ? t : null, n); else if (i && globalQueue.q) provisionalVerdict(t, !latestActive && !u);
|
|
360
363
|
// Outside a flush, the staging is an unflushed write (A28): the probe
|
|
361
364
|
// answers for the flushed world, and watches the seam of the flush that
|
package/dist/prod/deferred.js
CHANGED
|
@@ -121,7 +121,7 @@ GlobalQueue.er = e => lagging.size !== 0 ? lagOf(e, new Set) : undefined;
|
|
|
121
121
|
* does not replace (D-40) — restaged as the committed value, the hold's
|
|
122
122
|
* readers would re-derive against the old input. */ const serve = e => {
|
|
123
123
|
const r = handleAsync(t, e);
|
|
124
|
-
return t.l & CONFIG_HELD && t.
|
|
124
|
+
return t.l & CONFIG_HELD && t.ue !== NOT_PENDING ? t.ue : r;
|
|
125
125
|
};
|
|
126
126
|
const end = () => t.R & REACTIVE_DISPOSED && land(o);
|
|
127
127
|
return accessor(computed(r => {
|
|
@@ -133,26 +133,26 @@ GlobalQueue.er = e => lagging.size !== 0 ? lagOf(e, new Set) : undefined;
|
|
|
133
133
|
// Sticky, and read before this wrapper ever opens the window itself.
|
|
134
134
|
const n = l ||= !(t.m & STATUS_UNINITIALIZED) && !t.ce;
|
|
135
135
|
if (n) t.ce = true, t.l |= CONFIG_LAGS;
|
|
136
|
-
let
|
|
136
|
+
let s;
|
|
137
137
|
try {
|
|
138
|
-
|
|
138
|
+
s = e(r);
|
|
139
139
|
} catch (e) {
|
|
140
140
|
// The wrapping form: an unready source parks the node in the window,
|
|
141
141
|
// and the wait is its flight until the source's settle re-runs it.
|
|
142
|
-
if (n && e instanceof NotReadyError) ask(e);
|
|
142
|
+
if (n && e instanceof NotReadyError) ask(e); else land(o);
|
|
143
143
|
throw e;
|
|
144
144
|
}
|
|
145
|
-
if (n && typeof
|
|
146
|
-
if (isThenable(
|
|
147
|
-
ask(
|
|
148
|
-
const done = () => land(
|
|
149
|
-
|
|
150
|
-
return serve(
|
|
145
|
+
if (n && typeof s === "object" && s !== null) {
|
|
146
|
+
if (isThenable(s)) {
|
|
147
|
+
ask(s);
|
|
148
|
+
const done = () => land(s, true);
|
|
149
|
+
s.then(done, done);
|
|
150
|
+
return serve(s);
|
|
151
151
|
}
|
|
152
|
-
const e =
|
|
152
|
+
const e = s[Symbol.asyncIterator];
|
|
153
153
|
if (e) {
|
|
154
154
|
// A stream's flight ends at its first yield (or its end).
|
|
155
|
-
const r = e.call(
|
|
155
|
+
const r = e.call(s);
|
|
156
156
|
let t = true;
|
|
157
157
|
const done = () => land(o, true);
|
|
158
158
|
const o = {
|
|
@@ -160,7 +160,10 @@ GlobalQueue.er = e => lagging.size !== 0 ? lagOf(e, new Set) : undefined;
|
|
|
160
160
|
// promise, as for a plain flight: verdict and value in one flush.
|
|
161
161
|
next: e => {
|
|
162
162
|
const o = r.next(e);
|
|
163
|
-
if (t)
|
|
163
|
+
if (t) {
|
|
164
|
+
t = false;
|
|
165
|
+
if (isThenable(o)) o.then(done, done); else done();
|
|
166
|
+
}
|
|
164
167
|
return o;
|
|
165
168
|
},
|
|
166
169
|
return: e => r.return?.(e) ?? Promise.resolve({
|
|
@@ -175,7 +178,7 @@ GlobalQueue.er = e => lagging.size !== 0 ? lagOf(e, new Set) : undefined;
|
|
|
175
178
|
}
|
|
176
179
|
}
|
|
177
180
|
land(o);
|
|
178
|
-
return
|
|
181
|
+
return s;
|
|
179
182
|
}, r));
|
|
180
183
|
}
|
|
181
184
|
|