@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
@@ -0,0 +1,86 @@
1
+ import { CONFIG_VERDICT, CONFIG_AUTHORITATIVE, STATUS_ERROR, CONFIG_SLOT_NODE, REACTIVE_RECOMPUTING_DEPS } from "./core/constants.js";
2
+
3
+ import { ext } from "./core/core.js";
4
+
5
+ import { enqueueSub } from "./core/heap.js";
6
+
7
+ import { GlobalQueue } from "./core/scheduler.js";
8
+
9
+ // The mark core: a declared not-final state on a node that reads pending
10
+ // (`isPending` → true) on the node and everything derived from it, without
11
+ // holding anything or entangling a reader. Two declarers share it:
12
+ // `affects()` (affects.ts — a mark scoped to a transaction, with a store
13
+ // half) and `createDeferred` (deferred.ts — a mark whose lifetime is the
14
+ // node's own flight). Split out so the second does not ship the first.
15
+ // Representation: a count on the marked node (`_x._marks`). Coverage of the
16
+ // derivations is pull-derived at probe time — `isPending`'s read walks the
17
+ // probed node's dependencies for a marked one (verdict.ts → `_marked`) — so
18
+ // nothing is stored downstream and a mid-window recompute strands nothing.
19
+ // The push half is the verdict readers' re-derivation when a node's marks
20
+ // start and end (`repoll`): the only notification a mark makes.
21
+ /** Live marks, every declarer — the gate on the probe's walk. */
22
+ let active = 0;
23
+
24
+ /** The verdict readers downstream of `node` — through derivations, stopping
25
+ * at effects — re-derive: the mark's one notification (a probe's answer
26
+ * changed with no value notifying anyone). Truth readers (`until`, the
27
+ * `refresh` waiter) too, which a lagging flight parked (deferred.ts) — but
28
+ * not through a derived store, whose leaves change only once its derive
29
+ * re-runs: they re-derive at that write. */ function repoll(e, r = new Set, o = CONFIG_VERDICT | CONFIG_AUTHORITATIVE) {
30
+ for (let t = e.o; t !== null; t = t.t) {
31
+ const e = t.u;
32
+ if (r.has(e)) continue;
33
+ r.add(e);
34
+ if (e.l & o) enqueueSub(e);
35
+ if (!e.i) repoll(e, r, o);
36
+ // A derived store's derive: its leaves' readers derive from it too
37
+ // (store/projection.ts; a live target's property, has and keys nodes).
38
+ const n = e.fam;
39
+ if (n) for (const e of n.live) for (const o of [ e.n, e.h, {
40
+ k: e.k,
41
+ d: e.dk
42
+ } ]) if (o) for (const e of Reflect.ownKeys(o)) o[e] && repoll(o[e], r, CONFIG_VERDICT);
43
+ }
44
+ }
45
+
46
+ /** A node is covered by a live mark iff it carries one, or derives — through
47
+ * its current dependencies — from one that does. A store slot derives from
48
+ * its family's derive (a derived store's leaves are not the derive's
49
+ * dependents, store/projection.ts), so coverage hops there. A real error
50
+ * outranks an inherited mark (A24 (c)): coverage does not flow through an
51
+ * errored node (a direct mark on one still reads pending). Mid-recompute,
52
+ * only the validated prefix of the dependency list is this pass's. */ function marked(e, r) {
53
+ if (e.T !== null && e.T.I !== 0) return true;
54
+ const o = e;
55
+ if (o.m & STATUS_ERROR || r.has(e)) return false;
56
+ r.add(e);
57
+ if (o.l & CONFIG_SLOT_NODE) {
58
+ const e = o.O?.fam?.node;
59
+ return e != null && marked(e, r);
60
+ }
61
+ const t = o.R & REACTIVE_RECOMPUTING_DEPS ? o._ : undefined;
62
+ if (t !== null) for (let e = o.C ?? null; e !== null; e = e.G) {
63
+ if (marked(e.S, r)) return true;
64
+ if (e === t) break;
65
+ }
66
+ return false;
67
+ }
68
+
69
+ /** One mark on `node`. The declarer repolls once its bookkeeping is done. */ function mark(e) {
70
+ ext(e).I++;
71
+ active++;
72
+ }
73
+
74
+ /** Drops one mark from `node`: true when it was the last — the node's
75
+ * verdict readers have re-derived. */ function unmark(e) {
76
+ active--;
77
+ if (--e.T.I !== 0) return false;
78
+ repoll(e);
79
+ return true;
80
+ }
81
+
82
+ GlobalQueue.p = e => active !== 0 && marked(e, new Set);
83
+
84
+ GlobalQueue.N = mark;
85
+
86
+ export { mark, repoll, unmark };
@@ -1,10 +1,12 @@
1
- import { $REFRESH, CONFIG_VERDICT, STATUS_PENDING, CONFIG_SLOT_NODE, STATUS_ERROR, REACTIVE_RECOMPUTING_DEPS } from "./core/constants.js";
1
+ import { $REFRESH, STATUS_PENDING, CONFIG_SLOT_NODE } from "./core/constants.js";
2
2
 
