@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,7 +1,9 @@
1
- import { STATUS_PENDING, STATUS_ERROR, CONFIG_REDERIVE, CONFIG_HELD, CONFIG_FRAME, STATUS_UNINITIALIZED, EFFECT_RENDER, CONFIG_VERDICT, REACTIVE_DISPOSED, REACTIVE_LANE_READ, CONFIG_OVERRIDE, EFFECT_USER, EFFECT_TRACKED, REACTIVE_ZOMBIE, CAUGHT_REARMED } from "./core/constants.js";
1
+ import { STATUS_PENDING, STATUS_ERROR, CONFIG_REDERIVE, CONFIG_HELD, CONFIG_FRAME, STATUS_UNINITIALIZED, EFFECT_RENDER, CONFIG_VERDICT, REACTIVE_DISPOSED, REACTIVE_LANE_READ, REACTIVE_PROBED, CONFIG_STAGED_ERROR, CONFIG_OVERRIDE, EFFECT_USER, EFFECT_TRACKED, REACTIVE_ZOMBIE, CAUGHT_REARMED } from "./core/constants.js";
2
2
 
3
3
  import { signal, runWithOwner, computed, read, setSignal, recompute } from "./core/core.js";
4
4
 
5
+ import { reportDiagnostic, emitDiagnostic } from "./core/dev.js";
6
+
5
7
  import { NotReadyError, unwrapStatusError } from "./core/error.js";
6
8
 
7
9
  import { reportClientError } from "./core/error-hooks.js";
@@ -81,27 +83,37 @@ const boundaryOf = e => e.A[BOUNDARY];
81
83
  /** Catches what reaches it: an error boundary always; a loading one until it
82
84
  * has shown content, or while re-armed. */ const isCollecting = e => e.i === STATUS_ERROR || !e.D || e.h;
83
85
 
