@solidjs/signals 2.0.0-rc.19 → 2.0.0-rc.20

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 (74) hide show
  1. package/dist/dev-shared.js +553 -264
  2. package/dist/dev.attribution.js +18 -18
  3. package/dist/dev.js +1030 -439
  4. package/dist/observe/affects.js +12 -2
  5. package/dist/observe/boundaries.js +168 -115
  6. package/dist/observe/core/async.js +57 -37
  7. package/dist/observe/core/attribution.js +6 -6
  8. package/dist/observe/core/constants.js +9 -1
  9. package/dist/observe/core/copies.js +10 -0
  10. package/dist/observe/core/core.js +261 -181
  11. package/dist/observe/core/effect.js +32 -27
  12. package/dist/observe/core/graph.js +7 -7
  13. package/dist/observe/core/heap.js +29 -29
  14. package/dist/observe/core/lanes.js +301 -101
  15. package/dist/observe/core/owner.js +13 -13
  16. package/dist/observe/core/scheduler.js +124 -69
  17. package/dist/observe/core/truth.js +9 -7
  18. package/dist/observe/core/verdict.js +160 -98
  19. package/dist/observe/deferred.js +1 -1
  20. package/dist/observe/index.js +2 -0
  21. package/dist/observe/map.js +120 -116
  22. package/dist/observe/reveal.js +48 -48
  23. package/dist/observe/signals.js +5 -5
  24. package/dist/observe/store/affects.js +2 -2
  25. package/dist/observe/store/optimistic.js +272 -176
  26. package/dist/observe/store/projection.js +21 -10
  27. package/dist/observe/store/reconcile.js +8 -2
  28. package/dist/observe/store/store.js +91 -55
  29. package/dist/observe/store/types.js +11 -1
  30. package/dist/observe/store/utils.js +1 -1
  31. package/dist/prod/affects.js +12 -2
  32. package/dist/prod/boundaries.js +164 -109
  33. package/dist/prod/core/async.js +201 -181
  34. package/dist/prod/core/constants.js +9 -1
  35. package/dist/prod/core/copies.js +10 -0
  36. package/dist/prod/core/core.js +244 -164
  37. package/dist/prod/core/dev.js +108 -3
  38. package/dist/prod/core/effect.js +28 -23
  39. package/dist/prod/core/graph.js +9 -9
  40. package/dist/prod/core/heap.js +16 -16
  41. package/dist/prod/core/identities.js +1 -1
  42. package/dist/prod/core/lanes.js +307 -95
  43. package/dist/prod/core/owner.js +22 -22
  44. package/dist/prod/core/scheduler.js +266 -211
  45. package/dist/prod/core/truth.js +9 -7
  46. package/dist/prod/core/verdict.js +161 -99
  47. package/dist/prod/deferred.js +1 -1
  48. package/dist/prod/index.js +2 -0
  49. package/dist/prod/map.js +78 -74
  50. package/dist/prod/reveal.js +34 -34
  51. package/dist/prod/signals.js +3 -3
  52. package/dist/prod/store/affects.js +15 -15
  53. package/dist/prod/store/optimistic.js +185 -89
  54. package/dist/prod/store/projection.js +49 -38
  55. package/dist/prod/store/reconcile.js +8 -2
  56. package/dist/prod/store/store.js +99 -63
  57. package/dist/prod/store/types.js +11 -1
  58. package/dist/types/affects.d.ts +3 -2
  59. package/dist/types/boundaries.d.ts +14 -2
  60. package/dist/types/core/async.d.ts +2 -1
  61. package/dist/types/core/constants.d.ts +8 -0
  62. package/dist/types/core/copies.d.ts +54 -0
  63. package/dist/types/core/core.d.ts +15 -0
  64. package/dist/types/core/dev.d.ts +1 -1
  65. package/dist/types/core/lanes.d.ts +8 -1
  66. package/dist/types/core/scheduler.d.ts +36 -4
  67. package/dist/types/core/truth.d.ts +3 -1
  68. package/dist/types/core/types.d.ts +6 -0
  69. package/dist/types/index.d.ts +2 -0
  70. package/dist/types/store/hooks.d.ts +15 -1
  71. package/dist/types/store/store.d.ts +2 -1
  72. package/dist/types/store/target.d.ts +5 -0
  73. package/dist/types/store/types.d.ts +7 -0
  74. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { EFFECT_RENDER, EFFECT_USER, CONFIG_HELD, CONFIG_OVERRIDE, NOT_PENDING, STATUS_UNINITIALIZED, STATUS_PENDING, CONFIG_STAGED, REACTIVE_DISPOSED, REACTIVE_ZOMBIE, CONFIG_VERDICT, CONFIG_HAS_SNAPSHOT, REACTIVE_RECOMPUTING_DEPS, REACTIVE_MISSED_WAKE, CONFIG_IN_SNAPSHOT_SCOPE, REACTIVE_SNAPSHOT_STALE, CONFIG_HELD_FRAME, REACTIVE_LANE_DIRTY, CONFIG_STAGED_ERROR, CONFIG_INPUTS_PUBLISHED, STATUS_ERROR, EFFECT_TRACKED, REACTIVE_MANUAL_WRITE, CONFIG_GUESS, REACTIVE_FRAME_READ, CONFIG_REDERIVE } from "./constants.js";
1
+ import { EFFECT_RENDER, EFFECT_USER, CONFIG_HELD, CONFIG_OVERRIDE, NOT_PENDING, STATUS_UNINITIALIZED, STATUS_PENDING, CONFIG_STAGED, REACTIVE_DISPOSED, REACTIVE_ZOMBIE, CONFIG_VERDICT, CONFIG_HAS_SNAPSHOT, REACTIVE_RECOMPUTING_DEPS, REACTIVE_MISSED_WAKE, CONFIG_IN_SNAPSHOT_SCOPE, REACTIVE_SNAPSHOT_STALE, CONFIG_HELD_FRAME, REACTIVE_LANE_DIRTY, CONFIG_STAGED_ERROR, CONFIG_INPUTS_PUBLISHED, STATUS_ERROR, EFFECT_TRACKED, REACTIVE_MANUAL_WRITE, CONFIG_GUESS, REACTIVE_FRAME_READ, CONFIG_REDERIVE, CONFIG_FRAME } from "./constants.js";
2
2
 
3
3
  import { attrHooks } from "./attribution-hooks.js";
4
4
 
@@ -40,16 +40,32 @@ let endLanesHook = null;
40
40
 
41
41
  let lanesBlockedHook = null;
42
42
 
