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