@solidjs/signals 2.0.0-rc.2 → 2.0.0-rc.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-shared.js +6505 -0
- package/dist/dev.attribution.js +3484 -0
- package/dist/dev.js +10227 -9508
- package/dist/observe/affects-marks.js +86 -0
- package/dist/observe/affects.js +112 -0
- package/dist/observe/attribution.js +7 -0
- package/dist/observe/boundaries.js +696 -0
- package/dist/observe/core/action.js +182 -0
- package/dist/observe/core/async.js +824 -0
- package/dist/observe/core/attribution-costs.js +66 -0
- package/dist/observe/core/attribution-feedback.js +280 -0
- package/dist/observe/core/attribution-hooks.js +83 -0
- package/dist/observe/core/attribution-queries.js +43 -0
- package/dist/observe/core/attribution.js +3079 -0
- package/dist/observe/core/constants.js +269 -0
- package/dist/observe/core/context.js +63 -0
- package/dist/observe/core/copies.js +10 -0
- package/dist/observe/core/core.js +1707 -0
- package/dist/observe/core/dev.js +394 -0
- package/dist/observe/core/effect.js +193 -0
- package/dist/observe/core/error-hooks.js +71 -0
- package/dist/observe/core/error.js +82 -0
- package/dist/observe/core/external.js +97 -0
- package/dist/observe/core/graph.js +162 -0
- package/dist/observe/core/heap.js +124 -0
- package/dist/observe/core/identities.js +62 -0
- package/dist/observe/core/invariants.js +12 -0
- package/dist/observe/core/lanes.js +972 -0
- package/dist/observe/core/owner.js +371 -0
- package/dist/observe/core/scheduler.js +1157 -0
- package/dist/observe/core/truth.js +47 -0
- package/dist/observe/core/verdict.js +470 -0
- package/dist/observe/deferred.js +186 -0
- package/dist/observe/flatten.js +79 -0
- package/dist/observe/from.js +248 -0
- package/dist/observe/index.js +71 -0
- package/dist/observe/map.js +593 -0
- package/dist/observe/reveal.js +212 -0
- package/dist/observe/signals.js +717 -0
- package/dist/observe/store/affects.js +142 -0
- package/dist/observe/store/edges.js +39 -0
- package/dist/observe/store/hooks.js +16 -0
- package/dist/observe/store/index.js +47 -0
- package/dist/observe/store/optimistic.js +713 -0
- package/dist/observe/store/projection.js +345 -0
- package/dist/observe/store/reconcile.js +281 -0
- package/dist/observe/store/store.js +2127 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/target.js +46 -0
- package/dist/observe/store/types.js +83 -0
- package/dist/observe/store/utils.js +1063 -0
- package/dist/prod/affects-marks.js +86 -0
- package/dist/prod/affects.js +98 -112
- package/dist/prod/attribution.js +45 -0
- package/dist/prod/boundaries.js +578 -468
- package/dist/prod/core/action.js +92 -59
- package/dist/prod/core/async.js +522 -336
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +168 -44
- package/dist/prod/core/context.js +12 -16
- package/dist/prod/core/copies.js +10 -0
- package/dist/prod/core/core.js +1345 -627
- package/dist/prod/core/dev.js +123 -1
- package/dist/prod/core/effect.js +113 -80
- package/dist/prod/core/error-hooks.js +71 -0
- package/dist/prod/core/error.js +18 -4
- package/dist/prod/core/external.js +6 -7
- package/dist/prod/core/graph.js +119 -72
- package/dist/prod/core/heap.js +85 -109
- package/dist/prod/core/identities.js +62 -0
- package/dist/prod/core/invariants.js +1 -32
- package/dist/prod/core/lanes.js +931 -132
- package/dist/prod/core/owner.js +192 -129
- package/dist/prod/core/scheduler.js +948 -642
- package/dist/prod/core/truth.js +47 -0
- package/dist/prod/core/verdict.js +409 -420
- package/dist/prod/deferred.js +184 -0
- package/dist/prod/flatten.js +77 -0
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +40 -16
- package/dist/prod/map.js +481 -211
- package/dist/prod/reveal.js +212 -0
- package/dist/prod/signals.js +401 -84
- package/dist/prod/store/affects.js +142 -0
- package/dist/prod/store/edges.js +39 -0
- package/dist/prod/store/hooks.js +16 -0
- package/dist/prod/store/index.js +27 -18
- package/dist/prod/store/optimistic.js +707 -0
- package/dist/prod/store/projection.js +331 -0
- package/dist/prod/store/reconcile.js +281 -0
- package/dist/prod/store/store.js +1952 -267
- package/dist/prod/store/storePath.js +1 -1
- package/dist/prod/store/target.js +43 -0
- package/dist/prod/store/types.js +83 -0
- package/dist/prod/store/utils.js +997 -138
- package/dist/types/affects-marks.d.ts +14 -0
- package/dist/types/affects.d.ts +12 -30
- package/dist/types/attribution.d.ts +19 -0
- package/dist/types/attribution.prod.d.ts +22 -0
- package/dist/types/boundaries.d.ts +99 -124
- package/dist/types/carved.d.ts +1 -0
- package/dist/types/core/action.d.ts +23 -9
- package/dist/types/core/async.d.ts +34 -6
- package/dist/types/core/attribution-costs.d.ts +35 -0
- package/dist/types/core/attribution-feedback.d.ts +133 -0
- package/dist/types/core/attribution-hooks.d.ts +307 -8
- package/dist/types/core/attribution-queries.d.ts +24 -0
- package/dist/types/core/attribution.d.ts +802 -72
- package/dist/types/core/constants.d.ts +195 -38
- package/dist/types/core/copies.d.ts +54 -0
- package/dist/types/core/core.d.ts +295 -65
- package/dist/types/core/dev.d.ts +509 -22
- package/dist/types/core/effect.d.ts +1 -1
- package/dist/types/core/error-hooks.d.ts +71 -0
- package/dist/types/core/error.d.ts +18 -1
- package/dist/types/core/graph.d.ts +40 -1
- package/dist/types/core/heap.d.ts +5 -5
- package/dist/types/core/identities.d.ts +17 -0
- package/dist/types/core/index.d.ts +11 -7
- package/dist/types/core/invariants.d.ts +1 -26
- package/dist/types/core/lanes.d.ts +74 -43
- package/dist/types/core/owner.d.ts +27 -9
- package/dist/types/core/scheduler.d.ts +353 -102
- package/dist/types/core/truth.d.ts +18 -0
- package/dist/types/core/types.d.ts +97 -71
- package/dist/types/core/verdict.d.ts +35 -0
- package/dist/types/deferred.d.ts +28 -0
- package/dist/types/flatten.d.ts +8 -0
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +33 -7
- package/dist/types/map.d.ts +4 -2
- package/dist/types/reveal.d.ts +19 -0
- package/dist/types/signals.d.ts +196 -45
- package/dist/types/store/affects.d.ts +12 -0
- package/dist/types/store/edges.d.ts +9 -0
- package/dist/types/store/hooks.d.ts +62 -0
- package/dist/types/store/index.d.ts +42 -15
- package/dist/types/store/optimistic.d.ts +24 -45
- package/dist/types/store/projection.d.ts +17 -68
- package/dist/types/store/reconcile.d.ts +3 -46
- package/dist/types/store/store.d.ts +133 -136
- package/dist/types/store/storePath.d.ts +1 -1
- package/dist/types/store/target.d.ts +166 -0
- package/dist/types/store/types.d.ts +105 -0
- package/dist/types/store/utils.d.ts +188 -0
- package/package.json +31 -26
- package/dist/node.cjs +0 -8745
- package/dist/prod/core/optimistic.js +0 -265
- package/dist/prod/store/next/optimistic.js +0 -385
- package/dist/prod/store/next/projection.js +0 -172
- package/dist/prod/store/next/reconcile.js +0 -331
- package/dist/prod/store/next/store.js +0 -1499
- package/dist/prod/store/next/target.js +0 -20
- package/dist/types/core/optimistic.d.ts +0 -6
- package/dist/types/store/next/optimistic.d.ts +0 -20
- package/dist/types/store/next/projection.d.ts +0 -8
- package/dist/types/store/next/reconcile.d.ts +0 -3
- package/dist/types/store/next/store.d.ts +0 -77
- package/dist/types/store/next/target.d.ts +0 -117
- package/dist/types-cjs/affects.d.cts +0 -47
- package/dist/types-cjs/boundaries.d.cts +0 -175
- package/dist/types-cjs/core/action.d.cts +0 -64
- package/dist/types-cjs/core/async.d.cts +0 -21
- package/dist/types-cjs/core/attribution-hooks.d.cts +0 -52
- package/dist/types-cjs/core/attribution.d.cts +0 -186
- package/dist/types-cjs/core/constants.d.cts +0 -97
- package/dist/types-cjs/core/context.d.cts +0 -36
- package/dist/types-cjs/core/core.d.cts +0 -163
- package/dist/types-cjs/core/dev.d.cts +0 -81
- package/dist/types-cjs/core/effect.d.cts +0 -30
- package/dist/types-cjs/core/error.d.cts +0 -47
- package/dist/types-cjs/core/external.d.cts +0 -15
- package/dist/types-cjs/core/graph.d.cts +0 -6
- package/dist/types-cjs/core/heap.d.cts +0 -22
- package/dist/types-cjs/core/index.d.cts +0 -13
- package/dist/types-cjs/core/invariants.d.cts +0 -59
- package/dist/types-cjs/core/lanes.d.cts +0 -44
- package/dist/types-cjs/core/optimistic.d.cts +0 -6
- package/dist/types-cjs/core/owner.d.cts +0 -124
- package/dist/types-cjs/core/scheduler.d.cts +0 -180
- package/dist/types-cjs/core/types.d.cts +0 -192
- package/dist/types-cjs/core/verdict.d.cts +0 -2
- package/dist/types-cjs/index.d.cts +0 -10
- package/dist/types-cjs/map.d.cts +0 -69
- package/dist/types-cjs/package.json +0 -3
- package/dist/types-cjs/signals.d.cts +0 -624
- package/dist/types-cjs/store/index.d.cts +0 -19
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
- package/dist/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
- package/dist/types-cjs/store/next/store.d.cts +0 -77
- package/dist/types-cjs/store/next/target.d.cts +0 -117
- package/dist/types-cjs/store/optimistic.d.cts +0 -45
- package/dist/types-cjs/store/projection.d.cts +0 -70
- package/dist/types-cjs/store/reconcile.d.cts +0 -46
- package/dist/types-cjs/store/store.d.cts +0 -138
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -74
package/dist/prod/core/owner.js
CHANGED
|
@@ -1,32 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defaultContext, CONFIG_TRANSPARENT, REACTIVE_NONE, REACTIVE_DISPOSED, CONFIG_AUTO_DISPOSE, STATUS_PENDING, REACTIVE_FRAME_READ, REACTIVE_ZOMBIE } from "./constants.js";
|
|
2
2
|
|
|
3
|
-
import { context, runWithOwner,
|
|
3
|
+
import { context, runWithOwner, tracking } from "./core.js";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { unobserved, clearDeps } from "./graph.js";
|
|
6
6
|
|
|
7
|
-
import { deleteFromHeap
|
|
7
|
+
import { deleteFromHeap } from "./heap.js";
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { globalQueue, pendingNodes, schedule, dirtyQueue } from "./scheduler.js";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
// L2 (step 2): the parked frame. A pass parks the previous frame's children
|
|
12
|
+
// and `_disposal` list on `_x._pendingFirstChild` / `_x._pendingDisposal`
|
|
13
|
+
// (`parkChildren`, core.ts); they keep reacting until the node's commit
|
|
14
|
+
// disposes them (`zombie` walk below) or the owner dies. `markDisposal` flags
|
|
15
|
+
// the parked subtree REACTIVE_ZOMBIE: the splice guard and the reawaken path
|
|
16
|
+
// key off it, and the heap defers a zombie's recompute past the seam (no
|
|
17
|
+
// second heap — the deferral list in scheduler.ts).
|
|
14
18
|
function markDisposal(e) {
|
|
15
|
-
let
|
|
16
|
-
while (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// `deleteFromHeap` call site picks the queue from the zombie flag, so a
|
|
21
|
-
// node left physically linked in `dirtyQueue` after being zombified gets
|
|
22
|
-
// unlinked from the wrong queue on dispose, corrupting the bucket and
|
|
23
|
-
// livelocking the next `runHeap` that reaches it (#2759)
|
|
24
|
-
if (e & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT)) {
|
|
25
|
-
deleteFromHeap(t, e & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
|
|
26
|
-
if (e & REACTIVE_IN_HEAP) insertIntoHeap(t, zombieQueue); else insertIntoHeapHeight(t, zombieQueue);
|
|
27
|
-
}
|
|
28
|
-
markDisposal(t);
|
|
29
|
-
t = t.Ve;
|
|
19
|
+
let n = e.pe;
|
|
20
|
+
while (n) {
|
|
21
|
+
n.R |= REACTIVE_ZOMBIE;
|
|
22
|
+
markDisposal(n);
|
|
23
|
+
n = n.Ge;
|
|
30
24
|
}
|
|
31
25
|
}
|
|
32
26
|
|
|
@@ -37,28 +31,59 @@ function dispose(e) {
|
|
|
37
31
|
// left queued would be recomputed and resurrected by the next flush (#2983)
|
|
38
32
|
// — dep unlinking, child disposal) is exactly unobserved()'s body; only
|
|
39
33
|
// this flag distinguishes death from dormancy.
|
|
40
|
-
e.
|
|
34
|
+
e.l &= ~CONFIG_AUTO_DISPOSE;
|
|
41
35
|
unobserved(e);
|
|
42
36
|
}
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
38
|
+
// The first error a cleanup threw, boxed so a thrown `undefined` still
|
|
39
|
+
// counts. A throwing cleanup stops neither its siblings nor the rest of the
|
|
40
|
+
// tree: every cleanup runs. The error is rethrown once the teardown is over:
|
|
41
|
+
// by a root's dispose call outside a flush (`disposeRootSelf`), otherwise when
|
|
42
|
+
// the flush ends (`flush`; `runCleanup` schedules one), so a flush is never
|
|
43
|
+
// left half-applied. A halt drops it: the error that halted is the one
|
|
44
|
+
// reported, and a stale one must not surface from a later, unrelated dispose.
|
|
45
|
+
let cleanupError;
|
|
46
|
+
|
|
47
|
+
/** Runs a cleanup or `unobserved` hook; a throw is collected, not raised. @internal */ function runCleanup(e) {
|
|
48
|
+
try {
|
|
49
|
+
e();
|
|
50
|
+
} catch (e) {
|
|
51
|
+
cleanupError ||= [ e ];
|
|
52
|
+
schedule();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Rethrows the error `runCleanup` collected, once; `drop` discards it. @internal */ function rethrowCleanupError(e) {
|
|
57
|
+
const n = cleanupError;
|
|
58
|
+
cleanupError = undefined;
|
|
59
|
+
if (n && !e) throw n[0];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function disposeChildren(e, n = false, r) {
|
|
63
|
+
const t = e.R;
|
|
64
|
+
if (t & REACTIVE_DISPOSED) return;
|
|
65
|
+
// A parked frame dies with its owner (#3024): the commit that would retire
|
|
66
|
+
// it never comes once the node is DISPOSED, so it drains here or its
|
|
67
|
+
// cleanups never run and it stays subscribed, rerunning in a torn-down
|
|
68
|
+
// tree (#3561). Death only (`self`): a re-pass leaves the frame reacting
|
|
69
|
+
// until the commit.
|
|
70
|
+
if (n && !r && e.T !== null && (e.T.me !== null || e.T.Le !== null)) disposeChildren(e, false, true);
|
|
71
|
+
if (n) {
|
|
72
|
+
e.R = t | REACTIVE_DISPOSED;
|
|
73
|
+
}
|
|
74
|
+
if (n && e.X) {
|
|
75
|
+
if (e.T !== null) e.T.Ee = null;
|
|
76
|
+
// A death that can unblock the future (L2, `futureBlocked`): a held
|
|
77
|
+
// flight's — a transaction's or a lane's (its `_x._transaction`) — or a
|
|
78
|
+
// stale reader's (REACTIVE_FRAME_READ — a frame that derived from one).
|
|
79
|
+
// An idle pending queue would also pin it until an unrelated flush.
|
|
80
|
+
// Nothing else re-examines a dead node, so make sure a seam comes.
|
|
81
|
+
if (e.m & STATUS_PENDING && e.T?.Re != null || t & REACTIVE_FRAME_READ || pendingNodes.length) schedule();
|
|
56
82
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
while (
|
|
60
|
-
const e =
|
|
61
|
-
const t = o;
|
|
83
|
+
let l = r ? e.T.me : e.pe;
|
|
84
|
+
if (r) e.T.me = null; else e.pe = null;
|
|
85
|
+
while (l) {
|
|
86
|
+
const e = l;
|
|
62
87
|
// Owner teardown is death regardless of the child's own lifecycle
|
|
63
88
|
// (#3024): strip AUTO_DISPOSE so a post-disposal read freezes at the
|
|
64
89
|
// last committed value instead of reawakening in a torn-down tree.
|
|
@@ -66,7 +91,7 @@ function disposeChildren(e, t = false, n) {
|
|
|
66
91
|
// disposeChildren call early-returns on REACTIVE_DISPOSED) die too.
|
|
67
92
|
// Only unobserved()'s own node keeps its dormancy — it is never in
|
|
68
93
|
// this loop; its children are rebuilt fresh on reawaken.
|
|
69
|
-
|
|
94
|
+
e.l &= ~CONFIG_AUTO_DISPOSE;
|
|
70
95
|
// Heap removal must not be gated on `_deps`: a dependency-free
|
|
71
96
|
// computation queued by refresh() has a null dep list but still sits in
|
|
72
97
|
// the dirty heap, and left there the post-disposal flush recomputes it —
|
|
@@ -74,58 +99,78 @@ function disposeChildren(e, t = false, n) {
|
|
|
74
99
|
// comes back to life (post-unmount runs, leaked cleanups, #2983).
|
|
75
100
|
// deleteFromHeap self-guards on the in-heap flags (and tolerates plain
|
|
76
101
|
// Owners, whose _flags is undefined), so no gate here.
|
|
77
|
-
deleteFromHeap(
|
|
78
|
-
clearDeps(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
102
|
+
deleteFromHeap(e, dirtyQueue);
|
|
103
|
+
clearDeps(e);
|
|
104
|
+
// The chain is detached above so a node a cleanup links mid-drain lands
|
|
105
|
+
// on the fresh head and survives. Pointing each drained child's prev at
|
|
106
|
+
// itself routes its later splice onto the detached chain, never the head,
|
|
107
|
+
// and keeps the dev owner-chain-head invariant honest for those children.
|
|
108
|
+
l.we = l;
|
|
109
|
+
disposeChildren(l, true);
|
|
110
|
+
// Read after, not before: a sibling this disposal made dormant spliced
|
|
111
|
+
// itself out of the detached chain, and a cleanup may then have linked
|
|
112
|
+
// it at the fresh head, which rewrote the `_nextSibling` a pre-read
|
|
113
|
+
// would still be holding.
|
|
114
|
+
l = l.Ge;
|
|
87
115
|
}
|
|
116
|
+
if (!r) e.be = 0;
|
|
88
117
|
// O(1) splice out of parent's chain on individual dispose. Skipped during
|
|
89
|
-
// batch dispose (parent already disposed) and zombie
|
|
90
|
-
// parent's
|
|
91
|
-
// walks that already advanced past us
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const n = e.
|
|
95
|
-
|
|
96
|
-
if (n !== null) n.
|
|
97
|
-
|
|
118
|
+
// batch dispose (parent already disposed) and for a zombie (it sits on the
|
|
119
|
+
// parent's parked frame, drained whole by the commit). We leave
|
|
120
|
+
// node._nextSibling intact so outer walks that already advanced past us
|
|
121
|
+
// still reach later siblings.
|
|
122
|
+
if (n && !r && !(t & REACTIVE_ZOMBIE) && e._parent !== null && !(e._parent.R & REACTIVE_DISPOSED)) {
|
|
123
|
+
const n = e.we;
|
|
124
|
+
const r = e.Ge;
|
|
125
|
+
if (n !== null) n.Ge = r; else e._parent.pe = r;
|
|
126
|
+
if (r !== null) r.we = n;
|
|
127
|
+
e.we = null;
|
|
98
128
|
}
|
|
99
|
-
runDisposal(e,
|
|
129
|
+
runDisposal(e, r);
|
|
100
130
|
// Final effect-returned cleanup fires at true disposal, after `_disposal`
|
|
101
131
|
// to mirror rerun ordering (compute-phase teardown first, cleanup last).
|
|
102
|
-
if (
|
|
103
|
-
const
|
|
104
|
-
e.
|
|
105
|
-
|
|
132
|
+
if (n && e.ze) {
|
|
133
|
+
const n = e.ze;
|
|
134
|
+
e.ze = undefined;
|
|
135
|
+
runCleanup(n);
|
|
106
136
|
}
|
|
107
137
|
}
|
|
108
138
|
|
|
109
|
-
function
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
139
|
+
function linkChild(e, n) {
|
|
140
|
+
const r = e.pe;
|
|
141
|
+
n.we = null;
|
|
142
|
+
n.Ge = r;
|
|
143
|
+
if (r !== null) r.we = n;
|
|
144
|
+
e.pe = n;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function runDisposal(e, n) {
|
|
148
|
+
// Detach the list BEFORE running it (#3601), as `_cleanup` is (#2813). A
|
|
149
|
+
// cleanup that disposes an ancestor re-enters this node through the death
|
|
150
|
+
// walk while the loop is still running; with the list still attached, that
|
|
151
|
+
// walk ran every entry a second time. Detached, the re-entrant drain finds
|
|
152
|
+
// nothing. The same shape latched a throwing cleanup: the list survived the
|
|
153
|
+
// throw and every later drain re-ran and re-threw it.
|
|
154
|
+
const r = n ? e.T.Le : e.ke;
|
|
155
|
+
if (!r) return;
|
|
156
|
+
if (n) e.T.Le = null; else e.ke = null;
|
|
157
|
+
if (Array.isArray(r)) {
|
|
158
|
+
// Unwind order (#3572, restores 1.x #1562): later registrations run
|
|
159
|
+
// before earlier ones. Children have already been disposed by the caller,
|
|
160
|
+
// so with LIFO a body that registers cleanup before creating its children
|
|
161
|
+
// tears down after them — the same order a per-component owner gives.
|
|
162
|
+
for (let e = r.length - 1; e >= 0; e--) {
|
|
163
|
+
runCleanup(r[e]);
|
|
116
164
|
}
|
|
117
165
|
} else {
|
|
118
|
-
|
|
166
|
+
runCleanup(r);
|
|
119
167
|
}
|
|
120
|
-
if (t) {
|
|
121
|
-
if (e.o !== null) e.o.We = null;
|
|
122
|
-
} else e.he = null;
|
|
123
168
|
}
|
|
124
169
|
|
|
125
|
-
function childId(e,
|
|
126
|
-
let
|
|
127
|
-
while (
|
|
128
|
-
if (
|
|
170
|
+
function childId(e, n) {
|
|
171
|
+
let r = e;
|
|
172
|
+
while (r.l & CONFIG_TRANSPARENT && r._parent) r = r._parent;
|
|
173
|
+
if (r.id != null) return formatId(r.id, n ? r.be++ : r.be);
|
|
129
174
|
throw new Error("");
|
|
130
175
|
}
|
|
131
176
|
|
|
@@ -142,8 +187,8 @@ function childId(e, t) {
|
|
|
142
187
|
* The id a freshly-created node inherits: an explicit `options.id` wins;
|
|
143
188
|
* transparent nodes share their parent's id; otherwise the parent's next
|
|
144
189
|
* child id is consumed (or `undefined` outside an id-carrying tree).
|
|
145
|
-
*/ function inheritId(e,
|
|
146
|
-
return e?.id ?? (
|
|
190
|
+
*/ function inheritId(e, n, r) {
|
|
191
|
+
return e?.id ?? (n ? r?.id : r?.id != null ? getNextChildId(r) : undefined);
|
|
147
192
|
}
|
|
148
193
|
|
|
149
194
|
/**
|
|
@@ -155,9 +200,9 @@ function childId(e, t) {
|
|
|
155
200
|
return childId(e, false);
|
|
156
201
|
}
|
|
157
202
|
|
|
158
|
-
function formatId(e,
|
|
159
|
-
const
|
|
160
|
-
return e + (
|
|
203
|
+
function formatId(e, n) {
|
|
204
|
+
const r = n.toString(36), t = r.length - 1;
|
|
205
|
+
return e + (t ? String.fromCharCode(64 + t) : "") + r;
|
|
161
206
|
}
|
|
162
207
|
|
|
163
208
|
/**
|
|
@@ -176,7 +221,6 @@ function formatId(e, t) {
|
|
|
176
221
|
* }
|
|
177
222
|
* ```
|
|
178
223
|
*/ function getObserver() {
|
|
179
|
-
if (pendingCheckActive || latestReadActive) return PENDING_OWNER;
|
|
180
224
|
return tracking ? context : null;
|
|
181
225
|
}
|
|
182
226
|
|
|
@@ -203,17 +247,19 @@ function formatId(e, t) {
|
|
|
203
247
|
/**
|
|
204
248
|
* Low-level: registers `fn` as a disposal callback on the current owner.
|
|
205
249
|
* Most code should use `onCleanup()` from `solid-js`, which adds dev-mode
|
|
206
|
-
* checks. `cleanup()` is the unchecked primitive used by internals
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
250
|
+
* checks. `cleanup()` is the unchecked primitive used by internals; `owner`
|
|
251
|
+
* (internal) targets a specific owner's disposal list instead of the ambient
|
|
252
|
+
* one.
|
|
253
|
+
*/ function cleanup(e, n = context) {
|
|
254
|
+
if (!n) return e;
|
|
255
|
+
if (!n.ke) n.ke = e; else if (Array.isArray(n.ke)) n.ke.push(e); else n.ke = [ n.ke, e ];
|
|
210
256
|
return e;
|
|
211
257
|
}
|
|
212
258
|
|
|
213
259
|
/**
|
|
214
|
-
* Returns `true` if the owner has been disposed
|
|
215
|
-
*
|
|
216
|
-
*
|
|
260
|
+
* Returns `true` if the owner has been disposed. Pair with a captured owner
|
|
261
|
+
* to bail out of late callbacks whose surrounding component already
|
|
262
|
+
* unmounted.
|
|
217
263
|
*
|
|
218
264
|
* @example
|
|
219
265
|
* ```ts
|
|
@@ -226,11 +272,14 @@ function formatId(e, t) {
|
|
|
226
272
|
* }
|
|
227
273
|
* ```
|
|
228
274
|
*/ function isDisposed(e) {
|
|
229
|
-
return !!(e.
|
|
275
|
+
return !!(e.R & REACTIVE_DISPOSED);
|
|
230
276
|
}
|
|
231
277
|
|
|
232
278
|
function disposeRootSelf(e = true) {
|
|
233
279
|
disposeChildren(this, e);
|
|
280
|
+
// Outside a flush the dispose call rethrows; inside one, the flush does.
|
|
281
|
+
// Kept out of `disposeChildren`, whose hot path it slows.
|
|
282
|
+
if (cleanupError && !globalQueue.Y) rethrowCleanupError();
|
|
234
283
|
}
|
|
235
284
|
|
|
236
285
|
/**
|
|
@@ -241,41 +290,47 @@ function disposeRootSelf(e = true) {
|
|
|
241
290
|
*
|
|
242
291
|
* @internal
|
|
243
292
|
*/ function createOwner(e) {
|
|
244
|
-
const
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
293
|
+
const n = context;
|
|
294
|
+
const r = e?.transparent ?? false;
|
|
295
|
+
// Prod and observe boilerplates (see core.ts computed()). The observe
|
|
296
|
+
// literal carries the `_name` and `_loc` slots the rendering layer fills
|
|
297
|
+
// with the component label and JSX site (`owner._name = "<App>"`,
|
|
298
|
+
// `owner._loc = "src/App.tsx:3:5"`) — slots, so labelling a root is a
|
|
299
|
+
// plain store rather than a shape fork between labelled and plain roots.
|
|
300
|
+
const t = {
|
|
301
|
+
id: inheritId(e, r, n),
|
|
302
|
+
l: r ? CONFIG_TRANSPARENT : 0,
|
|
303
|
+
// Present from birth: disposeChildren marks death here on roots too, and
|
|
304
|
+
// a first store of a missing property is a shape transition plus a
|
|
305
|
+
// properties-store allocation per root — on a 100×4 table teardown that
|
|
306
|
+
// was 12 KB and most of disposal's time (2026-10-17).
|
|
307
|
+
R: REACTIVE_NONE,
|
|
308
|
+
Qe: true,
|
|
309
|
+
Ke: n?.Qe ? n.Ke : n,
|
|
310
|
+
pe: null,
|
|
311
|
+
Ge: null,
|
|
312
|
+
we: null,
|
|
251
313
|
ke: null,
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
we: t?.we || defaultContext,
|
|
257
|
-
Me: 0,
|
|
258
|
-
o: null,
|
|
259
|
-
ve: t,
|
|
314
|
+
A: n?.A || defaultContext,
|
|
315
|
+
be: 0,
|
|
316
|
+
T: null,
|
|
317
|
+
_parent: n,
|
|
260
318
|
dispose: disposeRootSelf
|
|
261
319
|
};
|
|
262
|
-
if (t)
|
|
263
|
-
|
|
264
|
-
if (e === null) {
|
|
265
|
-
t.ke = i;
|
|
266
|
-
} else {
|
|
267
|
-
i.Ve = e;
|
|
268
|
-
e.ct = i;
|
|
269
|
-
t.ke = i;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
return i;
|
|
320
|
+
if (n) linkChild(n, t);
|
|
321
|
+
return t;
|
|
273
322
|
}
|
|
274
323
|
|
|
275
324
|
/**
|
|
276
|
-
* Creates a
|
|
277
|
-
*
|
|
278
|
-
* `
|
|
325
|
+
* Creates a reactive root — an owner scope with its own `dispose()`. A root
|
|
326
|
+
* created inside an existing owner is owned by it and is disposed when the
|
|
327
|
+
* parent is disposed; call `dispose()` to tear it down earlier. To create a
|
|
328
|
+
* root that outlives its creator, detach explicitly:
|
|
329
|
+
* `runWithOwner(null, () => createRoot(...))`. Pass `id` to seed hydration
|
|
330
|
+
* ids for the tree it owns.
|
|
331
|
+
*
|
|
332
|
+
* `dispose()` tears down every signal, memo, effect, and `onCleanup`
|
|
333
|
+
* registered inside the root.
|
|
279
334
|
*
|
|
280
335
|
* Use this to host long-lived reactive scopes outside of a component (custom
|
|
281
336
|
* controllers, app bootstrapping, tests). Inside a component, prefer
|
|
@@ -283,6 +338,7 @@ function disposeRootSelf(e = true) {
|
|
|
283
338
|
*
|
|
284
339
|
* @example
|
|
285
340
|
* ```ts
|
|
341
|
+
* // At module level there is no owner, so this root lives until disposed.
|
|
286
342
|
* const dispose = createRoot(dispose => {
|
|
287
343
|
* const [n, setN] = createSignal(0);
|
|
288
344
|
* createEffect(() => n(), value => console.log(value));
|
|
@@ -292,12 +348,19 @@ function disposeRootSelf(e = true) {
|
|
|
292
348
|
*
|
|
293
349
|
* // Later, to tear everything down:
|
|
294
350
|
* dispose();
|
|
351
|
+
*
|
|
352
|
+
* // Inside an owner (component, effect, another root), detach explicitly
|
|
353
|
+
* // if the root must outlive its creator:
|
|
354
|
+
* const detached = runWithOwner(null, () => createRoot(d => d));
|
|
295
355
|
* ```
|
|
296
356
|
*
|
|
297
|
-
* @description https://
|
|
298
|
-
*/ function createRoot(e,
|
|
299
|
-
const
|
|
300
|
-
|
|
357
|
+
* @description https://v2.solidjs.com/reference/solid-js/advanced/owner-introspection/create-root
|
|
358
|
+
*/ function createRoot(e, n) {
|
|
359
|
+
const r = createOwner(n);
|
|
360
|
+
// A bound function, not an arrow: an arrow would share this scope, which
|
|
361
|
+
// holds `init`, so keeping `dispose` would keep `init` and all it closes
|
|
362
|
+
// over alive (#4095).
|
|
363
|
+
return runWithOwner(r, () => e(disposeRootSelf.bind(r, true)));
|
|
301
364
|
}
|
|
302
365
|
|
|
303
|
-
export { cleanup, createOwner, createRoot, dispose, disposeChildren, getNextChildId, getObserver, getOwner, inheritId, isDisposed, markDisposal, peekNextChildId };
|
|
366
|
+
export { cleanup, createOwner, createRoot, dispose, disposeChildren, getNextChildId, getObserver, getOwner, inheritId, isDisposed, linkChild, markDisposal, peekNextChildId, rethrowCleanupError, runCleanup };
|