@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
@@ -24,15 +24,15 @@ import { $TARGET, markRawIngest, isWrappable, rawValuesUsed, isRawValue } from "
24
24
  * identity), unkeyed items fall back to position.
25
25
  */ function reconcileState(e, n, t, o = false) {
26
26
  if (n == null) throw new Error("");
27
- const f = n?.[$TARGET];
28
- if (f === undefined || f.px !== n) throw new Error("");
29
- const l = t === null ? null : typeof t === "string" ? e => e?.[t] : t;
27
+ const f = n[$TARGET];
28
+ if (f?.px !== n) throw new Error("");
29
+ const i = t === null ? null : typeof t === "string" ? e => e?.[t] : t;
30
30
  // A user's reconcile on an optimistic family (S4): not an adoption of
31
31
  // truth but an optimistic edit — the keyed diff is written into the draft
32
32
  // (a matched row keeps its proxy, its changed leaves become its guesses),
33
33
  // and the setter's exit turns the draft into guesses like any.
34
34
  if (userWriting() && f.fam?.opt === true) {
35
- optHooks.reconcile(n, unwrapValue(e), l);
35
+ optHooks.reconcile(n, unwrapValue(e), i);
36
36
  return;
37
37
  }
38
38
  // Replace-mode root handed another store's proxy: chain to it (§7b).
@@ -43,21 +43,20 @@ import { $TARGET, markRawIngest, isWrappable, rawValuesUsed, isRawValue } from "
43
43
  adoptPB(f, e);
44
44
  return;
45
45
  }
