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

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 (90) hide show
  1. package/dist/dev-shared.js +1399 -285
  2. package/dist/dev.attribution.js +459 -307
  3. package/dist/dev.js +1864 -435
  4. package/dist/observe/affects.js +3 -1
  5. package/dist/observe/attribution.js +7 -1
  6. package/dist/observe/boundaries.js +209 -154
  7. package/dist/observe/core/action.js +18 -8
  8. package/dist/observe/core/async.js +220 -110
  9. package/dist/observe/core/attribution-costs.js +66 -0
  10. package/dist/observe/core/attribution-feedback.js +282 -0
  11. package/dist/observe/core/attribution-hooks.js +23 -1
  12. package/dist/observe/core/attribution-queries.js +28 -0
  13. package/dist/observe/core/attribution.js +262 -485
  14. package/dist/observe/core/constants.js +34 -1
  15. package/dist/observe/core/context.js +3 -3
  16. package/dist/observe/core/core.js +867 -367
  17. package/dist/observe/core/dev.js +78 -17
  18. package/dist/observe/core/effect.js +67 -51
  19. package/dist/observe/core/error-hooks.js +71 -0
  20. package/dist/observe/core/external.js +4 -4
  21. package/dist/observe/core/graph.js +37 -37
  22. package/dist/observe/core/heap.js +45 -45
  23. package/dist/observe/core/invariants.js +2 -0
  24. package/dist/observe/core/lanes.js +86 -49
  25. package/dist/observe/core/optimistic.js +242 -95
  26. package/dist/observe/core/owner.js +98 -84
  27. package/dist/observe/core/scheduler.js +543 -305
  28. package/dist/observe/core/verdict.js +247 -129
  29. package/dist/observe/index.js +7 -3
  30. package/dist/observe/map.js +126 -124
  31. package/dist/observe/signals.js +33 -17
  32. package/dist/observe/store/index.js +2 -0
  33. package/dist/observe/store/next/optimistic.js +141 -132
  34. package/dist/observe/store/next/projection.js +34 -21
  35. package/dist/observe/store/next/reconcile.js +58 -56
  36. package/dist/observe/store/next/store.js +260 -146
  37. package/dist/observe/store/store.js +5 -3
  38. package/dist/observe/store/utils.js +948 -135
  39. package/dist/prod/attribution.js +26 -17
  40. package/dist/prod/boundaries.js +128 -76
  41. package/dist/prod/core/action.js +16 -8
  42. package/dist/prod/core/async.js +251 -143
  43. package/dist/prod/core/constants.js +34 -1
  44. package/dist/prod/core/context.js +3 -3
  45. package/dist/prod/core/core.js +843 -347
  46. package/dist/prod/core/dev.js +17 -1
  47. package/dist/prod/core/effect.js +48 -34
  48. package/dist/prod/core/error-hooks.js +71 -0
  49. package/dist/prod/core/external.js +4 -4
  50. package/dist/prod/core/graph.js +37 -37
  51. package/dist/prod/core/heap.js +45 -45
  52. package/dist/prod/core/lanes.js +90 -53
  53. package/dist/prod/core/optimistic.js +247 -100
  54. package/dist/prod/core/owner.js +57 -45
  55. package/dist/prod/core/scheduler.js +543 -305
  56. package/dist/prod/core/verdict.js +245 -127
  57. package/dist/prod/index.js +7 -3
  58. package/dist/prod/map.js +112 -112
  59. package/dist/prod/signals.js +28 -12
  60. package/dist/prod/store/next/optimistic.js +135 -128
  61. package/dist/prod/store/next/projection.js +31 -20
  62. package/dist/prod/store/next/store.js +325 -252
  63. package/dist/prod/store/store.js +2 -2
  64. package/dist/prod/store/utils.js +946 -135
  65. package/dist/types/attribution.d.ts +7 -2
  66. package/dist/types/attribution.prod.d.ts +10 -1
  67. package/dist/types/boundaries.d.ts +10 -1
  68. package/dist/types/core/action.d.ts +12 -5
  69. package/dist/types/core/attribution-costs.d.ts +35 -0
  70. package/dist/types/core/attribution-feedback.d.ts +133 -0
  71. package/dist/types/core/attribution-hooks.d.ts +28 -3
  72. package/dist/types/core/attribution-queries.d.ts +10 -0
  73. package/dist/types/core/attribution.d.ts +51 -172
  74. package/dist/types/core/constants.d.ts +33 -0
  75. package/dist/types/core/core.d.ts +186 -5
  76. package/dist/types/core/dev.d.ts +129 -9
  77. package/dist/types/core/error-hooks.d.ts +71 -0
  78. package/dist/types/core/index.d.ts +3 -1
  79. package/dist/types/core/invariants.d.ts +4 -0
  80. package/dist/types/core/lanes.d.ts +31 -4
  81. package/dist/types/core/scheduler.d.ts +95 -2
  82. package/dist/types/core/types.d.ts +3 -0
  83. package/dist/types/index.d.ts +2 -2
  84. package/dist/types/signals.d.ts +8 -0
  85. package/dist/types/store/index.d.ts +2 -1
  86. package/dist/types/store/next/optimistic.d.ts +1 -1
  87. package/dist/types/store/next/store.d.ts +6 -5
  88. package/dist/types/store/next/target.d.ts +1 -1
  89. package/dist/types/store/utils.d.ts +177 -6
  90. package/package.json +1 -1