43
- function installLaneHooks(e, n, o, t, l, s, u, i, r) {
43
+ /** R5 (lanes.ts `laneSeams` parks a frame flight): the landing's re-derive
44
+ * of a reader adopts the flight instead (true: adopted, nothing to queue). */ let laneAdoptHook = null;
45
+
46
+ /** core.ts `frameRead` served lane work or a verdict reader a held node's
47
+ * committed value (lanes.ts `laneServed`). */ let laneServedHook = null;
48
+
49
+ /** A guess was written (lanes.ts `optimisticWrite`): the arms only a guess
50
+ * reaches (CONFIG_GUESS) — a build without `createOptimistic` or
51
+ * `createOptimisticStore` never sets it, and its bundler folds them. */ let guessing = false;
52
+
53
+ function armGuessing() {
54
+ guessing = true;
55
+ }
56
+
57
+ function installLaneHooks(e, o, n, l, t, s, u, i, r, a, f) {
44
58
  laneReadHook = e;
45
- laneStageHook = n;
46
- laneOutcomeHook = o;
47
- laneWriteHook = t;
48
- applyGuessesHook = l;
59
+ laneStageHook = o;
60
+ laneOutcomeHook = n;
61
+ laneWriteHook = l;
62
+ applyGuessesHook = t;
49
63
  laneSeamsHook = s;
50
64
  laneCorrectionsHook = u;
51
65
  endLanesHook = i;
52
66
  lanesBlockedHook = r;
67
+ laneAdoptHook = a;
68
+ laneServedHook = f;
53
69
  }
54
70
 
55
71
  // Boundaries (boundaries.ts): the display consumers between an observer
@@ -75,12 +91,12 @@ let boundarySeamHook = null;
75
91
 
76
92
  let heldRunHook = null;
77
93
 
78
- function installBoundaryHooks(e, n, o, t, l) {
94
+ function installBoundaryHooks(e, o, n, l, t) {
79
95
  catchHook = e;
80
- freshHook = n;
81
- hiddenHook = o;
82
- boundarySeamHook = t;
83
- heldRunHook = l;
96
+ freshHook = o;
97
+ hiddenHook = n;
98
+ boundarySeamHook = l;
99
+ heldRunHook = t;
84
100
  }
85
101
 
86
102
  /** Store (store/store.ts): `park` — the flush parked into `t`: the store
@@ -92,9 +108,9 @@ function installBoundaryHooks(e, n, o, t, l) {
92
108
 
93
109
  let storeCommitHook = null;
94
110
 
95
- function installStoreHooks(e, n) {
111
+ function installStoreHooks(e, o) {
96
112
  storeParkHook = e;
97
- storeCommitHook = n;
113
+ storeCommitHook = o;
98
114
  }
99
115
 
100
116
  /** `affects()` marks (affects.ts): the releases at a landing and at the seam
@@ -102,15 +118,19 @@ function installStoreHooks(e, n) {
102
118
 
103
119
  let releaseAmbientMarksHook = null;
104
120
 
105
- function installMarkHooks(e, n) {
121
+ function installMarkHooks(e, o) {
106
122
  releaseMarksHook = e;
107
- releaseAmbientMarksHook = n;
123
+ releaseAmbientMarksHook = o;
108
124
  }
109
125
 
110
126
  /** Verdicts (verdict.ts). */ let observeFlightHook = null;
111
127
 
112
- function installVerdictHooks(e) {
128
+ /** D-25's hold work (verdict.ts `holdWork`): on `source` going pending,
129
+ * whether verdict reader `n` waits on it instead of re-deriving. */ let holdWorkHook = null;
130
+
131
+ function installVerdictHooks(e, o) {
113
132
  observeFlightHook = e;
133
+ holdWorkHook = o;
114
134
  }
115
135
 
116
136
  /** External-source bridge (wired by enableExternalSource(); undefined while
@@ -118,9 +138,9 @@ function installVerdictHooks(e) {
118
138
 
119
139
  let externalUntrackHook = undefined;
120
140
 
121
- function setExternalHooks(e, n) {
141
+ function setExternalHooks(e, o) {
122
142
  wireExternalSourceHook = e;
123
- externalUntrackHook = n;
143
+ externalUntrackHook = o;
124
144
  }
125
145
 
126
146
  /** Live transactions — opened, unmerged, not landed. Scanned at every seam
@@ -128,24 +148,24 @@ function setExternalHooks(e, n) {
128
148
 
129
149
  /** Observe tier: this flush parked its transaction (`holdStart` fired). */ let holding = false;
130
150
 
131
- /** A transaction (listed here) or a lane (lanes.ts lists its own). */ function newTransaction(e, n = null) {
132
- const o = {
151
+ /** A transaction (listed here) or a lane (lanes.ts lists its own). */ function newTransaction(e, o = null) {
152
+ const n = {
133
153
  tn: [],
134
154
  un: [ [], [] ],
135
155
  En: [],
136
- cn: null,
137
- _parent: n,
156
+ eo: null,
157
+ _parent: o,
138
158
  P: e,
139
159
  Pe: null,
140
160
  tt: 0,
141
161
  nt: false,
142
162
  en: null,
143
- ge: false,
163
+ Ue: false,
144
164
  ln: false,
145
165
  I: null
146
166
  };
147
- if (!e) transactions.push(o);
148
- return o;
167
+ if (!e) transactions.push(n);
168
+ return n;
149
169
  }
150
170
 
151
171
  // Lanes (plan sec. 28, 2026-10-02; lanes.ts). A lane is "a new base of a transition":
@@ -175,6 +195,10 @@ function setPassLane(e) {
175
195
  * schedules the seam that consumes it: membership is the tick's — the same
176
196
  * synchronous frame — and the next tick's writes are not this one's. */ let flushTransaction = null;
177
197
 
198
+ /** The flush's transaction while only a `latest()` read of a staging opened
199
+ * it (verdict.ts `provisionalVerdict`): it holds nothing, and a verdict
200
+ * reader's plain read of a staging in it is the frame's read (D-22). */ let latestOpened = null;
201
+
178
202
  /** The transaction the passes running OUTSIDE a flush this tick derive from
179
203
  * (a mainline mount, a mainline re-pass): the passes' own (A29, creation-
180
204
  * time form — "the entry is the pass's alone"): their results are staged
@@ -188,8 +212,8 @@ function setPassLane(e) {
188
212
  * Cleared by the flush the join schedules, and at the end of a flush that
189
213
  * set it. */ let passTx = null;
190
214
 
191
- function joinPassTx(e, n) {
192
- if (globalQueue.q && !n || flushTransaction !== null) return joinFuture(e);
215
+ function joinPassTx(e, o) {
216
+ if (globalQueue.Y && !o || flushTransaction !== null) return joinFuture(e);
193
217
  if (passTx === null) passTx = resolveTx(e); else merge(resolveTx(e), passTx);
194
218
  schedule();
195
219
  }
@@ -206,36 +230,36 @@ function joinPassTx(e, n) {
206
230
  }
207
231
 
208
232
  function resolveTx(e) {
209
- while (e.cn !== null) e = e.cn;
233
+ while (e.eo !== null) e = e.eo;
210
234
  return e;
211
235
  }
212
236
 
213
237
  /** The flush joins transaction `t` — or needs one of its own (`null`: a pass
214
238
  * went pending with nothing held). Joining a second one merges it into the
215
239
  * flush's: the work that touched both entangles them (A15). */ function joinFuture(e) {
216
- const n = flushTransaction;
217
- if (n === null) {
240
+ const o = flushTransaction;
241
+ if (o === null) {
218
242
  flushTransaction = e === null ? newTransaction(false) : resolveTx(e);
219
- } else if (e !== null) merge(resolveTx(e), n);
220
- if (!globalQueue.q) schedule();
243
+ } else if (e !== null) merge(resolveTx(e), o);
244
+ if (!globalQueue.Y) schedule();
221
245
  }
222
246
 
223
247
  /** `t` merges into `f`: the work that touched both entangles them (A15).
224
248
  * A lane never merges: it is a sub-frame, not a peer — its work is routed
225
- * per pass (`passLane`). */ function merge(e, n) {
249
+ * per pass (`passLane`). */ function merge(e, o) {
226
250
  // Both ends resolved: a stale pointer to a transaction already merged
227
251
  // into the other would close a cycle `resolveTx` never leaves.
228
252
  e = resolveTx(e);
229
- n = resolveTx(n);
230
- if (e === n || e.P || n.P) return;
231
- e.cn = n;
232
- n.tt += e.tt;
233
- n.nt ||= e.nt;
234
- append(n.tn, e.tn);
235
- append(n.un[0], e.un[0]);
236
- append(n.un[1], e.un[1]);
237
- append(n.En, e.En);
238
- if (e.I !== null) append(n.I ??= [], e.I);
253
+ o = resolveTx(o);
254
+ if (e === o || e.P || o.P) return;
255
+ e.eo = o;
256
+ o.tt += e.tt;
257
+ o.nt ||= e.nt;
258
+ append(o.tn, e.tn);
259
+ append(o.un[0], e.un[0]);
260
+ append(o.un[1], e.un[1]);
261
+ append(o.En, e.En);
262
+ if (e.I !== null) append(o.I ??= [], e.I);
239
263
  transactions.splice(transactions.indexOf(e), 1);
240
264
  }
241
265
 
@@ -257,13 +281,13 @@ function resolveTx(e) {
257
281
  * in for the flight (A17: "visible until its own fetch settles"). */ function blocked(e) {
258
282
  // The transaction being judged (a lane consulted on its behalf judges for
259
283
  // it): a zombie whose removal it stages is moot for it alone (`onScreen`).
260
- const n = judge;
284
+ const o = judge;
261
285
  judge ??= e;
262
286
  // An action still running in it holds it open (action.ts). Its lanes
263
287
  // (lanes.ts): a lane under `t` blocks it while blocked itself.
264
- const o = e.tt !== 0 || blockedBy(e.tn, e) || !!lanesBlockedHook?.(e);
265
- judge = n;
266
- return o;
288
+ const n = e.tt !== 0 || blockedBy(e.tn, e) || !!lanesBlockedHook?.(e);
289
+ judge = o;
290
+ return n;
267
291
  }
268
292
 
269
293
  let judge = null;
@@ -278,28 +302,28 @@ let judge = null;
278
302
 
279
303
  /** A source the pending node waits on that is `t`'s (held by it, or by no
280
304
  * one) — not another transaction's or lane's work. Itself, when it is the
281
- * source. */ function ownSource(e, n) {
282
- const o = e.T?.fe;
283
- if (o === undefined) return true;
284
- for (const e of o) {
285
- const o = e.T?.Re;
286
- if (o == null || resolveTx(o) === n) return true;
305
+ * source. */ function ownSource(e, o) {
306
+ const n = e.T?.se;
307
+ if (n === undefined) return true;
308
+ for (const e of n) {
309
+ const n = e.T?.Re;
310
+ if (n == null || resolveTx(n) === o) return true;
287
311
  }
288
312
  return false;
289
313
  }
290
314
 
291
- function blockedBy(e, n, o = false) {
292
- for (let t = 0; t < e.length; t++) {
293
- const l = e[t];
294
- if (!(l.m & STATUS_PENDING) || l.R & REACTIVE_DISPOSED || l.l & CONFIG_GUESS || l.T.Re !== null && txOf(l) !== n || o && !ownSource(l, n)) continue;
315
+ function blockedBy(e, o, n = false) {
316
+ for (let l = 0; l < e.length; l++) {
317
+ const t = e[l];
318
+ if (!(t.m & STATUS_PENDING) || t.R & REACTIVE_DISPOSED || t.l & CONFIG_GUESS || t.T.Re !== null && txOf(t) !== o || n && !ownSource(t, o)) continue;
295
319
  // The frame's own pending observer (off screen: this one holds nothing;
296
320
  // the next listed node may).
297
- if (l.i === EFFECT_RENDER) {
298
- if (onScreen(l, judge ?? n)) return true;
321
+ if (t.i === EFFECT_RENDER) {
322
+ if (onScreen(t, judge ?? o)) return true;
299
323
  continue;
300
324
  }
301
- for (let e = l.o; e !== null; e = e.t) {
302
- const o = e.u;
325
+ for (let e = t.o; e !== null; e = e.t) {
326
+ const n = e.u;
303
327
  // A frame reader: a render effect, or a stale reader of the flight
304
328
  // (REACTIVE_FRAME_READ — a verdict reader, `observeFlight`; lane work,
305
329
  // `frameRead`): served committed instead of going pending, it derives
@@ -311,7 +335,7 @@ function blockedBy(e, n, o = false) {
311
335
  // lane-membership ruling, 2026-10-05). An output that never committed
312
336
  // shows nothing — a mount the frame has not revealed — and holds
313
337
  // nothing.
314
- if ((o.i === EFFECT_RENDER && o.m & STATUS_PENDING || o.R & REACTIVE_FRAME_READ || o.l & CONFIG_REDERIVE && o.m === STATUS_PENDING) && (e.de === o.Ne || o.T?.U != null) && !(o.R & REACTIVE_DISPOSED) && onScreen(o, judge ?? n)) return true;
338
+ if ((n.i === EFFECT_RENDER && n.m & STATUS_PENDING || n.R & REACTIVE_FRAME_READ || n.l & CONFIG_REDERIVE && n.m === STATUS_PENDING) && (e.Ne === n.de || n.T?.U != null) && !(n.R & REACTIVE_DISPOSED) && onScreen(n, judge ?? o)) return true;
315
339
  }
316
340
  }
317
341
  return false;
@@ -324,8 +348,8 @@ function blockedBy(e, n, o = false) {
324
348
  * is visible, a lane's reveal included: only the commit that disposes it
325
349
  * makes its say moot), and not behind a fallback (A33: a boundary showing its fallback is the display of
326
350
  * everything under it, so a reader there is not on screen and holds
327
- * nothing — boundaries.ts). */ function onScreen(e, n) {
328
- return !(e.R & REACTIVE_ZOMBIE && removalStagedBy(e, n)) && !hiddenHook?.(e);
351
+ * nothing — boundaries.ts). */ function onScreen(e, o) {
352
+ return !(e.R & REACTIVE_ZOMBIE && removalStagedBy(e, o)) && !hiddenHook?.(e);
329
353
  }
330
354
 
331
355
  /** A15 (#3463): a reader whose removal is staged — a zombie, parked by a
@@ -333,10 +357,10 @@ function blockedBy(e, n, o = false) {
333
357
  * except the transaction staging its removal: for that one its say is moot
334
358
  * (done, and the commit disposes it; not done, and it stays parked). The
335
359
  * staging transaction is the one holding the pass that parked the frame:
336
- * the nearest non-zombie ancestor. */ function removalStagedBy(e, n) {
337
- let o = e;
338
- while (o?.R & REACTIVE_ZOMBIE) o = o._parent;
339
- return o?.l & CONFIG_HELD && o.T?.Re != null && txOf(o) === resolveTx(n);
360
+ * the nearest non-zombie ancestor. */ function removalStagedBy(e, o) {
361
+ let n = e;
362
+ while (n?.R & REACTIVE_ZOMBIE) n = n._parent;
363
+ return n?.l & CONFIG_HELD && n.T?.Re != null && txOf(n) === resolveTx(o);
340
364
  }
341
365
 
342
366
  /** Unchanged passes this flush whose stale dependency tail awaits the
@@ -362,18 +386,18 @@ function deferZombie(e) {
362
386
  }
363
387
 
364
388
  /** Put a staged node in a transaction: flagged, stamped, on its landing
365
- * list. */ function holdNode(e, n) {
389
+ * list. */ function holdNode(e, o) {
366
390
  e.l |= CONFIG_HELD;
367
- list(e, n);
391
+ list(e, o);
368
392
  }
369
393
 
370
394
  /** Put a node on a transaction's list, once: a node's `_transaction` is the
371
395
  * transaction whose `_nodes` it is on (every site that sets one does the
372
- * other), so a re-pass, a re-landing or a re-staging adds nothing. */ function list(e, n) {
373
- const o = ext(e);
374
- if (o.Re === n) return;
375
- o.Re = n;
376
- n.tn.push(e);
396
+ * other), so a re-pass, a re-landing or a re-staging adds nothing. */ function list(e, o) {
397
+ const n = ext(e);
398
+ if (n.Re === o) return;
399
+ n.Re = o;
400
+ o.tn.push(e);
377
401
  }
378
402
 
379
403
  /** Hold the (uncommitted) frame under a held pass: every computed in the
@@ -388,22 +412,22 @@ function deferZombie(e) {
388
412
  * and `dissolveLane` no longer finds it — a lane node with no lane, which the
389
413
  * next read of it trips over (`laneRead` → `txOf`). Its frame is the lane's
390
414
  * too (ruling A: a lane pass's children are the lane's), revealed and
391
- * retired at the lane's seam. */ function holdFrame(e, n) {
392
- for (let o = e.pe; o !== null; o = o.Ge) {
393
- if (o.T?.Re?.P) continue;
394
- if (o.X !== undefined) {
395
- if (!(o.l & CONFIG_HELD)) holdNode(o, n);
396
- o.l |= CONFIG_HELD_FRAME;
415
+ * retired at the lane's seam. */ function holdFrame(e, o) {
416
+ for (let n = e.pe; n !== null; n = n.Ge) {
417
+ if (n.T?.Re?.P) continue;
418
+ if (n.X !== undefined) {
419
+ if (!(n.l & CONFIG_HELD)) holdNode(n, o);
420
+ n.l |= CONFIG_HELD_FRAME;
397
421
  }
398
- holdFrame(o, n);
422
+ holdFrame(n, o);
399
423
  }
400
424
  }
401
425
 
402
426
  /** The nodes under `owner` a transaction other than `t` holds (boundaries.ts:
403
- * what an earlier hold staged under a re-armed boundary). */ function heldUnder(e, n, o) {
404
- for (let t = e.pe; t !== null; t = t.Ge) {
405
- if ((t.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD && txOf(t) !== n) o(t);
406
- heldUnder(t, n, o);
427
+ * what an earlier hold staged under a re-armed boundary). */ function heldUnder(e, o, n) {
428
+ for (let l = e.pe; l !== null; l = l.Ge) {
429
+ if ((l.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD && txOf(l) !== o) n(l);
430
+ heldUnder(l, o, n);
407
431
  }
408
432
  }
409
433
 
@@ -413,10 +437,10 @@ function deferZombie(e) {
413
437
  }
414
438
 
415
439
  const dirtyQueue = {
416
- $e: new Array(2e3).fill(undefined),
440
+ et: new Array(2e3).fill(undefined),
417
441
  p: false,
418
442
  Fe: 0,
419
- et: 0
443
+ Et: 0
420
444
  };
421
445
 
422
446
  let clock = 0;
@@ -479,7 +503,7 @@ function schedule() {
479
503
  }
480
504
  if (scheduled) return;
481
505
  scheduled = true;
482
- if (!syncDepth && !globalQueue.q) {
506
+ if (!syncDepth && !globalQueue.Y) {
483
507
  queueMicrotask(flush);
484
508
  }
485
509
  }
@@ -504,7 +528,7 @@ function haltReactivity(e) {
504
528
  halted = true;
505
529
  // A cleanup error collected before the halt is dropped (owner.ts).
506
530
  rethrowCleanupError(true);
507
- let n = HALTED;
531
+ let o = HALTED;
508
532
  // Surface the cause here too: callers rethrow it, but a creation-time throw
509
533
  // unwinds through ancestor recomputes that convert it to status instead of
510
534
  // surfacing it (#2884), so the rethrow alone cannot guarantee visibility.
@@ -514,9 +538,9 @@ function haltReactivity(e) {
514
538
  // nothing an app or its telemetry can act on (#3338 — an uncaught throw
515
539
  // during the hydration render). The rethrow may reach the top as well in
516
540
  // the non-swallowed cases; a duplicate report beats a silent one.
517
- const o = e !== undefined && globalThis.reportError;
518
- o || e === undefined ? console.error(n) : console.error(n, e);
519
- o && o(e);
541
+ const n = e !== undefined && globalThis.reportError;
542
+ n || e === undefined ? console.error(o) : console.error(o, e);
543
+ n && n(e);
520
544
  }
521
545
 
522
546
  /**
@@ -524,7 +548,7 @@ function haltReactivity(e) {
524
548
  * error escaped from — for the REACTIVITY_HALTED message's owner path. Call
525
549
  * sites pick it in dev builds only (`haltReactivity(e)` in production), so
526
550
  * production keeps the one-argument halt and its bytes unchanged.
527
- */ function haltReactivityAt(e, n) {
551
+ */ function haltReactivityAt(e, o) {
528
552
  haltReactivity(e);
529
553
  }
530
554
 
@@ -542,10 +566,10 @@ function notifyHalted() {
542
566
 
543
567
  class GlobalQueue {
544
568
  un=[ [], [] ];
545
- q=false;
569
+ Y=false;
546
570
  flush() {
547
- if (this.q) return;
548
- this.q = true;
571
+ if (this.Y) return;
572
+ this.Y = true;
549
573
  // A28: companions of nodes written since the last flush mirror the
550
574
  // flushed world — re-synced inside the running window (the write is
551
575
  // "flushed" from here on).
@@ -563,14 +587,14 @@ class GlobalQueue {
563
587
  clock++;
564
588
  // A write the commit sweep staged with no subscriber to dirty is work
565
589
  // too — the next round commits it.
566
- scheduled = dirtyQueue.et >= dirtyQueue.Fe || pendingNodes.length !== 0;
590
+ scheduled = dirtyQueue.Et >= dirtyQueue.Fe || pendingNodes.length !== 0;
567
591
  this.run(EFFECT_RENDER);
568
592
  this.run(EFFECT_USER);
569
593
  if (false && holding) ;
570
594
  if (false && !scheduled) ;
571
595
  if (false) ;
572
596
  } finally {
573
- this.q = false;
597
+ this.Y = false;
574
598
  passTx = null;
575
599
  }
576
600
  }
@@ -585,7 +609,7 @@ class GlobalQueue {
585
609
  // pure round — the parent's flights before the parent is judged below.
586
610
  if (laneCorrectionsHook?.()) runHeap(dirtyQueue, GlobalQueue._e);
587
611
  const e = flushTransaction;
588
- flushTransaction = null;
612
+ flushTransaction = latestOpened = null;
589
613
  // The frame's verdict is in: the guesses written since the last seam
590
614
  // open their lane under the frame's transaction (a lane's own flush
591
615
  // parents a nested lane to it), or are dropped — the frame commits, and
@@ -595,13 +619,13 @@ class GlobalQueue {
595
619
  // A lane's own flush (its flight landing, its reveal) parks nothing: the
596
620
  // lane's work reached it per pass; the frame's plain writes commit.
597
621
  // (Resolved: a guess over another transaction's guess merged them.)
598
- const n = e !== null && !e.P ? resolveTx(e) : null;
599
- if (n !== null) {
622
+ const o = e !== null && !e.P ? resolveTx(e) : null;
623
+ if (o !== null) {
600
624
  // `t._nodes` grows under the walk (holdFrame pushes); the bound is
601
625
  // this flush's list, which does not.
602
626
  const e = pendingNodes.length;
603
- for (let o = 0; o < e; o++) {
604
- const e = pendingNodes[o];
627
+ for (let n = 0; n < e; n++) {
628
+ const e = pendingNodes[n];
605
629
  // Already held: the pass that re-staged it joined its transaction,
606
630
  // which is `t` (or merged into it). Lane work is the lane's (a
607
631
  // pending mark propagated onto it queued it here too).
@@ -614,30 +638,30 @@ class GlobalQueue {
614
638
  // stale stamp was the bridge that entangled unrelated updates
615
639
  // with a never-resolving flight). Its observers are held and
616
640
  // wait on its flight (`blocked`).
617
- if (e.ie === NOT_PENDING && e.m & STATUS_UNINITIALIZED && e.i !== EFFECT_RENDER) continue;
641
+ if (e.ue === NOT_PENDING && e.m & STATUS_UNINITIALIZED && e.i !== EFFECT_RENDER) continue;
618
642
  // A34 (2): a tick whose writes net to the committed value made no
619
643
  // proposal (`setShow(false); setShow(true)` on a committed true) —
620
644
  // not staged, not held, pends nothing; a later write to it is
621
645
  // plain mainline. (A node already held stays held when written
622
646
  // back: A34 (1).)
623
- if (e.ie !== NOT_PENDING && !(e.m & (STATUS_PENDING | STATUS_UNINITIALIZED)) && e.T?.Ue == null && e.T?.me == null &&
647
+ if (e.ue !== NOT_PENDING && !(e.m & (STATUS_PENDING | STATUS_UNINITIALIZED)) && e.T?.me == null && e.T?.Le == null &&
624
648
  // The comparator last: a pass that created children (an object
625
649
  // owning a fresh async memo, #4111) must not have it read them.
626
650
  // A NotReady read there is a change (`isSame`).
627
- isSame(e, e.le, e.ie)) {
628
- e.ie = NOT_PENDING;
651
+ isSame(e, e.le, e.ue)) {
652
+ e.ue = NOT_PENDING;
629
653
  e.l &= ~CONFIG_STAGED;
630
654
  continue;
631
655
  }
632
- holdNode(e, n);
656
+ holdNode(e, o);
633
657
  }
634
658
  // A held pass's frame is held with it (ruling A, O2): the children it
635
659
  // created are the transaction's — they compute, and a pass over them
636
660
  // or a write that reaches them joins; they effect at the landing.
637
- if (e.l & CONFIG_STAGED) holdFrame(e, n);
661
+ if (e.l & CONFIG_STAGED) holdFrame(e, o);
638
662
  }
639
663
  pendingNodes.length = 0;
640
- storeParkHook?.(n);
664
+ storeParkHook?.(o);
641
665
  // (This flush's runs are stashed with `t` below — after the landings,
642
666
  // so a `t` that lands at this very seam runs them first, ahead of
643
667
  // the runs it held from earlier flushes.)
@@ -648,10 +672,10 @@ class GlobalQueue {
648
672
  // holder's verdict lane's work — before the lane seams, which reveal
649
673
  // it (nothing commits this seam that could dispose it).
650
674
  // (Verdict readers exist only with the verdict engine installed.)
651
- const o = deferredZombies.splice(0);
675
+ const n = deferredZombies.splice(0);
652
676
  if (observeFlightHook) {
653
- o.sort((e, n) => e.he - n.he);
654
- for (let e = 0; e < o.length; e++) if ((o[e].R & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE)) === REACTIVE_ZOMBIE && o[e].l & CONFIG_VERDICT) recompute(o[e]);
677
+ n.sort((e, o) => e.he - o.he);
678
+ for (let e = 0; e < n.length; e++) if ((n[e].R & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE)) === REACTIVE_ZOMBIE && n[e].l & CONFIG_VERDICT) recompute(n[e]);
655
679
  }
656
680
  // The unchanged passes' tails stay linked (A30, #3469): their inputs
657
681
  // are held, and the committed frame still derives from them — no trim.
@@ -663,8 +687,8 @@ class GlobalQueue {
663
687
  // left an effect owing a run (`runEffect` trims when the run applies):
664
688
  // `recompute`'s own gates.
665
689
  for (let e = 0; e < heldTrims.length; e++) {
666
- const n = heldTrims[e];
667
- if (n.T?.U == null && !n.Ae) trimStaleDeps(n);
690
+ const o = heldTrims[e];
691
+ if (o.T?.U == null && !o.Ae) trimStaleDeps(o);
668
692
  }
669
693
  }
670
694
  // The list is the flush's either way. Reset only when there is something
@@ -678,23 +702,23 @@ class GlobalQueue {
678
702
  // removes its entry.
679
703
  // This flush's own runs, the lanes' reveals, and the landings' held runs
680
704
  // are collected apart and ordered below.
681
- const o = this.un;
682
- const t = [ [], [] ];
705
+ const n = this.un;
706
+ const l = [ [], [] ];
683
707
  // The passes that read this frame's stagings as the screen read held
684
708
  // writes if it parked: the lane seam re-derives them on the committed
685
709
  // world (a lane's runs wait this round).
686
710
  if (laneSeamsHook) {
687
- this.un = t;
688
- laneSeamsHook(n !== null ? stagedReaders : null);
711
+ this.un = l;
712
+ laneSeamsHook(o);
689
713
  if (stagedReaders.length) stagedReaders.length = 0;
690
714
  }
691
715
  this.un = [ [], [] ];
692
716
  for (let e = transactions.length - 1; e >= 0; e--) {
693
- const n = transactions[e];
694
- if (blocked(n)) continue;
717
+ const o = transactions[e];
718
+ if (blocked(o)) continue;
695
719
  transactions.splice(e, 1);
696
- endLanesHook?.(n);
697
- land(n);
720
+ endLanesHook?.(o);
721
+ land(o);
698
722
  // A landing's commits can dispose a zombie a transaction judged above
699
723
  // was blocked on (#3463: live "until the commit that disposes it") —
700
724
  // judge them again.
@@ -707,8 +731,8 @@ class GlobalQueue {
707
731
  // parked (something async below) — the window is the frame's, the marks
708
732
  // are its transaction's; else they release at the seam, verdict-only,
709
733
  // nothing to show (affects.ts).
710
- const l = n && liveTx(n);
711
- releaseAmbientMarksHook?.(l);
734
+ const t = o && liveTx(o);
735
+ releaseAmbientMarksHook?.(t);
712
736
  // The effect phase: lane work first (displayed ahead of the frame), then
713
737
  // this flush's runs, then the runs the landings held from earlier
714
738
  // flushes — as one pass would have queued them (#3540: a shell
@@ -716,21 +740,21 @@ class GlobalQueue {
716
740
  // write; #3528: a display-ahead swap before the count it is shown
717
741
  // beside). A parked frame's runs wait with its transaction instead: the
718
742
  // effect phase applies a committed frame.
719
- const s = l !== null;
743
+ const s = t !== null;
720
744
  for (let e = 0; e < 2; e++) {
721
- if (s) append(l.un[e], o[e]);
745
+ if (s) append(t.un[e], n[e]);
722
746
  // The plain flush — no reveal, no landing, not parked — has nothing to
723
747
  // order around its own runs: they are the queue as they stand (the
724
748
  // same array, not a copy; `run` takes it whole). Every other seam
725
749
  // builds the ordered queue above.
726
- this.un[e] = s || t[e].length || this.un[e].length ? t[e].concat(s ? [] : o[e], this.un[e]) : o[e];
750
+ this.un[e] = s || l[e].length || this.un[e].length ? l[e].concat(s ? [] : n[e], this.un[e]) : n[e];
727
751
  }
728
752
  if (deferredZombies.length !== 0) {
729
753
  // Survivors are the displayed frame of a held pass: they rerun for the
730
754
  // live write, parents before children.
731
- const e = deferredZombies.splice(0).sort((e, n) => e.he - n.he);
732
- for (let n = 0; n < e.length; n++) {
733
- if (!(e[n].R & REACTIVE_DISPOSED)) recompute(e[n]);
755
+ const e = deferredZombies.splice(0).sort((e, o) => e.he - o.he);
756
+ for (let o = 0; o < e.length; o++) {
757
+ if (!(e[o].R & REACTIVE_DISPOSED)) recompute(e[o]);
734
758
  }
735
759
  }
736
760
  // Boundaries: readers that settled, landed or died this flush are
@@ -738,18 +762,18 @@ class GlobalQueue {
738
762
  boundarySeamHook?.();
739
763
  }
740
764
  run(e) {
741
- const n = this.un[e - 1];
742
- if (n.length) {
765
+ const o = this.un[e - 1];
766
+ if (o.length) {
743
767
  this.un[e - 1] = [];
744
- runQueue(n, e);
768
+ runQueue(o, e);
745
769
  }
746
770
  }
747
- enqueue(e, n, o = passLane) {
771
+ enqueue(e, o, n = passLane) {
748
772
  // Lane work's runs are the lane's: they run at its reveal, not with
749
773
  // the frame (which may park). A lane pass that read the frame's own
750
774
  // staging is the frame's (`recompute` passes null): its run waits with
751
775
  // the frame.
752
- if (e) (o !== null ? o : this).un[e - 1].push(n);
776
+ if (e) (n !== null ? n : this).un[e - 1].push(o);
753
777
  schedule();
754
778
  }
755
779
  /** Status reaching the root: pending is absorbed (the root mount defers —
@@ -765,10 +789,10 @@ class GlobalQueue {
765
789
  *
766
790
  * A boundary between the observer and the root (boundaries.ts) is asked
767
791
  * first: a fallback catches what is not ready under it, and the root
768
- * never hears of it. */ notify(e, n, o, t) {
769
- if (catchHook?.(e, o & n, t)) return true;
770
- if (n & STATUS_PENDING) {
771
- if (o & STATUS_PENDING) {
792
+ * never hears of it. */ notify(e, o, n, l) {
793
+ if (catchHook?.(e, n & o, l)) return true;
794
+ if (o & STATUS_PENDING) {
795
+ if (n & STATUS_PENDING) {
772
796
  // A pass that went pending holds its frame: the async's own
773
797
  // synchronous frame is not ready (A15 reveal corollary: a reveal
774
798
  // that discovers a flight whose inputs are visible holds and joins
@@ -800,39 +824,61 @@ class GlobalQueue {
800
824
  * for it is void (#3322: an effect has one value slot, and the stale pass
801
825
  * overwrote the value that run was for) — the re-derivation's run replaces
802
826
  * it. Truthy when an effect re-derives (`land`). */ function reruns(e) {
803
- let n;
804
- for (let o = 0; o < e.En.length; o++) {
805
- const t = e.En[o];
827
+ let o;
828
+ for (let n = 0; n < e.En.length; n++) {
829
+ const l = e.En[n];
806
830
  // An errored reader's display is its error (D-39): the landing gives it
807
831
  // nothing to re-derive, and a re-run would be a read that retries the
808
- // errored source (#3945).
809
- if (t.R & REACTIVE_DISPOSED || t.m & STATUS_ERROR) continue;
810
- if (t.R & REACTIVE_FRAME_READ || t.l & CONFIG_VERDICT) {
811
- n ||= t.i;
812
- t.R &= ~REACTIVE_FRAME_READ;
813
- t.Ae = false;
832
+ // errored source (#3945) — unless that source is errored no longer: the
833
+ // reader was served a shown error the landing replaces (`throwShown`).
834
+ // Nor is the reader's own error: its pass threw over the committed value
835
+ // of what the landing carries, served as the screen (A10; a lane's node
836
+ // reading its parent's hold, or a pass with no value yet reading a
837
+ // staging, `stagedScreen`) — the landing is the new answer, and the
838
+ // reader re-derives on it (A15; D-39). A first load read so has no other
839
+ // run: its error would stay the screen (async-gen 91501 #1158, #119).
840
+ // A boundary's structure (its tree, its output: CONFIG_FRAME, no effect
841
+ // type) re-derives all the same: what it read as the screen is the
842
+ // content the landing replaces, and only its pass links the new content
843
+ // whose recovery must reach it (D-3, D-39, #4405).
844
+ const t = l.T?.U?.source;
845
+ if (l.R & REACTIVE_DISPOSED || l.m & STATUS_ERROR && (l.i || !(l.l & CONFIG_FRAME)) && t !== l && (t?.m ?? STATUS_ERROR) & STATUS_ERROR) continue;
846
+ if (l.R & REACTIVE_FRAME_READ || observeFlightHook && l.l & CONFIG_VERDICT) {
847
+ // A memo re-deriving its own error holds the release as an effect
848
+ // does (`land`): run first, the held runs showed that error beside a
849
+ // frame about to replace it (#4407; #4284: the grouping never changes
850
+ // the screen).
851
+ o ||= l.i || t === l;
852
+ // A lane's reveal leaves the mark to the transaction: a reader that
853
+ // also read a held node as committed (`staleReader`) still observes
854
+ // that flight until it re-runs — cleared here, the transaction landed
855
+ // at this seam with the flight up and voided the reveal's run (#4397).
856
+ if (!e.P) l.R &= ~REACTIVE_FRAME_READ;
857
+ l.Ae = false;
814
858
  // Its frame is replaced by the re-derivation: a run one of its
815
859
  // children queued this flush (re-run by the same landing) is for the
816
860
  // frame being replaced — void too (#3404).
817
- for (let e = t.pe; e !== null; e = e.Ge) if (e.i) e.Ae = false;
818
- enqueueSub(t);
861
+ for (let e = l.pe; e !== null; e = e.Ge) if (e.i) e.Ae = false;
862
+ // A frame flight the seam parked (lanes.ts `laneSeams`, R5) asked the
863
+ // question this landing would: adopted, it is asked once (F-9).
864
+ if (!laneAdoptHook?.(l)) enqueueSub(l);
819
865
  }
820
866
  }
821
867
  e.En.length = 0;
822
- return n;
868
+ return o;
823
869
  }
824
870
 
825
871
  /** The landing: the held frame becomes the frame. */ function land(e) {
826
- const n = reruns(e);
872
+ const o = reruns(e);
827
873
  if (releaseMarksHook && e.I !== null) releaseMarksHook(e.I);
828
874
  // Old children die in the commits (cleanups first), then the stashed
829
875
  // effects run ahead of this flush's own. A node a lane took over since
830
876
  // (a guess written over the staged truth) is the lane's to land.
831
- for (let n = 0; n < e.tn.length; n++) {
832
- const o = e.tn[n];
833
- if (o.T.Re === null || txOf(o) !== e) continue;
834
- o.T.Re = null;
835
- commitPendingNode(o);
877
+ for (let o = 0; o < e.tn.length; o++) {
878
+ const n = e.tn[o];
879
+ if (n.T.Re === null || txOf(n) !== e) continue;
880
+ n.T.Re = null;
881
+ commitPendingNode(n);
836
882
  }
837
883
  // A cleanup those commits ran that wrote a node `u` still held joined
838
884
  // `u`, which has left `transactions`: the write is this landing's, and
@@ -846,21 +892,21 @@ class GlobalQueue {
846
892
  // value. Queued last in this effect phase, the release hands them to the
847
893
  // next round's own runs, ahead of the re-derivation's: they show with it,
848
894
  // or park with it in the hold its pending opens. The commits stand.
849
- if (n) globalQueue.un[1].push(() => releaseQueues(e)); else releaseQueues(e);
895
+ if (o) globalQueue.un[1].push(() => releaseQueues(e)); else releaseQueues(e);
850
896
  }
851
897
 
852
898
  /** The held runs join this flush's effect phase after its own runs (the
853
899
  * landing's re-passes, in height order): the frame's effects run as one
854
900
  * pass would have queued them — a shell re-derived at the landing before a
855
901
  * boundary swap held since the write (#3540's log order). */ function releaseQueues(e) {
856
- for (let n = 0; n < 2; n++) {
857
- append(globalQueue.un[n], e.un[n]);
858
- e.un[n] = [];
902
+ for (let o = 0; o < 2; o++) {
903
+ append(globalQueue.un[o], e.un[o]);
904
+ e.un[o] = [];
859
905
  }
860
906
  }
861
907
 
862
- /** `a.push(...b)` without the argument-count limit. */ function append(e, n) {
863
- for (let o = 0; o < n.length; o++) e.push(n[o]);
908
+ /** `a.push(...b)` without the argument-count limit. */ function append(e, o) {
909
+ for (let n = 0; n < o.length; n++) e.push(o[n]);
864
910
  }
865
911
 
866
912
  /** Nodes staged this flush (`_pendingValue` set), committed at its end. */ const pendingNodes = [];
@@ -872,16 +918,16 @@ class GlobalQueue {
872
918
 
873
919
  /** A15's stale reader: `c` was served the committed value of a node `t`
874
920
  * holds (a render effect, a verdict reader, lane work) and is re-derived
875
- * after `t`'s landing (`_reruns`). Once per pass. */ function staleReader(e, n) {
921
+ * after `t`'s landing (`_reruns`). Once per pass. */ function staleReader(e, o) {
876
922
  if (!(e.R & REACTIVE_FRAME_READ)) {
877
923
  e.R |= REACTIVE_FRAME_READ;
878
- n.En.push(e);
924
+ o.En.push(e);
879
925
  }
880
926
  }
881
927
 
882
928
  function queuePendingNode(e) {
883
929
  pendingNodes.push(e);
884
- if (!globalQueue.q) markUnflushedStaged();
930
+ if (!globalQueue.Y) markUnflushedStaged();
885
931
  // A28
886
932
  }
887
933
 
@@ -901,10 +947,10 @@ function insertSubs(e) {
901
947
  // Presence bits gate the optional-slot probes (see constants.ts): one
902
948
  // masked read of the always-present _config instead of missing-property
903
949
  // lookups in the hottest notify loop.
904
- const n = e.l;
905
- const o = (n & CONFIG_HAS_SNAPSHOT) !== 0 && e.T?.De !== undefined;
906
- for (let n = e.o; n !== null; n = n.t) {
907
- const e = n.u;
950
+ const o = e.l;
951
+ const n = (o & CONFIG_HAS_SNAPSHOT) !== 0 && e.T?.De !== undefined;
952
+ for (let o = e.o; o !== null; o = o.t) {
953
+ const e = o.u;
908
954
  // Missed-wake latch (#3037): this write is landing while the subscriber
909
955
  // is mid-recompute (a nested pull committing beneath its reads), and the
910
956
  // heap refuses RECOMPUTING nodes. A gen-current link means the pass
@@ -913,8 +959,8 @@ function insertSubs(e) {
913
959
  // pass either re-reads them fresh or trims them), and neither does the
914
960
  // tail link: it is the read IN FLIGHT — read() links before it pulls, so
915
961
  // this very commit is what that read returns.
916
- if (e.R & REACTIVE_RECOMPUTING_DEPS && n.de === e.Ne && n !== e._) e.R |= REACTIVE_MISSED_WAKE;
917
- if (o && e.l & CONFIG_IN_SNAPSHOT_SCOPE) {
962
+ if (e.R & REACTIVE_RECOMPUTING_DEPS && o.Ne === e.de && o !== e._) e.R |= REACTIVE_MISSED_WAKE;
963
+ if (n && e.l & CONFIG_IN_SNAPSHOT_SCOPE) {
918
964
  e.R |= REACTIVE_SNAPSHOT_STALE;
919
965
  continue;
920
966
  }
@@ -929,91 +975,100 @@ function insertSubs(e) {
929
975
  * inert for its pass (`recompute` seats a lane only from its own `_x`), it
930
976
  * is a live write if the effect becomes a zombie later this flush — an
931
977
  * on-screen reader whose removal an adopted write stages follows the lane
932
- * (the lane-membership ruling, 2026-10-05; `_update`). */ function laneDirty(e, n) {
933
- for (let o = e.o; o !== null; o = o.t) {
934
- const e = o.u.T?.Re;
935
- if (e?.P ? sameLane(e, n) : o.u.i) o.u.R |= REACTIVE_LANE_DIRTY;
978
+ * (the lane-membership ruling, 2026-10-05; `_update`).
979
+ *
980
+ * A render effect re-run by a verdict memo's change (`createMemo(() =>
981
+ * latest(x))`, CONFIG_VERDICT) is the verdict reader the same read inline
982
+ * makes it, for that pass (F-6; D-26 `[s(), L()]`, #4284): a frame reader
983
+ * of its other reads — a staging's screen, a flight's committed value. One
984
+ * an earlier propagation this flush seated in another lane leaves that
985
+ * seat: its pass starts from the frame's, as the inline effect's does, and
986
+ * `laneRead` re-derives it on the screen if that lane holds (`entered`). */ function laneDirty(e, o) {
987
+ for (let n = e.o; n !== null; n = n.t) {
988
+ const l = n.u, t = l.T?.Re;
989
+ if (l.i === EFFECT_RENDER && e.l & CONFIG_VERDICT) l.l |= CONFIG_VERDICT, l.R &= ~REACTIVE_LANE_DIRTY;
990
+ if (t?.P ? sameLane(t, o) : l.i) l.R |= REACTIVE_LANE_DIRTY;
936
991
  }
937
992
  }
938
993
 
939
- /** One lane, or two of one link group (#3335): one reveal unit. */ function sameLane(e, n) {
940
- return e === n || e.en !== null && e.en === n.en;
994
+ /** One lane, or two of one link group (#3335): one reveal unit. */ function sameLane(e, o) {
995
+ return e === o || e.en !== null && e.en === o.en;
941
996
  }
942
997
 
943
998
  function commitPendingNode(e) {
944
- const n = e;
999
+ const o = e;
945
1000
  // L2: the commit is where a pass, held or not, stops being uncommitted —
946
1001
  // unless it has no answer yet. A pass still in flight (pending, nothing
947
1002
  // staged) stays uncommitted: a re-pass disposes its children on the spot,
948
1003
  // and the frame it parked stays the frame until a pass of this node
949
1004
  // commits a value.
950
- if (!n.X) {
1005
+ if (!o.X) {
951
1006
  e.l &= -385;
952
- if (e.ie !== NOT_PENDING) {
953
- e.le = e.ie;
954
- e.ie = NOT_PENDING;
1007
+ if (e.ue !== NOT_PENDING) {
1008
+ e.le = e.ue;
1009
+ e.ue = NOT_PENDING;
955
1010
  }
956
1011
  return;
957
1012
  }
958
1013
  // Computeds only from here (`_statusFlags` is not a signal field). A
959
1014
  // commit beneath a flight publishes its inputs (A15 reveal corollary,
960
1015
  // #3305): a reveal of it must observe, not show the pre-flight value.
961
- const o = e.ie === NOT_PENDING && (n.m & STATUS_PENDING) !== 0;
962
- const t = e.l & CONFIG_STAGED_ERROR;
1016
+ const n = e.ue === NOT_PENDING && (o.m & STATUS_PENDING) !== 0;
1017
+ const l = e.l & CONFIG_STAGED_ERROR;
963
1018
  // An answer commits: the error it replaces leaves the display (D-41).
964
- if (!o && n.T) n.T.Ie = undefined;
965
- e.l = o ? e.l & -1048833 | CONFIG_INPUTS_PUBLISHED : e.l & -3147137;
1019
+ if (!n && o.T) o.T.Te = null;
1020
+ e.l = n ? e.l & -1048833 | CONFIG_INPUTS_PUBLISHED : e.l & -3147137;
966
1021
  // D-41: the staged answer is an error — published now, when a value would
967
1022
  // show, through the ordinary error path (`stageError`). Its readers first
968
1023
  // see it in the cycle after this seam: a tracked re-read there is not a
969
1024
  // retry (`read`), or a boundary re-derived by it would retry it forever.
970
- if (t) {
971
- const o = e.ie;
972
- e.ie = NOT_PENDING;
973
- e.Se = clock + 1;
974
- notifyStatus(n, STATUS_ERROR, o);
975
- } else if (e.ie !== NOT_PENDING) {
976
- e.le = e.ie;
977
- e.ie = NOT_PENDING;
1025
+ if (l) {
1026
+ const n = e.ue;
1027
+ e.ue = NOT_PENDING;
1028
+ e.ie = clock + 1;
1029
+ notifyStatus(o, STATUS_ERROR, n);
1030
+ } else if (e.ue !== NOT_PENDING) {
1031
+ e.le = e.ue;
1032
+ e.ue = NOT_PENDING;
978
1033
  // A node born staged (recompute) initializes at this commit.
979
- n.m &= ~STATUS_UNINITIALIZED;
1034
+ o.m &= ~STATUS_UNINITIALIZED;
980
1035
  // A quiet re-ask's classification survives its landing and dies with
981
1036
  // the landed value's commit (A19 exc. 2, #3178): verdict-quiet through
982
1037
  // the reveal. (The sweep of a node still in flight is not a landing.)
983
1038
  // The A28 stash goes with it.
984
- if (n.T != null) n.T.Ve = false, n.T.je = NOT_PENDING;
1039
+ if (o.T != null) o.T.Ve = false, o.T.je = NOT_PENDING;
985
1040
  // An effect with a staged value was born held (L2): its first run is
986
1041
  // this commit's, not its creation's (A29) — queue it now.
987
1042
  if (e.i && e.i !== EFFECT_TRACKED) {
988
1043
  e.Ae = true;
989
- globalQueue.enqueue(e.i, e.W ??= GlobalQueue.K.bind(null, n));
1044
+ globalQueue.enqueue(e.i, e.W ??= GlobalQueue.q.bind(null, o));
990
1045
  }
991
1046
  }
992
1047
  // The committed value is the first observable answer for a loading-window
993
1048
  // node — the window closes here, not at compute time (#2990). Unconditional
994
1049
  // store to an always-present computed slot.
995
- n.ce = false;
996
- n.R &= ~REACTIVE_MANUAL_WRITE;
1050
+ o.ce = false;
1051
+ o.R &= ~REACTIVE_MANUAL_WRITE;
997
1052
  // The dependencies of the pass that produced the value are the frame's now:
998
1053
  // the previous frame's tail goes (A30, #3410; `recompute` left it for a
999
1054
  // staged pass). Only after a clean pass: `_error` is cleared by a clean
1000
1055
  // pass or by the node's own landing (whose pass was clean), so a set
1001
1056
  // `_error` means the last pass threw, kept its full list, and `_depsTail`
1002
1057
  // marks where it stopped.
1003
- if (n.T?.U == null) trimStaleDeps(n);
1004
- if (!(n.m & STATUS_PENDING)) n.m &= ~STATUS_UNINITIALIZED;
1058
+ if (o.T?.U == null) trimStaleDeps(o);
1059
+ if (!(o.m & STATUS_PENDING)) o.m &= ~STATUS_UNINITIALIZED;
1005
1060
  // L2: the children this commit publishes are the frame's now — the frame
1006
1061
  // they replace, parked by the pass (`recompute`), goes.
1007
- if (!o && n.T != null && (n.T.Ue !== null || n.T.me !== null)) GlobalQueue.Ce(n, false, true);
1062
+ if (!n && o.T != null && (o.T.me !== null || o.T.Le !== null)) GlobalQueue.Ce(o, false, true);
1008
1063
  }
1009
1064
 
1010
1065
  function commitPendingNodes() {
1011
1066
  for (let e = 0; e < pendingNodes.length; e++) {
1012
- const n = pendingNodes[e];
1067
+ const o = pendingNodes[e];
1013
1068
  // A node a lane pass re-staged this round is the lane's to reveal; one
1014
1069
  // a transaction holds (born held by a mainline pass, `passTx`) is that
1015
1070
  // transaction's to commit, at its landing.
1016
- if (!(n.l & (CONFIG_OVERRIDE | CONFIG_HELD))) commitPendingNode(n);
1071
+ if (!(o.l & (CONFIG_OVERRIDE | CONFIG_HELD))) commitPendingNode(o);
1017
1072
  }
1018
1073
  pendingNodes.length = 0;
1019
1074
  }
@@ -1038,7 +1093,7 @@ function flush(e) {
1038
1093
  }
1039
1094
  }
1040
1095
  }
1041
- if (globalQueue.q) {
1096
+ if (globalQueue.Y) {
1042
1097
  return;
1043
1098
  }
1044
1099
  if (halted) return;
@@ -1050,8 +1105,8 @@ function flush(e) {
1050
1105
  rethrowCleanupError();
1051
1106
  }
1052
1107
 
1053
- function runQueue(e, n) {
1054
- for (let o = 0; o < e.length; o++) e[o](n);
1108
+ function runQueue(e, o) {
1109
+ for (let n = 0; n < e.length; n++) e[n](o);
1055
1110
  }
1056
1111
 
1057
- export { GlobalQueue, MAINLINE_QUESTION, ROOT_ERROR_HOOK, actionDepth, applyGuessesHook, blocked, boundarySeamHook, bumpNotifyEpoch, catchHook, clock, commitPendingNode, deferZombie, dirtyQueue, endLanesHook, enforceLoadingBoundary, enterAction, exitAction, externalUntrackHook, flush, flushTransaction, freshHook, globalQueue, haltReactivity, haltReactivityAt, heldRunHook, heldTrim, heldUnder, hiddenHook, holdNode, insertSubs, installBoundaryHooks, installLaneHooks, installMarkHooks, installStoreHooks, installVerdictHooks, joinFuture, joinPassTx, laneCorrectionsHook, laneDirty, laneOutcomeHook, laneReadHook, laneSeamsHook, laneStageHook, laneWriteHook, lanesBlockedHook, list, liveTx, merge, newTransaction, nextQuestion, notifyEpoch, observeFlightHook, ownFlights, passLane, passTx, pendingNodes, question, queuePendingNode, releaseAmbientMarksHook, releaseMarksHook, releaseQueues, reruns, resetErrorHalt, resolveTx, sameLane, schedule, setExternalHooks, setPassLane, setQuestion, stagedReaders, staleReader, storeCommitHook, storeParkHook, txOf, unhold, wireExternalSourceHook };
1112
+ export { GlobalQueue, MAINLINE_QUESTION, ROOT_ERROR_HOOK, actionDepth, applyGuessesHook, armGuessing, blocked, boundarySeamHook, bumpNotifyEpoch, catchHook, clock, commitPendingNode, deferZombie, dirtyQueue, endLanesHook, enforceLoadingBoundary, enterAction, exitAction, externalUntrackHook, flush, flushTransaction, freshHook, globalQueue, guessing, haltReactivity, haltReactivityAt, heldRunHook, heldTrim, heldUnder, hiddenHook, holdNode, holdWorkHook, insertSubs, installBoundaryHooks, installLaneHooks, installMarkHooks, installStoreHooks, installVerdictHooks, joinFuture, joinPassTx, laneAdoptHook, laneCorrectionsHook, laneDirty, laneOutcomeHook, laneReadHook, laneSeamsHook, laneServedHook, laneStageHook, laneWriteHook, lanesBlockedHook, latestOpened, list, liveTx, merge, newTransaction, nextQuestion, notifyEpoch, observeFlightHook, ownFlights, passLane, passTx, pendingNodes, question, queuePendingNode, releaseAmbientMarksHook, releaseMarksHook, releaseQueues, reruns, resetErrorHalt, resolveTx, sameLane, schedule, setExternalHooks, setPassLane, setQuestion, stagedReaders, staleReader, storeCommitHook, storeParkHook, txOf, unhold, wireExternalSourceHook };