@solidjs/signals 2.0.0-beta.21 → 2.0.0-beta.22
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 +182 -298
- package/dist/node.cjs +1055 -1166
- package/dist/prod/affects.js +71 -163
- package/dist/prod/boundaries.js +141 -137
- package/dist/prod/core/action.js +3 -3
- package/dist/prod/core/async.js +83 -99
- package/dist/prod/core/core.js +254 -297
- package/dist/prod/core/effect.js +46 -46
- package/dist/prod/core/external.js +4 -4
- package/dist/prod/core/graph.js +54 -46
- package/dist/prod/core/heap.js +50 -50
- package/dist/prod/core/lanes.js +34 -34
- package/dist/prod/core/optimistic.js +64 -106
- package/dist/prod/core/owner.js +52 -52
- package/dist/prod/core/scheduler.js +209 -210
- package/dist/prod/core/verdict.js +129 -78
- package/dist/prod/map.js +101 -101
- package/dist/prod/signals.js +23 -5
- package/dist/prod/store/optimistic.js +11 -11
- package/dist/prod/store/projection.js +2 -2
- package/dist/prod/store/store.js +14 -14
- package/dist/types/affects.d.ts +9 -9
- package/dist/types/core/async.d.ts +1 -1
- package/dist/types/core/error.d.ts +7 -0
- package/dist/types/core/scheduler.d.ts +1 -6
- package/dist/types/core/types.d.ts +6 -11
- package/dist/types-cjs/affects.d.cts +9 -9
- package/dist/types-cjs/core/async.d.cts +1 -1
- package/dist/types-cjs/core/error.d.cts +7 -0
- package/dist/types-cjs/core/scheduler.d.cts +1 -6
- package/dist/types-cjs/core/types.d.cts +6 -11
- package/package.json +1 -1
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { NOT_PENDING, unwrapOverride, STATUS_UNINITIALIZED, OVERRIDE_UNDEFINED, STATUS_PENDING,
|
|
1
|
+
import { NOT_PENDING, unwrapOverride, STATUS_UNINITIALIZED, OVERRIDE_UNDEFINED, STATUS_PENDING, REACTIVE_MANUAL_WRITE, REACTIVE_OPTIMISTIC_DIRTY, EFFECT_RENDER, EFFECT_USER } from "./constants.js";
|
|
2
2
|
|
|
3
3
|
import { latestReadActive, currentOptimisticLane, stale } from "./core.js";
|
|
4
4
|
|
|
5
5
|
import { NotReadyError } from "./error.js";
|
|
6
6
|
|
|
7
|
-
import { enqueueSub } from "./heap.js";
|
|
8
|
-
|
|
9
7
|
import "./invariants.js";
|
|
10
8
|
|
|
11
9
|
import { resolveTransition, getOrCreateLane, hasActiveOverride, activeLanes, signalLanes, findLane, resolveLane, assignOrMergeLane } from "./lanes.js";
|
|
12
10
|
|
|
13
|
-
import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
|
|
11
|
+
import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule } from "./scheduler.js";
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* The optimistic write engine, moved out of core.ts/scheduler.ts. Everything
|
|
@@ -25,15 +23,11 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
|
|
|
25
23
|
* `_optimisticNodes.length`, `activeLanes.size`), so `!` invocations are safe
|
|
26
24
|
* once the gate holds — the same late-binding contract as verdict.ts.
|
|
27
25
|
*/
|
|
28
|
-
// When a background transition is stashed, plain optimistic signals need one
|
|
29
|
-
// committed-view rerun. Keep that override local to the stash flush.
|
|
30
|
-
let stashedOptimisticReads = null;
|
|
31
|
-
|
|
32
26
|
/** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, n) {
|
|
33
|
-
const t = e.
|
|
34
|
-
const i = t ? unwrapOverride(e.
|
|
27
|
+
const t = e.Ee !== NOT_PENDING;
|
|
28
|
+
const i = t ? unwrapOverride(e.Ee) : e.Re;
|
|
35
29
|
if (typeof n === "function") n = n(i);
|
|
36
|
-
const u = !!(e.
|
|
30
|
+
const u = !!(e.S & STATUS_UNINITIALIZED) || !e.Pe || !e.Pe(i, n);
|
|
37
31
|
if (!u) {
|
|
38
32
|
// Same-value write with an active override still entangles the current
|
|
39
33
|
// action's transition — the hold must outlast all overlapping actions.
|
|
@@ -47,66 +41,32 @@ let stashedOptimisticReads = null;
|
|
|
47
41
|
// No revert target is stashed: while the override is active every reader
|
|
48
42
|
// sees it (A17), so authoritative arrivals commit silently into _value and
|
|
49
43
|
// reverting is just dropping the override — _value is already correct.
|
|
50
|
-
else globalQueue.
|
|
44
|
+
else globalQueue.m.Ze.push(e);
|
|
51
45
|
// Stamp ownership on the node (post-merge, so entangled writers share the
|
|
52
46
|
// joint root). resolveTransition prefers this over the lane's _transition,
|
|
53
47
|
// which a shared subscriber can merge across transactions (#2912).
|
|
54
|
-
e.
|
|
55
|
-
const
|
|
56
|
-
e.
|
|
48
|
+
e.sn = activeTransition;
|
|
49
|
+
const o = getOrCreateLane(e);
|
|
50
|
+
e.je = o;
|
|
57
51
|
// Literal undefined must not land raw: the slot doubles as the optimistic
|
|
58
52
|
// brand, and erasing it makes the write invisible and routes follow-up
|
|
59
53
|
// writes off the optimistic path into permanent commits (#2898).
|
|
60
|
-
e.
|
|
61
|
-
GlobalQueue.
|
|
62
|
-
e.
|
|
54
|
+
e.Ee = n === undefined ? OVERRIDE_UNDEFINED : n;
|
|
55
|
+
GlobalQueue.Ie !== null && GlobalQueue.Ie(e, n);
|
|
56
|
+
e.ce = clock;
|
|
63
57
|
insertSubs(e, true);
|
|
64
58
|
schedule();
|
|
65
59
|
return n;
|
|
66
60
|
}
|
|
67
61
|
|
|
68
|
-
function readStashed(e) {
|
|
69
|
-
return !!stashedOptimisticReads?.has(e);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function queueStashedOptimisticEffects(e) {
|
|
73
|
-
for (let n = e.p; n !== null; n = n.de) {
|
|
74
|
-
const e = n.Ee;
|
|
75
|
-
if (!e.De) continue;
|
|
76
|
-
enqueueSub(e);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Incomplete-transition finalization when the stashed transition holds
|
|
82
|
-
* optimistic nodes: give plain optimistic signals one committed-view rerun.
|
|
83
|
-
*/ function stashOptimistic(e) {
|
|
84
|
-
stashedOptimisticReads = new Set;
|
|
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);
|
|
90
|
-
}
|
|
91
|
-
try {
|
|
92
|
-
finalizePureQueue(null, true);
|
|
93
|
-
} finally {
|
|
94
|
-
stashedOptimisticReads = null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
62
|
/**
|
|
99
63
|
* transitionComplete's override blockage: a settling transition stays open
|
|
100
64
|
* while one of its optimistic nodes holds an active override that is still
|
|
101
65
|
* pending on real (non-affects-sentinel) async.
|
|
102
66
|
*/ function transitionBlocked(e) {
|
|
103
|
-
for (let n = 0; n < e.
|
|
104
|
-
const t = e.
|
|
105
|
-
if (hasActiveOverride(t) && "
|
|
106
|
-
// Mark-sourced pending never blocks settlement: affects() releases AT
|
|
107
|
-
// settle, so counting its sentinel here would deadlock the window it
|
|
108
|
-
// is scoped to.
|
|
109
|
-
!t.k.source?.l) {
|
|
67
|
+
for (let n = 0; n < e.Ze.length; n++) {
|
|
68
|
+
const t = e.Ze[n];
|
|
69
|
+
if (hasActiveOverride(t) && "S" in t && t.S & STATUS_PENDING && t._ instanceof NotReadyError) {
|
|
110
70
|
return true;
|
|
111
71
|
}
|
|
112
72
|
}
|
|
@@ -120,25 +80,25 @@ function resolveOptimisticNodes(e) {
|
|
|
120
80
|
const n = e.length;
|
|
121
81
|
for (let t = 0; t < n; t++) {
|
|
122
82
|
const n = e[t];
|
|
123
|
-
n.
|
|
83
|
+
n.je = undefined;
|
|
124
84
|
// Revert is a pure drop: there is no revert target to commit —
|
|
125
85
|
// override-covered authoritative values hold in _pendingValue and
|
|
126
86
|
// elevate on their OWN transition's schedule (A18 as re-ruled 2026-07-07).
|
|
127
|
-
if (!(n.
|
|
128
|
-
const i = n.
|
|
129
|
-
n.
|
|
130
|
-
if (i !== NOT_PENDING && n.
|
|
131
|
-
n.
|
|
132
|
-
n.
|
|
87
|
+
if (!(n.S & STATUS_PENDING)) n.S &= ~STATUS_UNINITIALIZED;
|
|
88
|
+
const i = n.Ee;
|
|
89
|
+
n.Ee = NOT_PENDING;
|
|
90
|
+
if (i !== NOT_PENDING && n.Re !== unwrapOverride(i)) insertSubs(n, true);
|
|
91
|
+
n.Ue = null;
|
|
92
|
+
n.sn = null;
|
|
133
93
|
}
|
|
134
94
|
// Settlement checkpoint (#2838): companions caught in this batch (or owned
|
|
135
95
|
// by a node in it) re-derive from committed state, so verdicts survive the
|
|
136
96
|
// transition that produced them (A19 — pending is a property of the data).
|
|
137
97
|
for (let t = 0; t < n; t++) {
|
|
138
98
|
const n = e[t];
|
|
139
|
-
if (n.
|
|
140
|
-
const i = n.
|
|
141
|
-
if (i && (i.
|
|
99
|
+
if (n.ge || n.he) GlobalQueue.un(n);
|
|
100
|
+
const i = n.nn;
|
|
101
|
+
if (i && (i.ge === n || i.he === n)) GlobalQueue.un(i);
|
|
142
102
|
}
|
|
143
103
|
e.splice(0, n);
|
|
144
104
|
}
|
|
@@ -151,10 +111,10 @@ function runQueue(e, n) {
|
|
|
151
111
|
* Run effects from all lanes that are ready (no pending async).
|
|
152
112
|
*/ function runLaneEffects(e) {
|
|
153
113
|
for (const n of activeLanes) {
|
|
154
|
-
if (n.
|
|
155
|
-
const t = n.
|
|
114
|
+
if (n.tn || n.de.size > 0) continue;
|
|
115
|
+
const t = n.rn[e - 1];
|
|
156
116
|
if (t.length) {
|
|
157
|
-
n.
|
|
117
|
+
n.rn[e - 1] = [];
|
|
158
118
|
runQueue(t, e);
|
|
159
119
|
}
|
|
160
120
|
}
|
|
@@ -162,18 +122,18 @@ function runQueue(e, n) {
|
|
|
162
122
|
|
|
163
123
|
function cleanupCompletedLanes(e) {
|
|
164
124
|
for (const n of activeLanes) {
|
|
165
|
-
const t = e ? n.
|
|
125
|
+
const t = e ? n.Ue === e : !n.Ue;
|
|
166
126
|
if (!t) continue;
|
|
167
|
-
if (!n.
|
|
168
|
-
if (n.
|
|
169
|
-
if (n.
|
|
127
|
+
if (!n.tn) {
|
|
128
|
+
if (n.rn[0].length) runQueue(n.rn[0], EFFECT_RENDER);
|
|
129
|
+
if (n.rn[1].length) runQueue(n.rn[1], EFFECT_USER);
|
|
170
130
|
}
|
|
171
|
-
if (n.
|
|
172
|
-
n.
|
|
173
|
-
n.
|
|
174
|
-
n.
|
|
131
|
+
if (n.en.je === n) n.en.je = undefined;
|
|
132
|
+
n.de.clear();
|
|
133
|
+
n.rn[0].length = 0;
|
|
134
|
+
n.rn[1].length = 0;
|
|
175
135
|
activeLanes.delete(n);
|
|
176
|
-
signalLanes.delete(n.
|
|
136
|
+
signalLanes.delete(n.en);
|
|
177
137
|
}
|
|
178
138
|
}
|
|
179
139
|
|
|
@@ -181,7 +141,7 @@ function cleanupCompletedLanes(e) {
|
|
|
181
141
|
// Per-lane suspension: only throw if in same lane as pending async
|
|
182
142
|
// AND the node doesn't have an active override (overrides are the visible value,
|
|
183
143
|
// downstream in the lane should read the override, not throw)
|
|
184
|
-
const n = e.
|
|
144
|
+
const n = e.je;
|
|
185
145
|
if (!n) return false;
|
|
186
146
|
return findLane(n) === findLane(currentOptimisticLane) && !hasActiveOverride(e);
|
|
187
147
|
}
|
|
@@ -191,10 +151,10 @@ function cleanupCompletedLanes(e) {
|
|
|
191
151
|
* that reads a pending mid-transition write sees the committed value; the sub
|
|
192
152
|
* is recorded for replay at commit.
|
|
193
153
|
*/ function gatedRead(e, n, t) {
|
|
194
|
-
if (latestReadActive || e.
|
|
154
|
+
if (latestReadActive || e.Ne === NOT_PENDING || e.ke || n !== e && !(n.se & REACTIVE_MANUAL_WRITE)) {
|
|
195
155
|
return false;
|
|
196
156
|
}
|
|
197
|
-
activeTransition.
|
|
157
|
+
activeTransition.ln.add(t);
|
|
198
158
|
return true;
|
|
199
159
|
}
|
|
200
160
|
|
|
@@ -202,7 +162,7 @@ function cleanupCompletedLanes(e) {
|
|
|
202
162
|
* read()'s value selection under a lane: return the committed `_value` for
|
|
203
163
|
* optimistic/lane-assigned signals, stale-mode reads, and pending owners.
|
|
204
164
|
*/ function laneReadsCommitted(e, n, t) {
|
|
205
|
-
return e.
|
|
165
|
+
return e.Ee !== undefined || !!e.je || n === e && stale && t.nn !== e || !!(n.S & STATUS_PENDING);
|
|
206
166
|
}
|
|
207
167
|
|
|
208
168
|
/**
|
|
@@ -211,12 +171,12 @@ function cleanupCompletedLanes(e) {
|
|
|
211
171
|
* can run before its OPT-dirty child propagates).
|
|
212
172
|
*/ function recomputeLane(e, n) {
|
|
213
173
|
if (n) return resolveLane(e) ?? null;
|
|
214
|
-
for (let n = e.
|
|
215
|
-
const t = n.
|
|
216
|
-
if (t.
|
|
174
|
+
for (let n = e.Xe; n; n = n.et) {
|
|
175
|
+
const t = n.tt;
|
|
176
|
+
if (t.se & REACTIVE_OPTIMISTIC_DIRTY) {
|
|
217
177
|
const n = resolveLane(t);
|
|
218
178
|
if (n) {
|
|
219
|
-
e.
|
|
179
|
+
e.se |= REACTIVE_OPTIMISTIC_DIRTY;
|
|
220
180
|
assignOrMergeLane(e, n);
|
|
221
181
|
return n;
|
|
222
182
|
}
|
|
@@ -227,24 +187,24 @@ function cleanupCompletedLanes(e) {
|
|
|
227
187
|
|
|
228
188
|
/** recompute()'s catch path: track pending async in the current lane. */ function laneAsyncPending(e) {
|
|
229
189
|
const n = findLane(currentOptimisticLane);
|
|
230
|
-
if (n.
|
|
231
|
-
n.
|
|
232
|
-
e.
|
|
233
|
-
GlobalQueue.
|
|
190
|
+
if (n.en !== e) {
|
|
191
|
+
n.de.add(e);
|
|
192
|
+
e.je = n;
|
|
193
|
+
GlobalQueue.ae !== null && GlobalQueue.ae(n.en);
|
|
234
194
|
}
|
|
235
195
|
}
|
|
236
196
|
|
|
237
197
|
/** recompute()'s success path: the node's async settled, clear it from its lane. */ function laneAsyncSettled(e) {
|
|
238
198
|
const n = resolveLane(e);
|
|
239
199
|
if (n) {
|
|
240
|
-
n.
|
|
241
|
-
GlobalQueue.
|
|
200
|
+
n.de.delete(e);
|
|
201
|
+
GlobalQueue.ae !== null && GlobalQueue.ae(n.en);
|
|
242
202
|
}
|
|
243
203
|
}
|
|
244
204
|
|
|
245
205
|
function trackOptimisticStore(e) {
|
|
246
206
|
// After initTransition, globalQueue._batch IS activeTransition (same reference)
|
|
247
|
-
globalQueue.
|
|
207
|
+
globalQueue.m.cn.add(e);
|
|
248
208
|
schedule();
|
|
249
209
|
}
|
|
250
210
|
|
|
@@ -253,21 +213,19 @@ function trackOptimisticStore(e) {
|
|
|
253
213
|
* create optimistic state (verdict.ts at module top level, createOptimistic
|
|
254
214
|
* and createOptimisticStore at first call) BEFORE any optimistic node exists.
|
|
255
215
|
*/ function installOptimisticEngine() {
|
|
256
|
-
if (GlobalQueue.
|
|
257
|
-
GlobalQueue.
|
|
216
|
+
if (GlobalQueue.Pt !== null) return;
|
|
217
|
+
GlobalQueue.Pt = optimisticWrite;
|
|
258
218
|
GlobalQueue.En = resolveOptimisticNodes;
|
|
259
|
-
GlobalQueue.Tn =
|
|
260
|
-
GlobalQueue.
|
|
261
|
-
GlobalQueue.
|
|
262
|
-
GlobalQueue.
|
|
263
|
-
GlobalQueue.
|
|
264
|
-
GlobalQueue.
|
|
265
|
-
GlobalQueue.
|
|
266
|
-
GlobalQueue.
|
|
267
|
-
GlobalQueue
|
|
268
|
-
GlobalQueue.
|
|
269
|
-
GlobalQueue.Xe = laneAsyncSettled;
|
|
270
|
-
GlobalQueue.mn = trackOptimisticStore;
|
|
219
|
+
GlobalQueue.Tn = transitionBlocked;
|
|
220
|
+
GlobalQueue.dn = cleanupCompletedLanes;
|
|
221
|
+
GlobalQueue.In = runLaneEffects;
|
|
222
|
+
GlobalQueue.Ct = gatedRead;
|
|
223
|
+
GlobalQueue.At = laneSuspends;
|
|
224
|
+
GlobalQueue.Ot = laneReadsCommitted;
|
|
225
|
+
GlobalQueue.We = recomputeLane;
|
|
226
|
+
GlobalQueue.Ke = laneAsyncPending;
|
|
227
|
+
GlobalQueue.Me = laneAsyncSettled;
|
|
228
|
+
GlobalQueue.Nn = trackOptimisticStore;
|
|
271
229
|
}
|
|
272
230
|
|
|
273
231
|
export { installOptimisticEngine };
|
package/dist/prod/core/owner.js
CHANGED
|
@@ -12,10 +12,10 @@ 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.me;
|
|
16
16
|
while (n) {
|
|
17
|
-
const e = n.
|
|
18
|
-
n.
|
|
17
|
+
const e = n.se;
|
|
18
|
+
n.se = e | REACTIVE_ZOMBIE;
|
|
19
19
|
// migrate height-adjust entries too, not just recompute entries: every
|
|
20
20
|
// `deleteFromHeap` call site picks the queue from the zombie flag, so a
|
|
21
21
|
// node left physically linked in `dirtyQueue` after being zombified gets
|
|
@@ -26,79 +26,79 @@ function markDisposal(e) {
|
|
|
26
26
|
if (e & REACTIVE_IN_HEAP) insertIntoHeap(n, zombieQueue); else insertIntoHeapHeight(n, zombieQueue);
|
|
27
27
|
}
|
|
28
28
|
markDisposal(n);
|
|
29
|
-
n = n.
|
|
29
|
+
n = n.ve;
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function dispose(e) {
|
|
34
|
-
let n = e.
|
|
34
|
+
let n = e.Xe;
|
|
35
35
|
while (n !== null) {
|
|
36
36
|
n = unlinkSubs(n);
|
|
37
37
|
}
|
|
38
|
-
e.
|
|
39
|
-
e.
|
|
38
|
+
e.Xe = null;
|
|
39
|
+
e.qe = null;
|
|
40
40
|
disposeChildren(e, true);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function disposeChildren(e, n = false, t) {
|
|
44
|
-
const i = e.
|
|
44
|
+
const i = e.se;
|
|
45
45
|
if (i & REACTIVE_DISPOSED) return;
|
|
46
46
|
if (n) {
|
|
47
|
-
e.
|
|
47
|
+
e.se = i | REACTIVE_DISPOSED;
|
|
48
48
|
// Companions are created detached and outlive their owner, but a verdict
|
|
49
49
|
// must not: a disposed source can never settle, so an isPending companion
|
|
50
50
|
// latched `true` here would hold a spinner forever (INV-9, the PR #2845
|
|
51
51
|
// edge). Snap runs after the DISPOSED flag is set so the oracle reads
|
|
52
52
|
// false, and notifies subscribers still watching the companion.
|
|
53
53
|
const n = e;
|
|
54
|
-
if (n.
|
|
54
|
+
if (n.ge || n.he) GlobalQueue.un(n);
|
|
55
55
|
}
|
|
56
|
-
if (n && e.
|
|
57
|
-
let l = t ? e.
|
|
56
|
+
if (n && e.ke) e.Te = null;
|
|
57
|
+
let l = t ? e.Le : e.me;
|
|
58
58
|
while (l) {
|
|
59
|
-
const e = l.
|
|
60
|
-
if (l.
|
|
59
|
+
const e = l.ve;
|
|
60
|
+
if (l.Xe) {
|
|
61
61
|
const e = l;
|
|
62
62
|
deleteFromHeap(e, queueFor(e));
|
|
63
|
-
let n = e.
|
|
63
|
+
let n = e.Xe;
|
|
64
64
|
do {
|
|
65
65
|
n = unlinkSubs(n);
|
|
66
66
|
} while (n !== null);
|
|
67
|
-
e.
|
|
68
|
-
e.
|
|
67
|
+
e.Xe = null;
|
|
68
|
+
e.qe = null;
|
|
69
69
|
}
|
|
70
70
|
disposeChildren(l, true);
|
|
71
71
|
l = e;
|
|
72
72
|
}
|
|
73
73
|
if (t) {
|
|
74
|
-
e.
|
|
74
|
+
e.Le = null;
|
|
75
75
|
} else {
|
|
76
|
-
e.
|
|
77
|
-
e.
|
|
76
|
+
e.me = null;
|
|
77
|
+
e.Qe = 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.
|
|
85
|
-
const t = e.
|
|
86
|
-
if (n !== null) n.
|
|
87
|
-
if (t !== null) t.
|
|
88
|
-
e.
|
|
83
|
+
if (n && !t && !(i & REACTIVE_ZOMBIE) && e.Ge !== null && !(e.Ge.se & REACTIVE_DISPOSED)) {
|
|
84
|
+
const n = e.st;
|
|
85
|
+
const t = e.ve;
|
|
86
|
+
if (n !== null) n.ve = t; else e.Ge.me = t;
|
|
87
|
+
if (t !== null) t.st = n;
|
|
88
|
+
e.st = 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.Et) {
|
|
94
|
+
const n = e.Et;
|
|
95
|
+
e.Et = undefined;
|
|
96
96
|
n();
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
function runDisposal(e, n) {
|
|
101
|
-
let t = n ? e.
|
|
101
|
+
let t = n ? e.ye : e.xe;
|
|
102
102
|
if (!t) return;
|
|
103
103
|
if (Array.isArray(t)) {
|
|
104
104
|
for (let e = 0; e < t.length; e++) {
|
|
@@ -108,13 +108,13 @@ function runDisposal(e, n) {
|
|
|
108
108
|
} else {
|
|
109
109
|
t.call(t);
|
|
110
110
|
}
|
|
111
|
-
n ? e.
|
|
111
|
+
n ? e.ye = null : e.xe = null;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
function childId(e, n) {
|
|
115
115
|
let t = e;
|
|
116
|
-
while (t.
|
|
117
|
-
if (t.id != null) return formatId(t.id, n ? t.
|
|
116
|
+
while (t.T & CONFIG_TRANSPARENT && t.Ge) t = t.Ge;
|
|
117
|
+
if (t.id != null) return formatId(t.id, n ? t.Qe++ : t.Qe);
|
|
118
118
|
throw new Error("");
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -195,7 +195,7 @@ function formatId(e, n) {
|
|
|
195
195
|
* checks. `cleanup()` is the unchecked primitive used by internals.
|
|
196
196
|
*/ function cleanup(e) {
|
|
197
197
|
if (!context) return e;
|
|
198
|
-
if (!context.
|
|
198
|
+
if (!context.xe) context.xe = e; else if (Array.isArray(context.xe)) context.xe.push(e); else context.xe = [ context.xe, e ];
|
|
199
199
|
return e;
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -215,7 +215,7 @@ function formatId(e, n) {
|
|
|
215
215
|
* }
|
|
216
216
|
* ```
|
|
217
217
|
*/ function isDisposed(e) {
|
|
218
|
-
return !!(e.
|
|
218
|
+
return !!(e.se & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
function disposeRootSelf(e = true) {
|
|
@@ -234,29 +234,29 @@ function disposeRootSelf(e = true) {
|
|
|
234
234
|
const t = e?.transparent ?? false;
|
|
235
235
|
const i = {
|
|
236
236
|
id: inheritId(e, t, n),
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
237
|
+
T: t ? CONFIG_TRANSPARENT : 0,
|
|
238
|
+
ft: true,
|
|
239
|
+
Nt: n?.ft ? n.Nt : n,
|
|
240
|
+
me: null,
|
|
241
|
+
ve: null,
|
|
242
|
+
st: null,
|
|
243
|
+
xe: null,
|
|
244
|
+
C: n?.C ?? globalQueue,
|
|
245
245
|
we: n?.we || defaultContext,
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
246
|
+
Qe: 0,
|
|
247
|
+
ye: null,
|
|
248
|
+
Le: null,
|
|
249
|
+
Ge: n,
|
|
250
250
|
dispose: disposeRootSelf
|
|
251
251
|
};
|
|
252
252
|
if (n) {
|
|
253
|
-
const e = n.
|
|
253
|
+
const e = n.me;
|
|
254
254
|
if (e === null) {
|
|
255
|
-
n.
|
|
255
|
+
n.me = i;
|
|
256
256
|
} else {
|
|
257
|
-
i.
|
|
258
|
-
e.
|
|
259
|
-
n.
|
|
257
|
+
i.ve = e;
|
|
258
|
+
e.st = i;
|
|
259
|
+
n.me = i;
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
return i;
|