@solidjs/signals 2.0.0-rc.10 → 2.0.0-rc.13
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 +128 -60
- package/dist/dev.attribution.js +27 -12
- package/dist/dev.js +242 -32
- package/dist/observe/core/attribution.js +36 -21
- package/dist/observe/core/constants.js +21 -12
- package/dist/observe/core/core.js +44 -34
- package/dist/observe/core/dev.js +38 -15
- package/dist/observe/core/optimistic.js +65 -23
- package/dist/observe/core/owner.js +11 -11
- package/dist/observe/core/scheduler.js +26 -12
- package/dist/observe/core/verdict.js +2 -2
- package/dist/observe/map.js +241 -218
- package/dist/observe/store/next/store.js +159 -31
- package/dist/prod/core/constants.js +21 -12
- package/dist/prod/core/core.js +27 -17
- package/dist/prod/core/optimistic.js +62 -20
- package/dist/prod/core/owner.js +2 -2
- package/dist/prod/core/scheduler.js +29 -15
- package/dist/prod/core/verdict.js +1 -1
- package/dist/prod/map.js +200 -177
- package/dist/prod/store/next/optimistic.js +2 -2
- package/dist/prod/store/next/store.js +201 -73
- package/dist/types/core/attribution-hooks.d.ts +28 -0
- package/dist/types/core/attribution.d.ts +9 -0
- package/dist/types/core/constants.d.ts +21 -12
- package/dist/types/core/dev.d.ts +59 -6
- package/dist/types/core/index.d.ts +1 -1
- package/dist/types/core/scheduler.d.ts +5 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/signals.d.ts +18 -1
- package/dist/types/store/next/store.d.ts +4 -2
- package/package.json +1 -1
package/dist/observe/map.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { computed, runWithOwner, signal, setSignal } from "./core/core.js";
|
|
1
|
+
import { computed, runWithOwner, signal, currentOptimisticLane, setSignal } from "./core/core.js";
|
|
2
|
+
|
|
3
|
+
import { activeLanes } from "./core/lanes.js";
|
|
2
4
|
|
|
3
5
|
import { createOwner } from "./core/owner.js";
|
|
4
6
|
|
|
5
|
-
import "./core/scheduler.js";
|
|
7
|
+
import { GlobalQueue } from "./core/scheduler.js";
|
|
6
8
|
|
|
7
9
|
import { CONFIG_AUTO_DISPOSE } from "./core/constants.js";
|
|
8
10
|
|
|
@@ -22,26 +24,26 @@ import { $TRACK } from "./store/store.js";
|
|
|
22
24
|
|
|
23
25
|
import "./store/next/store.js";
|
|
24
26
|
|
|
25
|
-
function mapArray(t,
|
|
26
|
-
const
|
|
27
|
-
const r =
|
|
28
|
-
const n =
|
|
27
|
+
function mapArray(t, e, i) {
|
|
28
|
+
const s = typeof i?.keyed === "function" ? i.keyed : undefined;
|
|
29
|
+
const r = e.length > 1;
|
|
30
|
+
const n = e;
|
|
29
31
|
const o = {
|
|
30
32
|
ie: createOwner(),
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
zt:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
oi: 0,
|
|
34
|
+
hi: t,
|
|
35
|
+
fi: [],
|
|
36
|
+
ci: n,
|
|
37
|
+
ai: [],
|
|
38
|
+
ui: [],
|
|
39
|
+
zt: s,
|
|
40
|
+
li: s || i?.keyed === false ? [] : undefined,
|
|
41
|
+
pi: r && i?.keyed !== false ? [] : undefined,
|
|
42
|
+
di: i?.keyed === false,
|
|
43
|
+
mi: i?.fallback
|
|
42
44
|
};
|
|
43
|
-
const h = computed(updateKeyedMap.bind(o),
|
|
44
|
-
name:
|
|
45
|
+
const h = computed(updateKeyedMap.bind(o), i?.name ? {
|
|
46
|
+
name: i.name
|
|
45
47
|
} : undefined);
|
|
46
48
|
// Untracked reads inside the internal owner resolve via _parentComputed; routing
|
|
47
49
|
// them through node lets store-proxy lookups see pending writes (not stale _value).
|
|
@@ -54,21 +56,21 @@ const pureOptions = {
|
|
|
54
56
|
ownedWrite: true
|
|
55
57
|
};
|
|
56
58
|
|
|
57
|
-
function trySmallMove(t,
|
|
58
|
-
const r = t.
|
|
59
|
-
const n = t.
|
|
59
|
+
function trySmallMove(t, e, i, s) {
|
|
60
|
+
const r = t.fi;
|
|
61
|
+
const n = t.oi - 1;
|
|
60
62
|
const o = [];
|
|
61
63
|
const h = [];
|
|
62
64
|
const f = [];
|
|
63
65
|
// flat triples: oldStart, newStart, length
|
|
64
66
|
let c = 256;
|
|
65
|
-
let a =
|
|
66
|
-
let u =
|
|
67
|
+
let a = s;
|
|
68
|
+
let u = s;
|
|
67
69
|
let l = false;
|
|
68
|
-
while (a <= n && u <=
|
|
70
|
+
while (a <= n && u <= i - 1) {
|
|
69
71
|
const t = r[a];
|
|
70
|
-
const
|
|
71
|
-
if (t ===
|
|
72
|
+
const s = e[u];
|
|
73
|
+
if (t === s) {
|
|
72
74
|
if (!l) {
|
|
73
75
|
f.push(a, u, 0);
|
|
74
76
|
l = true;
|
|
@@ -80,30 +82,30 @@ function trySmallMove(t, s, e, i) {
|
|
|
80
82
|
}
|
|
81
83
|
l = false;
|
|
82
84
|
// Bounded realignment lookahead, shorter distance wins.
|
|
83
|
-
let
|
|
84
|
-
let
|
|
85
|
-
for (let t = 1; t <=
|
|
86
|
-
if (r[a + t] ===
|
|
87
|
-
|
|
85
|
+
let p = -1;
|
|
86
|
+
let d = Math.min(32 - o.length, n - a, c);
|
|
87
|
+
for (let t = 1; t <= d; t++) {
|
|
88
|
+
if (r[a + t] === s) {
|
|
89
|
+
p = t;
|
|
88
90
|
break;
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
|
-
c -=
|
|
92
|
-
let
|
|
93
|
-
|
|
94
|
-
for (let
|
|
95
|
-
if (
|
|
96
|
-
|
|
93
|
+
c -= p === -1 ? d : p;
|
|
94
|
+
let m = -1;
|
|
95
|
+
d = Math.min(32 - h.length, i - 1 - u, c);
|
|
96
|
+
for (let i = 1; i <= d; i++) {
|
|
97
|
+
if (e[u + i] === t) {
|
|
98
|
+
m = i;
|
|
97
99
|
break;
|
|
98
100
|
}
|
|
99
101
|
}
|
|
100
|
-
c -=
|
|
101
|
-
if (
|
|
102
|
-
while (
|
|
102
|
+
c -= m === -1 ? d : m;
|
|
103
|
+
if (p !== -1 && (m === -1 || p <= m)) {
|
|
104
|
+
while (p-- > 0) o.push(a++);
|
|
103
105
|
continue;
|
|
104
106
|
}
|
|
105
|
-
if (
|
|
106
|
-
while (
|
|
107
|
+
if (m !== -1) {
|
|
108
|
+
while (m-- > 0) h.push(u++);
|
|
107
109
|
continue;
|
|
108
110
|
}
|
|
109
111
|
if (c <= 0 || o.length === 32 || h.length === 32) return false;
|
|
@@ -114,11 +116,11 @@ function trySmallMove(t, s, e, i) {
|
|
|
114
116
|
if (o.length === 32) return false;
|
|
115
117
|
o.push(a);
|
|
116
118
|
}
|
|
117
|
-
for (;u <=
|
|
119
|
+
for (;u <= i - 1; u++) {
|
|
118
120
|
if (h.length === 32) return false;
|
|
119
121
|
h.push(u);
|
|
120
122
|
}
|
|
121
|
-
return commitSmallMove(t,
|
|
123
|
+
return commitSmallMove(t, e, i, o, h, f);
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
/** PHASE 2 of the small-move path, in its OWN function so that a pass which
|
|
@@ -127,17 +129,17 @@ function trySmallMove(t, s, e, i) {
|
|
|
127
129
|
* per function, and cold `replace` measured +0.5 ms with both phases in one
|
|
128
130
|
* body. Pairs displaced sources with destinations (an unmatched destination
|
|
129
131
|
* is a replacement/insertion → general path), then commits: slice() the live
|
|
130
|
-
* arrays, copy shifted runs, patch displaced pairs, dispose leftovers. */ function commitSmallMove(t,
|
|
131
|
-
const o = t.
|
|
132
|
+
* arrays, copy shifted runs, patch displaced pairs, dispose leftovers. */ function commitSmallMove(t, e, i, s, r, n) {
|
|
133
|
+
const o = t.fi;
|
|
132
134
|
let h;
|
|
133
135
|
let f;
|
|
134
136
|
let c;
|
|
135
137
|
if (r.length !== 0) {
|
|
136
|
-
c = new Array(
|
|
138
|
+
c = new Array(s.length);
|
|
137
139
|
for (f = 0; f < r.length; f++) {
|
|
138
140
|
let t = -1;
|
|
139
|
-
for (h = 0; h <
|
|
140
|
-
if (!c[h] && o[
|
|
141
|
+
for (h = 0; h < s.length; h++) {
|
|
142
|
+
if (!c[h] && o[s[h]] === e[r[f]]) {
|
|
141
143
|
t = h;
|
|
142
144
|
break;
|
|
143
145
|
}
|
|
@@ -154,126 +156,147 @@ function trySmallMove(t, s, e, i) {
|
|
|
154
156
|
// and if a displaced identity also occurs inside a run the two algorithms
|
|
155
157
|
// can hand different occurrences different owners (row-local state moves;
|
|
156
158
|
// a shrink could dispose the wrong one). Decline that case — general path.
|
|
157
|
-
if (
|
|
159
|
+
if (s.length !== 0 || r.length !== 0) {
|
|
158
160
|
const t = new Set;
|
|
159
|
-
for (h = 0; h <
|
|
160
|
-
for (f = 0; f < r.length; f++) t.add(
|
|
161
|
-
for (let
|
|
162
|
-
const
|
|
163
|
-
for (let
|
|
161
|
+
for (h = 0; h < s.length; h++) t.add(o[s[h]]);
|
|
162
|
+
for (f = 0; f < r.length; f++) t.add(e[r[f] >> 6]);
|
|
163
|
+
for (let e = 0; e < n.length; e += 3) {
|
|
164
|
+
const i = n[e];
|
|
165
|
+
for (let s = 0, r = n[e + 2]; s < r; s++) if (t.has(o[i + s])) return false;
|
|
164
166
|
}
|
|
165
167
|
}
|
|
166
|
-
const a = t.
|
|
167
|
-
const u = t.
|
|
168
|
-
const l = a.slice(0,
|
|
169
|
-
const
|
|
168
|
+
const a = t.ai;
|
|
169
|
+
const u = t.ui;
|
|
170
|
+
const l = a.slice(0, i);
|
|
171
|
+
const p = u.slice(0, i);
|
|
170
172
|
for (let t = 0; t < n.length; t += 3) {
|
|
171
|
-
const
|
|
172
|
-
const
|
|
173
|
-
if (
|
|
174
|
-
for (let
|
|
175
|
-
l[
|
|
176
|
-
|
|
173
|
+
const e = n[t];
|
|
174
|
+
const i = n[t + 1];
|
|
175
|
+
if (e !== i) {
|
|
176
|
+
for (let s = 0; s < n[t + 2]; s++) {
|
|
177
|
+
l[i + s] = a[e + s];
|
|
178
|
+
p[i + s] = u[e + s];
|
|
177
179
|
}
|
|
178
180
|
}
|
|
179
181
|
}
|
|
180
182
|
for (f = 0; f < r.length; f++) {
|
|
181
183
|
const t = r[f] >> 6;
|
|
182
|
-
const
|
|
183
|
-
l[t] = a[
|
|
184
|
-
|
|
184
|
+
const e = s[r[f] & 63];
|
|
185
|
+
l[t] = a[e];
|
|
186
|
+
p[t] = u[e];
|
|
185
187
|
}
|
|
186
|
-
t.
|
|
187
|
-
t.
|
|
188
|
-
t.
|
|
189
|
-
t.
|
|
188
|
+
t.ai = l;
|
|
189
|
+
t.ui = p;
|
|
190
|
+
t.oi = i;
|
|
191
|
+
t.fi = e.slice(0);
|
|
190
192
|
// Dispose unmatched sources LAST (general-path ordering).
|
|
191
|
-
for (h = 0; h <
|
|
192
|
-
if (c === undefined || !c[h]) u[
|
|
193
|
+
for (h = 0; h < s.length; h++) {
|
|
194
|
+
if (c === undefined || !c[h]) u[s[h]].dispose();
|
|
193
195
|
}
|
|
194
196
|
return true;
|
|
195
197
|
}
|
|
196
198
|
|
|
197
199
|
function updateKeyedMap() {
|
|
198
|
-
const t = this.
|
|
200
|
+
const t = this.hi() || [], e = t.length;
|
|
199
201
|
t[$TRACK];
|
|
200
202
|
// top level tracking
|
|
201
203
|
runWithOwner(this.ie, () => {
|
|
202
|
-
let
|
|
204
|
+
let i, s, r, n,
|
|
203
205
|
// Mappers write freshly-created row/index signals into the STAGE
|
|
204
206
|
// arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
|
|
205
|
-
o = this.
|
|
206
|
-
r[
|
|
207
|
-
return this.
|
|
207
|
+
o = this.li ? this.di ? () => {
|
|
208
|
+
r[s] = signal(t[s], pureOptions);
|
|
209
|
+
return this.ci(accessor(r[s]), s);
|
|
208
210
|
} : () => {
|
|
209
|
-
r[
|
|
210
|
-
n && (n[
|
|
211
|
-
return this.
|
|
212
|
-
} : this.
|
|
213
|
-
const
|
|
214
|
-
n[
|
|
215
|
-
return this.
|
|
211
|
+
r[s] = signal(t[s], pureOptions);
|
|
212
|
+
n && (n[s] = signal(s, pureOptions));
|
|
213
|
+
return this.ci(accessor(r[s]), n ? accessor(n[s]) : undefined);
|
|
214
|
+
} : this.pi ? () => {
|
|
215
|
+
const e = t[s];
|
|
216
|
+
n[s] = signal(s, pureOptions);
|
|
217
|
+
return this.ci(e, accessor(n[s]));
|
|
216
218
|
} : () => {
|
|
217
|
-
const
|
|
218
|
-
return this.
|
|
219
|
+
const e = t[s];
|
|
220
|
+
return this.ci(e);
|
|
219
221
|
};
|
|
220
222
|
// fast path for empty arrays
|
|
221
|
-
if (
|
|
222
|
-
if (this.
|
|
223
|
+
if (e === 0) {
|
|
224
|
+
if (this.oi !== 0) {
|
|
223
225
|
this.ie.dispose(false);
|
|
224
|
-
this.
|
|
225
|
-
this.
|
|
226
|
-
this.
|
|
227
|
-
this.
|
|
228
|
-
this.
|
|
229
|
-
this.
|
|
226
|
+
this.ui = [];
|
|
227
|
+
this.fi = [];
|
|
228
|
+
this.ai = [];
|
|
229
|
+
this.oi = 0;
|
|
230
|
+
this.li && (this.li = []);
|
|
231
|
+
this.pi && (this.pi = []);
|
|
230
232
|
}
|
|
231
|
-
if (this.
|
|
233
|
+
if (this.mi && !this.ai[0]) {
|
|
232
234
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
233
235
|
// dispose it before re-creating
|
|
234
|
-
this.
|
|
235
|
-
this.
|
|
236
|
+
this.ui[0]?.dispose();
|
|
237
|
+
this.ai[0] = runWithOwner(this.ui[0] = createOwner(), this.mi);
|
|
236
238
|
}
|
|
237
239
|
}
|
|
238
240
|
// fast path for new create
|
|
239
|
-
else if (this.
|
|
240
|
-
const h = new Array(
|
|
241
|
-
const f = new Array(
|
|
242
|
-
r = this.
|
|
243
|
-
n = this.
|
|
241
|
+
else if (this.oi === 0) {
|
|
242
|
+
const h = new Array(e);
|
|
243
|
+
const f = new Array(e);
|
|
244
|
+
r = this.li && new Array(e);
|
|
245
|
+
n = this.pi && new Array(e);
|
|
244
246
|
try {
|
|
245
|
-
for (
|
|
247
|
+
for (s = 0; s < e; s++) h[s] = runWithOwner(f[s] = createOwner(), o);
|
|
246
248
|
} catch (t) {
|
|
247
|
-
for (
|
|
249
|
+
for (i = 0; i <= s; i++) f[i]?.dispose();
|
|
248
250
|
throw t;
|
|
249
251
|
}
|
|
250
252
|
// commit
|
|
251
|
-
if (this.
|
|
253
|
+
if (this.ui[0]) this.ui[0].dispose();
|
|
252
254
|
// previous fallback
|
|
253
|
-
this.
|
|
254
|
-
this.
|
|
255
|
-
r && (this.
|
|
256
|
-
n && (this.
|
|
257
|
-
this.
|
|
258
|
-
this.
|
|
255
|
+
this.ai = h;
|
|
256
|
+
this.ui = f;
|
|
257
|
+
r && (this.li = r);
|
|
258
|
+
n && (this.pi = n);
|
|
259
|
+
this.fi = t.slice(0);
|
|
260
|
+
this.oi = e;
|
|
259
261
|
} else {
|
|
260
|
-
let h, f, c, a, u, l,
|
|
262
|
+
let h, f, c, a, u, l, p, d, m,
|
|
261
263
|
// Dev (attribution engine installed): the items behind the exited and
|
|
262
264
|
// entered rows, for the list-identity census.
|
|
263
|
-
|
|
265
|
+
w, O;
|
|
266
|
+
// The pass's write to a per-slot signal (a row accessor in index mode,
|
|
267
|
+
// an index accessor in keyed mode). The list's frame lives in these
|
|
268
|
+
// writes as much as in the computed's result, so under a LANE pass they
|
|
269
|
+
// are the lane's frame too (F1): a plain `setSignal` staged them into
|
|
270
|
+
// the action's transaction and the row readers were served the
|
|
271
|
+
// committed value until the action landed — `<For>` without `keyed`
|
|
272
|
+
// showed the pre-action list for the whole action while the keyed modes
|
|
273
|
+
// showed the optimistic one. The engine publishes the write as a
|
|
274
|
+
// derived override on the slot (lanes stage, A17) and lands or
|
|
275
|
+
// supersedes it when a plain pass later writes a slot still carrying
|
|
276
|
+
// one (A18) — `landOnOverride`'s slot arm. Decided once per pass, not
|
|
277
|
+
// per slot: a lane pass marks the map (`_laneSlots`: its slots may
|
|
278
|
+
// carry overrides), a marked map routes every slot write through the
|
|
279
|
+
// engine while any lane is live — a slot's override resolves with its
|
|
280
|
+
// lane's transaction, or with the batch for an orphan lane
|
|
281
|
+
// (resolveOptimisticNodes, then cleanupCompletedLanes, both before the
|
|
282
|
+
// completion wakes any recompute), so a pass that finds no lane live
|
|
283
|
+
// knows the slots are clean and drops the mark — and an unmarked map
|
|
284
|
+
// takes `setSignal` directly. The engine is installed whenever a lane
|
|
285
|
+
// is active.
|
|
286
|
+
const _ = (this.wi = currentOptimisticLane !== null || this.wi && activeLanes.size !== 0) ? GlobalQueue.Vn : setSignal;
|
|
264
287
|
// skip common prefix
|
|
265
|
-
for (h = 0, f = Math.min(this.
|
|
266
|
-
if (this.
|
|
288
|
+
for (h = 0, f = Math.min(this.oi, e); h < f && (this.fi[h] === t[h] || this.li && compare(this.zt, this.fi[h], t[h])); h++) {
|
|
289
|
+
if (this.li) _(this.li[h], t[h]);
|
|
267
290
|
}
|
|
268
291
|
// skip common suffix — counted only; retained entries land in one pass
|
|
269
292
|
// at commit instead of being staged and copied twice
|
|
270
|
-
for (f = this.
|
|
293
|
+
for (f = this.oi - 1, c = e - 1; f >= h && c >= h && (this.fi[f] === t[c] || this.li && compare(this.zt, this.fi[f], t[c])); f--,
|
|
271
294
|
c--) ;
|
|
272
295
|
// no structural change (every position matched in place at equal
|
|
273
296
|
// length — the common post-reconcile shape): keep the same mapped
|
|
274
297
|
// array identity so downstream consumers don't re-run at all
|
|
275
|
-
if (h ===
|
|
276
|
-
this.
|
|
298
|
+
if (h === e && this.oi === e) {
|
|
299
|
+
this.fi = t.slice(0);
|
|
277
300
|
return;
|
|
278
301
|
}
|
|
279
302
|
// SMALL-MOVE FAST PATH: extracted to its own function — inlining it
|
|
@@ -283,103 +306,103 @@ function updateKeyedMap() {
|
|
|
283
306
|
// (plain removals, tail edits), the general path is window-
|
|
284
307
|
// proportional and cheap — the fast path would only re-walk what the
|
|
285
308
|
// trims proved.
|
|
286
|
-
if (
|
|
309
|
+
if (e <= this.oi && f - h > 64 && this.li === undefined && this.pi === undefined) {
|
|
287
310
|
// PROBE before the scan: a small move keeps a mid-window item within
|
|
288
311
|
// ±32 of its old position; a REPLACE (all fresh items — the shape
|
|
289
312
|
// every page's first structural pass usually is) has it nowhere.
|
|
290
313
|
// ~65 compares, no allocation, and the scan function is never
|
|
291
314
|
// compiled for a replace (its cold first-call compile was the cost).
|
|
292
|
-
const
|
|
293
|
-
const
|
|
294
|
-
const r = Math.min(f,
|
|
295
|
-
let n = Math.max(h,
|
|
296
|
-
while (n <= r && this.
|
|
297
|
-
if (n <= r && trySmallMove(this, t,
|
|
315
|
+
const i = h + (c - h >> 1);
|
|
316
|
+
const s = t[i];
|
|
317
|
+
const r = Math.min(f, i + 32);
|
|
318
|
+
let n = Math.max(h, i - 32);
|
|
319
|
+
while (n <= r && this.fi[n] !== s) n++;
|
|
320
|
+
if (n <= r && trySmallMove(this, t, e, h)) return;
|
|
298
321
|
}
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
const
|
|
302
|
-
r = this.
|
|
303
|
-
n = this.
|
|
322
|
+
const y = e - this.oi;
|
|
323
|
+
const A = new Array(e);
|
|
324
|
+
const M = new Array(e);
|
|
325
|
+
r = this.li ? new Array(e) : undefined;
|
|
326
|
+
n = this.pi ? new Array(e) : undefined;
|
|
304
327
|
// 0) prepare a map of all indices in the changed window of newItems,
|
|
305
328
|
// scanning backwards so we encounter them in natural order
|
|
306
329
|
l = new Map;
|
|
307
|
-
|
|
308
|
-
for (
|
|
309
|
-
a = t[
|
|
330
|
+
p = new Array(c + 1);
|
|
331
|
+
for (s = c; s >= h; s--) {
|
|
332
|
+
a = t[s];
|
|
310
333
|
u = this.zt ? this.zt(a) : a;
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
l.set(u,
|
|
334
|
+
i = l.get(u);
|
|
335
|
+
p[s] = i === undefined ? -1 : i;
|
|
336
|
+
l.set(u, s);
|
|
314
337
|
}
|
|
315
338
|
// 1) step through the old changed window and see if items can be found
|
|
316
339
|
// in the new set; if so, stage them at their new positions; if not,
|
|
317
340
|
// queue them for disposal at commit
|
|
318
|
-
for (
|
|
319
|
-
a = this.
|
|
341
|
+
for (i = h; i <= f; i++) {
|
|
342
|
+
a = this.fi[i];
|
|
320
343
|
u = this.zt ? this.zt(a) : a;
|
|
321
|
-
|
|
322
|
-
if (
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
r && (r[
|
|
326
|
-
n && (n[
|
|
327
|
-
|
|
328
|
-
l.set(u,
|
|
344
|
+
s = l.get(u);
|
|
345
|
+
if (s !== undefined && s !== -1) {
|
|
346
|
+
A[s] = this.ai[i];
|
|
347
|
+
M[s] = this.ui[i];
|
|
348
|
+
r && (r[s] = this.li[i]);
|
|
349
|
+
n && (n[s] = this.pi[i]);
|
|
350
|
+
s = p[s];
|
|
351
|
+
l.set(u, s);
|
|
329
352
|
} else {
|
|
330
|
-
(
|
|
331
|
-
if (true && attrHooks !== null) (
|
|
353
|
+
(d ??= []).push(this.ui[i]);
|
|
354
|
+
if (true && attrHooks !== null) (w ??= []).push(a);
|
|
332
355
|
}
|
|
333
356
|
}
|
|
334
357
|
// 2) create new rows into the temp arrays; an abort disposes only these
|
|
335
358
|
try {
|
|
336
|
-
for (
|
|
337
|
-
if (
|
|
338
|
-
(
|
|
339
|
-
if (true && attrHooks !== null) (O ??= []).push(t[
|
|
340
|
-
|
|
359
|
+
for (s = h; s <= c; s++) {
|
|
360
|
+
if (M[s] !== undefined) continue;
|
|
361
|
+
(m ??= []).push(M[s] = createOwner());
|
|
362
|
+
if (true && attrHooks !== null) (O ??= []).push(t[s]);
|
|
363
|
+
A[s] = runWithOwner(M[s], o);
|
|
341
364
|
}
|
|
342
365
|
} catch (t) {
|
|
343
|
-
if (
|
|
366
|
+
if (m) for (i = 0; i < m.length; i++) m[i].dispose();
|
|
344
367
|
throw t;
|
|
345
368
|
}
|
|
346
369
|
// 3) commit: land the retained prefix and suffix plus the staged window
|
|
347
370
|
// into the fresh arrays, swap them in (new identity for downstream
|
|
348
371
|
// change propagation), then dispose exited rows
|
|
349
|
-
for (
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
r && (r[
|
|
353
|
-
n && (n[
|
|
372
|
+
for (i = 0; i < h; i++) {
|
|
373
|
+
A[i] = this.ai[i];
|
|
374
|
+
M[i] = this.ui[i];
|
|
375
|
+
r && (r[i] = this.li[i]);
|
|
376
|
+
n && (n[i] = this.pi[i]);
|
|
354
377
|
}
|
|
355
|
-
for (
|
|
356
|
-
if (r)
|
|
357
|
-
if (n)
|
|
378
|
+
for (s = h; s <= c; s++) {
|
|
379
|
+
if (r) _(r[s], t[s]);
|
|
380
|
+
if (n) _(n[s], s);
|
|
358
381
|
}
|
|
359
|
-
for (
|
|
360
|
-
|
|
361
|
-
|
|
382
|
+
for (s = c + 1; s < e; s++) {
|
|
383
|
+
A[s] = this.ai[s - y];
|
|
384
|
+
M[s] = this.ui[s - y];
|
|
362
385
|
if (r) {
|
|
363
|
-
r[
|
|
364
|
-
|
|
386
|
+
r[s] = this.li[s - y];
|
|
387
|
+
_(r[s], t[s]);
|
|
365
388
|
}
|
|
366
389
|
if (n) {
|
|
367
|
-
n[
|
|
368
|
-
if (
|
|
390
|
+
n[s] = this.pi[s - y];
|
|
391
|
+
if (y !== 0) _(n[s], s);
|
|
369
392
|
}
|
|
370
393
|
}
|
|
371
|
-
this.
|
|
372
|
-
this.
|
|
373
|
-
r && (this.
|
|
374
|
-
n && (this.
|
|
375
|
-
this.
|
|
394
|
+
this.ai = A;
|
|
395
|
+
this.ui = M;
|
|
396
|
+
r && (this.li = r);
|
|
397
|
+
n && (this.pi = n);
|
|
398
|
+
this.oi = e;
|
|
376
399
|
// save a copy of the mapped items for the next update
|
|
377
|
-
this.
|
|
378
|
-
if (
|
|
379
|
-
if (true && attrHooks !== null &&
|
|
400
|
+
this.fi = t.slice(0);
|
|
401
|
+
if (d) for (i = 0; i < d.length; i++) d[i].dispose();
|
|
402
|
+
if (true && attrHooks !== null && w !== undefined && O !== undefined) attrHooks.listChurn(this.ie.Yt, w, O, e, this.zt !== undefined);
|
|
380
403
|
}
|
|
381
404
|
});
|
|
382
|
-
return this.
|
|
405
|
+
return this.ai;
|
|
383
406
|
}
|
|
384
407
|
|
|
385
408
|
/**
|
|
@@ -396,18 +419,18 @@ function updateKeyedMap() {
|
|
|
396
419
|
* ```
|
|
397
420
|
*
|
|
398
421
|
* @description https://docs.solidjs.com/reference/reactive-utilities/repeat
|
|
399
|
-
*/ function repeat(t,
|
|
400
|
-
const
|
|
422
|
+
*/ function repeat(t, e, i) {
|
|
423
|
+
const s = e;
|
|
401
424
|
const r = {
|
|
402
425
|
ie: createOwner(),
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
426
|
+
oi: 0,
|
|
427
|
+
Oi: 0,
|
|
428
|
+
_i: t,
|
|
429
|
+
ci: s,
|
|
430
|
+
ui: [],
|
|
431
|
+
ai: [],
|
|
432
|
+
yi: i?.from,
|
|
433
|
+
mi: i?.fallback
|
|
411
434
|
};
|
|
412
435
|
const n = computed(updateRepeat.bind(r));
|
|
413
436
|
// Same as mapArray: untracked reads inside the internal owner resolve via
|
|
@@ -426,59 +449,59 @@ function updateKeyedMap() {
|
|
|
426
449
|
// for the post-settle retry. The overlap math also subsumes the previous
|
|
427
450
|
// disjoint-window/front-clear/end-clear/shift special cases.
|
|
428
451
|
function updateRepeat() {
|
|
429
|
-
const t = this.
|
|
430
|
-
const
|
|
452
|
+
const t = this._i();
|
|
453
|
+
const e = this.yi?.() || 0;
|
|
431
454
|
runWithOwner(this.ie, () => {
|
|
432
455
|
if (t === 0) {
|
|
433
|
-
if (this.
|
|
456
|
+
if (this.oi !== 0) {
|
|
434
457
|
this.ie.dispose(false);
|
|
435
|
-
this.
|
|
436
|
-
this.
|
|
437
|
-
this.
|
|
458
|
+
this.ui = [];
|
|
459
|
+
this.ai = [];
|
|
460
|
+
this.oi = 0;
|
|
438
461
|
// Reset offset to match the cleared data (#2767, repro 2).
|
|
439
|
-
this.
|
|
462
|
+
this.Oi = 0;
|
|
440
463
|
}
|
|
441
|
-
if (this.
|
|
464
|
+
if (this.mi && !this.ai[0]) {
|
|
442
465
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
443
466
|
// dispose it before re-creating
|
|
444
|
-
this.
|
|
445
|
-
this.
|
|
467
|
+
this.ui[0]?.dispose();
|
|
468
|
+
this.ai[0] = runWithOwner(this.ui[0] = createOwner(), this.mi);
|
|
446
469
|
}
|
|
447
470
|
return;
|
|
448
471
|
}
|
|
449
|
-
const
|
|
450
|
-
const
|
|
472
|
+
const i = e + t;
|
|
473
|
+
const s = this.Oi + this.oi;
|
|
451
474
|
// Retained overlap [keepStart, keepEnd) in global indexes; empty when the
|
|
452
475
|
// windows are disjoint or when coming from empty/fallback.
|
|
453
|
-
const r = Math.max(
|
|
454
|
-
const n = Math.min(
|
|
476
|
+
const r = Math.max(e, this.Oi);
|
|
477
|
+
const n = Math.min(i, s);
|
|
455
478
|
const o = new Array(t);
|
|
456
479
|
const h = new Array(t);
|
|
457
480
|
for (let t = r; t < n; t++) {
|
|
458
|
-
h[t -
|
|
459
|
-
o[t -
|
|
481
|
+
h[t - e] = this.ui[t - this.Oi];
|
|
482
|
+
o[t - e] = this.ai[t - this.Oi];
|
|
460
483
|
}
|
|
461
484
|
try {
|
|
462
|
-
for (let t =
|
|
485
|
+
for (let t = e; t < i; t++) {
|
|
463
486
|
if (t >= r && t < n) continue;
|
|
464
|
-
o[t -
|
|
487
|
+
o[t - e] = runWithOwner(h[t - e] = createOwner(), () => this.ci(t));
|
|
465
488
|
}
|
|
466
489
|
} catch (t) {
|
|
467
|
-
for (let t =
|
|
490
|
+
for (let t = e; t < i; t++) if ((t < r || t >= n) && h[t - e]) h[t - e].dispose();
|
|
468
491
|
throw t;
|
|
469
492
|
}
|
|
470
493
|
// commit: dispose the previous fallback or the rows leaving the window
|
|
471
|
-
if (this.
|
|
472
|
-
this.
|
|
473
|
-
this.
|
|
474
|
-
this.
|
|
475
|
-
this.
|
|
494
|
+
if (this.oi === 0) this.ui[0]?.dispose(); else for (let t = this.Oi; t < s; t++) if (t < e || t >= i) this.ui[t - this.Oi].dispose();
|
|
495
|
+
this.ai = o;
|
|
496
|
+
this.ui = h;
|
|
497
|
+
this.Oi = e;
|
|
498
|
+
this.oi = t;
|
|
476
499
|
});
|
|
477
|
-
return this.
|
|
500
|
+
return this.ai;
|
|
478
501
|
}
|
|
479
502
|
|
|
480
|
-
function compare(t,
|
|
481
|
-
return t ? t(
|
|
503
|
+
function compare(t, e, i) {
|
|
504
|
+
return t ? t(e) === t(i) : true;
|
|
482
505
|
}
|
|
483
506
|
|
|
484
507
|
export { mapArray, repeat };
|