@solidjs/signals 2.0.0-rc.14 → 2.0.0-rc.16

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 (98) hide show
  1. package/dist/dev-shared.js +882 -405
  2. package/dist/dev.attribution.js +172 -66
  3. package/dist/dev.js +1529 -745
  4. package/dist/observe/affects-marks.js +86 -0
  5. package/dist/observe/affects.js +32 -80
  6. package/dist/observe/boundaries.js +202 -166
  7. package/dist/observe/core/async.js +192 -141
  8. package/dist/observe/core/attribution-queries.js +1 -1
  9. package/dist/observe/core/attribution.js +315 -214
  10. package/dist/observe/core/constants.js +23 -4
  11. package/dist/observe/core/context.js +3 -3
  12. package/dist/observe/core/core.js +532 -360
  13. package/dist/observe/core/dev.js +63 -35
  14. package/dist/observe/core/effect.js +47 -47
  15. package/dist/observe/core/error.js +5 -3
  16. package/dist/observe/core/external.js +5 -6
  17. package/dist/observe/core/graph.js +56 -42
  18. package/dist/observe/core/heap.js +33 -33
  19. package/dist/observe/core/identities.js +62 -0
  20. package/dist/observe/core/lanes.js +242 -229
  21. package/dist/observe/core/owner.js +62 -50
  22. package/dist/observe/core/scheduler.js +322 -168
  23. package/dist/observe/core/truth.js +45 -0
  24. package/dist/observe/core/verdict.js +114 -64
  25. package/dist/observe/deferred.js +184 -0
  26. package/dist/observe/index.js +7 -1
  27. package/dist/observe/map.js +339 -254
  28. package/dist/observe/reveal.js +77 -77
  29. package/dist/observe/signals.js +54 -33
  30. package/dist/observe/store/affects.js +76 -69
  31. package/dist/observe/store/edges.js +39 -0
  32. package/dist/observe/store/hooks.js +13 -0
  33. package/dist/observe/store/index.js +0 -2
  34. package/dist/observe/store/optimistic.js +82 -44
  35. package/dist/observe/store/projection.js +83 -64
  36. package/dist/observe/store/reconcile.js +32 -30
  37. package/dist/observe/store/store.js +219 -123
  38. package/dist/prod/affects-marks.js +86 -0
  39. package/dist/prod/affects.js +33 -79
  40. package/dist/prod/boundaries.js +185 -149
  41. package/dist/prod/core/async.js +176 -135
  42. package/dist/prod/core/constants.js +23 -4
  43. package/dist/prod/core/context.js +3 -3
  44. package/dist/prod/core/core.js +521 -353
  45. package/dist/prod/core/effect.js +66 -66
  46. package/dist/prod/core/error.js +5 -3
  47. package/dist/prod/core/external.js +5 -6
  48. package/dist/prod/core/graph.js +56 -42
  49. package/dist/prod/core/heap.js +38 -38
  50. package/dist/prod/core/identities.js +62 -0
  51. package/dist/prod/core/lanes.js +237 -224
  52. package/dist/prod/core/owner.js +62 -51
  53. package/dist/prod/core/scheduler.js +312 -158
  54. package/dist/prod/core/truth.js +45 -0
  55. package/dist/prod/core/verdict.js +113 -63
  56. package/dist/prod/deferred.js +182 -0
  57. package/dist/prod/index.js +7 -1
  58. package/dist/prod/map.js +366 -281
  59. package/dist/prod/reveal.js +77 -77
  60. package/dist/prod/signals.js +59 -38
  61. package/dist/prod/store/affects.js +76 -69
  62. package/dist/prod/store/edges.js +39 -0
  63. package/dist/prod/store/hooks.js +13 -0
  64. package/dist/prod/store/index.js +0 -2
  65. package/dist/prod/store/optimistic.js +121 -84
  66. package/dist/prod/store/projection.js +46 -34
  67. package/dist/prod/store/reconcile.js +32 -30
  68. package/dist/prod/store/store.js +205 -116
  69. package/dist/types/affects-marks.d.ts +14 -0
  70. package/dist/types/boundaries.d.ts +5 -1
  71. package/dist/types/core/async.d.ts +10 -0
  72. package/dist/types/core/attribution.d.ts +6 -2
  73. package/dist/types/core/constants.d.ts +18 -1
  74. package/dist/types/core/core.d.ts +77 -5
  75. package/dist/types/core/dev.d.ts +43 -13
  76. package/dist/types/core/graph.d.ts +11 -0
  77. package/dist/types/core/identities.d.ts +17 -0
  78. package/dist/types/core/index.d.ts +2 -1
  79. package/dist/types/core/lanes.d.ts +2 -4
  80. package/dist/types/core/owner.d.ts +5 -3
  81. package/dist/types/core/scheduler.d.ts +59 -34
  82. package/dist/types/core/truth.d.ts +16 -0
  83. package/dist/types/core/types.d.ts +21 -6
  84. package/dist/types/core/verdict.d.ts +32 -0
  85. package/dist/types/deferred.d.ts +28 -0
  86. package/dist/types/index.d.ts +6 -0
  87. package/dist/types/map.d.ts +2 -2
  88. package/dist/types/signals.d.ts +28 -7
  89. package/dist/types/store/affects.d.ts +11 -0
  90. package/dist/types/store/edges.d.ts +9 -0
  91. package/dist/types/store/hooks.d.ts +48 -0
  92. package/dist/types/store/index.d.ts +10 -4
  93. package/dist/types/store/optimistic.d.ts +3 -2
  94. package/dist/types/store/projection.d.ts +4 -3
  95. package/dist/types/store/store.d.ts +4 -39
  96. package/dist/types/store/target.d.ts +16 -8
  97. package/dist/types/store/types.d.ts +14 -0
  98. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
