@solidjs/signals 2.0.0-rc.17 → 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 +296 -191
- package/dist/dev.attribution.js +16 -16
- package/dist/dev.js +527 -311
- package/dist/observe/core/async.js +148 -115
- package/dist/observe/core/constants.js +3 -1
- package/dist/observe/core/core.js +27 -27
- package/dist/observe/core/effect.js +29 -32
- package/dist/observe/core/graph.js +5 -5
- package/dist/observe/core/owner.js +7 -7
- package/dist/observe/core/scheduler.js +23 -12
- package/dist/observe/core/verdict.js +2 -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/store/reconcile.js +137 -121
- package/dist/observe/store/store.js +595 -618
- package/dist/observe/store/target.js +1 -5
- package/dist/prod/core/async.js +209 -176
- package/dist/prod/core/constants.js +3 -1
- package/dist/prod/core/core.js +33 -33
- package/dist/prod/core/effect.js +24 -27
- package/dist/prod/core/graph.js +2 -2
- package/dist/prod/core/lanes.js +14 -14
- package/dist/prod/core/scheduler.js +35 -24
- package/dist/prod/core/truth.js +4 -4
- package/dist/prod/core/verdict.js +7 -7
- package/dist/prod/deferred.js +17 -14
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +2 -0
- package/dist/prod/store/optimistic.js +1 -1
- package/dist/prod/store/reconcile.js +137 -121
- package/dist/prod/store/store.js +94 -117
- 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 +19 -3
- package/dist/types/core/scheduler.d.ts +15 -3
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -228,4 +228,6 @@ const defaultContext = {};
|
|
|
228
228
|
* @internal
|
|
229
229
|
*/ const $REFRESH = Symbol("refresh");
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
const NewSet = Set;
|
|
232
|
+
|
|
233
|
+
export { $REFRESH, CAUGHT_REARMED, CONFIG_AUTHORITATIVE, CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_FRESH_READ, CONFIG_GUESS, CONFIG_HAS_SNAPSHOT, CONFIG_HELD, CONFIG_HELD_FRAME, CONFIG_INPUTS_PUBLISHED, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_LAGS, CONFIG_MANUAL_WRITE, CONFIG_NO_SNAPSHOT, CONFIG_OVERRIDE, CONFIG_OWNED_WRITE, CONFIG_PROMOTED, CONFIG_REDERIVE, CONFIG_SLOT_NODE, CONFIG_STAGED, CONFIG_STAGED_ERROR, CONFIG_SYNC, CONFIG_TRANSPARENT, CONFIG_VERDICT, EFFECT_RENDER, EFFECT_TRACKED, EFFECT_USER, NOT_PENDING, NO_SNAPSHOT, NewSet, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_DISPOSED, REACTIVE_FRAME_READ, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, REACTIVE_JOINED, REACTIVE_LANE_DIRTY, REACTIVE_LANE_READ, REACTIVE_LAZY, REACTIVE_MANUAL_WRITE, REACTIVE_MISSED_WAKE, REACTIVE_NONE, REACTIVE_PROBED, REACTIVE_PROBE_UNANSWERED, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, REACTIVE_SCREEN_READ, REACTIVE_SNAPSHOT_STALE, REACTIVE_STAGED_READ, REACTIVE_ZOMBIE, STATUS_ERROR, STATUS_NONE, STATUS_PENDING, STATUS_UNINITIALIZED, SUPPORTS_PROXY, defaultContext };
|
package/dist/prod/core/core.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { notifyStatus, releaseFlightTeardown, handleAsync, clearStatus, parkLoadingWindow, stageError, settlePendingSource, releaseIfSettledUnobserved, settleErroredDependents } from "./async.js";
|
|
2
2
|
|
|
3
|
-
import { STATUS_UNINITIALIZED, REACTIVE_LAZY, REACTIVE_NONE, defaultContext, CONFIG_TRANSPARENT, CONFIG_OWNED_WRITE, CONFIG_AUTO_DISPOSE, CONFIG_SYNC, CONFIG_NO_SNAPSHOT, CONFIG_IN_SNAPSHOT_SCOPE, NOT_PENDING, NO_SNAPSHOT, CONFIG_HAS_SNAPSHOT, CONFIG_HELD, REACTIVE_MANUAL_WRITE, STATUS_ERROR, REACTIVE_DIRTY, CONFIG_OVERRIDE, REACTIVE_DISPOSED, REACTIVE_CHECK, REACTIVE_IN_HEAP, REACTIVE_REASK, REACTIVE_SNAPSHOT_STALE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_VERDICT, STATUS_PENDING, REACTIVE_LANE_DIRTY, CONFIG_GUESS, REACTIVE_RECOMPUTING_DEPS, CONFIG_LAGS, EFFECT_RENDER, CONFIG_HELD_FRAME, EFFECT_TRACKED, CONFIG_STAGED, CONFIG_STAGED_ERROR, REACTIVE_ZOMBIE, REACTIVE_MISSED_WAKE, REACTIVE_JOINED, REACTIVE_STAGED_READ, REACTIVE_PROBED, REACTIVE_FRAME_READ, REACTIVE_LANE_READ, REACTIVE_SCREEN_READ, REACTIVE_PROBE_UNANSWERED, CAUGHT_REARMED, CONFIG_PROMOTED, CONFIG_INPUTS_PUBLISHED, CONFIG_FRESH_READ, REACTIVE_IN_HEAP_HEIGHT, CONFIG_SLOT_NODE, EFFECT_USER, STATUS_NONE } from "./constants.js";
|
|
3
|
+
import { STATUS_UNINITIALIZED, REACTIVE_LAZY, REACTIVE_NONE, defaultContext, CONFIG_TRANSPARENT, CONFIG_OWNED_WRITE, CONFIG_AUTO_DISPOSE, CONFIG_SYNC, CONFIG_NO_SNAPSHOT, CONFIG_IN_SNAPSHOT_SCOPE, NOT_PENDING, NO_SNAPSHOT, CONFIG_HAS_SNAPSHOT, CONFIG_HELD, REACTIVE_MANUAL_WRITE, STATUS_ERROR, REACTIVE_DIRTY, CONFIG_OVERRIDE, REACTIVE_DISPOSED, REACTIVE_CHECK, REACTIVE_IN_HEAP, REACTIVE_REASK, REACTIVE_SNAPSHOT_STALE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_VERDICT, STATUS_PENDING, REACTIVE_LANE_DIRTY, CONFIG_GUESS, REACTIVE_RECOMPUTING_DEPS, CONFIG_LAGS, EFFECT_RENDER, CONFIG_HELD_FRAME, EFFECT_TRACKED, CONFIG_STAGED, CONFIG_STAGED_ERROR, REACTIVE_ZOMBIE, REACTIVE_MISSED_WAKE, REACTIVE_JOINED, REACTIVE_STAGED_READ, REACTIVE_PROBED, REACTIVE_FRAME_READ, REACTIVE_LANE_READ, REACTIVE_SCREEN_READ, REACTIVE_PROBE_UNANSWERED, CAUGHT_REARMED, CONFIG_PROMOTED, CONFIG_INPUTS_PUBLISHED, CONFIG_FRESH_READ, REACTIVE_IN_HEAP_HEIGHT, CONFIG_SLOT_NODE, EFFECT_USER, NewSet, STATUS_NONE } from "./constants.js";
|
|
4
4
|
|
|
5
5
|
import { NotReadyError } from "./error.js";
|
|
6
6
|
|
|
@@ -78,7 +78,7 @@ function ownerInSnapshotScope(e) {
|
|
|
78
78
|
|
|
79
79
|
function setSnapshotCapture(e) {
|
|
80
80
|
snapshotCaptureActive = e;
|
|
81
|
-
if (e && !snapshotSources) snapshotSources = new
|
|
81
|
+
if (e && !snapshotSources) snapshotSources = new NewSet;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function markSnapshotScope(e) {
|
|
@@ -199,7 +199,7 @@ function recompute(e, t = false) {
|
|
|
199
199
|
// after the new frame's first runs, and the held pass's own
|
|
200
200
|
// children die below (`disposeChildren`). The landing re-derives a
|
|
201
201
|
// fresh held frame for the reveal (`_reruns`).
|
|
202
|
-
e.
|
|
202
|
+
e.ue = NOT_PENDING;
|
|
203
203
|
if (n === EFFECT_RENDER) e.l &= ~CONFIG_HELD;
|
|
204
204
|
}
|
|
205
205
|
}
|
|
@@ -221,7 +221,7 @@ function recompute(e, t = false) {
|
|
|
221
221
|
// An error a pass staged (D-41) is replaced by this pass's answer: a
|
|
222
222
|
// value, a flight, or an error of its own (#4109, #4145).
|
|
223
223
|
if (e.l & CONFIG_STAGED_ERROR) {
|
|
224
|
-
e.
|
|
224
|
+
e.ue = NOT_PENDING;
|
|
225
225
|
e.l ^= CONFIG_STAGED_ERROR;
|
|
226
226
|
}
|
|
227
227
|
}
|
|
@@ -257,7 +257,7 @@ function recompute(e, t = false) {
|
|
|
257
257
|
e.ie = clock;
|
|
258
258
|
// The pass's previous value: its staging, else a lane node's lane value
|
|
259
259
|
// when it has one (lanes.ts), else the committed one.
|
|
260
|
-
let T = e.
|
|
260
|
+
let T = e.ue !== NOT_PENDING ? e.ue : e.l & CONFIG_OVERRIDE && e.T.v !== NOT_PENDING ? e.T.v : e.Ie;
|
|
261
261
|
let S = e.Fe;
|
|
262
262
|
let c = false;
|
|
263
263
|
// L2: did this pass read the future (REACTIVE_JOINED, set by read) — or,
|
|
@@ -307,7 +307,7 @@ function recompute(e, t = false) {
|
|
|
307
307
|
// D-41: a pass of a held node, or one that read a staging of this
|
|
308
308
|
// flush, stages its error (`stageError`).
|
|
309
309
|
if (n || !(I = stageError(e, t, true))) {
|
|
310
|
-
if (n) ext(e).
|
|
310
|
+
if (n) ext(e).se = true;
|
|
311
311
|
notifyStatus(e, n ? STATUS_PENDING : STATUS_ERROR, t);
|
|
312
312
|
// The replacement source is fully propagated now. If no new flight
|
|
313
313
|
// re-owned self, retire the superseded flight and its dependent copies.
|
|
@@ -390,7 +390,7 @@ function recompute(e, t = false) {
|
|
|
390
390
|
// publishes to — the staged `_pendingValue` when staged; a lane node's
|
|
391
391
|
// lane value (a node entering the lane this pass has none yet — its
|
|
392
392
|
// committed value, `laneStage` having voided a frame staging).
|
|
393
|
-
const o = e.
|
|
393
|
+
const o = e.ue !== NOT_PENDING ? e.ue : e.l & CONFIG_OVERRIDE && e.T.v !== NOT_PENDING ? e.T.v : e.Ie;
|
|
394
394
|
// A throwing comparator is contained inside `isSame` (A3, #2837; #4111).
|
|
395
395
|
const E = !n && l || !!e.T?.de || !isSame(e, o, T);
|
|
396
396
|
// Effects use `_equals: false` (no per-effect closure). The side effects that
|
|
@@ -403,7 +403,7 @@ function recompute(e, t = false) {
|
|
|
403
403
|
// last applied owes no run (lanes.ts).
|
|
404
404
|
!(e.R & REACTIVE_SCREEN_READ && !e.Ae && Object.is(e.ge, T)) &&
|
|
405
405
|
// A re-staging pass owes no run: the commit replays the effect (#3802).
|
|
406
|
-
e.
|
|
406
|
+
e.ue === NOT_PENDING) {
|
|
407
407
|
e.Ae = !e.T?.F;
|
|
408
408
|
// Reuse one bound runner per effect — runEffect no-ops on a stale
|
|
409
409
|
// `_modified`, so re-enqueueing the same function is harmless.
|
|
@@ -442,8 +442,8 @@ function recompute(e, t = false) {
|
|
|
442
442
|
// effect's value slot is private: the run the lane holds is what
|
|
443
443
|
// shows it — unless the effect was born held, whose first run is the
|
|
444
444
|
// commit's (A29): it re-stages, as below.
|
|
445
|
-
if (n && e.
|
|
446
|
-
} else if (t ? !((flushTransaction !== null || passTx !== null) && (A || creatorPass(f)?.R & REACTIVE_JOINED)) : n && e.
|
|
445
|
+
if (n && e.ue === NOT_PENDING) e.Ie = T; else if (n || C.ke) e.ue = T; else e.T.v = T;
|
|
446
|
+
} else if (t ? !((flushTransaction !== null || passTx !== null) && (A || creatorPass(f)?.R & REACTIVE_JOINED)) : n && e.ue === NOT_PENDING) {
|
|
447
447
|
// A first pass publishes directly. So does an effect: its value slot
|
|
448
448
|
// is private (only its own run reads it), and the staging round-trip
|
|
449
449
|
// (queuePendingNode + commitPendingNodes) paid per effect on the
|
|
@@ -456,7 +456,7 @@ function recompute(e, t = false) {
|
|
|
456
456
|
// that separation; it cannot be skipped on any path a pull can reach.
|
|
457
457
|
e.Ie = T;
|
|
458
458
|
} else {
|
|
459
|
-
e.
|
|
459
|
+
e.ue = T;
|
|
460
460
|
// Born held: in the transaction from birth, so a read of it this
|
|
461
461
|
// tick is a read of its world (the mount-during-a-hold case), not
|
|
462
462
|
// only after the seam parks it.
|
|
@@ -532,7 +532,7 @@ function recompute(e, t = false) {
|
|
|
532
532
|
// kept at a park — one spurious recompute at most). A creation pass and a
|
|
533
533
|
// tracked effect trim now: their frames are replaceable like a direct
|
|
534
534
|
// commit, and a tracked effect's spurious run would be user-visible.
|
|
535
|
-
if (!e.T?.F && e.
|
|
535
|
+
if (!e.T?.F && e.ue === NOT_PENDING && !(n && e.Ae)) {
|
|
536
536
|
if (t || n === EFFECT_TRACKED) trimStaleDeps(e); else heldTrim(e);
|
|
537
537
|
}
|
|
538
538
|
// A staged value, a parked frame (L2: the commit retires it), or status the
|
|
@@ -540,7 +540,7 @@ function recompute(e, t = false) {
|
|
|
540
540
|
// node for this flush's commit. A first pass queues only when pending or
|
|
541
541
|
// born held: otherwise its value published directly. A queued pass's
|
|
542
542
|
// children are uncommitted (CONFIG_STAGED) until that commit.
|
|
543
|
-
if (e.
|
|
543
|
+
if (e.ue !== NOT_PENDING || e.T !== null && (e.T.Ue !== null || e.T.me !== null) || (e.m & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0 && (!t || (e.m & STATUS_PENDING) !== 0)) {
|
|
544
544
|
e.l |= CONFIG_STAGED;
|
|
545
545
|
// Lane work is the lane's to reveal (its seam), not this flush's commit.
|
|
546
546
|
if (C === null) queuePendingNode(e);
|
|
@@ -629,7 +629,7 @@ function computed(e, t) {
|
|
|
629
629
|
// A loadingValue node is born committed: commit #0 is already in _value.
|
|
630
630
|
m: o ? 0 : STATUS_UNINITIALIZED,
|
|
631
631
|
ie: clock,
|
|
632
|
-
|
|
632
|
+
ue: NOT_PENDING,
|
|
633
633
|
Me: -1,
|
|
634
634
|
ce: o,
|
|
635
635
|
// Cold machinery (async slots) lives one hop away in the lazily-allocated extension — the core literal MUST
|
|
@@ -650,7 +650,7 @@ function computed(e, t) {
|
|
|
650
650
|
Se: null,
|
|
651
651
|
ae: null,
|
|
652
652
|
F: undefined,
|
|
653
|
-
|
|
653
|
+
se: undefined,
|
|
654
654
|
fe: undefined,
|
|
655
655
|
we: undefined,
|
|
656
656
|
Pe: undefined,
|
|
@@ -802,7 +802,7 @@ function computed(e, t) {
|
|
|
802
802
|
R: REACTIVE_LAZY,
|
|
803
803
|
m: STATUS_UNINITIALIZED,
|
|
804
804
|
ie: clock,
|
|
805
|
-
|
|
805
|
+
ue: NOT_PENDING,
|
|
806
806
|
Me: -1,
|
|
807
807
|
ce: false,
|
|
808
808
|
Ae: false,
|
|
@@ -839,7 +839,7 @@ function setEffectStatusNotify(e) {
|
|
|
839
839
|
* 0, and only effect literals carry the field) get the shared notifier.
|
|
840
840
|
* Presence doubles as the "display consumer" membership test in the status
|
|
841
841
|
* walks, exactly as the per-node field did when every effect carried one. */ function statusNotifierOf(e) {
|
|
842
|
-
return e.i ? effectStatusNotify
|
|
842
|
+
return e.i ? effectStatusNotify : null;
|
|
843
843
|
}
|
|
844
844
|
|
|
845
845
|
const lazyOptions = {
|
|
@@ -874,7 +874,7 @@ function signal(e, t) {
|
|
|
874
874
|
o: null,
|
|
875
875
|
ve: null,
|
|
876
876
|
ie: clock,
|
|
877
|
-
|
|
877
|
+
ue: NOT_PENDING,
|
|
878
878
|
// Signal-literal diet (§12e): NO _time/_fn/_statusFlags slots. Stores
|
|
879
879
|
// materialize one signal per touched leaf, so signal bytes are store
|
|
880
880
|
// bytes. _time is write-only on signals (every read site is computed-
|
|
@@ -914,7 +914,7 @@ function isEqual(e, t) {
|
|
|
914
914
|
o: null,
|
|
915
915
|
ve: null,
|
|
916
916
|
ie: clock,
|
|
917
|
-
|
|
917
|
+
ue: NOT_PENDING,
|
|
918
918
|
Me: -1,
|
|
919
919
|
T: null,
|
|
920
920
|
O: n,
|
|
@@ -1044,7 +1044,7 @@ function setVerdict(e) {
|
|
|
1044
1044
|
* never the graph — A32).
|
|
1045
1045
|
* False means the reader derives from the staged value.
|
|
1046
1046
|
*/ function readerSeesCommitted(e, t) {
|
|
1047
|
-
return !t || e.
|
|
1047
|
+
return !t || e.ue === NOT_PENDING || t.l & CONFIG_CHILDREN_FORBIDDEN;
|
|
1048
1048
|
}
|
|
1049
1049
|
|
|
1050
1050
|
/** A28 — set when a node is staged (queuePendingNode) OUTSIDE a flush;
|
|
@@ -1065,7 +1065,7 @@ function markUnflushedStaged() {
|
|
|
1065
1065
|
* is unflushed. Exempt: promoted writes (A28 (4): a write issued inside a
|
|
1066
1066
|
* recompute is promoted at that recompute's end — boundary and loading
|
|
1067
1067
|
* machinery, signals declared for in-computation writes). */ function unflushedValue(e) {
|
|
1068
|
-
if (globalQueue.q || e.
|
|
1068
|
+
if (globalQueue.q || e.ue === NOT_PENDING || e.l & CONFIG_PROMOTED) return NOT_PENDING;
|
|
1069
1069
|
// A held node (L2) carries a staged value between flushes too, but it was
|
|
1070
1070
|
// flushed — and parked. Not an unflushed write — unless rewritten since:
|
|
1071
1071
|
// then the flushed staging is what the world sees until the next flush.
|
|
@@ -1078,7 +1078,7 @@ function markUnflushedStaged() {
|
|
|
1078
1078
|
* stash is stamped with the clock, which that flush advances. */ function stashFlushed(e) {
|
|
1079
1079
|
const t = e.T;
|
|
1080
1080
|
if (t.Be !== clock) {
|
|
1081
|
-
t.je = e.
|
|
1081
|
+
t.je = e.ue;
|
|
1082
1082
|
t.Be = clock;
|
|
1083
1083
|
unflushedStaged = true;
|
|
1084
1084
|
}
|
|
@@ -1137,7 +1137,7 @@ function read(e) {
|
|
|
1137
1137
|
// The verdict windows (`latest`, `isPending`; verdict.ts): one cold path,
|
|
1138
1138
|
// off this one, present only while a window is open.
|
|
1139
1139
|
if (verdict !== null) return verdict(e, t);
|
|
1140
|
-
if (!n.X && e.T?.Pe === undefined && !snapshotCaptureActive && (!unflushedStaged || e.
|
|
1140
|
+
if (!n.X && e.T?.Pe === undefined && !snapshotCaptureActive && (!unflushedStaged || e.ue === NOT_PENDING) && // A28, see readNodeFast
|
|
1141
1141
|
!(e.l & CONFIG_OVERRIDE) && // lanes: the slow path's one arm
|
|
1142
1142
|
true) {
|
|
1143
1143
|
if (t) {
|
|
@@ -1158,13 +1158,13 @@ function read(e) {
|
|
|
1158
1158
|
}
|
|
1159
1159
|
}
|
|
1160
1160
|
// Committed visibility for untracked and children-forbidden readers.
|
|
1161
|
-
if (!t || e.
|
|
1161
|
+
if (!t || e.ue === NOT_PENDING || t.l & CONFIG_CHILDREN_FORBIDDEN) return e.Ie;
|
|
1162
1162
|
// (A plain signal is never uninitialized — the carve-out is `serve`'s.)
|
|
1163
1163
|
// Lane work over a folded lane (D-34), once the frame has a
|
|
1164
1164
|
// transaction, reads the screen too.
|
|
1165
1165
|
if ((observeFlightHook && t.l & CONFIG_VERDICT || laneStageHook && passLane?.folded) && stagedScreen(t)) return e.Ie;
|
|
1166
1166
|
stagedRead(t);
|
|
1167
|
-
return e.
|
|
1167
|
+
return e.ue;
|
|
1168
1168
|
}
|
|
1169
1169
|
// Rule 3: this read serves the committed value to a render effect outside a
|
|
1170
1170
|
// parking flush (decided after the pull below — a pull can join).
|
|
@@ -1250,7 +1250,7 @@ function read(e) {
|
|
|
1250
1250
|
const n = e.T?.Pe;
|
|
1251
1251
|
if (n !== undefined) {
|
|
1252
1252
|
const o = n === NO_SNAPSHOT ? undefined : n;
|
|
1253
|
-
const E = e.
|
|
1253
|
+
const E = e.ue !== NOT_PENDING ? e.ue : e.Ie;
|
|
1254
1254
|
if (E !== o) t.R |= REACTIVE_SNAPSHOT_STALE;
|
|
1255
1255
|
return o;
|
|
1256
1256
|
}
|
|
@@ -1287,7 +1287,7 @@ function read(e) {
|
|
|
1287
1287
|
// an untracked reader has nothing to serve and holds (A19 exception 1) — a
|
|
1288
1288
|
// bookkeeping read (`spectate`) likewise, and a children-forbidden reader
|
|
1289
1289
|
// (A32: the frame, which has nothing here).
|
|
1290
|
-
if (e.
|
|
1290
|
+
if (e.ue !== NOT_PENDING && e.m & STATUS_UNINITIALIZED && (!t || spectating || t.l & CONFIG_CHILDREN_FORBIDDEN)) throw new NotReadyError(null);
|
|
1291
1291
|
const n = t && unflushedStaged ? unflushedValue(e) : NOT_PENDING;
|
|
1292
1292
|
if (n !== NOT_PENDING) {
|
|
1293
1293
|
markLateLinker(t);
|
|
@@ -1297,8 +1297,8 @@ function read(e) {
|
|
|
1297
1297
|
if (observeFlightHook && t.l & CONFIG_VERDICT && !(e.m & STATUS_UNINITIALIZED) && stagedScreen(t)) return e.Ie;
|
|
1298
1298
|
stagedRead(t, e);
|
|
1299
1299
|
// D-41: the staged answer is an error (`stageError`).
|
|
1300
|
-
if (e.l & CONFIG_STAGED_ERROR) throw e.
|
|
1301
|
-
return e.
|
|
1300
|
+
if (e.l & CONFIG_STAGED_ERROR) throw e.ue;
|
|
1301
|
+
return e.ue;
|
|
1302
1302
|
}
|
|
1303
1303
|
|
|
1304
1304
|
/** A pass read a staging of this flush: it derives from what the flush may
|
|
@@ -1393,7 +1393,7 @@ function read(e) {
|
|
|
1393
1393
|
|
|
1394
1394
|
function setSignal(e, t) {
|
|
1395
1395
|
if (writeHook !== null) writeHook(e);
|
|
1396
|
-
const n = e.
|
|
1396
|
+
const n = e.ue === NOT_PENDING ? e.Ie : e.ue;
|
|
1397
1397
|
if (typeof t === "function") t = t(n);
|
|
1398
1398
|
// Lanes: a write landing on a guess is its truth (A18 — an async guess's
|
|
1399
1399
|
// own landing), judged against the guess; one landing on a lane's
|
|
@@ -1420,12 +1420,12 @@ function setSignal(e, t) {
|
|
|
1420
1420
|
// pass reads a value the server never had. Store leaves written here are
|
|
1421
1421
|
// plain signals and qualify the same way.
|
|
1422
1422
|
if (snapshotCaptureActive) captureWriteSnapshot(e, n);
|
|
1423
|
-
const E = e.
|
|
1423
|
+
const E = e.ue !== NOT_PENDING;
|
|
1424
1424
|
if (!E) queuePendingNode(e);
|
|
1425
1425
|
// A28: a held node rewritten outside a flush keeps its flushed staging
|
|
1426
1426
|
// for every reader until the flush that carries the rewrite.
|
|
1427
1427
|
else if (e.l & CONFIG_HELD && !globalQueue.q) stashFlushed(e);
|
|
1428
|
-
e.
|
|
1428
|
+
e.ue = t;
|
|
1429
1429
|
if (context !== null) notePromotedWrite(e);
|
|
1430
1430
|
// _time is a computed-only slot (§12e): writing it on a signal would fork
|
|
1431
1431
|
// the lean shape. Every read site is computed-typed.
|
|
@@ -1482,7 +1482,7 @@ function setSignal(e, t) {
|
|
|
1482
1482
|
e.R = e.R & ~REACTIVE_CHECK | REACTIVE_DIRTY;
|
|
1483
1483
|
insertIntoHeap(e, dirtyQueue);
|
|
1484
1484
|
schedule();
|
|
1485
|
-
} else if (e.
|
|
1485
|
+
} else if (e.ue !== NOT_PENDING) e.R |= REACTIVE_MANUAL_WRITE;
|
|
1486
1486
|
return t;
|
|
1487
1487
|
}
|
|
1488
1488
|
|
package/dist/prod/core/effect.js
CHANGED
|
@@ -15,44 +15,47 @@ import { globalQueue, schedule, heldRunHook, haltReactivity, GlobalQueue } from
|
|
|
15
15
|
* automatically added to the queue of effects to re-execute, which will cause them to fetch their
|
|
16
16
|
* sources and recompute
|
|
17
17
|
*/ function effect(t, e, E, u) {
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
recompute(
|
|
18
|
+
const r = !!u?.user;
|
|
19
|
+
const f = createEffectNode(t, e, E, r ? EFFECT_USER : EFFECT_RENDER, u);
|
|
20
|
+
recompute(f, true);
|
|
21
21
|
// A first pass that read a staged value was staged itself (recompute: born
|
|
22
22
|
// staged); the flush's commit replays this effect. Its first run is not this
|
|
23
23
|
// creation's (A29). A lane's node likewise: its run is the lane's, queued
|
|
24
24
|
// by the pass and released at the reveal (lanes.ts).
|
|
25
|
-
!u?.defer &&
|
|
25
|
+
!u?.defer && f.ue === NOT_PENDING && !f.T?.Re?.v && (f.i === EFFECT_USER || u?.schedule ? globalQueue.enqueue(f.i, runEffect.bind(null, f)) : runEffect(f, f.i));
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function notifyEffectStatus(
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
if (E & STATUS_ERROR) {
|
|
28
|
+
function notifyEffectStatus() {
|
|
29
|
+
const t = this.m;
|
|
30
|
+
const e = this.T?.F;
|
|
31
|
+
if (t & STATUS_ERROR) {
|
|
33
32
|
globalQueue.notify(this, STATUS_PENDING, 0);
|
|
34
33
|
if (this.i === EFFECT_USER) {
|
|
35
34
|
// The error handler is the error arm of the effect phase (#2840 ruling):
|
|
36
35
|
// queue it like the effect function. It runs in the same imperative,
|
|
37
36
|
// writable scope and throws escalate the same way. No payload is queued — the node already carries `_statusFlags`/`_error`,
|
|
38
37
|
// and the runner dispatches on them, so a recovery before the effect
|
|
39
|
-
// phase takes the success arm instead.
|
|
40
|
-
//
|
|
41
|
-
// re-propagates unblocked at commit.
|
|
38
|
+
// phase takes the success arm instead. (Re-read: the boundary
|
|
39
|
+
// notify above can run a redraw.)
|
|
42
40
|
if (this.m & STATUS_ERROR) {
|
|
43
41
|
this.Ae = true;
|
|
44
42
|
globalQueue.enqueue(this.i, this.W ??= runEffect.bind(null, this));
|
|
45
43
|
}
|
|
46
44
|
return;
|
|
47
45
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
haltReactivity(unwrapStatusError(u));
|
|
52
|
-
throw u;
|
|
53
|
-
}
|
|
46
|
+
// Dev locates the halt at the node that threw: the StatusError's
|
|
47
|
+
// source, upstream of this effect when a computed failed.
|
|
48
|
+
escalate(this, unwrapStatusError(e), e, this);
|
|
54
49
|
} else if (this.i === EFFECT_RENDER) {
|
|
55
|
-
globalQueue.notify(this, STATUS_PENDING | STATUS_ERROR,
|
|
50
|
+
globalQueue.notify(this, STATUS_PENDING | STATUS_ERROR, t, e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** An effect's error no boundary takes halts the system (boundary-or-halt):
|
|
55
|
+
* halted with `cause`, `thrown` rethrown; dev locates it at `subject`. */ function escalate(t, e, E = e, u = t) {
|
|
56
|
+
if (!globalQueue.notify(t, STATUS_ERROR, STATUS_ERROR)) {
|
|
57
|
+
haltReactivity(e);
|
|
58
|
+
throw E;
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
|
|
@@ -88,10 +91,7 @@ function runEffect(t, e) {
|
|
|
88
91
|
e?.();
|
|
89
92
|
}) : console.error(e);
|
|
90
93
|
} catch (e) {
|
|
91
|
-
|
|
92
|
-
haltReactivity(e);
|
|
93
|
-
throw e;
|
|
94
|
-
}
|
|
94
|
+
escalate(t, e);
|
|
95
95
|
}
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
@@ -109,10 +109,7 @@ function runEffect(t, e) {
|
|
|
109
109
|
} catch (e) {
|
|
110
110
|
ext(t).F = new StatusError(t, e);
|
|
111
111
|
t.m |= STATUS_ERROR;
|
|
112
|
-
|
|
113
|
-
haltReactivity(e);
|
|
114
|
-
throw e;
|
|
115
|
-
}
|
|
112
|
+
escalate(t, e);
|
|
116
113
|
} finally {
|
|
117
114
|
t.ge = t.Ie;
|
|
118
115
|
t.Ae = false;
|
package/dist/prod/core/graph.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { REACTIVE_RECOMPUTING_DEPS, CONFIG_AUTO_DISPOSE, STATUS_PENDING, REACTIVE_DISPOSED, REACTIVE_ZOMBIE, CONFIG_SLOT_NODE } from "./constants.js";
|
|
1
|
+
import { NewSet, REACTIVE_RECOMPUTING_DEPS, CONFIG_AUTO_DISPOSE, STATUS_PENDING, REACTIVE_DISPOSED, REACTIVE_ZOMBIE, CONFIG_SLOT_NODE } from "./constants.js";
|
|
2
2
|
|
|
3
3
|
import { deleteFromHeap } from "./heap.js";
|
|
4
4
|
|
|
@@ -107,7 +107,7 @@ function unobserved(e) {
|
|
|
107
107
|
* stays alive and serves its cache, uniform with observed memos) while
|
|
108
108
|
* reclamation still happens within one microtask — the enqueue site arms
|
|
109
109
|
* schedule(), so a flush is guaranteed even when no other work is queued.
|
|
110
|
-
*/ const dormantNodes = new
|
|
110
|
+
*/ const dormantNodes = new NewSet;
|
|
111
111
|
|
|
112
112
|
function sweepDormant() {
|
|
113
113
|
if (dormantNodes.size === 0) return;
|
package/dist/prod/core/lanes.js
CHANGED
|
@@ -119,7 +119,7 @@ function applyGuesses(e) {
|
|
|
119
119
|
// value re-asked renews the question; nothing to notify.
|
|
120
120
|
u = !t.xe || !t.xe(laneValueOf(t), l);
|
|
121
121
|
if (!(t.l & CONFIG_GUESS)) {
|
|
122
|
-
t.
|
|
122
|
+
t.ue = NOT_PENDING;
|
|
123
123
|
t.l |= CONFIG_GUESS;
|
|
124
124
|
}
|
|
125
125
|
t.T.v = l;
|
|
@@ -264,7 +264,7 @@ function unlink(e) {
|
|
|
264
264
|
}
|
|
265
265
|
if (!e.i) {
|
|
266
266
|
if (!(e.l & CONFIG_OVERRIDE)) {
|
|
267
|
-
e.
|
|
267
|
+
e.ue = NOT_PENDING;
|
|
268
268
|
e.l = e.l & -1048833 | CONFIG_OVERRIDE;
|
|
269
269
|
ext(e);
|
|
270
270
|
}
|
|
@@ -321,7 +321,7 @@ function supersede(e, n, s) {
|
|
|
321
321
|
// A confirmation is silent (A17); only truth readers are told.
|
|
322
322
|
GlobalQueue.sn?.(t);
|
|
323
323
|
}
|
|
324
|
-
e.
|
|
324
|
+
e.ue = n;
|
|
325
325
|
joinFuture(l);
|
|
326
326
|
}
|
|
327
327
|
|
|
@@ -365,7 +365,7 @@ function supersede(e, n, s) {
|
|
|
365
365
|
// of its flight observes it (#3648, #3651; #3305's commit beneath a
|
|
366
366
|
// flight).
|
|
367
367
|
u.Re = null;
|
|
368
|
-
if (!i && !r) l.
|
|
368
|
+
if (!i && !r) l.ue = f;
|
|
369
369
|
commitPendingNode(l);
|
|
370
370
|
if (!i) {
|
|
371
371
|
if (l.R & (REACTIVE_IN_HEAP | REACTIVE_DIRTY | REACTIVE_CHECK) || l.m & STATUS_PENDING) l.l |= CONFIG_INPUTS_PUBLISHED;
|
|
@@ -376,7 +376,7 @@ function supersede(e, n, s) {
|
|
|
376
376
|
// else the value it covered — is the parent's to land, and its readers
|
|
377
377
|
// re-derive from it there. What the screen showed stays the screen
|
|
378
378
|
// until then (A18 (c)).
|
|
379
|
-
if (l.
|
|
379
|
+
if (l.ue === NOT_PENDING) l.ue = covered(l);
|
|
380
380
|
if (e.ke) l.Ie = o;
|
|
381
381
|
holdNode(l, n);
|
|
382
382
|
insertSubs(l);
|
|
@@ -390,7 +390,7 @@ function supersede(e, n, s) {
|
|
|
390
390
|
// it: an input's truth equal to its committed value is silent).
|
|
391
391
|
u.Re = null;
|
|
392
392
|
if (!i) {
|
|
393
|
-
if (E !== NOT_PENDING && e.ke) l.
|
|
393
|
+
if (E !== NOT_PENDING && e.ke) l.ue = E;
|
|
394
394
|
if (l.m & STATUS_PENDING) {
|
|
395
395
|
u.Se = null;
|
|
396
396
|
enqueueSub(l);
|
|
@@ -470,7 +470,7 @@ function supersede(e, n, s) {
|
|
|
470
470
|
// joined its transaction) reads the answer it waited on — the lane's
|
|
471
471
|
// staging, revealed at this seam.
|
|
472
472
|
if (u & STATUS_PENDING && n.T.v === NOT_PENDING) return NOT_PENDING;
|
|
473
|
-
if (n.
|
|
473
|
+
if (n.ue !== NOT_PENDING && e.l & CONFIG_HELD && flushTransaction !== null && resolveTx(flushTransaction) === txOf(e)) return n.ue;
|
|
474
474
|
}
|
|
475
475
|
if (t.ln || !s && u & STATUS_PENDING) {
|
|
476
476
|
if (!s && !t.ke && u & STATUS_UNINITIALIZED) throw new NotReadyError(null);
|
|
@@ -529,7 +529,7 @@ function supersede(e, n, s) {
|
|
|
529
529
|
for (let e = 0; e < t.tn.length && lanes.indexOf(t) !== -1; e++) {
|
|
530
530
|
const n = t.tn[e];
|
|
531
531
|
if (n.l & CONFIG_GUESS && n.T.Re === t) {
|
|
532
|
-
const e = n.
|
|
532
|
+
const e = n.ue !== NOT_PENDING ? n.ue : covered(n);
|
|
533
533
|
supersede(n, e, !n.xe || !n.xe(n.T.v, e));
|
|
534
534
|
}
|
|
535
535
|
}
|
|
@@ -555,9 +555,9 @@ function laneSeam(e, n) {
|
|
|
555
555
|
}
|
|
556
556
|
const t = s.T;
|
|
557
557
|
if (t.Re !== e) continue;
|
|
558
|
-
if (!(s.l & CONFIG_GUESS) && !s.i && s.
|
|
559
|
-
t.v = s.
|
|
560
|
-
s.
|
|
558
|
+
if (!(s.l & CONFIG_GUESS) && !s.i && s.ue !== NOT_PENDING) {
|
|
559
|
+
t.v = s.ue;
|
|
560
|
+
s.ue = NOT_PENDING;
|
|
561
561
|
}
|
|
562
562
|
// The frame this pass built is the screen's now; the one it replaced
|
|
563
563
|
// goes (as `commitPendingNode` retires a committed pass's).
|
|
@@ -611,7 +611,7 @@ function laneSeam(e, n) {
|
|
|
611
611
|
// folds a current one beneath it (D-34): true.
|
|
612
612
|
const s = stale(e, question);
|
|
613
613
|
if (GlobalQueue.an?.(e, n, s) || s) {
|
|
614
|
-
e.
|
|
614
|
+
e.ue = n;
|
|
615
615
|
e.l |= CONFIG_HELD;
|
|
616
616
|
schedule();
|
|
617
617
|
return n;
|
|
@@ -620,7 +620,7 @@ function laneSeam(e, n) {
|
|
|
620
620
|
} else {
|
|
621
621
|
const s = txOf(e);
|
|
622
622
|
if (e.xe && e.xe(laneValueOf(e), n)) return n;
|
|
623
|
-
if (s.ke) e.
|
|
623
|
+
if (s.ke) e.ue = n; else e.T.v = n;
|
|
624
624
|
if (e.X !== undefined) e.ie = clock;
|
|
625
625
|
insertSubs(e);
|
|
626
626
|
laneDirty(e, s);
|
|
@@ -643,7 +643,7 @@ function laneSeam(e, n) {
|
|
|
643
643
|
* A24). The guess's own question answering supersedes as usual. */ function laneOutcome(e, n, s) {
|
|
644
644
|
if (s) return true;
|
|
645
645
|
if (stale(e, answered(e))) {
|
|
646
|
-
e.
|
|
646
|
+
e.ue = n;
|
|
647
647
|
e.l |= CONFIG_HELD;
|
|
648
648
|
return true;
|
|
649
649
|
}
|
|
@@ -612,18 +612,18 @@ class GlobalQueue {
|
|
|
612
612
|
// stale stamp was the bridge that entangled unrelated updates
|
|
613
613
|
// with a never-resolving flight). Its observers are held and
|
|
614
614
|
// wait on its flight (`blocked`).
|
|
615
|
-
if (e.
|
|
615
|
+
if (e.ue === NOT_PENDING && e.m & STATUS_UNINITIALIZED && e.i !== EFFECT_RENDER) continue;
|
|
616
616
|
// A34 (2): a tick whose writes net to the committed value made no
|
|
617
617
|
// proposal (`setShow(false); setShow(true)` on a committed true) —
|
|
618
618
|
// not staged, not held, pends nothing; a later write to it is
|
|
619
619
|
// plain mainline. (A node already held stays held when written
|
|
620
620
|
// back: A34 (1).)
|
|
621
|
-
if (e.
|
|
621
|
+
if (e.ue !== NOT_PENDING && !(e.m & (STATUS_PENDING | STATUS_UNINITIALIZED)) && e.T?.Ue == null && e.T?.me == null &&
|
|
622
622
|
// The comparator last: a pass that created children (an object
|
|
623
623
|
// owning a fresh async memo, #4111) must not have it read them.
|
|
624
624
|
// A NotReady read there is a change (`isSame`).
|
|
625
|
-
isSame(e, e.Ie, e.
|
|
626
|
-
e.
|
|
625
|
+
isSame(e, e.Ie, e.ue)) {
|
|
626
|
+
e.ue = NOT_PENDING;
|
|
627
627
|
e.l &= ~CONFIG_STAGED;
|
|
628
628
|
continue;
|
|
629
629
|
}
|
|
@@ -796,28 +796,31 @@ class GlobalQueue {
|
|
|
796
796
|
* or without the held read) owes nothing. A run this transaction stashed
|
|
797
797
|
* for it is void (#3322: an effect has one value slot, and the stale pass
|
|
798
798
|
* overwrote the value that run was for) — the re-derivation's run replaces
|
|
799
|
-
* it. */ function reruns(e) {
|
|
800
|
-
|
|
801
|
-
|
|
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];
|
|
802
803
|
// An errored reader's display is its error (D-39): the landing gives it
|
|
803
804
|
// nothing to re-derive, and a re-run would be a read that retries the
|
|
804
805
|
// errored source (#3945).
|
|
805
|
-
if (
|
|
806
|
-
if (
|
|
807
|
-
|
|
808
|
-
|
|
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;
|
|
809
811
|
// Its frame is replaced by the re-derivation: a run one of its
|
|
810
812
|
// children queued this flush (re-run by the same landing) is for the
|
|
811
813
|
// frame being replaced — void too (#3404).
|
|
812
|
-
for (let e =
|
|
813
|
-
enqueueSub(
|
|
814
|
+
for (let e = t.De; e !== null; e = e.pe) if (e.i) e.Ae = false;
|
|
815
|
+
enqueueSub(t);
|
|
814
816
|
}
|
|
815
817
|
}
|
|
816
818
|
e.En.length = 0;
|
|
819
|
+
return n;
|
|
817
820
|
}
|
|
818
821
|
|
|
819
822
|
/** The landing: the held frame becomes the frame. */ function land(e) {
|
|
820
|
-
reruns(e);
|
|
823
|
+
const n = reruns(e);
|
|
821
824
|
if (e.I !== null) releaseMarksHook(e.I);
|
|
822
825
|
// Old children die in the commits (cleanups first), then the stashed
|
|
823
826
|
// effects run ahead of this flush's own. A node a lane took over since
|
|
@@ -832,7 +835,15 @@ class GlobalQueue {
|
|
|
832
835
|
// `u`, which has left `transactions`: the write is this landing's, and
|
|
833
836
|
// the next flush must not park in it (#4089).
|
|
834
837
|
if (flushTransaction === e) flushTransaction = null;
|
|
835
|
-
|
|
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);
|
|
836
847
|
}
|
|
837
848
|
|
|
838
849
|
/** The held runs join this flush's effect phase after its own runs (the
|
|
@@ -935,16 +946,16 @@ function commitPendingNode(e) {
|
|
|
935
946
|
// commits a value.
|
|
936
947
|
if (!n.X) {
|
|
937
948
|
e.l &= -385;
|
|
938
|
-
if (e.
|
|
939
|
-
e.Ie = e.
|
|
940
|
-
e.
|
|
949
|
+
if (e.ue !== NOT_PENDING) {
|
|
950
|
+
e.Ie = e.ue;
|
|
951
|
+
e.ue = NOT_PENDING;
|
|
941
952
|
}
|
|
942
953
|
return;
|
|
943
954
|
}
|
|
944
955
|
// Computeds only from here (`_statusFlags` is not a signal field). A
|
|
945
956
|
// commit beneath a flight publishes its inputs (A15 reveal corollary,
|
|
946
957
|
// #3305): a reveal of it must observe, not show the pre-flight value.
|
|
947
|
-
const o = e.
|
|
958
|
+
const o = e.ue === NOT_PENDING && (n.m & STATUS_PENDING) !== 0;
|
|
948
959
|
const t = e.l & CONFIG_STAGED_ERROR;
|
|
949
960
|
// An answer commits: the error it replaces leaves the display (D-41).
|
|
950
961
|
if (!o && n.T) n.T.de = undefined;
|
|
@@ -954,13 +965,13 @@ function commitPendingNode(e) {
|
|
|
954
965
|
// see it in the cycle after this seam: a tracked re-read there is not a
|
|
955
966
|
// retry (`read`), or a boundary re-derived by it would retry it forever.
|
|
956
967
|
if (t) {
|
|
957
|
-
const o = e.
|
|
958
|
-
e.
|
|
968
|
+
const o = e.ue;
|
|
969
|
+
e.ue = NOT_PENDING;
|
|
959
970
|
e.ie = clock + 1;
|
|
960
971
|
notifyStatus(n, STATUS_ERROR, o);
|
|
961
|
-
} else if (e.
|
|
962
|
-
e.Ie = e.
|
|
963
|
-
e.
|
|
972
|
+
} else if (e.ue !== NOT_PENDING) {
|
|
973
|
+
e.Ie = e.ue;
|
|
974
|
+
e.ue = NOT_PENDING;
|
|
964
975
|
// A node born staged (recompute) initializes at this commit.
|
|
965
976
|
n.m &= ~STATUS_UNINITIALIZED;
|
|
966
977
|
// A quiet re-ask's classification survives its landing and dies with
|
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
|
}
|