@solidjs/signals 2.0.0-beta.31 → 2.0.0-beta.33
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 +250 -89
- package/dist/node.cjs +775 -637
- package/dist/prod/core/async.js +131 -62
- package/dist/prod/core/core.js +231 -194
- package/dist/prod/core/effect.js +27 -27
- package/dist/prod/core/external.js +4 -4
- package/dist/prod/core/graph.js +32 -32
- package/dist/prod/core/heap.js +36 -36
- package/dist/prod/core/lanes.js +14 -14
- package/dist/prod/core/optimistic.js +37 -37
- package/dist/prod/core/owner.js +53 -44
- package/dist/prod/core/scheduler.js +74 -70
- package/dist/prod/core/verdict.js +57 -46
- package/dist/prod/map.js +6 -6
- package/dist/prod/signals.js +2 -34
- package/dist/prod/store/optimistic.js +35 -30
- package/dist/prod/store/projection.js +41 -6
- package/dist/prod/store/store.js +7 -7
- package/dist/types/core/async.d.ts +9 -0
- package/dist/types/core/types.d.ts +24 -0
- package/dist/types/signals.d.ts +60 -4
- package/dist/types/store/store.d.ts +14 -0
- package/dist/types-cjs/core/async.d.cts +9 -0
- package/dist/types-cjs/core/types.d.cts +24 -0
- package/dist/types-cjs/signals.d.cts +60 -4
- package/dist/types-cjs/store/store.d.cts +14 -0
- package/package.json +1 -1
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 —
|
|
@@ -38,6 +38,22 @@ function clearPendingSources(e) {
|
|
|
38
38
|
e.oe = undefined;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* A loading-window node hit an unready source (sync throw in recompute, or a
|
|
43
|
+
* NotReadyError-rejected flight): register for the source's settle — the
|
|
44
|
+
* settlePendingSource walk runs off `_pendingSources` + `_blocked` alone —
|
|
45
|
+
* with NO read-visible pending status, no downstream propagation, no
|
|
46
|
+
* transition, no lane registration. Commit #0 keeps serving.
|
|
47
|
+
*/ function parkLoadingWindow(e, n) {
|
|
48
|
+
e.ue = true;
|
|
49
|
+
if (n.source) addPendingSource(e, n.source);
|
|
50
|
+
// A settled error is the node's answer ("the error stays the answer until
|
|
51
|
+
// this retry can actually run") — the park must not replace it: reads
|
|
52
|
+
// throw `_error` while STATUS_ERROR is set, and overwriting it here leaks
|
|
53
|
+
// a pending-class NotReadyError from a read-invisible park (#2989).
|
|
54
|
+
if (!(e.S & STATUS_ERROR)) setPendingError(e, n.source, n);
|
|
55
|
+
}
|
|
56
|
+
|
|
41
57
|
function setPendingError(e, n, t) {
|
|
42
58
|
if (!n) {
|
|
43
59
|
e._ = null;
|
|
@@ -54,10 +70,10 @@ function setPendingError(e, n, t) {
|
|
|
54
70
|
}
|
|
55
71
|
|
|
56
72
|
function forEachDependent(e, n) {
|
|
57
|
-
for (let t = e.o; t !== null; t = t.
|
|
73
|
+
for (let t = e.o; t !== null; t = t.le) n(t.fe, t);
|
|
58
74
|
// `?? null`: affects() marks route plain signals (no `_child` slot) through here.
|
|
59
|
-
for (let t = e.u ?? null; t !== null; t = t.
|
|
60
|
-
for (let e = t.o; e !== null; e = e.
|
|
75
|
+
for (let t = e.u ?? null; t !== null; t = t.ae) {
|
|
76
|
+
for (let e = t.o; e !== null; e = e.le) n(e.fe, e);
|
|
61
77
|
}
|
|
62
78
|
}
|
|
63
79
|
|
|
@@ -72,7 +88,7 @@ function forEachDependent(e, n) {
|
|
|
72
88
|
// callbacks handle their own release (settleAutodispose in handleAsync); this
|
|
73
89
|
// covers derivatively-pending dependents, which have no callbacks of their own.
|
|
74
90
|
function releaseIfSettledUnobserved(e) {
|
|
75
|
-
e.
|
|
91
|
+
e.ce && e.T & CONFIG_AUTO_DISPOSE && !e.o && !(e.se & REACTIVE_ZOMBIE) && !(e.S & STATUS_PENDING) && unobserved(e);
|
|
76
92
|
}
|
|
77
93
|
|
|
78
94
|
// Error-path sweep: notifyStatus(STATUS_ERROR) clears dependents' pending
|
|
@@ -128,24 +144,30 @@ function settlePendingSource(e) {
|
|
|
128
144
|
let t;
|
|
129
145
|
const r = new Set;
|
|
130
146
|
// Companion updates no-op without the verdict layer (null hook).
|
|
131
|
-
const o = GlobalQueue.
|
|
147
|
+
const o = GlobalQueue.Se;
|
|
132
148
|
const settle = u => {
|
|
133
149
|
if (r.has(u) || !removePendingSource(u, e)) return;
|
|
134
150
|
r.add(u);
|
|
135
|
-
u.
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
151
|
+
u.de = clock;
|
|
152
|
+
const i = u.oe?.values().next().value;
|
|
153
|
+
// STATUS_ERROR + pending sources only coexist via an errored loading
|
|
154
|
+
// window's park (notifyStatus(STATUS_ERROR) clears pending sources
|
|
155
|
+
// otherwise): the settled error stays the answer through the settle —
|
|
156
|
+
// nulling it here would have reads throw `null` until the re-enqueued
|
|
157
|
+
// retry lands, or lose it entirely if that retry parks again (#2989).
|
|
158
|
+
const l = u.S & STATUS_ERROR;
|
|
159
|
+
if (i) {
|
|
160
|
+
if (!l) setPendingError(u, i);
|
|
139
161
|
o !== null && o(u);
|
|
140
162
|
} else {
|
|
141
163
|
u.S &= ~STATUS_PENDING;
|
|
142
|
-
setPendingError(u);
|
|
164
|
+
if (!l) setPendingError(u);
|
|
143
165
|
o !== null && o(u);
|
|
144
|
-
if (u.
|
|
166
|
+
if (u.ue) {
|
|
145
167
|
enqueueSub(u);
|
|
146
168
|
n = true;
|
|
147
169
|
}
|
|
148
|
-
u.
|
|
170
|
+
u.ue = false;
|
|
149
171
|
// Fully settled with nobody watching: release candidate (#2934). Checked
|
|
150
172
|
// again at release time — deferred so unobserved() can't unlink subs
|
|
151
173
|
// lists this walk is still iterating.
|
|
@@ -176,6 +198,8 @@ function handleAsync(e, n, t) {
|
|
|
176
198
|
}
|
|
177
199
|
if (!o && !r) {
|
|
178
200
|
e.Te = null;
|
|
201
|
+
// A sync landing is the first real answer for a loadingValue node.
|
|
202
|
+
e.Ee = false;
|
|
179
203
|
return n;
|
|
180
204
|
}
|
|
181
205
|
e.Te = n;
|
|
@@ -192,21 +216,31 @@ function handleAsync(e, n, t) {
|
|
|
192
216
|
// are the transaction's reveal machinery and always re-enter.
|
|
193
217
|
const settleTransition = () => {
|
|
194
218
|
const n = resolveTransition(e);
|
|
195
|
-
if (n && e.S & STATUS_UNINITIALIZED && !currentTransition(n).
|
|
219
|
+
if (n && e.S & STATUS_UNINITIALIZED && !currentTransition(n).Ie.has(e)) {
|
|
196
220
|
// Drop the stale stamp too: the plain settle write (setSignal) and the
|
|
197
221
|
// stash-path restamp both re-enter the transaction through it.
|
|
198
|
-
e.
|
|
222
|
+
e.Ne = null;
|
|
199
223
|
return;
|
|
200
224
|
}
|
|
201
225
|
globalQueue.initTransition(n);
|
|
202
226
|
};
|
|
203
227
|
const handleError = t => {
|
|
204
228
|
if (e.Te !== n) return;
|
|
205
|
-
settleTransition();
|
|
206
229
|
// NotReadyError from rejected promises should be treated as pending, not error
|
|
207
|
-
|
|
230
|
+
let r = t instanceof NotReadyError;
|
|
231
|
+
if (r && e.Ee) {
|
|
232
|
+
// Loading window: the flight died waiting on an unready source. Keep
|
|
233
|
+
// serving commit #0 — same parking as recompute's catch for sync
|
|
234
|
+
// dependency throws. The dead flight is released so the clock-gated
|
|
235
|
+
// error-retry pull (updateIfNecessary) can also re-ask.
|
|
236
|
+
e.Te = null;
|
|
237
|
+
parkLoadingWindow(e, t);
|
|
238
|
+
e.de = clock;
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
settleTransition();
|
|
208
242
|
notifyStatus(e, r ? STATUS_PENDING : STATUS_ERROR, t);
|
|
209
|
-
e.
|
|
243
|
+
e.de = clock;
|
|
210
244
|
// A real error settles derivatively-pending dependents (notifyStatus
|
|
211
245
|
// cleared their pending sources), so stranded lazy ones release here —
|
|
212
246
|
// the error twin of settlePendingSource's release (#2934).
|
|
@@ -222,12 +256,12 @@ function handleAsync(e, n, t) {
|
|
|
222
256
|
const u = !!(e.S & STATUS_UNINITIALIZED);
|
|
223
257
|
trimStaleDeps(e);
|
|
224
258
|
clearStatus(e);
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
259
|
+
const i = resolveLane(e);
|
|
260
|
+
if (i) i.Ae.delete(e);
|
|
227
261
|
if (t) {
|
|
228
262
|
t(r);
|
|
229
263
|
if (u) clearStatus(e, true);
|
|
230
|
-
} else if (e.
|
|
264
|
+
} else if (e._e !== undefined) {
|
|
231
265
|
// Optimistic node — resting OR covered by an active override — holds
|
|
232
266
|
// through the shared pending-node path, exactly like a plain async memo,
|
|
233
267
|
// so the commit clears STATUS_UNINITIALIZED (#2806) and elevation to
|
|
@@ -246,22 +280,22 @@ function handleAsync(e, n, t) {
|
|
|
246
280
|
// only notified when the hold is visible to them: under an active
|
|
247
281
|
// override every reader sees the override (A17), so waking subs would
|
|
248
282
|
// re-show an unchanged view — the revert is the notification point.
|
|
249
|
-
GlobalQueue.
|
|
283
|
+
GlobalQueue.Pe !== null && GlobalQueue.Pe(e, r);
|
|
250
284
|
if (!hasActiveOverride(e)) insertSubs(e);
|
|
251
|
-
e.
|
|
252
|
-
} else if (
|
|
285
|
+
e.de = clock;
|
|
286
|
+
} else if (i) {
|
|
253
287
|
// Route through lane's effect queue for independent flushing
|
|
254
|
-
const n = e.
|
|
288
|
+
const n = e.Re;
|
|
255
289
|
const t = e.Ue;
|
|
256
290
|
const o = e.be;
|
|
257
291
|
try {
|
|
258
292
|
if (!n && u || !o || !o(r, t)) {
|
|
259
293
|
e.Ue = r;
|
|
260
|
-
e.
|
|
294
|
+
e.de = clock;
|
|
261
295
|
// The latest() shadow write gives latest() effects independent lanes; the
|
|
262
296
|
// _pendingSignal update is a no-op repeat of the clearStatus() call above
|
|
263
297
|
// (computePendingState doesn't read _value).
|
|
264
|
-
GlobalQueue.
|
|
298
|
+
GlobalQueue.Pe !== null && GlobalQueue.Pe(e, r);
|
|
265
299
|
insertSubs(e, true);
|
|
266
300
|
}
|
|
267
301
|
} catch (n) {
|
|
@@ -280,6 +314,13 @@ function handleAsync(e, n, t) {
|
|
|
280
314
|
notifyStatus(e, STATUS_ERROR, n);
|
|
281
315
|
}
|
|
282
316
|
}
|
|
317
|
+
// First real answer landing: the window closes when the answer becomes
|
|
318
|
+
// OBSERVABLE. A direct commit is observable now; a transition-held write
|
|
319
|
+
// (`_pendingValue` set above or inside setSignal) is not — the verdict's
|
|
320
|
+
// held-value branch is window-gated, and commitPendingNode closes the
|
|
321
|
+
// window when the hold commits, so no one-frame isPending pulse can leak
|
|
322
|
+
// to live observers between the landing and its commit (#2990).
|
|
323
|
+
if (e.De === NOT_PENDING) e.Ee = false;
|
|
283
324
|
settlePendingSource(e);
|
|
284
325
|
schedule();
|
|
285
326
|
flush();
|
|
@@ -300,9 +341,9 @@ function handleAsync(e, n, t) {
|
|
|
300
341
|
return false;
|
|
301
342
|
};
|
|
302
343
|
if (o) {
|
|
303
|
-
let t = false, r = false, o,
|
|
344
|
+
let t = false, r = false, o, i = true;
|
|
304
345
|
n.then(e => {
|
|
305
|
-
if (
|
|
346
|
+
if (i) {
|
|
306
347
|
u = e;
|
|
307
348
|
t = true;
|
|
308
349
|
} else {
|
|
@@ -310,7 +351,7 @@ function handleAsync(e, n, t) {
|
|
|
310
351
|
settleAutodispose();
|
|
311
352
|
}
|
|
312
353
|
}, e => {
|
|
313
|
-
if (
|
|
354
|
+
if (i) {
|
|
314
355
|
o = e;
|
|
315
356
|
r = true;
|
|
316
357
|
} else {
|
|
@@ -318,7 +359,7 @@ function handleAsync(e, n, t) {
|
|
|
318
359
|
settleAutodispose();
|
|
319
360
|
}
|
|
320
361
|
});
|
|
321
|
-
|
|
362
|
+
i = false;
|
|
322
363
|
if (r) {
|
|
323
364
|
// Settle through the same status path an async rejection uses, then
|
|
324
365
|
// unwind the in-progress synchronous read so the errored node isn't
|
|
@@ -326,15 +367,23 @@ function handleAsync(e, n, t) {
|
|
|
326
367
|
handleError(o);
|
|
327
368
|
throw o;
|
|
328
369
|
} else if (!t) {
|
|
370
|
+
// Loading window: serve commit #0 instead of suspending. No transition
|
|
371
|
+
// is opened — first-flight work on a loadingValue node is loading-class
|
|
372
|
+
// (invisible to boundaries and transitions); the flight itself is
|
|
373
|
+
// already registered in _inFlight and lands through asyncWrite.
|
|
374
|
+
if (e.Ee) return e.Ue;
|
|
329
375
|
globalQueue.initTransition(resolveTransition(e));
|
|
330
376
|
throw new NotReadyError(context);
|
|
377
|
+
} else {
|
|
378
|
+
// Synchronously-resolved promise: the first real answer landed.
|
|
379
|
+
e.Ee = false;
|
|
331
380
|
}
|
|
332
381
|
}
|
|
333
382
|
if (r) {
|
|
334
383
|
const t = n[Symbol.asyncIterator]();
|
|
335
384
|
let r = false;
|
|
336
385
|
let o = false;
|
|
337
|
-
let
|
|
386
|
+
let i = true;
|
|
338
387
|
cleanup(() => {
|
|
339
388
|
if (o) return;
|
|
340
389
|
o = true;
|
|
@@ -350,10 +399,25 @@ function handleAsync(e, n, t) {
|
|
|
350
399
|
if (!settleAutodispose()) iterate();
|
|
351
400
|
};
|
|
352
401
|
const iterate = () => {
|
|
353
|
-
let
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
402
|
+
let l, s, f = false, a = false, c = true;
|
|
403
|
+
// Protocol tolerance, matching `for await`: `await` unwraps whatever
|
|
404
|
+
// next() returns — a thenable OR a bare IteratorResult. Real producers
|
|
405
|
+
// use the bare form as a promise-free fast path when a value is already
|
|
406
|
+
// buffered (seroval's deserialized streams do), so a bare result is
|
|
407
|
+
// assimilated as an already-settled step instead of crashing on `.then`.
|
|
408
|
+
const S = t.next();
|
|
409
|
+
const d = isThenable(S) ? S : {
|
|
410
|
+
then: e => void e(S)
|
|
411
|
+
};
|
|
412
|
+
d.then(t => {
|
|
413
|
+
// The sync stash only serves the INITIAL drain (handleAsync's caller
|
|
414
|
+
// consumes syncValue / throws NotReady from it). A sync-settled step
|
|
415
|
+
// after an async gap — seroval buffering values between pulls, a
|
|
416
|
+
// sync-thenable producer mid-stream — has no caller reading the
|
|
417
|
+
// stash: it must write through the async path or the value is
|
|
418
|
+
// silently dropped.
|
|
419
|
+
if (c && i) {
|
|
420
|
+
l = t;
|
|
357
421
|
f = true;
|
|
358
422
|
if (t.done) o = true;
|
|
359
423
|
} else if (e.Te !== n) {
|
|
@@ -374,7 +438,7 @@ function handleAsync(e, n, t) {
|
|
|
374
438
|
}
|
|
375
439
|
}, t => {
|
|
376
440
|
if (c) {
|
|
377
|
-
|
|
441
|
+
s = t;
|
|
378
442
|
a = true;
|
|
379
443
|
} else if (e.Te === n) {
|
|
380
444
|
o = true;
|
|
@@ -386,41 +450,46 @@ function handleAsync(e, n, t) {
|
|
|
386
450
|
if (a) {
|
|
387
451
|
// Match the promise branch, but only rethrow during the initial read.
|
|
388
452
|
o = true;
|
|
389
|
-
handleError(
|
|
390
|
-
if (
|
|
453
|
+
handleError(s);
|
|
454
|
+
if (i) throw s;
|
|
391
455
|
return true;
|
|
392
456
|
}
|
|
393
|
-
if (f && !
|
|
394
|
-
u =
|
|
457
|
+
if (f && !l.done) {
|
|
458
|
+
u = l.value;
|
|
395
459
|
r = true;
|
|
396
460
|
return iterate();
|
|
397
461
|
}
|
|
398
|
-
return f &&
|
|
462
|
+
return f && l.done;
|
|
399
463
|
};
|
|
400
|
-
const
|
|
464
|
+
const l = iterate();
|
|
401
465
|
// Later iterate() calls run from asyncWrite, where rethrowing would be unhandled.
|
|
402
|
-
|
|
403
|
-
if (!r && !
|
|
466
|
+
i = false;
|
|
467
|
+
if (!r && !l) {
|
|
468
|
+
// Loading window: serve commit #0 (see the promise branch above).
|
|
469
|
+
if (e.Ee) return e.Ue;
|
|
404
470
|
globalQueue.initTransition(resolveTransition(e));
|
|
405
471
|
throw new NotReadyError(context);
|
|
406
472
|
}
|
|
473
|
+
// A sync first yield (or immediate empty completion) is the first real
|
|
474
|
+
// answer; async yields clear inside asyncWrite.
|
|
475
|
+
e.Ee = false;
|
|
407
476
|
}
|
|
408
477
|
return u;
|
|
409
478
|
}
|
|
410
479
|
|
|
411
480
|
function clearStatus(e, n = false) {
|
|
412
481
|
if (e.oe) clearPendingSources(e);
|
|
413
|
-
if (e.
|
|
482
|
+
if (e.ue) e.ue = false;
|
|
414
483
|
// The pending window is over; its quiet classification dies with it.
|
|
415
484
|
// (Unconditional: _reask is baked into the node literals, so this is a
|
|
416
485
|
// plain store to an existing slot — no shape change.)
|
|
417
|
-
e.
|
|
486
|
+
e.he = false;
|
|
418
487
|
e.S = n ? 0 : e.S & STATUS_UNINITIALIZED;
|
|
419
488
|
if (e._) setPendingError(e);
|
|
420
489
|
// Update pending signal for isPending() reactivity (companions only exist
|
|
421
490
|
// once the verdict layer created them, which installs the hooks).
|
|
422
|
-
if (e.
|
|
423
|
-
if (e.u && GlobalQueue.
|
|
491
|
+
if (e.ge || e.pe) GlobalQueue.Se(e);
|
|
492
|
+
if (e.u && GlobalQueue.Oe !== null) GlobalQueue.Oe(e);
|
|
424
493
|
if (e.i) e.i();
|
|
425
494
|
}
|
|
426
495
|
|
|
@@ -428,9 +497,9 @@ function notifyStatus(e, n, t, r, o) {
|
|
|
428
497
|
// Wrap regular errors to track source node
|
|
429
498
|
if (n === STATUS_ERROR && !(t instanceof StatusError) && !(t instanceof NotReadyError)) t = new StatusError(e, t);
|
|
430
499
|
const u = n === STATUS_PENDING && t instanceof NotReadyError ? t.source : undefined;
|
|
431
|
-
const
|
|
432
|
-
const
|
|
433
|
-
const
|
|
500
|
+
const i = u === e;
|
|
501
|
+
const l = n === STATUS_PENDING && e._e !== undefined && !i;
|
|
502
|
+
const s = l && hasActiveOverride(e);
|
|
434
503
|
if (!r) {
|
|
435
504
|
if (n === STATUS_PENDING && u) {
|
|
436
505
|
addPendingSource(e, u);
|
|
@@ -443,14 +512,14 @@ function notifyStatus(e, n, t, r, o) {
|
|
|
443
512
|
e.S = n | (n !== STATUS_ERROR ? e.S & STATUS_UNINITIALIZED : 0);
|
|
444
513
|
e._ = t;
|
|
445
514
|
}
|
|
446
|
-
GlobalQueue.
|
|
447
|
-
if (e.u && GlobalQueue.
|
|
515
|
+
GlobalQueue.Se !== null && GlobalQueue.Se(e);
|
|
516
|
+
if (e.u && GlobalQueue.Oe !== null) GlobalQueue.Oe(e);
|
|
448
517
|
}
|
|
449
518
|
if (o && !r) {
|
|
450
519
|
assignOrMergeLane(e, o);
|
|
451
520
|
}
|
|
452
|
-
const f = r ||
|
|
453
|
-
const a = r ||
|
|
521
|
+
const f = r || s;
|
|
522
|
+
const a = r || l ? undefined : o;
|
|
454
523
|
if (e.i) {
|
|
455
524
|
if (r && n === STATUS_PENDING) {
|
|
456
525
|
return;
|
|
@@ -463,22 +532,22 @@ function notifyStatus(e, n, t, r, o) {
|
|
|
463
532
|
return;
|
|
464
533
|
}
|
|
465
534
|
forEachDependent(e, (e, r) => {
|
|
466
|
-
e.
|
|
535
|
+
e.de = clock;
|
|
467
536
|
if (n === STATUS_PENDING && u && !e.oe?.has(u) || n !== STATUS_PENDING && (e._ !== t || e.oe)) {
|
|
468
537
|
// A pending-observer link is the subscription an `isPending` read created.
|
|
469
538
|
// It exists so the observer re-runs when the source settles, but it must
|
|
470
539
|
// not carry a real (non-NotReadyError) error — the synchronous `isPending`
|
|
471
540
|
// read swallows those, and the async path must match. Re-run the observer
|
|
472
541
|
// so `isPending` re-evaluates (to not-pending) instead of forwarding.
|
|
473
|
-
if (r.
|
|
542
|
+
if (r.Ge && n !== STATUS_PENDING && !(t instanceof NotReadyError)) {
|
|
474
543
|
enqueueSub(e);
|
|
475
544
|
schedule();
|
|
476
545
|
return;
|
|
477
546
|
}
|
|
478
|
-
if (!f && !e.
|
|
547
|
+
if (!f && !e.Ne) queuePendingNode(e);
|
|
479
548
|
notifyStatus(e, n, t, f, a);
|
|
480
549
|
}
|
|
481
550
|
});
|
|
482
551
|
}
|
|
483
552
|
|
|
484
|
-
export { addPendingSource, clearStatus, forEachDependent, handleAsync, isThenable, notifyStatus, releaseSettledDependents, setPendingError, settleErroredDependents, settlePendingSource };
|
|
553
|
+
export { addPendingSource, clearStatus, forEachDependent, handleAsync, isThenable, notifyStatus, parkLoadingWindow, releaseSettledDependents, setPendingError, settleErroredDependents, settlePendingSource };
|