@solidjs/signals 2.0.0-rc.17 → 2.0.0-rc.19

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 (71) hide show
  1. package/dist/dev-shared.js +426 -241
  2. package/dist/dev.attribution.js +19 -16
  3. package/dist/dev.js +768 -409
  4. package/dist/observe/boundaries.js +88 -67
  5. package/dist/observe/core/action.js +8 -0
  6. package/dist/observe/core/async.js +183 -138
  7. package/dist/observe/core/attribution.js +30 -28
  8. package/dist/observe/core/constants.js +23 -1
  9. package/dist/observe/core/core.js +185 -157
  10. package/dist/observe/core/effect.js +34 -37
  11. package/dist/observe/core/graph.js +8 -8
  12. package/dist/observe/core/heap.js +5 -5
  13. package/dist/observe/core/lanes.js +104 -84
  14. package/dist/observe/core/owner.js +17 -16
  15. package/dist/observe/core/scheduler.js +61 -47
  16. package/dist/observe/core/truth.js +6 -6
  17. package/dist/observe/core/verdict.js +15 -15
  18. package/dist/observe/deferred.js +40 -38
  19. package/dist/observe/from.js +248 -0
  20. package/dist/observe/index.js +4 -2
  21. package/dist/observe/map.js +22 -22
  22. package/dist/observe/reveal.js +5 -5
  23. package/dist/observe/signals.js +57 -15
  24. package/dist/observe/store/affects.js +1 -1
  25. package/dist/observe/store/hooks.js +3 -0
  26. package/dist/observe/store/optimistic.js +11 -11
  27. package/dist/observe/store/projection.js +34 -21
  28. package/dist/observe/store/reconcile.js +138 -122
  29. package/dist/observe/store/store.js +628 -641
  30. package/dist/observe/store/target.js +1 -5
  31. package/dist/observe/store/utils.js +7 -2
  32. package/dist/prod/boundaries.js +153 -132
  33. package/dist/prod/core/action.js +8 -0
  34. package/dist/prod/core/async.js +242 -197
  35. package/dist/prod/core/constants.js +16 -1
  36. package/dist/prod/core/core.js +166 -138
  37. package/dist/prod/core/effect.js +31 -34
  38. package/dist/prod/core/graph.js +5 -5
  39. package/dist/prod/core/heap.js +12 -12
  40. package/dist/prod/core/lanes.js +98 -78
  41. package/dist/prod/core/owner.js +15 -14
  42. package/dist/prod/core/scheduler.js +64 -50
  43. package/dist/prod/core/truth.js +6 -6
  44. package/dist/prod/core/verdict.js +17 -17
  45. package/dist/prod/deferred.js +40 -38
  46. package/dist/prod/from.js +248 -0
  47. package/dist/prod/index.js +4 -2
  48. package/dist/prod/map.js +14 -14
  49. package/dist/prod/reveal.js +8 -8
  50. package/dist/prod/signals.js +46 -4
  51. package/dist/prod/store/affects.js +1 -1
  52. package/dist/prod/store/hooks.js +3 -0
  53. package/dist/prod/store/optimistic.js +16 -16
  54. package/dist/prod/store/projection.js +22 -9
  55. package/dist/prod/store/reconcile.js +138 -122
  56. package/dist/prod/store/store.js +308 -331
  57. package/dist/prod/store/target.js +13 -17
  58. package/dist/prod/store/utils.js +2 -0
  59. package/dist/types/core/action.d.ts +8 -0
  60. package/dist/types/core/async.d.ts +12 -2
  61. package/dist/types/core/constants.d.ts +25 -0
  62. package/dist/types/core/core.d.ts +33 -4
  63. package/dist/types/core/dev.d.ts +1 -1
  64. package/dist/types/core/index.d.ts +1 -1
  65. package/dist/types/core/lanes.d.ts +5 -1
  66. package/dist/types/core/scheduler.d.ts +17 -3
  67. package/dist/types/from.d.ts +47 -0
  68. package/dist/types/index.d.ts +4 -1
  69. package/dist/types/signals.d.ts +37 -0
  70. package/dist/types/store/target.d.ts +2 -0
  71. package/package.json +1 -1
