@solidjs/signals 2.0.0-rc.5 → 2.0.0-rc.6

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.
@@ -28,13 +28,15 @@ function addPendingSource(e, n) {
28
28
  }
29
29
 
30
30
  function removePendingSource(e, n) {
31
- if (!e.o?.le?.delete(n)) return false;
32
- if (e.o?.le.size === 0) if (e.o !== null) e.o.le = undefined;
31
+ const t = e.o?.le;
32
+ if (!t?.delete(n)) return false;
33
+ if (!t.size) e.o.le = undefined;
33
34
  return true;
34
35
  }
35
36
 
36
37
  function clearPendingSources(e) {
37
- e.o?.le?.clear();
38
+ // This set is node-owned and never shared; dropping the sole reference
39
+ // releases the set and every entry without a redundant clear() walk.
38
40
  if (e.o !== null) e.o.le = undefined;
39
41
  }
40
42
 
@@ -140,6 +142,10 @@ function settleErroredDependents(e, n) {
140
142
  }
141
143
 
142
144
  function settlePendingSource(e) {
145
+ // The normal landing path already cleared the source's own set. Superseded
146
+ // re-parks arrive here with an abandoned self entry, which must retire in
147
+ // the same walk as its propagated copies.
148
+ removePendingSource(e, e);
143
149
  let n = false;
144
150
  let t;
145
151
  const r = new Set;
@@ -253,6 +259,10 @@ function handleAsync(e, n, t) {
253
259
  }
254
260
  settleTransition();
255
261
  notifyStatus(e, r ? STATUS_PENDING : STATUS_ERROR, t);
262
+ // A NotReady rejection is a landing into another pending source. The
263
+ // rejected flight will never settle its self entry, so transfer ownership
264
+ // after notifyStatus has propagated the replacement source.
265
+ if (r) settlePendingSource(e);
256
266
  e.Te = clock;
257
267
  // A real error settles derivatively-pending dependents (notifyStatus
258
268
  // cleared their pending sources), so stranded lazy ones release here —
@@ -267,14 +277,22 @@ function handleAsync(e, n, t) {
267
277
  if (e.ie & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY)) return;
268
278
  settleTransition();
269
279
  const i = !!(e.S & STATUS_UNINITIALIZED);
280
+ // Captured before clearStatus wipes it: a quiet re-ask's landing may be
281
+ // transition-held below, and the displayed value keeps answering the same
282
+ // question until the hold commits — the classification must survive to
283
+ // that reveal or companion synchronization briefly classifies the held
284
+ // old value as pending, a one-frame pulse to direct observers (#3178).
285
+ // A truthy capture implies `_x` exists, so the restore writes it directly.
286
+ const l = e.o?.De;
270
287
  trimStaleDeps(e);
271
288
  clearStatus(e);
272
- const l = resolveLane(e);
273
- if (l) l.De.delete(e);
289
+ if (l) e.o.De = true;
290
+ const s = resolveLane(e);
291
+ if (s) s.Oe.delete(e);
274
292
  if (t) {
275
293
  t(r);
276
294
  if (i) clearStatus(e, true);
277
- } else if (e.o?.Oe !== undefined) {
295
+ } else if (e.o?.Pe !== undefined) {
278
296
  // Optimistic node — resting OR covered by an active override — holds
279
297
  // through the shared pending-node path, exactly like a plain async memo,
280
298
  // so the commit clears STATUS_UNINITIALIZED (#2806) and elevation to
@@ -284,8 +302,8 @@ function handleAsync(e, n, t) {
284
302
  // (A17 — every reader sees the override); the revert reveals whatever
285
303
  // has committed by then, so corrections reveal atomically with their
286
304
  // transition rather than escaping it.
287
- if (e.Pe === NOT_PENDING) queuePendingNode(e);
288
- e.Pe = r;
305
+ if (e.Re === NOT_PENDING) queuePendingNode(e);
306
+ e.Re = r;
289
307
  // The hold is a companion-visible write like any other (A13/A19): the
290
308
  // clearStatus() above computed its verdict before the hold existed, so
291
309
  // isPending must re-derive (the value is not final until commit — V1)
@@ -293,7 +311,7 @@ function handleAsync(e, n, t) {
293
311
  // only notified when the hold is visible to them: under an active
294
312
  // override every reader sees the override (A17), so waking subs would
295
313
  // re-show an unchanged view — the revert is the notification point.
296
- GlobalQueue.Re?.(e, r);
314
+ GlobalQueue.Ue?.(e, r);
297
315
  if (!hasActiveOverride(e)) {
298
316
  insertSubs(e);
299
317
  } else if (e.T & CONFIG_AUTHORITATIVE_OBSERVED) {
@@ -306,14 +324,14 @@ function handleAsync(e, n, t) {
306
324
  // branch in recompute(). Optional call: the bit implies the
307
325
  // optimistic engine WAS consulted, but the hook only installs with
308
326
  // it — a bare-core build must not crash here.
309
- GlobalQueue.Ue?.(e);
327
+ GlobalQueue.he?.(e);
310
328
  }
311
329
  e.Te = clock;
312
- } else if (l) {
330
+ } else if (s) {
313
331
  // Route through lane's effect queue for independent flushing
314
- const n = e.he;
332
+ const n = e.ge;
315
333
  const t = e.be;
316
- const o = e.ge;
334
+ const o = e.pe;
317
335
  try {
318
336
  if (!n && i || !o || !o(r, t)) {
319
337
  e.be = r;
@@ -321,7 +339,7 @@ function handleAsync(e, n, t) {
321
339
  // The latest() shadow write gives latest() effects independent lanes; the
322
340
  // _pendingSignal update is a no-op repeat of the clearStatus() call above
323
341
  // (computePendingState doesn't read _value).
324
- GlobalQueue.Re?.(e, r);
342
+ GlobalQueue.Ue?.(e, r);
325
343
  insertSubs(e, true);
326
344
  }
327
345
  } catch (n) {
@@ -345,8 +363,12 @@ function handleAsync(e, n, t) {
345
363
  // (`_pendingValue` set above or inside setSignal) is not — the verdict's
346
364
  // held-value branch is window-gated, and commitPendingNode closes the
347
365
  // window when the hold commits, so no one-frame isPending pulse can leak
348
- // to live observers between the landing and its commit (#2990).
349
- if (e.Pe === NOT_PENDING) e.Ne = false;
366
+ // to live observers between the landing and its commit (#2990). The
367
+ // quiet re-ask classification follows the same schedule (#3178).
368
+ if (e.Re === NOT_PENDING) {
369
+ e.Ne = false;
370
+ if (l) e.o.De = false;
371
+ }
350
372
  settlePendingSource(e);
351
373
  schedule();
352
374
  flush();
@@ -505,7 +527,7 @@ function handleAsync(e, n, t) {
505
527
  // becomes disposal-bearing, which is exactly the class a directly
506
528
  // returned iterable already occupies.
507
529
  const registerDeferredClose = n => {
508
- if (!e.pe) e.pe = n; else if (Array.isArray(e.pe)) e.pe.push(n); else e.pe = [ e.pe, n ];
530
+ if (!e.Ge) e.Ge = n; else if (Array.isArray(e.Ge)) e.Ge.push(n); else e.Ge = [ e.Ge, n ];
509
531
  };
510
532
  n.then(r => {
511
533
  if (l) {
@@ -568,7 +590,7 @@ function clearStatus(e, n = false) {
568
590
  // The pending window is over; its quiet classification dies with it.
569
591
  // (Unconditional: _reask is baked into the node literals, so this is a
570
592
  // plain store to an existing slot — no shape change.)
571
- if (e.o !== null) e.o.Ge = false;
593
+ if (e.o !== null) e.o.De = false;
572
594
  e.S = n ? 0 : e.S & STATUS_UNINITIALIZED;
573
595
  if (e.o?._) setPendingError(e);
574
596
  // Update pending signal for isPending() reactivity (companions only exist
@@ -584,7 +606,7 @@ function notifyStatus(e, n, t, r, o) {
584
606
  if (n === STATUS_ERROR && !(t instanceof StatusError) && !(t instanceof NotReadyError)) t = new StatusError(e, t);
585
607
  const i = n === STATUS_PENDING && t instanceof NotReadyError ? t.source : undefined;
586
608
  const l = i === e;
587
- const s = n === STATUS_PENDING && e.o?.Oe !== undefined && !l;
609
+ const s = n === STATUS_PENDING && e.o?.Pe !== undefined && !l;
588
610
  const u = s && hasActiveOverride(e);
589
611
  if (!r) {
590
612
  if (n === STATUS_PENDING && i) {
@@ -1,6 +1,6 @@
1
- import { releaseFlightTeardown, handleAsync, clearStatus, parkLoadingWindow, notifyStatus, settleErroredDependents, settlePendingSource } from "./async.js";
1
+ import { releaseFlightTeardown, handleAsync, clearStatus, parkLoadingWindow, notifyStatus, settlePendingSource, settleErroredDependents } from "./async.js";
2
2
 
3
- import { EFFECT_TRACKED, REACTIVE_OPTIMISTIC_DIRTY, CONFIG_OPTIMISTIC, NOT_PENDING, STATUS_UNINITIALIZED, STATUS_ERROR, STATUS_PENDING, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, CONFIG_SYNC, CONFIG_HAS_LANE, REACTIVE_MISSED_WAKE, REACTIVE_NONE, REACTIVE_SNAPSHOT_STALE, unwrapOverride, CONFIG_DIRECT_COMMIT, OVERRIDE_UNDEFINED, CONFIG_AUTHORITATIVE_OBSERVED, CONFIG_HAS_COMPANIONS, REACTIVE_LAZY, REACTIVE_DISPOSED, CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_FRESH_READ, CONFIG_AUTHORITATIVE_READ, CONFIG_HELD_TRUTH, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, defaultContext, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_TRANSPARENT, CONFIG_OWNED_WRITE, CONFIG_NO_SNAPSHOT, CONFIG_FW_CHILDREN, NO_SNAPSHOT, CONFIG_HAS_SNAPSHOT, REACTIVE_MANUAL_WRITE, STORE_SNAPSHOT_PROPS, EFFECT_USER } from "./constants.js";
3
+ import { EFFECT_TRACKED, REACTIVE_OPTIMISTIC_DIRTY, CONFIG_OPTIMISTIC, NOT_PENDING, STATUS_UNINITIALIZED, STATUS_ERROR, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, CONFIG_SYNC, CONFIG_HAS_LANE, STATUS_PENDING, REACTIVE_MISSED_WAKE, REACTIVE_NONE, REACTIVE_SNAPSHOT_STALE, unwrapOverride, CONFIG_DIRECT_COMMIT, OVERRIDE_UNDEFINED, CONFIG_AUTHORITATIVE_OBSERVED, CONFIG_HAS_COMPANIONS, REACTIVE_LAZY, REACTIVE_DISPOSED, CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_FRESH_READ, CONFIG_AUTHORITATIVE_READ, CONFIG_HELD_TRUTH, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, defaultContext, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_TRANSPARENT, CONFIG_OWNED_WRITE, CONFIG_NO_SNAPSHOT, CONFIG_FW_CHILDREN, NO_SNAPSHOT, CONFIG_HAS_SNAPSHOT, REACTIVE_MANUAL_WRITE, STORE_SNAPSHOT_PROPS, EFFECT_USER } from "./constants.js";
4
4
 
5
5
  import { NotReadyError } from "./error.js";
6
6
 
@@ -108,7 +108,7 @@ function clearSnapshots() {
108
108
  function recompute(e, t = false) {
109
109
  // §12d: any recompute can clean a marked subscriber — invalidate skips.
110
110
  bumpNotifyEpoch();
111
- const n = e.he;
111
+ const n = e.ge;
112
112
  if (!t) {
113
113
  if (e.Ae && (!n || activeTransition) && activeTransition !== e.Ae) globalQueue.initTransition(e.Ae);
114
114
  deleteFromHeap(e, queueFor(e));
@@ -122,18 +122,18 @@ function recompute(e, t = false) {
122
122
  releaseFlightTeardown(e);
123
123
  }
124
124
  // Tracked effects run after finalizePureQueue, so dispose immediately instead of deferring
125
- if (e.Ae || n === EFFECT_TRACKED) disposeChildren(e); else if (e.xe !== null || e.pe !== null) {
125
+ if (e.Ae || n === EFFECT_TRACKED) disposeChildren(e); else if (e.xe !== null || e.Ge !== null) {
126
126
  markDisposal(e);
127
127
  const t = ext(e);
128
- t.qe = e.pe;
128
+ t.qe = e.Ge;
129
129
  t.Ye = e.xe;
130
- e.pe = null;
130
+ e.Ge = null;
131
131
  e.xe = null;
132
132
  e.Ze = 0;
133
133
  } else ;
134
134
  }
135
135
  let i = !!(e.ie & REACTIVE_OPTIMISTIC_DIRTY);
136
- const u = (e.T & CONFIG_OPTIMISTIC) !== 0 && e.o?.Oe !== NOT_PENDING && e.o?.Oe !== undefined;
136
+ const u = (e.T & CONFIG_OPTIMISTIC) !== 0 && e.o?.Pe !== NOT_PENDING && e.o?.Pe !== undefined;
137
137
  const l = !!(e.S & STATUS_UNINITIALIZED);
138
138
  // Outgoing error, captured before the compute clears status: if this run
139
139
  // recovers to an unchanged value, dependents still holding this object must
@@ -145,7 +145,7 @@ function recompute(e, t = false) {
145
145
  // settles synchronously, those dependents settle HERE — asyncWrite's
146
146
  // settlePendingSource walk never runs for a landing that was preempted
147
147
  // (#3181).
148
- const s = (e.S & STATUS_PENDING) !== 0 && e.o?.le?.has(e) === true;
148
+ const s = e.o?.le?.has(e);
149
149
  // Re-ask classification lives in the verdict module; capture the flag before
150
150
  // the recompute wipes _flags below.
151
151
  const a = (e.ie & REACTIVE_REASK) !== 0;
@@ -160,7 +160,7 @@ function recompute(e, t = false) {
160
160
  e.Ke++;
161
161
  e.ie = REACTIVE_RECOMPUTING_DEPS;
162
162
  e.Te = clock;
163
- let _ = e.Pe === NOT_PENDING ? e.be : e.Pe;
163
+ let _ = e.Re === NOT_PENDING ? e.be : e.Re;
164
164
  let f = e.Me;
165
165
  let I = false;
166
166
  let E = tracking;
@@ -251,6 +251,9 @@ function recompute(e, t = false) {
251
251
  if (GlobalQueue.et !== null) i = GlobalQueue.et(e, a);
252
252
  }
253
253
  notifyStatus(e, n ? STATUS_PENDING : STATUS_ERROR, t, undefined, n ? e.o?.Je : undefined);
254
+ // The replacement source is fully propagated now. If no new flight
255
+ // re-owned self, retire the superseded flight and its dependent copies.
256
+ if (n && s && !e.o?.Ie) settlePendingSource(e);
254
257
  if (i) GlobalQueue.k(e);
255
258
  }
256
259
  } finally {
@@ -268,10 +271,10 @@ function recompute(e, t = false) {
268
271
  }
269
272
  if (!e.o?._) {
270
273
  trimStaleDeps(e);
271
- const a = u ? unwrapOverride(e.o?.Oe) : e.Pe === NOT_PENDING ? e.be : e.Pe;
274
+ const a = u ? unwrapOverride(e.o?.Pe) : e.Re === NOT_PENDING ? e.be : e.Re;
272
275
  let c = false;
273
276
  try {
274
- c = !n && l || !e.ge || !e.ge(a, _);
277
+ c = !n && l || !e.pe || !e.pe(a, _);
275
278
  } catch (t) {
276
279
  // A throwing user comparator is an error of this node's computation.
277
280
  // Route it through the same status path as a compute-phase throw so
@@ -291,7 +294,7 @@ function recompute(e, t = false) {
291
294
  if (!t) e.C.enqueue(n, e.nt ??= GlobalQueue.it.bind(null, e));
292
295
  }
293
296
  if (e.o?._) ; else if (c) {
294
- const l = u ? e.o?.Oe : undefined;
297
+ const l = u ? e.o?.Pe : undefined;
295
298
  if (t ||
296
299
  // Plain sync flush (no transition on either side) commits effect
297
300
  // values directly — the pending round-trip (queuePendingNode +
@@ -308,11 +311,11 @@ function recompute(e, t = false) {
308
311
  // own reveal schedule; drop any superseded older hold so its queued
309
312
  // commit can't clobber the fresh value.
310
313
  if (u && i) {
311
- ext(e).Oe = _ === undefined ? OVERRIDE_UNDEFINED : _;
312
- e.Pe = NOT_PENDING;
314
+ ext(e).Pe = _ === undefined ? OVERRIDE_UNDEFINED : _;
315
+ e.Re = NOT_PENDING;
313
316
  }
314
317
  } else {
315
- e.Pe = _;
318
+ e.Re = _;
316
319
  // A window landing that gets held re-opens the window until the hold
317
320
  // commits — the verdict's held-value branch is window-gated (#2990).
318
321
  if (r) e.Ne = true;
@@ -321,17 +324,17 @@ function recompute(e, t = false) {
321
324
  // (#2831). Both companion writes are transition-scoped (optimistic) and
322
325
  // auto-revert/re-derive at commit. Skipped for plain flushes where the
323
326
  // pending value commits before effects run.
324
- if ((activeTransition || e.Ae) && GlobalQueue.Re !== null) GlobalQueue.Re(e, _);
327
+ if ((activeTransition || e.Ae) && GlobalQueue.Ue !== null) GlobalQueue.Ue(e, _);
325
328
  }
326
329
  // insertSubs only walks _subs (no scheduling of its own), so a
327
330
  // subscriber-less node has nothing to notify.
328
- if (e.u !== null && (!u || i || e.o?.Oe !== l)) insertSubs(e, i || u);
331
+ if (e.u !== null && (!u || i || e.o?.Pe !== l)) insertSubs(e, i || u);
329
332
  } else if (u) {
330
333
  // Unchanged value (equals the override) recomputed while the override
331
334
  // is active: _value may still be stale, so hold the authoritative value
332
335
  // for commit on its own transition's schedule — invisibly (A17/A18).
333
- if (e.Pe === NOT_PENDING) queuePendingNode(e);
334
- e.Pe = _;
336
+ if (e.Re === NOT_PENDING) queuePendingNode(e);
337
+ e.Re = _;
335
338
  if (r) e.Ne = true;
336
339
  // see the held branch above (#2990)
337
340
  // A authoritative-view reader (until()) observed this node past its
@@ -339,7 +342,7 @@ function recompute(e, t = false) {
339
342
  // exactly the acknowledgment it waits for. Wake those readers only;
340
343
  // A17 silence holds for every ordinary subscriber. (Hook installed by
341
344
  // until(), the only setter of the gating bit.)
342
- if (e.T & CONFIG_AUTHORITATIVE_OBSERVED) GlobalQueue.Ue(e);
345
+ if (e.T & CONFIG_AUTHORITATIVE_OBSERVED) GlobalQueue.he(e);
343
346
  } else if (e.Me != f) {
344
347
  for (let t = e.u; t !== null; t = t.ae) {
345
348
  insertIntoHeapHeight(t.ce, queueFor(t.ce));
@@ -351,20 +354,13 @@ function recompute(e, t = false) {
351
354
  // recoveries ride insertSubs above; a comparator throw re-errored the node
352
355
  // (el._x?._error re-set), so this only runs on a genuinely clean recovery.
353
356
  if (o !== undefined && !c && !e.o?._) settleErroredDependents(e, o);
354
- // Pending twin of the sweep above (#3181): a flight superseded by this
355
- // synchronous settle leaves every registered dependent still flagged
356
- // STATUS_PENDING with a pending source that will never land asyncWrite
357
- // owns the walk only for flights that actually land. An unchanged value
358
- // is the dangerous shape (a projection reconciling in place: a memo over
359
- // it re-throws its cached NotReadyError forever, and every reader that
360
- // suspended through that memo re-parks on the dead source), but the walk
361
- // runs on the changed shape too, exactly as the landing path does —
362
- // insertSubs notifies value SUBSCRIBERS, not pending REGISTRANTS, and
363
- // the two sets only partially overlap.
364
- if (s && !(e.S & STATUS_PENDING)) settlePendingSource(e);
357
+ // #3181: a synchronous settle supersedes the old landing callback, so
358
+ // recompute owns its pending-source sweep. An uninitialized node without
359
+ // a replacement source still has no truth to reveal and must stay parked.
360
+ if (s && !(e.S & (STATUS_PENDING | STATUS_UNINITIALIZED))) settlePendingSource(e);
365
361
  }
366
362
  currentOptimisticLane = N;
367
- const A = e.Pe !== NOT_PENDING || e.o !== null && (e.o.Ye !== null || e.o.qe !== null) || (e.S & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
363
+ const A = e.Re !== NOT_PENDING || e.o !== null && (e.o.Ye !== null || e.o.qe !== null) || (e.S & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
368
364
  // Override-covered holds (hasOverride) always queue: their commit belongs
369
365
  // to their own transition's schedule (A18 re-rule) and is unobservable
370
366
  // under the override (A17). Revert no longer commits anything, so an
@@ -418,8 +414,8 @@ function computed(e, t) {
418
414
  const u = {
419
415
  id: inheritId(t, n, context),
420
416
  T: (n ? CONFIG_TRANSPARENT : 0) | (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (!context || t?.lazy ? CONFIG_AUTO_DISPOSE : 0) | (t?.sync ? CONFIG_SYNC : 0) | (t?.H ? CONFIG_NO_SNAPSHOT : 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
421
- ge: t?.equals ?? isEqual,
422
- pe: null,
417
+ pe: t?.equals ?? isEqual,
418
+ Ge: null,
423
419
  C: context?.C ?? globalQueue,
424
420
  we: context?.we ?? defaultContext,
425
421
  Ze: 0,
@@ -441,7 +437,7 @@ function computed(e, t) {
441
437
  // A loadingValue node is born committed: commit #0 is already in _value.
442
438
  S: i ? 0 : STATUS_UNINITIALIZED,
443
439
  Te: clock,
444
- Pe: NOT_PENDING,
440
+ Re: NOT_PENDING,
445
441
  Ae: null,
446
442
  It: -1,
447
443
  Ne: i,
@@ -461,7 +457,7 @@ function computed(e, t) {
461
457
  * this; hot paths read `el._x?._field` gated by the _config presence bits.
462
458
  * Never call ext() just to store a field's default. */ function ext(e) {
463
459
  return e.o ??= {
464
- Oe: undefined,
460
+ Pe: undefined,
465
461
  Nt: undefined,
466
462
  Je: undefined,
467
463
  ye: undefined,
@@ -474,7 +470,7 @@ function computed(e, t) {
474
470
  fe: undefined,
475
471
  le: undefined,
476
472
  h: undefined,
477
- Ge: false,
473
+ De: false,
478
474
  i: null,
479
475
  Et: undefined,
480
476
  We: undefined,
@@ -494,8 +490,8 @@ function computed(e, t) {
494
490
  const o = {
495
491
  id: inheritId(u, l, context),
496
492
  T: (l ? CONFIG_TRANSPARENT : 0) | (u?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (u?.sync ? CONFIG_SYNC : 0) | (u?.dt ?? 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
497
- ge: false,
498
- pe: null,
493
+ pe: false,
494
+ Ge: null,
499
495
  C: context?.C ?? globalQueue,
500
496
  we: context?.we ?? defaultContext,
501
497
  Ze: 0,
@@ -516,7 +512,7 @@ function computed(e, t) {
516
512
  ie: REACTIVE_LAZY,
517
513
  S: STATUS_UNINITIALIZED,
518
514
  Te: clock,
519
- Pe: NOT_PENDING,
515
+ Re: NOT_PENDING,
520
516
  Ae: null,
521
517
  It: -1,
522
518
  Ne: false,
@@ -525,7 +521,7 @@ function computed(e, t) {
525
521
  Ot: t,
526
522
  Ct: n,
527
523
  Rt: undefined,
528
- he: i,
524
+ ge: i,
529
525
  o: null
530
526
  };
531
527
  // Effects dispatch status through the SHARED notifier (statusNotifierOf,
@@ -556,7 +552,7 @@ function setEffectStatusNotify(e) {
556
552
  * per-node field did when every effect carried one. */ function statusNotifierOf(e) {
557
553
  const t = e.o?.h;
558
554
  if (t !== undefined) return t;
559
- return e.he ? effectStatusNotify ?? undefined : undefined;
555
+ return e.ge ? effectStatusNotify ?? undefined : undefined;
560
556
  }
561
557
 
562
558
  const lazyOptions = {
@@ -590,7 +586,7 @@ function setupComputedNode(e, t) {
590
586
 
591
587
  function signal(e, t, n = null) {
592
588
  const i = {
593
- ge: t?.equals ?? isEqual,
589
+ pe: t?.equals ?? isEqual,
594
590
  T: (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (t?.H ? CONFIG_NO_SNAPSHOT : 0),
595
591
  be: e,
596
592
  u: null,
@@ -598,7 +594,7 @@ function signal(e, t, n = null) {
598
594
  Te: clock,
599
595
  st: n,
600
596
  Se: n?.o?.i || null,
601
- Pe: NOT_PENDING,
597
+ Re: NOT_PENDING,
602
598
  // Signal-literal diet (§12e): NO _time/_fn/_statusFlags slots. Stores
603
599
  // materialize one signal per touched leaf, so signal bytes are store
604
600
  // bytes. _time is write-only on signals (every read site is computed-
@@ -623,14 +619,14 @@ function signal(e, t, n = null) {
623
619
 
624
620
  function optimisticSignal(e, t) {
625
621
  const n = signal(e, t);
626
- ext(n).Oe = NOT_PENDING;
622
+ ext(n).Pe = NOT_PENDING;
627
623
  n.T |= CONFIG_OPTIMISTIC;
628
624
  return n;
629
625
  }
630
626
 
631
627
  function optimisticComputed(e, t) {
632
628
  const n = computed(e, t);
633
- ext(n).Oe = NOT_PENDING;
629
+ ext(n).Pe = NOT_PENDING;
634
630
  n.T |= CONFIG_OPTIMISTIC;
635
631
  return n;
636
632
  }
@@ -731,11 +727,11 @@ function isEqual(e, t) {
731
727
  /** Installs the until() machinery hook. Idempotent; called by until() before
732
728
  * any authoritative-view read happens (same late-binding contract as the
733
729
  * optimistic engine). */ function installAuthoritativeRead() {
734
- if (GlobalQueue.Ue === null) GlobalQueue.Ue = notifyAuthoritativeObservers;
730
+ if (GlobalQueue.he === null) GlobalQueue.he = notifyAuthoritativeObservers;
735
731
  }
736
732
 
737
733
  function readNodeFast(e) {
738
- if (latestReadActive || pendingCheckActive || e.oe || e.st || e.o?.Oe !== undefined || e.o?.We !== undefined || activeTransition !== null || currentOptimisticLane !== null || snapshotCaptureActive || false) return READ_SLOW;
734
+ if (latestReadActive || pendingCheckActive || e.oe || e.st || e.o?.Pe !== undefined || e.o?.We !== undefined || activeTransition !== null || currentOptimisticLane !== null || snapshotCaptureActive || false) return READ_SLOW;
739
735
  let t = context;
740
736
  if (t?.Gt) t = t.Dt;
741
737
  if (t && tracking) link(e, t);
@@ -743,7 +739,7 @@ function readNodeFast(e) {
743
739
  // committed visibility: like the effect half of createEffect and event
744
740
  // handlers, effect-phase code never observes its own unsettled write — the
745
741
  // write lands in the same flush's continuation (#3006).
746
- return !t || e.Pe === NOT_PENDING || t.T & CONFIG_CHILDREN_FORBIDDEN ? e.be : e.Pe;
742
+ return !t || e.Re === NOT_PENDING || t.T & CONFIG_CHILDREN_FORBIDDEN ? e.be : e.Re;
747
743
  }
748
744
 
749
745
  function read(e) {
@@ -765,10 +761,10 @@ function read(e) {
765
761
  } else if (typeof n.oe === "function") {
766
762
  prepareComputed(e, false);
767
763
  }
768
- if (!n.oe && u === e && e.o?.Oe === undefined && e.o?.We === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
764
+ if (!n.oe && u === e && e.o?.Pe === undefined && e.o?.We === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
769
765
  if (t && tracking) link(e, t);
770
766
  // Committed visibility for children-forbidden readers — see readNodeFast.
771
- return !t || e.Pe === NOT_PENDING || t.T & CONFIG_CHILDREN_FORBIDDEN ? e.be : e.Pe;
767
+ return !t || e.Re === NOT_PENDING || t.T & CONFIG_CHILDREN_FORBIDDEN ? e.be : e.Re;
772
768
  }
773
769
  if (t && tracking) {
774
770
  link(e, t, pendingCheckActive);
@@ -837,12 +833,12 @@ function read(e) {
837
833
  const n = e.o?.We;
838
834
  if (n !== undefined) {
839
835
  const i = n === NO_SNAPSHOT ? undefined : n;
840
- const u = e.Pe !== NOT_PENDING ? e.Pe : e.be;
836
+ const u = e.Re !== NOT_PENDING ? e.Re : e.be;
841
837
  if (u !== i) t.ie |= REACTIVE_SNAPSHOT_STALE;
842
838
  return i;
843
839
  }
844
840
  }
845
- if (e.o?.Oe !== undefined && e.o?.Oe !== NOT_PENDING) {
841
+ if (e.o?.Pe !== undefined && e.o?.Pe !== NOT_PENDING) {
846
842
  // A17: the override IS the value for every reader — except an authoritative
847
843
  // reader (until()'s predicate carries CONFIG_AUTHORITATIVE_READ): it must
848
844
  // observe independently-arriving truth, and serving it the caller's own
@@ -853,7 +849,7 @@ function read(e) {
853
849
  // authoritative — optimism never lives there); the sticky mark makes the
854
850
  // A17-silent "landing equals override" paths notify this node's subs so
855
851
  // the reader re-runs when truth arrives.
856
- if (!(t && t.T & CONFIG_AUTHORITATIVE_READ)) return unwrapOverride(e.o?.Oe);
852
+ if (!(t && t.T & CONFIG_AUTHORITATIVE_READ)) return unwrapOverride(e.o?.Pe);
857
853
  e.T |= CONFIG_AUTHORITATIVE_OBSERVED;
858
854
  }
859
855
  // Entanglement gate: a reader recomputing under an optimistic lane that reads
@@ -872,7 +868,7 @@ function read(e) {
872
868
  // (The lane-context clause lives with the engine.) Children-forbidden readers
873
869
  // (createTrackedEffect / onSettled callbacks) get committed visibility — see
874
870
  // readNodeFast (#3006).
875
- const l = !t || currentOptimisticLane !== null && GlobalQueue.bt(e, u, t) || e.Pe === NOT_PENDING || t.T & CONFIG_CHILDREN_FORBIDDEN || stale && e.Ae && activeTransition !== e.Ae ||
871
+ const l = !t || currentOptimisticLane !== null && GlobalQueue.bt(e, u, t) || e.Re === NOT_PENDING || t.T & CONFIG_CHILDREN_FORBIDDEN || stale && e.Ae && activeTransition !== e.Ae ||
876
872
  // A17 for HELD truth (#3164, see CONFIG_HELD_TRUTH): staged confirming
877
873
  // truth — fold-staged onto an armed family, or entangle-stolen by an
878
874
  // awaited until() — is masked from ordinary readers until its
@@ -881,7 +877,7 @@ function read(e) {
881
877
  // compose override + staged truth into a state no timeline contains).
882
878
  // Authoritative readers (until()'s predicate) and latest() see the
883
879
  // staged truth — the tunnel that keeps the hold deadlock-free.
884
- e.T & CONFIG_HELD_TRUTH && !latestReadActive && !(t.T & CONFIG_AUTHORITATIVE_READ) ? e.be : e.Pe;
880
+ e.T & CONFIG_HELD_TRUTH && !latestReadActive && !(t.T & CONFIG_AUTHORITATIVE_READ) ? e.be : e.Re;
885
881
  // Record that this isPending() probe observed the fresh pending value, so
886
882
  // the probe doesn't pair "pending" with the new value (#2831).
887
883
  if (pendingCheckActive) GlobalQueue.kt(e, l);
@@ -906,21 +902,21 @@ function setSignal(e, t) {
906
902
  // always-present config instead of a missing-property probe), and every
907
903
  // module that installs one installs the engine first.
908
904
  if (e.T & CONFIG_OPTIMISTIC && !projectionWriteActive) return GlobalQueue.xt(e, t);
909
- const n = e.Pe === NOT_PENDING ? e.be : e.Pe;
905
+ const n = e.Re === NOT_PENDING ? e.be : e.Re;
910
906
  if (typeof t === "function") t = t(n);
911
907
  // Uninitialized check first: the first commit has no previous value, so the
912
908
  // user comparator must not run against `undefined` (matches recompute).
913
- const i = !!(e.S & STATUS_UNINITIALIZED) || !e.ge || !e.ge(n, t);
909
+ const i = !!(e.S & STATUS_UNINITIALIZED) || !e.pe || !e.pe(n, t);
914
910
  if (!i) return t;
915
- const u = e.Pe !== NOT_PENDING;
911
+ const u = e.Re !== NOT_PENDING;
916
912
  if (!u) queuePendingNode(e);
917
- e.Pe = t;
913
+ e.Re = t;
918
914
  // syncCompanions only pokes _pendingSignal/_latestValueComputed — with
919
915
  // neither companion present the call is a guaranteed no-op (companions are
920
916
  // only ever created, never removed, and creating one installs the hook and
921
917
  // sets CONFIG_HAS_COMPANIONS — one masked read replaces two optional-field
922
918
  // probes on every write).
923
- e.T & CONFIG_HAS_COMPANIONS && GlobalQueue.Re !== null && GlobalQueue.Re(e, t);
919
+ e.T & CONFIG_HAS_COMPANIONS && GlobalQueue.Ue !== null && GlobalQueue.Ue(e, t);
924
920
  // _time is a computed-only slot (§12e): writing it on a signal would fork
925
921
  // the lean shape. Every read site is computed-typed.
926
922
  if (e.oe !== undefined) e.Te = clock;
@@ -943,7 +939,7 @@ function setSignal(e, t) {
943
939
  * cleanup point.
944
940
  */ function suppressComputedRecompute(e) {
945
941
  deleteFromHeap(e, queueFor(e));
946
- if (!(e.ie & REACTIVE_MANUAL_WRITE) && e.Pe === NOT_PENDING) {
942
+ if (!(e.ie & REACTIVE_MANUAL_WRITE) && e.Re === NOT_PENDING) {
947
943
  queuePendingNode(e);
948
944
  schedule();
949
945
  }
@@ -14,7 +14,7 @@ import { GlobalQueue, haltReactivity } from "./scheduler.js";
14
14
  const r = !!f?.user;
15
15
  const R = createEffectNode(t, e, E, r ? EFFECT_USER : EFFECT_RENDER, f);
16
16
  recompute(R, true);
17
- !f?.defer && (R.he === EFFECT_USER || f?.schedule ? R.C.enqueue(R.he, runEffect.bind(null, R)) : runEffect(R));
17
+ !f?.defer && (R.ge === EFFECT_USER || f?.schedule ? R.C.enqueue(R.ge, runEffect.bind(null, R)) : runEffect(R));
18
18
  }
19
19
 
20
20
  function notifyEffectStatus(t, e) {
@@ -23,7 +23,7 @@ function notifyEffectStatus(t, e) {
23
23
  const f = e !== undefined ? e : this.o?._;
24
24
  if (E & STATUS_ERROR) {
25
25
  this.C.notify(this, STATUS_PENDING, 0);
26
- if (this.he === EFFECT_USER) {
26
+ if (this.ge === EFFECT_USER) {
27
27
  // The error handler is the error arm of the effect phase (#2840 ruling):
28
28
  // queue it like the effect function. It runs in the same imperative,
29
29
  // writable scope, throws escalate the same way, and a held transition
@@ -35,7 +35,7 @@ function notifyEffectStatus(t, e) {
35
35
  // re-propagates unblocked at commit.
36
36
  if (this.S & STATUS_ERROR) {
37
37
  this.tt = true;
38
- this.C.enqueue(this.he, this.nt ??= runEffect.bind(null, this));
38
+ this.C.enqueue(this.ge, this.nt ??= runEffect.bind(null, this));
39
39
  }
40
40
  return;
41
41
  }
@@ -43,7 +43,7 @@ function notifyEffectStatus(t, e) {
43
43
  haltReactivity(unwrapStatusError(f));
44
44
  throw f;
45
45
  }
46
- } else if (this.he === EFFECT_RENDER) {
46
+ } else if (this.ge === EFFECT_RENDER) {
47
47
  this.C.notify(this, STATUS_PENDING | STATUS_ERROR, E, f);
48
48
  }
49
49
  }
@@ -60,7 +60,7 @@ function runEffect(t) {
60
60
  // Render effects bypass: their errors route to boundaries synchronously in
61
61
  // notifyEffectStatus, and a runner queued by an earlier valueChanged in the
62
62
  // same flush must not be hijacked by a later-arriving error status.
63
- if (t.S & STATUS_ERROR && t.he === EFFECT_USER) {
63
+ if (t.S & STATUS_ERROR && t.ge === EFFECT_USER) {
64
64
  const e = unwrapStatusError(t.o?._);
65
65
  t.At = t.be;
66
66
  t.tt = false;
@@ -126,7 +126,7 @@ GlobalQueue.it = runEffect;
126
126
  E.Rt = undefined;
127
127
  E.T = E.T & ~CONFIG_AUTO_DISPOSE | CONFIG_CHILDREN_FORBIDDEN;
128
128
  E.tt = true;
129
- E.he = EFFECT_TRACKED;
129
+ E.ge = EFFECT_TRACKED;
130
130
  // Status dispatch rides the SHARED notifier (statusNotifierOf keys off
131
131
  // _type): its error arm is behavior-identical to the closure that used to
132
132
  // live here, without the per-node NodeExtension allocation.
@@ -13,7 +13,7 @@ import { zombieQueue, dirtyQueue } from "./scheduler.js";
13
13
  * the heap and go directly to their effect queue; everything else is inserted
14
14
  * into its own (zombie-flag-routed) heap with the `_min` cursor pulled down.
15
15
  */ function enqueueSub(e) {
16
- if (e.he === EFFECT_TRACKED) {
16
+ if (e.ge === EFFECT_TRACKED) {
17
17
  const E = e;
18
18
  if (!E.tt) {
19
19
  E.tt = true;
@@ -25,7 +25,7 @@ const activeLanes = new Set;
25
25
  const r = t ? findLane(t) : null;
26
26
  e = {
27
27
  nn: n,
28
- De: new Set,
28
+ Oe: new Set,
29
29
  tn: [ [], [] ],
30
30
  rn: null,
31
31
  Ae: activeTransition,
@@ -71,8 +71,8 @@ function adoptCompanionLane(n, e) {
71
71
  // Move (not copy) the merged lane's work: after the merge all routing goes
72
72
  // through findLane() to the root, so anything left behind here is dead —
73
73
  // and anything *added* here later is a routing bug (INV-5).
74
- for (const i of e.De) n.De.add(i);
75
- e.De.clear();
74
+ for (const i of e.Oe) n.Oe.add(i);
75
+ e.Oe.clear();
76
76
  n.tn[0].push(...e.tn[0]);
77
77
  n.tn[1].push(...e.tn[1]);
78
78
  e.tn[0].length = 0;
@@ -109,7 +109,7 @@ function resolveTransition(n) {
109
109
  * Check if a node has an active optimistic override.
110
110
  */ function hasActiveOverride(n) {
111
111
  const e = n.o;
112
- return e !== null && e.Oe !== undefined && e.Oe !== NOT_PENDING;
112
+ return e !== null && e.Pe !== undefined && e.Pe !== NOT_PENDING;
113
113
  }
114
114
 
115
115
  /**