84
- /** A reader `b` waits on: recorded for its `on`, and `b` visited at the seam. */ function record(e, r) {
85
- e.F.add(r);
86
+ /** A reader `b` waits on: recorded for its `on`, and `b` visited at the seam. */ function record(e, n, r = n) {
87
+ e.F.set(n, r);
86
88
  collecting.add(e);
87
89
  }
88
90
 
89
91
  /** The reader goes to the fallback: recorded, and the output re-derives
90
92
  * (a no-op while the output's own pass is running — its post-check
91
- * decides). */ function caught(e, r, n) {
93
+ * decides). */ function caught(e, n, r, o = n) {
92
94
  if (e.i === STATUS_ERROR) {
93
95
  // An error boundary waits on what THREW (`StatusError.source`), not on
94
- // the reader that saw it: the reader recovers the moment a refetch
95
- // starts (its boundary catches the pending), while the error is settled
96
- // only when its source is neither errored nor in flight. `reset` re-runs
97
- // the same node.
98
- n ??= r.T?.U;
99
- r = n?.source ?? r;
100
- const o = unwrapStatusError(n);
101
- setSignal(e.U, o);
102
- reportClientError(o, e.H, r);
96
+ // the reader that saw it, while the error is settled only when its
97
+ // source is neither errored nor in flight and the reader is not pending
98
+ // on the answer that replaces it (`prune`) — or when the
99
+ // reader is disposed: a source no live reader holds holds nothing
100
+ // (#4373). A source that died (a memo its reader owned, kept past the
101
+ // pass that disposed it) settles nothing: the reader is waited on.
102
+ // `reset` re-runs the source.
103
+ r ??= n.T?.U;
104
+ o = r?.source ?? n;
105
+ if (o.R & REACTIVE_DISPOSED) o = n;
106
+ const t = unwrapStatusError(r);
107
+ setSignal(e.U, t);
108
+ reportClientError(t, e.H, o);
103
109
  }
104
- record(e, r);
110
+ record(e, n, o);
111
+ // A loading fallback behind an error fallback is hidden: the error stays
112
+ // the display until what the fallback waits on answers (D-39) — the
113
+ // error boundary waits on it too.
114
+ // (`_type`: STATUS_PENDING 1 < STATUS_ERROR 2 — an error boundary above a
115
+ // loading one.)
116
+ for (let r = e; r = r._parent; ) if (r.L && r.i > e.i) record(r, n);
105
117
  if (e.h) flip(e);
106
118
  // Already showing the fallback: one more reader to wait on changes
107
119
  // nothing on screen. The fallback is instantiated once per show — a later
@@ -117,8 +129,8 @@ const boundaryOf = e => e.A[BOUNDARY];
117
129
  * transaction with the arming frame's (#3540 `on: () => latest(dep)`). */ function flip(e) {
118
130
  e.D = false;
119
131
  e.P = e.B;
120
- const r = e.j;
121
- if (!e.P && r.l & CONFIG_HELD && txOf(r) !== flushTransaction) unhold(r);
132
+ const n = e.j;
133
+ if (!e.P && n.l & CONFIG_HELD && txOf(n) !== flushTransaction) unhold(n);
122
134
  if (laneStageHook && e.P !== null && e.j !== null) laneStageHook(e.j, e.P, true, false);
123
135
  }
124
136
 
@@ -131,25 +143,29 @@ function redraw(e) {
131
143
 
132
144
  /** `catchHook` (scheduler.ts): status from a frame reader, nearest boundary first.
133
145
  * A loading boundary on the way records a pending reader whether or not it
134
- * catches it (its `on` may collect it later). */ function catchStatus(e, r, n) {
135
- if (r === 0) {
146
+ * catches it (its `on` may collect it later). */ function catchStatus(e, n, r) {
147
+ if (n === 0) {
136
148
  // A status cleared. Judged by the node's status now, against each
137
- // boundary's own rule (`unsettled`) — the error path clears pending
149
+ // boundary's own rule (`prune`'s mask) — the error path clears pending
138
150
  // first and the node is still errored then. The last reader a fallback
139
151
  // waited on settling re-derives the output now, in the same heap (a
140
152
  // held reader's landing has joined its transaction, so the content
141
153
  // lands with its run, not a round after). Others still waiting: nothing
142
- // on screen changes, the fallback stays as it is.
143
- if (collecting.size !== 0) for (let r = boundaryOf(e); r; r = r._parent) if (!(e.m & unsettled(r)) && r.F.delete(e) && r.F.size === 0) {
144
- if (r.L) redraw(r);
145
- if (revealHooks && r.v !== null) revealHooks.V(r.v);
154
+ // on screen changes, the fallback stays as it is. `node` here is an
155
+ // effect reporting its own status. An error boundary records an effect
156
+ // only while it is errored, and a staged error keeps STATUS_ERROR on a
157
+ // node that had it (`stageError`), so `prune`'s CONFIG_STAGED_ERROR case
158
+ // cannot reach this path (#4364).
159
+ if (collecting.size !== 0) for (let n = boundaryOf(e); n; n = n._parent) if (!(n.F.get(e)?.m & (n.i | STATUS_PENDING)) && n.F.delete(e) && n.F.size === 0) {
160
+ if (n.L) redraw(n);
161
+ if (revealHooks && n.v !== null) revealHooks.V(n.v);
146
162
  }
147
163
  return false;
148
164
  }
149
165
  for (let o = boundaryOf(e); o; o = o._parent) {
150
- if (!(o.i & r)) continue;
166
+ if (!(o.i & n)) continue;
151
167
  if (isCollecting(o)) {
152
- caught(o, e, n);
168
+ caught(o, e, r);
153
169
  return o.h ? CAUGHT_REARMED : true;
154
170
  }
155
171
  record(o, e);
@@ -159,12 +175,12 @@ function redraw(e) {
159
175
 
160
176
  /** The nearest loading boundary that would catch `node` was re-armed this
161
177
  * flush. */ function armedOver(e) {
162
- for (let r = boundaryOf(e); r; r = r._parent) if (r.i & STATUS_PENDING && isCollecting(r)) return r.h;
178
+ for (let n = boundaryOf(e); n; n = n._parent) if (n.i & STATUS_PENDING && isCollecting(n)) return n.h;
163
179
  }
164
180
 
165
181
  /** The nearest boundary on `r`'s chain showing its fallback, if any
166
182
  * (`hiddenHook`: `r` is behind a fallback). */ function hiddenBy(e) {
167
- for (let r = boundaryOf(e); r; r = r._parent) if (r.L) return r;
183
+ for (let n = boundaryOf(e); n; n = n._parent) if (n.L) return n;
168
184
  return undefined;
169
185
  }
170
186
 
@@ -179,9 +195,9 @@ function redraw(e) {
179
195
  * synchronous on creation and never comes here. The run's `_modified` stays
180
196
  * set; the reveal re-queues it by type (`release`), and a boundary above
181
197
  * still showing its fallback holds it again then. */ function heldRun(e) {
182
- const r = hiddenBy(e);
183
- if (r === undefined) return false;
184
- (r.M ??= new Set).add(e);
198
+ const n = hiddenBy(e);
199
+ if (n === undefined) return false;
200
+ (n.M ??= new Set).add(e);
185
201
  return true;
186
202
  }
187
203
 
@@ -189,9 +205,9 @@ function redraw(e) {
189
205
  * its own phase — render updates with the frame that attaches the content,
190
206
  * user effects after it. */ function release(e) {
191
207
  if (e.M === null) return;
192
- for (const r of e.M) {
193
- const e = r.i;
194
- globalQueue.enqueue(e === EFFECT_TRACKED ? EFFECT_USER : e, e === EFFECT_TRACKED ? r.Z : r.W ??= GlobalQueue.K.bind(null, r));
208
+ for (const n of e.M) {
209
+ const e = n.i;
210
+ globalQueue.enqueue(e === EFFECT_TRACKED ? EFFECT_USER : e, e === EFFECT_TRACKED ? n.Z : n.W ??= GlobalQueue.q.bind(null, n));
195
211
  }
196
212
  e.M = null;
197
213
  }
@@ -201,13 +217,21 @@ function redraw(e) {
201
217
  * that landed but is held (its value staged in a transaction) is not: the
202
218
  * content reveals at the commit, with its run. The tree is: the output reads
203
219
  * it and enters the transaction itself (its committed value shows until the
204
- * landing). */ const unsettled = e => e.i === STATUS_ERROR ? STATUS_ERROR | STATUS_PENDING : STATUS_PENDING;
205
-
206
- function prune(e, r) {
207
- const n = unsettled(e);
208
- for (const o of e.F) {
209
- if (o.R & REACTIVE_DISPOSED) e.F.delete(o); else if (!(o.m & n)) {
210
- if ((o !== e.Y || e.h) && (o.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD) {
220
+ * landing). The statuses that keep a reader: pending — and its error, for an
221
+ * error boundary (`_type` is the status it catches) — on the reader or its
222
+ * source. A reader pending again after the source that threw answered (it
223
+ * re-asks through a memo that carried the error) has no new answer yet: the
224
+ * error stays the display (D-39: a pending is not a value; async-gen 91501
225
+ * #1831). */ function prune(e, n) {
226
+ const r = e.i | STATUS_PENDING;
227
+ for (const [o, t] of e.F) {
228
+ if (!((o.R | t.R) & REACTIVE_DISPOSED)) {
229
+ // An error staged on its source (D-41, `stageError`) is not settled:
230
+ // it publishes with the commit. A reader that threw it now (a lane
231
+ // pass, a reader of a node born staged) reached the boundary first
232
+ // (#4364).
233
+ if ((o.m | t.m) & r || r & STATUS_ERROR && t.l & CONFIG_STAGED_ERROR) continue;
234
+ if ((t !== e.K || e.h) && (t.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD) {
211
235
  // Landed, held: the content is that transaction's — the output's
212
236
  // pass enters it and the reveal lands with the reader's run. The
213
237
  // seam, past its park decision, waits for the commit instead. (A
@@ -215,11 +239,11 @@ function prune(e, r) {
215
239
  // has not shown content catches it instead: the fallback stays until
216
240
  // the reader is committed (#3540: what a fresh boundary catches holds
217
241
  // nothing outside it).
218
- if (!r || !e.D) continue;
219
- joinFuture(txOf(o));
242
+ if (!n || !e.D) continue;
243
+ joinFuture(txOf(t));
220
244
  }
221
- e.F.delete(o);
222
245
  }
246
+ e.F.delete(o);
223
247
  }
224
248
  return e.F.size;
225
249
  }
@@ -227,23 +251,28 @@ function prune(e, r) {
227
251
  /** Reveal order: a slot is ready when its content can show — it has shown
228
252
  * content, or nothing under it is unready (the tree neither pending nor
229
253
  * born held, no reader waited on). */ function ready(e) {
230
- return e.D || !(e.Y.m & STATUS_PENDING) && !(e.Y.l & CONFIG_HELD && (e.j === null || e.j.m & STATUS_UNINITIALIZED)) && prune(e, false) === 0;
254
+ return e.D || !(e.K.m & STATUS_PENDING) && !(e.K.l & CONFIG_HELD && (e.j === null || e.j.m & STATUS_UNINITIALIZED)) && prune(e, false) === 0;
231
255
  }
232
256
 
233
257
  /** `boundarySeamHook` (scheduler.ts), end of the seam: readers that settled, died,
234
258
  * or landed and committed are dropped; a fallback with none left reveals
235
259
  * next round. An arm resolves: nothing collected, nothing happened. */ function boundarySeam() {
236
260
  for (const e of collecting) {
237
- const r = e.j.R;
238
- if (r & REACTIVE_DISPOSED) {
261
+ const n = e.j.R;
262
+ if (n & REACTIVE_DISPOSED) {
239
263
  collecting.delete(e);
240
264
  continue;
241
265
  }
242
266
  // A parked frame's boundary (zombie) keeps its state for its revival.
243
- if (r & REACTIVE_ZOMBIE) continue;
267
+ if (n & REACTIVE_ZOMBIE) continue;
244
268
  prune(e, false);
245
- const n = e.j;
246
- if (e.h && !e.D && n.l & CONFIG_HELD && [ ...e.F ].every(e => !(e.m & STATUS_PENDING) && e.l & CONFIG_HELD && txOf(e) === txOf(n))) {
269
+ const r = e.j;
270
+ // A fallback staged into the very hold its readers landed in folds back
271
+ // (D-16, U-9): the content is ready when that hold commits (D-15). Not
272
+ // only at the re-arm's own seam: readers pending then land, held, a
273
+ // flush later (#4379 — the staged fallback otherwise commits with the
274
+ // hold, and a quiet refresh then caught keeps it up, F-9).
275
+ if (!e.D && r.l & CONFIG_HELD && [ ...e.F ].every(([, e]) => !(e.m & STATUS_PENDING) && e.l & CONFIG_HELD && txOf(e) === txOf(r))) {
247
276
  e.F.clear();
248
277
  e.D = true;
249
278
  }
@@ -284,22 +313,25 @@ function prune(e, r) {
284
313
  // whose frame has no transaction yet: the swap is still display-ahead — the frame gets one now (it lands
285
314
  // at this very seam if nothing holds it), and the swap is its verdict
286
315
  // lane's work, shown ahead of the frame's own runs (#3528).
287
- let r = passLane;
288
- if (r === null && globalQueue.q && getOwner().l & CONFIG_VERDICT) {
316
+ let n = passLane;
317
+ if (n === null && globalQueue.Y && getOwner().l & CONFIG_VERDICT) {
289
318
  joinFuture(null);
290
- r = GlobalQueue.J(flushTransaction);
319
+ n = GlobalQueue.J(flushTransaction);
291
320
  }
292
- e.B = r;
321
+ e.B = n;
293
322
  collecting.add(e);
294
- const n = e.F.size;
295
- heldUnder(e.H, flushTransaction, r => record(e, r));
296
- for (const r of e.F) {
297
- if (e.F.size !== n || r.m & STATUS_PENDING && !(r.R & REACTIVE_DISPOSED)) {
323
+ const r = e.F.size;
324
+ heldUnder(e.H, flushTransaction, n => record(e, n));
325
+ for (const [n] of e.F) {
326
+ if (e.F.size !== r || n.m & STATUS_PENDING && !(n.R & REACTIVE_DISPOSED)) {
298
327
  // What it collects was forwarded through it to the boundaries above
299
328
  // too (`catchStatus` records a reader in every boundary on the way).
300
329
  // It is this boundary's alone now (B5, the nearest catcher): an outer
301
330
  // re-armed by the same tick does not wait for it (D-14, U-4).
302
- for (let r = e._parent; r !== null; r = r._parent) for (const n of e.F) r.F.delete(n);
331
+ for (let n = e._parent; n !== null; n = n._parent)
332
+ // An outer error boundary keys its readers too, but waits on their
333
+ // sources: a re-armed Loading taking the pending does not settle it.
334
+ if (n.i & STATUS_PENDING) for (const [r] of e.F) n.F.delete(r);
303
335
  flip(e);
304
336
  redraw(e);
305
337
  return;
@@ -310,19 +342,33 @@ function prune(e, r) {
310
342
  /** The error boundary's `reset`: re-run what threw (a comparator throw
311
343
  * names a signal — nothing to re-run). */ function reset(e) {
312
344
  // A snapshot: a source failing again is caught — and re-added — mid-walk.
313
- for (const r of [ ...e.F ]) if (r.X !== undefined && !(r.R & REACTIVE_DISPOSED)) recompute(r);
345
+ for (const n of new Set(e.F.values())) if (n.X !== undefined && !(n.R & REACTIVE_DISPOSED)) recompute(n);
314
346
  schedule();
315
347
  }
316
348
 
317
- function createBoundary(e, r, n, o) {
349
+ /**
350
+ * Dev CHECK: the `on` dependencies evaluated to a function — `<Loading
351
+ * on={route}>` or `on={() => route()}` passes the accessor itself, a stable
352
+ * value that is never called, so nothing is read and the boundary never
353
+ * re-arms. Checked on the first run only: the shape is static.
354
+ */ function reportOnAccessor(e) {
355
+ reportDiagnostic(emitDiagnostic({
356
+ code: "LOADING_ON_ACCESSOR",
357
+ kind: "async",
358
+ severity: "warn",
359
+ message: "[LOADING_ON_ACCESSOR] A Loading boundary's `on` received a function. `on` takes the " + "dependency's value — `on={route()}`, or `on={[query(), page()]}` for several — and an " + "accessor passed instead is never called, so nothing is read and the boundary never re-arms."
360
+ }, e.H));
361
+ }
362
+
363
+ function createBoundary(e, n, r, o) {
318
364
  const t = createOwner();
319
365
  const l = {
320
366
  i: e,
321
367
  _parent: boundaryOf(t) ?? null,
322
368
  H: t,
323
- Y: null,
369
+ K: null,
324
370
  j: null,
325
- F: new Set,
371
+ F: new Map,
326
372
  D: false,
327
373
  h: false,
328
374
  B: null,
@@ -333,13 +379,13 @@ function createBoundary(e, r, n, o) {
333
379
  $: false,
334
380
  ee: false,
335
381
  U: e === STATUS_ERROR ? signal(undefined, ERROR_SIGNAL) : null,
336
- re: n,
337
- ne: null
382
+ ne: r,
383
+ re: null
338
384
  };
339
- const u = e === STATUS_PENDING ? t.A[REVEAL] : null;
385
+ const a = e === STATUS_PENDING ? t.A[REVEAL] : null;
340
386
  if (getOwner()) cleanup(() => {
341
387
  collecting.delete(l);
342
- if (revealHooks && u) revealHooks.oe(u, l);
388
+ if (revealHooks && a) revealHooks.oe(a, l);
343
389
  });
344
390
  // The `on` dependencies live OUTSIDE the boundary, as the condition of a
345
391
  // `<Show>` wrapping it would: created before the owner's context names it.
@@ -350,7 +396,8 @@ function createBoundary(e, r, n, o) {
350
396
  let e = false;
351
397
  runWithOwner(t, () => computed(() => {
352
398
  try {
353
- o();
399
+ const n = o();
400
+ if (false && !e && typeof n === "function") ;
354
401
  } catch (e) {
355
402
  if (!(e instanceof NotReadyError)) {
356
403
  if (!globalQueue.notify(getOwner(), STATUS_ERROR, STATUS_ERROR, e)) {
@@ -363,32 +410,32 @@ function createBoundary(e, r, n, o) {
363
410
  if (e) arm(l); else e = true;
364
411
  })).l |= CONFIG_REDERIVE;
365
412
  }
366
- const a = {
413
+ const u = {
367
414
  ...t.A,
368
415
  [BOUNDARY]: l
369
416
  };
370
- if (revealHooks !== null) a[REVEAL] = null;
371
- t.A = a;
417
+ if (revealHooks !== null) u[REVEAL] = null;
418
+ t.A = u;
372
419
  const i = runWithOwner(t, () => {
373
- const e = false ? computed(r, {
420
+ const e = false ? computed(n, {
374
421
  name: "children"
375
- }) : computed(r);
422
+ }) : computed(n);
376
423
  return false ? computed(() => flatten(read(e)), {
377
424
  name: "boundary"
378
425
  }) : computed(() => flatten(read(e)));
379
426
  });
380
- l.Y = i;
427
+ l.K = i;
381
428
  // A slot of the reveal order in its context (reveal.ts): gated until the
382
429
  // controller releases it — before the output's first pass.
383
- if (revealHooks && u) revealHooks.te(u, l);
384
- const f = computed(() => {
430
+ if (revealHooks && a) revealHooks.te(a, l);
431
+ const s = computed(() => {
385
432
  // Structure, not a derivation of its content (CONFIG_FRAME, #4283): it
386
433
  // reads a hold it is not part of as the screen, as the render effect
387
434
  // flattening the same children without a boundary would. Not while a
388
435
  // re-arm's swap is the change's work (`arm`), until that swap commits
389
436
  // (D-13, #3540).
390
- const r = getOwner();
391
- if (!l.h && !(r.l & CONFIG_HELD)) r.l |= CONFIG_FRAME;
437
+ const n = getOwner();
438
+ if (!l.h && !(n.l & CONFIG_HELD)) n.l |= CONFIG_FRAME;
392
439
  // Reveal order (reveal.ts): a gated slot shows its fallback — or, in a
393
440
  // collapsed tail, nothing — whatever its content's state; the
394
441
  // controller is told the pass ran (its readiness may have changed) and
@@ -399,7 +446,7 @@ function createBoundary(e, r, n, o) {
399
446
  // It may release this very slot (the frontier whose content just
400
447
  // settled): the pass goes on to show it — the redraw it asks for is
401
448
  // refused mid-pass and not needed.
402
- link(i, r);
449
+ link(i, n);
403
450
  if (revealHooks && l.v !== null) revealHooks.V(l.v);
404
451
  if (l.$) {
405
452
  if (l.ee) {
@@ -416,10 +463,10 @@ function createBoundary(e, r, n, o) {
416
463
  // display-ahead `on` causes is the lane's, and must still be the
417
464
  // fallback. Linked, so its recovery re-derives this pass; read again
418
465
  // once clean.
419
- const n = i.m & (STATUS_PENDING | STATUS_ERROR);
420
- if (n !== 0) {
421
- link(i, r);
422
- if (n & e) {
466
+ const r = i.m & (STATUS_PENDING | STATUS_ERROR);
467
+ if (r !== 0) {
468
+ link(i, n);
469
+ if (r & e) {
423
470
  if (isCollecting(l)) {
424
471
  caught(l, i, undefined);
425
472
  return fallback(l);
@@ -444,7 +491,7 @@ function createBoundary(e, r, n, o) {
444
491
  // enters: the outside sees its committed value until the landing,
445
492
  // which reveals the content — a fallback staged earlier is replaced
446
493
  // ahead of the commit and never shown.
447
- if (l.F.size !== 0 && r.m & STATUS_UNINITIALIZED && !(r.l & CONFIG_HELD)) return fallback(l);
494
+ if (l.F.size !== 0 && n.m & STATUS_UNINITIALIZED && !(n.l & CONFIG_HELD)) return fallback(l);
448
495
  // Readers under it still unready: the fallback, the tree untouched.
449
496
  // The seam re-derives this pass when they settle.
450
497
  if (prune(l, true) !== 0) return fallback(l);
@@ -452,10 +499,10 @@ function createBoundary(e, r, n, o) {
452
499
  let o;
453
500
  try {
454
501
  o = read(i);
455
- } catch (r) {
456
- if (r instanceof NotReadyError ? e === STATUS_PENDING : e === STATUS_ERROR) {
502
+ } catch (n) {
503
+ if (n instanceof NotReadyError ? e === STATUS_PENDING : e === STATUS_ERROR) {
457
504
  if (isCollecting(l)) {
458
- caught(l, i, r);
505
+ caught(l, i, n);
459
506
  return fallback(l);
460
507
  }
461
508
  // Forwarded: a loading boundary showing content keeps it and
@@ -463,7 +510,7 @@ function createBoundary(e, r, n, o) {
463
510
  record(l, i);
464
511
  }
465
512
  // A pending passes an error boundary by (A6).
466
- throw r;
513
+ throw n;
467
514
  }
468
515
  // Readers under it still unready (caught before, or while the read
469
516
  // ran the content at a mount): the fallback.
@@ -479,15 +526,15 @@ function createBoundary(e, r, n, o) {
479
526
  // the screen does not show (a swap staged with a held frame, replaced
480
527
  // before it commits) dies now: what it reads holds nothing (S-22 row
481
528
  // 3′, #4268).
482
- const t = l.ne;
529
+ const t = l.re;
483
530
  const drop = () => {
484
- if (!l.L && l.ne === t) {
531
+ if (!l.L && l.re === t) {
485
532
  // A fallback that threw (a rethrow the boundary does not
486
533
  // handle) is what an enclosing boundary waits on: it died, and
487
534
  // the seam of another round drops it there (#4270).
488
535
  if (t.m & STATUS_ERROR) schedule();
489
536
  dispose(t);
490
- l.ne = null;
537
+ l.re = null;
491
538
  }
492
539
  };
493
540
  if (t !== null) l.j.le !== t.le ? drop() : globalQueue.enqueue(EFFECT_RENDER, drop);
@@ -505,22 +552,24 @@ function createBoundary(e, r, n, o) {
505
552
  // and legitimately swaps mid-hydration (resume), so it must never be
506
553
  // frozen by snapshot capture.
507
554
  {
508
- ue: true
555
+ ae: true
509
556
  });
510
- f.l |= CONFIG_REDERIVE;
557
+ s.l |= CONFIG_REDERIVE;
511
558
  // The tree is structure too (the output's pass marks the output).
512
559
  i.l |= CONFIG_FRAME;
513
- l.j = f;
514
- return accessor(f);
560
+ l.j = s;
561
+ return accessor(s);
515
562
  }
516
563
 
517
564
  function fallback(e) {
565
+ // (The output's pass.)
566
+ const n = getOwner();
518
567
  // The swap a display-ahead re-arm asked for: this pass is the lane's — a
519
568
  // lane read by construction (REACTIVE_LANE_READ: `recompute`'s tail keeps
520
569
  // the pass in the lane).
521
- if (e.P !== null) {
570
+ if (e.P !== null) {
522
571
  setPassLane(e.P);
523
- e.j.R |= REACTIVE_LANE_READ;
572
+ n.R |= REACTIVE_LANE_READ;
524
573
  e.P = null;
525
574
  }
526
575
  e.L = true;
@@ -535,18 +584,24 @@ function fallback(e) {
535
584
  // outside the boundary, as the output is: its errors and runs are the
536
585
  // enclosing boundary's — with the output's id, so what it builds gets the
537
586
  // ids a build under the output would; disposed once content is on screen.
538
- if (e.ne === null) {
539
- const r = getOwner();
540
- e.ne = runWithOwner(r._parent, () => computed(() => e.re(e), {
541
- id: r.id
542
- }));
543
- }
544
- return read(e.ne);
587
+ if (e.re === null) e.re = runWithOwner(n._parent, () => computed(() => e.ne(e), {
588
+ id: n.id
589
+ }));
590
+ // The swap is structure (#3540): what the fallback reads ahead — a
591
+ // verdict (`latest()`), a lane — is the fallback's display-ahead, not the
592
+ // swap's: the output's pass stays where it was (F-6 stays inside the
593
+ // fallback, #4337).
594
+ const r = passLane;
595
+ const o = n.R;
596
+ const t = read(e.re);
597
+ setPassLane(r);
598
+ n.R ^= (n.R ^ o) & (REACTIVE_PROBED | REACTIVE_LANE_READ);
599
+ return t;
545
600
  }
546
601
 
547
602
  const ERROR_SIGNAL = {
548
603
  ownedWrite: true,
549
- ue: true
604
+ ae: true
550
605
  };
551
606
 
552
607
  /**
@@ -590,8 +645,8 @@ const ERROR_SIGNAL = {
590
645
  * ) as unknown as JSX.Element;
591
646
  * }
592
647
  * ```
593
- */ function createLoadingBoundary(e, r, n) {
594
- return createBoundary(STATUS_PENDING, e, () => r(), n?.on);
648
+ */ function createLoadingBoundary(e, n, r) {
649
+ return createBoundary(STATUS_PENDING, e, () => n(), r?.on);
595
650
  }
596
651
 
597
652
  /**
@@ -616,12 +671,12 @@ const ERROR_SIGNAL = {
616
671
  * ) as unknown as JSX.Element;
617
672
  * }
618
673
  * ```
619
- */ function createErrorBoundary(e, r) {
620
- return createBoundary(STATUS_ERROR, e, e => r(accessor(e.U), () => reset(e)));
674
+ */ function createErrorBoundary(e, n) {
675
+ return createBoundary(STATUS_ERROR, e, e => n(accessor(e.U), () => reset(e)));
621
676
  }
622
677
 
623
678
  // Installed at module evaluation — present exactly when something imports a
624
679
  // boundary. An app without one pays the three null checks and nothing else.
625
- installBoundaryHooks(catchStatus, (e, r) => !r && (e.m & STATUS_UNINITIALIZED ? catchStatus(e, STATUS_PENDING) : armedOver(e)), hiddenBy, boundarySeam, heldRun);
680
+ installBoundaryHooks(catchStatus, (e, n) => !n && (e.m & STATUS_UNINITIALIZED ? catchStatus(e, STATUS_PENDING) : armedOver(e)), hiddenBy, boundarySeam, heldRun);
626
681
 
627
682
  export { REVEAL, createErrorBoundary, createLoadingBoundary, prune, ready, redraw, revealHooks, setRevealHooks };