@solidjs/signals 2.0.0-beta.25 → 2.0.0-beta.26
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.
- package/dist/dev.js +113 -7
- package/dist/node.cjs +140 -41
- package/dist/prod/core/async.js +180 -107
- package/dist/prod/core/core.js +162 -162
- package/dist/prod/core/effect.js +28 -28
- package/dist/prod/core/external.js +4 -4
- package/dist/prod/core/graph.js +28 -28
- package/dist/prod/core/heap.js +30 -30
- package/dist/prod/core/lanes.js +15 -15
- package/dist/prod/core/optimistic.js +38 -38
- package/dist/prod/core/owner.js +44 -44
- package/dist/prod/core/scheduler.js +94 -94
- package/dist/prod/core/verdict.js +55 -55
- package/dist/prod/map.js +60 -60
- package/dist/prod/signals.js +1 -1
- package/dist/prod/store/optimistic.js +6 -6
- package/dist/prod/store/reconcile.js +1 -1
- package/dist/prod/store/store.js +58 -32
- package/dist/types/core/async.d.ts +1 -0
- package/dist/types-cjs/core/async.d.cts +1 -0
- package/package.json +1 -1
package/dist/prod/core/core.js
CHANGED
|
@@ -48,8 +48,8 @@ let snapshotSources = null;
|
|
|
48
48
|
|
|
49
49
|
function ownerInSnapshotScope(e) {
|
|
50
50
|
while (e) {
|
|
51
|
-
if (e.
|
|
52
|
-
e = e.
|
|
51
|
+
if (e.me) 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.
|
|
63
|
+
e.me = true;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function releaseSnapshotScope(e) {
|
|
67
|
-
e.
|
|
67
|
+
e.me = false;
|
|
68
68
|
releaseSubtree(e);
|
|
69
69
|
schedule();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
function releaseSubtree(e) {
|
|
73
|
-
let t = e.
|
|
73
|
+
let t = e.ke;
|
|
74
74
|
while (t) {
|
|
75
|
-
if (t.
|
|
76
|
-
t = t.
|
|
75
|
+
if (t.me) {
|
|
76
|
+
t = t.Fe;
|
|
77
77
|
continue;
|
|
78
78
|
}
|
|
79
|
-
if (t.
|
|
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.
|
|
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.
|
|
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.
|
|
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,35 +106,35 @@ function clearSnapshots() {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
function recompute(e, t = false) {
|
|
109
|
-
const n = e.
|
|
109
|
+
const n = e.Pe;
|
|
110
110
|
if (!t) {
|
|
111
|
-
if (e.
|
|
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.
|
|
115
|
+
if (e.Ie || n === EFFECT_TRACKED) disposeChildren(e); else if (e.ke !== null || e.Le !== null) {
|
|
116
116
|
markDisposal(e);
|
|
117
|
-
e.
|
|
118
|
-
e.
|
|
119
|
-
e.
|
|
120
|
-
e.
|
|
121
|
-
e.
|
|
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.
|
|
125
|
+
const u = e.Ae !== undefined && e.Ae !== NOT_PENDING;
|
|
126
126
|
const l = !!(e.S & STATUS_UNINITIALIZED);
|
|
127
127
|
// Re-ask classification lives in the verdict module; capture the flag before
|
|
128
128
|
// the recompute wipes _flags below.
|
|
129
129
|
const o = (e.se & REACTIVE_REASK) !== 0;
|
|
130
130
|
const s = context;
|
|
131
131
|
context = e;
|
|
132
|
-
e.
|
|
133
|
-
e.
|
|
132
|
+
e.We = null;
|
|
133
|
+
e.Ye++;
|
|
134
134
|
e.se = REACTIVE_RECOMPUTING_DEPS;
|
|
135
|
-
e.
|
|
136
|
-
let a = e.
|
|
137
|
-
let r = e.
|
|
135
|
+
e.Se = clock;
|
|
136
|
+
let a = e._e === NOT_PENDING ? e.Ue : e._e;
|
|
137
|
+
let r = e.Ve;
|
|
138
138
|
let c = tracking;
|
|
139
139
|
let _ = currentOptimisticLane;
|
|
140
140
|
tracking = true;
|
|
@@ -150,13 +150,13 @@ function recompute(e, t = false) {
|
|
|
150
150
|
// engine-driven paths, and _optimisticNodes is only pushed by
|
|
151
151
|
// _optimisticWrite, so the hook is installed whenever either gate holds.
|
|
152
152
|
if (i) {
|
|
153
|
-
const t = GlobalQueue.
|
|
153
|
+
const t = GlobalQueue.Ze(e, true);
|
|
154
154
|
if (t) currentOptimisticLane = t;
|
|
155
|
-
} else if (activeTransition && !t && activeTransition.
|
|
155
|
+
} else if (activeTransition && !t && activeTransition.je.length) {
|
|
156
156
|
// Lane adoption: parent-deeper-than-owned-child can run before its OPT-dirty
|
|
157
157
|
// child propagates. Walk deps once and inherit the OPT lane so this node
|
|
158
158
|
// recomputes under the right posture and propagates correctly.
|
|
159
|
-
const t = GlobalQueue.
|
|
159
|
+
const t = GlobalQueue.Ze(e, false);
|
|
160
160
|
if (t) {
|
|
161
161
|
i = true;
|
|
162
162
|
currentOptimisticLane = t;
|
|
@@ -167,7 +167,7 @@ function recompute(e, t = false) {
|
|
|
167
167
|
if (E) stale = true;
|
|
168
168
|
try {
|
|
169
169
|
if (!false && e.T & CONFIG_SYNC) {
|
|
170
|
-
a = e.
|
|
170
|
+
a = e.ae(a);
|
|
171
171
|
e.Te = null;
|
|
172
172
|
} else {
|
|
173
173
|
// Snapshot `_inFlight` so we can detect whether `_fn` self-registered an async
|
|
@@ -176,7 +176,7 @@ function recompute(e, t = false) {
|
|
|
176
176
|
// clobber the fresh subscription, so we skip it and let the internally-registered
|
|
177
177
|
// iteration drive updates.
|
|
178
178
|
const t = e.Te;
|
|
179
|
-
const n = e.
|
|
179
|
+
const n = e.ae(a);
|
|
180
180
|
const i = typeof n === "object" && n !== null;
|
|
181
181
|
const u = e.Te !== t;
|
|
182
182
|
a = u || !i ? n : handleAsync(e, n);
|
|
@@ -185,19 +185,19 @@ function recompute(e, t = false) {
|
|
|
185
185
|
// On a status-free node clearStatus is a guaranteed no-op: every branch
|
|
186
186
|
// in its body is gated on one of these fields, and with _statusFlags === 0
|
|
187
187
|
// the flags write (create or not) stores the 0 already there.
|
|
188
|
-
if (e.S !== 0 || e.i !== undefined || e._ || e.
|
|
188
|
+
if (e.S !== 0 || e.i !== undefined || e._ || e.be || e.de || e.oe !== undefined || e.he !== undefined || e.Ge !== undefined || e.u !== null) clearStatus(e, t);
|
|
189
189
|
// _optimisticLane is only ever assigned by engine paths.
|
|
190
|
-
if (e.
|
|
190
|
+
if (e.Me) GlobalQueue.Ke(e);
|
|
191
191
|
} catch (t) {
|
|
192
192
|
// Track pending async in the lane (not the lane's source — it creates the lane
|
|
193
193
|
// but doesn't belong to it). Set lane BEFORE notifyStatus for downstream propagation.
|
|
194
|
-
if (t instanceof NotReadyError && currentOptimisticLane) GlobalQueue.
|
|
194
|
+
if (t instanceof NotReadyError && currentOptimisticLane) GlobalQueue.ze(e);
|
|
195
195
|
let n = false;
|
|
196
196
|
if (t instanceof NotReadyError) {
|
|
197
|
-
e.
|
|
198
|
-
if (GlobalQueue
|
|
197
|
+
e.de = true;
|
|
198
|
+
if (GlobalQueue.$e !== null) n = GlobalQueue.$e(e, o);
|
|
199
199
|
}
|
|
200
|
-
notifyStatus(e, t instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, t, undefined, t instanceof NotReadyError ? e.
|
|
200
|
+
notifyStatus(e, t instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, t, undefined, t instanceof NotReadyError ? e.Me : undefined);
|
|
201
201
|
if (n) GlobalQueue.k(e);
|
|
202
202
|
} finally {
|
|
203
203
|
tracking = c;
|
|
@@ -208,7 +208,7 @@ function recompute(e, t = false) {
|
|
|
208
208
|
}
|
|
209
209
|
if (!e._) {
|
|
210
210
|
trimStaleDeps(e);
|
|
211
|
-
const o = u ? unwrapOverride(e.
|
|
211
|
+
const o = u ? unwrapOverride(e.Ae) : e._e === NOT_PENDING ? e.Ue : e._e;
|
|
212
212
|
let s = false;
|
|
213
213
|
try {
|
|
214
214
|
s = !n && l || !e.Re || !e.Re(o, a);
|
|
@@ -225,69 +225,69 @@ function recompute(e, t = false) {
|
|
|
225
225
|
// gate: the explicit recompute(node, true) inside effect() does not enqueue, so
|
|
226
226
|
// effect() can call its runner synchronously for the first run.
|
|
227
227
|
if (n && s) {
|
|
228
|
-
e
|
|
228
|
+
e.Be = !e._;
|
|
229
229
|
// Reuse one bound runner per effect — runEffect no-ops on a stale
|
|
230
230
|
// `_modified`, so re-enqueueing the same function is harmless.
|
|
231
|
-
if (!t) e.C.enqueue(n, e.
|
|
231
|
+
if (!t) e.C.enqueue(n, e.Je ??= GlobalQueue.Xe.bind(null, e));
|
|
232
232
|
}
|
|
233
233
|
if (e._) ; else if (s) {
|
|
234
|
-
const l = u ? e.
|
|
234
|
+
const l = u ? e.Ae : undefined;
|
|
235
235
|
if (t ||
|
|
236
236
|
// Plain sync flush (no transition on either side) commits effect
|
|
237
237
|
// values directly — the pending round-trip (queuePendingNode +
|
|
238
238
|
// commitPendingNodes) exists to sequence transition reveals, and
|
|
239
239
|
// paying it per effect on the plain path is pure overhead.
|
|
240
|
-
n && (activeTransition !== e.
|
|
241
|
-
e.
|
|
240
|
+
n && (activeTransition !== e.Ie || activeTransition === null) || i) {
|
|
241
|
+
e.Ue = a;
|
|
242
242
|
// Lane-propagated correction: upstream data is fresh, correct the
|
|
243
243
|
// override unconditionally. The direct _value commit is the lane's
|
|
244
244
|
// own reveal schedule; drop any superseded older hold so its queued
|
|
245
245
|
// commit can't clobber the fresh value.
|
|
246
246
|
if (u && i) {
|
|
247
|
-
e.
|
|
248
|
-
e.
|
|
247
|
+
e.Ae = a === undefined ? OVERRIDE_UNDEFINED : a;
|
|
248
|
+
e._e = NOT_PENDING;
|
|
249
249
|
}
|
|
250
250
|
} else {
|
|
251
|
-
e.
|
|
251
|
+
e._e = a;
|
|
252
252
|
// Transition-held sync recompute is a write path like setSignal/asyncWrite,
|
|
253
253
|
// so sync derivations of held sources stay visible to isPending()/latest()
|
|
254
254
|
// (#2831). Both companion writes are transition-scoped (optimistic) and
|
|
255
255
|
// auto-revert/re-derive at commit. Skipped for plain flushes where the
|
|
256
256
|
// pending value commits before effects run.
|
|
257
|
-
if ((activeTransition || e.
|
|
257
|
+
if ((activeTransition || e.Ie) && GlobalQueue.De !== null) GlobalQueue.De(e, a);
|
|
258
258
|
}
|
|
259
259
|
// insertSubs only walks _subs (no scheduling of its own), so a
|
|
260
260
|
// subscriber-less node has nothing to notify.
|
|
261
|
-
if (e.o !== null && (!u || i || e.
|
|
261
|
+
if (e.o !== null && (!u || i || e.Ae !== l)) insertSubs(e, i || u);
|
|
262
262
|
} else if (u) {
|
|
263
263
|
// Unchanged value (equals the override) recomputed while the override
|
|
264
264
|
// is active: _value may still be stale, so hold the authoritative value
|
|
265
265
|
// for commit on its own transition's schedule — invisibly (A17/A18).
|
|
266
|
-
if (e.
|
|
267
|
-
e.
|
|
268
|
-
} else if (e.
|
|
266
|
+
if (e._e === NOT_PENDING) queuePendingNode(e);
|
|
267
|
+
e._e = a;
|
|
268
|
+
} else if (e.Ve != r) {
|
|
269
269
|
for (let t = e.o; t !== null; t = t.ue) {
|
|
270
270
|
insertIntoHeapHeight(t.le, queueFor(t.le));
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
currentOptimisticLane = _;
|
|
275
|
-
const T = e.
|
|
275
|
+
const T = e._e !== NOT_PENDING || e.Qe !== null || e.ye !== null || (e.S & (STATUS_PENDING | STATUS_UNINITIALIZED)) !== 0;
|
|
276
276
|
// Override-covered holds (hasOverride) always queue: their commit belongs
|
|
277
277
|
// to their own transition's schedule (A18 re-rule) and is unobservable
|
|
278
278
|
// under the override (A17). Revert no longer commits anything, so an
|
|
279
279
|
// unqueued covered hold would leak (INV-7) once the revert clears
|
|
280
280
|
// _transition.
|
|
281
|
-
T && (!t || e.S & STATUS_PENDING) && (!e.
|
|
282
|
-
e.
|
|
281
|
+
T && (!t || e.S & STATUS_PENDING) && (!e.Ie || u) && queuePendingNode(e);
|
|
282
|
+
e.Ie && n && activeTransition !== e.Ie && runInTransition(e.Ie, () => recompute(e));
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
function updateIfNecessary(e) {
|
|
286
286
|
if (e.se & REACTIVE_CHECK) {
|
|
287
|
-
for (let t = e.
|
|
288
|
-
const n = t.
|
|
289
|
-
const i = n.
|
|
290
|
-
if (i.
|
|
287
|
+
for (let t = e.et; t; t = t.tt) {
|
|
288
|
+
const n = t.nt;
|
|
289
|
+
const i = n.it || n;
|
|
290
|
+
if (i.ae) {
|
|
291
291
|
updateIfNecessary(i);
|
|
292
292
|
}
|
|
293
293
|
if (e.se & REACTIVE_DIRTY) {
|
|
@@ -295,7 +295,7 @@ function updateIfNecessary(e) {
|
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
|
-
if (e.se & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY) || e._ && e.
|
|
298
|
+
if (e.se & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY) || e._ && e.Se < clock && !e.Te) {
|
|
299
299
|
recompute(e);
|
|
300
300
|
}
|
|
301
301
|
e.se = e.se & (REACTIVE_SNAPSHOT_STALE | REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT);
|
|
@@ -307,35 +307,35 @@ function computed(e, t) {
|
|
|
307
307
|
id: inheritId(t, n, context),
|
|
308
308
|
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
309
|
Re: t?.equals != null ? t.equals : isEqual,
|
|
310
|
-
|
|
311
|
-
|
|
310
|
+
ut: t?.unobserved,
|
|
311
|
+
Le: null,
|
|
312
312
|
C: context?.C ?? globalQueue,
|
|
313
313
|
we: context?.we ?? defaultContext,
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
314
|
+
qe: 0,
|
|
315
|
+
ae: e,
|
|
316
|
+
Ue: undefined,
|
|
317
|
+
Ve: 0,
|
|
318
318
|
u: null,
|
|
319
|
-
|
|
320
|
-
lt: null,
|
|
321
|
-
Xe: null,
|
|
322
|
-
qe: null,
|
|
323
|
-
We: 0,
|
|
324
|
-
o: null,
|
|
319
|
+
lt: undefined,
|
|
325
320
|
ot: null,
|
|
326
|
-
|
|
327
|
-
|
|
321
|
+
et: null,
|
|
322
|
+
We: null,
|
|
323
|
+
Ye: 0,
|
|
324
|
+
o: null,
|
|
328
325
|
st: null,
|
|
329
|
-
|
|
326
|
+
ve: context,
|
|
327
|
+
Fe: null,
|
|
328
|
+
rt: null,
|
|
329
|
+
ke: null,
|
|
330
330
|
se: t?.lazy ? REACTIVE_LAZY : REACTIVE_NONE,
|
|
331
331
|
S: STATUS_UNINITIALIZED,
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
Le: null,
|
|
332
|
+
Se: clock,
|
|
333
|
+
_e: NOT_PENDING,
|
|
335
334
|
ye: null,
|
|
335
|
+
Qe: null,
|
|
336
336
|
Te: null,
|
|
337
|
-
|
|
338
|
-
|
|
337
|
+
Ie: null,
|
|
338
|
+
be: false
|
|
339
339
|
};
|
|
340
340
|
setupComputedNode(i, t);
|
|
341
341
|
return i;
|
|
@@ -352,41 +352,41 @@ function computed(e, t) {
|
|
|
352
352
|
id: inheritId(l, o, context),
|
|
353
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),
|
|
354
354
|
Re: false,
|
|
355
|
-
|
|
356
|
-
|
|
355
|
+
ut: l?.unobserved,
|
|
356
|
+
Le: null,
|
|
357
357
|
C: context?.C ?? globalQueue,
|
|
358
358
|
we: context?.we ?? defaultContext,
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
359
|
+
qe: 0,
|
|
360
|
+
ae: e,
|
|
361
|
+
Ue: undefined,
|
|
362
|
+
Ve: 0,
|
|
363
363
|
u: null,
|
|
364
|
-
|
|
365
|
-
lt: null,
|
|
366
|
-
Xe: null,
|
|
367
|
-
qe: null,
|
|
368
|
-
We: 0,
|
|
369
|
-
o: null,
|
|
364
|
+
lt: undefined,
|
|
370
365
|
ot: null,
|
|
371
|
-
|
|
372
|
-
|
|
366
|
+
et: null,
|
|
367
|
+
We: null,
|
|
368
|
+
Ye: 0,
|
|
369
|
+
o: null,
|
|
373
370
|
st: null,
|
|
374
|
-
|
|
371
|
+
ve: context,
|
|
372
|
+
Fe: null,
|
|
373
|
+
rt: null,
|
|
374
|
+
ke: null,
|
|
375
375
|
se: REACTIVE_LAZY,
|
|
376
376
|
S: STATUS_UNINITIALIZED,
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
Le: null,
|
|
377
|
+
Se: clock,
|
|
378
|
+
_e: NOT_PENDING,
|
|
380
379
|
ye: null,
|
|
380
|
+
Qe: null,
|
|
381
381
|
Te: null,
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
382
|
+
Ie: null,
|
|
383
|
+
be: false,
|
|
384
|
+
Be: false,
|
|
385
|
+
ct: undefined,
|
|
386
|
+
_t: t,
|
|
387
|
+
ft: n,
|
|
388
|
+
Et: undefined,
|
|
389
|
+
Pe: i,
|
|
390
390
|
i: u
|
|
391
391
|
};
|
|
392
392
|
setupComputedNode(s, lazyOptions);
|
|
@@ -398,24 +398,24 @@ const lazyOptions = {
|
|
|
398
398
|
};
|
|
399
399
|
|
|
400
400
|
function setupComputedNode(e, t) {
|
|
401
|
-
e.
|
|
402
|
-
const n = context?.
|
|
401
|
+
e.ot = e;
|
|
402
|
+
const n = context?.Nt ? context.Tt : context;
|
|
403
403
|
if (context) {
|
|
404
|
-
const t = context.
|
|
404
|
+
const t = context.ke;
|
|
405
405
|
if (t === null) {
|
|
406
|
-
context.
|
|
406
|
+
context.ke = e;
|
|
407
407
|
} else {
|
|
408
|
-
e.
|
|
409
|
-
t.
|
|
410
|
-
context.
|
|
408
|
+
e.Fe = t;
|
|
409
|
+
t.rt = e;
|
|
410
|
+
context.ke = e;
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
|
-
if (n) e.
|
|
414
|
-
if (GlobalQueue.
|
|
413
|
+
if (n) e.Ve = n.Ve + 1;
|
|
414
|
+
if (GlobalQueue.It !== null) GlobalQueue.It(e);
|
|
415
415
|
!t?.lazy && recompute(e, true);
|
|
416
416
|
if (snapshotCaptureActive && !t?.lazy) {
|
|
417
417
|
if (!(e.S & STATUS_PENDING) && !(e.T & CONFIG_NO_SNAPSHOT)) {
|
|
418
|
-
e.
|
|
418
|
+
e.xe = e.Ue === undefined ? NO_SNAPSHOT : e.Ue;
|
|
419
419
|
snapshotSources.add(e);
|
|
420
420
|
}
|
|
421
421
|
}
|
|
@@ -425,18 +425,18 @@ function signal(e, t, n = null) {
|
|
|
425
425
|
const i = {
|
|
426
426
|
Re: t?.equals != null ? t.equals : isEqual,
|
|
427
427
|
T: (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (t?.V ? CONFIG_NO_SNAPSHOT : 0),
|
|
428
|
-
|
|
429
|
-
|
|
428
|
+
ut: t?.unobserved,
|
|
429
|
+
Ue: e,
|
|
430
430
|
o: null,
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
431
|
+
st: null,
|
|
432
|
+
Se: clock,
|
|
433
|
+
it: n,
|
|
434
434
|
fe: n?.u || null,
|
|
435
|
-
|
|
435
|
+
_e: NOT_PENDING
|
|
436
436
|
};
|
|
437
437
|
n && (n.u = i);
|
|
438
438
|
if (snapshotCaptureActive && !(i.T & CONFIG_NO_SNAPSHOT) && !((n?.S ?? 0) & STATUS_PENDING)) {
|
|
439
|
-
i.
|
|
439
|
+
i.xe = e === undefined ? NO_SNAPSHOT : e;
|
|
440
440
|
snapshotSources.add(i);
|
|
441
441
|
}
|
|
442
442
|
return i;
|
|
@@ -444,13 +444,13 @@ function signal(e, t, n = null) {
|
|
|
444
444
|
|
|
445
445
|
function optimisticSignal(e, t) {
|
|
446
446
|
const n = signal(e, t);
|
|
447
|
-
n.
|
|
447
|
+
n.Ae = NOT_PENDING;
|
|
448
448
|
return n;
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
function optimisticComputed(e, t) {
|
|
452
452
|
const n = computed(e, t);
|
|
453
|
-
n.
|
|
453
|
+
n.Ae = NOT_PENDING;
|
|
454
454
|
return n;
|
|
455
455
|
}
|
|
456
456
|
|
|
@@ -480,11 +480,11 @@ function isEqual(e, t) {
|
|
|
480
480
|
* );
|
|
481
481
|
* ```
|
|
482
482
|
*/ function untrack(e, t) {
|
|
483
|
-
if (GlobalQueue.
|
|
483
|
+
if (GlobalQueue.dt === null && !tracking && true) return e();
|
|
484
484
|
const n = tracking;
|
|
485
485
|
tracking = false;
|
|
486
486
|
try {
|
|
487
|
-
if (GlobalQueue.
|
|
487
|
+
if (GlobalQueue.dt !== null) return GlobalQueue.dt(e);
|
|
488
488
|
return e();
|
|
489
489
|
} finally {
|
|
490
490
|
tracking = n;
|
|
@@ -520,11 +520,11 @@ function isEqual(e, t) {
|
|
|
520
520
|
* snapshot / transition / lane / dev-strictRead state all take the full
|
|
521
521
|
* resolution. Anything slow returns READ_SLOW; the caller then calls read().
|
|
522
522
|
*/ function readNodeFast(e) {
|
|
523
|
-
if (latestReadActive || pendingCheckActive || e.
|
|
523
|
+
if (latestReadActive || pendingCheckActive || e.ae || e.it || e.Ae !== undefined || e.xe !== undefined || activeTransition !== null || currentOptimisticLane !== null || snapshotCaptureActive || false) return READ_SLOW;
|
|
524
524
|
let t = context;
|
|
525
|
-
if (t?.
|
|
525
|
+
if (t?.Nt) t = t.Tt;
|
|
526
526
|
if (t && tracking) link(e, t);
|
|
527
|
-
return !t || e.
|
|
527
|
+
return !t || e._e === NOT_PENDING ? e.Ue : e._e;
|
|
528
528
|
}
|
|
529
529
|
|
|
530
530
|
function read(e) {
|
|
@@ -532,46 +532,46 @@ function read(e) {
|
|
|
532
532
|
// Checked before isPending so that isPending(() => latest(x)) checks
|
|
533
533
|
// the _pendingSignal of _latestValueComputed (async in flight) rather
|
|
534
534
|
// than the original node (which stays "pending" while held in a transition).
|
|
535
|
-
if (latestReadActive) return GlobalQueue.
|
|
535
|
+
if (latestReadActive) return GlobalQueue.St(e);
|
|
536
536
|
let t = context;
|
|
537
|
-
if (t?.
|
|
537
|
+
if (t?.Nt) t = t.Tt;
|
|
538
538
|
const n = e;
|
|
539
|
-
const i = e.
|
|
539
|
+
const i = e.it;
|
|
540
540
|
const u = i || e;
|
|
541
541
|
// Handle isPending() mode: collect pending state while preserving normal read semantics.
|
|
542
542
|
// Probe mode is suspended while preparing the node so nested reads during a
|
|
543
543
|
// recompute don't collect into the probe.
|
|
544
544
|
if (pendingCheckActive) {
|
|
545
|
-
GlobalQueue.
|
|
546
|
-
} else if (typeof n.
|
|
545
|
+
GlobalQueue.At(e, t, u, i);
|
|
546
|
+
} else if (typeof n.ae === "function") {
|
|
547
547
|
prepareComputed(e, false);
|
|
548
548
|
}
|
|
549
|
-
if (!n.
|
|
549
|
+
if (!n.ae && u === e && e.Ae === undefined && e.xe === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
|
|
550
550
|
if (t && tracking) link(e, t);
|
|
551
|
-
return !t || e.
|
|
551
|
+
return !t || e._e === NOT_PENDING ? e.Ue : e._e;
|
|
552
552
|
}
|
|
553
553
|
if (t && tracking) {
|
|
554
554
|
link(e, t, pendingCheckActive);
|
|
555
|
-
if (u.
|
|
555
|
+
if (u.ae) {
|
|
556
556
|
const n = queueFor(e);
|
|
557
|
-
if (u.
|
|
557
|
+
if (u.Ve >= n.He) {
|
|
558
558
|
markNode(t);
|
|
559
559
|
markHeap(n);
|
|
560
560
|
updateIfNecessary(u);
|
|
561
561
|
}
|
|
562
|
-
const i = u.
|
|
562
|
+
const i = u.Ve;
|
|
563
563
|
// parent check is shallow, might need to be recursive
|
|
564
|
-
if (i >= t.
|
|
565
|
-
t.
|
|
564
|
+
if (i >= t.Ve && e.ve !== t) {
|
|
565
|
+
t.Ve = i + 1;
|
|
566
566
|
}
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
569
|
if (u.S & STATUS_PENDING) {
|
|
570
|
-
if (t && !(stale && u.
|
|
570
|
+
if (t && !(stale && u.Ie && activeTransition !== u.Ie)) {
|
|
571
571
|
// Per-lane suspension lives with the engine (a non-null lane implies it
|
|
572
572
|
// is installed): under a lane, only same-lane pending async without an
|
|
573
573
|
// active override throws.
|
|
574
|
-
if (currentOptimisticLane === null || GlobalQueue.
|
|
574
|
+
if (currentOptimisticLane === null || GlobalQueue.Ct(u)) {
|
|
575
575
|
if (!tracking && e !== t) link(e, t);
|
|
576
576
|
throw u._;
|
|
577
577
|
}
|
|
@@ -582,28 +582,28 @@ function read(e) {
|
|
|
582
582
|
throw u._;
|
|
583
583
|
}
|
|
584
584
|
}
|
|
585
|
-
if (e.
|
|
585
|
+
if (e.ae && e.S & STATUS_ERROR) {
|
|
586
586
|
// Only a genuine reactive re-read may retry an errored async source:
|
|
587
587
|
// - tracking: owned/tracked scope only (never events / `untrack` / effect side-effect phase)
|
|
588
588
|
// - !pendingCheckActive: an `isPending` probe observes the error, never refetches
|
|
589
589
|
// - el._time < clock: only on a later cycle than the one the error was found
|
|
590
|
-
if (tracking && !pendingCheckActive && e.
|
|
590
|
+
if (tracking && !pendingCheckActive && e.Se < clock) {
|
|
591
591
|
recompute(e);
|
|
592
592
|
return read(e);
|
|
593
593
|
} else throw e._;
|
|
594
594
|
}
|
|
595
595
|
if (snapshotCaptureActive && t && t.T & CONFIG_IN_SNAPSHOT_SCOPE) {
|
|
596
|
-
const n = e.
|
|
596
|
+
const n = e.xe;
|
|
597
597
|
if (n !== undefined) {
|
|
598
598
|
const i = n === NO_SNAPSHOT ? undefined : n;
|
|
599
|
-
const u = e.
|
|
599
|
+
const u = e._e !== NOT_PENDING ? e._e : e.Ue;
|
|
600
600
|
if (u !== i) t.se |= REACTIVE_SNAPSHOT_STALE;
|
|
601
601
|
return i;
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
|
-
if (e.
|
|
604
|
+
if (e.Ae !== undefined && e.Ae !== NOT_PENDING) {
|
|
605
605
|
// A17: the override IS the value for every reader.
|
|
606
|
-
return unwrapOverride(e.
|
|
606
|
+
return unwrapOverride(e.Ae);
|
|
607
607
|
}
|
|
608
608
|
// Entanglement gate: a reader recomputing under an optimistic lane that reads
|
|
609
609
|
// a pending mid-transition write sees the committed value. Projection-store
|
|
@@ -612,43 +612,43 @@ function read(e) {
|
|
|
612
612
|
// _pendingValue for correct fetching. The sub is recorded for replay at commit
|
|
613
613
|
// so it re-runs with the new committed view. (Gate details live with the
|
|
614
614
|
// engine — a non-null lane implies it is installed.)
|
|
615
|
-
if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.
|
|
616
|
-
return e.
|
|
615
|
+
if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.Ot(e, u, t)) {
|
|
616
|
+
return e.Ue;
|
|
617
617
|
}
|
|
618
618
|
// In optimistic lane context, return _value for optimistic/lane-assigned signals
|
|
619
619
|
// and for regular signals in stale mode (render effects). Non-stale readers (user
|
|
620
620
|
// effects) see _pendingValue so that latest() and direct reads stay consistent.
|
|
621
621
|
// (The lane-context clause lives with the engine.)
|
|
622
|
-
const l = !t || currentOptimisticLane !== null && GlobalQueue.
|
|
622
|
+
const l = !t || currentOptimisticLane !== null && GlobalQueue.Rt(e, u, t) || e._e === NOT_PENDING || stale && e.Ie && activeTransition !== e.Ie ? e.Ue : e._e;
|
|
623
623
|
// Record that this isPending() probe observed the fresh pending value, so
|
|
624
624
|
// the probe doesn't pair "pending" with the new value (#2831).
|
|
625
|
-
if (pendingCheckActive) GlobalQueue.
|
|
626
|
-
if (!t && u === e && typeof n.
|
|
625
|
+
if (pendingCheckActive) GlobalQueue.Pt(e, l);
|
|
626
|
+
if (!t && u === e && typeof n.ae === "function" && e.T & CONFIG_AUTO_DISPOSE && !(u.S & STATUS_PENDING) && !e.o) {
|
|
627
627
|
unobserved(e);
|
|
628
628
|
}
|
|
629
629
|
return l;
|
|
630
630
|
}
|
|
631
631
|
|
|
632
632
|
function setSignal(e, t) {
|
|
633
|
-
if (e.
|
|
633
|
+
if (e.Ie && activeTransition !== e.Ie) globalQueue.initTransition(e.Ie);
|
|
634
634
|
// The optimistic write path lives with the engine: only optimisticSignal /
|
|
635
635
|
// optimisticComputed callers and optimistic store nodes carry an
|
|
636
636
|
// _overrideValue slot, and every module that creates one installs the
|
|
637
637
|
// engine first.
|
|
638
|
-
if (e.
|
|
639
|
-
const n = e.
|
|
638
|
+
if (e.Ae !== undefined && !projectionWriteActive) return GlobalQueue.ht(e, t);
|
|
639
|
+
const n = e._e === NOT_PENDING ? e.Ue : e._e;
|
|
640
640
|
if (typeof t === "function") t = t(n);
|
|
641
641
|
// Uninitialized check first: the first commit has no previous value, so the
|
|
642
642
|
// user comparator must not run against `undefined` (matches recompute).
|
|
643
643
|
const i = !!(e.S & STATUS_UNINITIALIZED) || !e.Re || !e.Re(n, t);
|
|
644
644
|
if (!i) return t;
|
|
645
|
-
if (e.
|
|
646
|
-
e.
|
|
645
|
+
if (e._e === NOT_PENDING) queuePendingNode(e);
|
|
646
|
+
e._e = t;
|
|
647
647
|
// syncCompanions only pokes _pendingSignal/_latestValueComputed — with
|
|
648
648
|
// neither companion present the call is a guaranteed no-op (companions are
|
|
649
649
|
// only ever created, never removed, and creating one installs the hook).
|
|
650
|
-
(e.
|
|
651
|
-
e.
|
|
650
|
+
(e.he !== undefined || e.Ge !== undefined) && GlobalQueue.De !== null && GlobalQueue.De(e, t);
|
|
651
|
+
e.Se = clock;
|
|
652
652
|
insertSubs(e);
|
|
653
653
|
schedule();
|
|
654
654
|
return t;
|
|
@@ -662,7 +662,7 @@ function setSignal(e, t) {
|
|
|
662
662
|
* cleanup point.
|
|
663
663
|
*/ function suppressComputedRecompute(e) {
|
|
664
664
|
deleteFromHeap(e, queueFor(e));
|
|
665
|
-
if (!(e.se & REACTIVE_MANUAL_WRITE) && e.
|
|
665
|
+
if (!(e.se & REACTIVE_MANUAL_WRITE) && e._e === NOT_PENDING) {
|
|
666
666
|
queuePendingNode(e);
|
|
667
667
|
schedule();
|
|
668
668
|
}
|
|
@@ -745,7 +745,7 @@ function staleValues(e, t = true) {
|
|
|
745
745
|
if (!t) {
|
|
746
746
|
return;
|
|
747
747
|
}
|
|
748
|
-
if (typeof t.
|
|
748
|
+
if (typeof t.ae === "function" && !(t.se & (REACTIVE_DISPOSED | REACTIVE_MANUAL_WRITE))) {
|
|
749
749
|
// A refresh with no value-change dirt already queued is a re-ask of the
|
|
750
750
|
// same question: mark it so the recompute classifies any resulting
|
|
751
751
|
// pending window as quiet (not pending). If the node is already dirty
|