- import { defaultContext, CONFIG_TRANSPARENT, REACTIVE_DISPOSED, STATUS_PENDING, REACTIVE_FRAME_READ, CONFIG_AUTO_DISPOSE, REACTIVE_ZOMBIE } from "./constants.js";
1
+ import { defaultContext, CONFIG_TRANSPARENT, REACTIVE_NONE, REACTIVE_DISPOSED, CONFIG_AUTO_DISPOSE, STATUS_PENDING, REACTIVE_FRAME_READ, REACTIVE_ZOMBIE } from "./constants.js";
2
2
 
3
3
  import { context, runWithOwner, tracking } from "./core.js";
4
4
 
5
- import { clearDeps, unobserved } from "./graph.js";
5
+ import { unobserved, clearDeps } from "./graph.js";
6
6
 
7
7
  import { deleteFromHeap } from "./heap.js";
8
8
 
@@ -16,11 +16,11 @@ import { schedule, dirtyQueue } from "./scheduler.js";
16
16
  // key off it, and the heap defers a zombie's recompute past the seam (no
17
17
  // second heap — the deferral list in scheduler.ts).
18
18
  function markDisposal(e) {
19
- let n = e.ge;
19
+ let n = e.De;
20
20
  while (n) {
21
21
  n.R |= REACTIVE_ZOMBIE;
22
22
  markDisposal(n);
23
- n = n.me;
23
+ n = n.pe;
24
24
  }
25
25
  }
26
26
 
@@ -31,7 +31,7 @@ function dispose(e) {
31
31
  // left queued would be recomputed and resurrected by the next flush (#2983)
32
32
  // — dep unlinking, child disposal) is exactly unobserved()'s body; only
33
33
  // this flag distinguishes death from dormancy.
34
- e.u &= ~CONFIG_AUTO_DISPOSE;
34
+ e.l &= ~CONFIG_AUTO_DISPOSE;
35
35
  unobserved(e);
36
36
  }
37
37
 
