@solidjs/signals 2.0.0-beta.9 → 2.0.0-rc.1

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 (106) hide show
  1. package/README.md +14 -10
  2. package/dist/dev.js +6740 -2011
  3. package/dist/node.cjs +7927 -3340
  4. package/dist/prod/affects.js +126 -0
  5. package/dist/prod/boundaries.js +572 -0
  6. package/dist/prod/core/action.js +139 -0
  7. package/dist/prod/core/async.js +607 -0
  8. package/dist/prod/core/constants.js +92 -0
  9. package/dist/prod/core/context.js +67 -0
  10. package/dist/prod/core/core.js +828 -0
  11. package/dist/prod/core/dev.js +3 -0
  12. package/dist/prod/core/effect.js +145 -0
  13. package/dist/prod/core/error.js +68 -0
  14. package/dist/prod/core/external.js +98 -0
  15. package/dist/prod/core/graph.js +104 -0
  16. package/dist/prod/core/heap.js +140 -0
  17. package/dist/prod/core/invariants.js +42 -0
  18. package/dist/prod/core/lanes.js +140 -0
  19. package/dist/prod/core/optimistic.js +262 -0
  20. package/dist/prod/core/owner.js +302 -0
  21. package/dist/prod/core/scheduler.js +757 -0
  22. package/dist/prod/core/verdict.js +369 -0
  23. package/dist/prod/index.js +45 -0
  24. package/dist/prod/map.js +319 -0
  25. package/dist/prod/signals.js +394 -0
  26. package/dist/prod/store/index.js +36 -0
  27. package/dist/prod/store/next/optimistic.js +377 -0
  28. package/dist/prod/store/next/projection.js +172 -0
  29. package/dist/prod/store/next/reconcile.js +327 -0
  30. package/dist/prod/store/next/store.js +1232 -0
  31. package/dist/prod/store/next/target.js +20 -0
  32. package/dist/prod/store/store.js +325 -0
  33. package/dist/prod/store/storePath.js +103 -0
  34. package/dist/prod/store/utils.js +201 -0
  35. package/dist/types/affects.d.ts +47 -0
  36. package/dist/types/boundaries.d.ts +60 -13
  37. package/dist/types/core/action.d.ts +35 -6
  38. package/dist/types/core/async.d.ts +16 -1
  39. package/dist/types/core/constants.d.ts +35 -6
  40. package/dist/types/core/context.d.ts +10 -2
  41. package/dist/types/core/core.d.ts +66 -63
  42. package/dist/types/core/dev.d.ts +17 -2
  43. package/dist/types/core/effect.d.ts +1 -2
  44. package/dist/types/core/error.d.ts +33 -0
  45. package/dist/types/core/external.d.ts +0 -11
  46. package/dist/types/core/graph.d.ts +2 -1
  47. package/dist/types/core/heap.d.ts +8 -0
  48. package/dist/types/core/index.d.ts +3 -2
  49. package/dist/types/core/invariants.d.ts +59 -0
  50. package/dist/types/core/lanes.d.ts +2 -0
  51. package/dist/types/core/optimistic.d.ts +6 -0
  52. package/dist/types/core/owner.d.ts +50 -3
  53. package/dist/types/core/scheduler.d.ts +85 -11
  54. package/dist/types/core/types.d.ts +66 -1
  55. package/dist/types/core/verdict.d.ts +2 -0
  56. package/dist/types/index.d.ts +3 -2
  57. package/dist/types/map.d.ts +21 -5
  58. package/dist/types/signals.d.ts +183 -12
  59. package/dist/types/store/index.d.ts +16 -6
  60. package/dist/types/store/next/optimistic.d.ts +20 -0
  61. package/dist/types/store/next/projection.d.ts +24 -0
  62. package/dist/types/store/next/reconcile.d.ts +3 -0
  63. package/dist/types/store/next/store.d.ts +71 -0
  64. package/dist/types/store/next/target.d.ts +99 -0
  65. package/dist/types/store/optimistic.d.ts +3 -3
  66. package/dist/types/store/projection.d.ts +10 -6
  67. package/dist/types/store/reconcile.d.ts +31 -8
  68. package/dist/types/store/store.d.ts +91 -71
  69. package/dist/types/store/utils.d.ts +0 -40
  70. package/dist/types-cjs/affects.d.cts +47 -0
  71. package/dist/types-cjs/boundaries.d.cts +60 -13
  72. package/dist/types-cjs/core/action.d.cts +35 -6
  73. package/dist/types-cjs/core/async.d.cts +16 -1
  74. package/dist/types-cjs/core/constants.d.cts +35 -6
  75. package/dist/types-cjs/core/context.d.cts +10 -2
  76. package/dist/types-cjs/core/core.d.cts +66 -63
  77. package/dist/types-cjs/core/dev.d.cts +17 -2
  78. package/dist/types-cjs/core/effect.d.cts +1 -2
  79. package/dist/types-cjs/core/error.d.cts +33 -0
  80. package/dist/types-cjs/core/external.d.cts +0 -11
  81. package/dist/types-cjs/core/graph.d.cts +2 -1
  82. package/dist/types-cjs/core/heap.d.cts +8 -0
  83. package/dist/types-cjs/core/index.d.cts +3 -2
  84. package/dist/types-cjs/core/invariants.d.cts +59 -0
  85. package/dist/types-cjs/core/lanes.d.cts +2 -0
  86. package/dist/types-cjs/core/optimistic.d.cts +6 -0
  87. package/dist/types-cjs/core/owner.d.cts +50 -3
  88. package/dist/types-cjs/core/scheduler.d.cts +85 -11
  89. package/dist/types-cjs/core/types.d.cts +66 -1
  90. package/dist/types-cjs/core/verdict.d.cts +2 -0
  91. package/dist/types-cjs/index.d.cts +3 -2
  92. package/dist/types-cjs/map.d.cts +21 -5
  93. package/dist/types-cjs/signals.d.cts +183 -12
  94. package/dist/types-cjs/store/index.d.cts +16 -6
  95. package/dist/types-cjs/store/next/optimistic.d.cts +20 -0
  96. package/dist/types-cjs/store/next/projection.d.cts +24 -0
  97. package/dist/types-cjs/store/next/reconcile.d.cts +3 -0
  98. package/dist/types-cjs/store/next/store.d.cts +71 -0
  99. package/dist/types-cjs/store/next/target.d.cts +99 -0
  100. package/dist/types-cjs/store/optimistic.d.cts +3 -3
  101. package/dist/types-cjs/store/projection.d.cts +10 -6
  102. package/dist/types-cjs/store/reconcile.d.cts +31 -8
  103. package/dist/types-cjs/store/store.d.cts +91 -71
  104. package/dist/types-cjs/store/utils.d.cts +0 -40
  105. package/package.json +12 -9
  106. package/dist/prod.js +0 -3627
