@solidjs/signals 2.0.0-rc.0 → 2.0.0-rc.1
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/README.md +1 -1
- package/dist/dev.js +2622 -2438
- package/dist/node.cjs +3770 -3571
- package/dist/prod/core/async.js +186 -132
- package/dist/prod/core/core.js +118 -107
- package/dist/prod/core/effect.js +13 -13
- package/dist/prod/core/external.js +1 -1
- package/dist/prod/core/graph.js +8 -8
- package/dist/prod/core/heap.js +24 -24
- package/dist/prod/core/lanes.js +3 -3
- package/dist/prod/core/optimistic.js +38 -21
- package/dist/prod/core/owner.js +21 -21
- package/dist/prod/core/scheduler.js +55 -47
- package/dist/prod/core/verdict.js +40 -40
- package/dist/prod/index.js +7 -7
- package/dist/prod/map.js +81 -79
- package/dist/prod/signals.js +20 -1
- package/dist/prod/store/index.js +36 -0
- package/dist/prod/store/next/optimistic.js +377 -0
- package/dist/prod/store/next/projection.js +172 -0
- package/dist/prod/store/next/reconcile.js +327 -0
- package/dist/prod/store/next/store.js +1232 -0
- package/dist/prod/store/next/target.js +20 -0
- package/dist/prod/store/store.js +123 -879
- package/dist/prod/store/utils.js +59 -186
- package/dist/types/core/core.d.ts +8 -0
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/scheduler.d.ts +4 -2
- package/dist/types/signals.d.ts +19 -0
- package/dist/types/store/index.d.ts +15 -5
- package/dist/types/store/next/optimistic.d.ts +20 -0
- package/dist/types/store/next/projection.d.ts +24 -0
- package/dist/types/store/next/reconcile.d.ts +3 -0
- package/dist/types/store/next/store.d.ts +71 -0
- package/dist/types/store/next/target.d.ts +99 -0
- package/dist/types/store/store.d.ts +26 -101
- package/dist/types/store/utils.d.ts +0 -40
- package/dist/types-cjs/core/core.d.cts +8 -0
- package/dist/types-cjs/core/dev.d.cts +1 -1
- package/dist/types-cjs/core/scheduler.d.cts +4 -2
- package/dist/types-cjs/signals.d.cts +19 -0
- package/dist/types-cjs/store/index.d.cts +15 -5
- package/dist/types-cjs/store/next/optimistic.d.cts +20 -0
- package/dist/types-cjs/store/next/projection.d.cts +24 -0
- package/dist/types-cjs/store/next/reconcile.d.cts +3 -0
- package/dist/types-cjs/store/next/store.d.cts +71 -0
- package/dist/types-cjs/store/next/target.d.cts +99 -0
- package/dist/types-cjs/store/store.d.cts +26 -101
- package/dist/types-cjs/store/utils.d.cts +0 -40
- package/package.json +2 -1
- package/dist/prod/store/optimistic.js +0 -217
- package/dist/prod/store/projection.js +0 -231
- package/dist/prod/store/reconcile.js +0 -707
package/dist/prod/core/graph.js
CHANGED
|
@@ -10,10 +10,10 @@ import "./scheduler.js";
|
|
|
10
10
|
function unlinkSubs(l) {
|
|
11
11
|
const n = l.it;
|
|
12
12
|
const e = l.nt;
|
|
13
|
-
const u = l.
|
|
13
|
+
const u = l.ue;
|
|
14
14
|
const s = l.ll;
|
|
15
15
|
if (u !== null) u.ll = s; else n.rt = s;
|
|
16
|
-
if (s !== null) s.
|
|
16
|
+
if (s !== null) s.ue = u; else {
|
|
17
17
|
n.o = u;
|
|
18
18
|
if (u === null) {
|
|
19
19
|
n.ut?.();
|
|
@@ -61,7 +61,7 @@ function link(l, n, e = false) {
|
|
|
61
61
|
// read order within the computation.
|
|
62
62
|
const u = n.Ye;
|
|
63
63
|
if (u !== null && u.it === l) {
|
|
64
|
-
u.
|
|
64
|
+
u.ye &&= e;
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
let s = null;
|
|
@@ -72,7 +72,7 @@ function link(l, n, e = false) {
|
|
|
72
72
|
s.nl = n.Ze;
|
|
73
73
|
n.Ye = s;
|
|
74
74
|
// First touch of this pass: the previous pass's label is stale.
|
|
75
|
-
s.
|
|
75
|
+
s.ye = e;
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -85,7 +85,7 @@ function link(l, n, e = false) {
|
|
|
85
85
|
if (i !== null && i.fe === n && (!t || i.nl === n.Ze)) {
|
|
86
86
|
// Gen-matched during a recompute = repeat touch this pass (AND); outside
|
|
87
87
|
// a recompute there is no pass boundary, so the latest read labels it.
|
|
88
|
-
if (t) i.
|
|
88
|
+
if (t) i.ye &&= e; else i.ye = e;
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
const o = n.Ye = l.rt = {
|
|
@@ -93,12 +93,12 @@ function link(l, n, e = false) {
|
|
|
93
93
|
fe: n,
|
|
94
94
|
nt: s,
|
|
95
95
|
ll: i,
|
|
96
|
-
|
|
96
|
+
ue: null,
|
|
97
97
|
nl: n.Ze,
|
|
98
|
-
|
|
98
|
+
ye: e
|
|
99
99
|
};
|
|
100
100
|
if (u !== null) u.nt = o; else n.tt = o;
|
|
101
|
-
if (i !== null) i.
|
|
101
|
+
if (i !== null) i.ue = o; else l.o = o;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
export { link, trimStaleDeps, unlinkSubs, unobserved };
|
package/dist/prod/core/heap.js
CHANGED
|
@@ -15,25 +15,25 @@ import { zombieQueue, dirtyQueue } from "./scheduler.js";
|
|
|
15
15
|
const E = e;
|
|
16
16
|
if (!E.Je) {
|
|
17
17
|
E.Je = true;
|
|
18
|
-
E.C.enqueue(EFFECT_USER, E.
|
|
18
|
+
E.C.enqueue(EFFECT_USER, E.ht);
|
|
19
19
|
}
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
const E = queueFor(e);
|
|
23
|
-
if (E.Ve > e.
|
|
23
|
+
if (E.Ve > e.Le) E.Ve = e.Le;
|
|
24
24
|
insertIntoHeap(e, E);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function actualInsertIntoHeap(e, E) {
|
|
28
|
-
const t = (e.
|
|
29
|
-
if (t >= e.
|
|
30
|
-
const n = e.
|
|
28
|
+
const t = (e.Fe?.Tt ? e.Fe.It?.Le : e.Fe?.Le) ?? -1;
|
|
29
|
+
if (t >= e.Le) e.Le = t + 1;
|
|
30
|
+
const n = e.Le;
|
|
31
31
|
const I = E.eE[n];
|
|
32
32
|
if (I === undefined) E.eE[n] = e; else {
|
|
33
|
-
const E = I.
|
|
34
|
-
E.
|
|
35
|
-
e.
|
|
36
|
-
I.
|
|
33
|
+
const E = I.ot;
|
|
34
|
+
E.st = e;
|
|
35
|
+
e.ot = E;
|
|
36
|
+
I.ot = e;
|
|
37
37
|
}
|
|
38
38
|
if (n > E.EE) E.EE = n;
|
|
39
39
|
}
|
|
@@ -66,23 +66,23 @@ function deleteFromHeap(e, E) {
|
|
|
66
66
|
const t = e.se;
|
|
67
67
|
if (!(t & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
|
|
68
68
|
e.se = t & -25;
|
|
69
|
-
const n = e.
|
|
70
|
-
if (e.
|
|
71
|
-
const t = e.
|
|
69
|
+
const n = e.Le;
|
|
70
|
+
if (e.ot === e) E.eE[n] = undefined; else {
|
|
71
|
+
const t = e.st;
|
|
72
72
|
const I = E.eE[n];
|
|
73
73
|
const o = t ?? I;
|
|
74
|
-
if (e === I) E.eE[n] = t; else e.st
|
|
75
|
-
o.
|
|
74
|
+
if (e === I) E.eE[n] = t; else e.ot.st = t;
|
|
75
|
+
o.ot = e.ot;
|
|
76
76
|
}
|
|
77
|
-
e.
|
|
78
|
-
e.
|
|
77
|
+
e.ot = e;
|
|
78
|
+
e.st = undefined;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function markHeap(e) {
|
|
82
82
|
if (e.tE) return;
|
|
83
83
|
e.tE = true;
|
|
84
84
|
for (let E = 0; E <= e.EE; E++) {
|
|
85
|
-
for (let t = e.eE[E]; t !== undefined; t = t.
|
|
85
|
+
for (let t = e.eE[E]; t !== undefined; t = t.st) {
|
|
86
86
|
if (t.se & REACTIVE_IN_HEAP) markNode(t);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
@@ -92,12 +92,12 @@ function markNode(e, E = REACTIVE_DIRTY) {
|
|
|
92
92
|
const t = e.se;
|
|
93
93
|
if ((t & (REACTIVE_CHECK | REACTIVE_DIRTY)) >= E) return;
|
|
94
94
|
e.se = t & -4 | E;
|
|
95
|
-
for (let E = e.o; E !== null; E = E.
|
|
95
|
+
for (let E = e.o; E !== null; E = E.ue) {
|
|
96
96
|
markNode(E.fe, REACTIVE_CHECK);
|
|
97
97
|
}
|
|
98
98
|
if (e.u !== null) {
|
|
99
99
|
for (let E = e.u; E !== null; E = E.ae) {
|
|
100
|
-
for (let e = E.o; e !== null; e = e.
|
|
100
|
+
for (let e = E.o; e !== null; e = e.ue) {
|
|
101
101
|
markNode(e.fe, REACTIVE_CHECK);
|
|
102
102
|
}
|
|
103
103
|
}
|
|
@@ -118,15 +118,15 @@ function runHeap(e, E) {
|
|
|
118
118
|
|
|
119
119
|
function adjustHeight(e, E) {
|
|
120
120
|
deleteFromHeap(e, E);
|
|
121
|
-
let t = e.
|
|
121
|
+
let t = e.Le;
|
|
122
122
|
for (let E = e.tt; E; E = E.nt) {
|
|
123
123
|
const e = E.it;
|
|
124
124
|
const n = e.lt || e;
|
|
125
|
-
if (n.ce && n.
|
|
125
|
+
if (n.ce && n.Le >= t) t = n.Le + 1;
|
|
126
126
|
}
|
|
127
|
-
if (e.
|
|
128
|
-
e.
|
|
129
|
-
for (let E = e.o; E !== null; E = E.
|
|
127
|
+
if (e.Le !== t) {
|
|
128
|
+
e.Le = t;
|
|
129
|
+
for (let E = e.o; E !== null; E = E.ue) {
|
|
130
130
|
// Route each subscriber by its own zombie flag, mirroring the
|
|
131
131
|
// post-recompute height-adjust path. Inserting into the running `heap`
|
|
132
132
|
// unconditionally can park a zombie in `dirtyQueue` (or a live node in
|
package/dist/prod/core/lanes.js
CHANGED
|
@@ -36,8 +36,8 @@ const activeLanes = new Set;
|
|
|
36
36
|
// parent-child is a property of the nodes, not of write order — otherwise
|
|
37
37
|
// the owner's write merges the companion's subscribers into this lane and
|
|
38
38
|
// their effects wait on its async instead of flushing immediately.
|
|
39
|
-
adoptCompanionLane(n.
|
|
40
|
-
adoptCompanionLane(n.
|
|
39
|
+
adoptCompanionLane(n.Oe, e);
|
|
40
|
+
adoptCompanionLane(n.ge, e);
|
|
41
41
|
return e;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -105,7 +105,7 @@ function resolveTransition(n) {
|
|
|
105
105
|
/**
|
|
106
106
|
* Check if a node has an active optimistic override.
|
|
107
107
|
*/ function hasActiveOverride(n) {
|
|
108
|
-
return !!(n.
|
|
108
|
+
return !!(n.De !== undefined && n.De !== NOT_PENDING);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
@@ -24,10 +24,10 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
|
|
|
24
24
|
* once the gate holds — the same late-binding contract as verdict.ts.
|
|
25
25
|
*/
|
|
26
26
|
/** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, n) {
|
|
27
|
-
const t = e.
|
|
28
|
-
const i = t ? unwrapOverride(e.
|
|
27
|
+
const t = e.De !== NOT_PENDING;
|
|
28
|
+
const i = t ? unwrapOverride(e.De) : e.be;
|
|
29
29
|
if (typeof n === "function") n = n(i);
|
|
30
|
-
const u = !!(e.S & STATUS_UNINITIALIZED) || !e.
|
|
30
|
+
const u = !!(e.S & STATUS_UNINITIALIZED) || !e.Ue || !e.Ue(i, n);
|
|
31
31
|
if (!u) {
|
|
32
32
|
// Same-value write with an active override still entangles the current
|
|
33
33
|
// action's transition — the hold must outlast all overlapping actions.
|
|
@@ -51,10 +51,10 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
|
|
|
51
51
|
// Literal undefined must not land raw: the slot doubles as the optimistic
|
|
52
52
|
// brand, and erasing it makes the write invisible and routes follow-up
|
|
53
53
|
// writes off the optimistic path into permanent commits (#2898).
|
|
54
|
-
e.
|
|
54
|
+
e.De = n === undefined ? OVERRIDE_UNDEFINED : n;
|
|
55
55
|
// syncCompanions only pokes _pendingSignal/_latestValueComputed — with
|
|
56
56
|
// neither companion present the call is a guaranteed no-op.
|
|
57
|
-
(e.
|
|
57
|
+
(e.Oe !== undefined || e.ge !== undefined) && GlobalQueue.Pe !== null && GlobalQueue.Pe(e, n);
|
|
58
58
|
e.de = clock;
|
|
59
59
|
insertSubs(e, true);
|
|
60
60
|
schedule();
|
|
@@ -87,9 +87,9 @@ function resolveOptimisticNodes(e) {
|
|
|
87
87
|
// override-covered authoritative values hold in _pendingValue and
|
|
88
88
|
// elevate on their OWN transition's schedule (A18 as re-ruled 2026-07-07).
|
|
89
89
|
if (!(n.S & STATUS_PENDING)) n.S &= ~STATUS_UNINITIALIZED;
|
|
90
|
-
const i = n.
|
|
91
|
-
n.
|
|
92
|
-
if (i !== NOT_PENDING && n.
|
|
90
|
+
const i = n.De;
|
|
91
|
+
n.De = NOT_PENDING;
|
|
92
|
+
if (i !== NOT_PENDING && n.be !== unwrapOverride(i)) insertSubs(n, true);
|
|
93
93
|
n.Ne = null;
|
|
94
94
|
n.sn = null;
|
|
95
95
|
}
|
|
@@ -98,9 +98,9 @@ function resolveOptimisticNodes(e) {
|
|
|
98
98
|
// transition that produced them (A19 — pending is a property of the data).
|
|
99
99
|
for (let t = 0; t < n; t++) {
|
|
100
100
|
const n = e[t];
|
|
101
|
-
if (n.
|
|
101
|
+
if (n.Oe || n.ge) GlobalQueue.un(n);
|
|
102
102
|
const i = n.nn;
|
|
103
|
-
if (i && (i.
|
|
103
|
+
if (i && (i.Oe === n || i.ge === n)) GlobalQueue.un(i);
|
|
104
104
|
}
|
|
105
105
|
e.splice(0, n);
|
|
106
106
|
}
|
|
@@ -153,7 +153,7 @@ function cleanupCompletedLanes(e) {
|
|
|
153
153
|
* that reads a pending mid-transition write sees the committed value; the sub
|
|
154
154
|
* is recorded for replay at commit.
|
|
155
155
|
*/ function gatedRead(e, n, t) {
|
|
156
|
-
if (latestReadActive || e.
|
|
156
|
+
if (latestReadActive || e._e === NOT_PENDING || e.ce || n !== e && !(n.se & REACTIVE_MANUAL_WRITE)) {
|
|
157
157
|
return false;
|
|
158
158
|
}
|
|
159
159
|
activeTransition.ln.add(t);
|
|
@@ -164,7 +164,7 @@ function cleanupCompletedLanes(e) {
|
|
|
164
164
|
* read()'s value selection under a lane: return the committed `_value` for
|
|
165
165
|
* optimistic/lane-assigned signals, stale-mode reads, and pending owners.
|
|
166
166
|
*/ function laneReadsCommitted(e, n, t) {
|
|
167
|
-
if (e.
|
|
167
|
+
if (e.De !== undefined || !!e.Ke || !!(n.S & STATUS_PENDING)) return true;
|
|
168
168
|
if (n === e && stale && t.nn !== e) {
|
|
169
169
|
// The committed view can hide a same-tick ambient write (a lane member —
|
|
170
170
|
// even just an isPending companion flip — puts the reader "under a lane"
|
|
@@ -173,7 +173,7 @@ function cleanupCompletedLanes(e) {
|
|
|
173
173
|
// replay at commit — the same contract gatedRead provides when a
|
|
174
174
|
// transaction is active (#2963). If a transaction forms mid-flush,
|
|
175
175
|
// initTransition carries the recording over to it.
|
|
176
|
-
if (e.
|
|
176
|
+
if (e._e !== NOT_PENDING && activeTransition === null) globalQueue.m.ln.add(t);
|
|
177
177
|
return true;
|
|
178
178
|
}
|
|
179
179
|
return false;
|
|
@@ -184,7 +184,24 @@ function cleanupCompletedLanes(e) {
|
|
|
184
184
|
* a dependency's optimistic lane (own=false — parent-deeper-than-owned-child
|
|
185
185
|
* can run before its OPT-dirty child propagates).
|
|
186
186
|
*/ function recomputeLane(e, n) {
|
|
187
|
-
if (n)
|
|
187
|
+
if (n) {
|
|
188
|
+
const n = resolveLane(e);
|
|
189
|
+
if (!n) return null;
|
|
190
|
+
// Wake-only lane demotion (#3009): a plain write to a latest()-tracked
|
|
191
|
+
// source rides the optimistic channel only to wake verdict companions —
|
|
192
|
+
// its lane is sourced by the companion shadow (_parentSource set) and owns
|
|
193
|
+
// no transaction. When such a node is pulled mid-tick by a latest()/
|
|
194
|
+
// isPending() probe, lane posture would direct-commit _value, leaking the
|
|
195
|
+
// queued write into committed reads before the flush. Return `false` so
|
|
196
|
+
// recompute() runs plain: the value stages and commits with the flush.
|
|
197
|
+
// (el's own override slot excludes companions themselves; a lane merged
|
|
198
|
+
// into a real optimistic lane resolves to a non-companion source.)
|
|
199
|
+
if (!globalQueue.cn && !activeTransition && !n.Ne && n.en.nn !== undefined && e.De === undefined) {
|
|
200
|
+
e.Ke = undefined;
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
return n;
|
|
204
|
+
}
|
|
188
205
|
for (let n = e.tt; n; n = n.nt) {
|
|
189
206
|
const t = n.it;
|
|
190
207
|
if (t.se & REACTIVE_OPTIMISTIC_DIRTY) {
|
|
@@ -218,7 +235,7 @@ function cleanupCompletedLanes(e) {
|
|
|
218
235
|
|
|
219
236
|
function trackOptimisticStore(e) {
|
|
220
237
|
// After initTransition, globalQueue._batch IS activeTransition (same reference)
|
|
221
|
-
globalQueue.m.
|
|
238
|
+
globalQueue.m.dn.add(e);
|
|
222
239
|
schedule();
|
|
223
240
|
}
|
|
224
241
|
|
|
@@ -231,15 +248,15 @@ function trackOptimisticStore(e) {
|
|
|
231
248
|
GlobalQueue.Gt = optimisticWrite;
|
|
232
249
|
GlobalQueue.En = resolveOptimisticNodes;
|
|
233
250
|
GlobalQueue.Tn = transitionBlocked;
|
|
234
|
-
GlobalQueue.
|
|
235
|
-
GlobalQueue.
|
|
251
|
+
GlobalQueue.In = cleanupCompletedLanes;
|
|
252
|
+
GlobalQueue.Nn = runLaneEffects;
|
|
236
253
|
GlobalQueue.Rt = gatedRead;
|
|
237
254
|
GlobalQueue.Ot = laneSuspends;
|
|
238
|
-
GlobalQueue.
|
|
255
|
+
GlobalQueue.Dt = laneReadsCommitted;
|
|
239
256
|
GlobalQueue.je = recomputeLane;
|
|
240
|
-
GlobalQueue
|
|
241
|
-
GlobalQueue.
|
|
242
|
-
GlobalQueue.
|
|
257
|
+
GlobalQueue.ze = laneAsyncPending;
|
|
258
|
+
GlobalQueue.Be = laneAsyncSettled;
|
|
259
|
+
GlobalQueue.Qn = trackOptimisticStore;
|
|
243
260
|
}
|
|
244
261
|
|
|
245
262
|
export { installOptimisticEngine };
|
package/dist/prod/core/owner.js
CHANGED
|
@@ -12,7 +12,7 @@ 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.ke;
|
|
16
16
|
while (n) {
|
|
17
17
|
const e = n.se;
|
|
18
18
|
n.se = e | REACTIVE_ZOMBIE;
|
|
@@ -55,10 +55,10 @@ function disposeChildren(e, n = false, t) {
|
|
|
55
55
|
// edge). Snap runs after the DISPOSED flag is set so the oracle reads
|
|
56
56
|
// false, and notifies subscribers still watching the companion.
|
|
57
57
|
const n = e;
|
|
58
|
-
if (n.
|
|
58
|
+
if (n.Oe || n.ge) GlobalQueue.un(n);
|
|
59
59
|
}
|
|
60
60
|
if (n && e.ce) e.Te = null;
|
|
61
|
-
let l = t ? e.We : e.
|
|
61
|
+
let l = t ? e.We : e.ke;
|
|
62
62
|
while (l) {
|
|
63
63
|
const e = l.He;
|
|
64
64
|
const n = l;
|
|
@@ -82,32 +82,32 @@ function disposeChildren(e, n = false, t) {
|
|
|
82
82
|
if (t) {
|
|
83
83
|
e.We = null;
|
|
84
84
|
} else {
|
|
85
|
-
e.
|
|
85
|
+
e.ke = null;
|
|
86
86
|
e.qe = 0;
|
|
87
87
|
}
|
|
88
88
|
// O(1) splice out of parent's chain on individual dispose. Skipped during
|
|
89
89
|
// batch dispose (parent already disposed) and zombie disposal (node sits on
|
|
90
90
|
// parent's _pendingFirstChild). We leave node._nextSibling intact so outer
|
|
91
91
|
// walks that already advanced past us still reach later siblings.
|
|
92
|
-
if (n && !t && !(i & REACTIVE_ZOMBIE) && e.
|
|
92
|
+
if (n && !t && !(i & REACTIVE_ZOMBIE) && e.Fe !== null && !(e.Fe.se & REACTIVE_DISPOSED)) {
|
|
93
93
|
const n = e.ct;
|
|
94
94
|
const t = e.He;
|
|
95
|
-
if (n !== null) n.He = t; else e.ke
|
|
95
|
+
if (n !== null) n.He = t; else e.Fe.ke = t;
|
|
96
96
|
if (t !== null) t.ct = n;
|
|
97
97
|
e.ct = null;
|
|
98
98
|
}
|
|
99
99
|
runDisposal(e, t);
|
|
100
100
|
// Final effect-returned cleanup fires at true disposal, after `_disposal`
|
|
101
101
|
// to mirror rerun ordering (compute-phase teardown first, cleanup last).
|
|
102
|
-
if (n && e.
|
|
103
|
-
const n = e.
|
|
104
|
-
e.
|
|
102
|
+
if (n && e.Nt) {
|
|
103
|
+
const n = e.Nt;
|
|
104
|
+
e.Nt = undefined;
|
|
105
105
|
n();
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
function runDisposal(e, n) {
|
|
110
|
-
let t = n ? e.Qe : e.
|
|
110
|
+
let t = n ? e.Qe : e.he;
|
|
111
111
|
if (!t) return;
|
|
112
112
|
if (Array.isArray(t)) {
|
|
113
113
|
for (let e = 0; e < t.length; e++) {
|
|
@@ -117,12 +117,12 @@ function runDisposal(e, n) {
|
|
|
117
117
|
} else {
|
|
118
118
|
t.call(t);
|
|
119
119
|
}
|
|
120
|
-
n ? e.Qe = null : e.
|
|
120
|
+
n ? e.Qe = null : e.he = null;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
function childId(e, n) {
|
|
124
124
|
let t = e;
|
|
125
|
-
while (t.T & CONFIG_TRANSPARENT && t.
|
|
125
|
+
while (t.T & CONFIG_TRANSPARENT && t.Fe) t = t.Fe;
|
|
126
126
|
if (t.id != null) return formatId(t.id, n ? t.qe++ : t.qe);
|
|
127
127
|
throw new Error("");
|
|
128
128
|
}
|
|
@@ -204,7 +204,7 @@ function formatId(e, n) {
|
|
|
204
204
|
* checks. `cleanup()` is the unchecked primitive used by internals.
|
|
205
205
|
*/ function cleanup(e) {
|
|
206
206
|
if (!context) return e;
|
|
207
|
-
if (!context.
|
|
207
|
+
if (!context.he) context.he = e; else if (Array.isArray(context.he)) context.he.push(e); else context.he = [ context.he, e ];
|
|
208
208
|
return e;
|
|
209
209
|
}
|
|
210
210
|
|
|
@@ -244,28 +244,28 @@ function disposeRootSelf(e = true) {
|
|
|
244
244
|
const i = {
|
|
245
245
|
id: inheritId(e, t, n),
|
|
246
246
|
T: t ? CONFIG_TRANSPARENT : 0,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
Tt: true,
|
|
248
|
+
It: n?.Tt ? n.It : n,
|
|
249
|
+
ke: null,
|
|
250
250
|
He: null,
|
|
251
251
|
ct: null,
|
|
252
|
-
|
|
252
|
+
he: null,
|
|
253
253
|
C: n?.C ?? globalQueue,
|
|
254
254
|
we: n?.we || defaultContext,
|
|
255
255
|
qe: 0,
|
|
256
256
|
Qe: null,
|
|
257
257
|
We: null,
|
|
258
|
-
|
|
258
|
+
Fe: n,
|
|
259
259
|
dispose: disposeRootSelf
|
|
260
260
|
};
|
|
261
261
|
if (n) {
|
|
262
|
-
const e = n.
|
|
262
|
+
const e = n.ke;
|
|
263
263
|
if (e === null) {
|
|
264
|
-
n.
|
|
264
|
+
n.ke = i;
|
|
265
265
|
} else {
|
|
266
266
|
i.He = e;
|
|
267
267
|
e.ct = i;
|
|
268
|
-
n.
|
|
268
|
+
n.ke = i;
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
return i;
|