46
- const i = unwrapValue(e);
47
- if (l) {
46
+ const l = unwrapValue(e);
47
+ if (i) {
48
48
  const e = f.pb ?? f.v;
49
- const n = l(e);
50
- if (n !== undefined && !sameKey(l(i), n)) {
49
+ const n = i(e);
50
+ if (n !== undefined && !sameKey(i(l), n)) {
51
51
  if (!o) throw new Error("");
52
52
  // A different entity at the root: the old backing is disowned (wraps
53
53
  // fresh if re-handed) and the new one adopted whole.
54
- const e = f.pb ?? f.v;
55
- if (isOwned(e)) delete e[$OWNER]; else (f.fam?.map ?? storeLookup).delete(e);
56
- adoptPB(f, i);
54
+ if (isOwned(e)) delete e[$OWNER]; else (f.fam?.map ?? storeLookup).delete(e);
55
+ adoptPB(f, l);
57
56
  return;
58
57
  }
59
58
  }
60
- applyAdopt(f, i, l, o);
59
+ applyAdopt(f, l, i, o);
61
60
  }
62
61
 
63
62
  /** Adopt `incoming` at `t` and notify its nodes — one leaf write per
@@ -70,190 +69,207 @@ import { $TARGET, markRawIngest, isWrappable, rawValuesUsed, isRawValue } from "
70
69
  // a deletion here (#3743: the presence and value diffs both read `old`).
71
70
  const f = e.ovl ? materializePB(e) : e.pb ?? e.v;
72
71
  if (n === f && !isOwned(f)) return;
73
- const l = e.fam;
74
72
  // Q-D: a landing on an optimistic family is reconciled against the VIEW
75
73
  // — key matching from the arrangement the guesses made (R28), so a row
76
74
  // the guess added keeps its proxy when the server returns it.
77
- const i = l?.opt === true ? optHooks.view(e, f) : f;
78
- const s = Array.isArray(n);
79
- const u = e.s === true;
80
- const r = f;
75
+ const i = e.fam?.opt === true ? optHooks.view(e, f) : f;
76
+ const l = Array.isArray(n);
77
+ const r = e.s === true;
81
78
  adoptPB(e, n, false);
82
- if (u) markRawIngest(n);
83
- if (Array.isArray(i) !== s) {
84
- notifyFold(e, r, n);
79
+ if (r) markRawIngest(n);
80
+ // The deep witness is bumped once per adoption (none to bump: done).
81
+ let u = e.dk === null;
82
+ if (Array.isArray(i) !== l) {
83
+ notifyFold(e, f, n);
85
84
  return;
86
85
  }
87
- if (s) {
88
- const f = i;
89
- const s = n;
90
- const a = e.n;
91
- let c = 0;
92
- if (t && !u) {
93
- const i = f.length;
94
- const u = s.length;
95
- let d = false;
96
- let p = 0;
86
+ if (l) {
87
+ const l = e.n;
88
+ let s = 0;
89
+ if (t && !r) {
90
+ const r = i.length;
91
+ const a = n.length;
92
+ let c = 0;
97
93
  // Aligned prefix: same row (by reference or key) at the same index.
98
- for (const y = Math.min(i, u); p < y; p++) {
99
- const i = s[p];
100
- const u = f[p];
101
- if (u !== i && !sameRow(u, i, t)) break;
94
+ for (const d = Math.min(r, a); c < d; c++) {
95
+ const r = n[c];
96
+ const a = i[c];
97
+ if (a !== r && !sameRow(a, r, t)) break;
102
98
  // misaligned: fall to the keyed remainder below
103
- if ((u !== i || i !== null && typeof i === "object" && isOwned(i)) && i !== null && typeof i === "object") descend(unwrapValue(u), i, t, l, o);
104
- if (e.dk !== null && !d && !(i !== null && typeof i === "object" ? targetsEqual(u, i) : isEqual(u, i))) {
99
+ if (r !== null && typeof r === "object" && (a !== r || isOwned(r))) descend(unwrapValue(a), r, t, o, e, c);
100
+ if (!u && !(r !== null && typeof r === "object" ? targetsEqual(a, r) : isEqual(a, r))) {
105
101
  bumpDeep(e);
106
- d = true;
102
+ u = true;
107
103
  }
108
- if (a !== null) {
109
- const e = a[p];
104
+ if (l !== null) {
105
+ const e = l[c];
110
106
  if (e !== undefined) {
111
- c++;
112
- notifyKeyValue(e, p, r[p], i, r, n);
107
+ s++;
108
+ notifyKeyValue(e, c, f[c], r, f, n);
113
109
  }
114
110
  }
115
111
  }
116
- if (e.dk !== null && !d && p < s.length) bumpDeep(e);
117
- const y = p;
112
+ if (!u && c < n.length) bumpDeep(e);
113
+ const d = c;
118
114
  // misalignment point (== nlen on aligned ticks)
119
- let w = null;
120
- for (;p < s.length; p++) {
121
- const e = s[p];
122
- if (e !== null && typeof e === "object") {
123
- const n = t(e);
124
- let i;
115
+ let p = null;
116
+ for (;c < n.length; c++) {
117
+ const r = n[c];
118
+ if (r !== null && typeof r === "object") {
119
+ const n = t(r);
120
+ let f;
125
121
  if (n !== undefined) {
126
- if (w === null) {
127
- w = new Map;
128
- for (let e = y; e < f.length; e++) {
129
- const n = unwrapValue(f[e]);
122
+ if (p === null) {
123
+ p = new Map;
124
+ for (let e = d; e < i.length; e++) {
125
+ const n = unwrapValue(i[e]);
130
126
  if (n !== null && typeof n === "object") {
131
127
  const o = t(n);
132
128
  if (o === undefined) continue;
133
- const f = w.get(o);
134
- if (f === undefined) w.set(o, e); else if (Array.isArray(f)) f.push(e); else w.set(o, [ f, e ]);
129
+ const f = p.get(o);
130
+ if (f === undefined) p.set(o, e); else if (Array.isArray(f)) f.push(e); else p.set(o, [ f, e ]);
135
131
  }
136
132
  }
137
133
  }
138
- const e = w.get(n);
139
- if (e === undefined) i = undefined; else if (Array.isArray(e)) {
140
- i = unwrapValue(f[e.shift()]);
141
- if (e.length === 1) w.set(n, e[0]);
134
+ const e = p.get(n);
135
+ if (e === undefined) f = undefined; else if (Array.isArray(e)) {
136
+ f = unwrapValue(i[e.shift()]);
137
+ if (e.length === 1) p.set(n, e[0]);
142
138
  } else {
143
- i = unwrapValue(f[e]);
144
- w.delete(n);
139
+ f = unwrapValue(i[e]);
140
+ p.delete(n);
145
141
  }
146
142
  } else {
147
- i = unwrapValue(f[p]);
143
+ f = unwrapValue(i[c]);
148
144
  // keyless item: positional fallback
149
145
  }
150
- descend(i, e, t, l, o);
146
+ descend(f, r, t, o, e, c);
151
147
  }
152
- if (a !== null) {
153
- const e = a[p];
148
+ if (l !== null) {
149
+ const e = l[c];
154
150
  if (e !== undefined) {
155
- c++;
156
- notifyKeyDiff(e, p, r, n, false);
151
+ s++;
152
+ notifyKeyDiff(e, c, f, n, false);
157
153
  }
158
154
  }
159
155
  }
160
156
  } else {
161
- const i = Math.min(f.length, s.length);
162
- const d = s.length;
163
- let p = false;
164
- for (let y = 0; y < d; y++) {
165
- const d = s[y];
166
- if (!u && y < i && d !== null && typeof d === "object") descend(unwrapValue(f[y]), d, t, l, o);
167
- if (e.dk !== null && !p && !(d !== null && typeof d === "object" ? targetsEqual(f[y], d) : isEqual(f[y], d))) {
157
+ const a = Math.min(i.length, n.length);
158
+ const c = n.length;
159
+ for (let d = 0; d < c; d++) {
160
+ const c = n[d];
161
+ if (!r && d < a && c !== null && typeof c === "object") descend(unwrapValue(i[d]), c, t, o, e, d);
162
+ if (!u && !(c !== null && typeof c === "object" ? targetsEqual(i[d], c) : isEqual(i[d], c))) {
168
163
  bumpDeep(e);
169
- p = true;
164
+ u = true;
170
165
  }
171
- if (a !== null) {
172
- const e = a[y];
166
+ if (l !== null) {
167
+ const e = l[d];
173
168
  if (e !== undefined) {
174
- c++;
175
- notifyKeyDiff(e, y, r, n, false);
169
+ s++;
170
+ notifyKeyDiff(e, d, f, n, false);
176
171
  }
177
172
  }
178
173
  }
179
174
  }
180
175
  // Indices past the new length (and `length` itself) still have nodes.
181
- if (a !== null && c < e.nc) {
182
- for (const e of Reflect.ownKeys(a)) {
176
+ if (l !== null && s < e.nc) {
177
+ for (const e of Reflect.ownKeys(l)) {
183
178
  const t = typeof e === "string" ? +e : NaN;
184
- if (!(t >= 0 && t < s.length)) notifyKeyDiff(a[e], e, r, n, false);
179
+ if (!(t >= 0 && t < n.length)) notifyKeyDiff(l[e], e, f, n, false);
185
180
  }
186
181
  }
187
- notifyFoldTail(e, r, n);
182
+ notifyFoldTail(e, f, n);
188
183
  return;
189
184
  }
190
- const a = e.n;
191
- let c = 0;
192
- let d = false;
193
- for (const f in n) {
194
- const s = n[f];
195
- const p = r[f];
196
- const y = s !== null && typeof s === "object";
197
- if (p === s && (!y || !isOwned(s)) && (a === null || a[f] === undefined || !hasAccessorFlag(a[f]))) {
198
- if (a !== null && a[f] !== undefined) c++;
185
+ const s = e.n;
186
+ let a = 0;
187
+ for (const l in n) {
188
+ const c = n[l];
189
+ const d = f[l];
190
+ const p = c !== null && typeof c === "object";
191
+ if (d === c && (!p || !isOwned(c)) && (s === null || s[l] === undefined || !hasAccessorFlag(s[l]))) {
192
+ if (s?.[l] !== undefined) a++;
199
193
  continue;
200
194
  }
201
- if (y && !u) descend(unwrapValue(i[f]), s, t, l, o);
202
- if (e.dk !== null && !d && !(y ? targetsEqual(p, s) : isEqual(p, s))) {
195
+ if (p && !r) descend(unwrapValue(i[l]), c, t, o, e, l);
196
+ if (!u && !(p ? targetsEqual(d, c) : isEqual(d, c))) {
203
197
  bumpDeep(e);
204
- d = true;
198
+ u = true;
205
199
  }
206
- if (a !== null) {
207
- const e = a[f];
200
+ if (s !== null) {
201
+ const e = s[l];
208
202
  if (e !== undefined) {
209
- c++;
210
- notifyKeyValue(e, f, p, s, r, n);
203
+ a++;
204
+ notifyKeyValue(e, l, d, c, f, n);
211
205
  }
212
206
  }
213
207
  }
214
- const p = Object.getOwnPropertySymbols(n);
215
- for (let e = 0; e < p.length; e++) {
216
- const f = p[e];
217
- if (f === $OWNER) continue;
218
- const i = n[f];
219
- if (!u && i !== null && typeof i === "object") descend(unwrapValue(r[f]), i, t, l, o);
220
- if (a !== null) {
221
- const e = a[f];
208
+ const c = Object.getOwnPropertySymbols(n);
209
+ for (let i = 0; i < c.length; i++) {
210
+ const l = c[i];
211
+ if (l === $OWNER) continue;
212
+ const u = n[l];
213
+ if (!r && u !== null && typeof u === "object") descend(unwrapValue(f[l]), u, t, o, e, l);
214
+ if (s !== null) {
215
+ const e = s[l];
222
216
  if (e !== undefined) {
223
- c++;
224
- notifyKeyValue(e, f, r[f], i, r, n);
217
+ a++;
218
+ notifyKeyValue(e, l, f[l], u, f, n);
225
219
  }
226
220
  }
227
221
  }
228
222
  // Keys the incoming object no longer has still have nodes.
229
- if (a !== null && c < e.nc) {
230
- for (const e of Reflect.ownKeys(a)) {
231
- if (!hasOwnP.call(n, e)) notifyKeyDiff(a[e], e, r, n, false);
223
+ if (s !== null && a < e.nc) {
224
+ for (const e of Reflect.ownKeys(s)) {
225
+ if (!hasOwnP.call(n, e)) notifyKeyDiff(s[e], e, f, n, false);
232
226
  }
233
227
  }
234
- notifyFoldTail(e, r, n);
228
+ notifyFoldTail(e, f, n);
235
229
  }
236
230
 
237
231
  const hasOwnP = Object.prototype.hasOwnProperty;
238
232
 
239
233
  /** Descend into a changed child pair — only where something is proxied
240
234
  * below (§6d), never into a raw-marked leaf, never across array/object or a
241
- * key mismatch (that is a replacement, handled by the parent's slot). */ function descend(e, n, t, o, f = false) {
242
- if (e === null || typeof e !== "object" || n === null || typeof n !== "object") return;
243
- const l = lookupTarget(e, o);
244
- if (l === undefined) return;
235
+ * key mismatch (that is a replacement, handled by the parent's slot).
236
+ *
237
+ * A raw in both frames (the same objects swapped, reordered or shifted,
238
+ * #4001) must not leave two slots on one row. A raw already a live row keeps
239
+ * it at the slot it moved to; a row's `pk` follows the slot it sits at (a
240
+ * move or a pairing writes it), so a row whose raw is at that slot of the
241
+ * incoming frame is spoken for and not paired again here; a raw still
242
+ * resolving to a row that moved on drops the lookup (it wraps fresh, or is
243
+ * paired here). One lookup of `nv` on the common path, no allocation. */ function descend(e, n, t, o, f, i) {
244
+ // `nv` is an object at every call site.
245
+ if (e === null || typeof e !== "object") return;
246
+ const l = f.fam;
247
+ n = unwrapValue(n);
248
+ let r = lookupTarget(e, l);
249
+ const u = lookupTarget(n, l);
250
+ if (r !== undefined && r.pk !== i) {
251
+ if (r.pk != i && f.v[r.pk] === r.v) r = undefined; else if (r.u === f) r.pk = i;
252
+ }
253
+ if (u !== undefined && u !== r) {
254
+ if (u.v === n) {
255
+ if (u.u === f) u.pk = i;
256
+ return;
257
+ }
258
+ (l?.map ?? storeLookup).delete(n);
259
+ }
260
+ if (r === undefined) return;
245
261
  // nothing proxied below this pair
246
262
  if (!isWrappable(n)) return;
247
263
  if (rawValuesUsed && isRawValue(n)) return;
248
- n = unwrapValue(n);
249
264
  if (Array.isArray(e) !== Array.isArray(n)) return;
250
- if (t) {
265
+ // An array slot was paired by key already (or both rows are keyless).
266
+ if (typeof i !== "number" && t) {
251
267
  const o = t(e);
252
268
  const f = t(n);
253
269
  if (o !== undefined && f !== undefined && !sameKey(o, f)) return;
254
270
  }
255
- if (!f && t !== null && !l.d) return;
256
- applyAdopt(l, n, t, f);
271
+ if (!o && t !== null && !r.d) return;
272
+ applyAdopt(r, n, t, o);
257
273
  }
258
274
 
259
275
  export { reconcileState };