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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/dev-shared.js +785 -367
  2. package/dist/dev.attribution.js +75 -52
  3. package/dist/dev.js +1120 -567
  4. package/dist/observe/affects-marks.js +86 -0
  5. package/dist/observe/affects.js +22 -73
  6. package/dist/observe/boundaries.js +191 -189
  7. package/dist/observe/core/async.js +175 -131
  8. package/dist/observe/core/attribution-queries.js +1 -1
  9. package/dist/observe/core/attribution.js +176 -159
  10. package/dist/observe/core/constants.js +17 -3
  11. package/dist/observe/core/context.js +3 -3
  12. package/dist/observe/core/core.js +503 -363
  13. package/dist/observe/core/dev.js +66 -38
  14. package/dist/observe/core/effect.js +48 -48
  15. package/dist/observe/core/error.js +5 -3
  16. package/dist/observe/core/external.js +5 -6
  17. package/dist/observe/core/graph.js +57 -43
  18. package/dist/observe/core/heap.js +33 -33
  19. package/dist/observe/core/identities.js +62 -0
  20. package/dist/observe/core/lanes.js +226 -259
  21. package/dist/observe/core/owner.js +62 -50
  22. package/dist/observe/core/scheduler.js +319 -171
  23. package/dist/observe/core/truth.js +45 -0
  24. package/dist/observe/core/verdict.js +88 -50
  25. package/dist/observe/deferred.js +184 -0
  26. package/dist/observe/index.js +7 -1
  27. package/dist/observe/map.js +345 -260
  28. package/dist/observe/reveal.js +76 -76
  29. package/dist/observe/signals.js +41 -30
  30. package/dist/observe/store/affects.js +6 -6
  31. package/dist/observe/store/edges.js +39 -0
  32. package/dist/observe/store/optimistic.js +41 -36
  33. package/dist/observe/store/projection.js +68 -55
  34. package/dist/observe/store/store.js +157 -104
  35. package/dist/prod/affects-marks.js +86 -0
  36. package/dist/prod/affects.js +23 -72
  37. package/dist/prod/boundaries.js +155 -153
  38. package/dist/prod/core/async.js +171 -127
  39. package/dist/prod/core/constants.js +17 -3
  40. package/dist/prod/core/context.js +3 -3
  41. package/dist/prod/core/core.js +478 -342
  42. package/dist/prod/core/effect.js +68 -68
  43. package/dist/prod/core/error.js +5 -3
  44. package/dist/prod/core/external.js +5 -6
  45. package/dist/prod/core/graph.js +57 -43
  46. package/dist/prod/core/heap.js +38 -38
  47. package/dist/prod/core/identities.js +62 -0
  48. package/dist/prod/core/lanes.js +217 -250
  49. package/dist/prod/core/owner.js +62 -51
  50. package/dist/prod/core/scheduler.js +310 -162
  51. package/dist/prod/core/truth.js +45 -0
  52. package/dist/prod/core/verdict.js +87 -49
  53. package/dist/prod/deferred.js +182 -0
  54. package/dist/prod/index.js +7 -1
  55. package/dist/prod/map.js +360 -275
  56. package/dist/prod/reveal.js +76 -76
  57. package/dist/prod/signals.js +41 -30
  58. package/dist/prod/store/affects.js +6 -6
  59. package/dist/prod/store/edges.js +39 -0
  60. package/dist/prod/store/optimistic.js +37 -33
  61. package/dist/prod/store/projection.js +25 -19
  62. package/dist/prod/store/store.js +142 -96
  63. package/dist/types/affects-marks.d.ts +14 -0
  64. package/dist/types/boundaries.d.ts +1 -1
  65. package/dist/types/core/async.d.ts +10 -0
  66. package/dist/types/core/constants.d.ts +13 -1
  67. package/dist/types/core/core.d.ts +44 -2
  68. package/dist/types/core/dev.d.ts +43 -13
  69. package/dist/types/core/graph.d.ts +11 -0
  70. package/dist/types/core/identities.d.ts +17 -0
  71. package/dist/types/core/index.d.ts +2 -1
  72. package/dist/types/core/lanes.d.ts +2 -14
  73. package/dist/types/core/owner.d.ts +5 -3
  74. package/dist/types/core/scheduler.d.ts +47 -28
  75. package/dist/types/core/truth.d.ts +16 -0
  76. package/dist/types/core/types.d.ts +21 -0
  77. package/dist/types/core/verdict.d.ts +32 -0
  78. package/dist/types/deferred.d.ts +28 -0
  79. package/dist/types/index.d.ts +6 -0
  80. package/dist/types/map.d.ts +2 -2
  81. package/dist/types/signals.d.ts +28 -7
  82. package/dist/types/store/edges.d.ts +9 -0
  83. package/dist/types/store/index.d.ts +10 -3
  84. package/dist/types/store/optimistic.d.ts +3 -2
  85. package/dist/types/store/projection.d.ts +4 -3
  86. package/dist/types/store/store.d.ts +1 -1
  87. package/dist/types/store/target.d.ts +16 -8
  88. package/dist/types/store/types.d.ts +14 -0
  89. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { STATUS_PENDING, STATUS_ERROR, CONFIG_REDERIVE, REACTIVE_DISPOSED, STATUS_UNINITIALIZED, CONFIG_HELD, EFFECT_RENDER, REACTIVE_ZOMBIE, CONFIG_VERDICT, REACTIVE_LANE_READ, CONFIG_OVERRIDE, EFFECT_USER, EFFECT_TRACKED } from "./core/constants.js";
