@solidjs/signals 2.0.0-beta.25 → 2.0.0-beta.27

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.
@@ -1,6 +1,6 @@
1
- import { handleAsync, clearStatus, notifyStatus } from "./async.js";
1
+ import { handleAsync, clearStatus, notifyStatus, settleErroredDependents } from "./async.js";
2
2
 
3
- import { EFFECT_TRACKED, REACTIVE_OPTIMISTIC_DIRTY, NOT_PENDING, STATUS_UNINITIALIZED, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, CONFIG_SYNC, STATUS_PENDING, STATUS_ERROR, REACTIVE_NONE, REACTIVE_SNAPSHOT_STALE, unwrapOverride, OVERRIDE_UNDEFINED, REACTIVE_LAZY, REACTIVE_DISPOSED, CONFIG_AUTO_DISPOSE, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, defaultContext, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_TRANSPARENT, CONFIG_OWNED_WRITE, CONFIG_NO_SNAPSHOT, $REFRESH, REACTIVE_MANUAL_WRITE, NO_SNAPSHOT, STORE_SNAPSHOT_PROPS, EFFECT_USER } from "./constants.js";
3
+ import { EFFECT_TRACKED, REACTIVE_OPTIMISTIC_DIRTY, NOT_PENDING, STATUS_UNINITIALIZED, STATUS_ERROR, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, CONFIG_SYNC, STATUS_PENDING, REACTIVE_NONE, REACTIVE_SNAPSHOT_STALE, unwrapOverride, OVERRIDE_UNDEFINED, REACTIVE_LAZY, REACTIVE_DISPOSED, CONFIG_AUTO_DISPOSE, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, defaultContext, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_TRANSPARENT, CONFIG_OWNED_WRITE, CONFIG_NO_SNAPSHOT, $REFRESH, REACTIVE_MANUAL_WRITE, NO_SNAPSHOT, STORE_SNAPSHOT_PROPS, EFFECT_USER } from "./constants.js";
4
4
 
5
5
  import { NotReadyError } from "./error.js";
6
6
 
@@ -14,9 +14,9 @@ import "./invariants.js";
14
14
 
15
15
  import { disposeChildren, markDisposal, inheritId } from "./owner.js";
16
16
 
17
- GlobalQueue.pe = recompute;
17
+ GlobalQueue.Ce = recompute;
18
18
 
19
- GlobalQueue.Ce = disposeChildren;
19
+ GlobalQueue.me = disposeChildren;
20
20
 
21
21
  let tracking = false;
22
22
 
@@ -48,8 +48,8 @@ let snapshotSources = null;
48
48
 
49
49
  function ownerInSnapshotScope(e) {
50
50
  while (e) {
51
- if (e.Oe) return true;
52
- e = e.Ge;
51
+ if (e.ge) return true;
52
+ e = e.ve;
53
53
  }
54
54
  return false;
55
55
  }
@@ -60,41 +60,41 @@ function setSnapshotCapture(e) {
60
60
  }
61
61
 
62
62
  function markSnapshotScope(e) {
63
- e.Oe = true;
63
+ e.ge = true;
64
64
  }
65
65
 
66
66
  function releaseSnapshotScope(e) {
67
- e.Oe = false;
67
+ e.ge = false;
68
68
  releaseSubtree(e);
69
69
  schedule();
70
70
  }
71
71
 
