@solidjs/signals 2.0.0-rc.16 → 2.0.0-rc.17
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 +1719 -1603
- package/dist/dev.attribution.js +13 -13
- package/dist/dev.js +182 -45
- package/dist/observe/boundaries.js +2 -2
- package/dist/observe/core/async.js +3 -1
- package/dist/observe/core/context.js +2 -0
- package/dist/observe/core/core.js +26 -10
- package/dist/observe/core/effect.js +2 -0
- package/dist/observe/core/graph.js +10 -8
- package/dist/observe/core/lanes.js +25 -14
- package/dist/observe/core/owner.js +73 -47
- package/dist/observe/core/scheduler.js +189 -173
- package/dist/observe/core/verdict.js +3 -0
- package/dist/observe/map.js +2 -2
- package/dist/observe/signals.js +6 -1
- package/dist/observe/store/affects.js +13 -13
- package/dist/observe/store/optimistic.js +112 -71
- package/dist/observe/store/store.js +25 -16
- package/dist/prod/boundaries.js +2 -2
- package/dist/prod/core/async.js +3 -1
- package/dist/prod/core/context.js +2 -0
- package/dist/prod/core/core.js +31 -15
- package/dist/prod/core/effect.js +2 -0
- package/dist/prod/core/graph.js +10 -8
- package/dist/prod/core/heap.js +1 -1
- package/dist/prod/core/lanes.js +25 -14
- package/dist/prod/core/owner.js +70 -44
- package/dist/prod/core/scheduler.js +43 -27
- package/dist/prod/core/verdict.js +4 -1
- package/dist/prod/map.js +2 -2
- package/dist/prod/signals.js +18 -13
- package/dist/prod/store/optimistic.js +112 -71
- package/dist/prod/store/store.js +18 -7
- package/dist/types/core/core.d.ts +10 -3
- package/dist/types/core/dev.d.ts +9 -1
- package/dist/types/core/error.d.ts +9 -1
- package/dist/types/core/owner.d.ts +4 -0
- package/dist/types/core/scheduler.d.ts +23 -4
- package/package.json +1 -1
|
@@ -14,6 +14,8 @@ import { runHeap, enqueueSub, deleteFromHeap } from "./heap.js";
|
|
|
14
14
|
|
|
15
15
|
import { devCheckQuiescent } from "./invariants.js";
|
|
16
16
|
|
|
17
|
+
import { rethrowCleanupError } from "./owner.js";
|
|
18
|
+
|
|
17
19
|
// Optional-module hooks: module bindings, not `GlobalQueue` statics, so a
|
|
18
20
|
// bundle that never imports the installing module never assigns them — its
|
|
19
21
|
// minifier folds every guarded call site (and the branch behind it) away.
|
|
@@ -38,16 +40,16 @@ let endLanesHook = null;
|
|
|
38
40
|
|
|
39
41
|
let lanesBlockedHook = null;
|
|
40
42
|
|
|
41
|
-
function installLaneHooks(e,
|
|
43
|
+
function installLaneHooks(e, o, n, t, l, s, u, r, i) {
|
|
42
44
|
laneReadHook = e;
|
|
43
|
-
laneStageHook =
|
|
44
|
-
laneOutcomeHook =
|
|
45
|
+
laneStageHook = o;
|
|
46
|
+
laneOutcomeHook = n;
|
|
45
47
|
laneWriteHook = t;
|
|
46
48
|
applyGuessesHook = l;
|
|
47
49
|
laneSeamsHook = s;
|
|
48
50
|
laneCorrectionsHook = u;
|
|
49
|
-
endLanesHook =
|
|
50
|
-
lanesBlockedHook =
|
|
51
|
+
endLanesHook = r;
|
|
52
|
+
lanesBlockedHook = i;
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
// Boundaries (boundaries.ts): the display consumers between an observer
|
|
@@ -73,10 +75,10 @@ let boundarySeamHook = null;
|
|
|
73
75
|
|
|
74
76
|
let heldRunHook = null;
|
|
75
77
|
|
|
76
|
-
function installBoundaryHooks(e,
|
|
78
|
+
function installBoundaryHooks(e, o, n, t, l) {
|
|
77
79
|
catchHook = e;
|
|
78
|
-
freshHook =
|
|
79
|
-
hiddenHook =
|
|
80
|
+
freshHook = o;
|
|
81
|
+
hiddenHook = n;
|
|
80
82
|
boundarySeamHook = t;
|
|
81
83
|
heldRunHook = l;
|
|
82
84
|
}
|
|
@@ -90,9 +92,9 @@ function installBoundaryHooks(e, n, o, t, l) {
|
|
|
90
92
|
|
|
91
93
|
let storeCommitHook = null;
|
|
92
94
|
|
|
93
|
-
function installStoreHooks(e,
|
|
95
|
+
function installStoreHooks(e, o) {
|
|
94
96
|
storeParkHook = e;
|
|
95
|
-
storeCommitHook =
|
|
97
|
+
storeCommitHook = o;
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
/** `affects()` marks (affects.ts): the releases at a landing and at the seam
|
|
@@ -100,9 +102,9 @@ function installStoreHooks(e, n) {
|
|
|
100
102
|
|
|
101
103
|
let releaseAmbientMarksHook = null;
|
|
102
104
|
|
|
103
|
-
function installMarkHooks(e,
|
|
105
|
+
function installMarkHooks(e, o) {
|
|
104
106
|
releaseMarksHook = e;
|
|
105
|
-
releaseAmbientMarksHook =
|
|
107
|
+
releaseAmbientMarksHook = o;
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
/** Verdicts (verdict.ts). */ let observeFlightHook = null;
|
|
@@ -116,9 +118,9 @@ function installVerdictHooks(e) {
|
|
|
116
118
|
|
|
117
119
|
let externalUntrackHook = undefined;
|
|
118
120
|
|
|
119
|
-
function setExternalHooks(e,
|
|
121
|
+
function setExternalHooks(e, o) {
|
|
120
122
|
wireExternalSourceHook = e;
|
|
121
|
-
externalUntrackHook =
|
|
123
|
+
externalUntrackHook = o;
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
/** Live transactions — opened, unmerged, not landed. Scanned at every seam
|
|
@@ -126,13 +128,13 @@ function setExternalHooks(e, n) {
|
|
|
126
128
|
|
|
127
129
|
/** Observe tier: this flush parked its transaction (`holdStart` fired). */ let holding = false;
|
|
128
130
|
|
|
129
|
-
/** A transaction (listed here) or a lane (lanes.ts lists its own). */ function newTransaction(e,
|
|
130
|
-
const
|
|
131
|
+
/** A transaction (listed here) or a lane (lanes.ts lists its own). */ function newTransaction(e, o = null) {
|
|
132
|
+
const n = {
|
|
131
133
|
je: [],
|
|
132
134
|
un: [ [], [] ],
|
|
133
135
|
En: [],
|
|
134
|
-
|
|
135
|
-
_parent:
|
|
136
|
+
eo: null,
|
|
137
|
+
_parent: o,
|
|
136
138
|
V: e,
|
|
137
139
|
it: null,
|
|
138
140
|
tt: 0,
|
|
@@ -142,8 +144,8 @@ function setExternalHooks(e, n) {
|
|
|
142
144
|
ln: false,
|
|
143
145
|
I: null
|
|
144
146
|
};
|
|
145
|
-
if (!e) transactions.push(
|
|
146
|
-
return
|
|
147
|
+
if (!e) transactions.push(n);
|
|
148
|
+
return n;
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
// Lanes (plan sec. 28, 2026-10-02; lanes.ts). A lane is "a new base of a transition":
|
|
@@ -186,8 +188,8 @@ function setPassLane(e) {
|
|
|
186
188
|
* Cleared by the flush the join schedules, and at the end of a flush that
|
|
187
189
|
* set it. */ let passTx = null;
|
|
188
190
|
|
|
189
|
-
function joinPassTx(e,
|
|
190
|
-
if (globalQueue.q && !
|
|
191
|
+
function joinPassTx(e, o) {
|
|
192
|
+
if (globalQueue.q && !o || flushTransaction !== null) return joinFuture(e);
|
|
191
193
|
if (passTx === null) passTx = resolveTx(e); else merge(resolveTx(e), passTx);
|
|
192
194
|
schedule();
|
|
193
195
|
}
|
|
@@ -204,37 +206,37 @@ function joinPassTx(e, n) {
|
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
function resolveTx(e) {
|
|
207
|
-
while (e.
|
|
209
|
+
while (e.eo !== null) e = e.eo;
|
|
208
210
|
return e;
|
|
209
211
|
}
|
|
210
212
|
|
|
211
213
|
/** The flush joins transaction `t` — or needs one of its own (`null`: a pass
|
|
212
214
|
* went pending with nothing held). Joining a second one merges it into the
|
|
213
215
|
* flush's: the work that touched both entangles them (A15). */ function joinFuture(e) {
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
216
|
+
const o = flushTransaction;
|
|
217
|
+
if (o === null) {
|
|
216
218
|
flushTransaction = e === null ? newTransaction(false) : resolveTx(e);
|
|
217
|
-
} else if (e !== null) merge(resolveTx(e),
|
|
219
|
+
} else if (e !== null) merge(resolveTx(e), o);
|
|
218
220
|
if (!globalQueue.q) schedule();
|
|
219
221
|
}
|
|
220
222
|
|
|
221
223
|
/** `t` merges into `f`: the work that touched both entangles them (A15).
|
|
222
224
|
* A lane never merges: it is a sub-frame, not a peer — its work is routed
|
|
223
|
-
* per pass (`passLane`). */ function merge(e,
|
|
225
|
+
* per pass (`passLane`). */ function merge(e, o) {
|
|
224
226
|
// Both ends resolved: a stale pointer to a transaction already merged
|
|
225
227
|
// into the other would close a cycle `resolveTx` never leaves.
|
|
226
228
|
e = resolveTx(e);
|
|
227
|
-
|
|
228
|
-
if (e ===
|
|
229
|
-
if (attrHooks !== null) attrHooks.transitionMerged(
|
|
230
|
-
e.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
append(
|
|
234
|
-
append(
|
|
235
|
-
append(
|
|
236
|
-
append(
|
|
237
|
-
if (e.I !== null) append(
|
|
229
|
+
o = resolveTx(o);
|
|
230
|
+
if (e === o || e.V || o.V) return;
|
|
231
|
+
if (attrHooks !== null) attrHooks.transitionMerged(o, e);
|
|
232
|
+
e.eo = o;
|
|
233
|
+
o.tt += e.tt;
|
|
234
|
+
o.nt ||= e.nt;
|
|
235
|
+
append(o.je, e.je);
|
|
236
|
+
append(o.un[0], e.un[0]);
|
|
237
|
+
append(o.un[1], e.un[1]);
|
|
238
|
+
append(o.En, e.En);
|
|
239
|
+
if (e.I !== null) append(o.I ??= [], e.I);
|
|
238
240
|
transactions.splice(transactions.indexOf(e), 1);
|
|
239
241
|
}
|
|
240
242
|
|
|
@@ -256,13 +258,13 @@ function resolveTx(e) {
|
|
|
256
258
|
* in for the flight (A17: "visible until its own fetch settles"). */ function blocked(e) {
|
|
257
259
|
// The transaction being judged (a lane consulted on its behalf judges for
|
|
258
260
|
// it): a zombie whose removal it stages is moot for it alone (`onScreen`).
|
|
259
|
-
const
|
|
261
|
+
const o = judge;
|
|
260
262
|
judge ??= e;
|
|
261
263
|
// An action still running in it holds it open (action.ts). Its lanes
|
|
262
264
|
// (lanes.ts): a lane under `t` blocks it while blocked itself.
|
|
263
|
-
const
|
|
264
|
-
judge =
|
|
265
|
-
return
|
|
265
|
+
const n = e.tt !== 0 || blockedBy(e.je, e) || !!lanesBlockedHook?.(e);
|
|
266
|
+
judge = o;
|
|
267
|
+
return n;
|
|
266
268
|
}
|
|
267
269
|
|
|
268
270
|
let judge = null;
|
|
@@ -270,12 +272,12 @@ let judge = null;
|
|
|
270
272
|
/** Observe tier: the flights `t` waits on — its pending held sources a
|
|
271
273
|
* frame reader observes (`blockedBy`'s predicate, collected; the readers
|
|
272
274
|
* themselves are not sources). */ function blockersOf(e) {
|
|
273
|
-
const
|
|
274
|
-
for (let
|
|
275
|
-
const t = e.je[
|
|
276
|
-
if (!t.i && t.m & STATUS_PENDING && !(t.R & REACTIVE_DISPOSED) && (t.T.Je === null || txOf(t) === e) && blockedBy([ t ], e))
|
|
275
|
+
const o = [];
|
|
276
|
+
for (let n = 0; n < e.je.length; n++) {
|
|
277
|
+
const t = e.je[n];
|
|
278
|
+
if (!t.i && t.m & STATUS_PENDING && !(t.R & REACTIVE_DISPOSED) && (t.T.Je === null || txOf(t) === e) && blockedBy([ t ], e)) o.push(t);
|
|
277
279
|
}
|
|
278
|
-
return
|
|
280
|
+
return o;
|
|
279
281
|
}
|
|
280
282
|
|
|
281
283
|
/** `t`'s own flights only — not its lanes': a flight the frame asked for
|
|
@@ -288,28 +290,28 @@ let judge = null;
|
|
|
288
290
|
|
|
289
291
|
/** A source the pending node waits on that is `t`'s (held by it, or by no
|
|
290
292
|
* one) — not another transaction's or lane's work. Itself, when it is the
|
|
291
|
-
* source. */ function ownSource(e,
|
|
292
|
-
const
|
|
293
|
-
if (
|
|
294
|
-
for (const e of
|
|
295
|
-
const
|
|
296
|
-
if (
|
|
293
|
+
* source. */ function ownSource(e, o) {
|
|
294
|
+
const n = e.T?.fe;
|
|
295
|
+
if (n === undefined) return true;
|
|
296
|
+
for (const e of n) {
|
|
297
|
+
const n = e.T?.Je;
|
|
298
|
+
if (n == null || resolveTx(n) === o) return true;
|
|
297
299
|
}
|
|
298
300
|
return false;
|
|
299
301
|
}
|
|
300
302
|
|
|
301
|
-
function blockedBy(e,
|
|
303
|
+
function blockedBy(e, o, n = false) {
|
|
302
304
|
for (let t = 0; t < e.length; t++) {
|
|
303
305
|
const l = e[t];
|
|
304
|
-
if (!(l.m & STATUS_PENDING) || l.R & REACTIVE_DISPOSED || l.l & CONFIG_GUESS || l.T.Je !== null && txOf(l) !==
|
|
306
|
+
if (!(l.m & STATUS_PENDING) || l.R & REACTIVE_DISPOSED || l.l & CONFIG_GUESS || l.T.Je !== null && txOf(l) !== o || n && !ownSource(l, o)) continue;
|
|
305
307
|
// The frame's own pending observer (off screen: this one holds nothing;
|
|
306
308
|
// the next listed node may).
|
|
307
309
|
if (l.i === EFFECT_RENDER) {
|
|
308
|
-
if (onScreen(l, judge ??
|
|
310
|
+
if (onScreen(l, judge ?? o)) return true;
|
|
309
311
|
continue;
|
|
310
312
|
}
|
|
311
313
|
for (let e = l.o; e !== null; e = e.t) {
|
|
312
|
-
const
|
|
314
|
+
const n = e.u;
|
|
313
315
|
// A frame reader: a render effect, or a stale reader of the flight
|
|
314
316
|
// (REACTIVE_FRAME_READ — a verdict reader, `observeFlight`; lane work,
|
|
315
317
|
// `frameRead`): served committed instead of going pending, it derives
|
|
@@ -321,7 +323,7 @@ function blockedBy(e, n, o = false) {
|
|
|
321
323
|
// lane-membership ruling, 2026-10-05). An output that never committed
|
|
322
324
|
// shows nothing — a mount the frame has not revealed — and holds
|
|
323
325
|
// nothing.
|
|
324
|
-
if ((
|
|
326
|
+
if ((n.i === EFFECT_RENDER && n.m & STATUS_PENDING || n.R & REACTIVE_FRAME_READ || n.l & CONFIG_REDERIVE && n.m === STATUS_PENDING) && (e.Te === n.Ne || n.T?.F != null) && !(n.R & REACTIVE_DISPOSED) && onScreen(n, judge ?? o)) return true;
|
|
325
327
|
}
|
|
326
328
|
}
|
|
327
329
|
return false;
|
|
@@ -334,8 +336,8 @@ function blockedBy(e, n, o = false) {
|
|
|
334
336
|
* is visible, a lane's reveal included: only the commit that disposes it
|
|
335
337
|
* makes its say moot), and not behind a fallback (A33: a boundary showing its fallback is the display of
|
|
336
338
|
* everything under it, so a reader there is not on screen and holds
|
|
337
|
-
* nothing — boundaries.ts). */ function onScreen(e,
|
|
338
|
-
return !(e.R & REACTIVE_ZOMBIE && removalStagedBy(e,
|
|
339
|
+
* nothing — boundaries.ts). */ function onScreen(e, o) {
|
|
340
|
+
return !(e.R & REACTIVE_ZOMBIE && removalStagedBy(e, o)) && !hiddenHook?.(e);
|
|
339
341
|
}
|
|
340
342
|
|
|
341
343
|
/** A15 (#3463): a reader whose removal is staged — a zombie, parked by a
|
|
@@ -343,10 +345,10 @@ function blockedBy(e, n, o = false) {
|
|
|
343
345
|
* except the transaction staging its removal: for that one its say is moot
|
|
344
346
|
* (done, and the commit disposes it; not done, and it stays parked). The
|
|
345
347
|
* staging transaction is the one holding the pass that parked the frame:
|
|
346
|
-
* the nearest non-zombie ancestor. */ function removalStagedBy(e,
|
|
347
|
-
let
|
|
348
|
-
while (
|
|
349
|
-
return
|
|
348
|
+
* the nearest non-zombie ancestor. */ function removalStagedBy(e, o) {
|
|
349
|
+
let n = e;
|
|
350
|
+
while (n?.R & REACTIVE_ZOMBIE) n = n._parent;
|
|
351
|
+
return n?.l & CONFIG_HELD && n.T?.Je != null && txOf(n) === resolveTx(o);
|
|
350
352
|
}
|
|
351
353
|
|
|
352
354
|
/** Unchanged passes this flush whose stale dependency tail awaits the
|
|
@@ -372,18 +374,18 @@ function deferZombie(e) {
|
|
|
372
374
|
}
|
|
373
375
|
|
|
374
376
|
/** Put a staged node in a transaction: flagged, stamped, on its landing
|
|
375
|
-
* list. */ function holdNode(e,
|
|
377
|
+
* list. */ function holdNode(e, o) {
|
|
376
378
|
e.l |= CONFIG_HELD;
|
|
377
|
-
list(e,
|
|
379
|
+
list(e, o);
|
|
378
380
|
}
|
|
379
381
|
|
|
380
382
|
/** Put a node on a transaction's list, once: a node's `_transaction` is the
|
|
381
383
|
* transaction whose `_nodes` it is on (every site that sets one does the
|
|
382
|
-
* other), so a re-pass, a re-landing or a re-staging adds nothing. */ function list(e,
|
|
383
|
-
const
|
|
384
|
-
if (
|
|
385
|
-
|
|
386
|
-
|
|
384
|
+
* other), so a re-pass, a re-landing or a re-staging adds nothing. */ function list(e, o) {
|
|
385
|
+
const n = ext(e);
|
|
386
|
+
if (n.Je === o) return;
|
|
387
|
+
n.Je = o;
|
|
388
|
+
o.je.push(e);
|
|
387
389
|
}
|
|
388
390
|
|
|
389
391
|
/** Hold the (uncommitted) frame under a held pass: every computed in the
|
|
@@ -398,22 +400,22 @@ function deferZombie(e) {
|
|
|
398
400
|
* and `dissolveLane` no longer finds it — a lane node with no lane, which the
|
|
399
401
|
* next read of it trips over (`laneRead` → `txOf`). Its frame is the lane's
|
|
400
402
|
* too (ruling A: a lane pass's children are the lane's), revealed and
|
|
401
|
-
* retired at the lane's seam. */ function holdFrame(e,
|
|
402
|
-
for (let
|
|
403
|
-
if (
|
|
404
|
-
if (
|
|
405
|
-
if (!(
|
|
406
|
-
|
|
403
|
+
* retired at the lane's seam. */ function holdFrame(e, o) {
|
|
404
|
+
for (let n = e.ze; n !== null; n = n.Xe) {
|
|
405
|
+
if (n.T?.Je?.V) continue;
|
|
406
|
+
if (n.X !== undefined) {
|
|
407
|
+
if (!(n.l & CONFIG_HELD)) holdNode(n, o);
|
|
408
|
+
n.l |= CONFIG_HELD_FRAME;
|
|
407
409
|
}
|
|
408
|
-
holdFrame(
|
|
410
|
+
holdFrame(n, o);
|
|
409
411
|
}
|
|
410
412
|
}
|
|
411
413
|
|
|
412
414
|
/** The nodes under `owner` a transaction other than `t` holds (boundaries.ts:
|
|
413
|
-
* what an earlier hold staged under a re-armed boundary). */ function heldUnder(e,
|
|
415
|
+
* what an earlier hold staged under a re-armed boundary). */ function heldUnder(e, o, n) {
|
|
414
416
|
for (let t = e.ze; t !== null; t = t.Xe) {
|
|
415
|
-
if ((t.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD && txOf(t) !==
|
|
416
|
-
heldUnder(t,
|
|
417
|
+
if ((t.l & (CONFIG_HELD | CONFIG_OVERRIDE)) === CONFIG_HELD && txOf(t) !== o) n(t);
|
|
418
|
+
heldUnder(t, o, n);
|
|
417
419
|
}
|
|
418
420
|
}
|
|
419
421
|
|
|
@@ -510,7 +512,9 @@ function schedule() {
|
|
|
510
512
|
function haltReactivity(e) {
|
|
511
513
|
if (halted) return;
|
|
512
514
|
halted = true;
|
|
513
|
-
|
|
515
|
+
// A cleanup error collected before the halt is dropped (owner.ts).
|
|
516
|
+
rethrowCleanupError(true);
|
|
517
|
+
let o = "[REACTIVITY_HALTED]";
|
|
514
518
|
// Surface the cause here too: callers rethrow it, but a creation-time throw
|
|
515
519
|
// unwinds through ancestor recomputes that convert it to status instead of
|
|
516
520
|
// surfacing it (#2884), so the rethrow alone cannot guarantee visibility.
|
|
@@ -520,9 +524,18 @@ function haltReactivity(e) {
|
|
|
520
524
|
// nothing an app or its telemetry can act on (#3338 — an uncaught throw
|
|
521
525
|
// during the hydration render). The rethrow may reach the top as well in
|
|
522
526
|
// the non-swallowed cases; a duplicate report beats a silent one.
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
527
|
+
const n = e !== undefined && globalThis.reportError;
|
|
528
|
+
n || e === undefined ? console.error(o) : console.error(o, e);
|
|
529
|
+
n && n(e);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Dev: `haltReactivity`, located at `subject` — the computation the uncaught
|
|
534
|
+
* error escaped from — for the REACTIVITY_HALTED message's owner path. Call
|
|
535
|
+
* sites pick it in dev builds only (`haltReactivity(e)` in production), so
|
|
536
|
+
* production keeps the one-argument halt and its bytes unchanged.
|
|
537
|
+
*/ function haltReactivityAt(e, o) {
|
|
538
|
+
haltReactivity(e);
|
|
526
539
|
}
|
|
527
540
|
|
|
528
541
|
// Logs on the first write after a halt so a frozen interaction is traceable.
|
|
@@ -595,13 +608,13 @@ class GlobalQueue {
|
|
|
595
608
|
// A lane's own flush (its flight landing, its reveal) parks nothing: the
|
|
596
609
|
// lane's work reached it per pass; the frame's plain writes commit.
|
|
597
610
|
// (Resolved: a guess over another transaction's guess merged them.)
|
|
598
|
-
const
|
|
599
|
-
if (
|
|
611
|
+
const o = e !== null && !e.V ? resolveTx(e) : null;
|
|
612
|
+
if (o !== null) {
|
|
600
613
|
// `t._nodes` grows under the walk (holdFrame pushes); the bound is
|
|
601
614
|
// this flush's list, which does not.
|
|
602
615
|
const e = pendingNodes.length;
|
|
603
|
-
for (let
|
|
604
|
-
const e = pendingNodes[
|
|
616
|
+
for (let n = 0; n < e; n++) {
|
|
617
|
+
const e = pendingNodes[n];
|
|
605
618
|
// Already held: the pass that re-staged it joined its transaction,
|
|
606
619
|
// which is `t` (or merged into it). Lane work is the lane's (a
|
|
607
620
|
// pending mark propagated onto it queued it here too).
|
|
@@ -629,15 +642,15 @@ class GlobalQueue {
|
|
|
629
642
|
e.l &= ~CONFIG_STAGED;
|
|
630
643
|
continue;
|
|
631
644
|
}
|
|
632
|
-
holdNode(e,
|
|
645
|
+
holdNode(e, o);
|
|
633
646
|
}
|
|
634
647
|
// A held pass's frame is held with it (ruling A, O2): the children it
|
|
635
648
|
// created are the transaction's — they compute, and a pass over them
|
|
636
649
|
// or a write that reaches them joins; they effect at the landing.
|
|
637
|
-
if (e.l & CONFIG_STAGED) holdFrame(e,
|
|
650
|
+
if (e.l & CONFIG_STAGED) holdFrame(e, o);
|
|
638
651
|
}
|
|
639
652
|
pendingNodes.length = 0;
|
|
640
|
-
storeParkHook?.(
|
|
653
|
+
storeParkHook?.(o);
|
|
641
654
|
// (This flush's runs are stashed with `t` below — after the landings,
|
|
642
655
|
// so a `t` that lands at this very seam runs them first, ahead of
|
|
643
656
|
// the runs it held from earlier flushes.)
|
|
@@ -648,10 +661,10 @@ class GlobalQueue {
|
|
|
648
661
|
// holder's verdict lane's work — before the lane seams, which reveal
|
|
649
662
|
// it (nothing commits this seam that could dispose it).
|
|
650
663
|
// (Verdict readers exist only with the verdict engine installed.)
|
|
651
|
-
const
|
|
664
|
+
const n = deferredZombies.splice(0);
|
|
652
665
|
if (observeFlightHook) {
|
|
653
|
-
|
|
654
|
-
for (let e = 0; e <
|
|
666
|
+
n.sort((e, o) => e.Et - o.Et);
|
|
667
|
+
for (let e = 0; e < n.length; e++) if ((n[e].R & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE)) === REACTIVE_ZOMBIE && n[e].l & CONFIG_VERDICT) recompute(n[e]);
|
|
655
668
|
}
|
|
656
669
|
// The unchanged passes' tails stay linked (A30, #3469): their inputs
|
|
657
670
|
// are held, and the committed frame still derives from them — no trim.
|
|
@@ -663,8 +676,8 @@ class GlobalQueue {
|
|
|
663
676
|
// left an effect owing a run (`runEffect` trims when the run applies):
|
|
664
677
|
// `recompute`'s own gates.
|
|
665
678
|
for (let e = 0; e < heldTrims.length; e++) {
|
|
666
|
-
const
|
|
667
|
-
if (
|
|
679
|
+
const o = heldTrims[e];
|
|
680
|
+
if (o.T?.F == null && !o.Qe) trimStaleDeps(o);
|
|
668
681
|
}
|
|
669
682
|
}
|
|
670
683
|
// The list is the flush's either way. Reset only when there is something
|
|
@@ -678,22 +691,22 @@ class GlobalQueue {
|
|
|
678
691
|
// removes its entry.
|
|
679
692
|
// This flush's own runs, the lanes' reveals, and the landings' held runs
|
|
680
693
|
// are collected apart and ordered below.
|
|
681
|
-
const
|
|
694
|
+
const n = this.un;
|
|
682
695
|
const t = this.un = [ [], [] ];
|
|
683
696
|
// The passes that read this frame's stagings as the screen read held
|
|
684
697
|
// writes if it parked: the lane seam re-derives them on the committed
|
|
685
698
|
// world (a lane's runs wait this round).
|
|
686
699
|
if (laneSeamsHook) {
|
|
687
|
-
laneSeamsHook(
|
|
700
|
+
laneSeamsHook(o !== null ? stagedReaders : null);
|
|
688
701
|
if (stagedReaders.length) stagedReaders.length = 0;
|
|
689
702
|
}
|
|
690
703
|
this.un = [ [], [] ];
|
|
691
704
|
for (let e = transactions.length - 1; e >= 0; e--) {
|
|
692
|
-
const
|
|
693
|
-
if (blocked(
|
|
705
|
+
const o = transactions[e];
|
|
706
|
+
if (blocked(o)) continue;
|
|
694
707
|
transactions.splice(e, 1);
|
|
695
|
-
endLanesHook?.(
|
|
696
|
-
land(
|
|
708
|
+
endLanesHook?.(o);
|
|
709
|
+
land(o);
|
|
697
710
|
// A landing's commits can dispose a zombie a transaction judged above
|
|
698
711
|
// was blocked on (#3463: live "until the commit that disposes it") —
|
|
699
712
|
// judge them again.
|
|
@@ -706,7 +719,7 @@ class GlobalQueue {
|
|
|
706
719
|
// parked (something async below) — the window is the frame's, the marks
|
|
707
720
|
// are its transaction's; else they release at the seam, verdict-only,
|
|
708
721
|
// nothing to show (affects.ts).
|
|
709
|
-
const l =
|
|
722
|
+
const l = o && liveTx(o);
|
|
710
723
|
releaseAmbientMarksHook?.(l);
|
|
711
724
|
// The effect phase: lane work first (displayed ahead of the frame), then
|
|
712
725
|
// this flush's runs, then the runs the landings held from earlier
|
|
@@ -725,19 +738,19 @@ class GlobalQueue {
|
|
|
725
738
|
holding = true;
|
|
726
739
|
}
|
|
727
740
|
for (let e = 0; e < 2; e++) {
|
|
728
|
-
if (s) append(l.un[e],
|
|
741
|
+
if (s) append(l.un[e], n[e]);
|
|
729
742
|
// The plain flush — no reveal, no landing, not parked — has nothing to
|
|
730
743
|
// order around its own runs: they are the queue as they stand (the
|
|
731
744
|
// same array, not a copy; `run` takes it whole). Every other seam
|
|
732
745
|
// builds the ordered queue above.
|
|
733
|
-
this.un[e] = s || t[e].length || this.un[e].length ? t[e].concat(s ? [] :
|
|
746
|
+
this.un[e] = s || t[e].length || this.un[e].length ? t[e].concat(s ? [] : n[e], this.un[e]) : n[e];
|
|
734
747
|
}
|
|
735
748
|
if (deferredZombies.length !== 0) {
|
|
736
749
|
// Survivors are the displayed frame of a held pass: they rerun for the
|
|
737
750
|
// live write, parents before children.
|
|
738
|
-
const e = deferredZombies.splice(0).sort((e,
|
|
739
|
-
for (let
|
|
740
|
-
if (!(e[
|
|
751
|
+
const e = deferredZombies.splice(0).sort((e, o) => e.Et - o.Et);
|
|
752
|
+
for (let o = 0; o < e.length; o++) {
|
|
753
|
+
if (!(e[o].R & REACTIVE_DISPOSED)) recompute(e[o]);
|
|
741
754
|
}
|
|
742
755
|
}
|
|
743
756
|
// Boundaries: readers that settled, landed or died this flush are
|
|
@@ -745,18 +758,18 @@ class GlobalQueue {
|
|
|
745
758
|
boundarySeamHook?.();
|
|
746
759
|
}
|
|
747
760
|
run(e) {
|
|
748
|
-
const
|
|
749
|
-
if (
|
|
761
|
+
const o = this.un[e - 1];
|
|
762
|
+
if (o.length) {
|
|
750
763
|
this.un[e - 1] = [];
|
|
751
|
-
runQueue(
|
|
764
|
+
runQueue(o, e);
|
|
752
765
|
}
|
|
753
766
|
}
|
|
754
|
-
enqueue(e,
|
|
767
|
+
enqueue(e, o, n = passLane) {
|
|
755
768
|
// Lane work's runs are the lane's: they run at its reveal, not with
|
|
756
769
|
// the frame (which may park). A lane pass that read the frame's own
|
|
757
770
|
// staging is the frame's (`recompute` passes null): its run waits with
|
|
758
771
|
// the frame.
|
|
759
|
-
if (e) (
|
|
772
|
+
if (e) (n !== null ? n : this).un[e - 1].push(o);
|
|
760
773
|
schedule();
|
|
761
774
|
}
|
|
762
775
|
/** Status reaching the root: pending is absorbed (the root mount defers —
|
|
@@ -772,10 +785,10 @@ class GlobalQueue {
|
|
|
772
785
|
*
|
|
773
786
|
* A boundary between the observer and the root (boundaries.ts) is asked
|
|
774
787
|
* first: a fallback catches what is not ready under it, and the root
|
|
775
|
-
* never hears of it. */ notify(e,
|
|
776
|
-
if (catchHook?.(e,
|
|
777
|
-
if (
|
|
778
|
-
if (
|
|
788
|
+
* never hears of it. */ notify(e, o, n, t) {
|
|
789
|
+
if (catchHook?.(e, n & o, t)) return true;
|
|
790
|
+
if (o & STATUS_PENDING) {
|
|
791
|
+
if (n & STATUS_PENDING) {
|
|
779
792
|
// A pass that went pending holds its frame: the async's own
|
|
780
793
|
// synchronous frame is not ready (A15 reveal corollary: a reveal
|
|
781
794
|
// that discovers a flight whose inputs are visible holds and joins
|
|
@@ -807,20 +820,20 @@ class GlobalQueue {
|
|
|
807
820
|
* for it is void (#3322: an effect has one value slot, and the stale pass
|
|
808
821
|
* overwrote the value that run was for) — the re-derivation's run replaces
|
|
809
822
|
* it. */ function reruns(e) {
|
|
810
|
-
for (let
|
|
811
|
-
const
|
|
823
|
+
for (let o = 0; o < e.En.length; o++) {
|
|
824
|
+
const n = e.En[o];
|
|
812
825
|
// An errored reader's display is its error (D-39): the landing gives it
|
|
813
826
|
// nothing to re-derive, and a re-run would be a read that retries the
|
|
814
827
|
// errored source (#3945).
|
|
815
|
-
if (
|
|
816
|
-
if (
|
|
817
|
-
|
|
818
|
-
|
|
828
|
+
if (n.R & REACTIVE_DISPOSED || n.m & STATUS_ERROR) continue;
|
|
829
|
+
if (n.R & REACTIVE_FRAME_READ || n.l & CONFIG_VERDICT) {
|
|
830
|
+
n.R &= ~REACTIVE_FRAME_READ;
|
|
831
|
+
n.Qe = false;
|
|
819
832
|
// Its frame is replaced by the re-derivation: a run one of its
|
|
820
833
|
// children queued this flush (re-run by the same landing) is for the
|
|
821
834
|
// frame being replaced — void too (#3404).
|
|
822
|
-
for (let e =
|
|
823
|
-
enqueueSub(
|
|
835
|
+
for (let e = n.ze; e !== null; e = e.Xe) if (e.i) e.Qe = false;
|
|
836
|
+
enqueueSub(n);
|
|
824
837
|
}
|
|
825
838
|
}
|
|
826
839
|
e.En.length = 0;
|
|
@@ -835,11 +848,11 @@ class GlobalQueue {
|
|
|
835
848
|
// Old children die in the commits (cleanups first), then the stashed
|
|
836
849
|
// effects run ahead of this flush's own. A node a lane took over since
|
|
837
850
|
// (a guess written over the staged truth) is the lane's to land.
|
|
838
|
-
for (let
|
|
839
|
-
const
|
|
840
|
-
if (
|
|
841
|
-
|
|
842
|
-
commitPendingNode(
|
|
851
|
+
for (let o = 0; o < e.je.length; o++) {
|
|
852
|
+
const n = e.je[o];
|
|
853
|
+
if (n.T.Je === null || txOf(n) !== e) continue;
|
|
854
|
+
n.T.Je = null;
|
|
855
|
+
commitPendingNode(n);
|
|
843
856
|
}
|
|
844
857
|
// A cleanup those commits ran that wrote a node `u` still held joined
|
|
845
858
|
// `u`, which has left `transactions`: the write is this landing's, and
|
|
@@ -852,14 +865,14 @@ class GlobalQueue {
|
|
|
852
865
|
* landing's re-passes, in height order): the frame's effects run as one
|
|
853
866
|
* pass would have queued them — a shell re-derived at the landing before a
|
|
854
867
|
* boundary swap held since the write (#3540's log order). */ function releaseQueues(e) {
|
|
855
|
-
for (let
|
|
856
|
-
append(globalQueue.un[
|
|
857
|
-
e.un[
|
|
868
|
+
for (let o = 0; o < 2; o++) {
|
|
869
|
+
append(globalQueue.un[o], e.un[o]);
|
|
870
|
+
e.un[o] = [];
|
|
858
871
|
}
|
|
859
872
|
}
|
|
860
873
|
|
|
861
|
-
/** `a.push(...b)` without the argument-count limit. */ function append(e,
|
|
862
|
-
for (let
|
|
874
|
+
/** `a.push(...b)` without the argument-count limit. */ function append(e, o) {
|
|
875
|
+
for (let n = 0; n < o.length; n++) e.push(o[n]);
|
|
863
876
|
}
|
|
864
877
|
|
|
865
878
|
/** Nodes staged this flush (`_pendingValue` set), committed at its end. */ const pendingNodes = [];
|
|
@@ -871,10 +884,10 @@ class GlobalQueue {
|
|
|
871
884
|
|
|
872
885
|
/** A15's stale reader: `c` was served the committed value of a node `t`
|
|
873
886
|
* holds (a render effect, a verdict reader, lane work) and is re-derived
|
|
874
|
-
* after `t`'s landing (`_reruns`). Once per pass. */ function staleReader(e,
|
|
887
|
+
* after `t`'s landing (`_reruns`). Once per pass. */ function staleReader(e, o) {
|
|
875
888
|
if (!(e.R & REACTIVE_FRAME_READ)) {
|
|
876
889
|
e.R |= REACTIVE_FRAME_READ;
|
|
877
|
-
|
|
890
|
+
o.En.push(e);
|
|
878
891
|
}
|
|
879
892
|
}
|
|
880
893
|
|
|
@@ -900,13 +913,13 @@ function insertSubs(e) {
|
|
|
900
913
|
// Presence bits gate the optional-slot probes (see constants.ts): one
|
|
901
914
|
// masked read of the always-present _config instead of missing-property
|
|
902
915
|
// lookups in the hottest notify loop.
|
|
903
|
-
const
|
|
904
|
-
const
|
|
916
|
+
const o = e.l;
|
|
917
|
+
const n = (o & CONFIG_HAS_SNAPSHOT) !== 0 && e.T?.lt !== undefined;
|
|
905
918
|
// Observe-tier fan-out: this walk visits every subscriber edge anyway, so
|
|
906
919
|
// the graph-size count is one local increment here and no field anywhere.
|
|
907
920
|
let t = 0;
|
|
908
|
-
for (let
|
|
909
|
-
const e =
|
|
921
|
+
for (let o = e.o; o !== null; o = o.t) {
|
|
922
|
+
const e = o.u;
|
|
910
923
|
t++;
|
|
911
924
|
// Missed-wake latch (#3037): this write is landing while the subscriber
|
|
912
925
|
// is mid-recompute (a nested pull committing beneath its reads), and the
|
|
@@ -916,8 +929,8 @@ function insertSubs(e) {
|
|
|
916
929
|
// pass either re-reads them fresh or trims them), and neither does the
|
|
917
930
|
// tail link: it is the read IN FLIGHT — read() links before it pulls, so
|
|
918
931
|
// this very commit is what that read returns.
|
|
919
|
-
if (e.R & REACTIVE_RECOMPUTING_DEPS &&
|
|
920
|
-
if (
|
|
932
|
+
if (e.R & REACTIVE_RECOMPUTING_DEPS && o.Te === e.Ne && o !== e._) e.R |= REACTIVE_MISSED_WAKE;
|
|
933
|
+
if (n && e.l & CONFIG_IN_SNAPSHOT_SCOPE) {
|
|
921
934
|
e.R |= REACTIVE_SNAPSHOT_STALE;
|
|
922
935
|
continue;
|
|
923
936
|
}
|
|
@@ -933,25 +946,25 @@ function insertSubs(e) {
|
|
|
933
946
|
* inert for its pass (`recompute` seats a lane only from its own `_x`), it
|
|
934
947
|
* is a live write if the effect becomes a zombie later this flush — an
|
|
935
948
|
* on-screen reader whose removal an adopted write stages follows the lane
|
|
936
|
-
* (the lane-membership ruling, 2026-10-05; `_update`). */ function laneDirty(e,
|
|
937
|
-
for (let
|
|
938
|
-
const e =
|
|
939
|
-
if (e?.V ? sameLane(e,
|
|
949
|
+
* (the lane-membership ruling, 2026-10-05; `_update`). */ function laneDirty(e, o) {
|
|
950
|
+
for (let n = e.o; n !== null; n = n.t) {
|
|
951
|
+
const e = n.u.T?.Je;
|
|
952
|
+
if (e?.V ? sameLane(e, o) : n.u.i) n.u.R |= REACTIVE_LANE_DIRTY;
|
|
940
953
|
}
|
|
941
954
|
}
|
|
942
955
|
|
|
943
|
-
/** One lane, or two of one link group (#3335): one reveal unit. */ function sameLane(e,
|
|
944
|
-
return e ===
|
|
956
|
+
/** One lane, or two of one link group (#3335): one reveal unit. */ function sameLane(e, o) {
|
|
957
|
+
return e === o || e.nn !== null && e.nn === o.nn;
|
|
945
958
|
}
|
|
946
959
|
|
|
947
960
|
function commitPendingNode(e) {
|
|
948
|
-
const
|
|
961
|
+
const o = e;
|
|
949
962
|
// L2: the commit is where a pass, held or not, stops being uncommitted —
|
|
950
963
|
// unless it has no answer yet. A pass still in flight (pending, nothing
|
|
951
964
|
// staged) stays uncommitted: a re-pass disposes its children on the spot,
|
|
952
965
|
// and the frame it parked stays the frame until a pass of this node
|
|
953
966
|
// commits a value.
|
|
954
|
-
if (!
|
|
967
|
+
if (!o.X) {
|
|
955
968
|
e.l &= -385;
|
|
956
969
|
if (e.ue !== NOT_PENDING) {
|
|
957
970
|
e.Ie = e.ue;
|
|
@@ -962,62 +975,62 @@ function commitPendingNode(e) {
|
|
|
962
975
|
// Computeds only from here (`_statusFlags` is not a signal field). A
|
|
963
976
|
// commit beneath a flight publishes its inputs (A15 reveal corollary,
|
|
964
977
|
// #3305): a reveal of it must observe, not show the pre-flight value.
|
|
965
|
-
const
|
|
978
|
+
const n = e.ue === NOT_PENDING && (o.m & STATUS_PENDING) !== 0;
|
|
966
979
|
const t = e.l & CONFIG_STAGED_ERROR;
|
|
967
980
|
// An answer commits: the error it replaces leaves the display (D-41).
|
|
968
|
-
if (!
|
|
969
|
-
e.l =
|
|
981
|
+
if (!n && o.T) o.T.de = undefined;
|
|
982
|
+
e.l = n ? e.l & -1048833 | CONFIG_INPUTS_PUBLISHED : e.l & -3147137;
|
|
970
983
|
// D-41: the staged answer is an error — published now, when a value would
|
|
971
984
|
// show, through the ordinary error path (`stageError`). Its readers first
|
|
972
985
|
// see it in the cycle after this seam: a tracked re-read there is not a
|
|
973
986
|
// retry (`read`), or a boundary re-derived by it would retry it forever.
|
|
974
987
|
if (t) {
|
|
975
|
-
const
|
|
988
|
+
const n = e.ue;
|
|
976
989
|
e.ue = NOT_PENDING;
|
|
977
990
|
e.ie = clock + 1;
|
|
978
|
-
notifyStatus(
|
|
991
|
+
notifyStatus(o, STATUS_ERROR, n);
|
|
979
992
|
} else if (e.ue !== NOT_PENDING) {
|
|
980
993
|
e.Ie = e.ue;
|
|
981
994
|
e.ue = NOT_PENDING;
|
|
982
995
|
// A node born staged (recompute) initializes at this commit.
|
|
983
|
-
|
|
996
|
+
o.m &= ~STATUS_UNINITIALIZED;
|
|
984
997
|
// A quiet re-ask's classification survives its landing and dies with
|
|
985
998
|
// the landed value's commit (A19 exc. 2, #3178): verdict-quiet through
|
|
986
999
|
// the reveal. (The sweep of a node still in flight is not a landing.)
|
|
987
1000
|
// The A28 stash goes with it.
|
|
988
|
-
if (
|
|
1001
|
+
if (o.T != null) o.T.ut = false, o.T.Gt = NOT_PENDING;
|
|
989
1002
|
// An effect with a staged value was born held (L2): its first run is
|
|
990
1003
|
// this commit's, not its creation's (A29) — queue it now.
|
|
991
1004
|
if (e.i && e.i !== EFFECT_TRACKED) {
|
|
992
1005
|
e.Qe = true;
|
|
993
|
-
globalQueue.enqueue(e.i, e.W ??= GlobalQueue.K.bind(null,
|
|
1006
|
+
globalQueue.enqueue(e.i, e.W ??= GlobalQueue.K.bind(null, o));
|
|
994
1007
|
}
|
|
995
1008
|
}
|
|
996
1009
|
// The committed value is the first observable answer for a loading-window
|
|
997
1010
|
// node — the window closes here, not at compute time (#2990). Unconditional
|
|
998
1011
|
// store to an always-present computed slot.
|
|
999
|
-
|
|
1000
|
-
|
|
1012
|
+
o.ce = false;
|
|
1013
|
+
o.R &= ~REACTIVE_MANUAL_WRITE;
|
|
1001
1014
|
// The dependencies of the pass that produced the value are the frame's now:
|
|
1002
1015
|
// the previous frame's tail goes (A30, #3410; `recompute` left it for a
|
|
1003
1016
|
// staged pass). Only after a clean pass: `_error` is cleared by a clean
|
|
1004
1017
|
// pass or by the node's own landing (whose pass was clean), so a set
|
|
1005
1018
|
// `_error` means the last pass threw, kept its full list, and `_depsTail`
|
|
1006
1019
|
// marks where it stopped.
|
|
1007
|
-
if (
|
|
1008
|
-
if (!(
|
|
1020
|
+
if (o.T?.F == null) trimStaleDeps(o);
|
|
1021
|
+
if (!(o.m & STATUS_PENDING)) o.m &= ~STATUS_UNINITIALIZED;
|
|
1009
1022
|
// L2: the children this commit publishes are the frame's now — the frame
|
|
1010
1023
|
// they replace, parked by the pass (`recompute`), goes.
|
|
1011
|
-
if (!
|
|
1024
|
+
if (!n && o.T != null && (o.T.Nt !== null || o.T.ft !== null)) GlobalQueue.et(o, false, true);
|
|
1012
1025
|
}
|
|
1013
1026
|
|
|
1014
1027
|
function commitPendingNodes() {
|
|
1015
1028
|
for (let e = 0; e < pendingNodes.length; e++) {
|
|
1016
|
-
const
|
|
1029
|
+
const o = pendingNodes[e];
|
|
1017
1030
|
// A node a lane pass re-staged this round is the lane's to reveal; one
|
|
1018
1031
|
// a transaction holds (born held by a mainline pass, `passTx`) is that
|
|
1019
1032
|
// transaction's to commit, at its landing.
|
|
1020
|
-
if (!(
|
|
1033
|
+
if (!(o.l & (CONFIG_OVERRIDE | CONFIG_HELD))) commitPendingNode(o);
|
|
1021
1034
|
}
|
|
1022
1035
|
pendingNodes.length = 0;
|
|
1023
1036
|
}
|
|
@@ -1049,24 +1062,27 @@ function flush(e) {
|
|
|
1049
1062
|
// Attribution: whether this call drained anything, so `flushEnd` fires once
|
|
1050
1063
|
// per real drain and never for a no-op call. The declaration is dead in
|
|
1051
1064
|
// prod (its only write is behind true) and rollup drops it.
|
|
1052
|
-
let
|
|
1065
|
+
let o = false;
|
|
1053
1066
|
// The drain's opening instant, under the loop's own condition so it fires
|
|
1054
1067
|
// exactly when `flushEnd` below will. Outside every try (see the rule in
|
|
1055
1068
|
// attribution-hooks.ts).
|
|
1056
1069
|
if (attrHooks !== null && scheduled) attrHooks.flushStart();
|
|
1057
1070
|
while (scheduled) {
|
|
1058
1071
|
globalQueue.flush();
|
|
1059
|
-
|
|
1072
|
+
o = true;
|
|
1060
1073
|
}
|
|
1061
1074
|
// Outside every try in this function (see the rule in attribution-hooks.ts):
|
|
1062
1075
|
// the drain loop above is the one place all scheduled work funnels through,
|
|
1063
1076
|
// so this is the "committed and effects ran" instant for everything the
|
|
1064
1077
|
// loop processed.
|
|
1065
|
-
if (
|
|
1078
|
+
if (o && attrHooks !== null) attrHooks.flushEnd();
|
|
1079
|
+
// A cleanup that threw during the drain, now that the drain is complete
|
|
1080
|
+
// (owner.ts).
|
|
1081
|
+
rethrowCleanupError();
|
|
1066
1082
|
}
|
|
1067
1083
|
|
|
1068
|
-
function runQueue(e,
|
|
1069
|
-
for (let
|
|
1084
|
+
function runQueue(e, o) {
|
|
1085
|
+
for (let n = 0; n < e.length; n++) e[n](o);
|
|
1070
1086
|
}
|
|
1071
1087
|
|
|
1072
|
-
export { GlobalQueue, MAINLINE_QUESTION, ROOT_ERROR_HOOK, actionDepth, applyGuessesHook, blocked, blockersOf, boundarySeamHook, bumpNotifyEpoch, catchHook, clock, commitPendingNode, deferZombie, dirtyQueue, endLanesHook, enforceLoadingBoundary, enterAction, exitAction, externalUntrackHook, flush, flushTransaction, freshHook, globalQueue, haltReactivity, heldRunHook, heldTrim, heldUnder, hiddenHook, holdNode, insertSubs, installBoundaryHooks, installLaneHooks, installMarkHooks, installStoreHooks, installVerdictHooks, joinFuture, joinPassTx, laneCorrectionsHook, laneDirty, laneOutcomeHook, laneReadHook, laneSeamsHook, laneStageHook, laneWriteHook, lanesBlockedHook, list, liveTx, merge, newTransaction, nextQuestion, notifyEpoch, observeFlightHook, ownFlights, passLane, passTx, question, queuePendingNode, releaseAmbientMarksHook, releaseMarksHook, releaseQueues, reruns, resetErrorHalt, resolveTx, sameLane, schedule, setExternalHooks, setPassLane, setQuestion, stagedReaders, staleReader, storeCommitHook, storeParkHook, txOf, unhold, wireExternalSourceHook };
|
|
1088
|
+
export { GlobalQueue, MAINLINE_QUESTION, ROOT_ERROR_HOOK, actionDepth, applyGuessesHook, blocked, blockersOf, boundarySeamHook, bumpNotifyEpoch, catchHook, clock, commitPendingNode, deferZombie, dirtyQueue, endLanesHook, enforceLoadingBoundary, enterAction, exitAction, externalUntrackHook, flush, flushTransaction, freshHook, globalQueue, haltReactivity, haltReactivityAt, heldRunHook, heldTrim, heldUnder, hiddenHook, holdNode, insertSubs, installBoundaryHooks, installLaneHooks, installMarkHooks, installStoreHooks, installVerdictHooks, joinFuture, joinPassTx, laneCorrectionsHook, laneDirty, laneOutcomeHook, laneReadHook, laneSeamsHook, laneStageHook, laneWriteHook, lanesBlockedHook, list, liveTx, merge, newTransaction, nextQuestion, notifyEpoch, observeFlightHook, ownFlights, passLane, passTx, question, queuePendingNode, releaseAmbientMarksHook, releaseMarksHook, releaseQueues, reruns, resetErrorHalt, resolveTx, sameLane, schedule, setExternalHooks, setPassLane, setQuestion, stagedReaders, staleReader, storeCommitHook, storeParkHook, txOf, unhold, wireExternalSourceHook };
|