3
- import { ext } from "./core/core.js";
3
+ import "./core/core.js";
4
4
 
5
- import { enqueueSub } from "./core/heap.js";
5
+ import { schedule, resolveTx, flushTransaction, installMarkHooks, GlobalQueue } from "./core/scheduler.js";
6
6
 
7
- import { GlobalQueue, schedule, resolveTx, flushTransaction } from "./core/scheduler.js";
7
+ import { mark, repoll, unmark } from "./affects-marks.js";
8
+
9
+ import { storeMarks, installStoreAffects, releaseMarkScope } from "./store/affects.js";
8
10
 
9
11
  import { $TARGET } from "./store/types.js";
10
12
 
@@ -19,60 +21,22 @@ import { $TARGET } from "./store/types.js";
19
21
  // a node of its transaction (`blocked` never sees it), and a reader of marked
20
22
  // data joins nothing through it. A mark is never a re-ask, so a declared
21
23
  // reload's own `refresh()` cannot silence it; a real error outranks it.
22
- // Representation: a count on the marked node (`_x._marks`), listed with its
23
- // scope (the transaction's `_marks`, or the ambient list). Coverage of the
24
- // derivations is pull-derived at probe time — `isPending`'s read walks the
25
- // probed node's dependencies for a marked one (verdict.ts → `_marked`) — so
26
- // nothing is stored downstream and a mid-window recompute strands nothing.
27
- // The push half is the verdict readers' re-derivation at registration and at
28
- // release (`repoll`): the only notification a mark makes.
24
+ // Representation: the mark core (affects-marks.ts) — a count on the marked
25
+ // node, coverage pull-derived at probe time, readers repolled at registration
26
+ // and release. Here: each mark's scope (the transaction's `_marks`, or the
27
+ // ambient list) and the store half.
29
28
  // Installed on `GlobalQueue` when imported: a program that never declares a
30
29
  // mark carries none of this.
31
- /** Live marks, every scope — the gate on the probe's walk. */
32
- let active = 0;
33
-
34
- /** Marks declared outside a transaction: released at the next seam. */ const ambient = [];
35
-
36
- /** The verdict readers downstream of `node` — through derivations, stopping
37
- * at effects — re-derive: the mark's one notification (a probe's answer
38
- * changed with no value notifying anyone). */ function repoll(e, t = new Set) {
39
- for (let n = e.t; n !== null; n = n.l) {
40
- const e = n.o;
41
- if (t.has(e)) continue;
42
- t.add(e);
43
- if (e.u & CONFIG_VERDICT) enqueueSub(e);
44
- if (!e.i) repoll(e, t);
45
- }
46
- }
47
-
48
- /** A node is covered by a live mark iff it carries one, or derives — through
49
- * its current dependencies — from one that does. A real error outranks an
50
- * inherited mark (A24 (c)): coverage does not flow through an errored node
51
- * (a direct mark on one still reads pending). Mid-recompute, only the
52
- * validated prefix of the dependency list is this pass's. */ function marked(e, t) {
53
- if (e.m !== null && e.m.T !== 0) return true;
54
- const n = e;
55
- if (n.G & STATUS_ERROR || t.has(e)) return false;
56
- t.add(e);
57
- const r = n.R & REACTIVE_RECOMPUTING_DEPS ? n.S : undefined;
58
- if (r !== null) for (let e = n._ ?? null; e !== null; e = e.p) {
59
- if (marked(e.I, t)) return true;
60
- if (e === r) break;
61
- }
62
- return false;
63
- }
30
+ /** Marks declared outside a transaction: released at the next seam. */
31
+ const ambient = [];
64
32
 
