@solidjs/signals 2.0.0-rc.1 → 2.0.0-rc.10

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 (150) hide show
  1. package/dist/dev-shared.js +7138 -0
  2. package/dist/dev.attribution.js +3307 -0
  3. package/dist/dev.js +5691 -4491
  4. package/dist/observe/affects.js +129 -0
  5. package/dist/observe/attribution.js +7 -0
  6. package/dist/observe/boundaries.js +793 -0
  7. package/dist/observe/core/action.js +177 -0
  8. package/dist/observe/core/async.js +849 -0
  9. package/dist/observe/core/attribution-costs.js +66 -0
  10. package/dist/observe/core/attribution-feedback.js +280 -0
  11. package/dist/observe/core/attribution-hooks.js +83 -0
  12. package/dist/observe/core/attribution-queries.js +43 -0
  13. package/dist/observe/core/attribution.js +2904 -0
  14. package/dist/observe/core/constants.js +283 -0
  15. package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
  16. package/dist/observe/core/core.js +1999 -0
  17. package/dist/observe/core/dev.js +343 -0
  18. package/dist/observe/core/effect.js +200 -0
  19. package/dist/observe/core/error-hooks.js +71 -0
  20. package/dist/observe/core/error.js +80 -0
  21. package/dist/observe/core/external.js +98 -0
  22. package/dist/observe/core/graph.js +155 -0
  23. package/dist/observe/core/heap.js +147 -0
  24. package/dist/observe/core/invariants.js +45 -0
  25. package/dist/observe/core/lanes.js +205 -0
  26. package/dist/observe/core/optimistic.js +627 -0
  27. package/dist/observe/core/owner.js +353 -0
  28. package/dist/observe/core/scheduler.js +1547 -0
  29. package/dist/observe/core/verdict.js +674 -0
  30. package/dist/observe/index.js +59 -0
  31. package/dist/observe/map.js +484 -0
  32. package/dist/observe/signals.js +731 -0
  33. package/dist/observe/store/index.js +44 -0
  34. package/dist/observe/store/next/optimistic.js +717 -0
  35. package/dist/observe/store/next/projection.js +266 -0
  36. package/dist/observe/store/next/reconcile.js +375 -0
  37. package/dist/observe/store/next/store.js +2480 -0
  38. package/dist/observe/store/next/target.js +51 -0
  39. package/dist/observe/store/store.js +331 -0
  40. package/dist/observe/store/storePath.js +103 -0
  41. package/dist/observe/store/utils.js +1070 -0
  42. package/dist/prod/affects.js +10 -9
  43. package/dist/prod/attribution.js +45 -0
  44. package/dist/prod/boundaries.js +388 -178
  45. package/dist/prod/core/action.js +65 -37
  46. package/dist/prod/core/async.js +378 -163
  47. package/dist/prod/core/attribution-hooks.js +3 -0
  48. package/dist/prod/core/constants.js +186 -1
  49. package/dist/prod/core/context.js +10 -16
  50. package/dist/prod/core/core.js +1546 -416
  51. package/dist/prod/core/dev.js +18 -1
  52. package/dist/prod/core/effect.js +119 -79
  53. package/dist/prod/core/error-hooks.js +71 -0
  54. package/dist/prod/core/error.js +13 -1
  55. package/dist/prod/core/external.js +4 -4
  56. package/dist/prod/core/graph.js +105 -54
  57. package/dist/prod/core/heap.js +72 -65
  58. package/dist/prod/core/invariants.js +3 -2
  59. package/dist/prod/core/lanes.js +117 -52
  60. package/dist/prod/core/optimistic.js +458 -104
  61. package/dist/prod/core/owner.js +131 -84
  62. package/dist/prod/core/scheduler.js +998 -241
  63. package/dist/prod/core/verdict.js +417 -112
  64. package/dist/prod/index.js +20 -8
  65. package/dist/prod/map.js +312 -151
  66. package/dist/prod/signals.js +363 -32
  67. package/dist/prod/store/index.js +2 -0
  68. package/dist/prod/store/next/optimistic.js +530 -197
  69. package/dist/prod/store/next/projection.js +142 -57
  70. package/dist/prod/store/next/reconcile.js +149 -103
  71. package/dist/prod/store/next/store.js +1470 -346
  72. package/dist/prod/store/next/target.js +40 -9
  73. package/dist/prod/store/store.js +23 -19
  74. package/dist/prod/store/utils.js +997 -130
  75. package/dist/types/attribution.d.ts +19 -0
  76. package/dist/types/attribution.prod.d.ts +22 -0
  77. package/dist/types/boundaries.d.ts +78 -5
  78. package/dist/types/core/action.d.ts +12 -5
  79. package/dist/types/core/async.d.ts +3 -1
  80. package/dist/types/core/attribution-costs.d.ts +35 -0
  81. package/dist/types/core/attribution-feedback.d.ts +133 -0
  82. package/dist/types/core/attribution-hooks.d.ts +304 -0
  83. package/dist/types/core/attribution-queries.d.ts +24 -0
  84. package/dist/types/core/attribution.d.ts +892 -0
  85. package/dist/types/core/constants.d.ts +179 -0
  86. package/dist/types/core/core.d.ts +299 -25
  87. package/dist/types/core/dev.d.ts +421 -8
  88. package/dist/types/core/effect.d.ts +8 -1
  89. package/dist/types/core/error-hooks.d.ts +71 -0
  90. package/dist/types/core/error.d.ts +9 -0
  91. package/dist/types/core/graph.d.ts +23 -0
  92. package/dist/types/core/heap.d.ts +5 -3
  93. package/dist/types/core/index.d.ts +6 -3
  94. package/dist/types/core/invariants.d.ts +5 -1
  95. package/dist/types/core/lanes.d.ts +51 -19
  96. package/dist/types/core/owner.d.ts +15 -3
  97. package/dist/types/core/scheduler.d.ts +248 -1
  98. package/dist/types/core/types.d.ts +124 -41
  99. package/dist/types/index.d.ts +18 -5
  100. package/dist/types/map.d.ts +2 -0
  101. package/dist/types/signals.d.ts +145 -13
  102. package/dist/types/store/index.d.ts +7 -6
  103. package/dist/types/store/next/optimistic.d.ts +18 -13
  104. package/dist/types/store/next/projection.d.ts +5 -2
  105. package/dist/types/store/next/reconcile.d.ts +7 -0
  106. package/dist/types/store/next/store.d.ts +83 -11
  107. package/dist/types/store/next/target.d.ts +108 -11
  108. package/dist/types/store/store.d.ts +20 -11
  109. package/dist/types/store/utils.d.ts +188 -0
  110. package/package.json +31 -26
  111. package/dist/node.cjs +0 -8137
  112. package/dist/types/store/optimistic.d.ts +0 -45
  113. package/dist/types/store/projection.d.ts +0 -70
  114. package/dist/types/store/reconcile.d.ts +0 -46
  115. package/dist/types-cjs/affects.d.cts +0 -47
  116. package/dist/types-cjs/boundaries.d.cts +0 -175
  117. package/dist/types-cjs/core/action.d.cts +0 -64
  118. package/dist/types-cjs/core/async.d.cts +0 -21
  119. package/dist/types-cjs/core/constants.d.cts +0 -71
  120. package/dist/types-cjs/core/core.d.cts +0 -156
  121. package/dist/types-cjs/core/dev.d.cts +0 -64
  122. package/dist/types-cjs/core/effect.d.cts +0 -30
  123. package/dist/types-cjs/core/error.d.cts +0 -47
  124. package/dist/types-cjs/core/external.d.cts +0 -15
  125. package/dist/types-cjs/core/graph.d.cts +0 -5
  126. package/dist/types-cjs/core/heap.d.cts +0 -22
  127. package/dist/types-cjs/core/index.d.cts +0 -13
  128. package/dist/types-cjs/core/invariants.d.cts +0 -59
  129. package/dist/types-cjs/core/lanes.d.cts +0 -56
  130. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  131. package/dist/types-cjs/core/owner.d.cts +0 -124
  132. package/dist/types-cjs/core/scheduler.d.cts +0 -172
  133. package/dist/types-cjs/core/types.d.cts +0 -148
  134. package/dist/types-cjs/core/verdict.d.cts +0 -2
  135. package/dist/types-cjs/index.d.cts +0 -10
  136. package/dist/types-cjs/map.d.cts +0 -69
  137. package/dist/types-cjs/package.json +0 -3
  138. package/dist/types-cjs/signals.d.cts +0 -624
  139. package/dist/types-cjs/store/index.d.cts +0 -19
  140. package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
  141. package/dist/types-cjs/store/next/projection.d.cts +0 -24
  142. package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
  143. package/dist/types-cjs/store/next/store.d.cts +0 -71
  144. package/dist/types-cjs/store/next/target.d.cts +0 -99
  145. package/dist/types-cjs/store/optimistic.d.cts +0 -45
  146. package/dist/types-cjs/store/projection.d.cts +0 -70
  147. package/dist/types-cjs/store/reconcile.d.cts +0 -46
  148. package/dist/types-cjs/store/store.d.cts +0 -138
  149. package/dist/types-cjs/store/storePath.d.cts +0 -58
  150. package/dist/types-cjs/store/utils.d.cts +0 -74
