@solidjs/signals 2.0.0-rc.16 → 2.0.0-rc.18

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 (56) hide show
  1. package/dist/dev-shared.js +1972 -1751
  2. package/dist/dev.attribution.js +16 -16
  3. package/dist/dev.js +672 -319
  4. package/dist/observe/boundaries.js +2 -2
  5. package/dist/observe/core/async.js +151 -116
  6. package/dist/observe/core/constants.js +3 -1
  7. package/dist/observe/core/context.js +2 -0
  8. package/dist/observe/core/core.js +51 -35
  9. package/dist/observe/core/effect.js +29 -30
  10. package/dist/observe/core/graph.js +13 -11
  11. package/dist/observe/core/lanes.js +25 -14
  12. package/dist/observe/core/owner.js +77 -51
  13. package/dist/observe/core/scheduler.js +202 -175
  14. package/dist/observe/core/verdict.js +5 -2
  15. package/dist/observe/deferred.js +16 -13
  16. package/dist/observe/from.js +248 -0
  17. package/dist/observe/index.js +2 -0
  18. package/dist/observe/map.js +2 -2
  19. package/dist/observe/signals.js +6 -1
  20. package/dist/observe/store/affects.js +13 -13
  21. package/dist/observe/store/optimistic.js +112 -71
  22. package/dist/observe/store/reconcile.js +137 -121
  23. package/dist/observe/store/store.js +612 -626
  24. package/dist/observe/store/target.js +1 -5
  25. package/dist/prod/boundaries.js +2 -2
  26. package/dist/prod/core/async.js +211 -176
  27. package/dist/prod/core/constants.js +3 -1
  28. package/dist/prod/core/context.js +2 -0
  29. package/dist/prod/core/core.js +63 -47
  30. package/dist/prod/core/effect.js +24 -25
  31. package/dist/prod/core/graph.js +12 -10
  32. package/dist/prod/core/heap.js +1 -1
  33. package/dist/prod/core/lanes.js +39 -28
  34. package/dist/prod/core/owner.js +70 -44
  35. package/dist/prod/core/scheduler.js +78 -51
  36. package/dist/prod/core/truth.js +4 -4
  37. package/dist/prod/core/verdict.js +11 -8
  38. package/dist/prod/deferred.js +17 -14
  39. package/dist/prod/from.js +248 -0
  40. package/dist/prod/index.js +2 -0
  41. package/dist/prod/map.js +2 -2
  42. package/dist/prod/signals.js +18 -13
  43. package/dist/prod/store/optimistic.js +112 -71
  44. package/dist/prod/store/reconcile.js +137 -121
  45. package/dist/prod/store/store.js +109 -121
  46. package/dist/prod/store/target.js +13 -17
  47. package/dist/types/core/async.d.ts +12 -2
  48. package/dist/types/core/constants.d.ts +5 -0
  49. package/dist/types/core/core.d.ts +29 -6
  50. package/dist/types/core/dev.d.ts +9 -1
  51. package/dist/types/core/error.d.ts +9 -1
  52. package/dist/types/core/owner.d.ts +4 -0
  53. package/dist/types/core/scheduler.d.ts +38 -7
  54. package/dist/types/from.d.ts +47 -0
  55. package/dist/types/index.d.ts +1 -0
  56. package/package.json +1 -1
@@ -1,12 +1,12 @@
1
- import { CONFIG_OVERRIDE, CONFIG_AUTO_DISPOSE, NOT_PENDING } from "../core/constants.js";
1
+ import { CONFIG_OVERRIDE, CONFIG_GUESS, EFFECT_RENDER, CONFIG_CHILDREN_FORBIDDEN, NOT_PENDING, CONFIG_SLOT_NODE, CONFIG_AUTO_DISPOSE } from "../core/constants.js";
2
2
 
3
- import { computed, ext, untrack, read, isEqual } from "../core/core.js";
3
+ import { computed, joinPassAt, ext, untrack, read, isEqual } from "../core/core.js";
4
4
 
5
5
  import { pendingGuessOf, optimisticWrite } from "../core/lanes.js";
6
6
 
7
7
  import { getOwner } from "../core/owner.js";
8
8
 
9
- import { GlobalQueue, txOf, list, insertSubs, laneDirty, notifyEpoch, schedule } from "../core/scheduler.js";
9
+ import { GlobalQueue, txOf, insertSubs, joinFuture, resolveTx, passLane, list, laneDirty, notifyEpoch, schedule } from "../core/scheduler.js";
10
10
 
11
11
  import { runProjectionComputed } from "./projection.js";
12
12
 