@@ -15,44 +15,47 @@ import { globalQueue, schedule, heldRunHook, haltReactivity, GlobalQueue } from
15
15
  * automatically added to the queue of effects to re-execute, which will cause them to fetch their
16
16
  * sources and recompute
17
17
  */ function effect(t, e, E, u) {
18
- const f = !!u?.user;
19
- const r = createEffectNode(t, e, E, f ? EFFECT_USER : EFFECT_RENDER, u);
20
- recompute(r, true);
18
+ const r = !!u?.user;
19
+ const f = createEffectNode(t, e, E, r ? EFFECT_USER : EFFECT_RENDER, u);
20
+ recompute(f, true);
21
21
  // A first pass that read a staged value was staged itself (recompute: born
22
22
  // staged); the flush's commit replays this effect. Its first run is not this
23
23
  // creation's (A29). A lane's node likewise: its run is the lane's, queued
24
24
  // by the pass and released at the reveal (lanes.ts).
25
- !u?.defer && r.se === NOT_PENDING && !r.T?.Re?.v && (r.i === EFFECT_USER || u?.schedule ? globalQueue.enqueue(r.i, runEffect.bind(null, r)) : runEffect(r, r.i));
25
+ !u?.defer && f.ie === NOT_PENDING && !f.T?.Re?.P && (f.i === EFFECT_USER || u?.schedule ? globalQueue.enqueue(f.i, runEffect.bind(null, f)) : runEffect(f, f.i));
26
26
  }
27
27
 
