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