@solidjs/signals 2.0.0-rc.14 → 2.0.0-rc.15
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 +248 -189
- package/dist/dev.attribution.js +124 -41
- package/dist/dev.js +553 -322
- package/dist/observe/affects.js +34 -31
- package/dist/observe/boundaries.js +166 -132
- package/dist/observe/core/async.js +90 -83
- package/dist/observe/core/attribution-queries.js +1 -1
- package/dist/observe/core/attribution.js +281 -197
- package/dist/observe/core/constants.js +7 -2
- package/dist/observe/core/context.js +3 -3
- package/dist/observe/core/core.js +277 -245
- package/dist/observe/core/dev.js +3 -3
- package/dist/observe/core/effect.js +21 -21
- package/dist/observe/core/external.js +2 -2
- package/dist/observe/core/graph.js +25 -25
- package/dist/observe/core/heap.js +9 -9
- package/dist/observe/core/lanes.js +206 -160
- package/dist/observe/core/owner.js +27 -27
- package/dist/observe/core/scheduler.js +92 -86
- package/dist/observe/core/verdict.js +66 -54
- package/dist/observe/map.js +35 -35
- package/dist/observe/reveal.js +24 -24
- package/dist/observe/signals.js +38 -28
- package/dist/observe/store/affects.js +75 -68
- package/dist/observe/store/hooks.js +13 -0
- package/dist/observe/store/index.js +0 -2
- package/dist/observe/store/optimistic.js +67 -34
- package/dist/observe/store/projection.js +37 -31
- package/dist/observe/store/reconcile.js +32 -30
- package/dist/observe/store/store.js +128 -85
- package/dist/prod/affects.js +34 -31
- package/dist/prod/boundaries.js +143 -109
- package/dist/prod/core/async.js +64 -67
- package/dist/prod/core/constants.js +7 -2
- package/dist/prod/core/context.js +3 -3
- package/dist/prod/core/core.js +302 -270
- package/dist/prod/core/effect.js +38 -38
- package/dist/prod/core/external.js +4 -4
- package/dist/prod/core/graph.js +27 -27
- package/dist/prod/core/heap.js +30 -30
- package/dist/prod/core/lanes.js +257 -211
- package/dist/prod/core/owner.js +39 -39
- package/dist/prod/core/scheduler.js +125 -119
- package/dist/prod/core/verdict.js +70 -58
- package/dist/prod/map.js +73 -73
- package/dist/prod/reveal.js +38 -38
- package/dist/prod/signals.js +30 -20
- package/dist/prod/store/affects.js +75 -68
- package/dist/prod/store/hooks.js +13 -0
- package/dist/prod/store/index.js +0 -2
- package/dist/prod/store/optimistic.js +114 -81
- package/dist/prod/store/projection.js +30 -24
- package/dist/prod/store/reconcile.js +32 -30
- package/dist/prod/store/store.js +136 -93
- package/dist/types/boundaries.d.ts +4 -0
- package/dist/types/core/attribution.d.ts +6 -2
- package/dist/types/core/constants.d.ts +5 -0
- package/dist/types/core/core.d.ts +33 -3
- package/dist/types/core/lanes.d.ts +10 -0
- package/dist/types/core/scheduler.d.ts +12 -6
- package/dist/types/core/types.d.ts +0 -6
- package/dist/types/store/affects.d.ts +11 -0
- package/dist/types/store/hooks.d.ts +48 -0
- package/dist/types/store/index.d.ts +0 -1
- package/dist/types/store/store.d.ts +3 -38
- package/package.json +1 -1
package/dist/prod/core/lanes.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CONFIG_GUESS, NOT_PENDING, CONFIG_OVERRIDE, REACTIVE_DISPOSED, CONFIG_VERDICT, REACTIVE_PROBE_UNANSWERED, CONFIG_AUTHORITATIVE, CONFIG_CHILDREN_FORBIDDEN, STATUS_PENDING, EFFECT_RENDER, CONFIG_HELD, STATUS_UNINITIALIZED, REACTIVE_SCREEN_READ, REACTIVE_FRAME_READ, REACTIVE_LANE_READ, REACTIVE_RECOMPUTING_DEPS,
|
|
1
|
+
import { CONFIG_GUESS, NOT_PENDING, CONFIG_OVERRIDE, REACTIVE_DISPOSED, CONFIG_VERDICT, REACTIVE_PROBE_UNANSWERED, REACTIVE_LANE_DIRTY, CONFIG_AUTHORITATIVE, CONFIG_CHILDREN_FORBIDDEN, STATUS_PENDING, EFFECT_RENDER, CONFIG_HELD, STATUS_UNINITIALIZED, REACTIVE_SCREEN_READ, REACTIVE_FRAME_READ, REACTIVE_LANE_READ, REACTIVE_RECOMPUTING_DEPS, CONFIG_STAGED, REACTIVE_JOINED, REACTIVE_STAGED_READ, CONFIG_SLOT_NODE, REACTIVE_IN_HEAP, REACTIVE_DIRTY, REACTIVE_CHECK, CONFIG_INPUTS_PUBLISHED } from "./constants.js";
|
|
2
2
|
|
|
3
3
|
import { tracking, ext, stagedRead } from "./core.js";
|
|
4
4
|
|
|
@@ -38,6 +38,8 @@ import { schedule, question, nextQuestion, GlobalQueue, blocked, txOf, passLane,
|
|
|
38
38
|
/** Live lanes (parented). Scanned at every seam while non-empty. */
|
|
39
39
|
const lanes = [];
|
|
40
40
|
|
|
41
|
+
/** A pass left a shown slot the equality gate can no longer see (#3892). */ const LEFT_SHOWN = 1 << 20;
|
|
42
|
+
|
|
41
43
|
function newLane(e) {
|
|
42
44
|
const n = newTransaction(true, e);
|
|
43
45
|
lanes.push(n);
|
|
@@ -47,15 +49,15 @@ function newLane(e) {
|
|
|
47
49
|
/** A lane node's current value: its guess, or the latest it derived — the
|
|
48
50
|
* staging a shown lane holds for its next reveal, else its slot; the
|
|
49
51
|
* committed value while it has none (its first lane pass in flight). */ function laneValueOf(e) {
|
|
50
|
-
if (!(e.
|
|
51
|
-
const n = e.m.
|
|
52
|
-
return n !== NOT_PENDING ? n : e.
|
|
52
|
+
if (!(e.i & CONFIG_GUESS) && e.Oe !== NOT_PENDING) return e.Oe;
|
|
53
|
+
const n = e.m.B;
|
|
54
|
+
return n !== NOT_PENDING ? n : e.Ae;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
/** What the screen shows for a lane's node: the lane's value once the lane
|
|
56
58
|
* has revealed, the committed truth before. */ function display(e) {
|
|
57
|
-
const n = e.m.
|
|
58
|
-
return e.m.
|
|
59
|
+
const n = e.m.B;
|
|
60
|
+
return e.m.He.Ze && n !== NOT_PENDING ? n : e.Ae;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
/** Guesses written since the last seam (`[node, value, question, …]`).
|
|
@@ -70,7 +72,7 @@ function newLane(e) {
|
|
|
70
72
|
* on (a store setter's draft too, store/optimistic.ts). */ function guessedValueOf(e) {
|
|
71
73
|
const n = pendingGuessOf(e);
|
|
72
74
|
if (n !== NOT_PENDING) return n;
|
|
73
|
-
return e.
|
|
75
|
+
return e.i & CONFIG_OVERRIDE ? laneValueOf(e) : e.Ae;
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
/** The unflushed guess to `n`, else NOT_PENDING. */ function pendingGuessOf(e) {
|
|
@@ -84,9 +86,9 @@ function optimisticWrite(e, n) {
|
|
|
84
86
|
// again is no guess (the node's comparator, as for any write) — unless
|
|
85
87
|
// the node already carries one: the user re-asked, and the re-ask renews
|
|
86
88
|
// the guess's question and entangles its frame (#3347) without notifying.
|
|
87
|
-
const
|
|
88
|
-
if (typeof n === "function") n = n(
|
|
89
|
-
if (e.
|
|
89
|
+
const t = guessedValueOf(e);
|
|
90
|
+
if (typeof n === "function") n = n(t);
|
|
91
|
+
if (e.ye && e.ye(t, n) && !(e.i & CONFIG_GUESS)) return n;
|
|
90
92
|
pendingGuesses.push(e, n, question || nextQuestion());
|
|
91
93
|
schedule();
|
|
92
94
|
return n;
|
|
@@ -104,35 +106,35 @@ function optimisticWrite(e, n) {
|
|
|
104
106
|
/** A guess's own truth is in flight: the node's own refetch — or, a store
|
|
105
107
|
* leaf's, its family's derive (the slot's flight; store/optimistic.ts
|
|
106
108
|
* installs the resolver). A17: the guess stands in for the flight. */ function inFlight(e) {
|
|
107
|
-
return (e.
|
|
109
|
+
return (e.S & STATUS_PENDING) !== 0 || (e.i & CONFIG_SLOT_NODE) !== 0 && GlobalQueue.C?.(e) === true;
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
function applyGuesses(e) {
|
|
111
113
|
let n = null;
|
|
112
|
-
for (let
|
|
113
|
-
const
|
|
114
|
-
const
|
|
114
|
+
for (let t = 0; t < pendingGuesses.length; t += 3) {
|
|
115
|
+
const u = pendingGuesses[t];
|
|
116
|
+
const l = pendingGuesses[t + 1];
|
|
115
117
|
let s = true;
|
|
116
|
-
if (
|
|
118
|
+
if (u.i & CONFIG_OVERRIDE) {
|
|
117
119
|
// A lane's node already: a guess re-asked, or a derivation guessed
|
|
118
120
|
// over (its staging is void — the guess is the value now). Two
|
|
119
121
|
// suggestions for one slot cannot finish apart (A34 (1)): the frames
|
|
120
122
|
// entangle. The same value re-asked renews the question; nothing to
|
|
121
123
|
// notify.
|
|
122
|
-
s = !
|
|
123
|
-
if (!(
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
s = !u.ye || !u.ye(laneValueOf(u), l);
|
|
125
|
+
if (!(u.i & CONFIG_GUESS)) {
|
|
126
|
+
u.Oe = NOT_PENDING;
|
|
127
|
+
u.i |= CONFIG_GUESS;
|
|
126
128
|
}
|
|
127
|
-
|
|
128
|
-
const n = txOf(
|
|
129
|
+
u.m.B = l;
|
|
130
|
+
const n = txOf(u)._parent;
|
|
129
131
|
if (e !== null && n !== null) merge(e, n);
|
|
130
132
|
} else {
|
|
131
|
-
let
|
|
132
|
-
if (
|
|
133
|
-
if (e === null && inFlight(
|
|
133
|
+
let t;
|
|
134
|
+
if (u.i & CONFIG_HELD) t = newLane(txOf(u)); else {
|
|
135
|
+
if (e === null && inFlight(u)) e = newTransaction(false);
|
|
134
136
|
if (e === null) continue;
|
|
135
|
-
|
|
137
|
+
t = n ??= newLane(e);
|
|
136
138
|
}
|
|
137
139
|
// (A guess equal to a truth staged beneath it is confirmed at birth —
|
|
138
140
|
// A24 — and still re-derives its readers as the lane's: the truth's
|
|
@@ -140,17 +142,17 @@ function applyGuesses(e) {
|
|
|
140
142
|
// screen's plus the guess (plan sec. 19) — a derivation reading a held write
|
|
141
143
|
// beside the guess must not show it. Two flights for one input, when
|
|
142
144
|
// the worlds coincide, is the price.)
|
|
143
|
-
ext(
|
|
144
|
-
|
|
145
|
-
list(
|
|
145
|
+
ext(u).B = l;
|
|
146
|
+
u.i |= CONFIG_OVERRIDE | CONFIG_GUESS;
|
|
147
|
+
list(u, t);
|
|
146
148
|
}
|
|
147
|
-
ext(
|
|
149
|
+
ext(u)._e = pendingGuesses[t + 2];
|
|
148
150
|
if (s) {
|
|
149
151
|
// The lane's members re-derive as its work (REACTIVE_LANE_DIRTY): a
|
|
150
152
|
// blocked lane's re-guess does not re-run its render effects as stale
|
|
151
153
|
// readers republishing the committed view (#3460).
|
|
152
|
-
insertSubs(
|
|
153
|
-
laneDirty(
|
|
154
|
+
insertSubs(u);
|
|
155
|
+
laneDirty(u, txOf(u));
|
|
154
156
|
}
|
|
155
157
|
}
|
|
156
158
|
pendingGuesses.length = 0;
|
|
@@ -165,38 +167,40 @@ function applyGuesses(e) {
|
|
|
165
167
|
* through an ancestor's guess stays its own (the screen plus its own
|
|
166
168
|
* guesses). */ function enterLane(e, n) {
|
|
167
169
|
n.R |= REACTIVE_LANE_READ;
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
+
const t = passLane;
|
|
171
|
+
if (t === null) {
|
|
170
172
|
setPassLane(e);
|
|
171
173
|
// The pass read a held write before its first lane read (it joined the
|
|
172
174
|
// frame's future as mainline would): lane work sees the screen — the
|
|
173
175
|
// seam re-derives it on the committed world next round (`stagedReaders`,
|
|
174
|
-
// the park's repair), as it does a lane pass that read a staging.
|
|
175
|
-
|
|
176
|
+
// the park's repair), as it does a lane pass that read a staging. Not a
|
|
177
|
+
// pass whose held reads were all of nodes born held (no staged read,
|
|
178
|
+
// `stagedRead`): it has no committed world to re-derive on (#3969).
|
|
179
|
+
if (n.R & REACTIVE_JOINED && n.R & REACTIVE_STAGED_READ) stagedRead(n);
|
|
176
180
|
return;
|
|
177
181
|
}
|
|
178
|
-
if (sameLane(
|
|
179
|
-
if (under(
|
|
180
|
-
if (under(e,
|
|
181
|
-
linkLanes(
|
|
182
|
+
if (sameLane(t, e)) return setPassLane(e);
|
|
183
|
+
if (under(t, e)) return;
|
|
184
|
+
if (under(e, t)) return setPassLane(e);
|
|
185
|
+
linkLanes(t, e);
|
|
182
186
|
setPassLane(e);
|
|
183
187
|
}
|
|
184
188
|
|
|
185
189
|
/** Is `l` nested under `a` (an ancestor lane)? */ function under(e, n) {
|
|
186
|
-
for (let
|
|
190
|
+
for (let t = e._parent; t !== null && t.B; t = t._parent) if (t === n) return true;
|
|
187
191
|
return false;
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
/** One link group (a shared array) for both lanes' groups. */ function linkLanes(e, n) {
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
if (
|
|
194
|
-
if (
|
|
195
|
-
|
|
196
|
-
n.nn =
|
|
197
|
-
} else for (let e = 0; e <
|
|
198
|
-
|
|
199
|
-
|
|
195
|
+
const t = e.nn ?? (e.nn = [ e ]);
|
|
196
|
+
const u = n.nn;
|
|
197
|
+
if (u === t) return;
|
|
198
|
+
if (u === null) {
|
|
199
|
+
t.push(n);
|
|
200
|
+
n.nn = t;
|
|
201
|
+
} else for (let e = 0; e < u.length; e++) {
|
|
202
|
+
t.push(u[e]);
|
|
203
|
+
u[e].nn = t;
|
|
200
204
|
}
|
|
201
205
|
}
|
|
202
206
|
|
|
@@ -205,9 +209,9 @@ function applyGuesses(e) {
|
|
|
205
209
|
* blocks `k`'s parent, not `k` — nor, through the link, `l`: the guess
|
|
206
210
|
* shows, A17.) */ function linkBlocked(e) {
|
|
207
211
|
const n = e.nn;
|
|
208
|
-
if (n !== null) for (let
|
|
209
|
-
const
|
|
210
|
-
if (
|
|
212
|
+
if (n !== null) for (let t = 0; t < n.length; t++) {
|
|
213
|
+
const u = n[t];
|
|
214
|
+
if (u !== e && (u.tt !== 0 || ownFlights(u) || nestedBlocked(u))) return true;
|
|
211
215
|
}
|
|
212
216
|
return false;
|
|
213
217
|
}
|
|
@@ -215,8 +219,8 @@ function applyGuesses(e) {
|
|
|
215
219
|
function unlink(e) {
|
|
216
220
|
const n = e.nn;
|
|
217
221
|
if (n === null) return;
|
|
218
|
-
const
|
|
219
|
-
if (
|
|
222
|
+
const t = n.indexOf(e);
|
|
223
|
+
if (t !== -1) n.splice(t, 1);
|
|
220
224
|
e.nn = null;
|
|
221
225
|
}
|
|
222
226
|
|
|
@@ -227,7 +231,7 @@ function unlink(e) {
|
|
|
227
231
|
* lane under the holder, shown now, re-derived at the landing, ending with
|
|
228
232
|
* it. Judged at the seam like any lane: blocked while a verdict reader's
|
|
229
233
|
* own derivation is in flight (lane rule 3), shown otherwise. */ function verdictLane(e) {
|
|
230
|
-
return e.
|
|
234
|
+
return e.xe ??= newLane(e);
|
|
231
235
|
}
|
|
232
236
|
|
|
233
237
|
/** A lane pass's node (core.ts `recompute`, before its staging; a pending
|
|
@@ -244,19 +248,24 @@ function unlink(e) {
|
|
|
244
248
|
* not leave (A30: it never got there). A first pass under a lane is the
|
|
245
249
|
* lane's (ruling A); a guess is written, not derived — it never leaves this
|
|
246
250
|
* way. `errored`: the pass has no answer — or, a lane pass's pending
|
|
247
|
-
* propagation (async.ts `propagateStatus`), the node gone pending. */ function laneStage(e, n,
|
|
248
|
-
if (!(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
251
|
+
* propagation (async.ts `propagateStatus`), the node gone pending. */ function laneStage(e, n, t, u) {
|
|
252
|
+
if (!(t || u || e.R & REACTIVE_LANE_READ || e.i & CONFIG_GUESS)) {
|
|
253
|
+
const n = e.m;
|
|
254
|
+
if (n !== null) {
|
|
255
|
+
const t = n.He;
|
|
256
|
+
// Cleared before equality, so a return to the committed value notifies
|
|
257
|
+
// nobody. The seam wakes it unless the frame is still held (#3892).
|
|
258
|
+
if (t?.Ze && !blocked(resolveTx(t._parent))) e.R |= LEFT_SHOWN;
|
|
259
|
+
if (t?.B) n.He = null;
|
|
260
|
+
n.B = NOT_PENDING;
|
|
252
261
|
}
|
|
253
|
-
e.
|
|
262
|
+
e.i &= -1050881;
|
|
254
263
|
return false;
|
|
255
264
|
}
|
|
256
|
-
if (!e.
|
|
257
|
-
if (!(e.
|
|
258
|
-
e.
|
|
259
|
-
e.
|
|
265
|
+
if (!e.u) {
|
|
266
|
+
if (!(e.i & CONFIG_OVERRIDE)) {
|
|
267
|
+
e.Oe = NOT_PENDING;
|
|
268
|
+
e.i = e.i & -1048833 | CONFIG_OVERRIDE;
|
|
260
269
|
ext(e);
|
|
261
270
|
}
|
|
262
271
|
// A written guess whose own pass is the lane's work — its source is a
|
|
@@ -265,7 +274,7 @@ function unlink(e) {
|
|
|
265
274
|
// of the lane from here (its value the lane's, its fate the lane's), no
|
|
266
275
|
// longer a written guess. A pass with no answer (pending, errored)
|
|
267
276
|
// leaves the guess.
|
|
268
|
-
if (!
|
|
277
|
+
if (!u) e.i &= ~CONFIG_GUESS;
|
|
269
278
|
}
|
|
270
279
|
// A leaf has no lane value to seat it (`recompute`): one left waiting on
|
|
271
280
|
// the lane's flight runs its next pass as the lane's — the landing that
|
|
@@ -277,8 +286,8 @@ function unlink(e) {
|
|
|
277
286
|
// `laneRead` decides — its frame holds). Its pending is the frame's: queued
|
|
278
287
|
// for the commit sweep as mainline's (async.ts). A node born in the lane
|
|
279
288
|
// has nothing on screen: its leaf waits as the lane's.
|
|
280
|
-
else if (
|
|
281
|
-
if (
|
|
289
|
+
else if (u) {
|
|
290
|
+
if (u !== true && !(u.S & STATUS_UNINITIALIZED) && (e.i & CONFIG_HELD || e.R & REACTIVE_RECOMPUTING_DEPS) && !e.m?.He?.B) {
|
|
282
291
|
queuePendingNode(e);
|
|
283
292
|
return false;
|
|
284
293
|
}
|
|
@@ -288,29 +297,55 @@ function unlink(e) {
|
|
|
288
297
|
return true;
|
|
289
298
|
}
|
|
290
299
|
|
|
291
|
-
function supersede(e, n,
|
|
292
|
-
const
|
|
300
|
+
function supersede(e, n, t) {
|
|
301
|
+
const u = txOf(e);
|
|
293
302
|
// Resolved: the parent may have merged into another transaction since the
|
|
294
303
|
// lane opened (two actions guessing one slot entangle, A34 (1)) — the
|
|
295
304
|
// truth is held by the transaction that lands, not the merged-away one.
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
305
|
+
const l = resolveTx(u._parent ?? u);
|
|
306
|
+
// A store row answered by a new object the store would reconcile into
|
|
307
|
+
// the guessed one unchanged is an echo, not a correction (#3898): the
|
|
308
|
+
// server's object never matches the guess by reference.
|
|
309
|
+
if (t && e.i & CONFIG_SLOT_NODE && GlobalQueue.tn?.(e.m.B, n)) t = false;
|
|
310
|
+
if (t) {
|
|
311
|
+
dissolveLane(u, l, e);
|
|
299
312
|
// What the screen showed stays the screen until the parent lands (A18
|
|
300
313
|
// (c): display and untracked reads keep the override until the commit).
|
|
301
|
-
if (
|
|
302
|
-
e.
|
|
303
|
-
e.m.
|
|
304
|
-
e
|
|
305
|
-
holdNode(e, t);
|
|
306
|
-
joinFuture(t);
|
|
314
|
+
if (u.Ze) e.Ae = e.m.B;
|
|
315
|
+
e.i &= -10241;
|
|
316
|
+
e.m.B = NOT_PENDING;
|
|
317
|
+
holdNode(e, l);
|
|
307
318
|
if (e.t !== null) insertSubs(e);
|
|
308
319
|
} else {
|
|
309
|
-
e.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
for (let n = e.t; n !== null; n = n.l) if (n.o.u & CONFIG_AUTHORITATIVE) enqueueSub(n.o);
|
|
320
|
+
e.i |= CONFIG_HELD;
|
|
321
|
+
// A confirmation is silent (A17); only truth readers are told.
|
|
322
|
+
GlobalQueue.un?.(u);
|
|
313
323
|
}
|
|
324
|
+
e.Oe = n;
|
|
325
|
+
joinFuture(l);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Truth readers (`until`, `refresh`; CONFIG_AUTHORITATIVE) — pay-for-use:
|
|
329
|
+
* the first one installs these on GlobalQueue (signals.ts `watch`).
|
|
330
|
+
*
|
|
331
|
+
* A truth reader's read of a lane node: the lane's value when it is the
|
|
332
|
+
* truth (#3943), else the truth staged beneath a guess, else the committed
|
|
333
|
+
* value. */ function truthRead(e) {
|
|
334
|
+
return truth(e) ? laneValueOf(e) : e.i & CONFIG_GUESS && e.Oe !== NOT_PENDING ? e.Oe : e.Ae;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/** A guess confirmed: its lane's truth readers re-read — of the lane's
|
|
338
|
+
* derivations too, which may be the truth now (#3943). */ function truthConfirmed(e) {
|
|
339
|
+
for (let n = 0; n < e.ln.length; n++) for (let t = e.ln[n].t; t !== null; t = t.o) if (t.l.i & CONFIG_AUTHORITATIVE) enqueueSub(t.l);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** A lane node's value is the truth when every guess beneath it is
|
|
343
|
+
* confirmed — its source staged a value equal to the guess — and nothing
|
|
344
|
+
* beneath it is held in the parent: same inputs, same value. */ function truth(e) {
|
|
345
|
+
if (e.i & CONFIG_GUESS) return e.Oe !== NOT_PENDING && e.ye && e.ye(e.m.B, e.Oe);
|
|
346
|
+
if (e.Oe !== NOT_PENDING) return;
|
|
347
|
+
if (e.i & CONFIG_OVERRIDE) for (let n = e.p; n; n = n._) if (!truth(n.I)) return;
|
|
348
|
+
return 1;
|
|
314
349
|
}
|
|
315
350
|
|
|
316
351
|
/** A lane's end, two ways. `into === null`: the parent landed — the lane's
|
|
@@ -322,52 +357,52 @@ function supersede(e, n, u) {
|
|
|
322
357
|
* the screen (`_value` takes it, so the parent's re-derivation compares
|
|
323
358
|
* against what is seen), a truth staged beneath a guess is the parent's to
|
|
324
359
|
* land, and the runs it held (showing the void guess) are dropped: the
|
|
325
|
-
* parent's re-derivation makes the runs that show. */ function dissolveLane(e, n,
|
|
326
|
-
const
|
|
327
|
-
if (
|
|
360
|
+
* parent's re-derivation makes the runs that show. */ function dissolveLane(e, n, t) {
|
|
361
|
+
const u = lanes.indexOf(e);
|
|
362
|
+
if (u !== -1) lanes.splice(u, 1);
|
|
328
363
|
unlink(e);
|
|
329
364
|
// Its verdicts end with it (a correction's dissolution reaches here before
|
|
330
365
|
// `endLanes` would): the readers re-derive from the truth's notification.
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
333
|
-
e.
|
|
334
|
-
if (lanes.indexOf(
|
|
366
|
+
const l = e.xe;
|
|
367
|
+
if (l !== null) {
|
|
368
|
+
e.xe = null;
|
|
369
|
+
if (lanes.indexOf(l) !== -1) dissolveLane(l, null);
|
|
335
370
|
}
|
|
336
|
-
for (let
|
|
337
|
-
const
|
|
338
|
-
const s =
|
|
339
|
-
if (
|
|
340
|
-
const
|
|
341
|
-
const
|
|
342
|
-
const o = s.
|
|
371
|
+
for (let u = 0; u < e.ln.length; u++) {
|
|
372
|
+
const l = e.ln[u];
|
|
373
|
+
const s = l.m;
|
|
374
|
+
if (l === t || s.He !== e) continue;
|
|
375
|
+
const r = l.u;
|
|
376
|
+
const i = l.i & CONFIG_GUESS;
|
|
377
|
+
const o = s.B;
|
|
343
378
|
// What the screen shows of it (NOT_PENDING: nothing — a lane pass that
|
|
344
379
|
// errored or pends staged no value), and the lane's latest.
|
|
345
|
-
const E = e.
|
|
346
|
-
const f = laneValueOf(
|
|
347
|
-
s.
|
|
348
|
-
|
|
380
|
+
const E = e.Ze && !r ? o : l.Ae;
|
|
381
|
+
const f = laneValueOf(l);
|
|
382
|
+
s.B = NOT_PENDING;
|
|
383
|
+
l.i &= -10241;
|
|
349
384
|
if (n === null) {
|
|
350
385
|
// A derivation the revert re-derives (dirtied by the guess's
|
|
351
386
|
// notification — listed before it), or one still in flight, shows the
|
|
352
387
|
// lane's answer beside inputs that are the truth now: a fresh reader
|
|
353
388
|
// of its flight observes it (#3648, #3651; #3305's commit beneath a
|
|
354
389
|
// flight).
|
|
355
|
-
s.
|
|
356
|
-
if (!
|
|
357
|
-
commitPendingNode(
|
|
358
|
-
if (!
|
|
359
|
-
if (
|
|
360
|
-
if (E !== NOT_PENDING && (!
|
|
390
|
+
s.He = null;
|
|
391
|
+
if (!r && !i) l.Oe = f;
|
|
392
|
+
commitPendingNode(l);
|
|
393
|
+
if (!r) {
|
|
394
|
+
if (l.R & (REACTIVE_IN_HEAP | REACTIVE_DIRTY | REACTIVE_CHECK) || l.S & STATUS_PENDING) l.i |= CONFIG_INPUTS_PUBLISHED;
|
|
395
|
+
if (E !== NOT_PENDING && (!l.ye || !l.ye(E, l.Ae))) insertSubs(l);
|
|
361
396
|
}
|
|
362
|
-
} else if (
|
|
397
|
+
} else if (i) {
|
|
363
398
|
// A guess of a dissolving lane: its truth — a landing held beneath it,
|
|
364
399
|
// else the value it covered — is the parent's to land, and its readers
|
|
365
400
|
// re-derive from it there. What the screen showed stays the screen
|
|
366
401
|
// until then (A18 (c)).
|
|
367
|
-
if (
|
|
368
|
-
if (e.
|
|
369
|
-
holdNode(
|
|
370
|
-
insertSubs(
|
|
402
|
+
if (l.Oe === NOT_PENDING) l.Oe = covered(l);
|
|
403
|
+
if (e.Ze) l.Ae = o;
|
|
404
|
+
holdNode(l, n);
|
|
405
|
+
insertSubs(l);
|
|
371
406
|
} else {
|
|
372
407
|
// A correction: the lane's derivations are void. Shown, what the
|
|
373
408
|
// screen showed stays the screen (committed, inputs published — every
|
|
@@ -376,20 +411,20 @@ function supersede(e, n, u) {
|
|
|
376
411
|
// flight is asking the void world's question: its landing is nobody's
|
|
377
412
|
// answer — it re-asks from the truth (whose notification may not reach
|
|
378
413
|
// it: an input's truth equal to its committed value is silent).
|
|
379
|
-
s.
|
|
380
|
-
if (!
|
|
381
|
-
if (E !== NOT_PENDING && e.
|
|
382
|
-
if (
|
|
383
|
-
s.
|
|
384
|
-
enqueueSub(
|
|
414
|
+
s.He = null;
|
|
415
|
+
if (!r) {
|
|
416
|
+
if (E !== NOT_PENDING && e.Ze) l.Oe = E;
|
|
417
|
+
if (l.S & STATUS_PENDING) {
|
|
418
|
+
s.Te = null;
|
|
419
|
+
enqueueSub(l);
|
|
385
420
|
}
|
|
386
421
|
}
|
|
387
|
-
if (e.
|
|
388
|
-
commitPendingNode(
|
|
389
|
-
if (!
|
|
422
|
+
if (e.Ze) {
|
|
423
|
+
commitPendingNode(l);
|
|
424
|
+
if (!r) l.i |= CONFIG_INPUTS_PUBLISHED;
|
|
390
425
|
} else {
|
|
391
|
-
if (s.
|
|
392
|
-
|
|
426
|
+
if (s.Qe !== null || s.ve !== null) GlobalQueue.Fe(l, false, true);
|
|
427
|
+
l.i &= -1048961;
|
|
393
428
|
}
|
|
394
429
|
}
|
|
395
430
|
}
|
|
@@ -404,7 +439,7 @@ function supersede(e, n, u) {
|
|
|
404
439
|
// void: nothing of it reached the screen. So are the runs a blocked lane
|
|
405
440
|
// parked: they show a re-guess the seam never revealed, beside derivations
|
|
406
441
|
// that keep what the screen showed.
|
|
407
|
-
if (n === null || e.
|
|
442
|
+
if (n === null || e.Ze && !e.sn) releaseQueues(e); else e.rn[0].length = e.rn[1].length = 0;
|
|
408
443
|
}
|
|
409
444
|
|
|
410
445
|
/** Lanes. A lane's node is read by its reader's kind: an authoritative
|
|
@@ -422,59 +457,59 @@ function supersede(e, n, u) {
|
|
|
422
457
|
* verdict: released if the lane shows, held if it blocks) — and sees the
|
|
423
458
|
* lane's latest. NOT_PENDING falls through: lane work's read of a pending
|
|
424
459
|
* member throws like any. */ function laneRead(e, n) {
|
|
425
|
-
const
|
|
426
|
-
if (e !== null && e.
|
|
460
|
+
const t = n.i & CONFIG_GUESS;
|
|
461
|
+
if (e !== null && e.i & CONFIG_AUTHORITATIVE) return GlobalQueue.En(n);
|
|
427
462
|
if (e === null) return laneValueOf(n);
|
|
428
|
-
const
|
|
429
|
-
const
|
|
430
|
-
if (!tracking || e.
|
|
463
|
+
const u = txOf(n);
|
|
464
|
+
const l = n.S;
|
|
465
|
+
if (!tracking || e.i & CONFIG_CHILDREN_FORBIDDEN) {
|
|
431
466
|
// An untracked read inside lane work derives from the lane like a
|
|
432
467
|
// tracked one, minus the subscription — `untrack` is about
|
|
433
468
|
// dependencies, not about which world a pass derives from (a mapper's
|
|
434
469
|
// row reads under its root, store/map): the pass enters the lane (two
|
|
435
470
|
// lanes read by one pass link, as for tracked reads). Outside lane
|
|
436
471
|
// work, the screen.
|
|
437
|
-
if (passLane === null || e.
|
|
438
|
-
enterLane(
|
|
439
|
-
if (!
|
|
472
|
+
if (passLane === null || e.i & CONFIG_CHILDREN_FORBIDDEN) return display(n);
|
|
473
|
+
enterLane(u, e);
|
|
474
|
+
if (!t && l & STATUS_PENDING) return NOT_PENDING;
|
|
440
475
|
return laneValueOf(n);
|
|
441
476
|
}
|
|
442
|
-
if (e.
|
|
443
|
-
if (!
|
|
477
|
+
if (e.u === EFFECT_RENDER && (passLane === null || !sameLane(passLane, u))) {
|
|
478
|
+
if (!t) {
|
|
444
479
|
// A flight whose value has never shown: nothing to show — the leaf
|
|
445
480
|
// waits on it, and its own frame holds (A15, #3334), not the lane's
|
|
446
481
|
// parent. The landing lands the frame: its own pass (the flush
|
|
447
482
|
// joined its transaction) reads the answer it waited on — the lane's
|
|
448
483
|
// staging, revealed at this seam.
|
|
449
|
-
if (
|
|
450
|
-
if (n.
|
|
484
|
+
if (l & STATUS_PENDING && n.m.B === NOT_PENDING) return NOT_PENDING;
|
|
485
|
+
if (n.Oe !== NOT_PENDING && e.i & CONFIG_HELD && flushTransaction !== null && resolveTx(flushTransaction) === txOf(e)) return n.Oe;
|
|
451
486
|
}
|
|
452
|
-
if (
|
|
453
|
-
if (!
|
|
487
|
+
if (u.sn || !t && l & STATUS_PENDING) {
|
|
488
|
+
if (!t && !u.Ze && l & STATUS_UNINITIALIZED) throw new NotReadyError(null);
|
|
454
489
|
// Re-derived at the reveal; once per pass (the pass may also be a stale
|
|
455
490
|
// reader of a transaction, REACTIVE_FRAME_READ — both reruns apply).
|
|
456
491
|
if (!(e.R & REACTIVE_SCREEN_READ)) {
|
|
457
492
|
e.R |= REACTIVE_FRAME_READ | REACTIVE_SCREEN_READ;
|
|
458
|
-
|
|
493
|
+
u.fn.push(e);
|
|
459
494
|
}
|
|
460
495
|
return display(n);
|
|
461
496
|
}
|
|
462
497
|
}
|
|
463
|
-
enterLane(
|
|
464
|
-
if (!
|
|
498
|
+
enterLane(u, e);
|
|
499
|
+
if (!t && l & STATUS_PENDING) return NOT_PENDING;
|
|
465
500
|
return laneValueOf(n);
|
|
466
501
|
}
|
|
467
502
|
|
|
468
503
|
/** The value a guess covered: the node's committed value — a store slot's
|
|
469
504
|
* asked of the store (a chained link follows the inner store's commits). */ function covered(e) {
|
|
470
|
-
return e.
|
|
505
|
+
return e.i & CONFIG_SLOT_NODE && GlobalQueue.Nn !== undefined ? GlobalQueue.Nn(e) : e.Ae;
|
|
471
506
|
}
|
|
472
507
|
|
|
473
508
|
/** A guess in `l` whose own truth is in flight (its refetch — authoritative:
|
|
474
509
|
* the landing supersedes, not the body's end). */ function guessFlights(e) {
|
|
475
|
-
for (let n = 0; n < e.
|
|
476
|
-
const
|
|
477
|
-
if (
|
|
510
|
+
for (let n = 0; n < e.ln.length; n++) {
|
|
511
|
+
const t = e.ln[n];
|
|
512
|
+
if (t.i & CONFIG_GUESS && t.m.He === e && inFlight(t)) return true;
|
|
478
513
|
}
|
|
479
514
|
return false;
|
|
480
515
|
}
|
|
@@ -494,20 +529,20 @@ function supersede(e, n, u) {
|
|
|
494
529
|
* landing.) True when a lane was judged. */ function laneCorrections() {
|
|
495
530
|
let e = false;
|
|
496
531
|
const n = lanes.slice();
|
|
497
|
-
for (let
|
|
498
|
-
const
|
|
499
|
-
if (lanes.indexOf(
|
|
500
|
-
const
|
|
501
|
-
if (!
|
|
532
|
+
for (let t = 0; t < n.length; t++) {
|
|
533
|
+
const u = n[t];
|
|
534
|
+
if (lanes.indexOf(u) === -1) continue;
|
|
535
|
+
const l = resolveTx(u._parent);
|
|
536
|
+
if (!l.nt || l.tt !== 0 || l.B || ownFlights(l) || guessFlights(u)) continue;
|
|
502
537
|
e = true;
|
|
503
538
|
// Each guess's truth: the one beneath it (a landing held there), else
|
|
504
539
|
// the one it covered. (A correction dissolves the lane — the others are
|
|
505
540
|
// re-homed with theirs, `dissolveLane`.)
|
|
506
|
-
for (let e = 0; e <
|
|
507
|
-
const n =
|
|
508
|
-
if (n.
|
|
509
|
-
const e = n.
|
|
510
|
-
supersede(n, e, !n.
|
|
541
|
+
for (let e = 0; e < u.ln.length && lanes.indexOf(u) !== -1; e++) {
|
|
542
|
+
const n = u.ln[e];
|
|
543
|
+
if (n.i & CONFIG_GUESS && n.m.He === u) {
|
|
544
|
+
const e = n.Oe !== NOT_PENDING ? n.Oe : covered(n);
|
|
545
|
+
supersede(n, e, !n.ye || !n.ye(n.m.B, e));
|
|
511
546
|
}
|
|
512
547
|
}
|
|
513
548
|
}
|
|
@@ -518,24 +553,28 @@ function laneSeam(e, n) {
|
|
|
518
553
|
// Blocked — or one of its passes read a write the frame holds this seam:
|
|
519
554
|
// its runs wait, the pass re-derives on the screen next round.
|
|
520
555
|
if (n || blocked(e)) {
|
|
521
|
-
e.
|
|
556
|
+
e.sn = true;
|
|
522
557
|
return;
|
|
523
558
|
}
|
|
524
|
-
e.
|
|
525
|
-
e.
|
|
559
|
+
e.sn = false;
|
|
560
|
+
e.Ze = true;
|
|
526
561
|
reruns(e);
|
|
527
|
-
for (let n = 0; n < e.
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
562
|
+
for (let n = 0; n < e.ln.length; n++) {
|
|
563
|
+
const t = e.ln[n];
|
|
564
|
+
if (t.R & LEFT_SHOWN) {
|
|
565
|
+
t.R ^= LEFT_SHOWN;
|
|
566
|
+
insertSubs(t);
|
|
567
|
+
}
|
|
568
|
+
const u = t.m;
|
|
569
|
+
if (u.He !== e) continue;
|
|
570
|
+
if (!(t.i & CONFIG_GUESS) && !t.u && t.Oe !== NOT_PENDING) {
|
|
571
|
+
u.B = t.Oe;
|
|
572
|
+
t.Oe = NOT_PENDING;
|
|
534
573
|
}
|
|
535
574
|
// The frame this pass built is the screen's now; the one it replaced
|
|
536
575
|
// goes (as `commitPendingNode` retires a committed pass's).
|
|
537
|
-
if (
|
|
538
|
-
|
|
576
|
+
if (u.Qe !== null || u.ve !== null) GlobalQueue.Fe(t, false, true);
|
|
577
|
+
t.i &= ~CONFIG_STAGED;
|
|
539
578
|
}
|
|
540
579
|
releaseQueues(e);
|
|
541
580
|
}
|
|
@@ -543,10 +582,10 @@ function laneSeam(e, n) {
|
|
|
543
582
|
/** The parent landed: its lanes end, nested first. (None is blocked: a
|
|
544
583
|
* blocked lane blocks its parent.) */ function endLanes(e) {
|
|
545
584
|
for (let n = lanes.length - 1; n >= 0; n--) {
|
|
546
|
-
const
|
|
547
|
-
if (resolveTx(
|
|
548
|
-
endLanes(
|
|
549
|
-
dissolveLane(
|
|
585
|
+
const t = lanes[n];
|
|
586
|
+
if (resolveTx(t._parent) !== e) continue;
|
|
587
|
+
endLanes(t);
|
|
588
|
+
dissolveLane(t, null);
|
|
550
589
|
}
|
|
551
590
|
}
|
|
552
591
|
|
|
@@ -555,14 +594,14 @@ function laneSeam(e, n) {
|
|
|
555
594
|
* frame is not complete without it (A15) — landing it would commit the write
|
|
556
595
|
* beside a derivation still showing the old one. A guess whose own flight is
|
|
557
596
|
* up likewise: the question was asked in this frame. */ function lanesBlocked(e) {
|
|
558
|
-
return e.
|
|
597
|
+
return e.B && linkBlocked(e) || nestedBlocked(e);
|
|
559
598
|
}
|
|
560
599
|
|
|
561
600
|
/** The lanes under `t` (its own; a link group's are each other's). */ function nestedBlocked(e) {
|
|
562
601
|
for (let n = 0; n < lanes.length; n++) {
|
|
563
|
-
const
|
|
564
|
-
if (resolveTx(
|
|
565
|
-
if (blocked(
|
|
602
|
+
const t = lanes[n];
|
|
603
|
+
if (resolveTx(t._parent) !== e) continue;
|
|
604
|
+
if (blocked(t) || guessFlights(t)) return true;
|
|
566
605
|
}
|
|
567
606
|
return false;
|
|
568
607
|
}
|
|
@@ -572,7 +611,7 @@ function laneSeam(e, n) {
|
|
|
572
611
|
* landing), judged against the guess. On a derivation it is the lane's
|
|
573
612
|
* latest: its staging once the lane has shown (promoted at the next
|
|
574
613
|
* reveal), its slot before; the lane's members re-derive as its work. */ function laneWrite(e, n) {
|
|
575
|
-
if (e.
|
|
614
|
+
if (e.i & CONFIG_GUESS) {
|
|
576
615
|
// Provenance (A18, #3331; Q-D, plan sec. 39): a write asking an OLDER
|
|
577
616
|
// question than the guess's — another action's landing beneath it —
|
|
578
617
|
// is not its answer: held beneath (the truth for the commit; the
|
|
@@ -581,20 +620,20 @@ function laneSeam(e, n) {
|
|
|
581
620
|
// continuation's — the flight's); unstamped writes and mainline are
|
|
582
621
|
// current.
|
|
583
622
|
if (stale(e, question)) {
|
|
584
|
-
e.
|
|
585
|
-
e.
|
|
586
|
-
GlobalQueue.
|
|
623
|
+
e.Oe = n;
|
|
624
|
+
e.i |= CONFIG_HELD;
|
|
625
|
+
GlobalQueue.an?.(e, n);
|
|
587
626
|
schedule();
|
|
588
627
|
return n;
|
|
589
628
|
}
|
|
590
|
-
supersede(e, n, !e.
|
|
629
|
+
supersede(e, n, !e.ye || !e.ye(e.m.B, n));
|
|
591
630
|
} else {
|
|
592
|
-
const
|
|
593
|
-
if (e.
|
|
594
|
-
if (
|
|
595
|
-
if (e.
|
|
631
|
+
const t = txOf(e);
|
|
632
|
+
if (e.ye && e.ye(laneValueOf(e), n)) return n;
|
|
633
|
+
if (t.Ze) e.Oe = n; else e.m.B = n;
|
|
634
|
+
if (e.ee !== undefined) e.Ie = clock;
|
|
596
635
|
insertSubs(e);
|
|
597
|
-
laneDirty(e,
|
|
636
|
+
laneDirty(e, t);
|
|
598
637
|
}
|
|
599
638
|
schedule();
|
|
600
639
|
return n;
|
|
@@ -611,80 +650,87 @@ function laneSeam(e, n) {
|
|
|
611
650
|
* It is staged beneath the guess, for the commit like any landing, and
|
|
612
651
|
* nothing moves: no downstream re-ask, no pending flip on the guess's
|
|
613
652
|
* readers (`isPending` of the guess itself says the held truth differs,
|
|
614
|
-
* A24). The guess's own question answering supersedes as usual. */ function laneOutcome(e, n,
|
|
615
|
-
if (
|
|
653
|
+
* A24). The guess's own question answering supersedes as usual. */ function laneOutcome(e, n, t) {
|
|
654
|
+
if (t) return true;
|
|
616
655
|
if (stale(e, answered(e))) {
|
|
617
|
-
e.
|
|
618
|
-
e.
|
|
656
|
+
e.Oe = n;
|
|
657
|
+
e.i |= CONFIG_HELD;
|
|
619
658
|
return true;
|
|
620
659
|
}
|
|
621
|
-
supersede(e, n, !e.
|
|
660
|
+
supersede(e, n, !e.ye || !e.ye(e.m.B, n));
|
|
622
661
|
return true;
|
|
623
662
|
}
|
|
624
663
|
|
|
625
664
|
/** THE provenance test, for a derivation's pass and a write alike: an
|
|
626
665
|
* answer to question `q` landing on a guess is stale when `q` is older
|
|
627
666
|
* than the guess's own; unstamped (0) and mainline are current. */ function stale(e, n) {
|
|
628
|
-
return n !== 0 && n < e.m.
|
|
667
|
+
return n !== 0 && n < e.m._e;
|
|
629
668
|
}
|
|
630
669
|
|
|
631
670
|
/** The question a derivation's pass answered: the newest among the stamped
|
|
632
671
|
* sources that changed this round (a flight's landing carries the question
|
|
633
672
|
* that started it); 0 when none is stamped. */ function answered(e) {
|
|
634
673
|
let n = 0;
|
|
635
|
-
for (let
|
|
636
|
-
const e =
|
|
637
|
-
if (e.m !== null && e.m.
|
|
674
|
+
for (let t = e.p; t !== null; t = t._) {
|
|
675
|
+
const e = t.I;
|
|
676
|
+
if (e.m !== null && e.m._e > n && e.Ie === clock) n = e.m._e;
|
|
638
677
|
}
|
|
639
678
|
return n;
|
|
640
679
|
}
|
|
641
680
|
|
|
642
|
-
GlobalQueue.
|
|
681
|
+
GlobalQueue.rt = laneRead;
|
|
643
682
|
|
|
644
|
-
GlobalQueue.
|
|
683
|
+
GlobalQueue.W = laneStage;
|
|
645
684
|
|
|
646
|
-
GlobalQueue.
|
|
685
|
+
GlobalQueue.We = laneOutcome;
|
|
647
686
|
|
|
648
|
-
GlobalQueue.
|
|
687
|
+
GlobalQueue.Nt = laneWrite;
|
|
649
688
|
|
|
650
689
|
/** The lanes alive before this seam's guesses opened theirs (a prefix of
|
|
651
690
|
* `lanes`; nothing dissolves one between here and the seam loop): a lane
|
|
652
691
|
* born at the seam has no work to judge yet (its passes run next round) —
|
|
653
692
|
* it is neither shown nor blocked until it has. */ let judged = 0;
|
|
654
693
|
|
|
655
|
-
GlobalQueue.
|
|
694
|
+
GlobalQueue.In = e => {
|
|
656
695
|
judged = lanes.length;
|
|
657
696
|
if (pendingGuesses.length !== 0) applyGuesses(e);
|
|
658
697
|
};
|
|
659
698
|
|
|
660
|
-
GlobalQueue.
|
|
699
|
+
GlobalQueue._n = e => {
|
|
661
700
|
// Passes that read a write the parked frame holds as the screen
|
|
662
701
|
// (`stagedReaders`: lane work, a verdict reader before the verdict): they
|
|
663
702
|
// re-derive on the committed world next round (and register as stale
|
|
664
703
|
// readers of the transaction there); a lane's runs wait that round — a
|
|
665
704
|
// lane sees the screen plus its own guesses.
|
|
666
705
|
const n = [];
|
|
667
|
-
if (e !== null) for (let
|
|
668
|
-
const
|
|
669
|
-
const
|
|
706
|
+
if (e !== null) for (let t = 0; t < e.length; t++) {
|
|
707
|
+
const u = e[t];
|
|
708
|
+
const l = u.m?.He;
|
|
670
709
|
// A verdict reader a later read of the same pass routed into a verdict
|
|
671
710
|
// lane answered for itself: it re-derives at the holder's landing, not
|
|
672
711
|
// now (one run — #3322, #3540). Other verdict-lane work re-derives only
|
|
673
712
|
// if the frame stays parked: a transaction landing at this seam makes
|
|
674
713
|
// what it read the screen (one run).
|
|
675
|
-
if (
|
|
676
|
-
|
|
677
|
-
|
|
714
|
+
if (u.R & REACTIVE_DISPOSED || l != null && l._parent?.xe === l && (u.i & CONFIG_VERDICT ? !(u.R & REACTIVE_PROBE_UNANSWERED) : !blocked(l._parent))) continue;
|
|
715
|
+
// A leaked effect re-derives seated in its lane from its first read: it
|
|
716
|
+
// carries no lane value (`laneStage`), so without this its pass starts
|
|
717
|
+
// as mainline, joins the parked frame on its first held read and reads
|
|
718
|
+
// the staging, then re-enters the lane at its guess read and leaks
|
|
719
|
+
// again — every round (#4014). A computed is already seated by its
|
|
720
|
+
// override, and a written guess's own pass stays the frame's.
|
|
721
|
+
if (l != null && l.B && u.u) u.R |= REACTIVE_LANE_DIRTY;
|
|
722
|
+
enqueueSub(u);
|
|
723
|
+
if (l != null && l.B && n.indexOf(l) === -1) n.push(l);
|
|
678
724
|
}
|
|
679
725
|
for (let e = Math.min(judged, lanes.length) - 1; e >= 0; e--) laneSeam(lanes[e], n.indexOf(lanes[e]) !== -1);
|
|
680
726
|
};
|
|
681
727
|
|
|
682
|
-
GlobalQueue.
|
|
728
|
+
GlobalQueue.cn = () => lanes.length !== 0 && laneCorrections();
|
|
683
729
|
|
|
684
|
-
GlobalQueue.
|
|
730
|
+
GlobalQueue.Gn = endLanes;
|
|
685
731
|
|
|
686
|
-
GlobalQueue.
|
|
732
|
+
GlobalQueue.On = lanesBlocked;
|
|
687
733
|
|
|
688
|
-
GlobalQueue
|
|
734
|
+
GlobalQueue.$ = verdictLane;
|
|
689
735
|
|
|
690
|
-
export { display, enterLane, guessedValueOf, laneRead, laneStage, laneValueOf, optimisticWrite, pendingGuessOf, supersede, verdictLane };
|
|
736
|
+
export { display, enterLane, guessedValueOf, laneRead, laneStage, laneValueOf, optimisticWrite, pendingGuessOf, supersede, truthConfirmed, truthRead, verdictLane };
|