@@ -93,16 +93,16 @@ function notifyOptimisticWrites(e, n) {
93
93
  // A chained draft holds the inner store's raws; a raw is the inner slot it
94
94
  // resolves to (as a read of it serves) — the row a held write staged is
95
95
  // the same row, not a guess over the slot (#3796).
96
- const a = n[t];
97
- const f = unwrapValue(o && a ? resolveChainedRaw(e, t, a) : a);
96
+ const u = n[t];
97
+ const f = unwrapValue(o && u ? resolveChainedRaw(e, t, u) : u);
98
98
  if (!(t in i)) {
99
99
  guess(getNode(e, t), t, false, f);
100
100
  guess(getHasNode(e, t), t, true, true);
101
101
  s = true;
102
102
  } else {
103
103
  const n = i[t];
104
- const a = unwrapValue(o && n ? resolveChainedRaw(e, t, n) : n);
105
- if (!isEqual(a, f) && !targetsEqual(a, f)) {
104
+ const u = unwrapValue(o && n ? resolveChainedRaw(e, t, n) : n);
105
+ if (!isEqual(u, f) && !targetsEqual(u, f)) {
106
106
  guess(getNode(e, t), t, false, f);
107
107
  if (r) s = true;
108
108
  }
@@ -122,29 +122,31 @@ function notifyOptimisticWrites(e, n) {
122
122
  if (s) {
123
123
  const o = r ? n.map(unwrapValue) : shallowKeys(n);
124
124
  // The rows the setter removed from the view it saw, by key: a later
125
- // re-base over another action's truth must not bring them back.
125
+ // re-base over another action's truth must not bring them back. A set
126
+ // (empty or not) marks a keyed arrangement guess (`fold`).
126
127
  let s = null;
127
- const a = e.fam.key;
128
- if (r && a !== null && a !== undefined) {
128
+ const u = e.fam.key;
129
+ if (r && u !== null && u !== undefined) {
130
+ s = new Set;
129
131
  const e = new Set;
130
132
  for (let n = 0; n < o.length; n++) {
131
- const t = isWrappable(o[n]) ? a(o[n]) : undefined;
133
+ const t = isWrappable(o[n]) ? u(o[n]) : undefined;
132
134
  if (t !== undefined) e.add(t);
133
135
  }
134
136
  for (let n = 0; n < i.length; n++) {
135
137
  const t = unwrapValue(i[n]);
136
- const r = isWrappable(t) ? a(t) : undefined;
137
- if (r !== undefined && !e.has(r)) (s ??= new Set).add(r);
138
+ const r = isWrappable(t) ? u(t) : undefined;
139
+ if (r !== undefined && !e.has(r)) s.add(r);
138
140
  }
139
141
  }
140
142
  optimisticWrite(getContainerNode(e), new LaneView(o, t, s));
141
143
  }
142
144
  if (e.dk !== null) optimisticWrite(e.dk, {});
143
145
  markOverlaid(e);
144
- const a = optStaged.get(e);
145
- if (a === undefined) return null;
146
+ const u = optStaged.get(e);
147
+ if (u === undefined) return null;
146
148
  optStaged.delete(e);
147
- return a;
149
+ return u;
148
150
  }
149
151
 
150
152
  /** The container comparator's lane arm (store.ts `containerEquals`): an
@@ -228,18 +230,18 @@ function arrangementEqual(e, n, t) {
228
230
  }
229
231
  }
230
232
  for (let s = 0; s < n.length; s++) {
231
- const a = n[s];
233
+ const u = n[s];
232
234
  let f;
233
- if (isWrappable(a)) {
235
+ if (isWrappable(u)) {
234
236
  if (o !== null) {
235
- const e = t(a);
237
+ const e = t(u);
236
238
  if (e !== undefined) f = o.get(e);
237
239
  } else if (s < i && isWrappable(unwrapValue(r[s]))) f = r[s];
238
240
  }
239
241
  if (f !== undefined) {
240
- if (unwrapValue(f) !== a) reconcileDraft(f, a, t);
242
+ if (unwrapValue(f) !== u) reconcileDraft(f, u, t);
241
243
  if (e[s] !== f) e[s] = f;
242
- } else if (unwrapValue(e[s]) !== a) e[s] = a;
244
+ } else if (unwrapValue(e[s]) !== u) e[s] = u;
243
245
  }
244
246
  if (e.length !== n.length) e.length = n.length;
245
247
  return;
@@ -268,66 +270,105 @@ function arrangementEqual(e, n, t) {
268
270
  * node is born for it as the lane's derivation), on `length` only when the
269
271
  * committed length differs, and as the `LaneView`'s base for structural
270
272
  * reads. Unkeyed families compose
271
- * positionally — the guess stands as written (the documented residue). */ GlobalQueue.an = (e, n) => {
272
- const t = e.O;
273
- if (t === undefined || e.Vt !== $TRACK) return;
274
- const i = e.T.V;
275
- if (!(i instanceof LaneView)) return;
276
- if (!Array.isArray(n) || !Array.isArray(i.rows)) {
277
- i.base = n;
273
+ * positionally — the guess stands as written (the documented residue). */ GlobalQueue.an = (e, n, t) => {
274
+ if (!t) return fold(e, n);
275
+ const i = e.O;
276
+ if (i === undefined || e.Vt !== $TRACK) return;
277
+ const r = e.T.V;
278
+ if (!(r instanceof LaneView)) return;
279
+ if (!Array.isArray(n) || !Array.isArray(r.rows)) {
280
+ r.base = n;
278
281
  return;
279
282
  }
280
- const r = t.fam?.key ?? null;
281
- if (r === null) return;
282
- const o = new Map;
283
+ const o = i.fam?.key ?? null;
284
+ if (o === null) return;
285
+ const s = new Map;
283
286
  for (let e = 0; e < n.length; e++) {
284
287
  const t = n[e];
285
- const i = isWrappable(t) ? r(t) : undefined;
286
- if (i !== undefined && !o.has(i)) o.set(i, t);
288
+ const i = isWrappable(t) ? o(t) : undefined;
289
+ if (i !== undefined && !s.has(i)) s.set(i, t);
287
290
  }
288
- const s = new Set;
289
- const a = [];
290
- const f = i.rows;
291
- for (let e = 0; e < f.length; e++) {
292
- const n = f[e];
293
- const t = isWrappable(n) ? r(n) : undefined;
294
- const i = t !== undefined ? o.get(t) : undefined;
291
+ const u = new Set;
292
+ const f = [];
293
+ const a = r.rows;
294
+ for (let e = 0; e < a.length; e++) {
295
+ const n = a[e];
296
+ const t = isWrappable(n) ? o(n) : undefined;
297
+ const i = t !== undefined ? s.get(t) : undefined;
295
298
  if (i !== undefined) {
296
- a.push(i);
297
- s.add(t);
298
- } else a.push(n);
299
+ f.push(i);
300
+ u.add(t);
301
+ } else f.push(n);
299
302
  }
300
- const u = i.removed;
303
+ const l = r.removed;
301
304
  for (let e = 0; e < n.length; e++) {
302
305
  const t = n[e];
303
- const i = isWrappable(t) ? r(t) : undefined;
304
- if (i !== undefined && !s.has(i) && (u === null || !u.has(i))) a.push(t);
306
+ const i = isWrappable(t) ? o(t) : undefined;
307
+ if (i !== undefined && !u.has(i) && (l === null || !l.has(i))) f.push(t);
305
308
  }
306
- i.rows = a;
307
- i.base = a;
308
- const l = txOf(e);
309
- const c = committed(t);
310
- const d = t.n;
311
- for (let e = 0; e < a.length; e++) {
312
- const n = d?.[e];
309
+ r.rows = f;
310
+ r.base = f;
311
+ const c = txOf(e);
312
+ const d = committed(i);
313
+ const p = i.n;
314
+ for (let e = 0; e < f.length; e++) {
315
+ const n = p?.[e];
313
316
  // A slot the lane does not own shows the committed row: it becomes the
314
317
  // lane's only where the composed row is another row (by key — the same
315
318
  // key's new object is the same row, its target adopted it).
316
319
  if (n === undefined) {
317
- if (!sameRow(c[e], a[e], r)) laneSet(getNode(t, e), a[e], l);
318
- } else if (!sameRow(n.l & CONFIG_OVERRIDE ? n.T.V : c[e], a[e], r)) laneSet(n, a[e], l);
320
+ if (!sameRow(d[e], f[e], o)) laneSet(getNode(i, e), f[e], c);
321
+ } else if (!sameRow(n.l & CONFIG_OVERRIDE ? n.T.V : d[e], f[e], o)) laneSet(n, f[e], c);
319
322
  }
320
- if (d !== null) {
321
- for (let e = a.length; ;e++) {
322
- const n = d[e];
323
+ if (p !== null) {
324
+ for (let e = f.length; ;e++) {
325
+ const n = p[e];
323
326
  if (n === undefined) break;
324
- laneSet(n, undefined, l);
327
+ laneSet(n, undefined, c);
325
328
  }
326
- const e = d.length;
327
- if (e !== undefined && (e.l & CONFIG_OVERRIDE || c.length !== a.length)) laneSet(e, a.length, l);
329
+ const e = p.length;
330
+ if (e !== undefined && (e.l & CONFIG_OVERRIDE || d.length !== f.length)) laneSet(e, f.length, c);
328
331
  }
329
332
  };
330
333
 
334
+ /** D-34 for a keyed arrangement guess: rows by key, not positions. A
335
+ * current truth that differs folds into the hold beneath it instead of
336
+ * voiding the lane: the guess stays the lane's value and the screen's until
337
+ * the hold commits, where rows match by key, and the graph outside the lane
338
+ * re-derives from the truth now (`foldedRead`). A confirmation is silent
339
+ * (A17): only truth readers are told. True: the lane stages the truth
340
+ * beneath (`laneWrite`). */ function fold(e, n) {
341
+ const t = e.O?.k;
342
+ const i = txOf(e);
343
+ // A guess the screen never showed is void at the correction (D-34); a
344
+ // keyed arrangement guess's view carries its removed-keys set.
345
+ if (!i.It || !(t?.l & CONFIG_OVERRIDE) || !t.T.V?.removed) return false;
346
+ const r = e.T.V;
347
+ if ((!e.Ye || !e.Ye(r, n)) && !GlobalQueue.sn(r, n)) {
348
+ i.folded = foldedRead;
349
+ insertSubs(e);
350
+ } else GlobalQueue.tn?.(i);
351
+ joinFuture(resolveTx(i._parent ?? i));
352
+ return true;
353
+ }
354
+
355
+ /** A folded lane's guess read by a deriving pass outside the lane, tracked
356
+ * or not (`untrack` is about dependencies, not about which world a pass
357
+ * derives from), or by `latest()` (`c` null): the hold's world — the truth
358
+ * staged beneath the guess, else the value it covered — and the pass joins
359
+ * the hold. Lane passes and the screen keep the guess: held truth is masked
360
+ * from lane passes only (#3164). The store's own derive reconciles its
361
+ * landings against the arrangement the guesses made: it is the author, not
362
+ * a reader. */ function foldedRead(e, n) {
363
+ if (e !== null) {
364
+ if (!(n.l & CONFIG_GUESS) || passLane !== null || e.i === EFFECT_RENDER || e.l & CONFIG_CHILDREN_FORBIDDEN || n.O?.fam?.node === e) return NOT_PENDING;
365
+ const t = txOf(n);
366
+ joinPassAt(e, resolveTx(t._parent ?? t));
367
+ }
368
+ if (n.ue !== NOT_PENDING) return n.ue;
369
+ return n.l & CONFIG_SLOT_NODE ? GlobalQueue.fn(n) : n.Ie;
370
+ }
371
+
331
372
  function sameRow(e, n, t) {
332
373
  if (e === n) return true;
333
374
  if (!isWrappable(e) || !isWrappable(n)) return false;
@@ -521,11 +562,11 @@ i = false) {
521
562
  if (s !== null) {
522
563
  for (const e of Reflect.ownKeys(s)) {
523
564
  const o = s[e];
524
- let a;
525
- if (o.l & CONFIG_OVERRIDE) a = t(o); else if (!i || (a = pendingGuessOf(o)) === NOT_PENDING) continue;
526
- const f = !!a;
527
- const u = r ?? n;
528
- if (!f && e in u) delete ensure()[e];
565
+ let u;
566
+ if (o.l & CONFIG_OVERRIDE) u = t(o); else if (!i || (u = pendingGuessOf(o)) === NOT_PENDING) continue;
567
+ const f = !!u;
568
+ const a = r ?? n;
569
+ if (!f && e in a) delete ensure()[e];
529
570
  }
530
571
  }
531
572
  return r ?? n;
@@ -538,7 +579,7 @@ function createOptimisticStore(e, n, t) {
538
579
  // createProjectionInternal).
539
580
  const o = i ? n || {} : e;
540
581
  const s = r?.key === undefined ? "id" : r.key;
541
- const a = {
582
+ const u = {
542
583
  map: new WeakMap,
543
584
  node: null,
544
585
  live: new Set,
@@ -546,9 +587,9 @@ function createOptimisticStore(e, n, t) {
546
587
  opt: true,
547
588
  key: typeof s === "function" ? s : s === null ? null : e => isWrappable(e) ? e[s] : undefined
548
589
  };
549
- const f = wrap(o, null, null, a);
590
+ const f = wrap(o, null, null, u);
550
591
  nameStore(f, r?.name, r?.loc);
551
- if (a.shallow) {
592
+ if (u.shallow) {
552
593
  f[$TARGET].s = true;
553
594
  markRawIngest(o);
554
595
  }
@@ -564,11 +605,11 @@ function createOptimisticStore(e, n, t) {
564
605
  loc: r.loc
565
606
  };
566
607
  const i = computed(() => {
567
- if (!a.node) a.node = getOwner();
608
+ if (!u.node) u.node = getOwner();
568
609
  runProjectionComputed(f, n, s);
569
610
  }, t);
570
611
  i.l &= ~CONFIG_AUTO_DISPOSE;
571
- a.node = i;
612
+ u.node = i;
572
613
  }
573
614
  return [ f, e => storeSetter(f, e) ];
574
615
  }