@@ -0,0 +1,353 @@
1
+ import { REACTIVE_DISPOSED, CONFIG_CHILD_COMPANIONS, STATUS_PENDING, CONFIG_AUTO_DISPOSE, REACTIVE_ZOMBIE, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, CONFIG_TRANSPARENT, defaultContext } from "./constants.js";
2
+
3
+ import { context, runWithOwner, pendingCheckActive, latestReadActive, tracking } from "./core.js";
4
+
5
+ import { unregisterRoot, registerRoot } from "./dev.js";
6
+
7
+ import { clearDeps, unobserved } from "./graph.js";
8
+
9
+ import { deleteFromHeap, queueFor, insertIntoHeap, insertIntoHeapHeight } from "./heap.js";
10
+
11
+ import { GlobalQueue, wokenTransitions, schedule, zombieQueue, dirtyQueue, globalQueue } from "./scheduler.js";
12
+
13
+ const PENDING_OWNER = {};
14
+
15
+ // Dummy owner to trigger store's read() path
16
+ function markDisposal(e) {
17
+ let n = e._n;
18
+ while (n) {
19
+ const e = n.oe;
20
+ n.oe = e | REACTIVE_ZOMBIE;
21
+ // migrate height-adjust entries too, not just recompute entries: every
22
+ // `deleteFromHeap` call site picks the queue from the zombie flag, so a
23
+ // node left physically linked in `dirtyQueue` after being zombified gets
24
+ // unlinked from the wrong queue on dispose, corrupting the bucket and
25
+ // livelocking the next `runHeap` that reaches it (#2759)
26
+ if (e & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT)) {
27
+ deleteFromHeap(n, e & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
28
+ if (e & REACTIVE_IN_HEAP) insertIntoHeap(n, zombieQueue); else insertIntoHeapHeight(n, zombieQueue);
29
+ }
30
+ markDisposal(n);
31
+ n = n.Fn;
32
+ }
33
+ }
34
+
35
+ function dispose(e) {
36
+ // Direct disposal is death, not dormancy: strip the observation lifecycle
37
+ // so a later read freezes at the last committed value instead of
38
+ // reawakening the node (#3024). The teardown itself (heap removal — a node
39
+ // left queued would be recomputed and resurrected by the next flush (#2983)
40
+ // — dep unlinking, child disposal) is exactly unobserved()'s body; only
41
+ // this flag distinguishes death from dormancy.
42
+ e.C &= ~CONFIG_AUTO_DISPOSE;
43
+ unobserved(e);
44
+ }
45
+
46
+ function disposeChildren(e, n = false, t) {
47
+ const i = e.oe;
48
+ if (i & REACTIVE_DISPOSED) return;
49
+ // A previous frame parked as zombies (#3404) dies with its owner (#3024):
50
+ // the commit that would retire it returns on the DISPOSED flag set below,
51
+ // so it drains here or its cleanups never run and the zombies stay
52
+ // subscribed, to rerun in a torn-down tree (#3561). Death only (`self`):
53
+ // a rerun's `disposeChildren(el)` leaves the frame rendering until commit.
54
+ if (n && !t && e.o !== null && (e.o.dt !== null || e.o.Et !== null)) disposeChildren(e, false, true);
55
+ if (n) {
56
+ e.oe = i | REACTIVE_DISPOSED;
57
+ if (e._parent === null && e.Zt) unregisterRoot(e);
58
+ // Companions are created detached and outlive their owner, but a verdict
59
+ // must not: a disposed source can never settle, so an isPending companion
60
+ // latched `true` here would hold a spinner forever (INV-9, the PR #2845
61
+ // edge). Snap runs after the DISPOSED flag is set so the oracle reads
62
+ // false, and notifies subscribers still watching the companion.
63
+ const n = e;
64
+ if (n.o?.xe || n.o?.Me) GlobalQueue.Qn(n);
65
+ // A firewall's leaves have no lifecycle of their own, so a companion on
66
+ // one of them outlives its source the same way (INV-9's rationale). The
67
+ // firewall knows which leaves carry companions (CONFIG_CHILD_COMPANIONS,
68
+ // #3038): snap them with it — the snap retires a shadow whose firewall is
69
+ // disposed (spec O5).
70
+ if (n.C & CONFIG_CHILD_COMPANIONS) n.o.xt.forEach(GlobalQueue.Qn);
71
+ // A pending reader parked in a transaction may be the only thing holding
72
+ // it (#3372): its death is a completion event the transaction must be
73
+ // re-judged for, and nothing else re-enters a parked transaction.
74
+ const t = n.me;
75
+ if (t && n.S & STATUS_PENDING && !wokenTransitions.includes(t)) wokenTransitions.push(t),
76
+ schedule();
77
+ }
78
+ if (n && e.Se && e.o !== null) e.o.pe = null;
79
+ let o = t ? e.o?.dt ?? null : e._n;
80
+ if (!t) e._n = null;
81
+ while (o) {
82
+ const e = o;
83
+ // Owner teardown is death regardless of the child's own lifecycle
84
+ // (#3024): strip AUTO_DISPOSE so a post-disposal read freezes at the
85
+ // last committed value instead of reawakening in a torn-down tree.
86
+ // Runs before the recursion so already-dormant children (whose
87
+ // disposeChildren call early-returns on REACTIVE_DISPOSED) die too.
88
+ // Only unobserved()'s own node keeps its dormancy — it is never in
89
+ // this loop; its children are rebuilt fresh on reawaken.
90
+ e.C &= ~CONFIG_AUTO_DISPOSE;
91
+ // Heap removal must not be gated on `_deps`: a dependency-free
92
+ // computation queued by refresh() has a null dep list but still sits in
93
+ // the dirty heap, and left there the post-disposal flush recomputes it —
94
+ // recompute() rewriting `_flags` clears REACTIVE_DISPOSED and the node
95
+ // comes back to life (post-unmount runs, leaked cleanups, #2983).
96
+ // deleteFromHeap self-guards on the in-heap flags (and tolerates plain
97
+ // Owners, whose _flags is undefined), so no gate here.
98
+ deleteFromHeap(e, queueFor(e));
99
+ clearDeps(e);
100
+ // The chain is detached above so a node a cleanup links mid-drain lands
101
+ // on the fresh head and survives. Pointing each drained child's prev at
102
+ // itself routes its later splice onto the detached chain, never the head,
103
+ // and keeps the dev owner-chain-head invariant honest for those children.
104
+ o.kt = o;
105
+ disposeChildren(o, true);
106
+ // Read after, not before: a sibling this disposal made dormant spliced
107
+ // itself out of the detached chain, and a cleanup may then have linked
108
+ // it at the fresh head, which rewrote the `_nextSibling` a pre-read
109
+ // would still be holding.
110
+ o = o.Fn;
111
+ }
112
+ if (t) {
113
+ if (e.o !== null) e.o.dt = null;
114
+ } else e.Nt = 0;
115
+ // O(1) splice out of parent's chain on individual dispose. Skipped during
116
+ // batch dispose (parent already disposed) and zombie disposal (node sits on
117
+ // parent's _pendingFirstChild). We leave node._nextSibling intact so outer
118
+ // walks that already advanced past us still reach later siblings.
119
+ if (n && !t && !(i & REACTIVE_ZOMBIE) && e._parent !== null && !(e._parent.oe & REACTIVE_DISPOSED)) {
120
+ const n = e.kt;
121
+ const t = e.Fn;
122
+ if (n !== null) n.Fn = t; else e._parent._n = t;
123
+ if (t !== null) t.kt = n;
124
+ e.kt = null;
125
+ }
126
+ runDisposal(e, t);
127
+ // Final effect-returned cleanup fires at true disposal, after `_disposal`
128
+ // to mirror rerun ordering (compute-phase teardown first, cleanup last).
129
+ if (n && e.qt) {
130
+ const n = e.qt;
131
+ e.qt = undefined;
132
+ n();
133
+ }
134
+ }
135
+
136
+ function linkChild(e, n) {
137
+ const t = e._n;
138
+ n.kt = null;
139
+ n.Fn = t;
140
+ if (t !== null) t.kt = n;
141
+ e._n = n;
142
+ }
143
+
144
+ function runDisposal(e, n) {
145
+ // Detach the list BEFORE running it (#3601), as `_cleanup` is (#2813). A
146
+ // cleanup that disposes an ancestor re-enters this node through the death
147
+ // walk while the loop is still running; with the list still attached, that
148
+ // walk ran every entry a second time. Detached, the re-entrant drain finds
149
+ // nothing. The same shape latched a throwing cleanup: the list survived the
150
+ // throw and every later drain re-ran and re-threw it.
151
+ const t = n ? e.o?.Et : e.Ve;
152
+ if (!t) return;
153
+ if (n) e.o.Et = null; else e.Ve = null;
154
+ if (Array.isArray(t)) {
155
+ // Unwind order (#3572, restores 1.x #1562): later registrations run
156
+ // before earlier ones. Children have already been disposed by the caller,
157
+ // so with LIFO a body that registers cleanup before creating its children
158
+ // tears down after them — the same order a per-component owner gives.
159
+ for (let e = t.length - 1; e >= 0; e--) {
160
+ const n = t[e];
161
+ n.call(n);
162
+ }
163
+ } else {
164
+ t.call(t);
165
+ }
166
+ }
167
+
168
+ function childId(e, n) {
169
+ let t = e;
170
+ while (t.C & CONFIG_TRANSPARENT && t._parent) t = t._parent;
171
+ if (t.id != null) return formatId(t.id, n ? t.Nt++ : t.Nt);
172
+ throw new Error("");
173
+ }
174
+
175
+ /**
176
+ * Allocates and returns the next stable child id for `owner`. Used by
177
+ * hydration plumbing and `createUniqueId`. Not part of the user-facing API.
178
+ *
179
+ * @internal
180
+ */ function getNextChildId(e) {
181
+ return childId(e, true);
182
+ }
183
+
184
+ /**
185
+ * The id a freshly-created node inherits: an explicit `options.id` wins;
186
+ * transparent nodes share their parent's id; otherwise the parent's next
187
+ * child id is consumed (or `undefined` outside an id-carrying tree).
188
+ */ function inheritId(e, n, t) {
189
+ return e?.id ?? (n ? t?.id : t?.id != null ? getNextChildId(t) : undefined);
190
+ }
191
+
192
+ /**
193
+ * Returns the *next* child id for `owner` without consuming it. Used by
194
+ * hydration plumbing to peek at the id a future child will receive.
195
+ *
196
+ * @internal
197
+ */ function peekNextChildId(e) {
198
+ return childId(e, false);
199
+ }
200
+
201
+ function formatId(e, n) {
202
+ const t = n.toString(36), i = t.length - 1;
203
+ return e + (i ? String.fromCharCode(64 + i) : "") + t;
204
+ }
205
+
206
+ /**
207
+ * Returns the currently-tracking observer (the computation that subscribes to
208
+ * reactive reads at this point), or `null` if reads here would be untracked.
209
+ * Used by reactive primitives that need to know whether they're inside a
210
+ * tracking scope. App code rarely needs this — see `getOwner()` for the
211
+ * lifecycle owner instead.
212
+ *
213
+ * @example
214
+ * ```ts
215
+ * // Library predicate: only register a hot-path subscription when the
216
+ * // caller is inside a tracking scope (memo / effect compute / JSX).
217
+ * function trackIfTracked(source: () => unknown) {
218
+ * if (getObserver()) source();
219
+ * }
220
+ * ```
221
+ */ function getObserver() {
222
+ if (pendingCheckActive || latestReadActive) return PENDING_OWNER;
223
+ return tracking ? context : null;
224
+ }
225
+
226
+ /**
227
+ * Returns the current reactive **owner** — the lifecycle node that the next
228
+ * `cleanup()` / `onCleanup()` / `createSignal()` etc. will be attached to.
229
+ *
230
+ * Returns `null` if called outside any owner. Capture the owner with
231
+ * `getOwner()` and re-enter it later with `runWithOwner(owner, fn)` to attach
232
+ * disposables created from a callback (event handler, async resolution, etc.)
233
+ * back to a component's lifecycle.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * function defer<T>(fn: () => T) {
238
+ * const owner = getOwner();
239
+ * queueMicrotask(() => runWithOwner(owner, fn));
240
+ * }
241
+ * ```
242
+ */ function getOwner() {
243
+ return context;
244
+ }
245
+
246
+ /**
247
+ * Low-level: registers `fn` as a disposal callback on the current owner.
248
+ * Most code should use `onCleanup()` from `solid-js`, which adds dev-mode
249
+ * checks. `cleanup()` is the unchecked primitive used by internals.
250
+ */ function cleanup(e) {
251
+ if (!context) return e;
252
+ if (!context.Ve) context.Ve = e; else if (Array.isArray(context.Ve)) context.Ve.push(e); else context.Ve = [ context.Ve, e ];
253
+ return e;
254
+ }
255
+
256
+ /**
257
+ * Returns `true` if the owner has been disposed (or marked zombie pending
258
+ * disposal). Pair with a captured owner to bail out of late callbacks whose
259
+ * surrounding component already unmounted.
260
+ *
261
+ * @example
262
+ * ```ts
263
+ * function onSettleSafe(fn: () => void) {
264
+ * const owner = getOwner();
265
+ * queueMicrotask(() => {
266
+ * if (owner && isDisposed(owner)) return; // component unmounted; skip
267
+ * runWithOwner(owner, fn);
268
+ * });
269
+ * }
270
+ * ```
271
+ */ function isDisposed(e) {
272
+ return !!(e.oe & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
273
+ }
274
+
275
+ function disposeRootSelf(e = true) {
276
+ disposeChildren(this, e);
277
+ }
278
+
279
+ /**
280
+ * Creates a fresh owner attached as a child of the current owner (or as a
281
+ * detached root if there is none). Used by framework internals to group
282
+ * cleanups; app code should use `createRoot()` (host a reactive scope outside
283
+ * a component) or `runWithOwner()` (re-enter a captured owner).
284
+ *
285
+ * @internal
286
+ */ function createOwner(e) {
287
+ const n = context;
288
+ const t = e?.transparent ?? false;
289
+ // Prod and observe boilerplates (see core.ts computed()). The observe
290
+ // literal carries the `_name` slot the rendering layer fills with the
291
+ // component label (`owner._name = "<App>"`) — a slot, so labelling a root
292
+ // is a plain store rather than a shape fork between labelled and plain roots.
293
+ const i = {
294
+ id: inheritId(e, t, n),
295
+ C: t ? CONFIG_TRANSPARENT : 0,
296
+ Zt: true,
297
+ Yt: n?.Zt ? n.Yt : n,
298
+ _n: null,
299
+ Fn: null,
300
+ kt: null,
301
+ Ve: null,
302
+ T: n?.T ?? globalQueue,
303
+ rt: n?.rt || defaultContext,
304
+ Nt: 0,
305
+ o: null,
306
+ _parent: n,
307
+ dispose: disposeRootSelf,
308
+ _name: undefined
309
+ };
310
+ if (n) linkChild(n, i); else registerRoot(i);
311
+ return i;
312
+ }
313
+
314
+ /**
315
+ * Creates a reactive root — an owner scope with its own `dispose()`. A root
316
+ * created inside an existing owner is owned by it and is disposed when the
317
+ * parent is disposed; call `dispose()` to tear it down earlier. To create a
318
+ * root that outlives its creator, detach explicitly:
319
+ * `runWithOwner(null, () => createRoot(...))`. Pass `id` to seed hydration
320
+ * ids for the tree it owns.
321
+ *
322
+ * `dispose()` tears down every signal, memo, effect, and `onCleanup`
323
+ * registered inside the root.
324
+ *
325
+ * Use this to host long-lived reactive scopes outside of a component (custom
326
+ * controllers, app bootstrapping, tests). Inside a component, prefer
327
+ * letting Solid's component lifecycle own things.
328
+ *
329
+ * @example
330
+ * ```ts
331
+ * // At module level there is no owner, so this root lives until disposed.
332
+ * const dispose = createRoot(dispose => {
333
+ * const [n, setN] = createSignal(0);
334
+ * createEffect(() => n(), value => console.log(value));
335
+ * setInterval(() => setN(x => x + 1), 1000);
336
+ * return dispose;
337
+ * });
338
+ *
339
+ * // Later, to tear everything down:
340
+ * dispose();
341
+ *
342
+ * // Inside an owner (component, effect, another root), detach explicitly
343
+ * // if the root must outlive its creator:
344
+ * const detached = runWithOwner(null, () => createRoot(d => d));
345
+ * ```
346
+ *
347
+ * @description https://docs.solidjs.com/reference/reactive-utilities/create-root
348
+ */ function createRoot(e, n) {
349
+ const t = createOwner(n);
350
+ return runWithOwner(t, () => e(() => t.dispose()));
351
+ }
352
+
353
+ export { cleanup, createOwner, createRoot, dispose, disposeChildren, getNextChildId, getObserver, getOwner, inheritId, isDisposed, linkChild, markDisposal, peekNextChildId };