@solidjs/signals 2.0.0-rc.19 → 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 (74) hide show
  1. package/dist/dev-shared.js +553 -264
  2. package/dist/dev.attribution.js +18 -18
  3. package/dist/dev.js +1030 -439
  4. package/dist/observe/affects.js +12 -2
  5. package/dist/observe/boundaries.js +168 -115
  6. package/dist/observe/core/async.js +57 -37
  7. package/dist/observe/core/attribution.js +6 -6
  8. package/dist/observe/core/constants.js +9 -1
  9. package/dist/observe/core/copies.js +10 -0
  10. package/dist/observe/core/core.js +261 -181
  11. package/dist/observe/core/effect.js +32 -27
  12. package/dist/observe/core/graph.js +7 -7
  13. package/dist/observe/core/heap.js +29 -29
  14. package/dist/observe/core/lanes.js +301 -101
  15. package/dist/observe/core/owner.js +13 -13
  16. package/dist/observe/core/scheduler.js +124 -69
  17. package/dist/observe/core/truth.js +9 -7
  18. package/dist/observe/core/verdict.js +160 -98
  19. package/dist/observe/deferred.js +1 -1
  20. package/dist/observe/index.js +2 -0
  21. package/dist/observe/map.js +120 -116
  22. package/dist/observe/reveal.js +48 -48
  23. package/dist/observe/signals.js +5 -5
  24. package/dist/observe/store/affects.js +2 -2
  25. package/dist/observe/store/optimistic.js +272 -176
  26. package/dist/observe/store/projection.js +21 -10
  27. package/dist/observe/store/reconcile.js +8 -2
  28. package/dist/observe/store/store.js +91 -55
  29. package/dist/observe/store/types.js +11 -1
  30. package/dist/observe/store/utils.js +1 -1
  31. package/dist/prod/affects.js +12 -2
  32. package/dist/prod/boundaries.js +164 -109
  33. package/dist/prod/core/async.js +201 -181
  34. package/dist/prod/core/constants.js +9 -1
  35. package/dist/prod/core/copies.js +10 -0
  36. package/dist/prod/core/core.js +244 -164
  37. package/dist/prod/core/dev.js +108 -3
  38. package/dist/prod/core/effect.js +28 -23
  39. package/dist/prod/core/graph.js +9 -9
  40. package/dist/prod/core/heap.js +16 -16
  41. package/dist/prod/core/identities.js +1 -1
  42. package/dist/prod/core/lanes.js +307 -95
  43. package/dist/prod/core/owner.js +22 -22
  44. package/dist/prod/core/scheduler.js +266 -211
  45. package/dist/prod/core/truth.js +9 -7
  46. package/dist/prod/core/verdict.js +161 -99
  47. package/dist/prod/deferred.js +1 -1
  48. package/dist/prod/index.js +2 -0
  49. package/dist/prod/map.js +78 -74
  50. package/dist/prod/reveal.js +34 -34
  51. package/dist/prod/signals.js +3 -3
  52. package/dist/prod/store/affects.js +15 -15
  53. package/dist/prod/store/optimistic.js +185 -89
  54. package/dist/prod/store/projection.js +49 -38
  55. package/dist/prod/store/reconcile.js +8 -2
  56. package/dist/prod/store/store.js +99 -63
  57. package/dist/prod/store/types.js +11 -1
  58. package/dist/types/affects.d.ts +3 -2
  59. package/dist/types/boundaries.d.ts +14 -2
  60. package/dist/types/core/async.d.ts +2 -1
  61. package/dist/types/core/constants.d.ts +8 -0
  62. package/dist/types/core/copies.d.ts +54 -0
  63. package/dist/types/core/core.d.ts +15 -0
  64. package/dist/types/core/dev.d.ts +1 -1
  65. package/dist/types/core/lanes.d.ts +8 -1
  66. package/dist/types/core/scheduler.d.ts +36 -4
  67. package/dist/types/core/truth.d.ts +3 -1
  68. package/dist/types/core/types.d.ts +6 -0
  69. package/dist/types/index.d.ts +2 -0
  70. package/dist/types/store/hooks.d.ts +15 -1
  71. package/dist/types/store/store.d.ts +2 -1
  72. package/dist/types/store/target.d.ts +5 -0
  73. package/dist/types/store/types.d.ts +7 -0
  74. package/package.json +1 -1
@@ -26,12 +26,13 @@ import { globalQueue, schedule, heldRunHook, haltReactivity, GlobalQueue } from
26
26
  // staged); the flush's commit replays this effect. Its first run is not this
27
27
  // creation's (A29). A lane's node likewise: its run is the lane's, queued
28
28
  // by the pass and released at the reveal (lanes.ts).
