@solidjs/signals 2.0.0-rc.7 → 2.0.0-rc.8

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 (117) hide show
  1. package/dist/dev-shared.js +5243 -0
  2. package/dist/dev.attribution.js +2333 -0
  3. package/dist/dev.js +1229 -6834
  4. package/dist/observe/affects.js +127 -0
  5. package/dist/observe/attribution.js +1 -0
  6. package/dist/observe/boundaries.js +586 -0
  7. package/dist/observe/core/action.js +167 -0
  8. package/dist/observe/core/async.js +736 -0
  9. package/dist/observe/core/attribution-hooks.js +60 -0
  10. package/dist/observe/core/attribution.js +2318 -0
  11. package/dist/{types-cjs/core/constants.d.cts → observe/core/constants.js} +129 -73
  12. package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
  13. package/dist/observe/core/core.js +1289 -0
  14. package/dist/observe/core/dev.js +232 -0
  15. package/dist/observe/core/effect.js +179 -0
  16. package/dist/observe/core/error.js +80 -0
  17. package/dist/observe/core/external.js +98 -0
  18. package/dist/observe/core/graph.js +155 -0
  19. package/dist/observe/core/heap.js +147 -0
  20. package/dist/observe/core/invariants.js +43 -0
  21. package/dist/observe/core/lanes.js +168 -0
  22. package/dist/observe/core/optimistic.js +438 -0
  23. package/dist/observe/core/owner.js +308 -0
  24. package/dist/observe/core/scheduler.js +1190 -0
  25. package/dist/observe/core/verdict.js +551 -0
  26. package/dist/observe/index.js +55 -0
  27. package/dist/observe/map.js +482 -0
  28. package/dist/{types-cjs/signals.d.cts → observe/signals.js} +295 -317
  29. package/dist/observe/store/index.js +38 -0
  30. package/dist/observe/store/next/optimistic.js +651 -0
  31. package/dist/observe/store/next/projection.js +242 -0
  32. package/dist/observe/store/next/reconcile.js +373 -0
  33. package/dist/observe/store/next/store.js +2213 -0
  34. package/dist/observe/store/next/target.js +51 -0
  35. package/dist/observe/store/store.js +323 -0
  36. package/dist/observe/store/storePath.js +103 -0
  37. package/dist/observe/store/utils.js +210 -0
  38. package/dist/prod/attribution.js +32 -0
  39. package/dist/prod/core/action.js +52 -32
  40. package/dist/prod/core/async.js +171 -127
  41. package/dist/prod/core/constants.js +24 -1
  42. package/dist/prod/core/context.js +3 -3
  43. package/dist/prod/core/core.js +434 -291
  44. package/dist/prod/core/effect.js +54 -34
  45. package/dist/prod/core/external.js +2 -2
  46. package/dist/prod/core/graph.js +32 -32
  47. package/dist/prod/core/heap.js +49 -44
  48. package/dist/prod/core/lanes.js +45 -38
  49. package/dist/prod/core/optimistic.js +207 -73
  50. package/dist/prod/core/owner.js +43 -39
  51. package/dist/prod/core/scheduler.js +319 -190
  52. package/dist/prod/core/verdict.js +67 -67
  53. package/dist/prod/index.js +9 -3
  54. package/dist/prod/map.js +292 -141
  55. package/dist/prod/signals.js +7 -10
  56. package/dist/prod/store/next/optimistic.js +140 -125
  57. package/dist/prod/store/next/projection.js +3 -3
  58. package/dist/prod/store/next/reconcile.js +87 -84
  59. package/dist/prod/store/next/store.js +524 -280
  60. package/dist/prod/store/next/target.js +32 -10
  61. package/dist/prod/store/store.js +12 -14
  62. package/dist/prod/store/utils.js +36 -27
  63. package/dist/types/attribution.d.ts +15 -0
  64. package/dist/types/attribution.prod.d.ts +13 -0
  65. package/dist/types/core/async.d.ts +1 -1
  66. package/dist/types/core/attribution-hooks.d.ts +119 -6
  67. package/dist/types/core/attribution.d.ts +208 -53
  68. package/dist/types/core/constants.d.ts +23 -0
  69. package/dist/types/core/core.d.ts +7 -0
  70. package/dist/types/core/dev.d.ts +124 -26
  71. package/dist/types/core/effect.d.ts +8 -1
  72. package/dist/types/core/index.d.ts +2 -1
  73. package/dist/types/core/lanes.d.ts +8 -1
  74. package/dist/types/core/scheduler.d.ts +60 -0
  75. package/dist/types/core/types.d.ts +29 -9
  76. package/dist/types/index.d.ts +9 -2
  77. package/dist/types/map.d.ts +2 -0
  78. package/dist/types/store/index.d.ts +1 -0
  79. package/dist/types/store/next/store.d.ts +5 -0
  80. package/dist/types/store/next/target.d.ts +36 -9
  81. package/dist/types/store/utils.d.ts +7 -0
  82. package/package.json +21 -17
  83. package/dist/node.cjs +0 -10541
  84. package/dist/node.dev.cjs +0 -13724
  85. package/dist/types-cjs/affects.d.cts +0 -47
  86. package/dist/types-cjs/boundaries.d.cts +0 -175
  87. package/dist/types-cjs/core/action.d.cts +0 -64
  88. package/dist/types-cjs/core/async.d.cts +0 -23
  89. package/dist/types-cjs/core/attribution-hooks.d.cts +0 -127
  90. package/dist/types-cjs/core/attribution.d.cts +0 -495
  91. package/dist/types-cjs/core/core.d.cts +0 -185
  92. package/dist/types-cjs/core/dev.d.cts +0 -136
  93. package/dist/types-cjs/core/effect.d.cts +0 -30
  94. package/dist/types-cjs/core/error.d.cts +0 -56
  95. package/dist/types-cjs/core/external.d.cts +0 -15
  96. package/dist/types-cjs/core/graph.d.cts +0 -28
  97. package/dist/types-cjs/core/heap.d.cts +0 -24
  98. package/dist/types-cjs/core/index.d.cts +0 -13
  99. package/dist/types-cjs/core/invariants.d.cts +0 -59
  100. package/dist/types-cjs/core/lanes.d.cts +0 -54
  101. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  102. package/dist/types-cjs/core/owner.d.cts +0 -124
  103. package/dist/types-cjs/core/scheduler.d.cts +0 -236
  104. package/dist/types-cjs/core/types.d.cts +0 -204
  105. package/dist/types-cjs/core/verdict.d.cts +0 -2
  106. package/dist/types-cjs/index.d.cts +0 -10
  107. package/dist/types-cjs/map.d.cts +0 -69
  108. package/dist/types-cjs/package.json +0 -3
  109. package/dist/types-cjs/store/index.d.cts +0 -18
  110. package/dist/types-cjs/store/next/optimistic.d.cts +0 -25
  111. package/dist/types-cjs/store/next/projection.d.cts +0 -8
  112. package/dist/types-cjs/store/next/reconcile.d.cts +0 -10
  113. package/dist/types-cjs/store/next/store.d.cts +0 -121
  114. package/dist/types-cjs/store/next/target.d.cts +0 -166
  115. package/dist/types-cjs/store/store.d.cts +0 -143
  116. package/dist/types-cjs/store/storePath.d.cts +0 -58
  117. package/dist/types-cjs/store/utils.d.cts +0 -74