@@ -1,32 +1,34 @@
1
- import { REACTIVE_DISPOSED, CONFIG_AUTO_DISPOSE, REACTIVE_ZOMBIE, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, CONFIG_TRANSPARENT, defaultContext } from "./constants.js";
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
2
 
3
3
  import { context, runWithOwner, pendingCheckActive, latestReadActive, tracking } from "./core.js";
4
4
 
5
+ import "./dev.js";
6
+
5
7
  import { clearDeps, unobserved } from "./graph.js";
6
8
 
7
9
  import { deleteFromHeap, queueFor, insertIntoHeap, insertIntoHeapHeight } from "./heap.js";
8
10
 
9
- import { GlobalQueue, zombieQueue, dirtyQueue, globalQueue } from "./scheduler.js";
11
+ import { GlobalQueue, wokenTransitions, schedule, zombieQueue, dirtyQueue, globalQueue } from "./scheduler.js";
10
12
 
11
13
  const PENDING_OWNER = {};
12
14
 
13
15
  // Dummy owner to trigger store's read() path
14
16
  function markDisposal(e) {
15
- let t = e.Tt;
16
- while (t) {
17
- const e = t.it;
18
- t.it = e | REACTIVE_ZOMBIE;
17
+ let n = e.Ot;
18
+ while (n) {
19
+ const e = n.ft;
20
+ n.ft = e | REACTIVE_ZOMBIE;
19
21
  // migrate height-adjust entries too, not just recompute entries: every
20
22
  // `deleteFromHeap` call site picks the queue from the zombie flag, so a
21
23
  // node left physically linked in `dirtyQueue` after being zombified gets
22
24
  // unlinked from the wrong queue on dispose, corrupting the bucket and
23
25
  // livelocking the next `runHeap` that reaches it (#2759)
24
26
  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
+ deleteFromHeap(n, e & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
28
+ if (e & REACTIVE_IN_HEAP) insertIntoHeap(n, zombieQueue); else insertIntoHeapHeight(n, zombieQueue);
27
29
  }
28
- markDisposal(t);
29
- t = t.dt;
30
+ markDisposal(n);
31
+ n = n.At;
30
32
  }
31
33
  }
32
34
 
@@ -37,28 +39,40 @@ function dispose(e) {
37
39
  // left queued would be recomputed and resurrected by the next flush (#2983)
38
40
  // — dep unlinking, child disposal) is exactly unobserved()'s body; only
39
41
  // this flag distinguishes death from dormancy.
40
- e.T &= ~CONFIG_AUTO_DISPOSE;
42
+ e.C &= ~CONFIG_AUTO_DISPOSE;
41
43
  unobserved(e);
42
44
  }
43
45
 
44
- function disposeChildren(e, t = false, n) {
45
- const i = e.it;
46
+ function disposeChildren(e, n = false, t) {
47
+ const i = e.ft;
46
48
  if (i & REACTIVE_DISPOSED) return;
47
- if (t) {
48
- e.it = i | REACTIVE_DISPOSED;
49
+ if (n) {
50
+ e.ft = i | REACTIVE_DISPOSED;
49
51
  // Companions are created detached and outlive their owner, but a verdict
50
52
  // must not: a disposed source can never settle, so an isPending companion
51
53
  // latched `true` here would hold a spinner forever (INV-9, the PR #2845
52
54
  // edge). Snap runs after the DISPOSED flag is set so the oracle reads
53
55
  // false, and notifies subscribers still watching the companion.
54
- const t = e;
55
- if (t.o?.be || t.o?.pe) GlobalQueue.Dn(t);
56
+ const n = e;
57
+ if (n.o?.he || n.o?.Ge) GlobalQueue.Qn(n);
58
+ // A firewall's leaves have no lifecycle of their own, so a companion on
59
+ // one of them outlives its source the same way (INV-9's rationale). The
60
+ // firewall knows which leaves carry companions (CONFIG_CHILD_COMPANIONS,
61
+ // #3038): snap them with it — the snap retires a shadow whose firewall is
62
+ // disposed (spec O5).
63
+ if (n.C & CONFIG_CHILD_COMPANIONS) n.o.Jt.forEach(GlobalQueue.Qn);
64
+ // A pending reader parked in a transaction may be the only thing holding
65
+ // it (#3372): its death is a completion event the transaction must be
66
+ // re-judged for, and nothing else re-enters a parked transaction.
67
+ const t = n.Te;
68
+ if (t && n.S & STATUS_PENDING && !wokenTransitions.includes(t)) wokenTransitions.push(t),
69
+ schedule();
56
70
  }
57
- if (t && e.ot && e.o !== null) e.o.Se = null;
58
- let o = n ? e.o?.Rt ?? null : e.Tt;
71
+ if (n && e.ht && e.o !== null) e.o.ce = null;
72
+ let o = t ? e.o?.Pt ?? null : e.Ot;
59
73
  while (o) {
60
- const e = o.dt;
61
- const t = o;
74
+ const e = o.At;
75
+ const n = o;
62
76
  // Owner teardown is death regardless of the child's own lifecycle
63
77
  // (#3024): strip AUTO_DISPOSE so a post-disposal read freezes at the
64
78
  // last committed value instead of reawakening in a torn-down tree.
@@ -66,7 +80,7 @@ function disposeChildren(e, t = false, n) {
66
80
  // disposeChildren call early-returns on REACTIVE_DISPOSED) die too.
67
81
  // Only unobserved()'s own node keeps its dormancy — it is never in
68
82
  // this loop; its children are rebuilt fresh on reawaken.
69
- t.T &= ~CONFIG_AUTO_DISPOSE;
83
+ n.C &= ~CONFIG_AUTO_DISPOSE;
70
84
  // Heap removal must not be gated on `_deps`: a dependency-free
71
85
  // computation queued by refresh() has a null dep list but still sits in
72
86
  // the dirty heap, and left there the post-disposal flush recomputes it —
@@ -74,58 +88,58 @@ function disposeChildren(e, t = false, n) {
74
88
  // comes back to life (post-unmount runs, leaked cleanups, #2983).
75
89
  // deleteFromHeap self-guards on the in-heap flags (and tolerates plain
76
90
  // Owners, whose _flags is undefined), so no gate here.
77
- deleteFromHeap(t, queueFor(t));
78
- clearDeps(t);
91
+ deleteFromHeap(n, queueFor(n));
92
+ clearDeps(n);
79
93
  disposeChildren(o, true);
80
94
  o = e;
81
95
  }
82
- if (n) {
83
- if (e.o !== null) e.o.Rt = null;
96
+ if (t) {
97
+ if (e.o !== null) e.o.Pt = null;
84
98
  } else {
85
- e.Tt = null;
86
- e.Gt = 0;
99
+ e.Ot = null;
100
+ e.Ft = 0;
87
101
  }
88
102
  // O(1) splice out of parent's chain on individual dispose. Skipped during
89
103
  // batch dispose (parent already disposed) and zombie disposal (node sits on
90
104
  // parent's _pendingFirstChild). We leave node._nextSibling intact so outer
91
105
  // 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;
106
+ if (n && !t && !(i & REACTIVE_ZOMBIE) && e._parent !== null && !(e._parent.ft & REACTIVE_DISPOSED)) {
107
+ const n = e.Yt;
108
+ const t = e.At;
109
+ if (n !== null) n.At = t; else e._parent.Ot = t;
110
+ if (t !== null) t.Yt = n;
111
+ e.Yt = null;
98
112
  }
99
- runDisposal(e, n);
113
+ runDisposal(e, t);
100
114
  // Final effect-returned cleanup fires at true disposal, after `_disposal`
101
115
  // 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();
116
+ if (n && e.an) {
117
+ const n = e.an;
118
+ e.an = undefined;
119
+ n();
106
120
  }
107
121
  }
108
122
 
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);
123
+ function runDisposal(e, n) {
124
+ let t = n ? e.o?.Dt : e.Ue;
125
+ if (!t) return;
126
+ if (Array.isArray(t)) {
127
+ for (let e = 0; e < t.length; e++) {
128
+ const n = t[e];
129
+ n.call(n);
116
130
  }
117
131
  } else {
118
- n.call(n);
132
+ t.call(t);
119
133
  }
120
- if (t) {
121
- if (e.o !== null) e.o.Ct = null;
122
- } else e.he = null;
134
+ if (n) {
135
+ if (e.o !== null) e.o.Dt = null;
136
+ } else e.Ue = null;
123
137
  }
124
138
 
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);
139
+ function childId(e, n) {
140
+ let t = e;
141
+ while (t.C & CONFIG_TRANSPARENT && t._parent) t = t._parent;
142
+ if (t.id != null) return formatId(t.id, n ? t.Ft++ : t.Ft);
129
143
  throw new Error("");
130
144
  }
131
145
 
@@ -142,8 +156,8 @@ function childId(e, t) {
142
156
  * The id a freshly-created node inherits: an explicit `options.id` wins;
143
157
  * transparent nodes share their parent's id; otherwise the parent's next
144
158
  * 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);
159
+ */ function inheritId(e, n, t) {
160
+ return e?.id ?? (n ? t?.id : t?.id != null ? getNextChildId(t) : undefined);
147
161
  }
148
162
 
149
163
  /**
@@ -155,9 +169,9 @@ function childId(e, t) {
155
169
  return childId(e, false);
156
170
  }
157
171
 
158
- function formatId(e, t) {
159
- const n = t.toString(36), i = n.length - 1;
160
- return e + (i ? String.fromCharCode(64 + i) : "") + n;
172
+ function formatId(e, n) {
173
+ const t = n.toString(36), i = t.length - 1;
174
+ return e + (i ? String.fromCharCode(64 + i) : "") + t;
161
175
  }
162
176
 
163
177
  /**
@@ -206,7 +220,7 @@ function formatId(e, t) {
206
220
  * checks. `cleanup()` is the unchecked primitive used by internals.
207
221
  */ function cleanup(e) {
208
222
  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 ];
223
+ if (!context.Ue) context.Ue = e; else if (Array.isArray(context.Ue)) context.Ue.push(e); else context.Ue = [ context.Ue, e ];
210
224
  return e;
211
225
  }
212
226
 
@@ -226,7 +240,7 @@ function formatId(e, t) {
226
240
  * }
227
241
  * ```
228
242
  */ function isDisposed(e) {
229
- return !!(e.it & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
243
+ return !!(e.ft & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE));
230
244
  }
231
245
 
232
246
  function disposeRootSelf(e = true) {
@@ -241,37 +255,37 @@ function disposeRootSelf(e = true) {
241
255
  *
242
256
  * @internal
243
257
  */ function createOwner(e) {
244
- const t = context;
245
- const n = e?.transparent ?? false;
258
+ const n = context;
259
+ const t = e?.transparent ?? false;
246
260
  // Prod and observe boilerplates (see core.ts computed()). The observe
247
261
  // literal carries the `_name` slot the rendering layer fills with the
248
262
  // component label (`owner._name = "<App>"`) — a slot, so labelling a root
249
263
  // is a plain store rather than a shape fork between labelled and plain roots.
250
264
  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,
265
+ id: inheritId(e, t, n),
266
+ C: t ? CONFIG_TRANSPARENT : 0,
267
+ cn: true,
268
+ fn: n?.cn ? n.fn : n,
269
+ Ot: null,
270
+ At: null,
271
+ Yt: null,
272
+ Ue: null,
273
+ T: n?.T ?? globalQueue,
274
+ wt: n?.wt || defaultContext,
275
+ Ft: 0,
262
276
  o: null,
263
- Nt: t,
277
+ _parent: n,
264
278
  dispose: disposeRootSelf,
265
279
  _name: undefined
266
280
  };
267
- if (t) {
268
- const e = t.Tt;
281
+ if (n) {
282
+ const e = n.Ot;
269
283
  if (e === null) {
270
- t.Tt = i;
284
+ n.Ot = i;
271
285
  } else {
272
- i.dt = e;
273
- e.wt = i;
274
- t.Tt = i;
286
+ i.At = e;
287
+ e.Yt = i;
288
+ n.Ot = i;
275
289
  }
276
290
  }
277
291
  return i;
@@ -300,9 +314,9 @@ function disposeRootSelf(e = true) {
300
314
  * ```
301
315
  *
302
316
  * @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()));
317
+ */ function createRoot(e, n) {
318
+ const t = createOwner(n);
319
+ return runWithOwner(t, () => e(() => t.dispose()));
306
320
  }
307
321
 
308
322
  export { cleanup, createOwner, createRoot, dispose, disposeChildren, getNextChildId, getObserver, getOwner, inheritId, isDisposed, markDisposal, peekNextChildId };