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

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.
@@ -95,7 +95,10 @@ function clearSnapshots() {
95
95
  if (snapshotSources) {
96
96
  for (const e of snapshotSources) {
97
97
  delete e.Ve;
98
- delete e[STORE_SNAPSHOT_PROPS];
98
+ // StoreNode targets share one pre-initialized hidden class (see
99
+ // createStoreProxy) — assign undefined instead of deleting, and only
100
+ // when present so signal-node sources don't grow the field.
101
+ if (e[STORE_SNAPSHOT_PROPS] !== undefined) e[STORE_SNAPSHOT_PROPS] = undefined;
99
102
  }
100
103
  snapshotSources = null;
101
104
  }
@@ -111,23 +114,23 @@ function recompute(e, t = false) {
111
114
  // Tracked effects run after finalizePureQueue, so dispose immediately instead of deferring
112
115
  if (e.Ue || n === EFFECT_TRACKED) disposeChildren(e); else if (e.me !== null || e.xe !== null) {
113
116
  markDisposal(e);
114
- e.ye = e.xe;
115
- e.Le = e.me;
117
+ e.Le = e.xe;
118
+ e.ye = e.me;
116
119
  e.xe = null;
117
120
  e.me = null;
118
121
  e.Qe = 0;
119
122
  } else ;
120
123
  }
121
124
  let i = !!(e.se & REACTIVE_OPTIMISTIC_DIRTY);
122
- const l = e.Ee !== undefined && e.Ee !== NOT_PENDING;
123
- const u = !!(e.S & STATUS_UNINITIALIZED);
125
+ const u = e.Ee !== undefined && e.Ee !== NOT_PENDING;
126
+ const l = !!(e.S & STATUS_UNINITIALIZED);
124
127
  // Re-ask classification lives in the verdict module; capture the flag before
125
128
  // the recompute wipes _flags below.
126
129
  const o = (e.se & REACTIVE_REASK) !== 0;
127
130
  const s = context;
128
131
  context = e;
129
132
  e.qe = null;
130
- e.Ye++;
133
+ e.We++;
131
134
  e.se = REACTIVE_RECOMPUTING_DEPS;
132
135
  e.ce = clock;
133
136
  let a = e.Ne === NOT_PENDING ? e.Pe : e.Ne;
@@ -141,27 +144,27 @@ function recompute(e, t = false) {
141
144
  // computed) inside latest(fn) came out permanently dependency-less (#2926).
142
145
  // latestRead() already suspends the flag for its pull-recomputes; this
143
146
  // covers creation-time computes and flushes that run inside the window.
144
- const E = latestReadActive;
147
+ const f = latestReadActive;
145
148
  latestReadActive = false;
146
149
  // Lane posture lives with the engine: OPTIMISTIC_DIRTY is only ever set by
147
150
  // engine-driven paths, and _optimisticNodes is only pushed by
148
151
  // _optimisticWrite, so the hook is installed whenever either gate holds.
149
152
  if (i) {
150
- const t = GlobalQueue.We(e, true);
153
+ const t = GlobalQueue.Ye(e, true);
151
154
  if (t) currentOptimisticLane = t;
152
155
  } else if (activeTransition && !t && activeTransition.Ze.length) {
153
156
  // Lane adoption: parent-deeper-than-owned-child can run before its OPT-dirty
154
157
  // child propagates. Walk deps once and inherit the OPT lane so this node
155
158
  // recomputes under the right posture and propagates correctly.
156
- const t = GlobalQueue.We(e, false);
159
+ const t = GlobalQueue.Ye(e, false);
157
160
  if (t) {
158
161
  i = true;
159
162
  currentOptimisticLane = t;
160
163
  }
161
164
  }
162
- const f = n && n !== EFFECT_USER;
165
+ const E = n && n !== EFFECT_USER;
163
166
  const N = stale;
164
- if (f) stale = true;
167
+ if (E) stale = true;
165
168
  try {
166
169
  if (!false && e.T & CONFIG_SYNC) {
167
170
  a = e.ke(a);
@@ -175,11 +178,14 @@ function recompute(e, t = false) {
175
178
  const t = e.Te;
176
179
  const n = e.ke(a);
177
180
  const i = typeof n === "object" && n !== null;
178
- const l = e.Te !== t;
179
- a = l || !i ? n : handleAsync(e, n);
180
- if (!l && !i) e.Te = null;
181
+ const u = e.Te !== t;
182
+ a = u || !i ? n : handleAsync(e, n);
183
+ if (!u && !i) e.Te = null;
181
184
  }
182
- clearStatus(e, t);
185
+ // On a status-free node clearStatus is a guaranteed no-op: every branch
186
+ // in its body is gated on one of these fields, and with _statusFlags === 0
187
+ // 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);
183
189
  // _optimisticLane is only ever assigned by engine paths.
184
190
  if (e.je) GlobalQueue.Me(e);
185
191
  } catch (t) {
@@ -195,17 +201,17 @@ function recompute(e, t = false) {
195
201
  if (n) GlobalQueue.k(e);
196
202
  } finally {
197
203
  tracking = c;
198
- latestReadActive = E;
199
- if (f) stale = N;
204
+ latestReadActive = f;
205
+ if (E) stale = N;
200
206
  e.se = REACTIVE_NONE | (t ? e.se & REACTIVE_SNAPSHOT_STALE : 0);
201
207
  context = s;
202
208
  }
203
209
  if (!e._) {
204
210
  trimStaleDeps(e);
205
- const o = l ? unwrapOverride(e.Ee) : e.Ne === NOT_PENDING ? e.Pe : e.Ne;
211
+ const o = u ? unwrapOverride(e.Ee) : e.Ne === NOT_PENDING ? e.Pe : e.Ne;
206
212
  let s = false;
207
213
  try {
208
- s = !n && u || !e.Re || !e.Re(o, a);
214
+ s = !n && l || !e.Re || !e.Re(o, a);
209
215
  } catch (t) {
210
216
  // A throwing user comparator is an error of this node's computation.
211
217
  // Route it through the same status path as a compute-phase throw so
@@ -225,14 +231,19 @@ function recompute(e, t = false) {
225
231
  if (!t) e.C.enqueue(n, e.Be ??= GlobalQueue.Je.bind(null, e));
226
232
  }
227
233
  if (e._) ; else if (s) {
228
- const u = l ? e.Ee : undefined;
229
- if (t || n && activeTransition !== e.Ue || i) {
234
+ const l = u ? e.Ee : undefined;
235
+ if (t ||
236
+ // Plain sync flush (no transition on either side) commits effect
237
+ // values directly — the pending round-trip (queuePendingNode +
238
+ // commitPendingNodes) exists to sequence transition reveals, and
239
+ // paying it per effect on the plain path is pure overhead.
240
+ n && (activeTransition !== e.Ue || activeTransition === null) || i) {
230
241
  e.Pe = a;
231
242
  // Lane-propagated correction: upstream data is fresh, correct the
232
243
  // override unconditionally. The direct _value commit is the lane's
233
244
  // own reveal schedule; drop any superseded older hold so its queued
234
245
  // commit can't clobber the fresh value.
235
- if (l && i) {
246
+ if (u && i) {
236
247
  e.Ee = a === undefined ? OVERRIDE_UNDEFINED : a;
237
248
  e.Ne = NOT_PENDING;
238
249
  }
@@ -245,8 +256,10 @@ function recompute(e, t = false) {
245
256
  // pending value commits before effects run.
246
257
  if ((activeTransition || e.Ue) && GlobalQueue.Ie !== null) GlobalQueue.Ie(e, a);
247
258
  }
248
- if (!l || i || e.Ee !== u) insertSubs(e, i || l);
249
- } else if (l) {
259
+ // insertSubs only walks _subs (no scheduling of its own), so a
260
+ // subscriber-less node has nothing to notify.
261
+ if (e.o !== null && (!u || i || e.Ee !== l)) insertSubs(e, i || u);
262
+ } else if (u) {
250
263
  // Unchanged value (equals the override) recomputed while the override
251
264
  // is active: _value may still be stale, so hold the authoritative value
252
265
  // for commit on its own transition's schedule — invisibly (A17/A18).
@@ -259,13 +272,13 @@ function recompute(e, t = false) {
259
272
  }
260
273
  }
261
274
  currentOptimisticLane = _;
262
- const T = e.Ne !== NOT_PENDING || e.Le !== null || e.ye !== null || (e.S & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
275
+ const T = e.Ne !== NOT_PENDING || e.ye !== null || e.Le !== null || (e.S & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
263
276
  // Override-covered holds (hasOverride) always queue: their commit belongs
264
277
  // to their own transition's schedule (A18 re-rule) and is unobservable
265
278
  // under the override (A17). Revert no longer commits anything, so an
266
279
  // unqueued covered hold would leak (INV-7) once the revert clears
267
280
  // _transition.
268
- T && (!t || e.S & STATUS_PENDING) && (!e.Ue || l) && queuePendingNode(e);
281
+ T && (!t || e.S & STATUS_PENDING) && (!e.Ue || u) && queuePendingNode(e);
269
282
  e.Ue && n && activeTransition !== e.Ue && runInTransition(e.Ue, () => recompute(e));
270
283
  }
271
284
 
@@ -303,11 +316,11 @@ function computed(e, t) {
303
316
  Pe: undefined,
304
317
  He: 0,
305
318
  u: null,
306
- lt: undefined,
307
- ut: null,
319
+ ut: undefined,
320
+ lt: null,
308
321
  Xe: null,
309
322
  qe: null,
310
- Ye: 0,
323
+ We: 0,
311
324
  o: null,
312
325
  ot: null,
313
326
  Ge: context,
@@ -318,8 +331,8 @@ function computed(e, t) {
318
331
  S: STATUS_UNINITIALIZED,
319
332
  ce: clock,
320
333
  Ne: NOT_PENDING,
321
- ye: null,
322
334
  Le: null,
335
+ ye: null,
323
336
  Te: null,
324
337
  Ue: null,
325
338
  _e: false
@@ -333,13 +346,13 @@ function computed(e, t) {
333
346
  * so V8 sees the full hidden class shape at construction time. Effects always run in lazy
334
347
  * mode (recompute is called explicitly by `effect()`), so we hardcode the lazy bits and skip
335
348
  * the auto-dispose CONFIG bit (effect() previously cleared it post-construction).
336
- */ function createEffectNode(e, t, n, i, l, u) {
337
- const o = u?.transparent ?? false;
349
+ */ function createEffectNode(e, t, n, i, u, l) {
350
+ const o = l?.transparent ?? false;
338
351
  const s = {
339
- id: inheritId(u, o, context),
340
- T: (o ? CONFIG_TRANSPARENT : 0) | (u?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (u?.sync ? CONFIG_SYNC : 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
352
+ id: inheritId(l, o, context),
353
+ T: (o ? CONFIG_TRANSPARENT : 0) | (l?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (l?.sync ? CONFIG_SYNC : 0) | (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
341
354
  Re: false,
342
- it: u?.unobserved,
355
+ it: l?.unobserved,
343
356
  xe: null,
344
357
  C: context?.C ?? globalQueue,
345
358
  we: context?.we ?? defaultContext,
@@ -348,11 +361,11 @@ function computed(e, t) {
348
361
  Pe: undefined,
349
362
  He: 0,
350
363
  u: null,
351
- lt: undefined,
352
- ut: null,
364
+ ut: undefined,
365
+ lt: null,
353
366
  Xe: null,
354
367
  qe: null,
355
- Ye: 0,
368
+ We: 0,
356
369
  o: null,
357
370
  ot: null,
358
371
  Ge: context,
@@ -363,8 +376,8 @@ function computed(e, t) {
363
376
  S: STATUS_UNINITIALIZED,
364
377
  ce: clock,
365
378
  Ne: NOT_PENDING,
366
- ye: null,
367
379
  Le: null,
380
+ ye: null,
368
381
  Te: null,
369
382
  Ue: null,
370
383
  _e: false,
@@ -372,9 +385,9 @@ function computed(e, t) {
372
385
  rt: undefined,
373
386
  ct: t,
374
387
  _t: n,
375
- Et: undefined,
388
+ ft: undefined,
376
389
  Ae: i,
377
- i: l
390
+ i: u
378
391
  };
379
392
  setupComputedNode(s, lazyOptions);
380
393
  return s;
@@ -385,8 +398,8 @@ const lazyOptions = {
385
398
  };
386
399
 
387
400
  function setupComputedNode(e, t) {
388
- e.ut = e;
389
- const n = context?.ft ? context.Nt : context;
401
+ e.lt = e;
402
+ const n = context?.Et ? context.Nt : context;
390
403
  if (context) {
391
404
  const t = context.me;
392
405
  if (t === null) {
@@ -493,59 +506,80 @@ function isEqual(e, t) {
493
506
  }
494
507
  }
495
508
 
509
+ /**
510
+ * Sentinel returned by readNodeFast when the plain-signal fast path does not
511
+ * apply and the caller must fall back to the full read().
512
+ */ const READ_SLOW = Symbol("read-slow");
513
+
514
+ /**
515
+ * read()'s plain-signal fast path as a standalone entry for hot callers
516
+ * (store traps). Safe to substitute for read() only because the bail
517
+ * conditions mirror read()'s prelude and fast-path guard exactly: the
518
+ * latestRead and pendingCheck windows run side-effectful hooks before the
519
+ * fast path, `_fn` nodes need prepareComputed, and firewall / override /
520
+ * snapshot / transition / lane / dev-strictRead state all take the full
521
+ * resolution. Anything slow returns READ_SLOW; the caller then calls read().
522
+ */ 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;
524
+ let t = context;
525
+ if (t?.Et) t = t.Nt;
526
+ if (t && tracking) link(e, t);
527
+ return !t || e.Ne === NOT_PENDING ? e.Pe : e.Ne;
528
+ }
529
+
496
530
  function read(e) {
497
531
  // Handle latest() mode: read from _latestValueComputed
498
532
  // Checked before isPending so that isPending(() => latest(x)) checks
499
533
  // the _pendingSignal of _latestValueComputed (async in flight) rather
500
534
  // than the original node (which stays "pending" while held in a transition).
501
- if (latestReadActive) return GlobalQueue.St(e);
535
+ if (latestReadActive) return GlobalQueue.dt(e);
502
536
  let t = context;
503
- if (t?.ft) t = t.Nt;
537
+ if (t?.Et) t = t.Nt;
504
538
  const n = e;
505
539
  const i = e.nt;
506
- const l = i || e;
540
+ const u = i || e;
507
541
  // Handle isPending() mode: collect pending state while preserving normal read semantics.
508
542
  // Probe mode is suspended while preparing the node so nested reads during a
509
543
  // recompute don't collect into the probe.
510
544
  if (pendingCheckActive) {
511
- GlobalQueue.dt(e, t, l, i);
545
+ GlobalQueue.St(e, t, u, i);
512
546
  } else if (typeof n.ke === "function") {
513
547
  prepareComputed(e, false);
514
548
  }
515
- if (!n.ke && l === e && e.Ee === undefined && e.Ve === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
549
+ if (!n.ke && u === e && e.Ee === undefined && e.Ve === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
516
550
  if (t && tracking) link(e, t);
517
551
  return !t || e.Ne === NOT_PENDING ? e.Pe : e.Ne;
518
552
  }
519
553
  if (t && tracking) {
520
554
  link(e, t, pendingCheckActive);
521
- if (l.ke) {
555
+ if (u.ke) {
522
556
  const n = queueFor(e);
523
- if (l.He >= n.Fe) {
557
+ if (u.He >= n.Fe) {
524
558
  markNode(t);
525
559
  markHeap(n);
526
- updateIfNecessary(l);
560
+ updateIfNecessary(u);
527
561
  }
528
- const i = l.He;
562
+ const i = u.He;
529
563
  // parent check is shallow, might need to be recursive
530
564
  if (i >= t.He && e.Ge !== t) {
531
565
  t.He = i + 1;
532
566
  }
533
567
  }
534
568
  }
535
- if (l.S & STATUS_PENDING) {
536
- if (t && !(stale && l.Ue && activeTransition !== l.Ue)) {
569
+ if (u.S & STATUS_PENDING) {
570
+ if (t && !(stale && u.Ue && activeTransition !== u.Ue)) {
537
571
  // Per-lane suspension lives with the engine (a non-null lane implies it
538
572
  // is installed): under a lane, only same-lane pending async without an
539
573
  // active override throws.
540
- if (currentOptimisticLane === null || GlobalQueue.At(l)) {
574
+ if (currentOptimisticLane === null || GlobalQueue.At(u)) {
541
575
  if (!tracking && e !== t) link(e, t);
542
- throw l._;
576
+ throw u._;
543
577
  }
544
- } else if (t && l !== e && l.S & STATUS_UNINITIALIZED) {
578
+ } else if (t && u !== e && u.S & STATUS_UNINITIALIZED) {
545
579
  if (!tracking && e !== t) link(e, t);
546
- throw l._;
547
- } else if (!t && l.S & STATUS_UNINITIALIZED) {
548
- throw l._;
580
+ throw u._;
581
+ } else if (!t && u.S & STATUS_UNINITIALIZED) {
582
+ throw u._;
549
583
  }
550
584
  }
551
585
  if (e.ke && e.S & STATUS_ERROR) {
@@ -562,8 +596,8 @@ function read(e) {
562
596
  const n = e.Ve;
563
597
  if (n !== undefined) {
564
598
  const i = n === NO_SNAPSHOT ? undefined : n;
565
- const l = e.Ne !== NOT_PENDING ? e.Ne : e.Pe;
566
- if (l !== i) t.se |= REACTIVE_SNAPSHOT_STALE;
599
+ const u = e.Ne !== NOT_PENDING ? e.Ne : e.Pe;
600
+ if (u !== i) t.se |= REACTIVE_SNAPSHOT_STALE;
567
601
  return i;
568
602
  }
569
603
  }
@@ -578,21 +612,21 @@ function read(e) {
578
612
  // _pendingValue for correct fetching. The sub is recorded for replay at commit
579
613
  // so it re-runs with the new committed view. (Gate details live with the
580
614
  // engine — a non-null lane implies it is installed.)
581
- if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.Ct(e, l, t)) {
615
+ if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.Ct(e, u, t)) {
582
616
  return e.Pe;
583
617
  }
584
618
  // In optimistic lane context, return _value for optimistic/lane-assigned signals
585
619
  // and for regular signals in stale mode (render effects). Non-stale readers (user
586
620
  // effects) see _pendingValue so that latest() and direct reads stay consistent.
587
621
  // (The lane-context clause lives with the engine.)
588
- const u = !t || currentOptimisticLane !== null && GlobalQueue.Ot(e, l, t) || e.Ne === NOT_PENDING || stale && e.Ue && activeTransition !== e.Ue ? e.Pe : e.Ne;
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;
589
623
  // Record that this isPending() probe observed the fresh pending value, so
590
624
  // the probe doesn't pair "pending" with the new value (#2831).
591
- if (pendingCheckActive) GlobalQueue.Rt(e, u);
592
- if (!t && l === e && typeof n.ke === "function" && e.T & CONFIG_AUTO_DISPOSE && !(l.S & STATUS_PENDING) && !e.o) {
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) {
593
627
  unobserved(e);
594
628
  }
595
- return u;
629
+ return l;
596
630
  }
597
631
 
598
632
  function setSignal(e, t) {
@@ -610,7 +644,10 @@ function setSignal(e, t) {
610
644
  if (!i) return t;
611
645
  if (e.Ne === NOT_PENDING) queuePendingNode(e);
612
646
  e.Ne = t;
613
- GlobalQueue.Ie !== null && GlobalQueue.Ie(e, t);
647
+ // syncCompanions only pokes _pendingSignal/_latestValueComputed — with
648
+ // neither companion present the call is a guaranteed no-op (companions are
649
+ // 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);
614
651
  e.ce = clock;
615
652
  insertSubs(e);
616
653
  schedule();
@@ -726,4 +763,4 @@ function staleValues(e, t = true) {
726
763
  }
727
764
  }
728
765
 
729
- export { clearSnapshots, computed, context, createEffectNode, currentOptimisticLane, isEqual, latestReadActive, markSnapshotScope, optimisticComputed, optimisticSignal, pendingCheckActive, prepareComputed, read, recompute, refresh, releaseSnapshotScope, runWithOwner, setContextInternal, setLatestReadActive, setMemo, setPendingCheckActive, setSignal, setSnapshotCapture, signal, snapshotCaptureActive, snapshotSources, stale, staleValues, suppressComputedRecompute, tracking, untrack };
766
+ export { READ_SLOW, clearSnapshots, computed, context, createEffectNode, currentOptimisticLane, isEqual, latestReadActive, markSnapshotScope, optimisticComputed, optimisticSignal, pendingCheckActive, prepareComputed, read, readNodeFast, recompute, refresh, releaseSnapshotScope, runWithOwner, setContextInternal, setLatestReadActive, setMemo, setPendingCheckActive, setSignal, setSnapshotCapture, signal, snapshotCaptureActive, snapshotSources, stale, staleValues, suppressComputedRecompute, tracking, untrack };
@@ -66,8 +66,8 @@ function runEffect(t) {
66
66
  t.$e = false;
67
67
  try {
68
68
  t._t ? t._t(E, () => {
69
- const E = t.Et;
70
- t.Et = undefined;
69
+ const E = t.ft;
70
+ t.ft = undefined;
71
71
  E?.();
72
72
  }) : console.error(E);
73
73
  } catch (E) {
@@ -78,14 +78,14 @@ function runEffect(t) {
78
78
  }
79
79
  return;
80
80
  }
81
- const E = t.Et;
82
- t.Et = undefined;
81
+ const E = t.ft;
82
+ t.ft = undefined;
83
83
  try {
84
84
  E?.();
85
85
  const e = t.ct(t.Pe, t.rt);
86
86
  if (false && e !== undefined && typeof e !== "function") ;
87
87
  // The final cleanup is invoked by disposeChildren at true disposal.
88
- t.Et = e;
88
+ t.ft = e;
89
89
  } catch (E) {
90
90
  t._ = new StatusError(t, E);
91
91
  t.S |= STATUS_ERROR;
@@ -114,16 +114,16 @@ GlobalQueue.Je = runEffect;
114
114
  } finally {}
115
115
  };
116
116
  const e = computed(() => {
117
- const E = e.Et;
118
- e.Et = undefined;
117
+ const E = e.ft;
118
+ e.ft = undefined;
119
119
  E?.();
120
120
  const R = staleValues(t);
121
- e.Et = R;
121
+ e.ft = R;
122
122
  }, {
123
123
  ...E,
124
124
  lazy: true
125
125
  });
126
- e.Et = undefined;
126
+ e.ft = undefined;
127
127
  e.T = e.T & ~CONFIG_AUTO_DISPOSE | CONFIG_CHILDREN_FORBIDDEN;
128
128
  e.$e = true;
129
129
  e.Ae = EFFECT_TRACKED;
@@ -25,7 +25,16 @@
25
25
  class NotReadyError extends Error {
26
26
  source;
27
27
  constructor(r) {
28
+ // Control-flow throw: it happens on every read of a pending source, so in
29
+ // production skip V8's eager stack capture (proportional to stack depth —
30
+ // real cost under SSR) by zeroing the V8-specific stackTraceLimit around
31
+ // super(). Dev keeps the stack for debuggability; non-V8 engines (no
32
+ // stackTraceLimit) take the plain path.
33
+ const o = Error;
34
+ const t = o.stackTraceLimit;
35
+ if (t !== undefined) o.stackTraceLimit = 0;
28
36
  super();
37
+ if (t !== undefined) o.stackTraceLimit = t;
29
38
  this.source = r;
30
39
  }
31
40
  }
@@ -69,7 +69,7 @@ function link(l, n, e = false) {
69
69
  if (t) {
70
70
  s = u !== null ? u.et : n.Xe;
71
71
  if (s !== null && s.tt === l) {
72
- s.nl = n.Ye;
72
+ s.nl = n.We;
73
73
  n.qe = s;
74
74
  // First touch of this pass: the previous pass's label is stale.
75
75
  s.De = e;
@@ -82,7 +82,7 @@ function link(l, n, e = false) {
82
82
  // (the old alien-signals `isValidLink` walk, O(n²) when a computation
83
83
  // re-reads earlier deps non-consecutively, e.g. store leaf reads).
84
84
  const i = l.ot;
85
- if (i !== null && i.le === n && (!t || i.nl === n.Ye)) {
85
+ if (i !== null && i.le === n && (!t || i.nl === n.We)) {
86
86
  // Gen-matched during a recompute = repeat touch this pass (AND); outside
87
87
  // a recompute there is no pass boundary, so the latest read labels it.
88
88
  if (t) i.De &&= e; else i.De = e;
@@ -94,7 +94,7 @@ function link(l, n, e = false) {
94
94
  et: s,
95
95
  ll: i,
96
96
  ue: null,
97
- nl: n.Ye,
97
+ nl: n.We,
98
98
  De: e
99
99
  };
100
100
  if (u !== null) u.et = o; else n.Xe = o;
@@ -25,15 +25,15 @@ import { zombieQueue, dirtyQueue } from "./scheduler.js";
25
25
  }
26
26
 
27
27
  function actualInsertIntoHeap(e, E) {
28
- const t = (e.Ge?.ft ? e.Ge.Nt?.He : e.Ge?.He) ?? -1;
28
+ const t = (e.Ge?.Et ? e.Ge.Nt?.He : e.Ge?.He) ?? -1;
29
29
  if (t >= e.He) e.He = t + 1;
30
30
  const n = e.He;
31
31
  const I = E.eE[n];
32
32
  if (I === undefined) E.eE[n] = e; else {
33
- const E = I.ut;
34
- E.lt = e;
35
- e.ut = E;
36
- I.ut = e;
33
+ const E = I.lt;
34
+ E.ut = e;
35
+ e.lt = E;
36
+ I.lt = e;
37
37
  }
38
38
  if (n > E.EE) E.EE = n;
39
39
  }
@@ -67,22 +67,22 @@ function deleteFromHeap(e, E) {
67
67
  if (!(t & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
68
68
  e.se = t & -25;
69
69
  const n = e.He;
70
- if (e.ut === e) E.eE[n] = undefined; else {
71
- const t = e.lt;
70
+ if (e.lt === e) E.eE[n] = undefined; else {
71
+ const t = e.ut;
72
72
  const I = E.eE[n];
73
73
  const o = t ?? I;
74
- if (e === I) E.eE[n] = t; else e.ut.lt = t;
75
- o.ut = e.ut;
74
+ if (e === I) E.eE[n] = t; else e.lt.ut = t;
75
+ o.lt = e.lt;
76
76
  }
77
- e.ut = e;
78
- e.lt = undefined;
77
+ e.lt = e;
78
+ e.ut = undefined;
79
79
  }
80
80
 
81
81
  function markHeap(e) {
82
82
  if (e.tE) return;
83
83
  e.tE = true;
84
84
  for (let E = 0; E <= e.EE; E++) {
85
- for (let t = e.eE[E]; t !== undefined; t = t.lt) {
85
+ for (let t = e.eE[E]; t !== undefined; t = t.ut) {
86
86
  if (t.se & REACTIVE_IN_HEAP) markNode(t);
87
87
  }
88
88
  }
@@ -52,7 +52,9 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
52
52
  // brand, and erasing it makes the write invisible and routes follow-up
53
53
  // writes off the optimistic path into permanent commits (#2898).
54
54
  e.Ee = n === undefined ? OVERRIDE_UNDEFINED : n;
55
- GlobalQueue.Ie !== null && GlobalQueue.Ie(e, n);
55
+ // syncCompanions only pokes _pendingSignal/_latestValueComputed — with
56
+ // neither companion present the call is a guaranteed no-op.
57
+ (e.be !== undefined || e.ge !== undefined) && GlobalQueue.Ie !== null && GlobalQueue.Ie(e, n);
56
58
  e.ce = clock;
57
59
  insertSubs(e, true);
58
60
  schedule();
@@ -216,13 +218,13 @@ function trackOptimisticStore(e) {
216
218
  if (GlobalQueue.Pt !== null) return;
217
219
  GlobalQueue.Pt = optimisticWrite;
218
220
  GlobalQueue.En = resolveOptimisticNodes;
219
- GlobalQueue.Tn = transitionBlocked;
220
- GlobalQueue.dn = cleanupCompletedLanes;
221
+ GlobalQueue.dn = transitionBlocked;
222
+ GlobalQueue.Tn = cleanupCompletedLanes;
221
223
  GlobalQueue.In = runLaneEffects;
222
224
  GlobalQueue.Ct = gatedRead;
223
225
  GlobalQueue.At = laneSuspends;
224
226
  GlobalQueue.Ot = laneReadsCommitted;
225
- GlobalQueue.We = recomputeLane;
227
+ GlobalQueue.Ye = recomputeLane;
226
228
  GlobalQueue.Ke = laneAsyncPending;
227
229
  GlobalQueue.Me = laneAsyncSettled;
228
230
  GlobalQueue.Nn = trackOptimisticStore;
@@ -54,7 +54,7 @@ function disposeChildren(e, n = false, t) {
54
54
  if (n.be || n.ge) GlobalQueue.un(n);
55
55
  }
56
56
  if (n && e.ke) e.Te = null;
57
- let l = t ? e.Le : e.me;
57
+ let l = t ? e.ye : e.me;
58
58
  while (l) {
59
59
  const e = l.ve;
60
60
  if (l.Xe) {
@@ -71,7 +71,7 @@ function disposeChildren(e, n = false, t) {
71
71
  l = e;
72
72
  }
73
73
  if (t) {
74
- e.Le = null;
74
+ e.ye = null;
75
75
  } else {
76
76
  e.me = null;
77
77
  e.Qe = 0;
@@ -90,15 +90,15 @@ function disposeChildren(e, n = false, t) {
90
90
  runDisposal(e, t);
91
91
  // Final effect-returned cleanup fires at true disposal, after `_disposal`
92
92
  // to mirror rerun ordering (compute-phase teardown first, cleanup last).
93
- if (n && e.Et) {
94
- const n = e.Et;
95
- e.Et = undefined;
93
+ if (n && e.ft) {
94
+ const n = e.ft;
95
+ e.ft = undefined;
96
96
  n();
97
97
  }
98
98
  }
99
99
 
100
100
  function runDisposal(e, n) {
101
- let t = n ? e.ye : e.xe;
101
+ let t = n ? e.Le : e.xe;
102
102
  if (!t) return;
103
103
  if (Array.isArray(t)) {
104
104
  for (let e = 0; e < t.length; e++) {
@@ -108,7 +108,7 @@ function runDisposal(e, n) {
108
108
  } else {
109
109
  t.call(t);
110
110
  }
111
- n ? e.ye = null : e.xe = null;
111
+ n ? e.Le = null : e.xe = null;
112
112
  }
113
113
 
114
114
  function childId(e, n) {
@@ -235,8 +235,8 @@ function disposeRootSelf(e = true) {
235
235
  const i = {
236
236
  id: inheritId(e, t, n),
237
237
  T: t ? CONFIG_TRANSPARENT : 0,
238
- ft: true,
239
- Nt: n?.ft ? n.Nt : n,
238
+ Et: true,
239
+ Nt: n?.Et ? n.Nt : n,
240
240
  me: null,
241
241
  ve: null,
242
242
  st: null,
@@ -244,8 +244,8 @@ function disposeRootSelf(e = true) {
244
244
  C: n?.C ?? globalQueue,
245
245
  we: n?.we || defaultContext,
246
246
  Qe: 0,
247
- ye: null,
248
247
  Le: null,
248
+ ye: null,
249
249
  Ge: n,
250
250
  dispose: disposeRootSelf
251
251
  };