@solidjs/signals 2.0.0-rc.6 → 2.0.0-rc.8

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 (131) hide show
  1. package/dist/dev-shared.js +5243 -0
  2. package/dist/dev.attribution.js +2333 -0
  3. package/dist/dev.js +1758 -6621
  4. package/dist/observe/affects.js +127 -0
  5. package/dist/observe/attribution.js +1 -0
  6. package/dist/observe/boundaries.js +586 -0
  7. package/dist/observe/core/action.js +167 -0
  8. package/dist/observe/core/async.js +736 -0
  9. package/dist/observe/core/attribution-hooks.js +60 -0
  10. package/dist/observe/core/attribution.js +2318 -0
  11. package/dist/{types-cjs/core/constants.d.cts → observe/core/constants.js} +135 -71
  12. package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
  13. package/dist/observe/core/core.js +1289 -0
  14. package/dist/observe/core/dev.js +232 -0
  15. package/dist/observe/core/effect.js +179 -0
  16. package/dist/observe/core/error.js +80 -0
  17. package/dist/observe/core/external.js +98 -0
  18. package/dist/observe/core/graph.js +155 -0
  19. package/dist/observe/core/heap.js +147 -0
  20. package/dist/observe/core/invariants.js +43 -0
  21. package/dist/observe/core/lanes.js +168 -0
  22. package/dist/observe/core/optimistic.js +438 -0
  23. package/dist/observe/core/owner.js +308 -0
  24. package/dist/observe/core/scheduler.js +1190 -0
  25. package/dist/observe/core/verdict.js +551 -0
  26. package/dist/observe/index.js +55 -0
  27. package/dist/observe/map.js +482 -0
  28. package/dist/{types-cjs/signals.d.cts → observe/signals.js} +305 -317
  29. package/dist/observe/store/index.js +38 -0
  30. package/dist/observe/store/next/optimistic.js +651 -0
  31. package/dist/observe/store/next/projection.js +242 -0
  32. package/dist/observe/store/next/reconcile.js +373 -0
  33. package/dist/observe/store/next/store.js +2213 -0
  34. package/dist/observe/store/next/target.js +51 -0
  35. package/dist/observe/store/store.js +323 -0
  36. package/dist/observe/store/storePath.js +103 -0
  37. package/dist/observe/store/utils.js +210 -0
  38. package/dist/prod/attribution.js +32 -0
  39. package/dist/prod/boundaries.js +3 -1
  40. package/dist/prod/core/action.js +52 -32
  41. package/dist/prod/core/async.js +177 -128
  42. package/dist/prod/core/attribution-hooks.js +3 -0
  43. package/dist/prod/core/constants.js +32 -1
  44. package/dist/prod/core/context.js +10 -16
  45. package/dist/prod/core/core.js +505 -286
  46. package/dist/prod/core/dev.js +2 -0
  47. package/dist/prod/core/effect.js +72 -43
  48. package/dist/prod/core/external.js +2 -2
  49. package/dist/prod/core/graph.js +40 -36
  50. package/dist/prod/core/heap.js +50 -51
  51. package/dist/prod/core/lanes.js +43 -22
  52. package/dist/prod/core/optimistic.js +224 -80
  53. package/dist/prod/core/owner.js +43 -39
  54. package/dist/prod/core/scheduler.js +347 -232
  55. package/dist/prod/core/verdict.js +71 -74
  56. package/dist/prod/index.js +9 -5
  57. package/dist/prod/map.js +311 -150
  58. package/dist/prod/signals.js +52 -38
  59. package/dist/prod/store/next/optimistic.js +127 -131
  60. package/dist/prod/store/next/projection.js +3 -3
  61. package/dist/prod/store/next/reconcile.js +149 -294
  62. package/dist/prod/store/next/store.js +694 -380
  63. package/dist/prod/store/next/target.js +32 -10
  64. package/dist/prod/store/store.js +12 -14
  65. package/dist/prod/store/utils.js +36 -27
  66. package/dist/types/attribution.d.ts +15 -0
  67. package/dist/types/attribution.prod.d.ts +13 -0
  68. package/dist/types/core/async.d.ts +1 -1
  69. package/dist/types/core/attribution-hooks.d.ts +183 -6
  70. package/dist/types/core/attribution.d.ts +435 -24
  71. package/dist/types/core/constants.d.ts +31 -0
  72. package/dist/types/core/core.d.ts +19 -3
  73. package/dist/types/core/dev.d.ts +165 -26
  74. package/dist/types/core/effect.d.ts +8 -1
  75. package/dist/types/core/heap.d.ts +5 -3
  76. package/dist/types/core/index.d.ts +2 -1
  77. package/dist/types/core/invariants.d.ts +1 -1
  78. package/dist/types/core/lanes.d.ts +17 -0
  79. package/dist/types/core/scheduler.d.ts +69 -4
  80. package/dist/types/core/types.d.ts +29 -9
  81. package/dist/types/index.d.ts +9 -2
  82. package/dist/types/map.d.ts +2 -0
  83. package/dist/types/signals.d.ts +10 -0
  84. package/dist/types/store/index.d.ts +4 -6
  85. package/dist/types/store/next/optimistic.d.ts +4 -2
  86. package/dist/types/store/next/reconcile.d.ts +5 -12
  87. package/dist/types/store/next/store.d.ts +8 -9
  88. package/dist/types/store/next/target.d.ts +56 -55
  89. package/dist/types/store/store.d.ts +14 -9
  90. package/dist/types/store/utils.d.ts +7 -0
  91. package/package.json +21 -16
  92. package/dist/node.cjs +0 -11121
  93. package/dist/prod/store/next/patch-hooks.js +0 -13
  94. package/dist/prod/store/next/patch.js +0 -614
  95. package/dist/types/store/next/patch-hooks.d.ts +0 -41
  96. package/dist/types/store/next/patch.d.ts +0 -91
  97. package/dist/types-cjs/affects.d.cts +0 -47
  98. package/dist/types-cjs/boundaries.d.cts +0 -175
  99. package/dist/types-cjs/core/action.d.cts +0 -64
  100. package/dist/types-cjs/core/async.d.cts +0 -23
  101. package/dist/types-cjs/core/attribution-hooks.d.cts +0 -63
  102. package/dist/types-cjs/core/attribution.d.cts +0 -239
  103. package/dist/types-cjs/core/core.d.cts +0 -176
  104. package/dist/types-cjs/core/dev.d.cts +0 -95
  105. package/dist/types-cjs/core/effect.d.cts +0 -30
  106. package/dist/types-cjs/core/error.d.cts +0 -56
  107. package/dist/types-cjs/core/external.d.cts +0 -15
  108. package/dist/types-cjs/core/graph.d.cts +0 -28
  109. package/dist/types-cjs/core/heap.d.cts +0 -22
  110. package/dist/types-cjs/core/index.d.cts +0 -13
  111. package/dist/types-cjs/core/invariants.d.cts +0 -59
  112. package/dist/types-cjs/core/lanes.d.cts +0 -44
  113. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  114. package/dist/types-cjs/core/owner.d.cts +0 -124
  115. package/dist/types-cjs/core/scheduler.d.cts +0 -231
  116. package/dist/types-cjs/core/types.d.cts +0 -204
  117. package/dist/types-cjs/core/verdict.d.cts +0 -2
  118. package/dist/types-cjs/index.d.cts +0 -10
  119. package/dist/types-cjs/map.d.cts +0 -69
  120. package/dist/types-cjs/package.json +0 -3
  121. package/dist/types-cjs/store/index.d.cts +0 -21
  122. package/dist/types-cjs/store/next/optimistic.d.cts +0 -23
  123. package/dist/types-cjs/store/next/patch-hooks.d.cts +0 -41
  124. package/dist/types-cjs/store/next/patch.d.cts +0 -91
  125. package/dist/types-cjs/store/next/projection.d.cts +0 -8
  126. package/dist/types-cjs/store/next/reconcile.d.cts +0 -17
  127. package/dist/types-cjs/store/next/store.d.cts +0 -127
  128. package/dist/types-cjs/store/next/target.d.cts +0 -192
  129. package/dist/types-cjs/store/store.d.cts +0 -138
  130. package/dist/types-cjs/store/storePath.d.cts +0 -58
  131. package/dist/types-cjs/store/utils.d.cts +0 -74
