@solidjs/signals 2.0.0-rc.14 → 2.0.0-rc.16

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