72
72
  function releaseSubtree(e) {
73
- let t = e.me;
73
+ let t = e.ke;
74
74
  while (t) {
75
- if (t.Oe) {
76
- t = t.ve;
75
+ if (t.ge) {
76
+ t = t.Fe;
77
77
  continue;
78
78
  }
79
- if (t.ke) {
79
+ if (t.ae) {
80
80
  const e = t;
81
81
  e.T &= ~CONFIG_IN_SNAPSHOT_SCOPE;
82
82
  if (e.se & REACTIVE_SNAPSHOT_STALE) {
83
83
  e.se &= ~REACTIVE_SNAPSHOT_STALE;
84
84
  e.se |= REACTIVE_DIRTY;
85
- if (dirtyQueue.Fe > e.He) dirtyQueue.Fe = e.He;
85
+ if (dirtyQueue.He > e.Ve) dirtyQueue.He = e.Ve;
86
86
  insertIntoHeap(e, dirtyQueue);
87
87
  }
88
88
  }
89
89
  releaseSubtree(t);
90
- t = t.ve;
90
+ t = t.Fe;
91
91
  }
92
92
  }
93
93
 
94
94
  function clearSnapshots() {
95
95
  if (snapshotSources) {
96
96
  for (const e of snapshotSources) {
97
- delete e.Ve;
97
+ delete e.xe;
98
98
  // StoreNode targets share one pre-initialized hidden class (see
99
99
  // createStoreProxy) — assign undefined instead of deleting, and only
100
100
  // when present so signal-node sources don't grow the field.
@@ -106,37 +106,41 @@ function clearSnapshots() {
106
106
  }
107
107
 
108
108
  function recompute(e, t = false) {
109
- const n = e.Ae;
109
+ const n = e.Pe;
110
110
  if (!t) {
111
- if (e.Ue && (!n || activeTransition) && activeTransition !== e.Ue) globalQueue.initTransition(e.Ue);
111
+ if (e.Ie && (!n || activeTransition) && activeTransition !== e.Ie) globalQueue.initTransition(e.Ie);
112
112
  deleteFromHeap(e, queueFor(e));
113
113
  e.Te = null;
114
114
  // Tracked effects run after finalizePureQueue, so dispose immediately instead of deferring
115
- if (e.Ue || n === EFFECT_TRACKED) disposeChildren(e); else if (e.me !== null || e.xe !== null) {
115
+ if (e.Ie || n === EFFECT_TRACKED) disposeChildren(e); else if (e.ke !== null || e.Le !== null) {
116
116
  markDisposal(e);
117
- e.Le = e.xe;
118
- e.ye = e.me;
119
- e.xe = null;
120
- e.me = null;
121
- e.Qe = 0;
117
+ e.ye = e.Le;
118
+ e.Qe = e.ke;
119
+ e.Le = null;
120
+ e.ke = null;
121
+ e.qe = 0;
122
122
  } else ;
123
123
  }
124
124
  let i = !!(e.se & REACTIVE_OPTIMISTIC_DIRTY);
125
- const u = e.Ee !== undefined && e.Ee !== NOT_PENDING;
125
+ const u = e.Ae !== undefined && e.Ae !== NOT_PENDING;
126
126
  const l = !!(e.S & STATUS_UNINITIALIZED);
127
+ // Outgoing error, captured before the compute clears status: if this run
128
+ // recovers to an unchanged value, dependents still holding this object must
129
+ // be swept (settleErroredDependents, #2949).
130
+ const o = e.S & STATUS_ERROR ? e._ : undefined;
127
131
  // Re-ask classification lives in the verdict module; capture the flag before
128
132
  // the recompute wipes _flags below.
129
- const o = (e.se & REACTIVE_REASK) !== 0;
130
- const s = context;
133
+ const s = (e.se & REACTIVE_REASK) !== 0;
134
+ const a = context;
131
135
  context = e;
132
- e.qe = null;
133
- e.We++;
136
+ e.We = null;
137
+ e.Ye++;
134
138
  e.se = REACTIVE_RECOMPUTING_DEPS;
135
- e.ce = clock;
136
- let a = e.Ne === NOT_PENDING ? e.Pe : e.Ne;
137
- let r = e.He;
138
- let c = tracking;
139
- let _ = currentOptimisticLane;
139
+ e.Se = clock;
140
+ let r = e.De === NOT_PENDING ? e.Ue : e.De;
141
+ let c = e.Ve;
142
+ let _ = tracking;
143
+ let f = currentOptimisticLane;
140
144
  tracking = true;
141
145
  // A computed's fn establishes its OWN dependencies, so it must never run
142
146
  // inside a latest() read window: read() short-circuits through the
@@ -144,30 +148,30 @@ function recompute(e, t = false) {
144
148
  // computed) inside latest(fn) came out permanently dependency-less (#2926).
145
149
  // latestRead() already suspends the flag for its pull-recomputes; this
146
150
  // covers creation-time computes and flushes that run inside the window.
147
- const f = latestReadActive;
151
+ const E = latestReadActive;
148
152
  latestReadActive = false;
149
153
  // Lane posture lives with the engine: OPTIMISTIC_DIRTY is only ever set by
150
154
  // engine-driven paths, and _optimisticNodes is only pushed by
151
155
  // _optimisticWrite, so the hook is installed whenever either gate holds.
152
156
  if (i) {
153
- const t = GlobalQueue.Ye(e, true);
157
+ const t = GlobalQueue.Ze(e, true);
154
158
  if (t) currentOptimisticLane = t;
155
- } else if (activeTransition && !t && activeTransition.Ze.length) {
159
+ } else if (activeTransition && !t && activeTransition.je.length) {
156
160
  // Lane adoption: parent-deeper-than-owned-child can run before its OPT-dirty
157
161
  // child propagates. Walk deps once and inherit the OPT lane so this node
158
162
  // recomputes under the right posture and propagates correctly.
159
- const t = GlobalQueue.Ye(e, false);
163
+ const t = GlobalQueue.Ze(e, false);
160
164
  if (t) {
161
165
  i = true;
162
166
  currentOptimisticLane = t;
163
167
  }
164
168
  }
165
- const E = n && n !== EFFECT_USER;
166
- const N = stale;
167
- if (E) stale = true;
169
+ const N = n && n !== EFFECT_USER;
170
+ const T = stale;
171
+ if (N) stale = true;
168
172
  try {
169
173
  if (!false && e.T & CONFIG_SYNC) {
170
- a = e.ke(a);
174
+ r = e.ae(r);
171
175
  e.Te = null;
172
176
  } else {
173
177
  // Snapshot `_inFlight` so we can detect whether `_fn` self-registered an async
@@ -176,42 +180,42 @@ function recompute(e, t = false) {
176
180
  // clobber the fresh subscription, so we skip it and let the internally-registered
177
181
  // iteration drive updates.
178
182
  const t = e.Te;
179
- const n = e.ke(a);
183
+ const n = e.ae(r);
180
184
  const i = typeof n === "object" && n !== null;
181
185
  const u = e.Te !== t;
182
- a = u || !i ? n : handleAsync(e, n);
186
+ r = u || !i ? n : handleAsync(e, n);
183
187
  if (!u && !i) e.Te = null;
184
188
  }
185
189
  // On a status-free node clearStatus is a guaranteed no-op: every branch
186
190
  // in its body is gated on one of these fields, and with _statusFlags === 0
187
191
  // the flags write (create or not) stores the 0 already there.
188
- if (e.S !== 0 || e.i !== undefined || e._ || e._e || e.Se || e.oe !== undefined || e.be !== undefined || e.ge !== undefined || e.u !== null) clearStatus(e, t);
192
+ if (e.S !== 0 || e.i !== undefined || e._ || e.Re || e.de || e.oe !== undefined || e.he !== undefined || e.pe !== undefined || e.u !== null) clearStatus(e, t);
189
193
  // _optimisticLane is only ever assigned by engine paths.
190
- if (e.je) GlobalQueue.Me(e);
194
+ if (e.Me) GlobalQueue.Ke(e);
191
195
  } catch (t) {
192
196
  // Track pending async in the lane (not the lane's source — it creates the lane
193
197
  // but doesn't belong to it). Set lane BEFORE notifyStatus for downstream propagation.
194
- if (t instanceof NotReadyError && currentOptimisticLane) GlobalQueue.Ke(e);
198
+ if (t instanceof NotReadyError && currentOptimisticLane) GlobalQueue.ze(e);
195
199
  let n = false;
196
200
  if (t instanceof NotReadyError) {
197
- e.Se = true;
198
- if (GlobalQueue.ze !== null) n = GlobalQueue.ze(e, o);
201
+ e.de = true;
202
+ if (GlobalQueue.$e !== null) n = GlobalQueue.$e(e, s);
199
203
  }
200
- notifyStatus(e, t instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, t, undefined, t instanceof NotReadyError ? e.je : undefined);
204
+ notifyStatus(e, t instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, t, undefined, t instanceof NotReadyError ? e.Me : undefined);
201
205
  if (n) GlobalQueue.k(e);
202
206
  } finally {
203
- tracking = c;
204
- latestReadActive = f;
205
- if (E) stale = N;
207
+ tracking = _;
208
+ latestReadActive = E;
209
+ if (N) stale = T;
206
210
  e.se = REACTIVE_NONE | (t ? e.se & REACTIVE_SNAPSHOT_STALE : 0);
207
- context = s;
211
+ context = a;
208
212
  }
209
213
  if (!e._) {
210
214
  trimStaleDeps(e);
211
- const o = u ? unwrapOverride(e.Ee) : e.Ne === NOT_PENDING ? e.Pe : e.Ne;
212
- let s = false;
215
+ const s = u ? unwrapOverride(e.Ae) : e.De === NOT_PENDING ? e.Ue : e.De;
216
+ let a = false;
213
217
  try {
214
- s = !n && l || !e.Re || !e.Re(o, a);
218
+ a = !n && l || !e.be || !e.be(s, r);
215
219
  } catch (t) {
216
220
  // A throwing user comparator is an error of this node's computation.
217
221
  // Route it through the same status path as a compute-phase throw so
@@ -224,70 +228,76 @@ function recompute(e, t = false) {
224
228
  // its runner — happen here instead. `!create` matches the previous `initialized`
225
229
  // gate: the explicit recompute(node, true) inside effect() does not enqueue, so
226
230
  // effect() can call its runner synchronously for the first run.
227
- if (n && s) {
228
- e.$e = !e._;
231
+ if (n && a) {
232
+ e.Be = !e._;
229
233
  // Reuse one bound runner per effect — runEffect no-ops on a stale
230
234
  // `_modified`, so re-enqueueing the same function is harmless.
231
- if (!t) e.C.enqueue(n, e.Be ??= GlobalQueue.Je.bind(null, e));
235
+ if (!t) e.C.enqueue(n, e.Je ??= GlobalQueue.Xe.bind(null, e));
232
236
  }
233
- if (e._) ; else if (s) {
234
- const l = u ? e.Ee : undefined;
237
+ if (e._) ; else if (a) {
238
+ const l = u ? e.Ae : undefined;
235
239
  if (t ||
236
240
  // Plain sync flush (no transition on either side) commits effect
237
241
  // values directly — the pending round-trip (queuePendingNode +
238
242
  // commitPendingNodes) exists to sequence transition reveals, and
239
243
  // paying it per effect on the plain path is pure overhead.
240
- n && (activeTransition !== e.Ue || activeTransition === null) || i) {
241
- e.Pe = a;
244
+ n && (activeTransition !== e.Ie || activeTransition === null) || i) {
245
+ e.Ue = r;
242
246
  // Lane-propagated correction: upstream data is fresh, correct the
243
247
  // override unconditionally. The direct _value commit is the lane's
244
248
  // own reveal schedule; drop any superseded older hold so its queued
245
249
  // commit can't clobber the fresh value.
246
250
  if (u && i) {
247
- e.Ee = a === undefined ? OVERRIDE_UNDEFINED : a;
248
- e.Ne = NOT_PENDING;
251
+ e.Ae = r === undefined ? OVERRIDE_UNDEFINED : r;
252
+ e.De = NOT_PENDING;
249
253
  }
250
254
  } else {
251
- e.Ne = a;
255
+ e.De = r;
252
256
  // Transition-held sync recompute is a write path like setSignal/asyncWrite,
253
257
  // so sync derivations of held sources stay visible to isPending()/latest()
254
258
  // (#2831). Both companion writes are transition-scoped (optimistic) and
255
259
  // auto-revert/re-derive at commit. Skipped for plain flushes where the
256
260
  // pending value commits before effects run.
257
- if ((activeTransition || e.Ue) && GlobalQueue.Ie !== null) GlobalQueue.Ie(e, a);
261
+ if ((activeTransition || e.Ie) && GlobalQueue._e !== null) GlobalQueue._e(e, r);
258
262
  }
259
263
  // insertSubs only walks _subs (no scheduling of its own), so a
260
264
  // subscriber-less node has nothing to notify.
261
- if (e.o !== null && (!u || i || e.Ee !== l)) insertSubs(e, i || u);
265
+ if (e.o !== null && (!u || i || e.Ae !== l)) insertSubs(e, i || u);
262
266
  } else if (u) {
263
267
  // Unchanged value (equals the override) recomputed while the override
264
268
  // is active: _value may still be stale, so hold the authoritative value
265
269
  // for commit on its own transition's schedule — invisibly (A17/A18).
266
- if (e.Ne === NOT_PENDING) queuePendingNode(e);
267
- e.Ne = a;
268
- } else if (e.He != r) {
270
+ if (e.De === NOT_PENDING) queuePendingNode(e);
271
+ e.De = r;
272
+ } else if (e.Ve != c) {
269
273
  for (let t = e.o; t !== null; t = t.ue) {
270
274
  insertIntoHeapHeight(t.le, queueFor(t.le));
271
275
  }
272
276
  }
277
+ // Silent recovery: errored → unchanged value fires no notification, but
278
+ // dependents still holding the propagated error consumed their dirty flag
279
+ // in an errored run and may sit on stale commits (#2949). Changed-value
280
+ // recoveries ride insertSubs above; a comparator throw re-errored the node
281
+ // (el._error re-set), so this only runs on a genuinely clean recovery.
282
+ if (o !== undefined && !a && !e._) settleErroredDependents(e, o);
273
283
  }
274
- currentOptimisticLane = _;
275
- const T = e.Ne !== NOT_PENDING || e.ye !== null || e.Le !== null || (e.S & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
284
+ currentOptimisticLane = f;
285
+ const d = e.De !== NOT_PENDING || e.Qe !== null || e.ye !== null || (e.S & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
276
286
  // Override-covered holds (hasOverride) always queue: their commit belongs
277
287
  // to their own transition's schedule (A18 re-rule) and is unobservable
278
288
  // under the override (A17). Revert no longer commits anything, so an
279
289
  // unqueued covered hold would leak (INV-7) once the revert clears
280
290
  // _transition.
281
- T && (!t || e.S & STATUS_PENDING) && (!e.Ue || u) && queuePendingNode(e);
282
- e.Ue && n && activeTransition !== e.Ue && runInTransition(e.Ue, () => recompute(e));
291
+ d && (!t || e.S & STATUS_PENDING) && (!e.Ie || u) && queuePendingNode(e);
292
+ e.Ie && n && activeTransition !== e.Ie && runInTransition(e.Ie, () => recompute(e));
283
293
  }
284
294
 
285
295
  function updateIfNecessary(e) {
286
296
  if (e.se & REACTIVE_CHECK) {
287
- for (let t = e.Xe; t; t = t.et) {
288
- const n = t.tt;
289
- const i = n.nt || n;
290
- if (i.ke) {
297
+ for (let t = e.et; t; t = t.tt) {
298
+ const n = t.nt;
299
+ const i = n.it || n;
300
+ if (i.ae) {
291
301
  updateIfNecessary(i);
292
302
  }
293
303
  if (e.se & REACTIVE_DIRTY) {
@@ -295,7 +305,7 @@ function updateIfNecessary(e) {
295
305
  }
296
306
  }
297
307
  }
298
- if (e.se & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY) || e._ && e.ce < clock && !e.Te) {
308
+ if (e.se & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY) || e._ && e.Se < clock && !e.Te) {
299
309
  recompute(e);
300
310
  }
301
311
  e.se = e.se & (REACTIVE_SNAPSHOT_STALE | REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT);
@@ -306,36 +316,36 @@ function computed(e, t) {
306
316
  const i = {
307
317
  id: inheritId(t, n, context),
308
318
  T: (n ? CONFIG_TRANSPARENT : 0) | (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (!context || t?.lazy ? CONFIG_AUTO_DISPOSE : 0) | (t?.sync ? CONFIG_SYNC : 0) | (t?.V ? CONFIG_NO_SNAPSHOT : 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
309
- Re: t?.equals != null ? t.equals : isEqual,
310
- it: t?.unobserved,
311
- xe: null,
319
+ be: t?.equals != null ? t.equals : isEqual,
320
+ ut: t?.unobserved,
321
+ Le: null,
312
322
  C: context?.C ?? globalQueue,
313
323
  we: context?.we ?? defaultContext,
314
- Qe: 0,
315
- ke: e,
316
- Pe: undefined,
317
- He: 0,
324
+ qe: 0,
325
+ ae: e,
326
+ Ue: undefined,
327
+ Ve: 0,
318
328
  u: null,
319
- ut: undefined,
320
- lt: null,
321
- Xe: null,
322
- qe: null,
323
- We: 0,
324
- o: null,
329
+ lt: undefined,
325
330
  ot: null,
326
- Ge: context,
327
- ve: null,
331
+ et: null,
332
+ We: null,
333
+ Ye: 0,
334
+ o: null,
328
335
  st: null,
329
- me: null,
336
+ ve: context,
337
+ Fe: null,
338
+ rt: null,
339
+ ke: null,
330
340
  se: t?.lazy ? REACTIVE_LAZY : REACTIVE_NONE,
331
341
  S: STATUS_UNINITIALIZED,
332
- ce: clock,
333
- Ne: NOT_PENDING,
334
- Le: null,
342
+ Se: clock,
343
+ De: NOT_PENDING,
335
344
  ye: null,
345
+ Qe: null,
336
346
  Te: null,
337
- Ue: null,
338
- _e: false
347
+ Ie: null,
348
+ Re: false
339
349
  };
340
350
  setupComputedNode(i, t);
341
351
  return i;
@@ -351,42 +361,42 @@ function computed(e, t) {
351
361
  const s = {
352
362
  id: inheritId(l, o, context),
353
363
  T: (o ? CONFIG_TRANSPARENT : 0) | (l?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (l?.sync ? CONFIG_SYNC : 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
354
- Re: false,
355
- it: l?.unobserved,
356
- xe: null,
364
+ be: false,
365
+ ut: l?.unobserved,
366
+ Le: null,
357
367
  C: context?.C ?? globalQueue,
358
368
  we: context?.we ?? defaultContext,
359
- Qe: 0,
360
- ke: e,
361
- Pe: undefined,
362
- He: 0,
369
+ qe: 0,
370
+ ae: e,
371
+ Ue: undefined,
372
+ Ve: 0,
363
373
  u: null,
364
- ut: undefined,
365
- lt: null,
366
- Xe: null,
367
- qe: null,
368
- We: 0,
369
- o: null,
374
+ lt: undefined,
370
375
  ot: null,
371
- Ge: context,
372
- ve: null,
376
+ et: null,
377
+ We: null,
378
+ Ye: 0,
379
+ o: null,
373
380
  st: null,
374
- me: null,
381
+ ve: context,
382
+ Fe: null,
383
+ rt: null,
384
+ ke: null,
375
385
  se: REACTIVE_LAZY,
376
386
  S: STATUS_UNINITIALIZED,
377
- ce: clock,
378
- Ne: NOT_PENDING,
379
- Le: null,
387
+ Se: clock,
388
+ De: NOT_PENDING,
380
389
  ye: null,
390
+ Qe: null,
381
391
  Te: null,
382
- Ue: null,
383
- _e: false,
384
- $e: false,
385
- rt: undefined,
386
- ct: t,
387
- _t: n,
388
- ft: undefined,
389
- Ae: i,
392
+ Ie: null,
393
+ Re: false,
394
+ Be: false,
395
+ ct: undefined,
396
+ _t: t,
397
+ ft: n,
398
+ Et: undefined,
399
+ Pe: i,
390
400
  i: u
391
401
  };
392
402
  setupComputedNode(s, lazyOptions);
@@ -398,24 +408,24 @@ const lazyOptions = {
398
408
  };
399
409
 
400
410
  function setupComputedNode(e, t) {
401
- e.lt = e;
402
- const n = context?.Et ? context.Nt : context;
411
+ e.ot = e;
412
+ const n = context?.Nt ? context.Tt : context;
403
413
  if (context) {
404
- const t = context.me;
414
+ const t = context.ke;
405
415
  if (t === null) {
406
- context.me = e;
416
+ context.ke = e;
407
417
  } else {
408
- e.ve = t;
409
- t.st = e;
410
- context.me = e;
418
+ e.Fe = t;
419
+ t.rt = e;
420
+ context.ke = e;
411
421
  }
412
422
  }
413
- if (n) e.He = n.He + 1;
414
- if (GlobalQueue.Tt !== null) GlobalQueue.Tt(e);
423
+ if (n) e.Ve = n.Ve + 1;
424
+ if (GlobalQueue.dt !== null) GlobalQueue.dt(e);
415
425
  !t?.lazy && recompute(e, true);
416
426
  if (snapshotCaptureActive && !t?.lazy) {
417
427
  if (!(e.S & STATUS_PENDING) && !(e.T & CONFIG_NO_SNAPSHOT)) {
418
- e.Ve = e.Pe === undefined ? NO_SNAPSHOT : e.Pe;
428
+ e.xe = e.Ue === undefined ? NO_SNAPSHOT : e.Ue;
419
429
  snapshotSources.add(e);
420
430
  }
421
431
  }
@@ -423,20 +433,20 @@ function setupComputedNode(e, t) {
423
433
 
424
434
  function signal(e, t, n = null) {
425
435
  const i = {
426
- Re: t?.equals != null ? t.equals : isEqual,
436
+ be: t?.equals != null ? t.equals : isEqual,
427
437
  T: (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (t?.V ? CONFIG_NO_SNAPSHOT : 0),
428
- it: t?.unobserved,
429
- Pe: e,
438
+ ut: t?.unobserved,
439
+ Ue: e,
430
440
  o: null,
431
- ot: null,
432
- ce: clock,
433
- nt: n,
441
+ st: null,
442
+ Se: clock,
443
+ it: n,
434
444
  fe: n?.u || null,
435
- Ne: NOT_PENDING
445
+ De: NOT_PENDING
436
446
  };
437
447
  n && (n.u = i);
438
448
  if (snapshotCaptureActive && !(i.T & CONFIG_NO_SNAPSHOT) && !((n?.S ?? 0) & STATUS_PENDING)) {
439
- i.Ve = e === undefined ? NO_SNAPSHOT : e;
449
+ i.xe = e === undefined ? NO_SNAPSHOT : e;
440
450
  snapshotSources.add(i);
441
451
  }
442
452
  return i;
@@ -444,13 +454,13 @@ function signal(e, t, n = null) {
444
454
 
445
455
  function optimisticSignal(e, t) {
446
456
  const n = signal(e, t);
447
- n.Ee = NOT_PENDING;
457
+ n.Ae = NOT_PENDING;
448
458
  return n;
449
459
  }
450
460
 
451
461
  function optimisticComputed(e, t) {
452
462
  const n = computed(e, t);
453
- n.Ee = NOT_PENDING;
463
+ n.Ae = NOT_PENDING;
454
464
  return n;
455
465
  }
456
466
 
@@ -520,11 +530,11 @@ function isEqual(e, t) {
520
530
  * snapshot / transition / lane / dev-strictRead state all take the full
521
531
  * resolution. Anything slow returns READ_SLOW; the caller then calls read().
522
532
  */ function readNodeFast(e) {
523
- if (latestReadActive || pendingCheckActive || e.ke || e.nt || e.Ee !== undefined || e.Ve !== undefined || activeTransition !== null || currentOptimisticLane !== null || snapshotCaptureActive || false) return READ_SLOW;
533
+ if (latestReadActive || pendingCheckActive || e.ae || e.it || e.Ae !== undefined || e.xe !== undefined || activeTransition !== null || currentOptimisticLane !== null || snapshotCaptureActive || false) return READ_SLOW;
524
534
  let t = context;
525
- if (t?.Et) t = t.Nt;
535
+ if (t?.Nt) t = t.Tt;
526
536
  if (t && tracking) link(e, t);
527
- return !t || e.Ne === NOT_PENDING ? e.Pe : e.Ne;
537
+ return !t || e.De === NOT_PENDING ? e.Ue : e.De;
528
538
  }
529
539
 
530
540
  function read(e) {
@@ -532,46 +542,46 @@ function read(e) {
532
542
  // Checked before isPending so that isPending(() => latest(x)) checks
533
543
  // the _pendingSignal of _latestValueComputed (async in flight) rather
534
544
  // than the original node (which stays "pending" while held in a transition).
535
- if (latestReadActive) return GlobalQueue.dt(e);
545
+ if (latestReadActive) return GlobalQueue.St(e);
536
546
  let t = context;
537
- if (t?.Et) t = t.Nt;
547
+ if (t?.Nt) t = t.Tt;
538
548
  const n = e;
539
- const i = e.nt;
549
+ const i = e.it;
540
550
  const u = i || e;
541
551
  // Handle isPending() mode: collect pending state while preserving normal read semantics.
542
552
  // Probe mode is suspended while preparing the node so nested reads during a
543
553
  // recompute don't collect into the probe.
544
554
  if (pendingCheckActive) {
545
- GlobalQueue.St(e, t, u, i);
546
- } else if (typeof n.ke === "function") {
555
+ GlobalQueue.At(e, t, u, i);
556
+ } else if (typeof n.ae === "function") {
547
557
  prepareComputed(e, false);
548
558
  }
549
- if (!n.ke && u === e && e.Ee === undefined && e.Ve === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
559
+ if (!n.ae && u === e && e.Ae === undefined && e.xe === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
550
560
  if (t && tracking) link(e, t);
551
- return !t || e.Ne === NOT_PENDING ? e.Pe : e.Ne;
561
+ return !t || e.De === NOT_PENDING ? e.Ue : e.De;
552
562
  }
553
563
  if (t && tracking) {
554
564
  link(e, t, pendingCheckActive);
555
- if (u.ke) {
565
+ if (u.ae) {
556
566
  const n = queueFor(e);
557
- if (u.He >= n.Fe) {
567
+ if (u.Ve >= n.He) {
558
568
  markNode(t);
559
569
  markHeap(n);
560
570
  updateIfNecessary(u);
561
571
  }
562
- const i = u.He;
572
+ const i = u.Ve;
563
573
  // parent check is shallow, might need to be recursive
564
- if (i >= t.He && e.Ge !== t) {
565
- t.He = i + 1;
574
+ if (i >= t.Ve && e.ve !== t) {
575
+ t.Ve = i + 1;
566
576
  }
567
577
  }
568
578
  }
569
579
  if (u.S & STATUS_PENDING) {
570
- if (t && !(stale && u.Ue && activeTransition !== u.Ue)) {
580
+ if (t && !(stale && u.Ie && activeTransition !== u.Ie)) {
571
581
  // Per-lane suspension lives with the engine (a non-null lane implies it
572
582
  // is installed): under a lane, only same-lane pending async without an
573
583
  // active override throws.
574
- if (currentOptimisticLane === null || GlobalQueue.At(u)) {
584
+ if (currentOptimisticLane === null || GlobalQueue.Ct(u)) {
575
585
  if (!tracking && e !== t) link(e, t);
576
586
  throw u._;
577
587
  }
@@ -582,28 +592,32 @@ function read(e) {
582
592
  throw u._;
583
593
  }
584
594
  }
585
- if (e.ke && e.S & STATUS_ERROR) {
595
+ // `owner` is the computed itself, or the firewall behind a store node —
596
+ // firewall-backed reads follow the same rules (memo parity, #2897 ruling):
597
+ // an errored derive throws for every late reader instead of silently
598
+ // serving node values (the seed, or last-good data after a failed refetch).
599
+ if (u.ae && u.S & STATUS_ERROR) {
586
600
  // Only a genuine reactive re-read may retry an errored async source:
587
601
  // - tracking: owned/tracked scope only (never events / `untrack` / effect side-effect phase)
588
602
  // - !pendingCheckActive: an `isPending` probe observes the error, never refetches
589
- // - el._time < clock: only on a later cycle than the one the error was found
590
- if (tracking && !pendingCheckActive && e.ce < clock) {
591
- recompute(e);
603
+ // - owner._time < clock: only on a later cycle than the one the error was found
604
+ if (tracking && !pendingCheckActive && u.Se < clock) {
605
+ recompute(u);
592
606
  return read(e);
593
- } else throw e._;
607
+ } else throw u._;
594
608
  }
595
609
  if (snapshotCaptureActive && t && t.T & CONFIG_IN_SNAPSHOT_SCOPE) {
596
- const n = e.Ve;
610
+ const n = e.xe;
597
611
  if (n !== undefined) {
598
612
  const i = n === NO_SNAPSHOT ? undefined : n;
599
- const u = e.Ne !== NOT_PENDING ? e.Ne : e.Pe;
613
+ const u = e.De !== NOT_PENDING ? e.De : e.Ue;
600
614
  if (u !== i) t.se |= REACTIVE_SNAPSHOT_STALE;
601
615
  return i;
602
616
  }
603
617
  }
604
- if (e.Ee !== undefined && e.Ee !== NOT_PENDING) {
618
+ if (e.Ae !== undefined && e.Ae !== NOT_PENDING) {
605
619
  // A17: the override IS the value for every reader.
606
- return unwrapOverride(e.Ee);
620
+ return unwrapOverride(e.Ae);
607
621
  }
608
622
  // Entanglement gate: a reader recomputing under an optimistic lane that reads
609
623
  // a pending mid-transition write sees the committed value. Projection-store
@@ -612,43 +626,43 @@ function read(e) {
612
626
  // _pendingValue for correct fetching. The sub is recorded for replay at commit
613
627
  // so it re-runs with the new committed view. (Gate details live with the
614
628
  // engine — a non-null lane implies it is installed.)
615
- if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.Ct(e, u, t)) {
616
- return e.Pe;
629
+ if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.Ot(e, u, t)) {
630
+ return e.Ue;
617
631
  }
618
632
  // In optimistic lane context, return _value for optimistic/lane-assigned signals
619
633
  // and for regular signals in stale mode (render effects). Non-stale readers (user
620
634
  // effects) see _pendingValue so that latest() and direct reads stay consistent.
621
635
  // (The lane-context clause lives with the engine.)
622
- const l = !t || currentOptimisticLane !== null && GlobalQueue.Ot(e, u, t) || e.Ne === NOT_PENDING || stale && e.Ue && activeTransition !== e.Ue ? e.Pe : e.Ne;
636
+ const l = !t || currentOptimisticLane !== null && GlobalQueue.Rt(e, u, t) || e.De === NOT_PENDING || stale && e.Ie && activeTransition !== e.Ie ? e.Ue : e.De;
623
637
  // Record that this isPending() probe observed the fresh pending value, so
624
638
  // the probe doesn't pair "pending" with the new value (#2831).
625
- if (pendingCheckActive) GlobalQueue.Rt(e, l);
626
- if (!t && u === e && typeof n.ke === "function" && e.T & CONFIG_AUTO_DISPOSE && !(u.S & STATUS_PENDING) && !e.o) {
639
+ if (pendingCheckActive) GlobalQueue.Pt(e, l);
640
+ if (!t && u === e && typeof n.ae === "function" && e.T & CONFIG_AUTO_DISPOSE && !(u.S & STATUS_PENDING) && !e.o) {
627
641
  unobserved(e);
628
642
  }
629
643
  return l;
630
644
  }
631
645
 
632
646
  function setSignal(e, t) {
633
- if (e.Ue && activeTransition !== e.Ue) globalQueue.initTransition(e.Ue);
647
+ if (e.Ie && activeTransition !== e.Ie) globalQueue.initTransition(e.Ie);
634
648
  // The optimistic write path lives with the engine: only optimisticSignal /
635
649
  // optimisticComputed callers and optimistic store nodes carry an
636
650
  // _overrideValue slot, and every module that creates one installs the
637
651
  // engine first.
638
- if (e.Ee !== undefined && !projectionWriteActive) return GlobalQueue.Pt(e, t);
639
- const n = e.Ne === NOT_PENDING ? e.Pe : e.Ne;
652
+ if (e.Ae !== undefined && !projectionWriteActive) return GlobalQueue.ht(e, t);
653
+ const n = e.De === NOT_PENDING ? e.Ue : e.De;
640
654
  if (typeof t === "function") t = t(n);
641
655
  // Uninitialized check first: the first commit has no previous value, so the
642
656
  // user comparator must not run against `undefined` (matches recompute).
643
- const i = !!(e.S & STATUS_UNINITIALIZED) || !e.Re || !e.Re(n, t);
657
+ const i = !!(e.S & STATUS_UNINITIALIZED) || !e.be || !e.be(n, t);
644
658
  if (!i) return t;
645
- if (e.Ne === NOT_PENDING) queuePendingNode(e);
646
- e.Ne = t;
659
+ if (e.De === NOT_PENDING) queuePendingNode(e);
660
+ e.De = t;
647
661
  // syncCompanions only pokes _pendingSignal/_latestValueComputed — with
648
662
  // neither companion present the call is a guaranteed no-op (companions are
649
663
  // only ever created, never removed, and creating one installs the hook).
650
- (e.be !== undefined || e.ge !== undefined) && GlobalQueue.Ie !== null && GlobalQueue.Ie(e, t);
651
- e.ce = clock;
664
+ (e.he !== undefined || e.pe !== undefined) && GlobalQueue._e !== null && GlobalQueue._e(e, t);
665
+ e.Se = clock;
652
666
  insertSubs(e);
653
667
  schedule();
654
668
  return t;
@@ -662,7 +676,7 @@ function setSignal(e, t) {
662
676
  * cleanup point.
663
677
  */ function suppressComputedRecompute(e) {
664
678
  deleteFromHeap(e, queueFor(e));
665
- if (!(e.se & REACTIVE_MANUAL_WRITE) && e.Ne === NOT_PENDING) {
679
+ if (!(e.se & REACTIVE_MANUAL_WRITE) && e.De === NOT_PENDING) {
666
680
  queuePendingNode(e);
667
681
  schedule();
668
682
  }
@@ -745,7 +759,7 @@ function staleValues(e, t = true) {
745
759
  if (!t) {
746
760
  return;
747
761
  }
748
- if (typeof t.ke === "function" && !(t.se & (REACTIVE_DISPOSED | REACTIVE_MANUAL_WRITE))) {
762
+ if (typeof t.ae === "function" && !(t.se & (REACTIVE_DISPOSED | REACTIVE_MANUAL_WRITE))) {
749
763
  // A refresh with no value-change dirt already queued is a re-ask of the
750
764
  // same question: mark it so the recompute classifies any resulting
751
765
  // pending window as quiet (not pending). If the node is already dirty