@@ -0,0 +1,308 @@
1
+ import { REACTIVE_DISPOSED, 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 { clearDeps, unobserved } from "./graph.js";
6
+
7
+ import { deleteFromHeap, queueFor, insertIntoHeap, insertIntoHeapHeight } from "./heap.js";
8
+
9
+ import { GlobalQueue, zombieQueue, dirtyQueue, globalQueue } from "./scheduler.js";
10
+
11
+ const PENDING_OWNER = {};
12
+
13
+ // Dummy owner to trigger store's read() path
14
+ function markDisposal(e) {
15
+ let t = e.Tt;
16
+ while (t) {
17
+ const e = t.it;
18
+ t.it = e | REACTIVE_ZOMBIE;
19
+ // migrate height-adjust entries too, not just recompute entries: every
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.dt;
30
+ }
31
+ }
32
+
33
+ function dispose(e) {
34
+ // Direct disposal is death, not dormancy: strip the observation lifecycle
35
+ // so a later read freezes at the last committed value instead of
36
+ // reawakening the node (#3024). The teardown itself (heap removal — a node
37
+ // left queued would be recomputed and resurrected by the next flush (#2983)
38
+ // — dep unlinking, child disposal) is exactly unobserved()'s body; only
39
+ // this flag distinguishes death from dormancy.
40
+ e.T &= ~CONFIG_AUTO_DISPOSE;
41
+ unobserved(e);
42
+ }
43
+
44
+ function disposeChildren(e, t = false, n) {
45
+ const i = e.it;
46
+ if (i & REACTIVE_DISPOSED) return;
47
+ if (t) {
48
+ e.it = i | REACTIVE_DISPOSED;
49
+ // Companions are created detached and outlive their owner, but a verdict
50
+ // must not: a disposed source can never settle, so an isPending companion
51
+ // latched `true` here would hold a spinner forever (INV-9, the PR #2845
52
+ // edge). Snap runs after the DISPOSED flag is set so the oracle reads
53
+ // false, and notifies subscribers still watching the companion.
54
+ const t = e;
55
+ if (t.o?.be || t.o?.pe) GlobalQueue.Dn(t);
56
+ }
57
+ if (t && e.ot && e.o !== null) e.o.Se = null;
58
+ let o = n ? e.o?.Rt ?? null : e.Tt;
59
+ while (o) {
60
+ const e = o.dt;
61
+ const t = o;
62
+ // Owner teardown is death regardless of the child's own lifecycle
63
+ // (#3024): strip AUTO_DISPOSE so a post-disposal read freezes at the
64
+ // last committed value instead of reawakening in a torn-down tree.
65
+ // Runs before the recursion so already-dormant children (whose
66
+ // disposeChildren call early-returns on REACTIVE_DISPOSED) die too.
67
+ // Only unobserved()'s own node keeps its dormancy — it is never in
68
+ // this loop; its children are rebuilt fresh on reawaken.
69
+ t.T &= ~CONFIG_AUTO_DISPOSE;
70
+ // Heap removal must not be gated on `_deps`: a dependency-free
71
+ // computation queued by refresh() has a null dep list but still sits in
72
+ // the dirty heap, and left there the post-disposal flush recomputes it —
73
+ // recompute() rewriting `_flags` clears REACTIVE_DISPOSED and the node
74
+ // comes back to life (post-unmount runs, leaked cleanups, #2983).
75
+ // deleteFromHeap self-guards on the in-heap flags (and tolerates plain
76
+ // Owners, whose _flags is undefined), so no gate here.
77
+ deleteFromHeap(t, queueFor(t));
78
+ clearDeps(t);
79
+ disposeChildren(o, true);
80
+ o = e;
81
+ }
82
+ if (n) {
83
+ if (e.o !== null) e.o.Rt = null;
84
+ } else {
85
+ e.Tt = null;
86
+ e.Gt = 0;
87
+ }
88
+ // O(1) splice out of parent's chain on individual dispose. Skipped during
89
+ // batch dispose (parent already disposed) and zombie disposal (node sits on
90
+ // parent's _pendingFirstChild). We leave node._nextSibling intact so outer
91
+ // walks that already advanced past us still reach later siblings.
92
+ if (t && !n && !(i & REACTIVE_ZOMBIE) && e.Nt !== null && !(e.Nt.it & REACTIVE_DISPOSED)) {
93
+ const t = e.wt;
94
+ const n = e.dt;
95
+ if (t !== null) t.dt = n; else e.Nt.Tt = n;
96
+ if (n !== null) n.wt = t;
97
+ e.wt = null;
98
+ }
99
+ runDisposal(e, n);
100
+ // Final effect-returned cleanup fires at true disposal, after `_disposal`
101
+ // to mirror rerun ordering (compute-phase teardown first, cleanup last).
102
+ if (t && e.Xt) {
103
+ const t = e.Xt;
104
+ e.Xt = undefined;
105
+ t();
106
+ }
107
+ }
108
+
109
+ function runDisposal(e, t) {
110
+ let n = t ? e.o?.Ct : e.he;
111
+ if (!n) return;
112
+ if (Array.isArray(n)) {
113
+ for (let e = 0; e < n.length; e++) {
114
+ const t = n[e];
115
+ t.call(t);
116
+ }
117
+ } else {
118
+ n.call(n);
119
+ }
120
+ if (t) {
121
+ if (e.o !== null) e.o.Ct = null;
122
+ } else e.he = null;
123
+ }
124
+
125
+ function childId(e, t) {
126
+ let n = e;
127
+ while (n.T & CONFIG_TRANSPARENT && n.Nt) n = n.Nt;
128
+ if (n.id != null) return formatId(n.id, t ? n.Gt++ : n.Gt);
129
+ throw new Error("");
130
+ }
131
+
132
+ /**
133
+ * Allocates and returns the next stable child id for `owner`. Used by
134
+ * hydration plumbing and `createUniqueId`. Not part of the user-facing API.
135
+ *
136
+ * @internal
137
+ */ function getNextChildId(e) {
138
+ return childId(e, true);
139
+ }
140
+
141
+ /**
142
+ * The id a freshly-created node inherits: an explicit `options.id` wins;
143
+ * transparent nodes share their parent's id; otherwise the parent's next
144
+ * child id is consumed (or `undefined` outside an id-carrying tree).
145
+ */ function inheritId(e, t, n) {
146
+ return e?.id ?? (t ? n?.id : n?.id != null ? getNextChildId(n) : undefined);
147
+ }
148
+
149
+ /**
150
+ * Returns the *next* child id for `owner` without consuming it. Used by
151
+ * hydration plumbing to peek at the id a future child will receive.
152
+ *
153
+ * @internal
154
+ */ function peekNextChildId(e) {
155
+ return childId(e, false);
156
+ }
157
+
158
+ function formatId(e, t) {
159
+ const n = t.toString(36), i = n.length - 1;
160
+ return e + (i ? String.fromCharCode(64 + i) : "") + n;
161
+ }
162
+
163
+ /**
164
+ * Returns the currently-tracking observer (the computation that subscribes to
165
+ * reactive reads at this point), or `null` if reads here would be untracked.
166
+ * Used by reactive primitives that need to know whether they're inside a
167
+ * tracking scope. App code rarely needs this — see `getOwner()` for the
168
+ * lifecycle owner instead.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * // Library predicate: only register a hot-path subscription when the
173
+ * // caller is inside a tracking scope (memo / effect compute / JSX).
174
+ * function trackIfTracked(source: () => unknown) {
175
+ * if (getObserver()) source();
176
+ * }
177
+ * ```
178
+ */ function getObserver() {
179
+ if (pendingCheckActive || latestReadActive) return PENDING_OWNER;
180
+ return tracking ? context : null;
181
+ }
182
+
183
+ /**
184
+ * Returns the current reactive **owner** — the lifecycle node that the next
185
+ * `cleanup()` / `onCleanup()` / `createSignal()` etc. will be attached to.
186
+ *
187
+ * Returns `null` if called outside any owner. Capture the owner with
188
+ * `getOwner()` and re-enter it later with `runWithOwner(owner, fn)` to attach
189
+ * disposables created from a callback (event handler, async resolution, etc.)
190
+ * back to a component's lifecycle.
191
+ *
192
+ * @example
193
+ * ```ts
194
+ * function defer<T>(fn: () => T) {
195
+ * const owner = getOwner();
196
+ * queueMicrotask(() => runWithOwner(owner, fn));
197
+ * }
198
+ * ```
199
+ */ function getOwner() {
200
+ return context;
201
+ }
202
+
203
+ /**
204
+ * Low-level: registers `fn` as a disposal callback on the current owner.
205
+ * Most code should use `onCleanup()` from `solid-js`, which adds dev-mode
206
+ * checks. `cleanup()` is the unchecked primitive used by internals.
207
+ */ function cleanup(e) {
208
+ if (!context) return e;
209
+ if (!context.he) context.he = e; else if (Array.isArray(context.he)) context.he.push(e); else context.he = [ context.he, e ];
210
+ return e;
211
+ }
212
+
213
+ /**
214
+ * Returns `true` if the owner has been disposed (or marked zombie pending
215
+ * disposal). Pair with a captured owner to bail out of late callbacks whose
216
+ * surrounding component already unmounted.
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * function onSettleSafe(fn: () => void) {
221
+ * const owner = getOwner();
222
+ * queueMicrotask(() => {
223
+ * if (owner && isDisposed(owner)) return; // component unmounted; skip
224
+ * runWithOwner(owner, fn);
225
+ * });
226
+ * }
227
+ * ```
228
+ */ function isDisposed(e) {
229
+ return !!(e.it & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
230
+ }
231
+
232
+ function disposeRootSelf(e = true) {
233
+ disposeChildren(this, e);
234
+ }
235
+
236
+ /**
237
+ * Creates a fresh owner attached as a child of the current owner (or as a
238
+ * detached root if there is none). Used by framework internals to group
239
+ * cleanups; app code should use `createRoot()` (host a reactive scope outside
240
+ * a component) or `runWithOwner()` (re-enter a captured owner).
241
+ *
242
+ * @internal
243
+ */ function createOwner(e) {
244
+ const t = context;
245
+ const n = e?.transparent ?? false;
246
+ // Prod and observe boilerplates (see core.ts computed()). The observe
247
+ // literal carries the `_name` slot the rendering layer fills with the
248
+ // component label (`owner._name = "<App>"`) — a slot, so labelling a root
249
+ // is a plain store rather than a shape fork between labelled and plain roots.
250
+ const i = {
251
+ id: inheritId(e, n, t),
252
+ T: n ? CONFIG_TRANSPARENT : 0,
253
+ $t: true,
254
+ ln: t?.$t ? t.ln : t,
255
+ Tt: null,
256
+ dt: null,
257
+ wt: null,
258
+ he: null,
259
+ C: t?.C ?? globalQueue,
260
+ ft: t?.ft || defaultContext,
261
+ Gt: 0,
262
+ o: null,
263
+ Nt: t,
264
+ dispose: disposeRootSelf,
265
+ _name: undefined
266
+ };
267
+ if (t) {
268
+ const e = t.Tt;
269
+ if (e === null) {
270
+ t.Tt = i;
271
+ } else {
272
+ i.dt = e;
273
+ e.wt = i;
274
+ t.Tt = i;
275
+ }
276
+ }
277
+ return i;
278
+ }
279
+
280
+ /**
281
+ * Creates a detached reactive root. The callback receives a `dispose()`
282
+ * function which, when called, tears down every signal, memo, effect, and
283
+ * `onCleanup` registered inside the root.
284
+ *
285
+ * Use this to host long-lived reactive scopes outside of a component (custom
286
+ * controllers, app bootstrapping, tests). Inside a component, prefer
287
+ * letting Solid's component lifecycle own things.
288
+ *
289
+ * @example
290
+ * ```ts
291
+ * const dispose = createRoot(dispose => {
292
+ * const [n, setN] = createSignal(0);
293
+ * createEffect(() => n(), value => console.log(value));
294
+ * setInterval(() => setN(x => x + 1), 1000);
295
+ * return dispose;
296
+ * });
297
+ *
298
+ * // Later, to tear everything down:
299
+ * dispose();
300
+ * ```
301
+ *
302
+ * @description https://docs.solidjs.com/reference/reactive-utilities/create-root
303
+ */ function createRoot(e, t) {
304
+ const n = createOwner(t);
305
+ return runWithOwner(n, () => e(() => n.dispose()));
306
+ }
307
+
308
+ export { cleanup, createOwner, createRoot, dispose, disposeChildren, getNextChildId, getObserver, getOwner, inheritId, isDisposed, markDisposal, peekNextChildId };