29
- !r?.defer && E.ie === NOT_PENDING && !E.T?.Je?.V && (E.i === EFFECT_USER || r?.schedule ? globalQueue.enqueue(E.i, runEffect.bind(null, E)) : runEffect(E, E.i));
29
+ !r?.defer && E.ue === NOT_PENDING && !E.T?.Je?.V && (E.i === EFFECT_USER || r?.schedule ? globalQueue.enqueue(E.i, runEffect.bind(null, E)) : // Type 0: the synchronous first render, not a queued run (D-19).
30
+ runEffect(E, 0));
30
31
  }
31
32
 
32
33
  function notifyEffectStatus() {
33
34
  const t = this.m;
34
- const e = this.T?.F;
35
+ const e = this.T?.U;
35
36
  if (t & STATUS_ERROR) {
36
37
  globalQueue.notify(this, STATUS_PENDING, 0);
37
38
  if (this.i === EFFECT_USER) {
@@ -48,18 +49,20 @@ function notifyEffectStatus() {
48
49
  return;
49
50
  }
50
51
  // Dev locates the halt at the node that threw: the StatusError's
51
- // source, upstream of this effect when a computed failed.
52
- escalate(this, unwrapStatusError(e), e, this);
52
+ // source, upstream of this effect when a computed failed. The rethrow is
53
+ // the user's error, not the wrapper: the wrapper's `source` is a node, and
54
+ // a reporter that serializes the throw walks the reactive graph.
55
+ escalate(this, unwrapStatusError(e), this);
53
56
  } else if (this.i === EFFECT_RENDER) {
54
57
  globalQueue.notify(this, STATUS_PENDING | STATUS_ERROR, t, e);
55
58
  }
56
59
  }
57
60
 
58
61
  /** An effect's error no boundary takes halts the system (boundary-or-halt):
59
- * halted with `cause`, `thrown` rethrown; dev locates it at `subject`. */ function escalate(t, e, o = e, r = t) {
62
+ * halted with `cause` and rethrown; dev locates it at `subject`. */ function escalate(t, e, o = t) {
60
63
  if (!globalQueue.notify(t, STATUS_ERROR, STATUS_ERROR)) {
61
64
  haltReactivity(e);
62
- throw o;
65
+ throw e;
63
66
  }
64
67
  }
65
68
 
@@ -70,10 +73,12 @@ function runEffect(t, e) {
70
73
  // effect's update too (maintainer, 2026-10-02: "we held the queue but let
71
74
  // the sync renders through… we definitely shouldn't be showing portals
72
75
  // early") — a Portal's or head-tag's render effect writes outside the
73
- // hidden subtree. The synchronous first render on creation is not a queued
74
- // run and goes through. `_modified` stays set; the boundary re-queues the
75
- // run (`release`).
76
- if (heldRunHook?.(t)) return;
76
+ // hidden subtree. The synchronous first render on creation (`type` 0) is
77
+ // not a queued run and goes through, whichever boundary above is on its
78
+ // fallback then — an outer one about to reveal in this flush included
79
+ // (#4343). `_modified` stays set; the boundary re-queues the run
80
+ // (`release`).
81
+ if (e && heldRunHook?.(t)) return;
77
82
  // Error arm (#2840), user effects only: a compute-phase error that is still
78
83
  // the node's settled state at effect time runs the bundle's error handler in
79
84
  // this same imperative, writable scope. Unwrap the StatusError used for
@@ -85,13 +90,13 @@ function runEffect(t, e) {
85
90
  // notifyEffectStatus, and a runner queued by an earlier valueChanged in the
86
91
  // same flush must not be hijacked by a later-arriving error status.
87
92
  if (t.m & STATUS_ERROR && t.i === EFFECT_USER) {
88
- const e = unwrapStatusError(t.T?.F);
89
- t._t = t.le;
93
+ const e = unwrapStatusError(t.T?.U);
94
+ t.It = t.le;
90
95
  t.Qe = false;
91
96
  try {
92
- t.Ht ? t.Ht(e, () => {
93
- const e = t.kt;
94
- t.kt = undefined;
97
+ t.kt ? t.kt(e, () => {
98
+ const e = t.Vt;
99
+ t.Vt = undefined;
95
100
  e?.();
96
101
  }) : console.error(e);
97
102
  } catch (e) {
@@ -101,26 +106,26 @@ function runEffect(t, e) {
101
106
  }
102
107
  // Captured before the callback: its own throw errors the node below, but
103
108
  // the compute pass that produced `_value` was clean, so its tail still goes.
104
- const o = t.T?.F == null;
109
+ const o = t.T?.U == null;
105
110
  // Observe tier, like its `effectRunEnd` twin below: the frame the engine
106
111
  // opens here is what stamps the callback's writes as the effect's (the
107
112
  // cascade an observer reports) and what times the callback (the `effect`
108
113
  // record) — facts a production observer needs, not only a dev console.
109
114
  if (attrHooks !== null) attrHooks.effectRunStart(t);
110
- const r = t.kt;
111
- t.kt = undefined;
115
+ const r = t.Vt;
116
+ t.Vt = undefined;
112
117
  try {
113
118
  r?.();
114
- const e = t.Ge(t.le, t._t);
119
+ const e = t.Ge(t.le, t.It);
115
120
  if (false && e !== undefined && typeof e !== "function") ;
116
121
  // The final cleanup is invoked by disposeChildren at true disposal.
117
- t.kt = e;
122
+ t.Vt = e;
118
123
  } catch (e) {
119
- ext(t).F = new StatusError(t, e);
124
+ ext(t).U = new StatusError(t, e);
120
125
  t.m |= STATUS_ERROR;
121
126
  escalate(t, e);
122
127
  } finally {
123
- t._t = t.le;
128
+ t.It = t.le;
124
129
  t.Qe = false;
125
130
  // The run applied: this is the frame now, so the dependency tail the
126
131
  // compute pass left linked goes (A30, #3438 — `recompute` defers an
@@ -134,7 +139,7 @@ function runEffect(t, e) {
134
139
  if (attrHooks !== null) attrHooks.effectRunEnd(t);
135
140
  }
136
141
 
137
- GlobalQueue.K = runEffect;
142
+ GlobalQueue.q = runEffect;
138
143
 
139
144
  /**
140
145
  * Internal tracked effect - bypasses heap, goes directly to effect queue.
@@ -153,16 +158,16 @@ GlobalQueue.K = runEffect;
153
158
  } finally {}
154
159
  };
155
160
  const o = computed(() => {
156
- const e = o.kt;
157
- o.kt = undefined;
161
+ const e = o.Vt;
162
+ o.Vt = undefined;
158
163
  e?.();
159
164
  const r = staleValues(t);
160
- o.kt = r;
165
+ o.Vt = r;
161
166
  }, {
162
167
  ...e,
163
168
  lazy: true
164
169
  });
165
- o.kt = undefined;
170
+ o.Vt = undefined;
166
171
  o.l = o.l & ~CONFIG_AUTO_DISPOSE | CONFIG_CHILDREN_FORBIDDEN;
167
172
  o.Qe = true;
168
173
  o.i = EFFECT_TRACKED;
@@ -21,7 +21,7 @@ function unlinkSubs(e) {
21
21
  const l = e.G;
22
22
  const o = e.t;
23
23
  const s = e.en;
24
- if (o !== null) o.en = s; else n.Ct = s;
24
+ if (o !== null) o.en = s; else n.Ot = s;
25
25
  if (s !== null) s.t = o; else {
26
26
  n.o = o;
27
27
  if (o === null) {
@@ -29,7 +29,7 @@ function unlinkSubs(e) {
29
29
  // unobserved closure, no NodeExtension to hold it.
30
30
  // A user hook that throws is collected like a cleanup (owner.ts): the
31
31
  // unlink and the teardown around it carry on.
32
- if (n.l & CONFIG_SLOT_NODE) slotUnobservedHook(n); else if (n.T?.Dt) runCleanup(n.T.Dt);
32
+ if (n.l & CONFIG_SLOT_NODE) slotUnobservedHook(n); else if (n.T?.Gt) runCleanup(n.T.Gt);
33
33
  // No more subscribers; only tear down if CONFIG_AUTO_DISPOSE is set.
34
34
  // A pending node is exempt: its in-flight async work is an observer —
35
35
  // tearing down would orphan the work and re-execute it on the next
@@ -133,7 +133,7 @@ function link(e, n) {
133
133
  if (s) {
134
134
  o = l !== null ? l.G : n.C;
135
135
  if (o !== null && o.S === e) {
136
- o.Ie = n.Ne;
136
+ o.de = n.Ne;
137
137
  n._ = o;
138
138
  return;
139
139
  }
@@ -143,15 +143,15 @@ function link(e, n) {
143
143
  // [deps.._depsTail] prefix — the O(1) equivalent of scanning the dep list
144
144
  // (the old alien-signals `isValidLink` walk, O(n²) when a computation
145
145
  // re-reads earlier deps non-consecutively, e.g. store leaf reads).
146
- const r = e.Ct;
147
- if (r !== null && r.u === n && (!s || r.Ie === n.Ne)) return;
148
- const t = n._ = e.Ct = {
146
+ const r = e.Ot;
147
+ if (r !== null && r.u === n && (!s || r.de === n.Ne)) return;
148
+ const t = n._ = e.Ot = {
149
149
  S: e,
150
150
  u: n,
151
151
  G: o,
152
152
  en: r,
153
153
  t: null,
154
- Ie: n.Ne
154
+ de: n.Ne
155
155
  };
156
156
  if (l !== null) l.G = t; else n.C = t;
157
157
  if (r !== null) r.t = t; else e.o = t;
@@ -11,22 +11,22 @@ import { dirtyQueue } from "./scheduler.js";
11
11
  * callback to the user queue once the pass has committed (see
12
12
  * GlobalQueue._update, #3291).
13
13
  */ function enqueueSub(e) {
14
- if (dirtyQueue.lt > e.Et) dirtyQueue.lt = e.Et;
14
+ if (dirtyQueue.Et > e.lt) dirtyQueue.Et = e.lt;
15
15
  insertIntoHeap(e, dirtyQueue);
16
16
  }
17
17
 
18
18
  function actualInsertIntoHeap(e, t) {
19
- const E = (e._parent?.Pt ? e._parent.ht?.Et : e._parent?.Et) ?? -1;
20
- if (E >= e.Et) e.Et = E + 1;
21
- const n = e.Et;
22
- const I = t.gt[n];
23
- if (I === undefined) t.gt[n] = e; else {
24
- const t = I.Rt;
25
- t.At = e;
26
- e.Rt = t;
27
- I.Rt = e;
19
+ const E = (e._parent?.Pt ? e._parent.Ht?.lt : e._parent?.lt) ?? -1;
20
+ if (E >= e.lt) e.lt = E + 1;
21
+ const n = e.lt;
22
+ const I = t.jt[n];
23
+ if (I === undefined) t.jt[n] = e; else {
24
+ const t = I.Ct;
25
+ t.Rt = e;
26
+ e.Ct = t;
27
+ I.Ct = e;
28
28
  }
29
- if (n > t.jt) t.jt = n;
29
+ if (n > t.yt) t.yt = n;
30
30
  }
31
31
 
32
32
  function insertIntoHeap(e, t) {
@@ -65,23 +65,23 @@ function deleteFromHeap(e, t) {
65
65
  const E = e.R;
66
66
  if (!(E & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
67
67
  e.R = E & -25;
68
- const n = e.Et;
69
- if (e.Rt === e) t.gt[n] = undefined; else {
70
- const E = e.At;
71
- const I = t.gt[n];
68
+ const n = e.lt;
69
+ if (e.Ct === e) t.jt[n] = undefined; else {
70
+ const E = e.Rt;
71
+ const I = t.jt[n];
72
72
  const i = E ?? I;
73
- if (e === I) t.gt[n] = E; else e.Rt.At = E;
74
- i.Rt = e.Rt;
73
+ if (e === I) t.jt[n] = E; else e.Ct.Rt = E;
74
+ i.Ct = e.Ct;
75
75
  }
76
- e.Rt = e;
77
- e.At = undefined;
76
+ e.Ct = e;
77
+ e.Rt = undefined;
78
78
  }
79
79
 
80
80
  function markHeap(e) {
81
81
  if (e.p) return;
82
82
  e.p = true;
83
- for (let t = 0; t <= e.jt; t++) {
84
- for (let E = e.gt[t]; E !== undefined; E = E.At) {
83
+ for (let t = 0; t <= e.yt; t++) {
84
+ for (let E = e.jt[t]; E !== undefined; E = E.Rt) {
85
85
  if (E.R & REACTIVE_IN_HEAP) markNode(E);
86
86
  }
87
87
  }
@@ -98,25 +98,25 @@ function markNode(e, t = REACTIVE_DIRTY) {
98
98
 
99
99
  function runHeap(e, t) {
100
100
  e.p = false;
101
- for (e.lt = 0; e.lt <= e.jt; e.lt++) {
102
- let E = e.gt[e.lt];
101
+ for (e.Et = 0; e.Et <= e.yt; e.Et++) {
102
+ let E = e.jt[e.Et];
103
103
  while (E !== undefined) {
104
104
  if (E.R & REACTIVE_IN_HEAP) t(E); else adjustHeight(E, e);
105
- E = e.gt[e.lt];
105
+ E = e.jt[e.Et];
106
106
  }
107
107
  }
108
- e.jt = 0;
108
+ e.yt = 0;
109
109
  }
110
110
 
111
111
  function adjustHeight(e, t) {
112
112
  deleteFromHeap(e, t);
113
- let E = e.Et;
113
+ let E = e.lt;
114
114
  for (let t = e.C; t; t = t.G) {
115
115
  const e = t.S;
116
- if (e.X && e.Et >= E) E = e.Et + 1;
116
+ if (e.X && e.lt >= E) E = e.lt + 1;
117
117
  }
118
- if (e.Et !== E) {
119
- e.Et = E;
118
+ if (e.lt !== E) {
119
+ e.lt = E;
120
120
  for (let E = e.o; E !== null; E = E.t) insertIntoHeapHeight(E.u, t);
121
121
  }
122
122
  }