@solidjs/signals 2.0.0-rc.19 → 2.0.0-rc.20
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.
- package/dist/dev-shared.js +553 -264
- package/dist/dev.attribution.js +18 -18
- package/dist/dev.js +1030 -439
- package/dist/observe/affects.js +12 -2
- package/dist/observe/boundaries.js +168 -115
- package/dist/observe/core/async.js +57 -37
- package/dist/observe/core/attribution.js +6 -6
- package/dist/observe/core/constants.js +9 -1
- package/dist/observe/core/copies.js +10 -0
- package/dist/observe/core/core.js +261 -181
- package/dist/observe/core/effect.js +32 -27
- package/dist/observe/core/graph.js +7 -7
- package/dist/observe/core/heap.js +29 -29
- package/dist/observe/core/lanes.js +301 -101
- package/dist/observe/core/owner.js +13 -13
- package/dist/observe/core/scheduler.js +124 -69
- package/dist/observe/core/truth.js +9 -7
- package/dist/observe/core/verdict.js +160 -98
- package/dist/observe/deferred.js +1 -1
- package/dist/observe/index.js +2 -0
- package/dist/observe/map.js +120 -116
- package/dist/observe/reveal.js +48 -48
- package/dist/observe/signals.js +5 -5
- package/dist/observe/store/affects.js +2 -2
- package/dist/observe/store/optimistic.js +272 -176
- package/dist/observe/store/projection.js +21 -10
- package/dist/observe/store/reconcile.js +8 -2
- package/dist/observe/store/store.js +91 -55
- package/dist/observe/store/types.js +11 -1
- package/dist/observe/store/utils.js +1 -1
- package/dist/prod/affects.js +12 -2
- package/dist/prod/boundaries.js +164 -109
- package/dist/prod/core/async.js +201 -181
- package/dist/prod/core/constants.js +9 -1
- package/dist/prod/core/copies.js +10 -0
- package/dist/prod/core/core.js +244 -164
- package/dist/prod/core/dev.js +108 -3
- package/dist/prod/core/effect.js +28 -23
- package/dist/prod/core/graph.js +9 -9
- package/dist/prod/core/heap.js +16 -16
- package/dist/prod/core/identities.js +1 -1
- package/dist/prod/core/lanes.js +307 -95
- package/dist/prod/core/owner.js +22 -22
- package/dist/prod/core/scheduler.js +266 -211
- package/dist/prod/core/truth.js +9 -7
- package/dist/prod/core/verdict.js +161 -99
- package/dist/prod/deferred.js +1 -1
- package/dist/prod/index.js +2 -0
- package/dist/prod/map.js +78 -74
- package/dist/prod/reveal.js +34 -34
- package/dist/prod/signals.js +3 -3
- package/dist/prod/store/affects.js +15 -15
- package/dist/prod/store/optimistic.js +185 -89
- package/dist/prod/store/projection.js +49 -38
- package/dist/prod/store/reconcile.js +8 -2
- package/dist/prod/store/store.js +99 -63
- package/dist/prod/store/types.js +11 -1
- package/dist/types/affects.d.ts +3 -2
- package/dist/types/boundaries.d.ts +14 -2
- package/dist/types/core/async.d.ts +2 -1
- package/dist/types/core/constants.d.ts +8 -0
- package/dist/types/core/copies.d.ts +54 -0
- package/dist/types/core/core.d.ts +15 -0
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +8 -1
- package/dist/types/core/scheduler.d.ts +36 -4
- package/dist/types/core/truth.d.ts +3 -1
- package/dist/types/core/types.d.ts +6 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/store/hooks.d.ts +15 -1
- package/dist/types/store/store.d.ts +2 -1
- package/dist/types/store/target.d.ts +5 -0
- package/dist/types/store/types.d.ts +7 -0
- package/package.json +1 -1
package/dist/observe/map.js
CHANGED
|
@@ -16,7 +16,7 @@ import "./core/effect.js";
|
|
|
16
16
|
|
|
17
17
|
import { accessor } from "./signals.js";
|
|
18
18
|
|
|
19
|
-
import { $TRACK } from "./store/types.js";
|
|
19
|
+
import { $TRACK, shallowView, $TARGET } from "./store/types.js";
|
|
20
20
|
|
|
21
21
|
function mapArray(t, e, i) {
|
|
22
22
|
const s = typeof i?.keyed === "function" ? i.keyed : undefined;
|
|
@@ -25,13 +25,13 @@ function mapArray(t, e, i) {
|
|
|
25
25
|
const o = {
|
|
26
26
|
H: createOwner(),
|
|
27
27
|
wt: 0,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
Mt: t,
|
|
29
|
+
Wt: [],
|
|
30
|
+
vt: r,
|
|
31
|
+
Kt: [],
|
|
32
32
|
Ye: [],
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
gt: s,
|
|
34
|
+
$t: s || i?.keyed === false ? [] : undefined,
|
|
35
35
|
xt: n && i?.keyed !== false ? [] : undefined,
|
|
36
36
|
Ut: i?.keyed === false,
|
|
37
37
|
L: i?.fallback
|
|
@@ -48,7 +48,7 @@ const pureOptions = {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
function trySmallMove(t, e, i, s) {
|
|
51
|
-
const n = t.
|
|
51
|
+
const n = t.Wt;
|
|
52
52
|
const r = t.wt - 1;
|
|
53
53
|
const o = [];
|
|
54
54
|
const f = [];
|
|
@@ -74,29 +74,29 @@ function trySmallMove(t, e, i, s) {
|
|
|
74
74
|
u = false;
|
|
75
75
|
// Bounded realignment lookahead, shorter distance wins.
|
|
76
76
|
let d = -1;
|
|
77
|
-
let
|
|
78
|
-
for (let t = 1; t <=
|
|
77
|
+
let w = Math.min(32 - o.length, r - a, c);
|
|
78
|
+
for (let t = 1; t <= w; t++) {
|
|
79
79
|
if (n[a + t] === s) {
|
|
80
80
|
d = t;
|
|
81
81
|
break;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
c -= d === -1 ?
|
|
85
|
-
let
|
|
86
|
-
|
|
87
|
-
for (let i = 1; i <=
|
|
84
|
+
c -= d === -1 ? w : d;
|
|
85
|
+
let p = -1;
|
|
86
|
+
w = Math.min(32 - f.length, i - 1 - l, c);
|
|
87
|
+
for (let i = 1; i <= w; i++) {
|
|
88
88
|
if (e[l + i] === t) {
|
|
89
|
-
|
|
89
|
+
p = i;
|
|
90
90
|
break;
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
c -=
|
|
94
|
-
if (d !== -1 && (
|
|
93
|
+
c -= p === -1 ? w : p;
|
|
94
|
+
if (d !== -1 && (p === -1 || d <= p)) {
|
|
95
95
|
while (d-- > 0) o.push(a++);
|
|
96
96
|
continue;
|
|
97
97
|
}
|
|
98
|
-
if (
|
|
99
|
-
while (
|
|
98
|
+
if (p !== -1) {
|
|
99
|
+
while (p-- > 0) f.push(l++);
|
|
100
100
|
continue;
|
|
101
101
|
}
|
|
102
102
|
if (c <= 0 || o.length === 32 || f.length === 32) return false;
|
|
@@ -121,7 +121,7 @@ function trySmallMove(t, e, i, s) {
|
|
|
121
121
|
* body. Pairs displaced sources with destinations (an unmatched destination
|
|
122
122
|
* is a replacement/insertion → general path), then commits: slice() the live
|
|
123
123
|
* arrays, copy shifted runs, patch displaced pairs, dispose leftovers. */ function commitSmallMove(t, e, i, s, n, r) {
|
|
124
|
-
const o = t.
|
|
124
|
+
const o = t.Wt;
|
|
125
125
|
let f;
|
|
126
126
|
let h;
|
|
127
127
|
let c;
|
|
@@ -156,7 +156,7 @@ function trySmallMove(t, e, i, s) {
|
|
|
156
156
|
for (let s = 0, n = r[e + 2]; s < n; s++) if (t.has(o[i + s])) return false;
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
const a = t.
|
|
159
|
+
const a = t.Kt;
|
|
160
160
|
const l = t.Ye;
|
|
161
161
|
const u = a.slice(0, i);
|
|
162
162
|
const d = l.slice(0, i);
|
|
@@ -176,10 +176,10 @@ function trySmallMove(t, e, i, s) {
|
|
|
176
176
|
u[t] = a[e];
|
|
177
177
|
d[t] = l[e];
|
|
178
178
|
}
|
|
179
|
-
t.
|
|
179
|
+
t.Kt = u;
|
|
180
180
|
t.Ye = d;
|
|
181
181
|
t.wt = i;
|
|
182
|
-
t.
|
|
182
|
+
t.Wt = e.slice(0);
|
|
183
183
|
// Dispose unmatched sources LAST (general-path ordering).
|
|
184
184
|
for (f = 0; f < s.length; f++) {
|
|
185
185
|
if (c === undefined || !c[f]) l[s[f]].dispose();
|
|
@@ -195,22 +195,22 @@ function trySmallMove(t, e, i, s) {
|
|
|
195
195
|
* the map path below starts from scratch (it rewrites every window slot of
|
|
196
196
|
* `temp` / `rows` / `indexes`, so only `tempNodes`' `!== undefined` probe
|
|
197
197
|
* needs the reset). The stage arrays are scratch — nothing live is touched. */ function stageRemoval(t, e, i, s, n, r, o, f, h) {
|
|
198
|
-
const c = t.
|
|
199
|
-
const a = t.
|
|
198
|
+
const c = t.gt;
|
|
199
|
+
const a = t.Wt;
|
|
200
200
|
const l = t.Ye;
|
|
201
201
|
const u = [];
|
|
202
202
|
let d = i;
|
|
203
|
-
for (let
|
|
204
|
-
const n = c ? c(e[
|
|
203
|
+
for (let w = i; w <= n; d++, w++) {
|
|
204
|
+
const n = c ? c(e[w]) : e[w];
|
|
205
205
|
while (d <= s && (c ? c(a[d]) : a[d]) !== n) u.push(l[d++]);
|
|
206
206
|
if (d > s) {
|
|
207
207
|
o.fill(undefined);
|
|
208
208
|
return null;
|
|
209
209
|
}
|
|
210
|
-
r[
|
|
211
|
-
o[
|
|
212
|
-
if (f) f[
|
|
213
|
-
if (h) h[
|
|
210
|
+
r[w] = t.Kt[d];
|
|
211
|
+
o[w - i] = l[d];
|
|
212
|
+
if (f) f[w - i] = t.$t[d];
|
|
213
|
+
if (h) h[w - i] = t.xt[d];
|
|
214
214
|
}
|
|
215
215
|
for (;d <= s; d++) u.push(l[d]);
|
|
216
216
|
return u;
|
|
@@ -223,40 +223,40 @@ function trySmallMove(t, e, i, s) {
|
|
|
223
223
|
* the JIT's optimization budget — the inlined commit measured ~10% slower on
|
|
224
224
|
* full-window reorders (the small-move note has the same finding). */ function commitWindow(t, e, i, s, n, r, o, f, h) {
|
|
225
225
|
const c = t.Ye;
|
|
226
|
-
const a = t
|
|
226
|
+
const a = t.$t;
|
|
227
227
|
const l = t.xt;
|
|
228
228
|
const u = t.wt;
|
|
229
229
|
const d = i - u;
|
|
230
|
-
let
|
|
230
|
+
let w, p;
|
|
231
231
|
if (d > 0) {
|
|
232
232
|
// Grow first: a store past the end from the top is a third slower than
|
|
233
233
|
// filling a pre-sized tail (measured on 1k refs, 2026-10-15).
|
|
234
234
|
c.length = i;
|
|
235
235
|
if (a) a.length = i;
|
|
236
236
|
if (l) l.length = i;
|
|
237
|
-
for (
|
|
238
|
-
c[
|
|
239
|
-
if (a) a[
|
|
240
|
-
if (l) l[
|
|
237
|
+
for (w = u - 1, p = i - 1; w > n; w--, p--) {
|
|
238
|
+
c[p] = c[w];
|
|
239
|
+
if (a) a[p] = a[w];
|
|
240
|
+
if (l) l[p] = l[w];
|
|
241
241
|
}
|
|
242
242
|
} else if (d < 0) {
|
|
243
|
-
for (
|
|
244
|
-
c[
|
|
245
|
-
if (a) a[
|
|
246
|
-
if (l) l[
|
|
243
|
+
for (w = n + 1, p = r + 1; w < u; w++, p++) {
|
|
244
|
+
c[p] = c[w];
|
|
245
|
+
if (a) a[p] = a[w];
|
|
246
|
+
if (l) l[p] = l[w];
|
|
247
247
|
}
|
|
248
248
|
c.length = i;
|
|
249
249
|
if (a) a.length = i;
|
|
250
250
|
if (l) l.length = i;
|
|
251
251
|
}
|
|
252
|
-
for (
|
|
253
|
-
c[
|
|
254
|
-
if (a) setSignal(a[
|
|
255
|
-
if (l) setSignal(l[
|
|
252
|
+
for (p = s; p <= r; p++) {
|
|
253
|
+
c[p] = o[p - s];
|
|
254
|
+
if (a) setSignal(a[p] = f[p - s], e[p]);
|
|
255
|
+
if (l) setSignal(l[p] = h[p - s], p);
|
|
256
256
|
}
|
|
257
|
-
for (
|
|
258
|
-
if (a) setSignal(a[
|
|
259
|
-
if (l && d !== 0) setSignal(l[
|
|
257
|
+
for (p = r + 1; p < i; p++) {
|
|
258
|
+
if (a) setSignal(a[p], e[p]);
|
|
259
|
+
if (l && d !== 0) setSignal(l[p], p);
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
|
|
@@ -267,11 +267,15 @@ function updateKeyedMap() {
|
|
|
267
267
|
// the flight's reader (pending tracking + post-settle retry) instead of
|
|
268
268
|
// vanishing. Set per pass: the first pass runs inside `computed()`, before
|
|
269
269
|
// the node exists to the caller.
|
|
270
|
-
this.H.
|
|
271
|
-
|
|
270
|
+
this.H.Ht = getOwner();
|
|
271
|
+
let t = this.Mt() || [];
|
|
272
272
|
t[$TRACK];
|
|
273
273
|
// top level tracking (a store array's container node)
|
|
274
|
-
|
|
274
|
+
// A shallow store array diffs its backing: its slots are raw records, and
|
|
275
|
+
// a trap per slot read was most of a one-row write on a 1k-row list.
|
|
276
|
+
t = shallowView?.(t[$TARGET]) ?? t;
|
|
277
|
+
const e = t.length;
|
|
278
|
+
runWithOwner(this.H, () => {
|
|
275
279
|
let i, s,
|
|
276
280
|
// The stage slot a mapper writes its row/index signal into: `j` on the
|
|
277
281
|
// create-all path, `j - start` on the general path, whose stage arrays
|
|
@@ -279,44 +283,44 @@ function updateKeyedMap() {
|
|
|
279
283
|
n, r, o,
|
|
280
284
|
// Mappers write freshly-created row/index signals into the STAGE
|
|
281
285
|
// arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
|
|
282
|
-
f = this
|
|
286
|
+
f = this.$t ? this.Ut ? () => {
|
|
283
287
|
r[n] = signal(t[s], pureOptions);
|
|
284
|
-
return this.
|
|
288
|
+
return this.vt(accessor(r[n]), s);
|
|
285
289
|
} : () => {
|
|
286
290
|
r[n] = signal(t[s], pureOptions);
|
|
287
291
|
o && (o[n] = signal(s, pureOptions));
|
|
288
|
-
return this.
|
|
292
|
+
return this.vt(accessor(r[n]), o ? accessor(o[n]) : undefined);
|
|
289
293
|
} : this.xt ? () => {
|
|
290
294
|
const e = t[s];
|
|
291
295
|
o[n] = signal(s, pureOptions);
|
|
292
|
-
return this.
|
|
296
|
+
return this.vt(e, accessor(o[n]));
|
|
293
297
|
} : () => {
|
|
294
298
|
const e = t[s];
|
|
295
|
-
return this.
|
|
299
|
+
return this.vt(e);
|
|
296
300
|
};
|
|
297
301
|
// fast path for empty arrays
|
|
298
302
|
if (e === 0) {
|
|
299
303
|
if (this.wt !== 0) {
|
|
300
304
|
this.H.dispose(false);
|
|
301
305
|
this.Ye = [];
|
|
302
|
-
this.
|
|
303
|
-
this.
|
|
306
|
+
this.Wt = [];
|
|
307
|
+
this.Kt = [];
|
|
304
308
|
this.wt = 0;
|
|
305
|
-
this
|
|
309
|
+
this.$t && (this.$t = []);
|
|
306
310
|
this.xt && (this.xt = []);
|
|
307
311
|
}
|
|
308
|
-
if (this.L && !this.
|
|
312
|
+
if (this.L && !this.Kt.length) {
|
|
309
313
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
310
314
|
// dispose it before re-creating
|
|
311
315
|
this.Ye[0]?.dispose();
|
|
312
|
-
this.
|
|
316
|
+
this.Kt[0] = runWithOwner(this.Ye[0] = createOwner(), this.L);
|
|
313
317
|
}
|
|
314
318
|
}
|
|
315
319
|
// fast path for new create
|
|
316
320
|
else if (this.wt === 0) {
|
|
317
321
|
const h = new Array(e);
|
|
318
322
|
const c = new Array(e);
|
|
319
|
-
r = this
|
|
323
|
+
r = this.$t && new Array(e);
|
|
320
324
|
o = this.xt && new Array(e);
|
|
321
325
|
try {
|
|
322
326
|
for (s = 0; s < e; s++) {
|
|
@@ -330,14 +334,14 @@ function updateKeyedMap() {
|
|
|
330
334
|
// commit
|
|
331
335
|
if (this.Ye[0]) this.Ye[0].dispose();
|
|
332
336
|
// previous fallback
|
|
333
|
-
this.
|
|
337
|
+
this.Kt = h;
|
|
334
338
|
this.Ye = c;
|
|
335
|
-
r && (this
|
|
339
|
+
r && (this.$t = r);
|
|
336
340
|
o && (this.xt = o);
|
|
337
|
-
this.
|
|
341
|
+
this.Wt = t.slice(0);
|
|
338
342
|
this.wt = e;
|
|
339
343
|
} else {
|
|
340
|
-
let h, c, a, l, u, d,
|
|
344
|
+
let h, c, a, l, u, d, w, p, m,
|
|
341
345
|
// Dev (attribution engine installed): the items behind the exited and
|
|
342
346
|
// entered rows, for the list-identity census.
|
|
343
347
|
O, _;
|
|
@@ -364,18 +368,18 @@ function updateKeyedMap() {
|
|
|
364
368
|
// CARVE 2: the lane-slot arm (`_landOnOverride`, F1) went with the engine.
|
|
365
369
|
const y = setSignal;
|
|
366
370
|
// skip common prefix
|
|
367
|
-
for (h = 0, c = Math.min(this.wt, e); h < c && (this.
|
|
368
|
-
if (this
|
|
371
|
+
for (h = 0, c = Math.min(this.wt, e); h < c && (this.Wt[h] === t[h] || this.$t && compare(this.gt, this.Wt[h], t[h])); h++) {
|
|
372
|
+
if (this.$t) y(this.$t[h], t[h]);
|
|
369
373
|
}
|
|
370
374
|
// skip common suffix — counted only; retained entries land in one pass
|
|
371
375
|
// at commit instead of being staged and copied twice
|
|
372
|
-
for (c = this.wt - 1, a = e - 1; c >= h && a >= h && (this.
|
|
376
|
+
for (c = this.wt - 1, a = e - 1; c >= h && a >= h && (this.Wt[c] === t[a] || this.$t && compare(this.gt, this.Wt[c], t[a])); c--,
|
|
373
377
|
a--) ;
|
|
374
378
|
// no structural change (every position matched in place at equal
|
|
375
379
|
// length — the common post-reconcile shape): keep the same mapped
|
|
376
380
|
// array identity so downstream consumers don't re-run at all
|
|
377
381
|
if (h === e && this.wt === e) {
|
|
378
|
-
this.
|
|
382
|
+
this.Wt = t.slice(0);
|
|
379
383
|
return;
|
|
380
384
|
}
|
|
381
385
|
// SMALL-MOVE FAST PATH: extracted to its own function — inlining it
|
|
@@ -385,7 +389,7 @@ function updateKeyedMap() {
|
|
|
385
389
|
// (plain removals, tail edits), the general path is window-
|
|
386
390
|
// proportional and cheap — the fast path would only re-walk what the
|
|
387
391
|
// trims proved.
|
|
388
|
-
if (e <= this.wt && c - h > 64 && this
|
|
392
|
+
if (e <= this.wt && c - h > 64 && this.$t === undefined && this.xt === undefined) {
|
|
389
393
|
// PROBE before the scan: a small move keeps a mid-window item within
|
|
390
394
|
// ±32 of its old position; a REPLACE (all fresh items — the shape
|
|
391
395
|
// every page's first structural pass usually is) has it nowhere.
|
|
@@ -395,10 +399,10 @@ function updateKeyedMap() {
|
|
|
395
399
|
const s = t[i];
|
|
396
400
|
const n = Math.min(c, i + 32);
|
|
397
401
|
let r = Math.max(h, i - 32);
|
|
398
|
-
while (r <= n && this.
|
|
402
|
+
while (r <= n && this.Wt[r] !== s) r++;
|
|
399
403
|
if (r <= n && trySmallMove(this, t, e, h)) return;
|
|
400
404
|
}
|
|
401
|
-
const
|
|
405
|
+
const A = e - this.wt;
|
|
402
406
|
// WINDOW-SIZED STAGING, IN-PLACE COMMIT (2026-10-15). The strong-abort
|
|
403
407
|
// contract (#2903) only needs the pass to touch nothing live before
|
|
404
408
|
// every mapper has succeeded; it never needed four fresh newLen-sized
|
|
@@ -414,46 +418,46 @@ function updateKeyedMap() {
|
|
|
414
418
|
// staging plus a position-sized chain array per commit (uibench's
|
|
415
419
|
// one-item tree ops at 4–6× Octane, jfb-reorder `removefirst` at
|
|
416
420
|
// 2.5×); now it stages one slot.
|
|
417
|
-
const
|
|
421
|
+
const g = a - h + 1;
|
|
418
422
|
const S = new Array(e);
|
|
419
|
-
const M = new Array(
|
|
420
|
-
r = this
|
|
421
|
-
o = this.xt ? new Array(
|
|
423
|
+
const M = new Array(g);
|
|
424
|
+
r = this.$t ? new Array(g) : undefined;
|
|
425
|
+
o = this.xt ? new Array(g) : undefined;
|
|
422
426
|
// A shrinking pass is tried as a pure removal first (stageRemoval: no
|
|
423
427
|
// key map, one key call per item); anything else takes the map path.
|
|
424
|
-
const k =
|
|
428
|
+
const k = A < 0 ? stageRemoval(this, t, h, c, a, S, M, r, o) : null;
|
|
425
429
|
if (k !== null) {
|
|
426
430
|
// (The list-churn census below wants removals AND creations in one
|
|
427
431
|
// pass; a pure removal has none, so no item ledger is kept here.)
|
|
428
|
-
if (k.length !== 0)
|
|
432
|
+
if (k.length !== 0) p = k;
|
|
429
433
|
} else {
|
|
430
434
|
// 0) prepare a map of all indices in the changed window of newItems,
|
|
431
435
|
// scanning backwards so we encounter them in natural order
|
|
432
436
|
d = new Map;
|
|
433
|
-
|
|
437
|
+
w = new Array(g);
|
|
434
438
|
for (s = a; s >= h; s--) {
|
|
435
439
|
l = t[s];
|
|
436
|
-
u = this.
|
|
440
|
+
u = this.gt ? this.gt(l) : l;
|
|
437
441
|
i = d.get(u);
|
|
438
|
-
|
|
442
|
+
w[s - h] = i === undefined ? -1 : i;
|
|
439
443
|
d.set(u, s);
|
|
440
444
|
}
|
|
441
445
|
// 1) step through the old changed window and see if items can be found
|
|
442
446
|
// in the new set; if so, stage them at their new positions; if not,
|
|
443
447
|
// queue them for disposal at commit
|
|
444
448
|
for (i = h; i <= c; i++) {
|
|
445
|
-
l = this.
|
|
446
|
-
u = this.
|
|
449
|
+
l = this.Wt[i];
|
|
450
|
+
u = this.gt ? this.gt(l) : l;
|
|
447
451
|
s = d.get(u);
|
|
448
452
|
if (s !== undefined && s !== -1) {
|
|
449
|
-
S[s] = this.
|
|
453
|
+
S[s] = this.Kt[i];
|
|
450
454
|
M[s - h] = this.Ye[i];
|
|
451
|
-
r && (r[s - h] = this
|
|
455
|
+
r && (r[s - h] = this.$t[i]);
|
|
452
456
|
o && (o[s - h] = this.xt[i]);
|
|
453
|
-
s =
|
|
457
|
+
s = w[s - h];
|
|
454
458
|
d.set(u, s);
|
|
455
459
|
} else {
|
|
456
|
-
(
|
|
460
|
+
(p ??= []).push(this.Ye[i]);
|
|
457
461
|
if (true && attrHooks !== null) (O ??= []).push(l);
|
|
458
462
|
}
|
|
459
463
|
}
|
|
@@ -475,18 +479,18 @@ function updateKeyedMap() {
|
|
|
475
479
|
// array; the bookkeeping arrays take the staged window IN PLACE (own
|
|
476
480
|
// function: kept out of this body on purpose, see commitWindow); then
|
|
477
481
|
// the exited rows dispose
|
|
478
|
-
for (i = 0; i < h; i++) S[i] = this.
|
|
479
|
-
for (s = a + 1; s < e; s++) S[s] = this.
|
|
482
|
+
for (i = 0; i < h; i++) S[i] = this.Kt[i];
|
|
483
|
+
for (s = a + 1; s < e; s++) S[s] = this.Kt[s - A];
|
|
480
484
|
commitWindow(this, t, e, h, c, a, M, r, o);
|
|
481
|
-
this.
|
|
485
|
+
this.Kt = S;
|
|
482
486
|
this.wt = e;
|
|
483
487
|
// save a copy of the mapped items for the next update
|
|
484
|
-
this.
|
|
485
|
-
if (
|
|
486
|
-
if (true && attrHooks !== null && O !== undefined && _ !== undefined) attrHooks.listChurn(this.H.
|
|
488
|
+
this.Wt = t.slice(0);
|
|
489
|
+
if (p) for (i = 0; i < p.length; i++) p[i].dispose();
|
|
490
|
+
if (true && attrHooks !== null && O !== undefined && _ !== undefined) attrHooks.listChurn(this.H.Ht, O, _, e, this.gt !== undefined);
|
|
487
491
|
}
|
|
488
492
|
});
|
|
489
|
-
return this.
|
|
493
|
+
return this.Kt;
|
|
490
494
|
}
|
|
491
495
|
|
|
492
496
|
/**
|
|
@@ -508,12 +512,12 @@ function updateKeyedMap() {
|
|
|
508
512
|
const n = {
|
|
509
513
|
H: createOwner(),
|
|
510
514
|
wt: 0,
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
515
|
+
qt: 0,
|
|
516
|
+
zt: t,
|
|
517
|
+
vt: s,
|
|
514
518
|
Ye: [],
|
|
515
|
-
|
|
516
|
-
|
|
519
|
+
Kt: [],
|
|
520
|
+
Bt: i?.from,
|
|
517
521
|
L: i?.fallback
|
|
518
522
|
};
|
|
519
523
|
const r = computed(updateRepeat.bind(n));
|
|
@@ -530,56 +534,56 @@ function updateKeyedMap() {
|
|
|
530
534
|
// disjoint-window/front-clear/end-clear/shift special cases.
|
|
531
535
|
function updateRepeat() {
|
|
532
536
|
// As in updateKeyedMap: the node is the row callbacks' reader, per pass.
|
|
533
|
-
this.H.
|
|
534
|
-
const t = this.
|
|
535
|
-
const e = this.
|
|
537
|
+
this.H.Ht = getOwner();
|
|
538
|
+
const t = this.zt();
|
|
539
|
+
const e = this.Bt?.() || 0;
|
|
536
540
|
runWithOwner(this.H, () => {
|
|
537
541
|
if (t === 0) {
|
|
538
542
|
if (this.wt !== 0) {
|
|
539
543
|
this.H.dispose(false);
|
|
540
544
|
this.Ye = [];
|
|
541
|
-
this.
|
|
545
|
+
this.Kt = [];
|
|
542
546
|
this.wt = 0;
|
|
543
547
|
// Reset offset to match the cleared data (#2767, repro 2).
|
|
544
|
-
this
|
|
548
|
+
this.qt = 0;
|
|
545
549
|
}
|
|
546
|
-
if (this.L && !this.
|
|
550
|
+
if (this.L && !this.Kt.length) {
|
|
547
551
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
548
552
|
// dispose it before re-creating
|
|
549
553
|
this.Ye[0]?.dispose();
|
|
550
|
-
this.
|
|
554
|
+
this.Kt[0] = runWithOwner(this.Ye[0] = createOwner(), this.L);
|
|
551
555
|
}
|
|
552
556
|
return;
|
|
553
557
|
}
|
|
554
558
|
const i = e + t;
|
|
555
|
-
const s = this
|
|
559
|
+
const s = this.qt + this.wt;
|
|
556
560
|
// Retained overlap [keepStart, keepEnd) in global indexes; empty when the
|
|
557
561
|
// windows are disjoint or when coming from empty/fallback.
|
|
558
|
-
const n = Math.max(e, this
|
|
562
|
+
const n = Math.max(e, this.qt);
|
|
559
563
|
const r = Math.min(i, s);
|
|
560
564
|
const o = new Array(t);
|
|
561
565
|
const f = new Array(t);
|
|
562
566
|
for (let t = n; t < r; t++) {
|
|
563
|
-
f[t - e] = this.Ye[t - this
|
|
564
|
-
o[t - e] = this.
|
|
567
|
+
f[t - e] = this.Ye[t - this.qt];
|
|
568
|
+
o[t - e] = this.Kt[t - this.qt];
|
|
565
569
|
}
|
|
566
570
|
try {
|
|
567
571
|
for (let t = e; t < i; t++) {
|
|
568
572
|
if (t >= n && t < r) continue;
|
|
569
|
-
o[t - e] = runWithOwner(f[t - e] = createOwner(), () => this.
|
|
573
|
+
o[t - e] = runWithOwner(f[t - e] = createOwner(), () => this.vt(t));
|
|
570
574
|
}
|
|
571
575
|
} catch (t) {
|
|
572
576
|
for (let t = e; t < i; t++) if ((t < n || t >= r) && f[t - e]) f[t - e].dispose();
|
|
573
577
|
throw t;
|
|
574
578
|
}
|
|
575
579
|
// commit: dispose the previous fallback or the rows leaving the window
|
|
576
|
-
if (this.wt === 0) this.Ye[0]?.dispose(); else for (let t = this
|
|
577
|
-
this.
|
|
580
|
+
if (this.wt === 0) this.Ye[0]?.dispose(); else for (let t = this.qt; t < s; t++) if (t < e || t >= i) this.Ye[t - this.qt].dispose();
|
|
581
|
+
this.Kt = o;
|
|
578
582
|
this.Ye = f;
|
|
579
|
-
this
|
|
583
|
+
this.qt = e;
|
|
580
584
|
this.wt = t;
|
|
581
585
|
});
|
|
582
|
-
return this.
|
|
586
|
+
return this.Kt;
|
|
583
587
|
}
|
|
584
588
|
|
|
585
589
|
function compare(t, e, i) {
|