@@ -0,0 +1,319 @@
1
+ import { computed, runWithOwner, signal, setSignal } from "./core/core.js";
2
+
3
+ import { createOwner } from "./core/owner.js";
4
+
5
+ import "./core/scheduler.js";
6
+
7
+ import { CONFIG_AUTO_DISPOSE } from "./core/constants.js";
8
+
9
+ import "./core/invariants.js";
10
+
11
+ import "./core/verdict.js";
12
+
13
+ import "./core/effect.js";
14
+
15
+ import { accessor } from "./signals.js";
16
+
17
+ import { $TRACK } from "./store/store.js";
18
+
19
+ import "./store/next/store.js";
20
+
21
+ function mapArray(t, s, i) {
22
+ const e = typeof i?.keyed === "function" ? i.keyed : undefined;
23
+ const r = s.length > 1;
24
+ const n = s;
25
+ const h = {
26
+ wt: createOwner(),
27
+ jt: 0,
28
+ Wt: t,
29
+ Mt: [],
30
+ xt: n,
31
+ Kt: [],
32
+ Ft: [],
33
+ Ut: e,
34
+ $t: e || i?.keyed === false ? [] : undefined,
35
+ qt: r && i?.keyed !== false ? [] : undefined,
36
+ zt: i?.keyed === false,
37
+ Bt: i?.fallback
38
+ };
39
+ const o = computed(updateKeyedMap.bind(h));
40
+ // Untracked reads inside the internal owner resolve via _parentComputed; routing
41
+ // them through node lets store-proxy lookups see pending writes (not stale _value).
42
+ h.wt.It = o;
43
+ o.T &= ~CONFIG_AUTO_DISPOSE;
44
+ return accessor(o);
45
+ }
46
+
47
+ const pureOptions = {
48
+ ownedWrite: true
49
+ };
50
+
51
+ // Exception safety (#2903): a map callback can throw NotReadyError mid-pass
52
+ // (async read), and the computed re-runs the whole pass after settle. Every
53
+ // pass therefore STAGES its work — new rows are created into temp arrays and
54
+ // removals are deferred — and commits to `this` only after every mapper
55
+ // succeeded. An aborted pass disposes just the owners it created and leaves
56
+ // `_items`/`_mappings`/`_nodes`/`_rows`/`_indexes`/`_len` exactly as they
57
+ // were, so the retry diffs against uncorrupted state. Consequence of the
58
+ // strong-abort ordering: removed rows now dispose AFTER the pass's new rows
59
+ // are created (you cannot destroy state before knowing the pass will land).
60
+ function updateKeyedMap() {
61
+ const t = this.Wt() || [], s = t.length;
62
+ t[$TRACK];
63
+ // top level tracking
64
+ runWithOwner(this.wt, () => {
65
+ let i, e, r, n,
66
+ // Mappers write freshly-created row/index signals into the STAGE
67
+ // arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
68
+ h = this.$t ? this.zt ? () => {
69
+ r[e] = signal(t[e], pureOptions);
70
+ return this.xt(accessor(r[e]), e);
71
+ } : () => {
72
+ r[e] = signal(t[e], pureOptions);
73
+ n && (n[e] = signal(e, pureOptions));
74
+ return this.xt(accessor(r[e]), n ? accessor(n[e]) : undefined);
75
+ } : this.qt ? () => {
76
+ const s = t[e];
77
+ n[e] = signal(e, pureOptions);
78
+ return this.xt(s, accessor(n[e]));
79
+ } : () => {
80
+ const s = t[e];
81
+ return this.xt(s);
82
+ };
83
+ // fast path for empty arrays
84
+ if (s === 0) {
85
+ if (this.jt !== 0) {
86
+ this.wt.dispose(false);
87
+ this.Ft = [];
88
+ this.Mt = [];
89
+ this.Kt = [];
90
+ this.jt = 0;
91
+ this.$t && (this.$t = []);
92
+ this.qt && (this.qt = []);
93
+ }
94
+ if (this.Bt && !this.Kt[0]) {
95
+ // an aborted fallback attempt leaves an owner without a mapping;
96
+ // dispose it before re-creating
97
+ this.Ft[0]?.dispose();
98
+ this.Kt[0] = runWithOwner(this.Ft[0] = createOwner(), this.Bt);
99
+ }
100
+ }
101
+ // fast path for new create
102
+ else if (this.jt === 0) {
103
+ const o = new Array(s);
104
+ const c = new Array(s);
105
+ r = this.$t && new Array(s);
106
+ n = this.qt && new Array(s);
107
+ try {
108
+ for (e = 0; e < s; e++) o[e] = runWithOwner(c[e] = createOwner(), h);
109
+ } catch (t) {
110
+ for (i = 0; i <= e; i++) c[i]?.dispose();
111
+ throw t;
112
+ }
113
+ // commit
114
+ if (this.Ft[0]) this.Ft[0].dispose();
115
+ // previous fallback
116
+ this.Kt = o;
117
+ this.Ft = c;
118
+ r && (this.$t = r);
119
+ n && (this.qt = n);
120
+ this.Mt = t.slice(0);
121
+ this.jt = s;
122
+ } else {
123
+ let o, c, a, f, u, p, w, l, d;
124
+ // skip common prefix
125
+ for (o = 0, c = Math.min(this.jt, s); o < c && (this.Mt[o] === t[o] || this.$t && compare(this.Ut, this.Mt[o], t[o])); o++) {
126
+ if (this.$t) setSignal(this.$t[o], t[o]);
127
+ }
128
+ // skip common suffix — counted only; retained entries land in one pass
129
+ // at commit instead of being staged and copied twice
130
+ for (c = this.jt - 1, a = s - 1; c >= o && a >= o && (this.Mt[c] === t[a] || this.$t && compare(this.Ut, this.Mt[c], t[a])); c--,
131
+ a--) ;
132
+ // no structural change (every position matched in place at equal
133
+ // length — the common post-reconcile shape): keep the same mapped
134
+ // array identity so downstream consumers don't re-run at all
135
+ if (o === s && this.jt === s) {
136
+ this.Mt = t.slice(0);
137
+ return;
138
+ }
139
+ const O = s - this.jt;
140
+ const m = new Array(s);
141
+ const _ = new Array(s);
142
+ r = this.$t ? new Array(s) : undefined;
143
+ n = this.qt ? new Array(s) : undefined;
144
+ // 0) prepare a map of all indices in the changed window of newItems,
145
+ // scanning backwards so we encounter them in natural order
146
+ p = new Map;
147
+ w = new Array(a + 1);
148
+ for (e = a; e >= o; e--) {
149
+ f = t[e];
150
+ u = this.Ut ? this.Ut(f) : f;
151
+ i = p.get(u);
152
+ w[e] = i === undefined ? -1 : i;
153
+ p.set(u, e);
154
+ }
155
+ // 1) step through the old changed window and see if items can be found
156
+ // in the new set; if so, stage them at their new positions; if not,
157
+ // queue them for disposal at commit
158
+ for (i = o; i <= c; i++) {
159
+ f = this.Mt[i];
160
+ u = this.Ut ? this.Ut(f) : f;
161
+ e = p.get(u);
162
+ if (e !== undefined && e !== -1) {
163
+ m[e] = this.Kt[i];
164
+ _[e] = this.Ft[i];
165
+ r && (r[e] = this.$t[i]);
166
+ n && (n[e] = this.qt[i]);
167
+ e = w[e];
168
+ p.set(u, e);
169
+ } else (l ??= []).push(this.Ft[i]);
170
+ }
171
+ // 2) create new rows into the temp arrays; an abort disposes only these
172
+ try {
173
+ for (e = o; e <= a; e++) {
174
+ if (_[e] !== undefined) continue;
175
+ (d ??= []).push(_[e] = createOwner());
176
+ m[e] = runWithOwner(_[e], h);
177
+ }
178
+ } catch (t) {
179
+ if (d) for (i = 0; i < d.length; i++) d[i].dispose();
180
+ throw t;
181
+ }
182
+ // 3) commit: land the retained prefix and suffix plus the staged window
183
+ // into the fresh arrays, swap them in (new identity for downstream
184
+ // change propagation), then dispose exited rows
185
+ for (i = 0; i < o; i++) {
186
+ m[i] = this.Kt[i];
187
+ _[i] = this.Ft[i];
188
+ r && (r[i] = this.$t[i]);
189
+ n && (n[i] = this.qt[i]);
190
+ }
191
+ for (e = o; e <= a; e++) {
192
+ if (r) setSignal(r[e], t[e]);
193
+ if (n) setSignal(n[e], e);
194
+ }
195
+ for (e = a + 1; e < s; e++) {
196
+ m[e] = this.Kt[e - O];
197
+ _[e] = this.Ft[e - O];
198
+ if (r) {
199
+ r[e] = this.$t[e - O];
200
+ setSignal(r[e], t[e]);
201
+ }
202
+ if (n) {
203
+ n[e] = this.qt[e - O];
204
+ if (O !== 0) setSignal(n[e], e);
205
+ }
206
+ }
207
+ this.Kt = m;
208
+ this.Ft = _;
209
+ r && (this.$t = r);
210
+ n && (this.qt = n);
211
+ this.jt = s;
212
+ // save a copy of the mapped items for the next update
213
+ this.Mt = t.slice(0);
214
+ if (l) for (i = 0; i < l.length; i++) l[i].dispose();
215
+ }
216
+ });
217
+ return this.Kt;
218
+ }
219
+
220
+ /**
221
+ * Reactively renders a callback `count` times, reusing previously-rendered
222
+ * entries when only the count changes. Underlying helper for `<Repeat>`.
223
+ *
224
+ * - `options.from` — start index (default `0`); useful for offset/windowed
225
+ * rendering.
226
+ * - `options.fallback` — accessor returning a value to show when count is `0`.
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * const view = repeat(count, i => `Item ${i}`, { fallback: () => "empty" });
231
+ * ```
232
+ *
233
+ * @description https://docs.solidjs.com/reference/reactive-utilities/repeat
234
+ */ function repeat(t, s, i) {
235
+ const e = s;
236
+ const r = {
237
+ wt: createOwner(),
238
+ jt: 0,
239
+ Ht: 0,
240
+ Jt: t,
241
+ xt: e,
242
+ Ft: [],
243
+ Kt: [],
244
+ Vt: i?.from,
245
+ Bt: i?.fallback
246
+ };
247
+ const n = computed(updateRepeat.bind(r));
248
+ // Same as mapArray: untracked reads inside the internal owner resolve via
249
+ // _parentComputed, so async reads in row callbacks register with the node
250
+ // (pending tracking + post-settle retry) instead of vanishing.
251
+ r.wt.It = n;
252
+ n.T &= ~CONFIG_AUTO_DISPOSE;
253
+ return accessor(n);
254
+ }
255
+
256
+ // Same staged-commit discipline as `updateKeyedMap` (#2903): the retained
257
+ // window overlap is copied into fresh arrays, missing indexes are created
258
+ // into them, and `this` is only touched — including disposal of rows leaving
259
+ // the window — after every `_map` call succeeded. A NotReadyError mid-pass
260
+ // disposes only the owners this pass created and leaves prior state intact
261
+ // for the post-settle retry. The overlap math also subsumes the previous
262
+ // disjoint-window/front-clear/end-clear/shift special cases.
263
+ function updateRepeat() {
264
+ const t = this.Jt();
265
+ const s = this.Vt?.() || 0;
266
+ runWithOwner(this.wt, () => {
267
+ if (t === 0) {
268
+ if (this.jt !== 0) {
269
+ this.wt.dispose(false);
270
+ this.Ft = [];
271
+ this.Kt = [];
272
+ this.jt = 0;
273
+ // Reset offset to match the cleared data (#2767, repro 2).
274
+ this.Ht = 0;
275
+ }
276
+ if (this.Bt && !this.Kt[0]) {
277
+ // an aborted fallback attempt leaves an owner without a mapping;
278
+ // dispose it before re-creating
279
+ this.Ft[0]?.dispose();
280
+ this.Kt[0] = runWithOwner(this.Ft[0] = createOwner(), this.Bt);
281
+ }
282
+ return;
283
+ }
284
+ const i = s + t;
285
+ const e = this.Ht + this.jt;
286
+ // Retained overlap [keepStart, keepEnd) in global indexes; empty when the
287
+ // windows are disjoint or when coming from empty/fallback.
288
+ const r = Math.max(s, this.Ht);
289
+ const n = Math.min(i, e);
290
+ const h = new Array(t);
291
+ const o = new Array(t);
292
+ for (let t = r; t < n; t++) {
293
+ o[t - s] = this.Ft[t - this.Ht];
294
+ h[t - s] = this.Kt[t - this.Ht];
295
+ }
296
+ try {
297
+ for (let t = s; t < i; t++) {
298
+ if (t >= r && t < n) continue;
299
+ h[t - s] = runWithOwner(o[t - s] = createOwner(), () => this.xt(t));
300
+ }
301
+ } catch (t) {
302
+ for (let t = s; t < i; t++) if ((t < r || t >= n) && o[t - s]) o[t - s].dispose();
303
+ throw t;
304
+ }
305
+ // commit: dispose the previous fallback or the rows leaving the window
306
+ if (this.jt === 0) this.Ft[0]?.dispose(); else for (let t = this.Ht; t < e; t++) if (t < s || t >= i) this.Ft[t - this.Ht].dispose();
307
+ this.Kt = h;
308
+ this.Ft = o;
309
+ this.Ht = s;
310
+ this.jt = t;
311
+ });
312
+ return this.Kt;
313
+ }
314
+
315
+ function compare(t, s, i) {
316
+ return t ? t(s) === t(i) : true;
317
+ }
318
+
319
+ export { mapArray, repeat };