28
- function notifyEffectStatus(t, e) {
29
- // Use passed values if provided, otherwise read from node
30
- const E = t !== undefined ? t : this.m;
31
- const u = e !== undefined ? e : this.T?.F;
32
- if (E & STATUS_ERROR) {
28
+ function notifyEffectStatus() {
29
+ const t = this.m;
30
+ const e = this.T?.U;
31
+ if (t & STATUS_ERROR) {
33
32
  globalQueue.notify(this, STATUS_PENDING, 0);
34
33
  if (this.i === EFFECT_USER) {
35
34
  // The error handler is the error arm of the effect phase (#2840 ruling):
36
35
  // queue it like the effect function. It runs in the same imperative,
37
36
  // writable scope and throws escalate the same way. No payload is queued — the node already carries `_statusFlags`/`_error`,
38
37
  // and the runner dispatches on them, so a recovery before the effect
39
- // phase takes the success arm instead. Blocked forwards (explicit
40
- // `status` arg without node-state writes) don't queue: the status
41
- // re-propagates unblocked at commit.
38
+ // phase takes the success arm instead. (Re-read: the boundary
39
+ // notify above can run a redraw.)
42
40
  if (this.m & STATUS_ERROR) {
43
41
  this.Ae = true;
44
42
  globalQueue.enqueue(this.i, this.W ??= runEffect.bind(null, this));
45
43
  }
46
44
  return;
47
45
  }
48
- if (!globalQueue.notify(this, STATUS_ERROR, STATUS_ERROR)) {
49
- // Dev locates the halt at the node that threw: the StatusError's
50
- // source, upstream of this effect when a computed failed.
51
- haltReactivity(unwrapStatusError(u));
52
- throw u;
53
- }
46
+ // Dev locates the halt at the node that threw: the StatusError's
47
+ // source, upstream of this effect when a computed failed.
48
+ escalate(this, unwrapStatusError(e), e, this);
54
49
  } else if (this.i === EFFECT_RENDER) {
55
- globalQueue.notify(this, STATUS_PENDING | STATUS_ERROR, E, u);
50
+ globalQueue.notify(this, STATUS_PENDING | STATUS_ERROR, t, e);
51
+ }
52
+ }
53
+
54
+ /** An effect's error no boundary takes halts the system (boundary-or-halt):
55
+ * halted with `cause`, `thrown` rethrown; dev locates it at `subject`. */ function escalate(t, e, E = e, u = t) {
56
+ if (!globalQueue.notify(t, STATUS_ERROR, STATUS_ERROR)) {
57
+ haltReactivity(e);
58
+ throw E;
56
59
  }
57
60
  }
58
61
 
@@ -78,8 +81,8 @@ function runEffect(t, e) {
78
81
  // notifyEffectStatus, and a runner queued by an earlier valueChanged in the
79
82
  // same flush must not be hijacked by a later-arriving error status.
80
83
  if (t.m & STATUS_ERROR && t.i === EFFECT_USER) {
81
- const e = unwrapStatusError(t.T?.F);
82
- t.ge = t.Ie;
84
+ const e = unwrapStatusError(t.T?.U);
85
+ t.ke = t.le;
83
86
  t.Ae = false;
84
87
  try {
85
88
  t.qe ? t.qe(e, () => {
@@ -88,33 +91,27 @@ function runEffect(t, e) {
88
91
  e?.();
89
92
  }) : console.error(e);
90
93
  } catch (e) {
91
- if (!globalQueue.notify(t, STATUS_ERROR, STATUS_ERROR)) {
92
- haltReactivity(e);
93
- throw e;
94
- }
94
+ escalate(t, e);
95
95
  }
96
96
  return;
97
97
  }
98
98
  // Captured before the callback: its own throw errors the node below, but
99
99
  // the compute pass that produced `_value` was clean, so its tail still goes.
100
- const E = t.T?.F == null;
100
+ const E = t.T?.U == null;
101
101
  const u = t.Je;
102
102
  t.Je = undefined;
103
103
  try {
104
104
  u?.();
105
- const e = t.Ke(t.Ie, t.ge);
105
+ const e = t.Ke(t.le, t.ke);
106
106
  if (false && e !== undefined && typeof e !== "function") ;
107
107
  // The final cleanup is invoked by disposeChildren at true disposal.
108
108
  t.Je = e;
109
109
  } catch (e) {
110
- ext(t).F = new StatusError(t, e);
110
+ ext(t).U = new StatusError(t, e);
111
111
  t.m |= STATUS_ERROR;
112
- if (!globalQueue.notify(t, STATUS_ERROR, STATUS_ERROR)) {
113
- haltReactivity(e);
114
- throw e;
115
- }
112
+ escalate(t, e);
116
113
  } finally {
117
- t.ge = t.Ie;
114
+ t.ke = t.le;
118
115
  t.Ae = false;
119
116
  // The run applied: this is the frame now, so the dependency tail the
120
117
  // compute pass left linked goes (A30, #3438 — `recompute` defers an
@@ -160,7 +157,7 @@ GlobalQueue.K = runEffect;
160
157
  // Status dispatch rides the SHARED notifier (statusNotifierOf keys off
161
158
  // _type): its error arm is behavior-identical to the closure that used to
162
159
  // live here, without the per-node NodeExtension allocation.
163
- E.M = run;
160
+ E.Z = run;
164
161
  // The first run rides the heap like every wake (GlobalQueue._update), so a
165
162
  // tracked effect created inside a render-effect callback runs after that
166
163
  // pass's staged writes commit, not before.
@@ -1,4 +1,4 @@
1
- import { REACTIVE_RECOMPUTING_DEPS, CONFIG_AUTO_DISPOSE, STATUS_PENDING, REACTIVE_DISPOSED, REACTIVE_ZOMBIE, CONFIG_SLOT_NODE } from "./constants.js";
1
+ import { NewSet, REACTIVE_RECOMPUTING_DEPS, CONFIG_AUTO_DISPOSE, STATUS_PENDING, REACTIVE_DISPOSED, REACTIVE_ZOMBIE, CONFIG_SLOT_NODE } from "./constants.js";
2
2
 
3
3
  import { deleteFromHeap } from "./heap.js";
4
4
 
@@ -107,7 +107,7 @@ function unobserved(e) {
107
107
  * stays alive and serves its cache, uniform with observed memos) while
108
108
  * reclamation still happens within one microtask — the enqueue site arms
109
109
  * schedule(), so a flush is guaranteed even when no other work is queued.
110
- */ const dormantNodes = new Set;
110
+ */ const dormantNodes = new NewSet;
111
111
 
112
112
  function sweepDormant() {
113
113
  if (dormantNodes.size === 0) return;
@@ -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.Te = n.Ne;
136
+ o.de = n.Ne;
137
137
  n._ = o;
138
138
  return;
139
139
  }
@@ -144,14 +144,14 @@ function link(e, n) {
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
146
  const r = e.ve;
147
- if (r !== null && r.u === n && (!s || r.Te === n.Ne)) return;
147
+ if (r !== null && r.u === n && (!s || r.de === n.Ne)) return;
148
148
  const t = n._ = e.ve = {
149
149
  S: e,
150
150
  u: n,
151
151
  G: o,
152
152
  Xe: r,
153
153
  t: null,
154
- Te: 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,14 +11,14 @@ 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.Ge > e.Fe) dirtyQueue.Ge = e.Fe;
14
+ if (dirtyQueue.Fe > e.he) dirtyQueue.Fe = e.he;
15
15
  insertIntoHeap(e, dirtyQueue);
16
16
  }
17
17
 
18
18
  function actualInsertIntoHeap(e, t) {
19
- const E = (e._parent?.Qe ? e._parent.Ye?.Fe : e._parent?.Fe) ?? -1;
20
- if (E >= e.Fe) e.Fe = E + 1;
21
- const n = e.Fe;
19
+ const E = (e._parent?.Qe ? e._parent.Ye?.he : e._parent?.he) ?? -1;
20
+ if (E >= e.he) e.he = E + 1;
21
+ const n = e.he;
22
22
  const I = t.$e[n];
23
23
  if (I === undefined) t.$e[n] = e; else {
24
24
  const t = I.We;
@@ -65,7 +65,7 @@ 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.Fe;
68
+ const n = e.he;
69
69
  if (e.We === e) t.$e[n] = undefined; else {
70
70
  const E = e.be;
71
71
  const I = t.$e[n];
@@ -98,11 +98,11 @@ function markNode(e, t = REACTIVE_DIRTY) {
98
98
 
99
99
  function runHeap(e, t) {
100
100
  e.p = false;
101
- for (e.Ge = 0; e.Ge <= e.et; e.Ge++) {
102
- let E = e.$e[e.Ge];
101
+ for (e.Fe = 0; e.Fe <= e.et; e.Fe++) {
102
+ let E = e.$e[e.Fe];
103
103
  while (E !== undefined) {
104
104
  if (E.R & REACTIVE_IN_HEAP) t(E); else adjustHeight(E, e);
105
- E = e.$e[e.Ge];
105
+ E = e.$e[e.Fe];
106
106
  }
107
107
  }
108
108
  e.et = 0;
@@ -110,13 +110,13 @@ function runHeap(e, t) {
110
110
 
111
111
  function adjustHeight(e, t) {
112
112
  deleteFromHeap(e, t);
113
- let E = e.Fe;
113
+ let E = e.he;
114
114
  for (let t = e.C; t; t = t.G) {
115
115
  const e = t.S;
116
- if (e.X && e.Fe >= E) E = e.Fe + 1;
116
+ if (e.X && e.he >= E) E = e.he + 1;
117
117
  }
118
- if (e.Fe !== E) {
119
- e.Fe = E;
118
+ if (e.he !== E) {
119
+ e.he = E;
120
120
  for (let E = e.o; E !== null; E = E.t) insertIntoHeapHeight(E.u, t);
121
121
  }
122
122
  }