@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.
- package/dist/dev-shared.js +5243 -0
- package/dist/dev.attribution.js +2333 -0
- package/dist/dev.js +1758 -6621
- package/dist/observe/affects.js +127 -0
- package/dist/observe/attribution.js +1 -0
- package/dist/observe/boundaries.js +586 -0
- package/dist/observe/core/action.js +167 -0
- package/dist/observe/core/async.js +736 -0
- package/dist/observe/core/attribution-hooks.js +60 -0
- package/dist/observe/core/attribution.js +2318 -0
- package/dist/{types-cjs/core/constants.d.cts → observe/core/constants.js} +135 -71
- package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
- package/dist/observe/core/core.js +1289 -0
- package/dist/observe/core/dev.js +232 -0
- package/dist/observe/core/effect.js +179 -0
- package/dist/observe/core/error.js +80 -0
- package/dist/observe/core/external.js +98 -0
- package/dist/observe/core/graph.js +155 -0
- package/dist/observe/core/heap.js +147 -0
- package/dist/observe/core/invariants.js +43 -0
- package/dist/observe/core/lanes.js +168 -0
- package/dist/observe/core/optimistic.js +438 -0
- package/dist/observe/core/owner.js +308 -0
- package/dist/observe/core/scheduler.js +1190 -0
- package/dist/observe/core/verdict.js +551 -0
- package/dist/observe/index.js +55 -0
- package/dist/observe/map.js +482 -0
- package/dist/{types-cjs/signals.d.cts → observe/signals.js} +305 -317
- package/dist/observe/store/index.js +38 -0
- package/dist/observe/store/next/optimistic.js +651 -0
- package/dist/observe/store/next/projection.js +242 -0
- package/dist/observe/store/next/reconcile.js +373 -0
- package/dist/observe/store/next/store.js +2213 -0
- package/dist/observe/store/next/target.js +51 -0
- package/dist/observe/store/store.js +323 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/utils.js +210 -0
- package/dist/prod/attribution.js +32 -0
- package/dist/prod/boundaries.js +3 -1
- package/dist/prod/core/action.js +52 -32
- package/dist/prod/core/async.js +177 -128
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +32 -1
- package/dist/prod/core/context.js +10 -16
- package/dist/prod/core/core.js +505 -286
- package/dist/prod/core/dev.js +2 -0
- package/dist/prod/core/effect.js +72 -43
- package/dist/prod/core/external.js +2 -2
- package/dist/prod/core/graph.js +40 -36
- package/dist/prod/core/heap.js +50 -51
- package/dist/prod/core/lanes.js +43 -22
- package/dist/prod/core/optimistic.js +224 -80
- package/dist/prod/core/owner.js +43 -39
- package/dist/prod/core/scheduler.js +347 -232
- package/dist/prod/core/verdict.js +71 -74
- package/dist/prod/index.js +9 -5
- package/dist/prod/map.js +311 -150
- package/dist/prod/signals.js +52 -38
- package/dist/prod/store/next/optimistic.js +127 -131
- package/dist/prod/store/next/projection.js +3 -3
- package/dist/prod/store/next/reconcile.js +149 -294
- package/dist/prod/store/next/store.js +694 -380
- package/dist/prod/store/next/target.js +32 -10
- package/dist/prod/store/store.js +12 -14
- package/dist/prod/store/utils.js +36 -27
- package/dist/types/attribution.d.ts +15 -0
- package/dist/types/attribution.prod.d.ts +13 -0
- package/dist/types/core/async.d.ts +1 -1
- package/dist/types/core/attribution-hooks.d.ts +183 -6
- package/dist/types/core/attribution.d.ts +435 -24
- package/dist/types/core/constants.d.ts +31 -0
- package/dist/types/core/core.d.ts +19 -3
- package/dist/types/core/dev.d.ts +165 -26
- package/dist/types/core/effect.d.ts +8 -1
- package/dist/types/core/heap.d.ts +5 -3
- package/dist/types/core/index.d.ts +2 -1
- package/dist/types/core/invariants.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +17 -0
- package/dist/types/core/scheduler.d.ts +69 -4
- package/dist/types/core/types.d.ts +29 -9
- package/dist/types/index.d.ts +9 -2
- package/dist/types/map.d.ts +2 -0
- package/dist/types/signals.d.ts +10 -0
- package/dist/types/store/index.d.ts +4 -6
- package/dist/types/store/next/optimistic.d.ts +4 -2
- package/dist/types/store/next/reconcile.d.ts +5 -12
- package/dist/types/store/next/store.d.ts +8 -9
- package/dist/types/store/next/target.d.ts +56 -55
- package/dist/types/store/store.d.ts +14 -9
- package/dist/types/store/utils.d.ts +7 -0
- package/package.json +21 -16
- package/dist/node.cjs +0 -11121
- package/dist/prod/store/next/patch-hooks.js +0 -13
- package/dist/prod/store/next/patch.js +0 -614
- package/dist/types/store/next/patch-hooks.d.ts +0 -41
- package/dist/types/store/next/patch.d.ts +0 -91
- package/dist/types-cjs/affects.d.cts +0 -47
- package/dist/types-cjs/boundaries.d.cts +0 -175
- package/dist/types-cjs/core/action.d.cts +0 -64
- package/dist/types-cjs/core/async.d.cts +0 -23
- package/dist/types-cjs/core/attribution-hooks.d.cts +0 -63
- package/dist/types-cjs/core/attribution.d.cts +0 -239
- package/dist/types-cjs/core/core.d.cts +0 -176
- package/dist/types-cjs/core/dev.d.cts +0 -95
- package/dist/types-cjs/core/effect.d.cts +0 -30
- package/dist/types-cjs/core/error.d.cts +0 -56
- package/dist/types-cjs/core/external.d.cts +0 -15
- package/dist/types-cjs/core/graph.d.cts +0 -28
- package/dist/types-cjs/core/heap.d.cts +0 -22
- package/dist/types-cjs/core/index.d.cts +0 -13
- package/dist/types-cjs/core/invariants.d.cts +0 -59
- package/dist/types-cjs/core/lanes.d.cts +0 -44
- package/dist/types-cjs/core/optimistic.d.cts +0 -6
- package/dist/types-cjs/core/owner.d.cts +0 -124
- package/dist/types-cjs/core/scheduler.d.cts +0 -231
- package/dist/types-cjs/core/types.d.cts +0 -204
- package/dist/types-cjs/core/verdict.d.cts +0 -2
- package/dist/types-cjs/index.d.cts +0 -10
- package/dist/types-cjs/map.d.cts +0 -69
- package/dist/types-cjs/package.json +0 -3
- package/dist/types-cjs/store/index.d.cts +0 -21
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -23
- package/dist/types-cjs/store/next/patch-hooks.d.cts +0 -41
- package/dist/types-cjs/store/next/patch.d.cts +0 -91
- package/dist/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -17
- package/dist/types-cjs/store/next/store.d.cts +0 -127
- package/dist/types-cjs/store/next/target.d.cts +0 -192
- package/dist/types-cjs/store/store.d.cts +0 -138
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- 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
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
return accessor(
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
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.
|
|
194
|
+
const t = this.es() || [], s = t.length;
|
|
62
195
|
t[$TRACK];
|
|
63
196
|
// top level tracking
|
|
64
|
-
runWithOwner(this.
|
|
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
|
-
|
|
201
|
+
o = this.cs ? this.us ? () => {
|
|
69
202
|
r[e] = signal(t[e], pureOptions);
|
|
70
|
-
return this.
|
|
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.
|
|
75
|
-
} : this.
|
|
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.
|
|
211
|
+
return this.ns(s, accessor(n[e]));
|
|
79
212
|
} : () => {
|
|
80
213
|
const s = t[e];
|
|
81
|
-
return this.
|
|
214
|
+
return this.ns(s);
|
|
82
215
|
};
|
|
83
216
|
// fast path for empty arrays
|
|
84
217
|
if (s === 0) {
|
|
85
|
-
if (this
|
|
86
|
-
this.
|
|
87
|
-
this.
|
|
88
|
-
this.
|
|
89
|
-
this.
|
|
90
|
-
this
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
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.
|
|
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.
|
|
98
|
-
this.
|
|
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
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
r = this.
|
|
106
|
-
n = this.
|
|
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++)
|
|
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++)
|
|
243
|
+
for (i = 0; i <= e; i++) f[i]?.dispose();
|
|
111
244
|
throw t;
|
|
112
245
|
}
|
|
113
246
|
// commit
|
|
114
|
-
if (this.
|
|
247
|
+
if (this.fs[0]) this.fs[0].dispose();
|
|
115
248
|
// previous fallback
|
|
116
|
-
this.
|
|
117
|
-
this.
|
|
118
|
-
r && (this.
|
|
119
|
-
n && (this.
|
|
120
|
-
this.
|
|
121
|
-
this
|
|
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
|
|
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 (
|
|
126
|
-
if (this.
|
|
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 (
|
|
131
|
-
|
|
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 (
|
|
136
|
-
this.
|
|
271
|
+
if (h === s && this.ss === s) {
|
|
272
|
+
this.rs = t.slice(0);
|
|
137
273
|
return;
|
|
138
274
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
for (e =
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
i =
|
|
152
|
-
|
|
153
|
-
|
|
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 =
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
e =
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
r && (r[e] = this.
|
|
166
|
-
n && (n[e] = this.
|
|
167
|
-
e =
|
|
168
|
-
|
|
169
|
-
} else
|
|
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 =
|
|
174
|
-
if (
|
|
175
|
-
(
|
|
176
|
-
|
|
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 (
|
|
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 <
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
r && (r[i] = this.
|
|
189
|
-
n && (n[i] = this.
|
|
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 =
|
|
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 =
|
|
196
|
-
|
|
197
|
-
|
|
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.
|
|
359
|
+
r[e] = this.cs[e - _];
|
|
200
360
|
setSignal(r[e], t[e]);
|
|
201
361
|
}
|
|
202
362
|
if (n) {
|
|
203
|
-
n[e] = this.
|
|
204
|
-
if (
|
|
363
|
+
n[e] = this.ls[e - _];
|
|
364
|
+
if (_ !== 0) setSignal(n[e], e);
|
|
205
365
|
}
|
|
206
366
|
}
|
|
207
|
-
this.
|
|
208
|
-
this.
|
|
209
|
-
r && (this.
|
|
210
|
-
n && (this.
|
|
211
|
-
this
|
|
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.
|
|
214
|
-
if (
|
|
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.
|
|
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
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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.
|
|
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.
|
|
265
|
-
const s = this.
|
|
266
|
-
runWithOwner(this.
|
|
425
|
+
const t = this.ws();
|
|
426
|
+
const s = this.Os?.() || 0;
|
|
427
|
+
runWithOwner(this.ts, () => {
|
|
267
428
|
if (t === 0) {
|
|
268
|
-
if (this
|
|
269
|
-
this.
|
|
270
|
-
this.
|
|
271
|
-
this.
|
|
272
|
-
this
|
|
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.
|
|
435
|
+
this.ds = 0;
|
|
275
436
|
}
|
|
276
|
-
if (this.
|
|
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.
|
|
280
|
-
this.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
294
|
-
|
|
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
|
-
|
|
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) &&
|
|
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
|
|
307
|
-
this.
|
|
308
|
-
this.
|
|
309
|
-
this.
|
|
310
|
-
this
|
|
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.
|
|
473
|
+
return this.hs;
|
|
313
474
|
}
|
|
314
475
|
|
|
315
476
|
function compare(t, s, i) {
|