package/dist/prod/map.js CHANGED
@@ -6,6 +6,8 @@ import "./core/scheduler.js";
6
6
 
7
7
  import { CONFIG_AUTO_DISPOSE } from "./core/constants.js";
8
8
 
9
+ import { attrHooks } from "./core/attribution-hooks.js";
10
+
9
11
  import "./core/invariants.js";
10
12
 
11
13
  import "./core/verdict.js";
@@ -22,199 +24,358 @@ function mapArray(t, s, i) {
22
24
  const e = typeof i?.keyed === "function" ? i.keyed : undefined;
23
25
  const r = s.length > 1;
24
26
  const n = s;
25
- const h = {
26
- Kt: createOwner(),
27
- $t: 0,
28
- Jt: t,
29
- Xt: [],
30
- Yt: n,
31
- Zt: [],
32
- ts: [],
33
- ss: e,
34
- es: e || i?.keyed === false ? [] : undefined,
35
- rs: r && i?.keyed !== false ? [] : undefined,
36
- ns: i?.keyed === false,
37
- hs: i?.fallback
27
+ const o = {
28
+ ts: createOwner(),
29
+ ss: 0,
30
+ es: t,
31
+ rs: [],
32
+ ns: n,
33
+ hs: [],
34
+ fs: [],
35
+ xt: e,
36
+ cs: e || i?.keyed === false ? [] : undefined,
37
+ ls: r && i?.keyed !== false ? [] : undefined,
38
+ us: i?.keyed === false,
39
+ ps: i?.fallback
38
40
  };
39
- const o = computed(updateKeyedMap.bind(h));
41
+ const h = computed(updateKeyedMap.bind(o), undefined);
40
42
  // Untracked reads inside the internal owner resolve via _parentComputed; routing
41
43
  // them through node lets store-proxy lookups see pending writes (not stale _value).
42
- h.Kt.Dt = o;
43
- o.T &= ~CONFIG_AUTO_DISPOSE;
44
- return accessor(o);
44
+ o.ts.bt = h;
45
+ h.T &= ~CONFIG_AUTO_DISPOSE;
46
+ return accessor(h);
45
47
  }
46
48
 
47
49
  const pureOptions = {
48
50
  ownedWrite: true
49
51
  };
50
52
 
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).
53
+ function trySmallMove(t, s, i, e) {
54
+ const r = t.rs;
55
+ const n = t.ss - 1;
56
+ const o = [];
57
+ const h = [];
58
+ const f = [];
59
+ // flat triples: oldStart, newStart, length
60
+ let c = 256;
61
+ let a = e;
62
+ let l = e;
63
+ let u = false;
64
+ while (a <= n && l <= i - 1) {
65
+ const t = r[a];
66
+ const e = s[l];
67
+ if (t === e) {
68
+ if (!u) {
69
+ f.push(a, l, 0);
70
+ u = true;
71
+ }
72
+ f[f.length - 1]++;
73
+ a++;
74
+ l++;
75
+ continue;
76
+ }
77
+ u = false;
78
+ // Bounded realignment lookahead, shorter distance wins.
79
+ let p = -1;
80
+ let d = Math.min(32 - o.length, n - a, c);
81
+ for (let t = 1; t <= d; t++) {
82
+ if (r[a + t] === e) {
83
+ p = t;
84
+ break;
85
+ }
86
+ }
87
+ c -= p === -1 ? d : p;
88
+ let w = -1;
89
+ d = Math.min(32 - h.length, i - 1 - l, c);
90
+ for (let i = 1; i <= d; i++) {
91
+ if (s[l + i] === t) {
92
+ w = i;
93
+ break;
94
+ }
95
+ }
96
+ c -= w === -1 ? d : w;
97
+ if (p !== -1 && (w === -1 || p <= w)) {
98
+ while (p-- > 0) o.push(a++);
99
+ continue;
100
+ }
101
+ if (w !== -1) {
102
+ while (w-- > 0) h.push(l++);
103
+ continue;
104
+ }
105
+ if (c <= 0 || o.length === 32 || h.length === 32) return false;
106
+ o.push(a++);
107
+ h.push(l++);
108
+ }
109
+ for (;a <= n; a++) {
110
+ if (o.length === 32) return false;
111
+ o.push(a);
112
+ }
113
+ for (;l <= i - 1; l++) {
114
+ if (h.length === 32) return false;
115
+ h.push(l);
116
+ }
117
+ return commitSmallMove(t, s, i, o, h, f);
118
+ }
119
+
120
+ /** PHASE 2 of the small-move path, in its OWN function so that a pass which
121
+ * only SCANS and bails (a full replace: the first structural pass of a page,
122
+ * typically) compiles nothing but the scan — V8 parses and compiles lazily
123
+ * per function, and cold `replace` measured +0.5 ms with both phases in one
124
+ * body. Pairs displaced sources with destinations (an unmatched destination
125
+ * is a replacement/insertion → general path), then commits: slice() the live
126
+ * arrays, copy shifted runs, patch displaced pairs, dispose leftovers. */ function commitSmallMove(t, s, i, e, r, n) {
127
+ const o = t.rs;
128
+ let h;
129
+ let f;
130
+ let c;
131
+ if (r.length !== 0) {
132
+ c = new Array(e.length);
133
+ for (f = 0; f < r.length; f++) {
134
+ let t = -1;
135
+ for (h = 0; h < e.length; h++) {
136
+ if (!c[h] && o[e[h]] === s[r[f]]) {
137
+ t = h;
138
+ break;
139
+ }
140
+ }
141
+ if (t === -1) return false;
142
+ c[t] = true;
143
+ r[f] = r[f] << 6 | t;
144
+ // pack pairing (found < 32)
145
+ }
146
+ }
147
+ // DUPLICATES: the general path pairs equal identities by OCCURRENCE ORDER
148
+ // (the chained index map). Displaced↔displaced pairing above is ascending
149
+ // on both sides, so it agrees; but an aligned run was matched by POSITION,
150
+ // and if a displaced identity also occurs inside a run the two algorithms
151
+ // can hand different occurrences different owners (row-local state moves;
152
+ // a shrink could dispose the wrong one). Decline that case — general path.
153
+ if (e.length !== 0 || r.length !== 0) {
154
+ const t = new Set;
155
+ for (h = 0; h < e.length; h++) t.add(o[e[h]]);
156
+ for (f = 0; f < r.length; f++) t.add(s[r[f] >> 6]);
157
+ for (let s = 0; s < n.length; s += 3) {
158
+ const i = n[s];
159
+ for (let e = 0, r = n[s + 2]; e < r; e++) if (t.has(o[i + e])) return false;
160
+ }
161
+ }
162
+ const a = t.hs;
163
+ const l = t.fs;
164
+ const u = a.slice(0, i);
165
+ const p = l.slice(0, i);
166
+ for (let t = 0; t < n.length; t += 3) {
167
+ const s = n[t];
168
+ const i = n[t + 1];
169
+ if (s !== i) {
170
+ for (let e = 0; e < n[t + 2]; e++) {
171
+ u[i + e] = a[s + e];
172
+ p[i + e] = l[s + e];
173
+ }
174
+ }
175
+ }
176
+ for (f = 0; f < r.length; f++) {
177
+ const t = r[f] >> 6;
178
+ const s = e[r[f] & 63];
179
+ u[t] = a[s];
180
+ p[t] = l[s];
181
+ }
182
+ t.hs = u;
183
+ t.fs = p;
184
+ t.ss = i;
185
+ t.rs = s.slice(0);
186
+ // Dispose unmatched sources LAST (general-path ordering).
187
+ for (h = 0; h < e.length; h++) {
188
+ if (c === undefined || !c[h]) l[e[h]].dispose();
189
+ }
190
+ return true;
191
+ }
192
+
60
193
  function updateKeyedMap() {
61
- const t = this.Jt() || [], s = t.length;
194
+ const t = this.es() || [], s = t.length;
62
195
  t[$TRACK];
63
196
  // top level tracking
64
- runWithOwner(this.Kt, () => {
197
+ runWithOwner(this.ts, () => {
65
198
  let i, e, r, n,
66
199
  // Mappers write freshly-created row/index signals into the STAGE
67
200
  // arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
68
- h = this.es ? this.ns ? () => {
201
+ o = this.cs ? this.us ? () => {
69
202
  r[e] = signal(t[e], pureOptions);
70
- return this.Yt(accessor(r[e]), e);
203
+ return this.ns(accessor(r[e]), e);
71
204
  } : () => {
72
205
  r[e] = signal(t[e], pureOptions);
73
206
  n && (n[e] = signal(e, pureOptions));
74
- return this.Yt(accessor(r[e]), n ? accessor(n[e]) : undefined);
75
- } : this.rs ? () => {
207
+ return this.ns(accessor(r[e]), n ? accessor(n[e]) : undefined);
208
+ } : this.ls ? () => {
76
209
  const s = t[e];
77
210
  n[e] = signal(e, pureOptions);
78
- return this.Yt(s, accessor(n[e]));
211
+ return this.ns(s, accessor(n[e]));
79
212
  } : () => {
80
213
  const s = t[e];
81
- return this.Yt(s);
214
+ return this.ns(s);
82
215
  };
83
216
  // fast path for empty arrays
84
217
  if (s === 0) {
85
- if (this.$t !== 0) {
86
- this.Kt.dispose(false);
87
- this.ts = [];
88
- this.Xt = [];
89
- this.Zt = [];
90
- this.$t = 0;
91
- this.es && (this.es = []);
92
- this.rs && (this.rs = []);
218
+ if (this.ss !== 0) {
219
+ this.ts.dispose(false);
220
+ this.fs = [];
221
+ this.rs = [];
222
+ this.hs = [];
223
+ this.ss = 0;
224
+ this.cs && (this.cs = []);
225
+ this.ls && (this.ls = []);
93
226
  }
94
- if (this.hs && !this.Zt[0]) {
227
+ if (this.ps && !this.hs[0]) {
95
228
  // an aborted fallback attempt leaves an owner without a mapping;
96
229
  // dispose it before re-creating
97
- this.ts[0]?.dispose();
98
- this.Zt[0] = runWithOwner(this.ts[0] = createOwner(), this.hs);
230
+ this.fs[0]?.dispose();
231
+ this.hs[0] = runWithOwner(this.fs[0] = createOwner(), this.ps);
99
232
  }
100
233
  }
101
234
  // fast path for new create
102
- else if (this.$t === 0) {
103
- const o = new Array(s);
104
- const c = new Array(s);
105
- r = this.es && new Array(s);
106
- n = this.rs && new Array(s);
235
+ else if (this.ss === 0) {
236
+ const h = new Array(s);
237
+ const f = new Array(s);
238
+ r = this.cs && new Array(s);
239
+ n = this.ls && new Array(s);
107
240
  try {
108
- for (e = 0; e < s; e++) o[e] = runWithOwner(c[e] = createOwner(), h);
241
+ for (e = 0; e < s; e++) h[e] = runWithOwner(f[e] = createOwner(), o);
109
242
  } catch (t) {
110
- for (i = 0; i <= e; i++) c[i]?.dispose();
243
+ for (i = 0; i <= e; i++) f[i]?.dispose();
111
244
  throw t;
112
245
  }
113
246
  // commit
114
- if (this.ts[0]) this.ts[0].dispose();
247
+ if (this.fs[0]) this.fs[0].dispose();
115
248
  // previous fallback
116
- this.Zt = o;
117
- this.ts = c;
118
- r && (this.es = r);
119
- n && (this.rs = n);
120
- this.Xt = t.slice(0);
121
- this.$t = s;
249
+ this.hs = h;
250
+ this.fs = f;
251
+ r && (this.cs = r);
252
+ n && (this.ls = n);
253
+ this.rs = t.slice(0);
254
+ this.ss = s;
122
255
  } else {
123
- let o, c, a, f, u, p, w, l, d;
256
+ let h, f, c, a, l, u, p, d, w,
257
+ // Dev (attribution engine installed): the items behind the exited and
258
+ // entered rows, for the list-identity census.
259
+ m, O;
124
260
  // skip common prefix
125
- for (o = 0, c = Math.min(this.$t, s); o < c && (this.Xt[o] === t[o] || this.es && compare(this.ss, this.Xt[o], t[o])); o++) {
126
- if (this.es) setSignal(this.es[o], t[o]);
261
+ for (h = 0, f = Math.min(this.ss, s); h < f && (this.rs[h] === t[h] || this.cs && compare(this.xt, this.rs[h], t[h])); h++) {
262
+ if (this.cs) setSignal(this.cs[h], t[h]);
127
263
  }
128
264
  // skip common suffix — counted only; retained entries land in one pass
129
265
  // at commit instead of being staged and copied twice
130
- for (c = this.$t - 1, a = s - 1; c >= o && a >= o && (this.Xt[c] === t[a] || this.es && compare(this.ss, this.Xt[c], t[a])); c--,
131
- a--) ;
266
+ for (f = this.ss - 1, c = s - 1; f >= h && c >= h && (this.rs[f] === t[c] || this.cs && compare(this.xt, this.rs[f], t[c])); f--,
267
+ c--) ;
132
268
  // no structural change (every position matched in place at equal
133
269
  // length — the common post-reconcile shape): keep the same mapped
134
270
  // array identity so downstream consumers don't re-run at all
135
- if (o === s && this.$t === s) {
136
- this.Xt = t.slice(0);
271
+ if (h === s && this.ss === s) {
272
+ this.rs = t.slice(0);
137
273
  return;
138
274
  }
139
- const O = s - this.$t;
140
- const m = new Array(s);
141
- const _ = new Array(s);
142
- r = this.es ? new Array(s) : undefined;
143
- n = this.rs ? new Array(s) : undefined;
275
+ // SMALL-MOVE FAST PATH: extracted to its own function — inlining it
276
+ // here bloats updateKeyedMap past the JIT's optimization budget and
277
+ // deoptimizes the GENERAL path (measured 2x on reverse). Gated to
278
+ // LARGE trimmed windows: when the trims already shrank the window
279
+ // (plain removals, tail edits), the general path is window-
280
+ // proportional and cheap — the fast path would only re-walk what the
281
+ // trims proved.
282
+ if (s <= this.ss && f - h > 64 && this.cs === undefined && this.ls === undefined) {
283
+ // PROBE before the scan: a small move keeps a mid-window item within
284
+ // ±32 of its old position; a REPLACE (all fresh items — the shape
285
+ // every page's first structural pass usually is) has it nowhere.
286
+ // ~65 compares, no allocation, and the scan function is never
287
+ // compiled for a replace (its cold first-call compile was the cost).
288
+ const i = h + (c - h >> 1);
289
+ const e = t[i];
290
+ const r = Math.min(f, i + 32);
291
+ let n = Math.max(h, i - 32);
292
+ while (n <= r && this.rs[n] !== e) n++;
293
+ if (n <= r && trySmallMove(this, t, s, h)) return;
294
+ }
295
+ const _ = s - this.ss;
296
+ const y = new Array(s);
297
+ const A = new Array(s);
298
+ r = this.cs ? new Array(s) : undefined;
299
+ n = this.ls ? new Array(s) : undefined;
144
300
  // 0) prepare a map of all indices in the changed window of newItems,
145
301
  // 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.ss ? this.ss(f) : f;
151
- i = p.get(u);
152
- w[e] = i === undefined ? -1 : i;
153
- p.set(u, e);
302
+ u = new Map;
303
+ p = new Array(c + 1);
304
+ for (e = c; e >= h; e--) {
305
+ a = t[e];
306
+ l = this.xt ? this.xt(a) : a;
307
+ i = u.get(l);
308
+ p[e] = i === undefined ? -1 : i;
309
+ u.set(l, e);
154
310
  }
155
311
  // 1) step through the old changed window and see if items can be found
156
312
  // in the new set; if so, stage them at their new positions; if not,
157
313
  // queue them for disposal at commit
158
- for (i = o; i <= c; i++) {
159
- f = this.Xt[i];
160
- u = this.ss ? this.ss(f) : f;
161
- e = p.get(u);
314
+ for (i = h; i <= f; i++) {
315
+ a = this.rs[i];
316
+ l = this.xt ? this.xt(a) : a;
317
+ e = u.get(l);
162
318
  if (e !== undefined && e !== -1) {
163
- m[e] = this.Zt[i];
164
- _[e] = this.ts[i];
165
- r && (r[e] = this.es[i]);
166
- n && (n[e] = this.rs[i]);
167
- e = w[e];
168
- p.set(u, e);
169
- } else (l ??= []).push(this.ts[i]);
319
+ y[e] = this.hs[i];
320
+ A[e] = this.fs[i];
321
+ r && (r[e] = this.cs[i]);
322
+ n && (n[e] = this.ls[i]);
323
+ e = p[e];
324
+ u.set(l, e);
325
+ } else {
326
+ (d ??= []).push(this.fs[i]);
327
+ if (false && attrHooks !== null) ;
328
+ }
170
329
  }
171
330
  // 2) create new rows into the temp arrays; an abort disposes only these
172
331
  try {
173
- for (e = o; e <= a; e++) {
174
- if (_[e] !== undefined) continue;
175
- (d ??= []).push(_[e] = createOwner());
176
- m[e] = runWithOwner(_[e], h);
332
+ for (e = h; e <= c; e++) {
333
+ if (A[e] !== undefined) continue;
334
+ (w ??= []).push(A[e] = createOwner());
335
+ if (false && attrHooks !== null) ;
336
+ y[e] = runWithOwner(A[e], o);
177
337
  }
178
338
  } catch (t) {
179
- if (d) for (i = 0; i < d.length; i++) d[i].dispose();
339
+ if (w) for (i = 0; i < w.length; i++) w[i].dispose();
180
340
  throw t;
181
341
  }
182
342
  // 3) commit: land the retained prefix and suffix plus the staged window
183
343
  // into the fresh arrays, swap them in (new identity for downstream
184
344
  // change propagation), then dispose exited rows
185
- for (i = 0; i < o; i++) {
186
- m[i] = this.Zt[i];
187
- _[i] = this.ts[i];
188
- r && (r[i] = this.es[i]);
189
- n && (n[i] = this.rs[i]);
345
+ for (i = 0; i < h; i++) {
346
+ y[i] = this.hs[i];
347
+ A[i] = this.fs[i];
348
+ r && (r[i] = this.cs[i]);
349
+ n && (n[i] = this.ls[i]);
190
350
  }
191
- for (e = o; e <= a; e++) {
351
+ for (e = h; e <= c; e++) {
192
352
  if (r) setSignal(r[e], t[e]);
193
353
  if (n) setSignal(n[e], e);
194
354
  }
195
- for (e = a + 1; e < s; e++) {
196
- m[e] = this.Zt[e - O];
197
- _[e] = this.ts[e - O];
355
+ for (e = c + 1; e < s; e++) {
356
+ y[e] = this.hs[e - _];
357
+ A[e] = this.fs[e - _];
198
358
  if (r) {
199
- r[e] = this.es[e - O];
359
+ r[e] = this.cs[e - _];
200
360
  setSignal(r[e], t[e]);
201
361
  }
202
362
  if (n) {
203
- n[e] = this.rs[e - O];
204
- if (O !== 0) setSignal(n[e], e);
363
+ n[e] = this.ls[e - _];
364
+ if (_ !== 0) setSignal(n[e], e);
205
365
  }
206
366
  }
207
- this.Zt = m;
208
- this.ts = _;
209
- r && (this.es = r);
210
- n && (this.rs = n);
211
- this.$t = s;
367
+ this.hs = y;
368
+ this.fs = A;
369
+ r && (this.cs = r);
370
+ n && (this.ls = n);
371
+ this.ss = s;
212
372
  // save a copy of the mapped items for the next update
213
- this.Xt = t.slice(0);
214
- if (l) for (i = 0; i < l.length; i++) l[i].dispose();
373
+ this.rs = t.slice(0);
374
+ if (d) for (i = 0; i < d.length; i++) d[i].dispose();
375
+ if (false && attrHooks !== null && m !== undefined && O !== undefined) ;
215
376
  }
216
377
  });
217
- return this.Zt;
378
+ return this.hs;
218
379
  }
219
380
 
220
381
  /**
@@ -234,21 +395,21 @@ function updateKeyedMap() {
234
395
  */ function repeat(t, s, i) {
235
396
  const e = s;
236
397
  const r = {
237
- Kt: createOwner(),
238
- $t: 0,
239
- cs: 0,
240
- fs: t,
241
- Yt: e,
242
- ts: [],
243
- Zt: [],
244
- us: i?.from,
245
- hs: i?.fallback
398
+ ts: createOwner(),
399
+ ss: 0,
400
+ ds: 0,
401
+ ws: t,
402
+ ns: e,
403
+ fs: [],
404
+ hs: [],
405
+ Os: i?.from,
406
+ ps: i?.fallback
246
407
  };
247
408
  const n = computed(updateRepeat.bind(r));
248
409
  // Same as mapArray: untracked reads inside the internal owner resolve via
249
410
  // _parentComputed, so async reads in row callbacks register with the node
250
411
  // (pending tracking + post-settle retry) instead of vanishing.
251
- r.Kt.Dt = n;
412
+ r.ts.bt = n;
252
413
  n.T &= ~CONFIG_AUTO_DISPOSE;
253
414
  return accessor(n);
254
415
  }
@@ -261,55 +422,55 @@ function updateKeyedMap() {
261
422
  // for the post-settle retry. The overlap math also subsumes the previous
262
423
  // disjoint-window/front-clear/end-clear/shift special cases.
263
424
  function updateRepeat() {
264
- const t = this.fs();
265
- const s = this.us?.() || 0;
266
- runWithOwner(this.Kt, () => {
425
+ const t = this.ws();
426
+ const s = this.Os?.() || 0;
427
+ runWithOwner(this.ts, () => {
267
428
  if (t === 0) {
268
- if (this.$t !== 0) {
269
- this.Kt.dispose(false);
270
- this.ts = [];
271
- this.Zt = [];
272
- this.$t = 0;
429
+ if (this.ss !== 0) {
430
+ this.ts.dispose(false);
431
+ this.fs = [];
432
+ this.hs = [];
433
+ this.ss = 0;
273
434
  // Reset offset to match the cleared data (#2767, repro 2).
274
- this.cs = 0;
435
+ this.ds = 0;
275
436
  }
276
- if (this.hs && !this.Zt[0]) {
437
+ if (this.ps && !this.hs[0]) {
277
438
  // an aborted fallback attempt leaves an owner without a mapping;
278
439
  // dispose it before re-creating
279
- this.ts[0]?.dispose();
280
- this.Zt[0] = runWithOwner(this.ts[0] = createOwner(), this.hs);
440
+ this.fs[0]?.dispose();
441
+ this.hs[0] = runWithOwner(this.fs[0] = createOwner(), this.ps);
281
442
  }
282
443
  return;
283
444
  }
284
445
  const i = s + t;
285
- const e = this.cs + this.$t;
446
+ const e = this.ds + this.ss;
286
447
  // Retained overlap [keepStart, keepEnd) in global indexes; empty when the
287
448
  // windows are disjoint or when coming from empty/fallback.
288
- const r = Math.max(s, this.cs);
449
+ const r = Math.max(s, this.ds);
289
450
  const n = Math.min(i, e);
290
- const h = new Array(t);
291
451
  const o = new Array(t);
452
+ const h = new Array(t);
292
453
  for (let t = r; t < n; t++) {
293
- o[t - s] = this.ts[t - this.cs];
294
- h[t - s] = this.Zt[t - this.cs];
454
+ h[t - s] = this.fs[t - this.ds];
455
+ o[t - s] = this.hs[t - this.ds];
295
456
  }
296
457
  try {
297
458
  for (let t = s; t < i; t++) {
298
459
  if (t >= r && t < n) continue;
299
- h[t - s] = runWithOwner(o[t - s] = createOwner(), () => this.Yt(t));
460
+ o[t - s] = runWithOwner(h[t - s] = createOwner(), () => this.ns(t));
300
461
  }
301
462
  } catch (t) {
302
- for (let t = s; t < i; t++) if ((t < r || t >= n) && o[t - s]) o[t - s].dispose();
463
+ for (let t = s; t < i; t++) if ((t < r || t >= n) && h[t - s]) h[t - s].dispose();
303
464
  throw t;
304
465
  }
305
466
  // commit: dispose the previous fallback or the rows leaving the window
306
- if (this.$t === 0) this.ts[0]?.dispose(); else for (let t = this.cs; t < e; t++) if (t < s || t >= i) this.ts[t - this.cs].dispose();
307
- this.Zt = h;
308
- this.ts = o;
309
- this.cs = s;
310
- this.$t = t;
467
+ if (this.ss === 0) this.fs[0]?.dispose(); else for (let t = this.ds; t < e; t++) if (t < s || t >= i) this.fs[t - this.ds].dispose();
468
+ this.hs = o;
469
+ this.fs = h;
470
+ this.ds = s;
471
+ this.ss = t;
311
472
  });
312
- return this.Zt;
473
+ return this.hs;
313
474
  }
314
475
 
315
476
  function compare(t, s, i) {