@solidjs/signals 2.0.0-rc.7 → 2.0.0-rc.9
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 +6357 -0
- package/dist/dev.attribution.js +2485 -0
- package/dist/dev.js +2851 -7027
- package/dist/observe/affects.js +129 -0
- package/dist/observe/attribution.js +7 -0
- package/dist/observe/boundaries.js +641 -0
- package/dist/observe/core/action.js +177 -0
- package/dist/observe/core/async.js +846 -0
- package/dist/observe/core/attribution-costs.js +66 -0
- package/dist/observe/core/attribution-feedback.js +282 -0
- package/dist/observe/core/attribution-hooks.js +82 -0
- package/dist/observe/core/attribution-queries.js +28 -0
- package/dist/observe/core/attribution.js +2095 -0
- package/dist/observe/core/constants.js +248 -0
- package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
- package/dist/observe/core/core.js +1789 -0
- package/dist/observe/core/dev.js +293 -0
- package/dist/observe/core/effect.js +195 -0
- package/dist/observe/core/error-hooks.js +71 -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 +45 -0
- package/dist/observe/core/lanes.js +205 -0
- package/dist/observe/core/optimistic.js +585 -0
- package/dist/observe/core/owner.js +322 -0
- package/dist/observe/core/scheduler.js +1428 -0
- package/dist/observe/core/verdict.js +669 -0
- package/dist/observe/index.js +59 -0
- package/dist/observe/map.js +484 -0
- package/dist/{types-cjs/signals.d.cts → observe/signals.js} +311 -317
- package/dist/observe/store/index.js +40 -0
- package/dist/observe/store/next/optimistic.js +660 -0
- package/dist/observe/store/next/projection.js +255 -0
- package/dist/observe/store/next/reconcile.js +375 -0
- package/dist/observe/store/next/store.js +2327 -0
- package/dist/observe/store/next/target.js +51 -0
- package/dist/observe/store/store.js +325 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/utils.js +1023 -0
- package/dist/prod/attribution.js +41 -0
- package/dist/prod/boundaries.js +128 -76
- package/dist/prod/core/action.js +65 -37
- package/dist/prod/core/async.js +324 -172
- package/dist/prod/core/constants.js +57 -1
- package/dist/prod/core/context.js +3 -3
- package/dist/prod/core/core.js +1003 -364
- package/dist/prod/core/dev.js +17 -1
- package/dist/prod/core/effect.js +76 -42
- package/dist/prod/core/error-hooks.js +71 -0
- package/dist/prod/core/external.js +4 -4
- package/dist/prod/core/graph.js +37 -37
- package/dist/prod/core/heap.js +61 -56
- package/dist/prod/core/lanes.js +107 -63
- package/dist/prod/core/optimistic.js +374 -93
- package/dist/prod/core/owner.js +62 -46
- package/dist/prod/core/scheduler.js +653 -286
- package/dist/prod/core/verdict.js +245 -127
- package/dist/prod/index.js +15 -5
- package/dist/prod/map.js +292 -141
- package/dist/prod/signals.js +29 -16
- package/dist/prod/store/next/optimistic.js +77 -55
- package/dist/prod/store/next/projection.js +31 -20
- package/dist/prod/store/next/reconcile.js +87 -84
- package/dist/prod/store/next/store.js +718 -401
- package/dist/prod/store/next/target.js +32 -10
- package/dist/prod/store/store.js +12 -14
- package/dist/prod/store/utils.js +950 -130
- package/dist/types/attribution.d.ts +20 -0
- package/dist/types/attribution.prod.d.ts +22 -0
- package/dist/types/boundaries.d.ts +10 -1
- package/dist/types/core/action.d.ts +12 -5
- package/dist/types/core/async.d.ts +1 -1
- package/dist/types/core/attribution-costs.d.ts +35 -0
- package/dist/types/core/attribution-feedback.d.ts +133 -0
- package/dist/types/core/attribution-hooks.d.ts +147 -9
- package/dist/types/core/attribution-queries.d.ts +10 -0
- package/dist/types/core/attribution.d.ts +216 -182
- package/dist/types/core/constants.d.ts +56 -0
- package/dist/types/core/core.d.ts +190 -2
- package/dist/types/core/dev.d.ts +246 -28
- package/dist/types/core/effect.d.ts +8 -1
- package/dist/types/core/error-hooks.d.ts +71 -0
- package/dist/types/core/index.d.ts +4 -1
- package/dist/types/core/invariants.d.ts +4 -0
- package/dist/types/core/lanes.d.ts +39 -5
- package/dist/types/core/scheduler.d.ts +153 -0
- package/dist/types/core/types.d.ts +32 -9
- package/dist/types/index.d.ts +10 -3
- package/dist/types/map.d.ts +2 -0
- package/dist/types/signals.d.ts +8 -0
- package/dist/types/store/index.d.ts +2 -0
- package/dist/types/store/next/optimistic.d.ts +1 -1
- package/dist/types/store/next/store.d.ts +11 -5
- package/dist/types/store/next/target.d.ts +37 -10
- package/dist/types/store/utils.d.ts +178 -0
- package/package.json +21 -17
- package/dist/node.cjs +0 -10541
- package/dist/node.dev.cjs +0 -13724
- 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 -127
- package/dist/types-cjs/core/attribution.d.cts +0 -495
- package/dist/types-cjs/core/constants.d.cts +0 -159
- package/dist/types-cjs/core/core.d.cts +0 -185
- package/dist/types-cjs/core/dev.d.cts +0 -136
- 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 -24
- 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 -54
- 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 -236
- 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 -18
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -25
- package/dist/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -10
- package/dist/types-cjs/store/next/store.d.cts +0 -121
- package/dist/types-cjs/store/next/target.d.cts +0 -166
- package/dist/types-cjs/store/store.d.cts +0 -143
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -74
package/dist/prod/index.js
CHANGED
|
@@ -12,7 +12,9 @@ export { $REFRESH, SUPPORTS_PROXY } from "./core/constants.js";
|
|
|
12
12
|
|
|
13
13
|
import "./core/invariants.js";
|
|
14
14
|
|
|
15
|
-
export {
|
|
15
|
+
export { ownerPath } from "./core/dev.js";
|
|
16
|
+
|
|
17
|
+
export { ROOT_ERROR_HOOK, enforceLoadingBoundary, flush, resetErrorHalt } from "./core/scheduler.js";
|
|
16
18
|
|
|
17
19
|
export { isPending, latest } from "./core/verdict.js";
|
|
18
20
|
|
|
@@ -20,6 +22,8 @@ import "./core/effect.js";
|
|
|
20
22
|
|
|
21
23
|
export { action } from "./core/action.js";
|
|
22
24
|
|
|
25
|
+
export { configureClientErrors } from "./core/error-hooks.js";
|
|
26
|
+
|
|
23
27
|
export { createEffect, createMemo, createOptimistic, createReaction, createRenderEffect, createSignal, createTrackedEffect, onCleanup, onSettled, refresh, resolve, until } from "./signals.js";
|
|
24
28
|
|
|
25
29
|
export { affects } from "./affects.js";
|
|
@@ -32,16 +36,22 @@ export { createErrorBoundary, createLoadingBoundary, createRevealOrder, flatten
|
|
|
32
36
|
|
|
33
37
|
export { $PROXY, $TARGET, $TRACK, isWrappable } from "./store/store.js";
|
|
34
38
|
|
|
39
|
+
export { MergeView, OmitView, SOURCE_MEMO, SOURCE_MERGE, SOURCE_OMIT, SOURCE_PLAIN, SOURCE_PROXY, hasStaticKeys, isStatic, merge, mergeSources, mergeView, omit, omitView, resolvedTable, sourceGet, sourceHas, sourceKeys, sourceOwners, viewOf } from "./store/utils.js";
|
|
40
|
+
|
|
35
41
|
export { createOptimisticStoreNext as createOptimisticStore } from "./store/next/optimistic.js";
|
|
36
42
|
|
|
37
43
|
export { createProjectionNext as createProjection } from "./store/next/projection.js";
|
|
38
44
|
|
|
39
|
-
export { merge, omit } from "./store/utils.js";
|
|
40
|
-
|
|
41
45
|
export { storeHasFamily, storeHasOptimisticFamily, storeIsShallow } from "./store/next/store.js";
|
|
42
46
|
|
|
43
47
|
export { storePath } from "./store/storePath.js";
|
|
44
48
|
|
|
45
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Observe tier (diagnostics channel, attribution hook slot + interaction
|
|
51
|
+
* frame): dev and observe builds. The attribution engine itself is the
|
|
52
|
+
* `@solidjs/signals/attribution` entry.
|
|
53
|
+
*/ const OBSERVE = undefined;
|
|
54
|
+
|
|
55
|
+
/** Dev tier (devtools hooks, graph traversal, console reporting): dev builds only. */ const DEV = undefined;
|
|
46
56
|
|
|
47
|
-
export { DEV };
|
|
57
|
+
export { DEV, OBSERVE };
|
package/dist/prod/map.js
CHANGED
|
@@ -24,165 +24,316 @@ function mapArray(t, s, i) {
|
|
|
24
24
|
const e = typeof i?.keyed === "function" ? i.keyed : undefined;
|
|
25
25
|
const r = s.length > 1;
|
|
26
26
|
const n = s;
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
const o = {
|
|
28
|
+
se: createOwner(),
|
|
29
|
+
ts: 0,
|
|
30
|
+
ss: t,
|
|
31
|
+
es: [],
|
|
32
|
+
rs: n,
|
|
33
|
+
ns: [],
|
|
34
|
+
hs: [],
|
|
35
|
+
qt: e,
|
|
36
|
+
fs: e || i?.keyed === false ? [] : undefined,
|
|
37
|
+
cs: r && i?.keyed !== false ? [] : undefined,
|
|
38
|
+
ls: i?.keyed === false,
|
|
39
|
+
us: i?.fallback
|
|
40
40
|
};
|
|
41
|
-
const
|
|
41
|
+
const h = computed(updateKeyedMap.bind(o), undefined);
|
|
42
42
|
// Untracked reads inside the internal owner resolve via _parentComputed; routing
|
|
43
43
|
// them through node lets store-proxy lookups see pending writes (not stale _value).
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return accessor(
|
|
44
|
+
o.se.Qt = h;
|
|
45
|
+
h.T &= ~CONFIG_AUTO_DISPOSE;
|
|
46
|
+
return accessor(h);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const pureOptions = {
|
|
50
50
|
ownedWrite: true
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
function trySmallMove(t, s, i, e) {
|
|
54
|
+
const r = t.es;
|
|
55
|
+
const n = t.ts - 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.es;
|
|
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.ns;
|
|
163
|
+
const l = t.hs;
|
|
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.ns = u;
|
|
183
|
+
t.hs = p;
|
|
184
|
+
t.ts = i;
|
|
185
|
+
t.es = 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
|
+
|
|
62
193
|
function updateKeyedMap() {
|
|
63
|
-
const t = this.
|
|
194
|
+
const t = this.ss() || [], s = t.length;
|
|
64
195
|
t[$TRACK];
|
|
65
196
|
// top level tracking
|
|
66
|
-
runWithOwner(this
|
|
197
|
+
runWithOwner(this.se, () => {
|
|
67
198
|
let i, e, r, n,
|
|
68
199
|
// Mappers write freshly-created row/index signals into the STAGE
|
|
69
200
|
// arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
|
|
70
|
-
|
|
201
|
+
o = this.fs ? this.ls ? () => {
|
|
71
202
|
r[e] = signal(t[e], pureOptions);
|
|
72
|
-
return this.
|
|
203
|
+
return this.rs(accessor(r[e]), e);
|
|
73
204
|
} : () => {
|
|
74
205
|
r[e] = signal(t[e], pureOptions);
|
|
75
206
|
n && (n[e] = signal(e, pureOptions));
|
|
76
|
-
return this.
|
|
77
|
-
} : this.
|
|
207
|
+
return this.rs(accessor(r[e]), n ? accessor(n[e]) : undefined);
|
|
208
|
+
} : this.cs ? () => {
|
|
78
209
|
const s = t[e];
|
|
79
210
|
n[e] = signal(e, pureOptions);
|
|
80
|
-
return this.
|
|
211
|
+
return this.rs(s, accessor(n[e]));
|
|
81
212
|
} : () => {
|
|
82
213
|
const s = t[e];
|
|
83
|
-
return this.
|
|
214
|
+
return this.rs(s);
|
|
84
215
|
};
|
|
85
216
|
// fast path for empty arrays
|
|
86
217
|
if (s === 0) {
|
|
87
|
-
if (this.
|
|
88
|
-
this
|
|
89
|
-
this.
|
|
90
|
-
this.
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
218
|
+
if (this.ts !== 0) {
|
|
219
|
+
this.se.dispose(false);
|
|
220
|
+
this.hs = [];
|
|
221
|
+
this.es = [];
|
|
222
|
+
this.ns = [];
|
|
223
|
+
this.ts = 0;
|
|
224
|
+
this.fs && (this.fs = []);
|
|
225
|
+
this.cs && (this.cs = []);
|
|
95
226
|
}
|
|
96
|
-
if (this.
|
|
227
|
+
if (this.us && !this.ns[0]) {
|
|
97
228
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
98
229
|
// dispose it before re-creating
|
|
99
|
-
this.
|
|
100
|
-
this.
|
|
230
|
+
this.hs[0]?.dispose();
|
|
231
|
+
this.ns[0] = runWithOwner(this.hs[0] = createOwner(), this.us);
|
|
101
232
|
}
|
|
102
233
|
}
|
|
103
234
|
// fast path for new create
|
|
104
|
-
else if (this.
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
r = this.
|
|
108
|
-
n = this.
|
|
235
|
+
else if (this.ts === 0) {
|
|
236
|
+
const h = new Array(s);
|
|
237
|
+
const f = new Array(s);
|
|
238
|
+
r = this.fs && new Array(s);
|
|
239
|
+
n = this.cs && new Array(s);
|
|
109
240
|
try {
|
|
110
|
-
for (e = 0; e < s; e++)
|
|
241
|
+
for (e = 0; e < s; e++) h[e] = runWithOwner(f[e] = createOwner(), o);
|
|
111
242
|
} catch (t) {
|
|
112
|
-
for (i = 0; i <= e; i++)
|
|
243
|
+
for (i = 0; i <= e; i++) f[i]?.dispose();
|
|
113
244
|
throw t;
|
|
114
245
|
}
|
|
115
246
|
// commit
|
|
116
|
-
if (this.
|
|
247
|
+
if (this.hs[0]) this.hs[0].dispose();
|
|
117
248
|
// previous fallback
|
|
118
|
-
this.
|
|
119
|
-
this.
|
|
120
|
-
r && (this.
|
|
121
|
-
n && (this.
|
|
122
|
-
this.
|
|
123
|
-
this.
|
|
249
|
+
this.ns = h;
|
|
250
|
+
this.hs = f;
|
|
251
|
+
r && (this.fs = r);
|
|
252
|
+
n && (this.cs = n);
|
|
253
|
+
this.es = t.slice(0);
|
|
254
|
+
this.ts = s;
|
|
124
255
|
} else {
|
|
125
|
-
let
|
|
256
|
+
let h, f, c, a, l, u, p, d, w,
|
|
126
257
|
// Dev (attribution engine installed): the items behind the exited and
|
|
127
258
|
// entered rows, for the list-identity census.
|
|
128
259
|
m, O;
|
|
129
260
|
// skip common prefix
|
|
130
|
-
for (
|
|
131
|
-
if (this.
|
|
261
|
+
for (h = 0, f = Math.min(this.ts, s); h < f && (this.es[h] === t[h] || this.fs && compare(this.qt, this.es[h], t[h])); h++) {
|
|
262
|
+
if (this.fs) setSignal(this.fs[h], t[h]);
|
|
132
263
|
}
|
|
133
264
|
// skip common suffix — counted only; retained entries land in one pass
|
|
134
265
|
// at commit instead of being staged and copied twice
|
|
135
|
-
for (
|
|
266
|
+
for (f = this.ts - 1, c = s - 1; f >= h && c >= h && (this.es[f] === t[c] || this.fs && compare(this.qt, this.es[f], t[c])); f--,
|
|
136
267
|
c--) ;
|
|
137
268
|
// no structural change (every position matched in place at equal
|
|
138
269
|
// length — the common post-reconcile shape): keep the same mapped
|
|
139
270
|
// array identity so downstream consumers don't re-run at all
|
|
140
|
-
if (
|
|
141
|
-
this.
|
|
271
|
+
if (h === s && this.ts === s) {
|
|
272
|
+
this.es = t.slice(0);
|
|
142
273
|
return;
|
|
143
274
|
}
|
|
144
|
-
|
|
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.ts && f - h > 64 && this.fs === undefined && this.cs === 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.es[n] !== e) n++;
|
|
293
|
+
if (n <= r && trySmallMove(this, t, s, h)) return;
|
|
294
|
+
}
|
|
295
|
+
const _ = s - this.ts;
|
|
145
296
|
const y = new Array(s);
|
|
146
297
|
const A = new Array(s);
|
|
147
|
-
r = this.
|
|
148
|
-
n = this.
|
|
298
|
+
r = this.fs ? new Array(s) : undefined;
|
|
299
|
+
n = this.cs ? new Array(s) : undefined;
|
|
149
300
|
// 0) prepare a map of all indices in the changed window of newItems,
|
|
150
301
|
// scanning backwards so we encounter them in natural order
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
for (e = c; e >=
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
i =
|
|
157
|
-
|
|
158
|
-
|
|
302
|
+
u = new Map;
|
|
303
|
+
p = new Array(c + 1);
|
|
304
|
+
for (e = c; e >= h; e--) {
|
|
305
|
+
a = t[e];
|
|
306
|
+
l = this.qt ? this.qt(a) : a;
|
|
307
|
+
i = u.get(l);
|
|
308
|
+
p[e] = i === undefined ? -1 : i;
|
|
309
|
+
u.set(l, e);
|
|
159
310
|
}
|
|
160
311
|
// 1) step through the old changed window and see if items can be found
|
|
161
312
|
// in the new set; if so, stage them at their new positions; if not,
|
|
162
313
|
// queue them for disposal at commit
|
|
163
|
-
for (i =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
e =
|
|
314
|
+
for (i = h; i <= f; i++) {
|
|
315
|
+
a = this.es[i];
|
|
316
|
+
l = this.qt ? this.qt(a) : a;
|
|
317
|
+
e = u.get(l);
|
|
167
318
|
if (e !== undefined && e !== -1) {
|
|
168
|
-
y[e] = this.
|
|
169
|
-
A[e] = this.
|
|
170
|
-
r && (r[e] = this.
|
|
171
|
-
n && (n[e] = this.
|
|
172
|
-
e =
|
|
173
|
-
|
|
319
|
+
y[e] = this.ns[i];
|
|
320
|
+
A[e] = this.hs[i];
|
|
321
|
+
r && (r[e] = this.fs[i]);
|
|
322
|
+
n && (n[e] = this.cs[i]);
|
|
323
|
+
e = p[e];
|
|
324
|
+
u.set(l, e);
|
|
174
325
|
} else {
|
|
175
|
-
(d ??= []).push(this.
|
|
326
|
+
(d ??= []).push(this.hs[i]);
|
|
176
327
|
if (false && attrHooks !== null) ;
|
|
177
328
|
}
|
|
178
329
|
}
|
|
179
330
|
// 2) create new rows into the temp arrays; an abort disposes only these
|
|
180
331
|
try {
|
|
181
|
-
for (e =
|
|
332
|
+
for (e = h; e <= c; e++) {
|
|
182
333
|
if (A[e] !== undefined) continue;
|
|
183
334
|
(w ??= []).push(A[e] = createOwner());
|
|
184
335
|
if (false && attrHooks !== null) ;
|
|
185
|
-
y[e] = runWithOwner(A[e],
|
|
336
|
+
y[e] = runWithOwner(A[e], o);
|
|
186
337
|
}
|
|
187
338
|
} catch (t) {
|
|
188
339
|
if (w) for (i = 0; i < w.length; i++) w[i].dispose();
|
|
@@ -191,40 +342,40 @@ function updateKeyedMap() {
|
|
|
191
342
|
// 3) commit: land the retained prefix and suffix plus the staged window
|
|
192
343
|
// into the fresh arrays, swap them in (new identity for downstream
|
|
193
344
|
// change propagation), then dispose exited rows
|
|
194
|
-
for (i = 0; i <
|
|
195
|
-
y[i] = this.
|
|
196
|
-
A[i] = this.
|
|
197
|
-
r && (r[i] = this.
|
|
198
|
-
n && (n[i] = this.
|
|
345
|
+
for (i = 0; i < h; i++) {
|
|
346
|
+
y[i] = this.ns[i];
|
|
347
|
+
A[i] = this.hs[i];
|
|
348
|
+
r && (r[i] = this.fs[i]);
|
|
349
|
+
n && (n[i] = this.cs[i]);
|
|
199
350
|
}
|
|
200
|
-
for (e =
|
|
351
|
+
for (e = h; e <= c; e++) {
|
|
201
352
|
if (r) setSignal(r[e], t[e]);
|
|
202
353
|
if (n) setSignal(n[e], e);
|
|
203
354
|
}
|
|
204
355
|
for (e = c + 1; e < s; e++) {
|
|
205
|
-
y[e] = this.
|
|
206
|
-
A[e] = this.
|
|
356
|
+
y[e] = this.ns[e - _];
|
|
357
|
+
A[e] = this.hs[e - _];
|
|
207
358
|
if (r) {
|
|
208
|
-
r[e] = this.
|
|
359
|
+
r[e] = this.fs[e - _];
|
|
209
360
|
setSignal(r[e], t[e]);
|
|
210
361
|
}
|
|
211
362
|
if (n) {
|
|
212
|
-
n[e] = this.
|
|
363
|
+
n[e] = this.cs[e - _];
|
|
213
364
|
if (_ !== 0) setSignal(n[e], e);
|
|
214
365
|
}
|
|
215
366
|
}
|
|
216
|
-
this.
|
|
217
|
-
this.
|
|
218
|
-
r && (this.
|
|
219
|
-
n && (this.
|
|
220
|
-
this.
|
|
367
|
+
this.ns = y;
|
|
368
|
+
this.hs = A;
|
|
369
|
+
r && (this.fs = r);
|
|
370
|
+
n && (this.cs = n);
|
|
371
|
+
this.ts = s;
|
|
221
372
|
// save a copy of the mapped items for the next update
|
|
222
|
-
this.
|
|
373
|
+
this.es = t.slice(0);
|
|
223
374
|
if (d) for (i = 0; i < d.length; i++) d[i].dispose();
|
|
224
375
|
if (false && attrHooks !== null && m !== undefined && O !== undefined) ;
|
|
225
376
|
}
|
|
226
377
|
});
|
|
227
|
-
return this.
|
|
378
|
+
return this.ns;
|
|
228
379
|
}
|
|
229
380
|
|
|
230
381
|
/**
|
|
@@ -244,21 +395,21 @@ function updateKeyedMap() {
|
|
|
244
395
|
*/ function repeat(t, s, i) {
|
|
245
396
|
const e = s;
|
|
246
397
|
const r = {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
398
|
+
se: createOwner(),
|
|
399
|
+
ts: 0,
|
|
400
|
+
ps: 0,
|
|
401
|
+
ds: t,
|
|
402
|
+
rs: e,
|
|
403
|
+
hs: [],
|
|
404
|
+
ns: [],
|
|
405
|
+
ws: i?.from,
|
|
406
|
+
us: i?.fallback
|
|
256
407
|
};
|
|
257
408
|
const n = computed(updateRepeat.bind(r));
|
|
258
409
|
// Same as mapArray: untracked reads inside the internal owner resolve via
|
|
259
410
|
// _parentComputed, so async reads in row callbacks register with the node
|
|
260
411
|
// (pending tracking + post-settle retry) instead of vanishing.
|
|
261
|
-
r
|
|
412
|
+
r.se.Qt = n;
|
|
262
413
|
n.T &= ~CONFIG_AUTO_DISPOSE;
|
|
263
414
|
return accessor(n);
|
|
264
415
|
}
|
|
@@ -271,55 +422,55 @@ function updateKeyedMap() {
|
|
|
271
422
|
// for the post-settle retry. The overlap math also subsumes the previous
|
|
272
423
|
// disjoint-window/front-clear/end-clear/shift special cases.
|
|
273
424
|
function updateRepeat() {
|
|
274
|
-
const t = this.
|
|
275
|
-
const s = this.
|
|
276
|
-
runWithOwner(this
|
|
425
|
+
const t = this.ds();
|
|
426
|
+
const s = this.ws?.() || 0;
|
|
427
|
+
runWithOwner(this.se, () => {
|
|
277
428
|
if (t === 0) {
|
|
278
|
-
if (this.
|
|
279
|
-
this
|
|
280
|
-
this.
|
|
281
|
-
this.
|
|
282
|
-
this.
|
|
429
|
+
if (this.ts !== 0) {
|
|
430
|
+
this.se.dispose(false);
|
|
431
|
+
this.hs = [];
|
|
432
|
+
this.ns = [];
|
|
433
|
+
this.ts = 0;
|
|
283
434
|
// Reset offset to match the cleared data (#2767, repro 2).
|
|
284
|
-
this.
|
|
435
|
+
this.ps = 0;
|
|
285
436
|
}
|
|
286
|
-
if (this.
|
|
437
|
+
if (this.us && !this.ns[0]) {
|
|
287
438
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
288
439
|
// dispose it before re-creating
|
|
289
|
-
this.
|
|
290
|
-
this.
|
|
440
|
+
this.hs[0]?.dispose();
|
|
441
|
+
this.ns[0] = runWithOwner(this.hs[0] = createOwner(), this.us);
|
|
291
442
|
}
|
|
292
443
|
return;
|
|
293
444
|
}
|
|
294
445
|
const i = s + t;
|
|
295
|
-
const e = this.
|
|
446
|
+
const e = this.ps + this.ts;
|
|
296
447
|
// Retained overlap [keepStart, keepEnd) in global indexes; empty when the
|
|
297
448
|
// windows are disjoint or when coming from empty/fallback.
|
|
298
|
-
const r = Math.max(s, this.
|
|
449
|
+
const r = Math.max(s, this.ps);
|
|
299
450
|
const n = Math.min(i, e);
|
|
300
|
-
const h = new Array(t);
|
|
301
451
|
const o = new Array(t);
|
|
452
|
+
const h = new Array(t);
|
|
302
453
|
for (let t = r; t < n; t++) {
|
|
303
|
-
|
|
304
|
-
|
|
454
|
+
h[t - s] = this.hs[t - this.ps];
|
|
455
|
+
o[t - s] = this.ns[t - this.ps];
|
|
305
456
|
}
|
|
306
457
|
try {
|
|
307
458
|
for (let t = s; t < i; t++) {
|
|
308
459
|
if (t >= r && t < n) continue;
|
|
309
|
-
|
|
460
|
+
o[t - s] = runWithOwner(h[t - s] = createOwner(), () => this.rs(t));
|
|
310
461
|
}
|
|
311
462
|
} catch (t) {
|
|
312
|
-
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();
|
|
313
464
|
throw t;
|
|
314
465
|
}
|
|
315
466
|
// commit: dispose the previous fallback or the rows leaving the window
|
|
316
|
-
if (this.
|
|
317
|
-
this.
|
|
318
|
-
this.
|
|
319
|
-
this.
|
|
320
|
-
this.
|
|
467
|
+
if (this.ts === 0) this.hs[0]?.dispose(); else for (let t = this.ps; t < e; t++) if (t < s || t >= i) this.hs[t - this.ps].dispose();
|
|
468
|
+
this.ns = o;
|
|
469
|
+
this.hs = h;
|
|
470
|
+
this.ps = s;
|
|
471
|
+
this.ts = t;
|
|
321
472
|
});
|
|
322
|
-
return this.
|
|
473
|
+
return this.ns;
|
|
323
474
|
}
|
|
324
475
|
|
|
325
476
|
function compare(t, s, i) {
|