65
33
  /** Releases one scope's marks (a landed transaction's, the ambient list at
66
34
  * the seam): a node whose last mark drops re-derives its verdict readers. */ function release(e) {
67
35
  for (let t = 0; t < e.length; t++) {
68
- const n = e[t];
69
- active--;
70
- if (--n.m.T === 0) {
71
- repoll(n);
72
- // A store mark's carrier: its scope (and the marks the nodes born in
73
- // its window inherited) goes with it.
74
- GlobalQueue.N?.(n);
75
- }
36
+ const r = e[t];
37
+ // A store mark's carrier: its scope (and the marks the nodes born in
38
+ // its window inherited) goes with the last mark.
39
+ if (unmark(r)) releaseMarkScope(r);
76
40
  }
77
41
  e.length = 0;
78
42
  }
@@ -82,47 +46,37 @@ let active = 0;
82
46
  mark(e);
83
47
  const t = flushTransaction;
84
48
  if (t === null) ambient.push(e); else {
85
- const n = resolveTx(t);
86
- (n.T ??= []).push(e);
49
+ const r = resolveTx(t);
50
+ (r.I ??= []).push(e);
87
51
  }
88
52
  repoll(e);
89
53
  }
90
54
 
91
- function mark(e) {
92
- ext(e).T++;
93
- active++;
94
- }
95
-
96
55
  function affects(e, t) {
97
56
  // A store (the store half, store/affects.ts): the slot's leaf, or the
98
57
  // record's carrier and every live node under it.
99
- const n = e?.[$TARGET];
100
- if (n !== undefined) {
101
- const e = GlobalQueue.O(n, t);
58
+ const r = e?.[$TARGET];
59
+ if (r !== undefined) {
60
+ installStoreAffects();
61
+ const e = storeMarks(r, t);
102
62
  for (let t = 0; t < e.length; t++) register(e[t]);
103
63
  schedule();
104
64
  return;
105
65
  }
106
- const r = e?.[$REFRESH];
107
- if (!r) {
66
+ const s = e?.[$REFRESH];
67
+ if (!s) {
108
68
  return;
109
69
  }
110
- register(r);
70
+ register(s);
111
71
  schedule();
112
72
  }
113
73
 
114
- GlobalQueue.C = e => active !== 0 && marked(e, new Set);
115
-
116
- GlobalQueue.h = mark;
117
-
118
- GlobalQueue.A = release;
119
-
120
- GlobalQueue.D = e => {
74
+ installMarkHooks(release, e => {
121
75
  if (ambient.length === 0) return;
122
76
  // The flush parked: the declaration's window is the frame's — the marks
123
77
  // are its transaction's ("nothing async below ⇒ no window").
124
78
  if (e !== null) {
125
- const t = e.T ??= [];
79
+ const t = e.I ??= [];
126
80
  for (let e = 0; e < ambient.length; e++) t.push(ambient[e]);
127
81
  ambient.length = 0;
128
82
  return;
@@ -132,17 +86,17 @@ GlobalQueue.D = e => {
132
86
  // the window is the flight's; the mark stays to the seam after the
133
87
  // landing. The rest release: verdict-only, nothing to show.
134
88
  let t = 0;
135
- const n = [];
89
+ const r = [];
136
90
  for (let e = 0; e < ambient.length; e++) {
137
- const r = ambient[e];
138
- if (inFlight(r)) ambient[t++] = r; else n.push(r);
91
+ const s = ambient[e];
92
+ if (inFlight(s)) ambient[t++] = s; else r.push(s);
139
93
  }
140
94
  ambient.length = t;
141
- if (n.length !== 0) release(n);
142
- };
95
+ if (r.length !== 0) release(r);
96
+ });
143
97
 
144
98
  function inFlight(e) {
145
- return (e.G & STATUS_PENDING) !== 0 || (e.u & CONFIG_SLOT_NODE) !== 0 && GlobalQueue.F?.(e) === true;
99
+ return (e.m & STATUS_PENDING) !== 0 || (e.l & CONFIG_SLOT_NODE) !== 0 && GlobalQueue.k?.(e) === true;
146
100
  }
147
101
 
148
102
  export { affects };