@solidjs/signals 2.0.0-beta.19 → 2.0.0-beta.20
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 +670 -371
- package/dist/node.cjs +1878 -1606
- package/dist/prod/affects.js +17 -21
- package/dist/prod/core/action.js +19 -6
- package/dist/prod/core/async.js +57 -71
- package/dist/prod/core/constants.js +15 -1
- package/dist/prod/core/core.js +39 -39
- package/dist/prod/core/effect.js +14 -14
- package/dist/prod/core/graph.js +1 -1
- package/dist/prod/core/heap.js +2 -2
- package/dist/prod/core/lanes.js +23 -13
- package/dist/prod/core/optimistic.js +107 -99
- package/dist/prod/core/owner.js +23 -23
- package/dist/prod/core/scheduler.js +180 -180
- package/dist/prod/core/verdict.js +12 -13
- package/dist/prod/map.js +196 -167
- package/dist/prod/signals.js +1 -1
- package/dist/prod/store/optimistic.js +103 -68
- package/dist/prod/store/reconcile.js +80 -46
- package/dist/prod/store/store.js +204 -73
- package/dist/prod/store/utils.js +61 -42
- package/dist/types/core/action.d.ts +19 -6
- package/dist/types/core/constants.d.ts +12 -0
- package/dist/types/core/dev.d.ts +7 -0
- package/dist/types/core/lanes.d.ts +2 -0
- package/dist/types/core/scheduler.d.ts +2 -6
- package/dist/types/core/types.d.ts +9 -1
- package/dist/types/store/store.d.ts +8 -2
- package/dist/types-cjs/core/action.d.cts +19 -6
- package/dist/types-cjs/core/constants.d.cts +12 -0
- package/dist/types-cjs/core/dev.d.cts +7 -0
- package/dist/types-cjs/core/lanes.d.cts +2 -0
- package/dist/types-cjs/core/scheduler.d.cts +2 -6
- package/dist/types-cjs/core/types.d.cts +9 -1
- package/dist/types-cjs/store/store.d.cts +8 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { NOT_PENDING, STATUS_UNINITIALIZED, STATUS_PENDING, CONFIG_OWNED_WRITE, REACTIVE_MANUAL_WRITE, REACTIVE_OPTIMISTIC_DIRTY, EFFECT_RENDER, EFFECT_USER } from "./constants.js";
|
|
1
|
+
import { NOT_PENDING, unwrapOverride, STATUS_UNINITIALIZED, OVERRIDE_UNDEFINED, STATUS_PENDING, CONFIG_OWNED_WRITE, REACTIVE_MANUAL_WRITE, REACTIVE_OPTIMISTIC_DIRTY, EFFECT_RENDER, EFFECT_USER } from "./constants.js";
|
|
2
2
|
|
|
3
|
-
import { latestReadActive,
|
|
3
|
+
import { latestReadActive, currentOptimisticLane, stale } from "./core.js";
|
|
4
4
|
|
|
5
5
|
import { NotReadyError } from "./error.js";
|
|
6
6
|
|
|
@@ -29,33 +29,40 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
|
|
|
29
29
|
// committed-view rerun. Keep that override local to the stash flush.
|
|
30
30
|
let stashedOptimisticReads = null;
|
|
31
31
|
|
|
32
|
-
/** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e,
|
|
33
|
-
const
|
|
34
|
-
const i =
|
|
35
|
-
if (typeof
|
|
36
|
-
const u = !!(e.i & STATUS_UNINITIALIZED) || !e.Ge || !e.Ge(i,
|
|
32
|
+
/** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, n) {
|
|
33
|
+
const t = e.be !== NOT_PENDING;
|
|
34
|
+
const i = t ? unwrapOverride(e.be) : e.Ue;
|
|
35
|
+
if (typeof n === "function") n = n(i);
|
|
36
|
+
const u = !!(e.i & STATUS_UNINITIALIZED) || !e.Ge || !e.Ge(i, n);
|
|
37
37
|
if (!u) {
|
|
38
38
|
// Same-value write with an active override still entangles the current
|
|
39
39
|
// action's transition — the hold must outlast all overlapping actions.
|
|
40
|
-
if (
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
40
|
+
if (t) {
|
|
41
|
+
const n = resolveTransition(e);
|
|
42
|
+
if (n && activeTransition !== n) globalQueue.initTransition(n);
|
|
43
43
|
}
|
|
44
|
-
return
|
|
44
|
+
return n;
|
|
45
45
|
}
|
|
46
|
-
if (
|
|
46
|
+
if (t) globalQueue.initTransition(resolveTransition(e));
|
|
47
47
|
// No revert target is stashed: while the override is active every reader
|
|
48
48
|
// sees it (A17), so authoritative arrivals commit silently into _value and
|
|
49
49
|
// reverting is just dropping the override — _value is already correct.
|
|
50
|
-
else globalQueue.Be.push(e);
|
|
50
|
+
else globalQueue.N.Be.push(e);
|
|
51
|
+
// Stamp ownership on the node (post-merge, so entangled writers share the
|
|
52
|
+
// joint root). resolveTransition prefers this over the lane's _transition,
|
|
53
|
+
// which a shared subscriber can merge across transactions (#2912).
|
|
54
|
+
e.fn = activeTransition;
|
|
51
55
|
const s = getOrCreateLane(e);
|
|
52
56
|
e.Je = s;
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
// Literal undefined must not land raw: the slot doubles as the optimistic
|
|
58
|
+
// brand, and erasing it makes the write invisible and routes follow-up
|
|
59
|
+
// writes off the optimistic path into permanent commits (#2898).
|
|
60
|
+
e.be = n === undefined ? OVERRIDE_UNDEFINED : n;
|
|
61
|
+
GlobalQueue._e !== null && GlobalQueue._e(e, n);
|
|
55
62
|
e.Ie = clock;
|
|
56
63
|
insertSubs(e, true);
|
|
57
64
|
schedule();
|
|
58
|
-
return
|
|
65
|
+
return n;
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
function readStashed(e) {
|
|
@@ -63,8 +70,8 @@ function readStashed(e) {
|
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
function queueStashedOptimisticEffects(e) {
|
|
66
|
-
for (let
|
|
67
|
-
const e =
|
|
73
|
+
for (let n = e.p; n !== null; n = n.de) {
|
|
74
|
+
const e = n.Ee;
|
|
68
75
|
if (!e.De) continue;
|
|
69
76
|
enqueueSub(e);
|
|
70
77
|
}
|
|
@@ -75,11 +82,11 @@ function queueStashedOptimisticEffects(e) {
|
|
|
75
82
|
* optimistic nodes: give plain optimistic signals one committed-view rerun.
|
|
76
83
|
*/ function stashOptimistic(e) {
|
|
77
84
|
stashedOptimisticReads = new Set;
|
|
78
|
-
for (let
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
stashedOptimisticReads.add(
|
|
82
|
-
queueStashedOptimisticEffects(
|
|
85
|
+
for (let n = 0; n < e.Be.length; n++) {
|
|
86
|
+
const t = e.Be[n];
|
|
87
|
+
if (t.xe || t.U & CONFIG_OWNED_WRITE) continue;
|
|
88
|
+
stashedOptimisticReads.add(t);
|
|
89
|
+
queueStashedOptimisticEffects(t);
|
|
83
90
|
}
|
|
84
91
|
try {
|
|
85
92
|
finalizePureQueue(null, true);
|
|
@@ -93,13 +100,13 @@ function queueStashedOptimisticEffects(e) {
|
|
|
93
100
|
* while one of its optimistic nodes holds an active override that is still
|
|
94
101
|
* pending on real (non-affects-sentinel) async.
|
|
95
102
|
*/ function transitionBlocked(e) {
|
|
96
|
-
for (let
|
|
97
|
-
const
|
|
98
|
-
if (hasActiveOverride(
|
|
103
|
+
for (let n = 0; n < e.Be.length; n++) {
|
|
104
|
+
const t = e.Be[n];
|
|
105
|
+
if (hasActiveOverride(t) && "i" in t && t.i & STATUS_PENDING && t.k instanceof NotReadyError &&
|
|
99
106
|
// Mark-sourced pending never blocks settlement: affects() releases AT
|
|
100
107
|
// settle, so counting its sentinel here would deadlock the window it
|
|
101
108
|
// is scoped to.
|
|
102
|
-
!
|
|
109
|
+
!t.k.source?.l) {
|
|
103
110
|
return true;
|
|
104
111
|
}
|
|
105
112
|
}
|
|
@@ -110,62 +117,63 @@ function resolveOptimisticNodes(e) {
|
|
|
110
117
|
// Settlement writes below (snapCompanionsToState → updatePendingSignal-style
|
|
111
118
|
// notifications) may push fresh optimistic nodes; only this batch settles
|
|
112
119
|
// now, so iterate a fixed window and splice it out at the end.
|
|
113
|
-
const
|
|
114
|
-
for (let
|
|
115
|
-
const
|
|
116
|
-
|
|
120
|
+
const n = e.length;
|
|
121
|
+
for (let t = 0; t < n; t++) {
|
|
122
|
+
const n = e[t];
|
|
123
|
+
n.Je = undefined;
|
|
117
124
|
// Revert is a pure drop: there is no revert target to commit —
|
|
118
125
|
// override-covered authoritative values hold in _pendingValue and
|
|
119
126
|
// elevate on their OWN transition's schedule (A18 as re-ruled 2026-07-07).
|
|
120
|
-
if (!(
|
|
121
|
-
const i =
|
|
122
|
-
|
|
123
|
-
if (i !== NOT_PENDING &&
|
|
124
|
-
|
|
127
|
+
if (!(n.i & STATUS_PENDING)) n.i &= ~STATUS_UNINITIALIZED;
|
|
128
|
+
const i = n.be;
|
|
129
|
+
n.be = NOT_PENDING;
|
|
130
|
+
if (i !== NOT_PENDING && n.Ue !== unwrapOverride(i)) insertSubs(n, true);
|
|
131
|
+
n.ve = null;
|
|
132
|
+
n.fn = null;
|
|
125
133
|
}
|
|
126
134
|
// Settlement checkpoint (#2838): companions caught in this batch (or owned
|
|
127
135
|
// by a node in it) re-derive from committed state, so verdicts survive the
|
|
128
136
|
// transition that produced them (A19 — pending is a property of the data).
|
|
129
|
-
for (let
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
132
|
-
const i =
|
|
133
|
-
if (i && (i.ye ===
|
|
137
|
+
for (let t = 0; t < n; t++) {
|
|
138
|
+
const n = e[t];
|
|
139
|
+
if (n.ye || n.pe) GlobalQueue.R(n);
|
|
140
|
+
const i = n.en;
|
|
141
|
+
if (i && (i.ye === n || i.pe === n)) GlobalQueue.R(i);
|
|
134
142
|
}
|
|
135
|
-
e.splice(0,
|
|
143
|
+
e.splice(0, n);
|
|
136
144
|
}
|
|
137
145
|
|
|
138
|
-
function runQueue(e,
|
|
139
|
-
for (let
|
|
146
|
+
function runQueue(e, n) {
|
|
147
|
+
for (let t = 0; t < e.length; t++) e[t](n);
|
|
140
148
|
}
|
|
141
149
|
|
|
142
150
|
/**
|
|
143
151
|
* Run effects from all lanes that are ready (no pending async).
|
|
144
152
|
*/ function runLaneEffects(e) {
|
|
145
|
-
for (const
|
|
146
|
-
if (
|
|
147
|
-
const
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
runQueue(
|
|
153
|
+
for (const n of activeLanes) {
|
|
154
|
+
if (n.an || n.Pe.size > 0) continue;
|
|
155
|
+
const t = n.tn[e - 1];
|
|
156
|
+
if (t.length) {
|
|
157
|
+
n.tn[e - 1] = [];
|
|
158
|
+
runQueue(t, e);
|
|
151
159
|
}
|
|
152
160
|
}
|
|
153
161
|
}
|
|
154
162
|
|
|
155
163
|
function cleanupCompletedLanes(e) {
|
|
156
|
-
for (const
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
159
|
-
if (!
|
|
160
|
-
if (
|
|
161
|
-
if (
|
|
164
|
+
for (const n of activeLanes) {
|
|
165
|
+
const t = e ? n.ve === e : !n.ve;
|
|
166
|
+
if (!t) continue;
|
|
167
|
+
if (!n.an) {
|
|
168
|
+
if (n.tn[0].length) runQueue(n.tn[0], EFFECT_RENDER);
|
|
169
|
+
if (n.tn[1].length) runQueue(n.tn[1], EFFECT_USER);
|
|
162
170
|
}
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
activeLanes.delete(
|
|
168
|
-
signalLanes.delete(
|
|
171
|
+
if (n.rn.Je === n) n.rn.Je = undefined;
|
|
172
|
+
n.Pe.clear();
|
|
173
|
+
n.tn[0].length = 0;
|
|
174
|
+
n.tn[1].length = 0;
|
|
175
|
+
activeLanes.delete(n);
|
|
176
|
+
signalLanes.delete(n.rn);
|
|
169
177
|
}
|
|
170
178
|
}
|
|
171
179
|
|
|
@@ -173,44 +181,44 @@ function cleanupCompletedLanes(e) {
|
|
|
173
181
|
// Per-lane suspension: only throw if in same lane as pending async
|
|
174
182
|
// AND the node doesn't have an active override (overrides are the visible value,
|
|
175
183
|
// downstream in the lane should read the override, not throw)
|
|
176
|
-
const
|
|
177
|
-
if (!
|
|
178
|
-
return findLane(
|
|
184
|
+
const n = e.Je;
|
|
185
|
+
if (!n) return false;
|
|
186
|
+
return findLane(n) === findLane(currentOptimisticLane) && !hasActiveOverride(e);
|
|
179
187
|
}
|
|
180
188
|
|
|
181
189
|
/**
|
|
182
190
|
* read()'s entanglement gate: a reader recomputing under an optimistic lane
|
|
183
191
|
* that reads a pending mid-transition write sees the committed value; the sub
|
|
184
192
|
* is recorded for replay at commit.
|
|
185
|
-
*/ function gatedRead(e,
|
|
186
|
-
if (latestReadActive || e.ge === NOT_PENDING || e.xe ||
|
|
193
|
+
*/ function gatedRead(e, n, t) {
|
|
194
|
+
if (latestReadActive || e.ge === NOT_PENDING || e.xe || n !== e && !(n.u & REACTIVE_MANUAL_WRITE)) {
|
|
187
195
|
return false;
|
|
188
196
|
}
|
|
189
|
-
activeTransition.
|
|
197
|
+
activeTransition.un.add(t);
|
|
190
198
|
return true;
|
|
191
199
|
}
|
|
192
200
|
|
|
193
201
|
/**
|
|
194
202
|
* read()'s value selection under a lane: return the committed `_value` for
|
|
195
203
|
* optimistic/lane-assigned signals, stale-mode reads, and pending owners.
|
|
196
|
-
*/ function laneReadsCommitted(e,
|
|
197
|
-
return e.be !== undefined || !!e.Je ||
|
|
204
|
+
*/ function laneReadsCommitted(e, n, t) {
|
|
205
|
+
return e.be !== undefined || !!e.Je || n === e && stale && t.en !== e || !!(n.i & STATUS_PENDING);
|
|
198
206
|
}
|
|
199
207
|
|
|
200
208
|
/**
|
|
201
209
|
* recompute()'s lane posture: resolve the node's own lane (own=true), or adopt
|
|
202
210
|
* a dependency's optimistic lane (own=false — parent-deeper-than-owned-child
|
|
203
211
|
* can run before its OPT-dirty child propagates).
|
|
204
|
-
*/ function recomputeLane(e,
|
|
205
|
-
if (
|
|
206
|
-
for (let
|
|
207
|
-
const
|
|
208
|
-
if (
|
|
209
|
-
const
|
|
210
|
-
if (
|
|
212
|
+
*/ function recomputeLane(e, n) {
|
|
213
|
+
if (n) return resolveLane(e) ?? null;
|
|
214
|
+
for (let n = e.S; n; n = n.st) {
|
|
215
|
+
const t = n.ot;
|
|
216
|
+
if (t.u & REACTIVE_OPTIMISTIC_DIRTY) {
|
|
217
|
+
const n = resolveLane(t);
|
|
218
|
+
if (n) {
|
|
211
219
|
e.u |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
212
|
-
assignOrMergeLane(e,
|
|
213
|
-
return
|
|
220
|
+
assignOrMergeLane(e, n);
|
|
221
|
+
return n;
|
|
214
222
|
}
|
|
215
223
|
}
|
|
216
224
|
}
|
|
@@ -218,25 +226,25 @@ function cleanupCompletedLanes(e) {
|
|
|
218
226
|
}
|
|
219
227
|
|
|
220
228
|
/** recompute()'s catch path: track pending async in the current lane. */ function laneAsyncPending(e) {
|
|
221
|
-
const
|
|
222
|
-
if (
|
|
223
|
-
|
|
224
|
-
e.Je =
|
|
225
|
-
GlobalQueue.
|
|
229
|
+
const n = findLane(currentOptimisticLane);
|
|
230
|
+
if (n.rn !== e) {
|
|
231
|
+
n.Pe.add(e);
|
|
232
|
+
e.Je = n;
|
|
233
|
+
GlobalQueue.P !== null && GlobalQueue.P(n.rn);
|
|
226
234
|
}
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
/** recompute()'s success path: the node's async settled, clear it from its lane. */ function laneAsyncSettled(e) {
|
|
230
|
-
const
|
|
231
|
-
if (
|
|
232
|
-
|
|
233
|
-
GlobalQueue.
|
|
238
|
+
const n = resolveLane(e);
|
|
239
|
+
if (n) {
|
|
240
|
+
n.Pe.delete(e);
|
|
241
|
+
GlobalQueue.P !== null && GlobalQueue.P(n.rn);
|
|
234
242
|
}
|
|
235
243
|
}
|
|
236
244
|
|
|
237
245
|
function trackOptimisticStore(e) {
|
|
238
|
-
// After initTransition, globalQueue.
|
|
239
|
-
globalQueue.
|
|
246
|
+
// After initTransition, globalQueue._batch IS activeTransition (same reference)
|
|
247
|
+
globalQueue.N.dn.add(e);
|
|
240
248
|
schedule();
|
|
241
249
|
}
|
|
242
250
|
|
|
@@ -247,19 +255,19 @@ function trackOptimisticStore(e) {
|
|
|
247
255
|
*/ function installOptimisticEngine() {
|
|
248
256
|
if (GlobalQueue.bt !== null) return;
|
|
249
257
|
GlobalQueue.bt = optimisticWrite;
|
|
250
|
-
GlobalQueue.
|
|
251
|
-
GlobalQueue.
|
|
252
|
-
GlobalQueue.
|
|
253
|
-
GlobalQueue.
|
|
254
|
-
GlobalQueue.
|
|
255
|
-
GlobalQueue.
|
|
256
|
-
GlobalQueue.
|
|
258
|
+
GlobalQueue.En = resolveOptimisticNodes;
|
|
259
|
+
GlobalQueue.Tn = stashOptimistic;
|
|
260
|
+
GlobalQueue.In = transitionBlocked;
|
|
261
|
+
GlobalQueue.Nn = cleanupCompletedLanes;
|
|
262
|
+
GlobalQueue.On = runLaneEffects;
|
|
263
|
+
GlobalQueue.Dt = readStashed;
|
|
264
|
+
GlobalQueue.gt = gatedRead;
|
|
257
265
|
GlobalQueue.ht = laneSuspends;
|
|
258
|
-
GlobalQueue.
|
|
266
|
+
GlobalQueue.vt = laneReadsCommitted;
|
|
259
267
|
GlobalQueue.$e = recomputeLane;
|
|
260
268
|
GlobalQueue.et = laneAsyncPending;
|
|
261
269
|
GlobalQueue.Xe = laneAsyncSettled;
|
|
262
|
-
GlobalQueue.
|
|
270
|
+
GlobalQueue.mn = trackOptimisticStore;
|
|
263
271
|
}
|
|
264
272
|
|
|
265
273
|
export { installOptimisticEngine };
|
package/dist/prod/core/owner.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { REACTIVE_DISPOSED, REACTIVE_ZOMBIE, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, CONFIG_TRANSPARENT, defaultContext } from "./constants.js";
|
|
2
2
|
|
|
3
3
|
import { context, runWithOwner, pendingCheckActive, latestReadActive, tracking } from "./core.js";
|
|
4
4
|
|
|
@@ -6,13 +6,13 @@ import { unlinkSubs } from "./graph.js";
|
|
|
6
6
|
|
|
7
7
|
import { deleteFromHeap, queueFor, insertIntoHeap, insertIntoHeapHeight } from "./heap.js";
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { GlobalQueue, zombieQueue, dirtyQueue, globalQueue } from "./scheduler.js";
|
|
10
10
|
|
|
11
11
|
const PENDING_OWNER = {};
|
|
12
12
|
|
|
13
13
|
// Dummy owner to trigger store's read() path
|
|
14
14
|
function markDisposal(e) {
|
|
15
|
-
let n = e.
|
|
15
|
+
let n = e.He;
|
|
16
16
|
while (n) {
|
|
17
17
|
const e = n.u;
|
|
18
18
|
n.u = e | REACTIVE_ZOMBIE;
|
|
@@ -54,7 +54,7 @@ function disposeChildren(e, n = false, t) {
|
|
|
54
54
|
if (n.ye || n.pe) GlobalQueue.R(n);
|
|
55
55
|
}
|
|
56
56
|
if (n && e.xe) e.Ae = null;
|
|
57
|
-
let l = t ? e.Ze : e.
|
|
57
|
+
let l = t ? e.Ze : e.He;
|
|
58
58
|
while (l) {
|
|
59
59
|
const e = l.Ve;
|
|
60
60
|
if (l.S) {
|
|
@@ -73,26 +73,26 @@ function disposeChildren(e, n = false, t) {
|
|
|
73
73
|
if (t) {
|
|
74
74
|
e.Ze = null;
|
|
75
75
|
} else {
|
|
76
|
-
e.
|
|
76
|
+
e.He = null;
|
|
77
77
|
e.je = 0;
|
|
78
78
|
}
|
|
79
79
|
// O(1) splice out of parent's chain on individual dispose. Skipped during
|
|
80
80
|
// batch dispose (parent already disposed) and zombie disposal (node sits on
|
|
81
81
|
// parent's _pendingFirstChild). We leave node._nextSibling intact so outer
|
|
82
82
|
// walks that already advanced past us still reach later siblings.
|
|
83
|
-
if (n && !t && !(i & REACTIVE_ZOMBIE) && e.
|
|
84
|
-
const n = e.
|
|
83
|
+
if (n && !t && !(i & REACTIVE_ZOMBIE) && e.Fe !== null && !(e.Fe.u & REACTIVE_DISPOSED)) {
|
|
84
|
+
const n = e.Nt;
|
|
85
85
|
const t = e.Ve;
|
|
86
|
-
if (n !== null) n.Ve = t; else e.He
|
|
87
|
-
if (t !== null) t.
|
|
88
|
-
e.
|
|
86
|
+
if (n !== null) n.Ve = t; else e.Fe.He = t;
|
|
87
|
+
if (t !== null) t.Nt = n;
|
|
88
|
+
e.Nt = null;
|
|
89
89
|
}
|
|
90
90
|
runDisposal(e, t);
|
|
91
91
|
// Final effect-returned cleanup fires at true disposal, after `_disposal`
|
|
92
92
|
// to mirror rerun ordering (compute-phase teardown first, cleanup last).
|
|
93
|
-
if (n && e.
|
|
94
|
-
const n = e.
|
|
95
|
-
e.
|
|
93
|
+
if (n && e.dt) {
|
|
94
|
+
const n = e.dt;
|
|
95
|
+
e.dt = undefined;
|
|
96
96
|
n();
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -113,7 +113,7 @@ function runDisposal(e, n) {
|
|
|
113
113
|
|
|
114
114
|
function childId(e, n) {
|
|
115
115
|
let t = e;
|
|
116
|
-
while (t.U & CONFIG_TRANSPARENT && t.
|
|
116
|
+
while (t.U & CONFIG_TRANSPARENT && t.Fe) t = t.Fe;
|
|
117
117
|
if (t.id != null) return formatId(t.id, n ? t.je++ : t.je);
|
|
118
118
|
throw new Error("");
|
|
119
119
|
}
|
|
@@ -235,28 +235,28 @@ function disposeRootSelf(e = true) {
|
|
|
235
235
|
const i = {
|
|
236
236
|
id: inheritId(e, t, n),
|
|
237
237
|
U: t ? CONFIG_TRANSPARENT : 0,
|
|
238
|
-
|
|
239
|
-
Ct: n?.
|
|
240
|
-
|
|
238
|
+
At: true,
|
|
239
|
+
Ct: n?.At ? n.Ct : n,
|
|
240
|
+
He: null,
|
|
241
241
|
Ve: null,
|
|
242
|
-
|
|
242
|
+
Nt: null,
|
|
243
243
|
Me: null,
|
|
244
244
|
v: n?.v ?? globalQueue,
|
|
245
245
|
we: n?.we || defaultContext,
|
|
246
246
|
je: 0,
|
|
247
247
|
We: null,
|
|
248
248
|
Ze: null,
|
|
249
|
-
|
|
249
|
+
Fe: n,
|
|
250
250
|
dispose: disposeRootSelf
|
|
251
251
|
};
|
|
252
252
|
if (n) {
|
|
253
|
-
const e = n.
|
|
253
|
+
const e = n.He;
|
|
254
254
|
if (e === null) {
|
|
255
|
-
n.
|
|
255
|
+
n.He = i;
|
|
256
256
|
} else {
|
|
257
257
|
i.Ve = e;
|
|
258
|
-
e.
|
|
259
|
-
n.
|
|
258
|
+
e.Nt = i;
|
|
259
|
+
n.He = i;
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
return i;
|