@@ -43,20 +43,20 @@ function disposeChildren(e, n = false, t) {
43
43
  // cleanups never run and it stays subscribed, rerunning in a torn-down
44
44
  // tree (#3561). Death only (`self`): a re-pass leaves the frame reacting
45
45
  // until the commit.
46
- if (n && !t && e.m !== null && (e.m.Me !== null || e.m.Be !== null)) disposeChildren(e, false, true);
46
+ if (n && !t && e.T !== null && (e.T.Ue !== null || e.T.me !== null)) disposeChildren(e, false, true);
47
47
  if (n) {
48
48
  e.R = i | REACTIVE_DISPOSED;
49
49
  }
50
- if (n && e.re) {
51
- if (e.m !== null) e.m.De = null;
50
+ if (n && e.X) {
51
+ if (e.T !== null) e.T.Se = null;
52
52
  // A death that can unblock the future (L2, `futureBlocked`): a held
53
53
  // flight's — a transaction's or a lane's (its `_x._transaction`) — or a
54
54
  // stale reader's (REACTIVE_FRAME_READ — a frame that derived from one).
55
55
  // Nothing else re-examines a dead node, so make sure a seam comes.
56
- if (e.G & STATUS_PENDING && e.m?.ke != null || i & REACTIVE_FRAME_READ) schedule();
56
+ if (e.m & STATUS_PENDING && e.T?.Re != null || i & REACTIVE_FRAME_READ) schedule();
57
57
  }
58
- let l = t ? e.m.Me : e.ge;
59
- if (t) e.m.Me = null; else e.ge = null;
58
+ let l = t ? e.T.Ue : e.De;
59
+ if (t) e.T.Ue = null; else e.De = null;
60
60
  while (l) {
61
61
  const e = l;
62
62
  // Owner teardown is death regardless of the child's own lifecycle
@@ -66,7 +66,7 @@ function disposeChildren(e, n = false, t) {
66
66
  // disposeChildren call early-returns on REACTIVE_DISPOSED) die too.
67
67
  // Only unobserved()'s own node keeps its dormancy — it is never in
68
68
  // this loop; its children are rebuilt fresh on reawaken.
69
- e.u &= ~CONFIG_AUTO_DISPOSE;
69
+ e.l &= ~CONFIG_AUTO_DISPOSE;
70
70
  // Heap removal must not be gated on `_deps`: a dependency-free
71
71
  // computation queued by refresh() has a null dep list but still sits in
72
72
  // the dirty heap, and left there the post-disposal flush recomputes it —
@@ -80,43 +80,43 @@ function disposeChildren(e, n = false, t) {
80
80
  // on the fresh head and survives. Pointing each drained child's prev at
81
81
  // itself routes its later splice onto the detached chain, never the head,
82
82
  // and keeps the dev owner-chain-head invariant honest for those children.
83
- l.Je = l;
83
+ l.Ze = l;
84
84
  disposeChildren(l, true);
85
85
  // Read after, not before: a sibling this disposal made dormant spliced
86
86
  // itself out of the detached chain, and a cleanup may then have linked
87
87
  // it at the fresh head, which rewrote the `_nextSibling` a pre-read
88
88
  // would still be holding.
89
- l = l.me;
89
+ l = l.pe;
90
90
  }
91
- if (!t) e.Ye = 0;
91
+ if (!t) e.ye = 0;
92
92
  // O(1) splice out of parent's chain on individual dispose. Skipped during
93
93
  // batch dispose (parent already disposed) and for a zombie (it sits on the
94
94
  // parent's parked frame, drained whole by the commit). We leave
95
95
  // node._nextSibling intact so outer walks that already advanced past us
96
96
  // still reach later siblings.
97
97
  if (n && !t && !(i & REACTIVE_ZOMBIE) && e._parent !== null && !(e._parent.R & REACTIVE_DISPOSED)) {
98
- const n = e.Je;
99
- const t = e.me;
100
- if (n !== null) n.me = t; else e._parent.ge = t;
101
- if (t !== null) t.Je = n;
102
- e.Je = null;
98
+ const n = e.Ze;
99
+ const t = e.pe;
100
+ if (n !== null) n.pe = t; else e._parent.De = t;
101
+ if (t !== null) t.Ze = n;
102
+ e.Ze = null;
103
103
  }
104
104
  runDisposal(e, t);
105
105
  // Final effect-returned cleanup fires at true disposal, after `_disposal`
106
106
  // to mirror rerun ordering (compute-phase teardown first, cleanup last).
107
- if (n && e.lt) {
108
- const n = e.lt;
109
- e.lt = undefined;
107
+ if (n && e.Je) {
108
+ const n = e.Je;
109
+ e.Je = undefined;
110
110
  n();
111
111
  }
112
112
  }
113
113
 
114
114
  function linkChild(e, n) {
115
- const t = e.ge;
116
- n.Je = null;
117
- n.me = t;
118
- if (t !== null) t.Je = n;
119
- e.ge = n;
115
+ const t = e.De;
116
+ n.Ze = null;
117
+ n.pe = t;
118
+ if (t !== null) t.Ze = n;
119
+ e.De = n;
120
120
  }
121
121
 
122
122
  function runDisposal(e, n) {
@@ -126,9 +126,9 @@ function runDisposal(e, n) {
126
126
  // walk ran every entry a second time. Detached, the re-entrant drain finds
127
127
  // nothing. The same shape latched a throwing cleanup: the list survived the
128
128
  // throw and every later drain re-ran and re-threw it.
129
- const t = n ? e.m.Be : e.Pe;
129
+ const t = n ? e.T.me : e.He;
130
130
  if (!t) return;
131
- if (n) e.m.Be = null; else e.Pe = null;
131
+ if (n) e.T.me = null; else e.He = null;
132
132
  if (Array.isArray(t)) {
133
133
  // Unwind order (#3572, restores 1.x #1562): later registrations run
134
134
  // before earlier ones. Children have already been disposed by the caller,
@@ -145,8 +145,8 @@ function runDisposal(e, n) {
145
145
 
146
146
  function childId(e, n) {
147
147
  let t = e;
148
- while (t.u & CONFIG_TRANSPARENT && t._parent) t = t._parent;
149
- if (t.id != null) return formatId(t.id, n ? t.Ye++ : t.Ye);
148
+ while (t.l & CONFIG_TRANSPARENT && t._parent) t = t._parent;
149
+ if (t.id != null) return formatId(t.id, n ? t.ye++ : t.ye);
150
150
  throw new Error("");
151
151
  }
152
152
 
@@ -223,10 +223,12 @@ function formatId(e, n) {
223
223
  /**
224
224
  * Low-level: registers `fn` as a disposal callback on the current owner.
225
225
  * Most code should use `onCleanup()` from `solid-js`, which adds dev-mode
226
- * checks. `cleanup()` is the unchecked primitive used by internals.
227
- */ function cleanup(e) {
228
- if (!context) return e;
229
- if (!context.Pe) context.Pe = e; else if (Array.isArray(context.Pe)) context.Pe.push(e); else context.Pe = [ context.Pe, e ];
226
+ * checks. `cleanup()` is the unchecked primitive used by internals; `owner`
227
+ * (internal) targets a specific owner's disposal list instead of the ambient
228
+ * one.
229
+ */ function cleanup(e, n = context) {
230
+ if (!n) return e;
231
+ if (!n.He) n.He = e; else if (Array.isArray(n.He)) n.He.push(e); else n.He = [ n.He, e ];
230
232
  return e;
231
233
  }
232
234
 
@@ -264,21 +266,27 @@ function disposeRootSelf(e = true) {
264
266
  const n = context;
265
267
  const t = e?.transparent ?? false;
266
268
  // Prod and observe boilerplates (see core.ts computed()). The observe
267
- // literal carries the `_name` slot the rendering layer fills with the
268
- // component label (`owner._name = "<App>"`) — a slot, so labelling a root
269
- // is a plain store rather than a shape fork between labelled and plain roots.
269
+ // literal carries the `_name` and `_loc` slots the rendering layer fills
270
+ // with the component label and JSX site (`owner._name = "<App>"`,
271
+ // `owner._loc = "src/App.tsx:3:5"`) — slots, so labelling a root is a
272
+ // plain store rather than a shape fork between labelled and plain roots.
270
273
  const i = {
271
274
  id: inheritId(e, t, n),
272
- u: t ? CONFIG_TRANSPARENT : 0,
273
- Et: true,
274
- ut: n?.Et ? n.ut : n,
275
- ge: null,
276
- me: null,
277
- Je: null,
278
- Pe: null,
279
- U: n?.U || defaultContext,
280
- Ye: 0,
281
- m: null,
275
+ l: t ? CONFIG_TRANSPARENT : 0,
276
+ // Present from birth: disposeChildren marks death here on roots too, and
277
+ // a first store of a missing property is a shape transition plus a
278
+ // properties-store allocation per root — on a 100×4 table teardown that
279
+ // was 12 KB and most of disposal's time (2026-10-17).
280
+ R: REACTIVE_NONE,
281
+ je: true,
282
+ Ye: n?.je ? n.Ye : n,
283
+ De: null,
284
+ pe: null,
285
+ Ze: null,
286
+ He: null,
287
+ A: n?.A || defaultContext,
288
+ ye: 0,
289
+ T: null,
282
290
  _parent: n,
283
291
  dispose: disposeRootSelf
284
292
  };
@@ -319,10 +327,13 @@ function disposeRootSelf(e = true) {
319
327
  * const detached = runWithOwner(null, () => createRoot(d => d));
320
328
  * ```
321
329
  *
322
- * @description https://docs.solidjs.com/reference/reactive-utilities/create-root
330
+ * @description https://v2.solidjs.com/reference/solid-js/advanced/owner-introspection/create-root
323
331
  */ function createRoot(e, n) {
324
332
  const t = createOwner(n);
325
- return runWithOwner(t, () => e(() => t.dispose()));
333
+ // A bound function, not an arrow: an arrow would share this scope, which
334
+ // holds `init`, so keeping `dispose` would keep `init` and all it closes
335
+ // over alive (#4095).
336
+ return runWithOwner(t, () => e(disposeRootSelf.bind(t, true)));
326
337
  }
327
338
 
328
339
  export { cleanup, createOwner, createRoot, dispose, disposeChildren, getNextChildId, getObserver, getOwner, inheritId, isDisposed, linkChild, markDisposal, peekNextChildId };