@solidjs/signals 2.0.0-beta.31 → 2.0.0-beta.32
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 +15 -2
- package/dist/node.cjs +17 -2
- package/dist/prod/core/async.js +49 -34
- package/dist/prod/core/core.js +22 -22
- package/dist/prod/core/effect.js +3 -3
- package/dist/prod/core/lanes.js +1 -1
- package/dist/prod/core/optimistic.js +6 -6
- package/dist/prod/core/owner.js +1 -1
- package/dist/prod/core/scheduler.js +4 -4
- package/dist/prod/core/verdict.js +21 -21
- package/dist/prod/store/optimistic.js +2 -2
- package/dist/prod/store/store.js +1 -1
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -2083,9 +2083,22 @@ function handleAsync(el, result, setter) {
|
|
|
2083
2083
|
resolved = false,
|
|
2084
2084
|
rejected = false,
|
|
2085
2085
|
isSync = true;
|
|
2086
|
-
|
|
2086
|
+
// Protocol tolerance, matching `for await`: `await` unwraps whatever
|
|
2087
|
+
// next() returns — a thenable OR a bare IteratorResult. Real producers
|
|
2088
|
+
// use the bare form as a promise-free fast path when a value is already
|
|
2089
|
+
// buffered (seroval's deserialized streams do), so a bare result is
|
|
2090
|
+
// assimilated as an already-settled step instead of crashing on `.then`.
|
|
2091
|
+
const step = it.next();
|
|
2092
|
+
const settled = isThenable(step) ? step : { then: onSettle => void onSettle(step) };
|
|
2093
|
+
settled.then(
|
|
2087
2094
|
r => {
|
|
2088
|
-
|
|
2095
|
+
// The sync stash only serves the INITIAL drain (handleAsync's caller
|
|
2096
|
+
// consumes syncValue / throws NotReady from it). A sync-settled step
|
|
2097
|
+
// after an async gap — seroval buffering values between pulls, a
|
|
2098
|
+
// sync-thenable producer mid-stream — has no caller reading the
|
|
2099
|
+
// stash: it must write through the async path or the value is
|
|
2100
|
+
// silently dropped.
|
|
2101
|
+
if (isSync && initialRead) {
|
|
2089
2102
|
syncResult = r;
|
|
2090
2103
|
resolved = true;
|
|
2091
2104
|
if (r.done) completed = true;
|
package/dist/node.cjs
CHANGED
|
@@ -1909,8 +1909,23 @@ function handleAsync(e, t, n) {
|
|
|
1909
1909
|
};
|
|
1910
1910
|
const iterate = () => {
|
|
1911
1911
|
let u, l, a = false, c = false, f = true;
|
|
1912
|
-
|
|
1913
|
-
|
|
1912
|
+
// Protocol tolerance, matching `for await`: `await` unwraps whatever
|
|
1913
|
+
// next() returns — a thenable OR a bare IteratorResult. Real producers
|
|
1914
|
+
// use the bare form as a promise-free fast path when a value is already
|
|
1915
|
+
// buffered (seroval's deserialized streams do), so a bare result is
|
|
1916
|
+
// assimilated as an already-settled step instead of crashing on `.then`.
|
|
1917
|
+
const E = n.next();
|
|
1918
|
+
const d = isThenable(E) ? E : {
|
|
1919
|
+
then: e => void e(E)
|
|
1920
|
+
};
|
|
1921
|
+
d.then(n => {
|
|
1922
|
+
// The sync stash only serves the INITIAL drain (handleAsync's caller
|
|
1923
|
+
// consumes syncValue / throws NotReady from it). A sync-settled step
|
|
1924
|
+
// after an async gap — seroval buffering values between pulls, a
|
|
1925
|
+
// sync-thenable producer mid-stream — has no caller reading the
|
|
1926
|
+
// stash: it must write through the async path or the value is
|
|
1927
|
+
// silently dropped.
|
|
1928
|
+
if (f && s) {
|
|
1914
1929
|
u = n;
|
|
1915
1930
|
a = true;
|
|
1916
1931
|
if (n.done) i = true;
|
package/dist/prod/core/async.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { STATUS_UNINITIALIZED, STATUS_ERROR, STATUS_PENDING,
|
|
1
|
+
import { STATUS_UNINITIALIZED, STATUS_ERROR, STATUS_PENDING, REACTIVE_DIRTY, REACTIVE_OPTIMISTIC_DIRTY, NOT_PENDING, CONFIG_AUTO_DISPOSE, REACTIVE_ZOMBIE } from "./constants.js";
|
|
2
2
|
|
|
3
3
|
import { untrack, context, setSignal } from "./core.js";
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ import "./invariants.js";
|
|
|
6
6
|
|
|
7
7
|
import { NotReadyError, StatusError } from "./error.js";
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { trimStaleDeps, unobserved } from "./graph.js";
|
|
10
10
|
|
|
11
11
|
import { enqueueSub } from "./heap.js";
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@ import { resolveTransition, hasActiveOverride, assignOrMergeLane, resolveLane }
|
|
|
14
14
|
|
|
15
15
|
import { cleanup } from "./owner.js";
|
|
16
16
|
|
|
17
|
-
import { globalQueue, GlobalQueue,
|
|
17
|
+
import { globalQueue, GlobalQueue, schedule, flush, queuePendingNode, insertSubs, clock, currentTransition } from "./scheduler.js";
|
|
18
18
|
|
|
19
19
|
// The lazily-created Set is the ONE container for pending sources. Its
|
|
20
20
|
// predecessor — a singular slot promoted to a Set on the second source —
|
|
@@ -133,9 +133,9 @@ function settlePendingSource(e) {
|
|
|
133
133
|
if (r.has(u) || !removePendingSource(u, e)) return;
|
|
134
134
|
r.add(u);
|
|
135
135
|
u.Se = clock;
|
|
136
|
-
const
|
|
137
|
-
if (
|
|
138
|
-
setPendingError(u,
|
|
136
|
+
const s = u.oe?.values().next().value;
|
|
137
|
+
if (s) {
|
|
138
|
+
setPendingError(u, s);
|
|
139
139
|
o !== null && o(u);
|
|
140
140
|
} else {
|
|
141
141
|
u.S &= ~STATUS_PENDING;
|
|
@@ -222,8 +222,8 @@ function handleAsync(e, n, t) {
|
|
|
222
222
|
const u = !!(e.S & STATUS_UNINITIALIZED);
|
|
223
223
|
trimStaleDeps(e);
|
|
224
224
|
clearStatus(e);
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
225
|
+
const s = resolveLane(e);
|
|
226
|
+
if (s) s.Ne.delete(e);
|
|
227
227
|
if (t) {
|
|
228
228
|
t(r);
|
|
229
229
|
if (u) clearStatus(e, true);
|
|
@@ -249,14 +249,14 @@ function handleAsync(e, n, t) {
|
|
|
249
249
|
GlobalQueue._e !== null && GlobalQueue._e(e, r);
|
|
250
250
|
if (!hasActiveOverride(e)) insertSubs(e);
|
|
251
251
|
e.Se = clock;
|
|
252
|
-
} else if (
|
|
252
|
+
} else if (s) {
|
|
253
253
|
// Route through lane's effect queue for independent flushing
|
|
254
254
|
const n = e.Pe;
|
|
255
|
-
const t = e.
|
|
256
|
-
const o = e.
|
|
255
|
+
const t = e.be;
|
|
256
|
+
const o = e.he;
|
|
257
257
|
try {
|
|
258
258
|
if (!n && u || !o || !o(r, t)) {
|
|
259
|
-
e.
|
|
259
|
+
e.be = r;
|
|
260
260
|
e.Se = clock;
|
|
261
261
|
// The latest() shadow write gives latest() effects independent lanes; the
|
|
262
262
|
// _pendingSignal update is a no-op repeat of the clearStatus() call above
|
|
@@ -300,9 +300,9 @@ function handleAsync(e, n, t) {
|
|
|
300
300
|
return false;
|
|
301
301
|
};
|
|
302
302
|
if (o) {
|
|
303
|
-
let t = false, r = false, o,
|
|
303
|
+
let t = false, r = false, o, s = true;
|
|
304
304
|
n.then(e => {
|
|
305
|
-
if (
|
|
305
|
+
if (s) {
|
|
306
306
|
u = e;
|
|
307
307
|
t = true;
|
|
308
308
|
} else {
|
|
@@ -310,7 +310,7 @@ function handleAsync(e, n, t) {
|
|
|
310
310
|
settleAutodispose();
|
|
311
311
|
}
|
|
312
312
|
}, e => {
|
|
313
|
-
if (
|
|
313
|
+
if (s) {
|
|
314
314
|
o = e;
|
|
315
315
|
r = true;
|
|
316
316
|
} else {
|
|
@@ -318,7 +318,7 @@ function handleAsync(e, n, t) {
|
|
|
318
318
|
settleAutodispose();
|
|
319
319
|
}
|
|
320
320
|
});
|
|
321
|
-
|
|
321
|
+
s = false;
|
|
322
322
|
if (r) {
|
|
323
323
|
// Settle through the same status path an async rejection uses, then
|
|
324
324
|
// unwind the in-progress synchronous read so the errored node isn't
|
|
@@ -334,7 +334,7 @@ function handleAsync(e, n, t) {
|
|
|
334
334
|
const t = n[Symbol.asyncIterator]();
|
|
335
335
|
let r = false;
|
|
336
336
|
let o = false;
|
|
337
|
-
let
|
|
337
|
+
let s = true;
|
|
338
338
|
cleanup(() => {
|
|
339
339
|
if (o) return;
|
|
340
340
|
o = true;
|
|
@@ -350,10 +350,25 @@ function handleAsync(e, n, t) {
|
|
|
350
350
|
if (!settleAutodispose()) iterate();
|
|
351
351
|
};
|
|
352
352
|
const iterate = () => {
|
|
353
|
-
let
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
353
|
+
let l, i, f = false, a = false, c = true;
|
|
354
|
+
// Protocol tolerance, matching `for await`: `await` unwraps whatever
|
|
355
|
+
// next() returns — a thenable OR a bare IteratorResult. Real producers
|
|
356
|
+
// use the bare form as a promise-free fast path when a value is already
|
|
357
|
+
// buffered (seroval's deserialized streams do), so a bare result is
|
|
358
|
+
// assimilated as an already-settled step instead of crashing on `.then`.
|
|
359
|
+
const S = t.next();
|
|
360
|
+
const d = isThenable(S) ? S : {
|
|
361
|
+
then: e => void e(S)
|
|
362
|
+
};
|
|
363
|
+
d.then(t => {
|
|
364
|
+
// The sync stash only serves the INITIAL drain (handleAsync's caller
|
|
365
|
+
// consumes syncValue / throws NotReady from it). A sync-settled step
|
|
366
|
+
// after an async gap — seroval buffering values between pulls, a
|
|
367
|
+
// sync-thenable producer mid-stream — has no caller reading the
|
|
368
|
+
// stash: it must write through the async path or the value is
|
|
369
|
+
// silently dropped.
|
|
370
|
+
if (c && s) {
|
|
371
|
+
l = t;
|
|
357
372
|
f = true;
|
|
358
373
|
if (t.done) o = true;
|
|
359
374
|
} else if (e.Te !== n) {
|
|
@@ -387,20 +402,20 @@ function handleAsync(e, n, t) {
|
|
|
387
402
|
// Match the promise branch, but only rethrow during the initial read.
|
|
388
403
|
o = true;
|
|
389
404
|
handleError(i);
|
|
390
|
-
if (
|
|
405
|
+
if (s) throw i;
|
|
391
406
|
return true;
|
|
392
407
|
}
|
|
393
|
-
if (f && !
|
|
394
|
-
u =
|
|
408
|
+
if (f && !l.done) {
|
|
409
|
+
u = l.value;
|
|
395
410
|
r = true;
|
|
396
411
|
return iterate();
|
|
397
412
|
}
|
|
398
|
-
return f &&
|
|
413
|
+
return f && l.done;
|
|
399
414
|
};
|
|
400
|
-
const
|
|
415
|
+
const l = iterate();
|
|
401
416
|
// Later iterate() calls run from asyncWrite, where rethrowing would be unhandled.
|
|
402
|
-
|
|
403
|
-
if (!r && !
|
|
417
|
+
s = false;
|
|
418
|
+
if (!r && !l) {
|
|
404
419
|
globalQueue.initTransition(resolveTransition(e));
|
|
405
420
|
throw new NotReadyError(context);
|
|
406
421
|
}
|
|
@@ -414,12 +429,12 @@ function clearStatus(e, n = false) {
|
|
|
414
429
|
// The pending window is over; its quiet classification dies with it.
|
|
415
430
|
// (Unconditional: _reask is baked into the node literals, so this is a
|
|
416
431
|
// plain store to an existing slot — no shape change.)
|
|
417
|
-
e.
|
|
432
|
+
e.Ue = false;
|
|
418
433
|
e.S = n ? 0 : e.S & STATUS_UNINITIALIZED;
|
|
419
434
|
if (e._) setPendingError(e);
|
|
420
435
|
// Update pending signal for isPending() reactivity (companions only exist
|
|
421
436
|
// once the verdict layer created them, which installs the hooks).
|
|
422
|
-
if (e.
|
|
437
|
+
if (e.Re || e.pe) GlobalQueue.ce(e);
|
|
423
438
|
if (e.u && GlobalQueue.Ge !== null) GlobalQueue.Ge(e);
|
|
424
439
|
if (e.i) e.i();
|
|
425
440
|
}
|
|
@@ -428,9 +443,9 @@ function notifyStatus(e, n, t, r, o) {
|
|
|
428
443
|
// Wrap regular errors to track source node
|
|
429
444
|
if (n === STATUS_ERROR && !(t instanceof StatusError) && !(t instanceof NotReadyError)) t = new StatusError(e, t);
|
|
430
445
|
const u = n === STATUS_PENDING && t instanceof NotReadyError ? t.source : undefined;
|
|
431
|
-
const
|
|
432
|
-
const
|
|
433
|
-
const i =
|
|
446
|
+
const s = u === e;
|
|
447
|
+
const l = n === STATUS_PENDING && e.Ae !== undefined && !s;
|
|
448
|
+
const i = l && hasActiveOverride(e);
|
|
434
449
|
if (!r) {
|
|
435
450
|
if (n === STATUS_PENDING && u) {
|
|
436
451
|
addPendingSource(e, u);
|
|
@@ -450,7 +465,7 @@ function notifyStatus(e, n, t, r, o) {
|
|
|
450
465
|
assignOrMergeLane(e, o);
|
|
451
466
|
}
|
|
452
467
|
const f = r || i;
|
|
453
|
-
const a = r ||
|
|
468
|
+
const a = r || l ? undefined : o;
|
|
454
469
|
if (e.i) {
|
|
455
470
|
if (r && n === STATUS_PENDING) {
|
|
456
471
|
return;
|
package/dist/prod/core/core.js
CHANGED
|
@@ -137,7 +137,7 @@ function recompute(e, t = false) {
|
|
|
137
137
|
e.Ye++;
|
|
138
138
|
e.se = REACTIVE_RECOMPUTING_DEPS;
|
|
139
139
|
e.Se = clock;
|
|
140
|
-
let r = e.De === NOT_PENDING ? e.
|
|
140
|
+
let r = e.De === NOT_PENDING ? e.be : e.De;
|
|
141
141
|
let c = e.Ve;
|
|
142
142
|
let _ = tracking;
|
|
143
143
|
let f = currentOptimisticLane;
|
|
@@ -189,7 +189,7 @@ function recompute(e, t = false) {
|
|
|
189
189
|
// On a status-free node clearStatus is a guaranteed no-op: every branch
|
|
190
190
|
// in its body is gated on one of these fields, and with _statusFlags === 0
|
|
191
191
|
// the flags write (create or not) stores the 0 already there.
|
|
192
|
-
if (e.S !== 0 || e.i !== undefined || e._ || e.
|
|
192
|
+
if (e.S !== 0 || e.i !== undefined || e._ || e.Ue || e.de || e.oe !== undefined || e.Re !== undefined || e.pe !== undefined || e.u !== null) clearStatus(e, t);
|
|
193
193
|
// _optimisticLane is only ever assigned by engine paths.
|
|
194
194
|
if (e.Me) GlobalQueue.Ke(e);
|
|
195
195
|
} catch (t) {
|
|
@@ -212,10 +212,10 @@ function recompute(e, t = false) {
|
|
|
212
212
|
}
|
|
213
213
|
if (!e._) {
|
|
214
214
|
trimStaleDeps(e);
|
|
215
|
-
const s = u ? unwrapOverride(e.Ae) : e.De === NOT_PENDING ? e.
|
|
215
|
+
const s = u ? unwrapOverride(e.Ae) : e.De === NOT_PENDING ? e.be : e.De;
|
|
216
216
|
let a = false;
|
|
217
217
|
try {
|
|
218
|
-
a = !n && l || !e.
|
|
218
|
+
a = !n && l || !e.he || !e.he(s, r);
|
|
219
219
|
} catch (t) {
|
|
220
220
|
// A throwing user comparator is an error of this node's computation.
|
|
221
221
|
// Route it through the same status path as a compute-phase throw so
|
|
@@ -242,7 +242,7 @@ function recompute(e, t = false) {
|
|
|
242
242
|
// commitPendingNodes) exists to sequence transition reveals, and
|
|
243
243
|
// paying it per effect on the plain path is pure overhead.
|
|
244
244
|
n && (activeTransition !== e.Ie || activeTransition === null) || i) {
|
|
245
|
-
e.
|
|
245
|
+
e.be = r;
|
|
246
246
|
// Lane-propagated correction: upstream data is fresh, correct the
|
|
247
247
|
// override unconditionally. The direct _value commit is the lane's
|
|
248
248
|
// own reveal schedule; drop any superseded older hold so its queued
|
|
@@ -316,14 +316,14 @@ function computed(e, t) {
|
|
|
316
316
|
const i = {
|
|
317
317
|
id: inheritId(t, n, context),
|
|
318
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),
|
|
319
|
-
|
|
319
|
+
he: t?.equals != null ? t.equals : isEqual,
|
|
320
320
|
ut: t?.unobserved,
|
|
321
321
|
Le: null,
|
|
322
322
|
C: context?.C ?? globalQueue,
|
|
323
323
|
we: context?.we ?? defaultContext,
|
|
324
324
|
qe: 0,
|
|
325
325
|
ae: e,
|
|
326
|
-
|
|
326
|
+
be: undefined,
|
|
327
327
|
Ve: 0,
|
|
328
328
|
u: null,
|
|
329
329
|
lt: undefined,
|
|
@@ -345,7 +345,7 @@ function computed(e, t) {
|
|
|
345
345
|
Qe: null,
|
|
346
346
|
Te: null,
|
|
347
347
|
Ie: null,
|
|
348
|
-
|
|
348
|
+
Ue: false
|
|
349
349
|
};
|
|
350
350
|
setupComputedNode(i, t);
|
|
351
351
|
return i;
|
|
@@ -361,14 +361,14 @@ function computed(e, t) {
|
|
|
361
361
|
const s = {
|
|
362
362
|
id: inheritId(l, o, context),
|
|
363
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),
|
|
364
|
-
|
|
364
|
+
he: false,
|
|
365
365
|
ut: l?.unobserved,
|
|
366
366
|
Le: null,
|
|
367
367
|
C: context?.C ?? globalQueue,
|
|
368
368
|
we: context?.we ?? defaultContext,
|
|
369
369
|
qe: 0,
|
|
370
370
|
ae: e,
|
|
371
|
-
|
|
371
|
+
be: undefined,
|
|
372
372
|
Ve: 0,
|
|
373
373
|
u: null,
|
|
374
374
|
lt: undefined,
|
|
@@ -390,7 +390,7 @@ function computed(e, t) {
|
|
|
390
390
|
Qe: null,
|
|
391
391
|
Te: null,
|
|
392
392
|
Ie: null,
|
|
393
|
-
|
|
393
|
+
Ue: false,
|
|
394
394
|
Be: false,
|
|
395
395
|
ct: undefined,
|
|
396
396
|
_t: t,
|
|
@@ -425,7 +425,7 @@ function setupComputedNode(e, t) {
|
|
|
425
425
|
!t?.lazy && recompute(e, true);
|
|
426
426
|
if (snapshotCaptureActive && !t?.lazy) {
|
|
427
427
|
if (!(e.S & STATUS_PENDING) && !(e.T & CONFIG_NO_SNAPSHOT)) {
|
|
428
|
-
e.xe = e.
|
|
428
|
+
e.xe = e.be === undefined ? NO_SNAPSHOT : e.be;
|
|
429
429
|
snapshotSources.add(e);
|
|
430
430
|
}
|
|
431
431
|
}
|
|
@@ -433,10 +433,10 @@ function setupComputedNode(e, t) {
|
|
|
433
433
|
|
|
434
434
|
function signal(e, t, n = null) {
|
|
435
435
|
const i = {
|
|
436
|
-
|
|
436
|
+
he: t?.equals != null ? t.equals : isEqual,
|
|
437
437
|
T: (t?.ownedWrite ? CONFIG_OWNED_WRITE : 0) | (t?.V ? CONFIG_NO_SNAPSHOT : 0),
|
|
438
438
|
ut: t?.unobserved,
|
|
439
|
-
|
|
439
|
+
be: e,
|
|
440
440
|
o: null,
|
|
441
441
|
st: null,
|
|
442
442
|
Se: clock,
|
|
@@ -534,7 +534,7 @@ function isEqual(e, t) {
|
|
|
534
534
|
let t = context;
|
|
535
535
|
if (t?.Nt) t = t.Tt;
|
|
536
536
|
if (t && tracking) link(e, t);
|
|
537
|
-
return !t || e.De === NOT_PENDING ? e.
|
|
537
|
+
return !t || e.De === NOT_PENDING ? e.be : e.De;
|
|
538
538
|
}
|
|
539
539
|
|
|
540
540
|
function read(e) {
|
|
@@ -558,7 +558,7 @@ function read(e) {
|
|
|
558
558
|
}
|
|
559
559
|
if (!n.ae && u === e && e.Ae === undefined && e.xe === undefined && activeTransition === null && currentOptimisticLane === null && !snapshotCaptureActive && true) {
|
|
560
560
|
if (t && tracking) link(e, t);
|
|
561
|
-
return !t || e.De === NOT_PENDING ? e.
|
|
561
|
+
return !t || e.De === NOT_PENDING ? e.be : e.De;
|
|
562
562
|
}
|
|
563
563
|
if (t && tracking) {
|
|
564
564
|
link(e, t, pendingCheckActive);
|
|
@@ -610,7 +610,7 @@ function read(e) {
|
|
|
610
610
|
const n = e.xe;
|
|
611
611
|
if (n !== undefined) {
|
|
612
612
|
const i = n === NO_SNAPSHOT ? undefined : n;
|
|
613
|
-
const u = e.De !== NOT_PENDING ? e.De : e.
|
|
613
|
+
const u = e.De !== NOT_PENDING ? e.De : e.be;
|
|
614
614
|
if (u !== i) t.se |= REACTIVE_SNAPSHOT_STALE;
|
|
615
615
|
return i;
|
|
616
616
|
}
|
|
@@ -627,13 +627,13 @@ function read(e) {
|
|
|
627
627
|
// so it re-runs with the new committed view. (Gate details live with the
|
|
628
628
|
// engine — a non-null lane implies it is installed.)
|
|
629
629
|
if (currentOptimisticLane !== null && activeTransition !== null && t !== null && GlobalQueue.Ot(e, u, t)) {
|
|
630
|
-
return e.
|
|
630
|
+
return e.be;
|
|
631
631
|
}
|
|
632
632
|
// In optimistic lane context, return _value for optimistic/lane-assigned signals
|
|
633
633
|
// and for regular signals in stale mode (render effects). Non-stale readers (user
|
|
634
634
|
// effects) see _pendingValue so that latest() and direct reads stay consistent.
|
|
635
635
|
// (The lane-context clause lives with the engine.)
|
|
636
|
-
const l = !t || currentOptimisticLane !== null && GlobalQueue.Rt(e, u, t) || e.De === NOT_PENDING || stale && e.Ie && activeTransition !== e.Ie ? e.
|
|
636
|
+
const l = !t || currentOptimisticLane !== null && GlobalQueue.Rt(e, u, t) || e.De === NOT_PENDING || stale && e.Ie && activeTransition !== e.Ie ? e.be : e.De;
|
|
637
637
|
// Record that this isPending() probe observed the fresh pending value, so
|
|
638
638
|
// the probe doesn't pair "pending" with the new value (#2831).
|
|
639
639
|
if (pendingCheckActive) GlobalQueue.Pt(e, l);
|
|
@@ -650,18 +650,18 @@ function setSignal(e, t) {
|
|
|
650
650
|
// _overrideValue slot, and every module that creates one installs the
|
|
651
651
|
// engine first.
|
|
652
652
|
if (e.Ae !== undefined && !projectionWriteActive) return GlobalQueue.ht(e, t);
|
|
653
|
-
const n = e.De === NOT_PENDING ? e.
|
|
653
|
+
const n = e.De === NOT_PENDING ? e.be : e.De;
|
|
654
654
|
if (typeof t === "function") t = t(n);
|
|
655
655
|
// Uninitialized check first: the first commit has no previous value, so the
|
|
656
656
|
// user comparator must not run against `undefined` (matches recompute).
|
|
657
|
-
const i = !!(e.S & STATUS_UNINITIALIZED) || !e.
|
|
657
|
+
const i = !!(e.S & STATUS_UNINITIALIZED) || !e.he || !e.he(n, t);
|
|
658
658
|
if (!i) return t;
|
|
659
659
|
if (e.De === NOT_PENDING) queuePendingNode(e);
|
|
660
660
|
e.De = t;
|
|
661
661
|
// syncCompanions only pokes _pendingSignal/_latestValueComputed — with
|
|
662
662
|
// neither companion present the call is a guaranteed no-op (companions are
|
|
663
663
|
// only ever created, never removed, and creating one installs the hook).
|
|
664
|
-
(e.
|
|
664
|
+
(e.Re !== undefined || e.pe !== undefined) && GlobalQueue._e !== null && GlobalQueue._e(e, t);
|
|
665
665
|
e.Se = clock;
|
|
666
666
|
insertSubs(e);
|
|
667
667
|
schedule();
|
package/dist/prod/core/effect.js
CHANGED
|
@@ -62,7 +62,7 @@ function runEffect(t) {
|
|
|
62
62
|
// same flush must not be hijacked by a later-arriving error status.
|
|
63
63
|
if (t.S & STATUS_ERROR && t.Pe === EFFECT_USER) {
|
|
64
64
|
const E = unwrapStatusError(t._);
|
|
65
|
-
t.ct = t.
|
|
65
|
+
t.ct = t.be;
|
|
66
66
|
t.Be = false;
|
|
67
67
|
try {
|
|
68
68
|
t.ft ? t.ft(E, () => {
|
|
@@ -82,7 +82,7 @@ function runEffect(t) {
|
|
|
82
82
|
t.Et = undefined;
|
|
83
83
|
try {
|
|
84
84
|
E?.();
|
|
85
|
-
const e = t._t(t.
|
|
85
|
+
const e = t._t(t.be, t.ct);
|
|
86
86
|
if (false && e !== undefined && typeof e !== "function") ;
|
|
87
87
|
// The final cleanup is invoked by disposeChildren at true disposal.
|
|
88
88
|
t.Et = e;
|
|
@@ -94,7 +94,7 @@ function runEffect(t) {
|
|
|
94
94
|
throw E;
|
|
95
95
|
}
|
|
96
96
|
} finally {
|
|
97
|
-
t.ct = t.
|
|
97
|
+
t.ct = t.be;
|
|
98
98
|
t.Be = false;
|
|
99
99
|
}
|
|
100
100
|
}
|
package/dist/prod/core/lanes.js
CHANGED
|
@@ -36,7 +36,7 @@ const activeLanes = new Set;
|
|
|
36
36
|
// parent-child is a property of the nodes, not of write order — otherwise
|
|
37
37
|
// the owner's write merges the companion's subscribers into this lane and
|
|
38
38
|
// their effects wait on its async instead of flushing immediately.
|
|
39
|
-
adoptCompanionLane(n.
|
|
39
|
+
adoptCompanionLane(n.Re, e);
|
|
40
40
|
adoptCompanionLane(n.pe, e);
|
|
41
41
|
return e;
|
|
42
42
|
}
|
|
@@ -25,9 +25,9 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
|
|
|
25
25
|
*/
|
|
26
26
|
/** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, n) {
|
|
27
27
|
const t = e.Ae !== NOT_PENDING;
|
|
28
|
-
const i = t ? unwrapOverride(e.Ae) : e.
|
|
28
|
+
const i = t ? unwrapOverride(e.Ae) : e.be;
|
|
29
29
|
if (typeof n === "function") n = n(i);
|
|
30
|
-
const u = !!(e.S & STATUS_UNINITIALIZED) || !e.
|
|
30
|
+
const u = !!(e.S & STATUS_UNINITIALIZED) || !e.he || !e.he(i, n);
|
|
31
31
|
if (!u) {
|
|
32
32
|
// Same-value write with an active override still entangles the current
|
|
33
33
|
// action's transition — the hold must outlast all overlapping actions.
|
|
@@ -54,7 +54,7 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
|
|
|
54
54
|
e.Ae = n === undefined ? OVERRIDE_UNDEFINED : n;
|
|
55
55
|
// syncCompanions only pokes _pendingSignal/_latestValueComputed — with
|
|
56
56
|
// neither companion present the call is a guaranteed no-op.
|
|
57
|
-
(e.
|
|
57
|
+
(e.Re !== undefined || e.pe !== undefined) && GlobalQueue._e !== null && GlobalQueue._e(e, n);
|
|
58
58
|
e.Se = clock;
|
|
59
59
|
insertSubs(e, true);
|
|
60
60
|
schedule();
|
|
@@ -89,7 +89,7 @@ function resolveOptimisticNodes(e) {
|
|
|
89
89
|
if (!(n.S & STATUS_PENDING)) n.S &= ~STATUS_UNINITIALIZED;
|
|
90
90
|
const i = n.Ae;
|
|
91
91
|
n.Ae = NOT_PENDING;
|
|
92
|
-
if (i !== NOT_PENDING && n.
|
|
92
|
+
if (i !== NOT_PENDING && n.be !== unwrapOverride(i)) insertSubs(n, true);
|
|
93
93
|
n.Ie = null;
|
|
94
94
|
n.sn = null;
|
|
95
95
|
}
|
|
@@ -98,9 +98,9 @@ function resolveOptimisticNodes(e) {
|
|
|
98
98
|
// transition that produced them (A19 — pending is a property of the data).
|
|
99
99
|
for (let t = 0; t < n; t++) {
|
|
100
100
|
const n = e[t];
|
|
101
|
-
if (n.
|
|
101
|
+
if (n.Re || n.pe) GlobalQueue.un(n);
|
|
102
102
|
const i = n.nn;
|
|
103
|
-
if (i && (i.
|
|
103
|
+
if (i && (i.Re === n || i.pe === n)) GlobalQueue.un(i);
|
|
104
104
|
}
|
|
105
105
|
e.splice(0, n);
|
|
106
106
|
}
|
package/dist/prod/core/owner.js
CHANGED
|
@@ -51,7 +51,7 @@ function disposeChildren(e, n = false, t) {
|
|
|
51
51
|
// edge). Snap runs after the DISPOSED flag is set so the oracle reads
|
|
52
52
|
// false, and notifies subscribers still watching the companion.
|
|
53
53
|
const n = e;
|
|
54
|
-
if (n.
|
|
54
|
+
if (n.Re || n.pe) GlobalQueue.un(n);
|
|
55
55
|
}
|
|
56
56
|
if (n && e.ae) e.Te = null;
|
|
57
57
|
let l = t ? e.Qe : e.ke;
|
|
@@ -543,14 +543,14 @@ function commitPendingNode(e) {
|
|
|
543
543
|
const t = e;
|
|
544
544
|
if (!t.ae) {
|
|
545
545
|
if (e.De !== NOT_PENDING) {
|
|
546
|
-
e.
|
|
546
|
+
e.be = e.De;
|
|
547
547
|
e.De = NOT_PENDING;
|
|
548
548
|
}
|
|
549
|
-
if (e.
|
|
549
|
+
if (e.Re || e.pe) GlobalQueue.un(e);
|
|
550
550
|
return;
|
|
551
551
|
}
|
|
552
552
|
if (e.De !== NOT_PENDING) {
|
|
553
|
-
e.
|
|
553
|
+
e.be = e.De;
|
|
554
554
|
e.De = NOT_PENDING;
|
|
555
555
|
// Set _modified for effects, but not for tracked effects (they handle their own scheduling)
|
|
556
556
|
if (e.Pe && e.Pe !== EFFECT_TRACKED) e.Be = true;
|
|
@@ -558,7 +558,7 @@ function commitPendingNode(e) {
|
|
|
558
558
|
t.se &= ~REACTIVE_MANUAL_WRITE;
|
|
559
559
|
if (!(t.S & STATUS_PENDING)) t.S &= ~STATUS_UNINITIALIZED;
|
|
560
560
|
if (t.Qe !== null || t.ye !== null) GlobalQueue.me(t, false, true);
|
|
561
|
-
if (e.
|
|
561
|
+
if (e.Re || e.pe) GlobalQueue.un(e);
|
|
562
562
|
}
|
|
563
563
|
|
|
564
564
|
function commitPendingNodes() {
|
|
@@ -32,15 +32,15 @@ let pendingProbe = null;
|
|
|
32
32
|
* Get or create the pending signal for a node (lazy).
|
|
33
33
|
* Used by isPending() to track pending state reactively.
|
|
34
34
|
*/ function getPendingSignal(e) {
|
|
35
|
-
if (!e.
|
|
35
|
+
if (!e.Re) {
|
|
36
36
|
// Start false, write true if pending - ensures reversion returns to false
|
|
37
|
-
e.
|
|
37
|
+
e.Re = optimisticSignal(false, {
|
|
38
38
|
ownedWrite: true
|
|
39
39
|
});
|
|
40
|
-
e.
|
|
41
|
-
if (computePendingState(e)) setSignal(e.
|
|
40
|
+
e.Re.nn = e;
|
|
41
|
+
if (computePendingState(e)) setSignal(e.Re, true);
|
|
42
42
|
}
|
|
43
|
-
return e.
|
|
43
|
+
return e.Re;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
function collectPendingSources(e) {
|
|
@@ -102,10 +102,10 @@ function collectPendingSources(e) {
|
|
|
102
102
|
|
|
103
103
|
function quietPending(e) {
|
|
104
104
|
if (e.oe) {
|
|
105
|
-
for (const t of e.oe) if (!t.
|
|
105
|
+
for (const t of e.oe) if (!t.Ue) return false;
|
|
106
106
|
return true;
|
|
107
107
|
}
|
|
108
|
-
return e.
|
|
108
|
+
return e.Ue;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
function newQuestionInFlight(e) {
|
|
@@ -129,27 +129,27 @@ function computePendingState(e) {
|
|
|
129
129
|
return !!(n.se & REACTIVE_MANUAL_WRITE) || !n.Te && !(n.S & STATUS_PENDING) || !!(n.S & STATUS_PENDING) && quietPending(n);
|
|
130
130
|
}
|
|
131
131
|
if (e.De !== NOT_PENDING && !(t.S & STATUS_UNINITIALIZED)) {
|
|
132
|
-
if (hasActiveOverride(e)) return !e.
|
|
132
|
+
if (hasActiveOverride(e)) return !e.he || !e.he(e.De, unwrapOverride(e.Ae));
|
|
133
133
|
return true;
|
|
134
134
|
}
|
|
135
135
|
return newQuestionInFlight(t);
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
function syncCompanions(e, t) {
|
|
139
|
-
if (e.
|
|
139
|
+
if (e.Re) updatePendingSignal(e);
|
|
140
140
|
if (e.pe) setSignal(e.pe, t);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
function updatePendingSignal(e) {
|
|
144
|
-
if (e.
|
|
145
|
-
setSignal(e.
|
|
144
|
+
if (e.Re) {
|
|
145
|
+
setSignal(e.Re, computePendingState(e));
|
|
146
146
|
}
|
|
147
147
|
if (e.pe) updatePendingSignal(e.pe);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
function updateChildCompanions(e) {
|
|
151
151
|
for (let t = e.u; t !== null; t = t.fe) {
|
|
152
|
-
if (t.
|
|
152
|
+
if (t.Re || t.pe) updatePendingSignal(t);
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -167,7 +167,7 @@ function updateChildCompanions(e) {
|
|
|
167
167
|
const visit = e => {
|
|
168
168
|
if (i.has(e)) return;
|
|
169
169
|
i.add(e);
|
|
170
|
-
if (e.
|
|
170
|
+
if (e.Re || e.pe) n(e);
|
|
171
171
|
for (let t = e.o; t !== null; t = t.ue) visit(t.le);
|
|
172
172
|
for (let t = e.u ?? null; t !== null; t = t.fe) {
|
|
173
173
|
visit(t);
|
|
@@ -177,11 +177,11 @@ function updateChildCompanions(e) {
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
function snapCompanionsToState(e) {
|
|
180
|
-
const t = e.
|
|
180
|
+
const t = e.Re;
|
|
181
181
|
if (t && (t.Ae === undefined || t.Ae === NOT_PENDING)) {
|
|
182
182
|
const n = computePendingState(e);
|
|
183
|
-
if (t.
|
|
184
|
-
t.
|
|
183
|
+
if (t.be !== n || t.De !== NOT_PENDING) {
|
|
184
|
+
t.be = n;
|
|
185
185
|
t.De = NOT_PENDING;
|
|
186
186
|
t.Se = clock;
|
|
187
187
|
insertSubs(t);
|
|
@@ -190,7 +190,7 @@ function snapCompanionsToState(e) {
|
|
|
190
190
|
}
|
|
191
191
|
const n = e.pe;
|
|
192
192
|
if (n && !(n.se & REACTIVE_DISPOSED)) {
|
|
193
|
-
if ((n.Ae === undefined || n.Ae === NOT_PENDING) && n.De === NOT_PENDING && !Object.is(n.
|
|
193
|
+
if ((n.Ae === undefined || n.Ae === NOT_PENDING) && n.De === NOT_PENDING && !Object.is(n.be, e.be) && !(n.se & (REACTIVE_DIRTY | REACTIVE_CHECK))) {
|
|
194
194
|
n.se |= REACTIVE_DIRTY;
|
|
195
195
|
insertIntoHeap(n, queueFor(n));
|
|
196
196
|
insertSubs(n);
|
|
@@ -223,7 +223,7 @@ function getLatestValueComputed(e) {
|
|
|
223
223
|
const t = getLatestValueComputed(e);
|
|
224
224
|
const n = latestReadActive;
|
|
225
225
|
setLatestReadActive(false);
|
|
226
|
-
const i = e.Ae !== undefined && e.Ae !== NOT_PENDING ? unwrapOverride(e.Ae) : e.
|
|
226
|
+
const i = e.Ae !== undefined && e.Ae !== NOT_PENDING ? unwrapOverride(e.Ae) : e.be;
|
|
227
227
|
let r;
|
|
228
228
|
try {
|
|
229
229
|
// An untracked latest() read has no reading context, so read() never
|
|
@@ -279,9 +279,9 @@ function recordFreshRead(e, t) {
|
|
|
279
279
|
|
|
280
280
|
function applyReask(e, t) {
|
|
281
281
|
const n = !!(e.S & STATUS_PENDING);
|
|
282
|
-
const i = t && !(n && !e.
|
|
283
|
-
const r = n && e.
|
|
284
|
-
e.
|
|
282
|
+
const i = t && !(n && !e.Ue);
|
|
283
|
+
const r = n && e.Ue !== i;
|
|
284
|
+
e.Ue = i;
|
|
285
285
|
return r;
|
|
286
286
|
}
|
|
287
287
|
|
package/dist/prod/store/store.js
CHANGED
|
@@ -291,7 +291,7 @@ function ownEnumerableKeysPlain(e) {
|
|
|
291
291
|
* The value a store leaf's backing signal currently shows to readers: active
|
|
292
292
|
* override, else held pending value, else committed value.
|
|
293
293
|
*/ function visibleNodeValue(e) {
|
|
294
|
-
return e.Ae !== undefined && e.Ae !== NOT_PENDING ? unwrapOverride(e.Ae) : e.De !== NOT_PENDING ? e.De : e.
|
|
294
|
+
return e.Ae !== undefined && e.Ae !== NOT_PENDING ? unwrapOverride(e.Ae) : e.De !== NOT_PENDING ? e.De : e.be;
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
function hasOwnStoreProperty(e, t) {
|
package/package.json
CHANGED