@solidjs/signals 2.0.0-rc.17 → 2.0.0-rc.18
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-shared.js +296 -191
- package/dist/dev.attribution.js +16 -16
- package/dist/dev.js +527 -311
- package/dist/observe/core/async.js +148 -115
- package/dist/observe/core/constants.js +3 -1
- package/dist/observe/core/core.js +27 -27
- package/dist/observe/core/effect.js +29 -32
- package/dist/observe/core/graph.js +5 -5
- package/dist/observe/core/owner.js +7 -7
- package/dist/observe/core/scheduler.js +23 -12
- package/dist/observe/core/verdict.js +2 -2
- package/dist/observe/deferred.js +16 -13
- package/dist/observe/from.js +248 -0
- package/dist/observe/index.js +2 -0
- package/dist/observe/store/reconcile.js +137 -121
- package/dist/observe/store/store.js +595 -618
- package/dist/observe/store/target.js +1 -5
- package/dist/prod/core/async.js +209 -176
- package/dist/prod/core/constants.js +3 -1
- package/dist/prod/core/core.js +33 -33
- package/dist/prod/core/effect.js +24 -27
- package/dist/prod/core/graph.js +2 -2
- package/dist/prod/core/lanes.js +14 -14
- package/dist/prod/core/scheduler.js +35 -24
- package/dist/prod/core/truth.js +4 -4
- package/dist/prod/core/verdict.js +7 -7
- package/dist/prod/deferred.js +17 -14
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +2 -0
- package/dist/prod/store/optimistic.js +1 -1
- package/dist/prod/store/reconcile.js +137 -121
- package/dist/prod/store/store.js +94 -117
- package/dist/prod/store/target.js +13 -17
- package/dist/types/core/async.d.ts +12 -2
- package/dist/types/core/constants.d.ts +5 -0
- package/dist/types/core/core.d.ts +19 -3
- package/dist/types/core/scheduler.d.ts +15 -3
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/dev-shared.js
CHANGED
|
@@ -306,6 +306,8 @@ const defaultContext = {};
|
|
|
306
306
|
*/
|
|
307
307
|
const $REFRESH = Symbol("refresh");
|
|
308
308
|
|
|
309
|
+
const NewSet = Set;
|
|
310
|
+
|
|
309
311
|
let attrHooks = null;
|
|
310
312
|
/**
|
|
311
313
|
* The installed engine, registered on `globalThis` as well (the records
|
|
@@ -2032,8 +2034,18 @@ function nextQuestion() {
|
|
|
2032
2034
|
}
|
|
2033
2035
|
const MAINLINE_QUESTION = 0x7fffffff;
|
|
2034
2036
|
let inEffectCallback = false;
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
+
/** Dev-only: matches no event, so a window or phase holding it applies
|
|
2038
|
+
* whatever event is current (see `strictReadEvent`, core.ts). */
|
|
2039
|
+
const ANY_EVENT = {};
|
|
2040
|
+
/** Dev-only: the DOM event current when the effect phase was entered. A
|
|
2041
|
+
* handler dispatched synchronously from that phase (`el.focus()`) runs under
|
|
2042
|
+
* a different event and is not in it (#4235). */
|
|
2043
|
+
let effectCallbackEvent = ANY_EVENT;
|
|
2044
|
+
function setEffectCallback(value, event = ANY_EVENT) {
|
|
2045
|
+
{
|
|
2046
|
+
inEffectCallback = value;
|
|
2047
|
+
effectCallbackEvent = event;
|
|
2048
|
+
}
|
|
2037
2049
|
}
|
|
2038
2050
|
function schedule() {
|
|
2039
2051
|
if (halted) {
|
|
@@ -2421,8 +2433,9 @@ class GlobalQueue {
|
|
|
2421
2433
|
* or without the held read) owes nothing. A run this transaction stashed
|
|
2422
2434
|
* for it is void (#3322: an effect has one value slot, and the stale pass
|
|
2423
2435
|
* overwrote the value that run was for) — the re-derivation's run replaces
|
|
2424
|
-
* it. */
|
|
2436
|
+
* it. Truthy when an effect re-derives (`land`). */
|
|
2425
2437
|
function reruns(u) {
|
|
2438
|
+
let frame;
|
|
2426
2439
|
for (let i = 0; i < u._reruns.length; i++) {
|
|
2427
2440
|
const r = u._reruns[i];
|
|
2428
2441
|
// An errored reader's display is its error (D-39): the landing gives it
|
|
@@ -2430,6 +2443,7 @@ function reruns(u) {
|
|
|
2430
2443
|
// errored source (#3945).
|
|
2431
2444
|
if (r._flags & REACTIVE_DISPOSED || r._statusFlags & STATUS_ERROR) continue;
|
|
2432
2445
|
if (r._flags & REACTIVE_FRAME_READ || r._config & CONFIG_VERDICT) {
|
|
2446
|
+
frame ||= r._type;
|
|
2433
2447
|
r._flags &= ~REACTIVE_FRAME_READ;
|
|
2434
2448
|
r._modified = false;
|
|
2435
2449
|
// Its frame is replaced by the re-derivation: a run one of its
|
|
@@ -2440,13 +2454,14 @@ function reruns(u) {
|
|
|
2440
2454
|
}
|
|
2441
2455
|
}
|
|
2442
2456
|
u._reruns.length = 0;
|
|
2457
|
+
return frame;
|
|
2443
2458
|
}
|
|
2444
2459
|
/** The landing: the held frame becomes the frame. */
|
|
2445
2460
|
function land(u) {
|
|
2446
2461
|
// Attribution hook: judged complete — its held writes commit next
|
|
2447
2462
|
// (`_nodes` still lists them).
|
|
2448
2463
|
if (attrHooks !== null) attrHooks.transitionSettled(u);
|
|
2449
|
-
reruns(u);
|
|
2464
|
+
const frame = reruns(u);
|
|
2450
2465
|
if (u._marks !== null) releaseMarksHook(u._marks);
|
|
2451
2466
|
// Old children die in the commits (cleanups first), then the stashed
|
|
2452
2467
|
// effects run ahead of this flush's own. A node a lane took over since
|
|
@@ -2461,7 +2476,16 @@ function land(u) {
|
|
|
2461
2476
|
// `u`, which has left `transactions`: the write is this landing's, and
|
|
2462
2477
|
// the next flush must not park in it (#4089).
|
|
2463
2478
|
if (flushTransaction === u) flushTransaction = null;
|
|
2464
|
-
|
|
2479
|
+
// An effect re-derives next round (`reruns`): the held runs wait for it
|
|
2480
|
+
// (D-9, the A15 reveal corollary, #4071). Its re-derivation can discover a
|
|
2481
|
+
// flight — a stale reader whose mainline pass stopped reading it, now
|
|
2482
|
+
// reading the landed world — and a landing that showed its runs first
|
|
2483
|
+
// would reveal the held write beside a frame that can only show its old
|
|
2484
|
+
// value. Queued last in this effect phase, the release hands them to the
|
|
2485
|
+
// next round's own runs, ahead of the re-derivation's: they show with it,
|
|
2486
|
+
// or park with it in the hold its pending opens. The commits stand.
|
|
2487
|
+
if (frame) globalQueue._queues[1].push(() => releaseQueues(u));
|
|
2488
|
+
else releaseQueues(u);
|
|
2465
2489
|
}
|
|
2466
2490
|
/** The held runs join this flush's effect phase after its own runs (the
|
|
2467
2491
|
* landing's re-passes, in height order): the frame's effects run as one
|
|
@@ -2720,8 +2744,22 @@ function flush(fn) {
|
|
|
2720
2744
|
// (owner.ts).
|
|
2721
2745
|
rethrowCleanupError();
|
|
2722
2746
|
}
|
|
2747
|
+
/** Dev-only: the DOM event current when the running effect queue started,
|
|
2748
|
+
* or `ANY_EVENT` outside one. Read once per queue rather than once per
|
|
2749
|
+
* effect (the getter is costly under jsdom); no event starts or ends between
|
|
2750
|
+
* two effects of one synchronous queue (#4235). */
|
|
2751
|
+
let queueEvent = ANY_EVENT;
|
|
2723
2752
|
function runQueue(queue, type) {
|
|
2724
|
-
|
|
2753
|
+
{
|
|
2754
|
+
const prev = queueEvent;
|
|
2755
|
+
queueEvent = dispatchingEvent();
|
|
2756
|
+
try {
|
|
2757
|
+
for (let i = 0; i < queue.length; i++) queue[i](type);
|
|
2758
|
+
} finally {
|
|
2759
|
+
queueEvent = prev;
|
|
2760
|
+
}
|
|
2761
|
+
return;
|
|
2762
|
+
}
|
|
2725
2763
|
}
|
|
2726
2764
|
|
|
2727
2765
|
/**
|
|
@@ -2943,7 +2981,7 @@ function unobserved(el) {
|
|
|
2943
2981
|
* reclamation still happens within one microtask — the enqueue site arms
|
|
2944
2982
|
* schedule(), so a flush is guaranteed even when no other work is queued.
|
|
2945
2983
|
*/
|
|
2946
|
-
const dormantNodes = new
|
|
2984
|
+
const dormantNodes = new NewSet();
|
|
2947
2985
|
function sweepDormant() {
|
|
2948
2986
|
if (dormantNodes.size === 0) return;
|
|
2949
2987
|
for (const el of dormantNodes) {
|
|
@@ -3011,7 +3049,7 @@ function link(dep, sub) {
|
|
|
3011
3049
|
// to clear it, stranding the Set members' pending forever (#2893).
|
|
3012
3050
|
function addPendingSource(el, source) {
|
|
3013
3051
|
if (el._x?._pendingSources?.has(source)) return false;
|
|
3014
|
-
(ext(el)._pendingSources ??= new
|
|
3052
|
+
(ext(el)._pendingSources ??= new NewSet()).add(source);
|
|
3015
3053
|
return true;
|
|
3016
3054
|
}
|
|
3017
3055
|
function removePendingSource(el, source) {
|
|
@@ -3094,7 +3132,7 @@ function releaseIfSettledUnobserved(node) {
|
|
|
3094
3132
|
// Collect-then-release so unobserved() never unlinks under the walk.
|
|
3095
3133
|
function releaseSettledDependents(el) {
|
|
3096
3134
|
let candidates;
|
|
3097
|
-
const visited = new
|
|
3135
|
+
const visited = new NewSet();
|
|
3098
3136
|
const visit = node => {
|
|
3099
3137
|
if (visited.has(node)) return;
|
|
3100
3138
|
visited.add(node);
|
|
@@ -3160,7 +3198,7 @@ function stageError(el, error, inPass) {
|
|
|
3160
3198
|
}
|
|
3161
3199
|
function settleErroredDependents(el, error) {
|
|
3162
3200
|
let scheduled = false;
|
|
3163
|
-
const visited = new
|
|
3201
|
+
const visited = new NewSet();
|
|
3164
3202
|
const visit = node => {
|
|
3165
3203
|
if (visited.has(node)) return;
|
|
3166
3204
|
visited.add(node);
|
|
@@ -3237,7 +3275,7 @@ function settlePendingSource(el, source = el) {
|
|
|
3237
3275
|
removePendingSource(el, source);
|
|
3238
3276
|
let scheduled = false;
|
|
3239
3277
|
let released;
|
|
3240
|
-
const visited = new
|
|
3278
|
+
const visited = new NewSet();
|
|
3241
3279
|
const settle = node => {
|
|
3242
3280
|
if (
|
|
3243
3281
|
visited.has(node) ||
|
|
@@ -3304,6 +3342,37 @@ function releaseFlightTeardown(el) {
|
|
|
3304
3342
|
teardown();
|
|
3305
3343
|
}
|
|
3306
3344
|
}
|
|
3345
|
+
/**
|
|
3346
|
+
* Internal (not a package export): run `fn` when the current pass's flight
|
|
3347
|
+
* is superseded, at the same instant as the iterator close above, instead of
|
|
3348
|
+
* when the replacing pass commits (owner cleanups wait for that). Chains onto
|
|
3349
|
+
* the node's teardown slot; fires once with it. A no-op unless the ambient
|
|
3350
|
+
* owner is a computed in its own pass. `consumeIterator` fills the slot
|
|
3351
|
+
* before its first pull, so a source opened in an async generator's body
|
|
3352
|
+
* (`for await`) composes after the generator's close.
|
|
3353
|
+
*/
|
|
3354
|
+
function onSupersede(fn) {
|
|
3355
|
+
const el = context;
|
|
3356
|
+
if (el === null || el._fn === undefined || !(el._flags & REACTIVE_RECOMPUTING_DEPS)) return;
|
|
3357
|
+
const fresh = el._x === null;
|
|
3358
|
+
const x = ext(el);
|
|
3359
|
+
// Allocating the extension mid-run turns `_x?._inFlight` from undefined into
|
|
3360
|
+
// null, which recompute would read as a flight this body registered itself.
|
|
3361
|
+
// Restore undefined here, so the fix costs nothing for code that never
|
|
3362
|
+
// calls onSupersede.
|
|
3363
|
+
if (fresh) x._inFlight = undefined;
|
|
3364
|
+
const prev = x._flightTeardown;
|
|
3365
|
+
x._flightTeardown =
|
|
3366
|
+
prev === null
|
|
3367
|
+
? fn
|
|
3368
|
+
: () => {
|
|
3369
|
+
try {
|
|
3370
|
+
prev();
|
|
3371
|
+
} finally {
|
|
3372
|
+
fn();
|
|
3373
|
+
}
|
|
3374
|
+
};
|
|
3375
|
+
}
|
|
3307
3376
|
function handleAsync(
|
|
3308
3377
|
el,
|
|
3309
3378
|
result,
|
|
@@ -3407,8 +3476,14 @@ function handleAsync(
|
|
|
3407
3476
|
// D-41: a held node's error is staged (`stageError`). A derived store's
|
|
3408
3477
|
// readers learn its error through the family, not the derive's
|
|
3409
3478
|
// dependents: it publishes now.
|
|
3410
|
-
if (stillPending || setter || !stageError(el, error))
|
|
3479
|
+
if (stillPending || setter || !stageError(el, error)) {
|
|
3411
3480
|
notifyStatus(el, stillPending ? STATUS_PENDING : STATUS_ERROR, error);
|
|
3481
|
+
// The error is this pass's answer, published now: it replaces the shown
|
|
3482
|
+
// frame as a value's commit would (`commitPendingNode`), so the frame
|
|
3483
|
+
// the pass parked goes instead of waiting for a later success. A no-op
|
|
3484
|
+
// when nothing is parked.
|
|
3485
|
+
if (!stillPending) disposeChildren(el, false, true);
|
|
3486
|
+
}
|
|
3412
3487
|
// A NotReady rejection is a landing into another pending source. The
|
|
3413
3488
|
// rejected flight will never settle its self entry, so transfer ownership
|
|
3414
3489
|
// after notifyStatus has propagated the replacement source.
|
|
@@ -3523,7 +3598,11 @@ function handleAsync(
|
|
|
3523
3598
|
cleanup(close, owner);
|
|
3524
3599
|
// Flight-identity cancellation (#3122): the registration above is the
|
|
3525
3600
|
// owner-death backstop; the teardown slot fires at the _inFlight release
|
|
3526
|
-
// sites so supersede stops this stream immediately.
|
|
3601
|
+
// sites so supersede stops this stream immediately. Assigned, not
|
|
3602
|
+
// chained (chaining here costs every app bytes): it replaces any
|
|
3603
|
+
// `onSupersede` teardown this run registered earlier, which then falls
|
|
3604
|
+
// back to the owner-cleanup channel. A returned `from()` is unaffected:
|
|
3605
|
+
// `close` calls its `return()`, which runs its own teardown.
|
|
3527
3606
|
ext(el)._flightTeardown = close;
|
|
3528
3607
|
// Release check before each next pull: an unobserved lazy node must tear
|
|
3529
3608
|
// down (its close above runs via disposal, closing the iterator) instead
|
|
@@ -3686,12 +3765,12 @@ function handleAsync(
|
|
|
3686
3765
|
handleError(syncError);
|
|
3687
3766
|
throw syncError;
|
|
3688
3767
|
} else if (!resolved) {
|
|
3689
|
-
//
|
|
3690
|
-
// work on a loadingValue node is
|
|
3691
|
-
// boundaries
|
|
3692
|
-
// lands through asyncWrite.
|
|
3693
|
-
|
|
3694
|
-
|
|
3768
|
+
// Not landed: the shared tail below suspends, or — loading window —
|
|
3769
|
+
// serves commit #0 (first-flight work on a loadingValue node is
|
|
3770
|
+
// loading-class, invisible to boundaries; the flight itself is already
|
|
3771
|
+
// registered in _inFlight and lands through asyncWrite). A promise is
|
|
3772
|
+
// never an iterator, so nothing between here and there runs.
|
|
3773
|
+
liveLanded = false;
|
|
3695
3774
|
} else if (!flattenIfIterable(syncValue)) {
|
|
3696
3775
|
// Synchronously-resolved promise: the first real answer landed.
|
|
3697
3776
|
el._loading = false;
|
|
@@ -3703,7 +3782,7 @@ function handleAsync(
|
|
|
3703
3782
|
if (iterator) flattenIfIterable(result);
|
|
3704
3783
|
if (liveLanded !== null) {
|
|
3705
3784
|
if (!liveLanded) {
|
|
3706
|
-
// Loading window: serve commit #0
|
|
3785
|
+
// Loading window: serve commit #0 instead of suspending.
|
|
3707
3786
|
if (el._loading) return el._value;
|
|
3708
3787
|
throw new NotReadyError(context);
|
|
3709
3788
|
}
|
|
@@ -3715,7 +3794,7 @@ function handleAsync(
|
|
|
3715
3794
|
}
|
|
3716
3795
|
function clearStatus(el, clearUninitialized = false) {
|
|
3717
3796
|
if (el._x?._pendingSources) clearPendingSources(el);
|
|
3718
|
-
if (el._x?._blocked)
|
|
3797
|
+
if (el._x?._blocked) el._x._blocked = false;
|
|
3719
3798
|
el._statusFlags = clearUninitialized ? 0 : el._statusFlags & STATUS_UNINITIALIZED;
|
|
3720
3799
|
if (el._x?._error) setPendingError(el);
|
|
3721
3800
|
const notify = statusNotifierOf(el);
|
|
@@ -3755,7 +3834,7 @@ function landStatus(el, clearUninitialized = false) {
|
|
|
3755
3834
|
setPendingError(el, sources.values().next().value);
|
|
3756
3835
|
} else clearStatus(el, clearUninitialized);
|
|
3757
3836
|
}
|
|
3758
|
-
function notifyStatus(el, status, error
|
|
3837
|
+
function notifyStatus(el, status, error) {
|
|
3759
3838
|
// Wrap regular errors to track source node
|
|
3760
3839
|
if (
|
|
3761
3840
|
status === STATUS_ERROR &&
|
|
@@ -3766,21 +3845,19 @@ function notifyStatus(el, status, error, blockStatus) {
|
|
|
3766
3845
|
const pendingSource =
|
|
3767
3846
|
status === STATUS_PENDING && error instanceof NotReadyError ? error.source : undefined;
|
|
3768
3847
|
// (CARVE 2: the lane assignment went with the engine.)
|
|
3769
|
-
{
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
el._statusFlags
|
|
3781
|
-
|
|
3782
|
-
ext(el)._error = error;
|
|
3783
|
-
}
|
|
3848
|
+
if (status === STATUS_PENDING && pendingSource) {
|
|
3849
|
+
// D-41: a re-ask of a shown error keeps it the display (`_shownError`).
|
|
3850
|
+
if (el._statusFlags & STATUS_ERROR) el._x._shownError = el._x._error;
|
|
3851
|
+
addPendingSource(el, pendingSource);
|
|
3852
|
+
el._statusFlags = STATUS_PENDING | (el._statusFlags & STATUS_UNINITIALIZED);
|
|
3853
|
+
// Preserve the current source on this propagation so readers park on
|
|
3854
|
+
// the distinct pending source.
|
|
3855
|
+
setPendingError(el, pendingSource, error);
|
|
3856
|
+
} else {
|
|
3857
|
+
clearPendingSources(el);
|
|
3858
|
+
el._statusFlags =
|
|
3859
|
+
status | (status !== STATUS_ERROR ? el._statusFlags & STATUS_UNINITIALIZED : 0);
|
|
3860
|
+
ext(el)._error = error;
|
|
3784
3861
|
}
|
|
3785
3862
|
// Lanes: a written guess is an optimistic boundary (A17 — "the optimistic
|
|
3786
3863
|
// future value until we know otherwise"). Its own source in flight is its
|
|
@@ -3794,9 +3871,7 @@ function notifyStatus(el, status, error, blockStatus) {
|
|
|
3794
3871
|
}
|
|
3795
3872
|
const elNotify = statusNotifierOf(el);
|
|
3796
3873
|
if (elNotify) {
|
|
3797
|
-
|
|
3798
|
-
elNotify.call(el);
|
|
3799
|
-
}
|
|
3874
|
+
elNotify.call(el);
|
|
3800
3875
|
return;
|
|
3801
3876
|
}
|
|
3802
3877
|
propagateStatus(el, status, error);
|
|
@@ -3806,7 +3881,7 @@ function notifyStatus(el, status, error, blockStatus) {
|
|
|
3806
3881
|
* family's leaves, which are not the derive's dependents — the family
|
|
3807
3882
|
* propagates the derive's status from each leaf to the leaf's readers
|
|
3808
3883
|
* (store/projection.ts `wakeFamily`), exactly as a memo's would reach its. */
|
|
3809
|
-
function propagateStatus(el, status, error
|
|
3884
|
+
function propagateStatus(el, status, error) {
|
|
3810
3885
|
const pendingSource =
|
|
3811
3886
|
status === STATUS_PENDING && error instanceof NotReadyError ? error.source : undefined;
|
|
3812
3887
|
forEachDependent(el, (sub, link) => {
|
|
@@ -3863,23 +3938,21 @@ function propagateStatus(el, status, error, downstreamBlockStatus) {
|
|
|
3863
3938
|
// bookkeeping (loading window, uninitialized clear) runs with the flush
|
|
3864
3939
|
// — with the lane, when the pass propagating is the lane's work and
|
|
3865
3940
|
// the dependent's pending is the lane's own flight (`laneStage`).
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
)
|
|
3881
|
-
joinFuture(txOf(sub));
|
|
3882
|
-
}
|
|
3941
|
+
// (No answer: a pending propagation leaves a written guess a guess.)
|
|
3942
|
+
if (laneStageHook && passLane !== null) laneStageHook(sub, passLane, true, el);
|
|
3943
|
+
else {
|
|
3944
|
+
queuePendingNode(sub);
|
|
3945
|
+
// A15 (#3443): pending propagates onto a held memo without
|
|
3946
|
+
// recomputing it, and the propagation itself enters the memo's
|
|
3947
|
+
// transaction — the flight flows into a memo that transaction
|
|
3948
|
+
// holds, so the write that started it is held with it. A render
|
|
3949
|
+
// effect's membership is its pass's (`notify`), never sticky.
|
|
3950
|
+
if (
|
|
3951
|
+
status === STATUS_PENDING &&
|
|
3952
|
+
(sub._config & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD &&
|
|
3953
|
+
!sub._type
|
|
3954
|
+
)
|
|
3955
|
+
joinFuture(txOf(sub));
|
|
3883
3956
|
}
|
|
3884
3957
|
notifyStatus(sub, status, error);
|
|
3885
3958
|
}
|
|
@@ -3945,7 +4018,11 @@ const PRIMITIVE_IN_EFFECT_CALLBACK_MESSAGE =
|
|
|
3945
4018
|
* created there is inert and harmless. Tracked effects and onSettled are
|
|
3946
4019
|
* children-forbidden and refuse through PRIMITIVE_IN_FORBIDDEN_SCOPE. */
|
|
3947
4020
|
function assertNotInEffectCallback() {
|
|
3948
|
-
if (
|
|
4021
|
+
if (
|
|
4022
|
+
inEffectCallback &&
|
|
4023
|
+
context === null &&
|
|
4024
|
+
(effectCallbackEvent === ANY_EVENT || dispatchingEvent() === effectCallbackEvent)
|
|
4025
|
+
) {
|
|
3949
4026
|
emitDiagnostic({
|
|
3950
4027
|
code: "PRIMITIVE_IN_EFFECT_CALLBACK",
|
|
3951
4028
|
kind: "lifecycle",
|
|
@@ -3978,7 +4055,7 @@ function ownerInSnapshotScope(owner) {
|
|
|
3978
4055
|
}
|
|
3979
4056
|
function setSnapshotCapture(active) {
|
|
3980
4057
|
snapshotCaptureActive = active;
|
|
3981
|
-
if (active && !snapshotSources) snapshotSources = new
|
|
4058
|
+
if (active && !snapshotSources) snapshotSources = new NewSet();
|
|
3982
4059
|
}
|
|
3983
4060
|
function markSnapshotScope(owner) {
|
|
3984
4061
|
owner._snapshotScope = true;
|
|
@@ -4907,7 +4984,7 @@ function setEffectStatusNotify(fn) {
|
|
|
4907
4984
|
* Presence doubles as the "display consumer" membership test in the status
|
|
4908
4985
|
* walks, exactly as the per-node field did when every effect carried one. */
|
|
4909
4986
|
function statusNotifierOf(el) {
|
|
4910
|
-
return el._type ?
|
|
4987
|
+
return el._type ? effectStatusNotify : null;
|
|
4911
4988
|
}
|
|
4912
4989
|
const lazyOptions = { lazy: true };
|
|
4913
4990
|
function setupComputedNode(self, options) {
|
|
@@ -5056,11 +5133,31 @@ function exitDisposal() {
|
|
|
5056
5133
|
function resetDisposalDepth() {
|
|
5057
5134
|
disposalDepth = 0;
|
|
5058
5135
|
}
|
|
5059
|
-
|
|
5136
|
+
/**
|
|
5137
|
+
* Dev-only: the DOM event being dispatched when the open strict-read window
|
|
5138
|
+
* opened (`globalThis.event`; null between dispatches and off the main
|
|
5139
|
+
* thread's Window), or `ANY_EVENT` when the window did not record one. A DOM
|
|
5140
|
+
* call made in an effect callback that dispatches events synchronously
|
|
5141
|
+
* (`el.focus()`, `el.click()`, `dialog.showModal()`) runs that event's
|
|
5142
|
+
* handlers inside the window; a handler is a one-shot snapshot whoever
|
|
5143
|
+
* dispatched the event, so a read made while a different event is current is
|
|
5144
|
+
* outside the window (#4235). Only queued effect runs record the event, read
|
|
5145
|
+
* once per queue (the getter is costly under jsdom); `strictReadActive` is
|
|
5146
|
+
* the check.
|
|
5147
|
+
*/
|
|
5148
|
+
let strictReadEvent;
|
|
5149
|
+
// `?? null`: no current event must not read as a missing argument below.
|
|
5150
|
+
const dispatchingEvent = () => globalThis.event ?? null;
|
|
5151
|
+
function setStrictRead(v, event = ANY_EVENT) {
|
|
5060
5152
|
const prev = strictRead;
|
|
5061
5153
|
strictRead = v;
|
|
5154
|
+
strictReadEvent = event;
|
|
5062
5155
|
return prev;
|
|
5063
5156
|
}
|
|
5157
|
+
/** Dev-only: is the strict-read window open for a read made now? */
|
|
5158
|
+
function strictReadActive() {
|
|
5159
|
+
return !!strictRead && (strictReadEvent === ANY_EVENT || dispatchingEvent() === strictReadEvent);
|
|
5160
|
+
}
|
|
5064
5161
|
/**
|
|
5065
5162
|
* Runs `fn` outside of any reactive tracking — reads inside `fn` will not
|
|
5066
5163
|
* subscribe the current scope. Returns whatever `fn` returns.
|
|
@@ -5099,9 +5196,11 @@ function setStrictRead(v) {
|
|
|
5099
5196
|
function untrack(fn, strictReadLabel) {
|
|
5100
5197
|
const prevTracking = tracking;
|
|
5101
5198
|
const prevStrictRead = strictRead;
|
|
5199
|
+
const prevStrictReadEvent = strictReadEvent;
|
|
5102
5200
|
tracking = false;
|
|
5103
5201
|
{
|
|
5104
5202
|
strictRead = strictReadLabel || false;
|
|
5203
|
+
strictReadEvent = ANY_EVENT;
|
|
5105
5204
|
untrackDepth++;
|
|
5106
5205
|
}
|
|
5107
5206
|
try {
|
|
@@ -5111,6 +5210,7 @@ function untrack(fn, strictReadLabel) {
|
|
|
5111
5210
|
tracking = prevTracking;
|
|
5112
5211
|
{
|
|
5113
5212
|
strictRead = prevStrictRead;
|
|
5213
|
+
strictReadEvent = prevStrictReadEvent;
|
|
5114
5214
|
untrackDepth--;
|
|
5115
5215
|
}
|
|
5116
5216
|
}
|
|
@@ -5317,7 +5417,7 @@ function read(el) {
|
|
|
5317
5417
|
stagedRead(c);
|
|
5318
5418
|
return el._pendingValue;
|
|
5319
5419
|
}
|
|
5320
|
-
if (strictRead && owner._statusFlags & STATUS_PENDING)
|
|
5420
|
+
if (strictRead && owner._statusFlags & STATUS_PENDING && strictReadActive())
|
|
5321
5421
|
throwPendingUntrackedRead(strictRead, {
|
|
5322
5422
|
ownerId: c?.id,
|
|
5323
5423
|
ownerName: c?._name,
|
|
@@ -5438,7 +5538,7 @@ function read(el) {
|
|
|
5438
5538
|
// Ahead of the snapshot serve below: a component body's direct read is
|
|
5439
5539
|
// wrong in the same way whether the pass is hydrating or not, and the
|
|
5440
5540
|
// hydration pass is the console nobody is watching (#3675).
|
|
5441
|
-
if (strictRead)
|
|
5541
|
+
if (strictRead && strictReadActive())
|
|
5442
5542
|
warnStrictReadUntracked(strictRead, {
|
|
5443
5543
|
ownerId: c?.id,
|
|
5444
5544
|
ownerName: c?._name,
|
|
@@ -5865,7 +5965,7 @@ export {
|
|
|
5865
5965
|
CONFIG_STAGED as Z,
|
|
5866
5966
|
merge as _,
|
|
5867
5967
|
NotReadyError as a,
|
|
5868
|
-
|
|
5968
|
+
resetUnhandledAsync as a$,
|
|
5869
5969
|
REACTIVE_JOINED as a0,
|
|
5870
5970
|
REACTIVE_STAGED_READ as a1,
|
|
5871
5971
|
stagedRead as a2,
|
|
@@ -5876,135 +5976,140 @@ export {
|
|
|
5876
5976
|
verdict as a7,
|
|
5877
5977
|
link as a8,
|
|
5878
5978
|
pullComputed as a9,
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5979
|
+
signal as aA,
|
|
5980
|
+
setSignal as aB,
|
|
5981
|
+
cleanup as aC,
|
|
5982
|
+
read as aD,
|
|
5983
|
+
DEV as aE,
|
|
5984
|
+
CONFIG_TRANSPARENT as aF,
|
|
5985
|
+
NoOwnerError as aG,
|
|
5986
|
+
ContextNotFoundError as aH,
|
|
5987
|
+
createEffectNode as aI,
|
|
5988
|
+
recompute as aJ,
|
|
5989
|
+
EFFECT_USER as aK,
|
|
5990
|
+
reportDiagnostic as aL,
|
|
5991
|
+
computed as aM,
|
|
5992
|
+
staleValues as aN,
|
|
5993
|
+
CONFIG_AUTO_DISPOSE as aO,
|
|
5994
|
+
EFFECT_TRACKED as aP,
|
|
5995
|
+
heldRunHook as aQ,
|
|
5996
|
+
unwrapStatusError as aR,
|
|
5997
|
+
setStrictRead as aS,
|
|
5998
|
+
queueEvent as aT,
|
|
5999
|
+
StatusError as aU,
|
|
6000
|
+
trimStaleDeps as aV,
|
|
6001
|
+
haltReactivityAt as aW,
|
|
6002
|
+
strictReadEvent as aX,
|
|
6003
|
+
setTrackedQueueCallback as aY,
|
|
6004
|
+
setEffectStatusNotify as aZ,
|
|
6005
|
+
_hitUnhandledAsync as a_,
|
|
5906
6006
|
strictRead as aa,
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
6007
|
+
strictReadActive as ab,
|
|
6008
|
+
warnStrictReadUntracked as ac,
|
|
6009
|
+
staleReader as ad,
|
|
6010
|
+
globalQueue as ae,
|
|
6011
|
+
joinPass as af,
|
|
6012
|
+
markLateLinker as ag,
|
|
6013
|
+
spectating as ah,
|
|
6014
|
+
unflushedValue as ai,
|
|
6015
|
+
CONFIG_STAGED_ERROR as aj,
|
|
6016
|
+
stagedReaders as ak,
|
|
6017
|
+
bornInto as al,
|
|
6018
|
+
enterAction as am,
|
|
6019
|
+
setEffectCallback as an,
|
|
6020
|
+
exitAction as ao,
|
|
6021
|
+
isThenable as ap,
|
|
6022
|
+
actionDepth as aq,
|
|
6023
|
+
flush as ar,
|
|
6024
|
+
setQuestion as as,
|
|
6025
|
+
emitDiagnostic as at,
|
|
6026
|
+
enterCallback as au,
|
|
6027
|
+
exitCallback as av,
|
|
6028
|
+
getOwner as aw,
|
|
6029
|
+
inEffectCallback as ax,
|
|
6030
|
+
effectCallbackEvent as ay,
|
|
6031
|
+
setExternalHooks as az,
|
|
5932
6032
|
CONFIG_AUTHORITATIVE as b,
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
6033
|
+
resetErrorHalt as b$,
|
|
6034
|
+
ROOT_ERROR_HOOK as b0,
|
|
6035
|
+
registerGraph as b1,
|
|
6036
|
+
runWithOwner as b2,
|
|
6037
|
+
setMemo as b3,
|
|
6038
|
+
$REFRESH as b4,
|
|
6039
|
+
markRefresh as b5,
|
|
6040
|
+
createRoot as b6,
|
|
6041
|
+
getObserver as b7,
|
|
6042
|
+
dispose as b8,
|
|
6043
|
+
TimeoutError as b9,
|
|
6044
|
+
handleAsync as bA,
|
|
6045
|
+
addPendingSource as bB,
|
|
6046
|
+
propagateStatus as bC,
|
|
6047
|
+
forEachDependent as bD,
|
|
6048
|
+
settlePendingSource as bE,
|
|
6049
|
+
joinPassAt as bF,
|
|
6050
|
+
notifyEpoch as bG,
|
|
6051
|
+
SUPPORTS_PROXY as bH,
|
|
6052
|
+
releaseMarksHook as bI,
|
|
6053
|
+
installMarkHooks as bJ,
|
|
6054
|
+
CONFIG_LAGS as bK,
|
|
6055
|
+
REACTIVE_REASK as bL,
|
|
6056
|
+
onSupersede as bM,
|
|
6057
|
+
haltReactivity as bN,
|
|
6058
|
+
heldUnder as bO,
|
|
6059
|
+
unhold as bP,
|
|
6060
|
+
laneStageHook as bQ,
|
|
6061
|
+
REACTIVE_ZOMBIE as bR,
|
|
6062
|
+
installBoundaryHooks as bS,
|
|
6063
|
+
CAUGHT_REARMED as bT,
|
|
6064
|
+
OBSERVE as bU,
|
|
6065
|
+
clearSnapshots as bV,
|
|
6066
|
+
enforceLoadingBoundary as bW,
|
|
6067
|
+
getNextChildId as bX,
|
|
6068
|
+
markSnapshotScope as bY,
|
|
6069
|
+
peekNextChildId as bZ,
|
|
6070
|
+
releaseSnapshotScope as b_,
|
|
6071
|
+
untrack as ba,
|
|
6072
|
+
dirtyQueue as bb,
|
|
6073
|
+
CONFIG_REDERIVE as bc,
|
|
6074
|
+
passTx as bd,
|
|
6075
|
+
CONFIG_FRESH_READ as be,
|
|
6076
|
+
createOwner as bf,
|
|
6077
|
+
writeHook as bg,
|
|
6078
|
+
REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE as bh,
|
|
6079
|
+
ownedScopeWriteMessage as bi,
|
|
6080
|
+
isEqual as bj,
|
|
6081
|
+
CONFIG_MANUAL_WRITE as bk,
|
|
6082
|
+
snapshotCaptureActive as bl,
|
|
6083
|
+
captureWriteSnapshot as bm,
|
|
6084
|
+
notePromotedWrite as bn,
|
|
6085
|
+
slotSignal as bo,
|
|
6086
|
+
stagedScreen as bp,
|
|
6087
|
+
CONFIG_PROMOTED as bq,
|
|
6088
|
+
setSlotUnobserved as br,
|
|
6089
|
+
installStoreHooks as bs,
|
|
6090
|
+
joinPassTx as bt,
|
|
6091
|
+
asyncTailFlights as bu,
|
|
6092
|
+
untrackDepth as bv,
|
|
6093
|
+
checkPostAwaitRead as bw,
|
|
6094
|
+
disposalDepth as bx,
|
|
6095
|
+
insertIntoHeap as by,
|
|
6096
|
+
isDisposed as bz,
|
|
5997
6097
|
CONFIG_OVERRIDE as c,
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6098
|
+
setConsoleFooter as c0,
|
|
6099
|
+
setSnapshotCapture as c1,
|
|
6100
|
+
setWriteHook as c2,
|
|
6101
|
+
setAttributionHooks as c3,
|
|
6102
|
+
liveRootOwners as c4,
|
|
6103
|
+
ownerPath as c5,
|
|
6104
|
+
isSuppressed as c6,
|
|
6105
|
+
blockersOf as c7,
|
|
6106
|
+
CONFIG_PLUMBING as c8,
|
|
6107
|
+
anyExcluded as c9,
|
|
6108
|
+
isExcluded as ca,
|
|
6109
|
+
CONFIG_WIDE as cb,
|
|
6110
|
+
GRAPH_SIZE_WARN_AT as cc,
|
|
6111
|
+
noteFanOut as cd,
|
|
6112
|
+
CONFIG_SUPERSEDES as ce,
|
|
6008
6113
|
newTransaction as d,
|
|
6009
6114
|
enqueueSub as e,
|
|
6010
6115
|
CONFIG_VERDICT as f,
|