1
+ import { STATUS_PENDING, STATUS_ERROR, CONFIG_REDERIVE, STATUS_UNINITIALIZED, CONFIG_HELD, EFFECT_RENDER, CONFIG_VERDICT, REACTIVE_DISPOSED, REACTIVE_LANE_READ, 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
 
@@ -12,7 +12,7 @@ import { enqueueSub } from "./core/heap.js";
12
12
 
13
13
  import { createOwner, getOwner, cleanup, dispose } from "./core/owner.js";
14
14
 
15
- import { globalQueue, haltReactivity, passLane, joinFuture, GlobalQueue, flushTransaction, schedule, setPassLane, txOf } from "./core/scheduler.js";
15
+ import { globalQueue, haltReactivity, passLane, joinFuture, GlobalQueue, flushTransaction, heldUnder, setPassLane, txOf, unhold, laneStageHook, schedule, installBoundaryHooks } from "./core/scheduler.js";
16
16
 
17
17
  import { flatten } from "./flatten.js";
18
18
 
@@ -40,7 +40,7 @@ import { accessor } from "./signals.js";
40
40
  * the root holds the frame as for any reader. The tree's own status takes
41
41
  * the same route from the output's pass (`read(tree)` throws it).
42
42
  *
43
- * The hold (`blocked`, scheduler.ts) asks `hidden`: a reader behind a
43
+ * The hold (`blocked`, scheduler.ts) asks `hiddenBy`: a reader behind a
44
44
  * fallback — any boundary on its chain whose last pass chose the fallback —
45
45
  * is not on screen and holds nothing. An error boundary flipping to its
46
46
  * fallback is the same as a loading one resetting: every reader under it
@@ -73,34 +73,38 @@ function setRevealHooks(e) {
73
73
 
74
74
  /** Boundaries with readers to sweep (or an arm to resolve) at the seam. */ const collecting = new Set;
75
75
 
76
- const boundaryOf = e => e.D[BOUNDARY];
76
+ const boundaryOf = e => e.A[BOUNDARY];
77
77
 
78
78
  /** Catches what reaches it: an error boundary always; a loading one until it
79
- * has shown content, or while re-armed. */ const isCollecting = e => e.u === STATUS_ERROR || !e.h || e.U;
79
+ * has shown content, or while re-armed. */ const isCollecting = e => e.i === STATUS_ERROR || !e.D || e.h;
80
+
81
+ /** A reader `b` waits on: recorded for its `on`, and `b` visited at the seam. */ function record(e, n) {
82
+ e.U.add(n);
83
+ collecting.add(e);
84
+ }
80
85
 
81
86
  /** The reader goes to the fallback: recorded, and the output re-derives
82
87
  * (a no-op while the output's own pass is running — its post-check
83
88
  * decides). */ function caught(e, n, r) {
84
- if (e.u === STATUS_ERROR) {
89
+ if (e.i === STATUS_ERROR) {
85
90
  // An error boundary waits on what THREW (`StatusError.source`), not on
86
91
  // the reader that saw it: the reader recovers the moment a refetch
87
92
  // starts (its boundary catches the pending), while the error is settled
88
93
  // only when its source is neither errored nor in flight. `reset` re-runs
89
94
  // the same node.
90
- r ??= n.m?.F;
95
+ r ??= n.T?.F;
91
96
  n = r?.source ?? n;
92
97
  const t = unwrapStatusError(r);
93
98
  setSignal(e.F, t);
94
99
  reportClientError(t, e.L, n);
95
100
  }
96
- e.V.add(n);
97
- collecting.add(e);
98
- if (e.U) flip(e);
101
+ record(e, n);
102
+ if (e.h) flip(e);
99
103
  // Already showing the fallback: one more reader to wait on changes
100
104
  // nothing on screen. The fallback is instantiated once per show — a later
101
105
  // error reaches it through the `error` accessor, which is why it is one.
102
- if (!e.v) redraw(e);
103
- if (e.H !== null) revealHooks.P(e.H);
106
+ if (!e.H) redraw(e);
107
+ if (e.V !== null) revealHooks.P(e.V);
104
108
  }
105
109
 
106
110
  /** A re-armed boundary found something pending: fresh again, and the swap
@@ -108,19 +112,21 @@ const boundaryOf = e => e.D[BOUNDARY];
108
112
  * the lane's work from its next pass's head — not a re-pass of the
109
113
  * transaction holding its pending content, which would entangle that
110
114
  * transaction with the arming frame's (#3540 `on: () => latest(dep)`). */ function flip(e) {
111
- e.h = false;
112
- e.B = e.j;
113
- if (e.B !== null && e.Z !== null) GlobalQueue.W(e.Z, e.B, true, false);
115
+ e.D = false;
116
+ e.v = e.B;
117
+ const n = e.j;
118
+ if (!e.v && n.l & CONFIG_HELD && txOf(n) !== flushTransaction) unhold(n);
119
+ if (e.v !== null && e.j !== null) laneStageHook(e.j, e.v, true, false);
114
120
  }
115
121
 
116
122
  function redraw(e) {
117
- if (e.Z !== null && !(e.Z.R & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE))) {
118
- enqueueSub(e.Z);
123
+ if (e.j !== null && !(e.j.R & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE))) {
124
+ enqueueSub(e.j);
119
125
  schedule();
120
126
  }
121
127
  }
122
128
 
123
- /** GlobalQueue._catch: status from a frame reader, nearest boundary first.
129
+ /** `catchHook` (scheduler.ts): status from a frame reader, nearest boundary first.
124
130
  * A loading boundary on the way records a pending reader whether or not it
125
131
  * catches it (its `on` may collect it later). */ function catchStatus(e, n, r) {
126
132
  if (n === 0) {
@@ -131,34 +137,35 @@ function redraw(e) {
131
137
  // held reader's landing has joined its transaction, so the content
132
138
  // lands with its run, not a round after). Others still waiting: nothing
133
139
  // on screen changes, the fallback stays as it is.
134
- if (collecting.size !== 0) for (let n = boundaryOf(e); n !== undefined; n = n._parent ?? undefined) if (!(e.S & unsettled(n)) && n.V.delete(e) && n.V.size === 0) {
135
- if (n.v) redraw(n);
136
- if (n.H !== null) revealHooks.P(n.H);
140
+ if (collecting.size !== 0) for (let n = boundaryOf(e); n; n = n._parent) if (!(e.m & unsettled(n)) && n.U.delete(e) && n.U.size === 0) {
141
+ if (n.H) redraw(n);
142
+ if (n.V !== null) revealHooks.P(n.V);
137
143
  }
138
144
  return false;
139
145
  }
140
- for (let t = boundaryOf(e); t !== undefined; t = t._parent ?? undefined) {
141
- if (!(t.u & n)) continue;
146
+ for (let t = boundaryOf(e); t; t = t._parent) {
147
+ if (!(t.i & n)) continue;
142
148
  if (isCollecting(t)) {
143
149
  caught(t, e, r);
144
- return true;
150
+ return t.h ? CAUGHT_REARMED : true;
145
151
  }
146
- t.V.add(e);
147
- collecting.add(t);
152
+ record(t, e);
148
153
  }
149
154
  return false;
150
155
  }
151
156
 
152
- /** The nearest boundary on `r`'s chain showing its fallback, if any. */ function hiddenBy(e) {
153
- for (let n = boundaryOf(e); n !== undefined; n = n._parent ?? undefined) if (n.v) return n;
154
- return undefined;
157
+ /** The nearest loading boundary that would catch `node` was re-armed this
158
+ * flush. */ function armedOver(e) {
159
+ for (let n = boundaryOf(e); n; n = n._parent) if (n.i & STATUS_PENDING && isCollecting(n)) return n.h;
155
160
  }
156
161
 
157
- /** GlobalQueue._hidden: behind a fallback. */ function hidden(e) {
158
- return hiddenBy(e) !== undefined;
162
+ /** The nearest boundary on `r`'s chain showing its fallback, if any
163
+ * (`hiddenHook`: `r` is behind a fallback). */ function hiddenBy(e) {
164
+ for (let n = boundaryOf(e); n; n = n._parent) if (n.H) return n;
165
+ return undefined;
159
166
  }
160
167
 
161
- /** GlobalQueue._heldRun: a queued run behind a fallback waits for the reveal
168
+ /** `heldRunHook` (scheduler.ts): a queued run behind a fallback waits for the reveal
162
169
  * (maintainer, 2026-10-02: the queue is held, the synchronous first render
163
170
  * goes through). A user effect's, which would read a DOM that is not
164
171
  * attached ("many depend on reading the DOM, something that can't happen
@@ -171,19 +178,19 @@ function redraw(e) {
171
178
  * still showing its fallback holds it again then. */ function heldRun(e) {
172
179
  const n = hiddenBy(e);
173
180
  if (n === undefined) return false;
174
- (n.K ??= new Set).add(e);
181
+ (n.Z ??= new Set).add(e);
175
182
  return true;
176
183
  }
177
184
 
178
185
  /** The reveal: the runs held behind the fallback are this flush's, each in
179
186
  * its own phase — render updates with the frame that attaches the content,
180
187
  * user effects after it. */ function release(e) {
181
- if (e.K === null) return;
182
- for (const n of e.K) {
183
- const e = n.u;
184
- globalQueue.enqueue(e === EFFECT_TRACKED ? EFFECT_USER : e, e === EFFECT_TRACKED ? n.M : n.Y ??= GlobalQueue.q.bind(null, n));
188
+ if (e.Z === null) return;
189
+ for (const n of e.Z) {
190
+ const e = n.i;
191
+ globalQueue.enqueue(e === EFFECT_TRACKED ? EFFECT_USER : e, e === EFFECT_TRACKED ? n.M : n.W ??= GlobalQueue.K.bind(null, n));
185
192
  }
186
- e.K = null;
193
+ e.Z = null;
187
194
  }
188
195
 
189
196
  /** Drop the readers that settled or died. Settled: a loading reader no
@@ -191,13 +198,13 @@ function redraw(e) {
191
198
  * that landed but is held (its value staged in a transaction) is not: the
192
199
  * content reveals at the commit, with its run. The tree is: the output reads
193
200
  * it and enters the transaction itself (its committed value shows until the
194
- * landing). */ const unsettled = e => e.u === STATUS_ERROR ? STATUS_ERROR | STATUS_PENDING : STATUS_PENDING;
201
+ * landing). */ const unsettled = e => e.i === STATUS_ERROR ? STATUS_ERROR | STATUS_PENDING : STATUS_PENDING;
195
202
 
196
203
  function prune(e, n) {
197
204
  const r = unsettled(e);
198
- for (const t of e.V) {
199
- if (t.R & REACTIVE_DISPOSED) e.V.delete(t); else if (!(t.S & r)) {
200
- if (t !== e.J && (t.i & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD) {
205
+ for (const t of e.U) {
206
+ if (t.R & REACTIVE_DISPOSED) e.U.delete(t); else if (!(t.m & r)) {
207
+ if ((t !== e.Y || e.h) && (t.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD) {
201
208
  // Landed, held: the content is that transaction's — the output's
202
209
  // pass enters it and the reveal lands with the reader's run. The
203
210
  // seam, past its park decision, waits for the commit instead. (A
@@ -205,26 +212,26 @@ function prune(e, n) {
205
212
  // has not shown content catches it instead: the fallback stays until
206
213
  // the reader is committed (#3540: what a fresh boundary catches holds
207
214
  // nothing outside it).
208
- if (!n || !e.h) continue;
215
+ if (!n || !e.D) continue;
209
216
  joinFuture(txOf(t));
210
217
  }
211
- e.V.delete(t);
218
+ e.U.delete(t);
212
219
  }
213
220
  }
214
- return e.V.size;
221
+ return e.U.size;
215
222
  }
216
223
 
217
224
  /** Reveal order: a slot is ready when its content can show — it has shown
218
225
  * content, or nothing under it is unready (the tree neither pending nor
219
226
  * born held, no reader waited on). */ function ready(e) {
220
- return e.h || !(e.J.S & STATUS_PENDING) && !(e.J.i & CONFIG_HELD && (e.Z === null || e.Z.S & STATUS_UNINITIALIZED)) && prune(e, false) === 0;
227
+ 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;
221
228
  }
222
229
 
223
- /** GlobalQueue._boundarySeam, end of the seam: readers that settled, died,
230
+ /** `boundarySeamHook` (scheduler.ts), end of the seam: readers that settled, died,
224
231
  * or landed and committed are dropped; a fallback with none left reveals
225
232
  * next round. An arm resolves: nothing collected, nothing happened. */ function boundarySeam() {
226
233
  for (const e of collecting) {
227
- const n = e.Z.R;
234
+ const n = e.j.R;
228
235
  if (n & REACTIVE_DISPOSED) {
229
236
  collecting.delete(e);
230
237
  continue;
@@ -232,34 +239,31 @@ function prune(e, n) {
232
239
  // A parked frame's boundary (zombie) keeps its state for its revival.
233
240
  if (n & REACTIVE_ZOMBIE) continue;
234
241
  prune(e, false);
235
- e.U = false;
236
- if (e.V.size === 0) {
242
+ const r = e.j;
243
+ if (e.h && !e.D && r.l & CONFIG_HELD && [ ...e.U ].every(e => !(e.m & STATUS_PENDING) && e.l & CONFIG_HELD && txOf(e) === txOf(r))) {
244
+ e.U.clear();
245
+ e.D = true;
246
+ }
247
+ e.h = false;
248
+ if (e.U.size === 0) {
237
249
  collecting.delete(e);
238
- if (e.v) redraw(e);
239
- if (e.H !== null) revealHooks.P(e.H);
250
+ if (e.H) redraw(e);
251
+ if (e.V !== null) revealHooks.P(e.V);
240
252
  }
241
253
  }
242
254
  }
243
255
 
244
- /** The `on` pass is a verdict's: it probed itself (CONFIG_VERDICT), or it
245
- * read a memo that did (#3528's `createMemo(() => isPending(m2))`) — its
246
- * swap is display-ahead either way. */ function verdictDerived(e) {
247
- if (e.i & CONFIG_VERDICT) return true;
248
- for (let n = e.p; n !== null; n = n._) if (n.I.i & CONFIG_VERDICT) return true;
249
- return false;
250
- }
251
-
252
256
  /** `on` changed after the mount: fresh again if anything under it is
253
257
  * pending now; collecting for the rest of the flush either way. */ function arm(e) {
254
- if (!e.h) {
258
+ if (!e.D) {
255
259
  // Already re-armed and on its fallback, as the frame's work — and the
256
260
  // `on` pass arms again as lane work: its verdict was provisional (a
257
261
  // memo of `isPending(m2)` is a watcher until the flush parks, then the
258
262
  // holder's verdict lane's — verdict.ts), and the swap it asked for is
259
263
  // display-ahead after all (#3528). Re-home the swap: the output re-runs
260
264
  // as the lane's, shown now beside the held frame.
261
- if (e.v && e.B === null && e.j === null && passLane !== null) {
262
- e.j = passLane;
265
+ if (e.H && e.v === null && e.B === null && passLane !== null) {
266
+ e.B = passLane;
263
267
  // The swap the frame's pass staged (held with the frame) is void: the
264
268
  // lane's pass stages it anew (`flip` lists the output in the lane,
265
269
  // which voids its staging), as a watcher's provisional value is
@@ -269,20 +273,28 @@ function prune(e, n) {
269
273
  }
270
274
  return;
271
275
  }
272
- e.U = true;
273
- // A verdict read in `on` (`isPending`) whose frame has no transaction
274
- // yet: the swap is still display-ahead — the frame gets one now (it lands
276
+ e.h = true;
277
+ // A verdict read in `on` (`isPending`, or a memo of one — #3528's
278
+ // `createMemo(() => isPending(m2))`: the mark carries, core.ts `read`)
279
+ // whose frame has no transaction yet: the swap is still display-ahead — the frame gets one now (it lands
275
280
  // at this very seam if nothing holds it), and the swap is its verdict
276
281
  // lane's work, shown ahead of the frame's own runs (#3528).
277
282
  let n = passLane;
278
- if (n === null && globalQueue.X && verdictDerived(getOwner())) {
283
+ if (n === null && globalQueue.q && getOwner().l & CONFIG_VERDICT) {
279
284
  joinFuture(null);
280
- n = GlobalQueue.$(flushTransaction);
285
+ n = GlobalQueue.J(flushTransaction);
281
286
  }
282
- e.j = n;
287
+ e.B = n;
283
288
  collecting.add(e);
284
- for (const n of e.V) {
285
- if (n.S & STATUS_PENDING && !(n.R & REACTIVE_DISPOSED)) {
289
+ const r = e.U.size;
290
+ heldUnder(e.L, flushTransaction, n => record(e, n));
291
+ for (const n of e.U) {
292
+ if (e.U.size !== r || n.m & STATUS_PENDING && !(n.R & REACTIVE_DISPOSED)) {
293
+ // What it collects was forwarded through it to the boundaries above
294
+ // too (`catchStatus` records a reader in every boundary on the way).
295
+ // It is this boundary's alone now (B5, the nearest catcher): an outer
296
+ // re-armed by the same tick does not wait for it (D-14, U-4).
297
+ for (let n = e._parent; n !== null; n = n._parent) for (const r of e.U) n.U.delete(r);
286
298
  flip(e);
287
299
  redraw(e);
288
300
  return;
@@ -293,36 +305,36 @@ function prune(e, n) {
293
305
  /** The error boundary's `reset`: re-run what threw (a comparator throw
294
306
  * names a signal — nothing to re-run). */ function reset(e) {
295
307
  // A snapshot: a source failing again is caught — and re-added — mid-walk.
296
- for (const n of [ ...e.V ]) if (n.ee !== undefined && !(n.R & REACTIVE_DISPOSED)) recompute(n);
308
+ for (const n of [ ...e.U ]) if (n.X !== undefined && !(n.R & REACTIVE_DISPOSED)) recompute(n);
297
309
  schedule();
298
310
  }
299
311
 
300
312
  function createBoundary(e, n, r, t) {
301
- const l = createOwner();
302
- const o = {
303
- u: e,
304
- _parent: boundaryOf(l) ?? null,
305
- L: l,
306
- J: null,
307
- Z: null,
308
- V: new Set,
309
- h: false,
310
- U: false,
313
+ const o = createOwner();
314
+ const l = {
315
+ i: e,
316
+ _parent: boundaryOf(o) ?? null,
317
+ L: o,
318
+ Y: null,
311
319
  j: null,
320
+ U: new Set,
321
+ D: false,
322
+ h: false,
312
323
  B: null,
313
- v: false,
314
- K: null,
315
- H: null,
316
- ne: false,
317
- re: false,
324
+ v: null,
325
+ H: false,
326
+ Z: null,
327
+ V: null,
328
+ $: false,
329
+ ee: false,
318
330
  F: e === STATUS_ERROR ? signal(undefined, ERROR_SIGNAL) : null,
319
- te: r,
320
- le: null
331
+ ne: r,
332
+ re: null
321
333
  };
322
- const u = e === STATUS_PENDING ? l.D[REVEAL] : null;
334
+ const u = e === STATUS_PENDING ? o.A[REVEAL] : null;
323
335
  if (getOwner()) cleanup(() => {
324
- collecting.delete(o);
325
- if (u) revealHooks.oe(u, o);
336
+ collecting.delete(l);
337
+ if (u) revealHooks.te(u, l);
326
338
  });
327
339
  // The `on` dependencies live OUTSIDE the boundary, as the condition of a
328
340
  // `<Show>` wrapping it would: created before the owner's context names it.
@@ -331,7 +343,7 @@ function createBoundary(e, n, r, t) {
331
343
  // does not suspend the parent — and re-arms.
332
344
  if (t) {
333
345
  let e = false;
334
- runWithOwner(l, () => computed(() => {
346
+ runWithOwner(o, () => computed(() => {
335
347
  try {
336
348
  t();
337
349
  } catch (e) {
@@ -343,16 +355,16 @@ function createBoundary(e, n, r, t) {
343
355
  return;
344
356
  }
345
357
  }
346
- if (e) arm(o); else e = true;
347
- })).i |= CONFIG_REDERIVE;
358
+ if (e) arm(l); else e = true;
359
+ })).l |= CONFIG_REDERIVE;
348
360
  }
349
361
  const a = {
350
- ...l.D,
351
- [BOUNDARY]: o
362
+ ...o.A,
363
+ [BOUNDARY]: l
352
364
  };
353
365
  if (revealHooks !== null) a[REVEAL] = null;
354
- l.D = a;
355
- const i = runWithOwner(l, () => {
366
+ o.A = a;
367
+ const i = runWithOwner(o, () => {
356
368
  const e = false ? computed(n, {
357
369
  name: "children"
358
370
  }) : computed(n);
@@ -360,29 +372,29 @@ function createBoundary(e, n, r, t) {
360
372
  name: "boundary"
361
373
  }) : computed(() => flatten(read(e)));
362
374
  });
363
- o.J = i;
375
+ l.Y = i;
364
376
  // A slot of the reveal order in its context (reveal.ts): gated until the
365
377
  // controller releases it — before the output's first pass.
366
- if (u) revealHooks.ue(u, o);
378
+ if (u) revealHooks.oe(u, l);
367
379
  const f = computed(() => {
368
380
  // Reveal order (reveal.ts): a gated slot shows its fallback — or, in a
369
381
  // collapsed tail, nothing — whatever its content's state; the
370
382
  // controller is told the pass ran (its readiness may have changed) and
371
383
  // releases it in turn.
372
- if (o.ne) {
384
+ if (l.$) {
373
385
  // Linked without being read: the tree settling (or changing)
374
386
  // re-derives this pass, which is how the controller hears of it.
375
387
  // It may release this very slot (the frontier whose content just
376
388
  // settled): the pass goes on to show it — the redraw it asks for is
377
389
  // refused mid-pass and not needed.
378
390
  link(i, getOwner());
379
- if (o.H !== null) revealHooks.P(o.H);
380
- if (o.ne) {
381
- if (o.re) {
382
- o.v = true;
391
+ if (l.V !== null) revealHooks.P(l.V);
392
+ if (l.$) {
393
+ if (l.ee) {
394
+ l.H = true;
383
395
  return undefined;
384
396
  }
385
- return fallback(o);
397
+ return fallback(l);
386
398
  }
387
399
  }
388
400
  // A tree carrying a status is not read: an errored memo's reactive
@@ -392,24 +404,23 @@ function createBoundary(e, n, r, t) {
392
404
  // display-ahead `on` causes is the lane's, and must still be the
393
405
  // fallback. Linked, so its recovery re-derives this pass; read again
394
406
  // once clean.
395
- const n = i.S & (STATUS_PENDING | STATUS_ERROR);
407
+ const n = i.m & (STATUS_PENDING | STATUS_ERROR);
396
408
  if (n !== 0) {
397
409
  link(i, getOwner());
398
410
  if (n & e) {
399
- if (isCollecting(o)) {
400
- caught(o, i, undefined);
401
- return fallback(o);
411
+ if (isCollecting(l)) {
412
+ caught(l, i, undefined);
413
+ return fallback(l);
402
414
  }
403
415
  // Forwarded: a loading boundary showing content keeps it and
404
416
  // holds the frame like any reader (recorded for its `on`).
405
- o.V.add(i);
406
- collecting.add(o);
417
+ record(l, i);
407
418
  }
408
419
  // A pending passes an error boundary by (A6); an error, a loading
409
420
  // one; a loading boundary showing content forwards its pending.
410
- throw i.m.F;
421
+ throw i.T.F;
411
422
  }
412
- if (isCollecting(o)) {
423
+ if (isCollecting(l)) {
413
424
  // A29's boundary exemption (#3540): a boundary MOUNTED over a held
414
425
  // value (its first pass; a first pass under it that read a hold was
415
426
  // collected, `joinPass` — the tree's own, or a render effect's that
@@ -422,52 +433,51 @@ function createBoundary(e, n, r, t) {
422
433
  // which reveals the content — a fallback staged earlier is replaced
423
434
  // ahead of the commit and never shown.
424
435
  const e = getOwner();
425
- if (o.V.size !== 0 && e.S & STATUS_UNINITIALIZED && !(e.i & CONFIG_HELD)) return fallback(o);
436
+ if (l.U.size !== 0 && e.m & STATUS_UNINITIALIZED && !(e.l & CONFIG_HELD)) return fallback(l);
426
437
  // Readers under it still unready: the fallback, the tree untouched.
427
438
  // The seam re-derives this pass when they settle.
428
- if (prune(o, true) !== 0) return fallback(o);
439
+ if (prune(l, true) !== 0) return fallback(l);
429
440
  }
430
441
  let r;
431
442
  try {
432
443
  r = read(i);
433
444
  } catch (n) {
434
445
  if (n instanceof NotReadyError ? e === STATUS_PENDING : e === STATUS_ERROR) {
435
- if (isCollecting(o)) {
436
- caught(o, i, n);
437
- return fallback(o);
446
+ if (isCollecting(l)) {
447
+ caught(l, i, n);
448
+ return fallback(l);
438
449
  }
439
450
  // Forwarded: a loading boundary showing content keeps it and
440
451
  // holds the frame like any reader (recorded for its `on`).
441
- o.V.add(i);
442
- collecting.add(o);
452
+ record(l, i);
443
453
  }
444
454
  // A pending passes an error boundary by (A6).
445
455
  throw n;
446
456
  }
447
457
  // Readers under it still unready (caught before, or while the read
448
458
  // ran the content at a mount): the fallback.
449
- if (isCollecting(o) && o.V.size !== 0) return fallback(o);
450
- o.h = true;
451
- o.v = false;
459
+ if (isCollecting(l) && l.U.size !== 0) return fallback(l);
460
+ l.D = true;
461
+ l.H = false;
452
462
  // The fallback dies when the content that replaces it is on screen —
453
463
  // with this flush's commits when the pass is the frame's, at the
454
464
  // landing when the frame parks (the run is held with it, as the old
455
465
  // children of a held pass are) — not now: a held swap keeps the
456
466
  // fallback on screen, live, until it commits. A pass back to the
457
467
  // fallback before then finds it still built and keeps it.
458
- const t = o.le;
468
+ const t = l.re;
459
469
  if (t !== null) globalQueue.enqueue(EFFECT_RENDER, () => {
460
- if (!o.v && o.le === t) {
470
+ if (!l.H && l.re === t) {
461
471
  dispose(t);
462
- o.le = null;
472
+ l.re = null;
463
473
  }
464
474
  });
465
- release(o);
475
+ release(l);
466
476
  // Shown: the slot leaves its reveal order (a later re-arm gates nobody
467
477
  // else; the frontier moves on).
468
- if (o.H !== null) {
469
- const e = o.H;
470
- o.H = null;
478
+ if (l.V !== null) {
479
+ const e = l.V;
480
+ l.V = null;
471
481
  revealHooks.P(e);
472
482
  }
473
483
  return r;
@@ -476,10 +486,10 @@ function createBoundary(e, n, r, t) {
476
486
  // and legitimately swaps mid-hydration (resume), so it must never be
477
487
  // frozen by snapshot capture.
478
488
  {
479
- ae: true
489
+ le: true
480
490
  });
481
- f.i |= CONFIG_REDERIVE;
482
- o.Z = f;
491
+ f.l |= CONFIG_REDERIVE;
492
+ l.j = f;
483
493
  return accessor(f);
484
494
  }
485
495
 
@@ -487,12 +497,12 @@ function fallback(e) {
487
497
  // The swap a display-ahead re-arm asked for: this pass is the lane's — a
488
498
  // lane read by construction (REACTIVE_LANE_READ: `recompute`'s tail keeps
489
499
  // the pass in the lane).
490
- if (e.B !== null) {
491
- setPassLane(e.B);
492
- e.Z.R |= REACTIVE_LANE_READ;
493
- e.B = null;
500
+ if (e.v !== null) {
501
+ setPassLane(e.v);
502
+ e.j.R |= REACTIVE_LANE_READ;
503
+ e.v = null;
494
504
  }
495
- e.v = true;
505
+ e.H = true;
496
506
  // Built in its own scope, like `Show`'s function child, once per show
497
507
  // (D-39: the fallback is the display until a new answer replaces the
498
508
  // error): a re-derive of the output while it shows — a second reader
@@ -504,18 +514,18 @@ function fallback(e) {
504
514
  // outside the boundary, as the output is: its errors and runs are the
505
515
  // enclosing boundary's — with the output's id, so what it builds gets the
506
516
  // ids a build under the output would; disposed once content is on screen.
507
- if (e.le === null) {
517
+ if (e.re === null) {
508
518
  const n = getOwner();
509
- e.le = runWithOwner(n._parent, () => computed(() => e.te(e), {
519
+ e.re = runWithOwner(n._parent, () => computed(() => e.ne(e), {
510
520
  id: n.id
511
521
  }));
512
522
  }
513
- return read(e.le);
523
+ return read(e.re);
514
524
  }
515
525
 
516
526
  const ERROR_SIGNAL = {
517
527
  ownedWrite: true,
518
- ae: true
528
+ le: true
519
529
  };
520
530
 
521
531
  /**
@@ -591,14 +601,6 @@ const ERROR_SIGNAL = {
591
601
 
592
602
  // Installed at module evaluation — present exactly when something imports a
593
603
  // boundary. An app without one pays the three null checks and nothing else.
594
- GlobalQueue.ie = catchStatus;
595
-
596
- GlobalQueue.fe = e => e.S & STATUS_UNINITIALIZED && catchStatus(e, STATUS_PENDING);
597
-
598
- GlobalQueue.ce = hidden;
599
-
600
- GlobalQueue.se = boundarySeam;
601
-
602
- GlobalQueue.Ee = heldRun;
604
+ installBoundaryHooks(catchStatus, (e, n) => !n && (e.m & STATUS_UNINITIALIZED ? catchStatus(e, STATUS_PENDING) : armedOver(e)), hiddenBy, boundarySeam, heldRun);
603
605
 
604
606
  export { REVEAL, createErrorBoundary, createLoadingBoundary, prune, ready, redraw, revealHooks, setRevealHooks };