@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.
Files changed (198) hide show
  1. package/dist/dev-shared.js +6505 -0
  2. package/dist/dev.attribution.js +3484 -0
  3. package/dist/dev.js +10227 -9508
  4. package/dist/observe/affects-marks.js +86 -0
  5. package/dist/observe/affects.js +112 -0
  6. package/dist/observe/attribution.js +7 -0
  7. package/dist/observe/boundaries.js +696 -0
  8. package/dist/observe/core/action.js +182 -0
  9. package/dist/observe/core/async.js +824 -0
  10. package/dist/observe/core/attribution-costs.js +66 -0
  11. package/dist/observe/core/attribution-feedback.js +280 -0
  12. package/dist/observe/core/attribution-hooks.js +83 -0
  13. package/dist/observe/core/attribution-queries.js +43 -0
  14. package/dist/observe/core/attribution.js +3079 -0
  15. package/dist/observe/core/constants.js +269 -0
  16. package/dist/observe/core/context.js +63 -0
  17. package/dist/observe/core/copies.js +10 -0
  18. package/dist/observe/core/core.js +1707 -0
  19. package/dist/observe/core/dev.js +394 -0
  20. package/dist/observe/core/effect.js +193 -0
  21. package/dist/observe/core/error-hooks.js +71 -0
  22. package/dist/observe/core/error.js +82 -0
  23. package/dist/observe/core/external.js +97 -0
  24. package/dist/observe/core/graph.js +162 -0
  25. package/dist/observe/core/heap.js +124 -0
  26. package/dist/observe/core/identities.js +62 -0
  27. package/dist/observe/core/invariants.js +12 -0
  28. package/dist/observe/core/lanes.js +972 -0
  29. package/dist/observe/core/owner.js +371 -0
  30. package/dist/observe/core/scheduler.js +1157 -0
  31. package/dist/observe/core/truth.js +47 -0
  32. package/dist/observe/core/verdict.js +470 -0
  33. package/dist/observe/deferred.js +186 -0
  34. package/dist/observe/flatten.js +79 -0
  35. package/dist/observe/from.js +248 -0
  36. package/dist/observe/index.js +71 -0
  37. package/dist/observe/map.js +593 -0
  38. package/dist/observe/reveal.js +212 -0
  39. package/dist/observe/signals.js +717 -0
  40. package/dist/observe/store/affects.js +142 -0
  41. package/dist/observe/store/edges.js +39 -0
  42. package/dist/observe/store/hooks.js +16 -0
  43. package/dist/observe/store/index.js +47 -0
  44. package/dist/observe/store/optimistic.js +713 -0
  45. package/dist/observe/store/projection.js +345 -0
  46. package/dist/observe/store/reconcile.js +281 -0
  47. package/dist/observe/store/store.js +2127 -0
  48. package/dist/observe/store/storePath.js +103 -0
  49. package/dist/observe/store/target.js +46 -0
  50. package/dist/observe/store/types.js +83 -0
  51. package/dist/observe/store/utils.js +1063 -0
  52. package/dist/prod/affects-marks.js +86 -0
  53. package/dist/prod/affects.js +98 -112
  54. package/dist/prod/attribution.js +45 -0
  55. package/dist/prod/boundaries.js +578 -468
  56. package/dist/prod/core/action.js +92 -59
  57. package/dist/prod/core/async.js +522 -336
  58. package/dist/prod/core/attribution-hooks.js +3 -0
  59. package/dist/prod/core/constants.js +168 -44
  60. package/dist/prod/core/context.js +12 -16
  61. package/dist/prod/core/copies.js +10 -0
  62. package/dist/prod/core/core.js +1345 -627
  63. package/dist/prod/core/dev.js +123 -1
  64. package/dist/prod/core/effect.js +113 -80
  65. package/dist/prod/core/error-hooks.js +71 -0
  66. package/dist/prod/core/error.js +18 -4
  67. package/dist/prod/core/external.js +6 -7
  68. package/dist/prod/core/graph.js +119 -72
  69. package/dist/prod/core/heap.js +85 -109
  70. package/dist/prod/core/identities.js +62 -0
  71. package/dist/prod/core/invariants.js +1 -32
  72. package/dist/prod/core/lanes.js +931 -132
  73. package/dist/prod/core/owner.js +192 -129
  74. package/dist/prod/core/scheduler.js +948 -642
  75. package/dist/prod/core/truth.js +47 -0
  76. package/dist/prod/core/verdict.js +409 -420
  77. package/dist/prod/deferred.js +184 -0
  78. package/dist/prod/flatten.js +77 -0
  79. package/dist/prod/from.js +248 -0
  80. package/dist/prod/index.js +40 -16
  81. package/dist/prod/map.js +481 -211
  82. package/dist/prod/reveal.js +212 -0
  83. package/dist/prod/signals.js +401 -84
  84. package/dist/prod/store/affects.js +142 -0
  85. package/dist/prod/store/edges.js +39 -0
  86. package/dist/prod/store/hooks.js +16 -0
  87. package/dist/prod/store/index.js +27 -18
  88. package/dist/prod/store/optimistic.js +707 -0
  89. package/dist/prod/store/projection.js +331 -0
  90. package/dist/prod/store/reconcile.js +281 -0
  91. package/dist/prod/store/store.js +1952 -267
  92. package/dist/prod/store/storePath.js +1 -1
  93. package/dist/prod/store/target.js +43 -0
  94. package/dist/prod/store/types.js +83 -0
  95. package/dist/prod/store/utils.js +997 -138
  96. package/dist/types/affects-marks.d.ts +14 -0
  97. package/dist/types/affects.d.ts +12 -30
  98. package/dist/types/attribution.d.ts +19 -0
  99. package/dist/types/attribution.prod.d.ts +22 -0
  100. package/dist/types/boundaries.d.ts +99 -124
  101. package/dist/types/carved.d.ts +1 -0
  102. package/dist/types/core/action.d.ts +23 -9
  103. package/dist/types/core/async.d.ts +34 -6
  104. package/dist/types/core/attribution-costs.d.ts +35 -0
  105. package/dist/types/core/attribution-feedback.d.ts +133 -0
  106. package/dist/types/core/attribution-hooks.d.ts +307 -8
  107. package/dist/types/core/attribution-queries.d.ts +24 -0
  108. package/dist/types/core/attribution.d.ts +802 -72
  109. package/dist/types/core/constants.d.ts +195 -38
  110. package/dist/types/core/copies.d.ts +54 -0
  111. package/dist/types/core/core.d.ts +295 -65
  112. package/dist/types/core/dev.d.ts +509 -22
  113. package/dist/types/core/effect.d.ts +1 -1
  114. package/dist/types/core/error-hooks.d.ts +71 -0
  115. package/dist/types/core/error.d.ts +18 -1
  116. package/dist/types/core/graph.d.ts +40 -1
  117. package/dist/types/core/heap.d.ts +5 -5
  118. package/dist/types/core/identities.d.ts +17 -0
  119. package/dist/types/core/index.d.ts +11 -7
  120. package/dist/types/core/invariants.d.ts +1 -26
  121. package/dist/types/core/lanes.d.ts +74 -43
  122. package/dist/types/core/owner.d.ts +27 -9
  123. package/dist/types/core/scheduler.d.ts +353 -102
  124. package/dist/types/core/truth.d.ts +18 -0
  125. package/dist/types/core/types.d.ts +97 -71
  126. package/dist/types/core/verdict.d.ts +35 -0
  127. package/dist/types/deferred.d.ts +28 -0
  128. package/dist/types/flatten.d.ts +8 -0
  129. package/dist/types/from.d.ts +47 -0
  130. package/dist/types/index.d.ts +33 -7
  131. package/dist/types/map.d.ts +4 -2
  132. package/dist/types/reveal.d.ts +19 -0
  133. package/dist/types/signals.d.ts +196 -45
  134. package/dist/types/store/affects.d.ts +12 -0
  135. package/dist/types/store/edges.d.ts +9 -0
  136. package/dist/types/store/hooks.d.ts +62 -0
  137. package/dist/types/store/index.d.ts +42 -15
  138. package/dist/types/store/optimistic.d.ts +24 -45
  139. package/dist/types/store/projection.d.ts +17 -68
  140. package/dist/types/store/reconcile.d.ts +3 -46
  141. package/dist/types/store/store.d.ts +133 -136
  142. package/dist/types/store/storePath.d.ts +1 -1
  143. package/dist/types/store/target.d.ts +166 -0
  144. package/dist/types/store/types.d.ts +105 -0
  145. package/dist/types/store/utils.d.ts +188 -0
  146. package/package.json +31 -26
  147. package/dist/node.cjs +0 -8745
  148. package/dist/prod/core/optimistic.js +0 -265
  149. package/dist/prod/store/next/optimistic.js +0 -385
  150. package/dist/prod/store/next/projection.js +0 -172
  151. package/dist/prod/store/next/reconcile.js +0 -331
  152. package/dist/prod/store/next/store.js +0 -1499
  153. package/dist/prod/store/next/target.js +0 -20
  154. package/dist/types/core/optimistic.d.ts +0 -6
  155. package/dist/types/store/next/optimistic.d.ts +0 -20
  156. package/dist/types/store/next/projection.d.ts +0 -8
  157. package/dist/types/store/next/reconcile.d.ts +0 -3
  158. package/dist/types/store/next/store.d.ts +0 -77
  159. package/dist/types/store/next/target.d.ts +0 -117
  160. package/dist/types-cjs/affects.d.cts +0 -47
  161. package/dist/types-cjs/boundaries.d.cts +0 -175
  162. package/dist/types-cjs/core/action.d.cts +0 -64
  163. package/dist/types-cjs/core/async.d.cts +0 -21
  164. package/dist/types-cjs/core/attribution-hooks.d.cts +0 -52
  165. package/dist/types-cjs/core/attribution.d.cts +0 -186
  166. package/dist/types-cjs/core/constants.d.cts +0 -97
  167. package/dist/types-cjs/core/context.d.cts +0 -36
  168. package/dist/types-cjs/core/core.d.cts +0 -163
  169. package/dist/types-cjs/core/dev.d.cts +0 -81
  170. package/dist/types-cjs/core/effect.d.cts +0 -30
  171. package/dist/types-cjs/core/error.d.cts +0 -47
  172. package/dist/types-cjs/core/external.d.cts +0 -15
  173. package/dist/types-cjs/core/graph.d.cts +0 -6
  174. package/dist/types-cjs/core/heap.d.cts +0 -22
  175. package/dist/types-cjs/core/index.d.cts +0 -13
  176. package/dist/types-cjs/core/invariants.d.cts +0 -59
  177. package/dist/types-cjs/core/lanes.d.cts +0 -44
  178. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  179. package/dist/types-cjs/core/owner.d.cts +0 -124
  180. package/dist/types-cjs/core/scheduler.d.cts +0 -180
  181. package/dist/types-cjs/core/types.d.cts +0 -192
  182. package/dist/types-cjs/core/verdict.d.cts +0 -2
  183. package/dist/types-cjs/index.d.cts +0 -10
  184. package/dist/types-cjs/map.d.cts +0 -69
  185. package/dist/types-cjs/package.json +0 -3
  186. package/dist/types-cjs/signals.d.cts +0 -624
  187. package/dist/types-cjs/store/index.d.cts +0 -19
  188. package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
  189. package/dist/types-cjs/store/next/projection.d.cts +0 -8
  190. package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
  191. package/dist/types-cjs/store/next/store.d.cts +0 -77
  192. package/dist/types-cjs/store/next/target.d.cts +0 -117
  193. package/dist/types-cjs/store/optimistic.d.cts +0 -45
  194. package/dist/types-cjs/store/projection.d.cts +0 -70
  195. package/dist/types-cjs/store/reconcile.d.cts +0 -46
  196. package/dist/types-cjs/store/store.d.cts +0 -138
  197. package/dist/types-cjs/store/storePath.d.cts +0 -58
  198. 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 };