@solidjs/signals 2.0.0-beta.19 → 2.0.0-beta.21
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/README.md +5 -1
- package/dist/dev.js +753 -378
- package/dist/node.cjs +1947 -1607
- package/dist/prod/affects.js +17 -21
- package/dist/prod/core/action.js +66 -15
- package/dist/prod/core/async.js +57 -71
- package/dist/prod/core/constants.js +15 -1
- package/dist/prod/core/core.js +39 -39
- package/dist/prod/core/effect.js +14 -14
- package/dist/prod/core/graph.js +1 -1
- package/dist/prod/core/heap.js +11 -3
- package/dist/prod/core/lanes.js +23 -13
- package/dist/prod/core/optimistic.js +107 -99
- package/dist/prod/core/owner.js +23 -23
- package/dist/prod/core/scheduler.js +188 -181
- package/dist/prod/core/verdict.js +29 -15
- package/dist/prod/map.js +196 -167
- package/dist/prod/signals.js +1 -1
- package/dist/prod/store/optimistic.js +103 -68
- package/dist/prod/store/reconcile.js +80 -46
- package/dist/prod/store/store.js +204 -73
- package/dist/prod/store/utils.js +61 -42
- package/dist/types/core/action.d.ts +35 -6
- package/dist/types/core/constants.d.ts +12 -0
- package/dist/types/core/dev.d.ts +7 -0
- package/dist/types/core/lanes.d.ts +2 -0
- package/dist/types/core/scheduler.d.ts +2 -6
- package/dist/types/core/types.d.ts +9 -1
- package/dist/types/store/store.d.ts +8 -2
- package/dist/types-cjs/core/action.d.cts +35 -6
- package/dist/types-cjs/core/constants.d.cts +12 -0
- package/dist/types-cjs/core/dev.d.cts +7 -0
- package/dist/types-cjs/core/lanes.d.cts +2 -0
- package/dist/types-cjs/core/scheduler.d.cts +2 -6
- package/dist/types-cjs/core/types.d.cts +9 -1
- package/dist/types-cjs/store/store.d.cts +8 -2
- package/package.json +1 -1
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NOT_PENDING, REACTIVE_DISPOSED, REACTIVE_DIRTY, REACTIVE_CHECK, unwrapOverride, REACTIVE_ZOMBIE, STATUS_UNINITIALIZED, STATUS_PENDING, REACTIVE_MANUAL_WRITE } from "./constants.js";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { setSignal, prepareComputed, read, context, stale, currentOptimisticLane, tracking, setLatestReadActive, setContextInternal, optimisticComputed, setPendingCheckActive, latestReadActive, optimisticSignal, pendingCheckActive } from "./core.js";
|
|
4
4
|
|
|
5
5
|
import { NotReadyError } from "./error.js";
|
|
6
6
|
|
|
7
7
|
import { link } from "./graph.js";
|
|
8
8
|
|
|
9
|
-
import { insertIntoHeap, queueFor } from "./heap.js";
|
|
9
|
+
import { insertIntoHeap, queueFor, markHeap } from "./heap.js";
|
|
10
10
|
|
|
11
11
|
import "./invariants.js";
|
|
12
12
|
|
|
13
|
-
import {
|
|
13
|
+
import { findLane, hasActiveOverride } from "./lanes.js";
|
|
14
14
|
|
|
15
15
|
import { installOptimisticEngine } from "./optimistic.js";
|
|
16
16
|
|
|
17
|
-
import { GlobalQueue, clock, insertSubs, schedule } from "./scheduler.js";
|
|
17
|
+
import { GlobalQueue, clock, insertSubs, schedule, activeTransition } from "./scheduler.js";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* The isPending()/latest() verdict layer, moved out of core.ts. Importing this
|
|
@@ -61,11 +61,10 @@ function collectPendingSources(e) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
function quietPending(e) {
|
|
64
|
-
if (e.
|
|
65
|
-
for (const t of e.
|
|
64
|
+
if (e.m) {
|
|
65
|
+
for (const t of e.m) if (!t.A) return false;
|
|
66
66
|
return true;
|
|
67
67
|
}
|
|
68
|
-
if (e.m) return e.m.A;
|
|
69
68
|
return e.A;
|
|
70
69
|
}
|
|
71
70
|
|
|
@@ -76,11 +75,11 @@ function newQuestionInFlight(e) {
|
|
|
76
75
|
function computePendingState(e) {
|
|
77
76
|
const t = e;
|
|
78
77
|
if (t.u & REACTIVE_DISPOSED) return false;
|
|
79
|
-
if (e.
|
|
78
|
+
if (e.M) return true;
|
|
80
79
|
const n = e.rt;
|
|
81
80
|
if (e.en) {
|
|
82
81
|
const t = e.en;
|
|
83
|
-
if (t.
|
|
82
|
+
if (t.M) return true;
|
|
84
83
|
const n = t.rt || t;
|
|
85
84
|
return newQuestionInFlight(n);
|
|
86
85
|
}
|
|
@@ -88,7 +87,7 @@ function computePendingState(e) {
|
|
|
88
87
|
return !!(n.u & REACTIVE_MANUAL_WRITE) || !n.Ae && !(n.i & STATUS_PENDING) || !!(n.i & STATUS_PENDING) && quietPending(n);
|
|
89
88
|
}
|
|
90
89
|
if (e.ge !== NOT_PENDING && !(t.i & STATUS_UNINITIALIZED)) {
|
|
91
|
-
if (hasActiveOverride(e)) return !e.Ge || !e.Ge(e.ge, e.be);
|
|
90
|
+
if (hasActiveOverride(e)) return !e.Ge || !e.Ge(e.ge, unwrapOverride(e.be));
|
|
92
91
|
return true;
|
|
93
92
|
}
|
|
94
93
|
return newQuestionInFlight(t);
|
|
@@ -173,9 +172,19 @@ function getLatestValueComputed(e) {
|
|
|
173
172
|
const t = getLatestValueComputed(e);
|
|
174
173
|
const n = latestReadActive;
|
|
175
174
|
setLatestReadActive(false);
|
|
176
|
-
const i = e.be !== undefined && e.be !== NOT_PENDING ? e.be : e.Ue;
|
|
175
|
+
const i = e.be !== undefined && e.be !== NOT_PENDING ? unwrapOverride(e.be) : e.Ue;
|
|
177
176
|
let r;
|
|
178
177
|
try {
|
|
178
|
+
// An untracked latest() read has no reading context, so read() never
|
|
179
|
+
// performs its mid-tick pull — a plain write queued between two latest()
|
|
180
|
+
// calls left a still-subscribed shadow at its previous speculative value
|
|
181
|
+
// until the flush (#2922). Mirror the tracked-read pull here: mark the
|
|
182
|
+
// queued staleness through the graph, then bring the shadow up to date.
|
|
183
|
+
const e = queueFor(t);
|
|
184
|
+
if (t.qe >= e.Le && !(t.u & (REACTIVE_DISPOSED | REACTIVE_ZOMBIE))) {
|
|
185
|
+
markHeap(e);
|
|
186
|
+
prepareComputed(t, true);
|
|
187
|
+
}
|
|
179
188
|
r = read(t);
|
|
180
189
|
} catch (t) {
|
|
181
190
|
if (t instanceof NotReadyError && (!context || !(e.i & STATUS_UNINITIALIZED))) return i;
|
|
@@ -191,6 +200,11 @@ function getLatestValueComputed(e) {
|
|
|
191
200
|
return i;
|
|
192
201
|
}
|
|
193
202
|
}
|
|
203
|
+
// A shadow recomputed by the pull above (not at creation) holds its fresh
|
|
204
|
+
// speculative value in _pendingValue; a contextless read() only surfaces
|
|
205
|
+
// _value. Overrides stay authoritative (A17), and stale readers keep the
|
|
206
|
+
// other transition's committed view, matching read()'s own selection.
|
|
207
|
+
if (t.ge !== NOT_PENDING && !hasActiveOverride(t) && !(stale && t.ve && activeTransition !== t.ve)) return t.ge;
|
|
194
208
|
return r;
|
|
195
209
|
}
|
|
196
210
|
|
|
@@ -272,7 +286,7 @@ function isPending(e) {
|
|
|
272
286
|
// direct calls used, so behavior is identical once this module loads.
|
|
273
287
|
GlobalQueue._e = syncCompanions;
|
|
274
288
|
|
|
275
|
-
GlobalQueue.
|
|
289
|
+
GlobalQueue.P = updatePendingSignal;
|
|
276
290
|
|
|
277
291
|
GlobalQueue.me = updateChildCompanions;
|
|
278
292
|
|
|
@@ -282,12 +296,12 @@ GlobalQueue.Gt = latestRead;
|
|
|
282
296
|
|
|
283
297
|
GlobalQueue.Pt = pendingCheckRead;
|
|
284
298
|
|
|
285
|
-
GlobalQueue.
|
|
299
|
+
GlobalQueue.kt = recordFreshRead;
|
|
286
300
|
|
|
287
301
|
GlobalQueue.tt = applyReask;
|
|
288
302
|
|
|
289
303
|
GlobalQueue.nt = repollDownstreamVerdicts;
|
|
290
304
|
|
|
291
|
-
GlobalQueue.
|
|
305
|
+
GlobalQueue.wt = witnessAffects;
|
|
292
306
|
|
|
293
307
|
export { isPending, latest };
|
package/dist/prod/map.js
CHANGED
|
@@ -18,26 +18,26 @@ import { $TRACK } from "./store/store.js";
|
|
|
18
18
|
|
|
19
19
|
function mapArray(t, s, i) {
|
|
20
20
|
const e = typeof i?.keyed === "function" ? i.keyed : undefined;
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
const r = s.length > 1;
|
|
22
|
+
const n = s;
|
|
23
|
+
const h = {
|
|
24
|
+
jt: createOwner(),
|
|
25
|
+
Wt: 0,
|
|
26
|
+
Kt: t,
|
|
27
|
+
xt: [],
|
|
28
|
+
$t: n,
|
|
29
|
+
qt: [],
|
|
30
|
+
zt: [],
|
|
31
|
+
Ht: e,
|
|
32
|
+
Jt: e || i?.keyed === false ? [] : undefined,
|
|
33
|
+
Xt: r && i?.keyed !== false ? [] : undefined,
|
|
34
|
+
Yt: i?.keyed === false,
|
|
35
|
+
Zt: i?.fallback
|
|
36
36
|
};
|
|
37
|
-
const o = computed(updateKeyedMap.bind(
|
|
37
|
+
const o = computed(updateKeyedMap.bind(h));
|
|
38
38
|
// Untracked reads inside the internal owner resolve via _parentComputed; routing
|
|
39
39
|
// them through node lets store-proxy lookups see pending writes (not stale _value).
|
|
40
|
-
|
|
40
|
+
h.jt.Ct = o;
|
|
41
41
|
o.U &= ~CONFIG_AUTO_DISPOSE;
|
|
42
42
|
return accessor(o);
|
|
43
43
|
}
|
|
@@ -46,114 +46,149 @@ const pureOptions = {
|
|
|
46
46
|
ownedWrite: true
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
// Exception safety (#2903): a map callback can throw NotReadyError mid-pass
|
|
50
|
+
// (async read), and the computed re-runs the whole pass after settle. Every
|
|
51
|
+
// pass therefore STAGES its work — new rows are created into temp arrays and
|
|
52
|
+
// removals are deferred — and commits to `this` only after every mapper
|
|
53
|
+
// succeeded. An aborted pass disposes just the owners it created and leaves
|
|
54
|
+
// `_items`/`_mappings`/`_nodes`/`_rows`/`_indexes`/`_len` exactly as they
|
|
55
|
+
// were, so the retry diffs against uncorrupted state. Consequence of the
|
|
56
|
+
// strong-abort ordering: removed rows now dispose AFTER the pass's new rows
|
|
57
|
+
// are created (you cannot destroy state before knowing the pass will land).
|
|
49
58
|
function updateKeyedMap() {
|
|
50
|
-
const t = this.
|
|
59
|
+
const t = this.Kt() || [], s = t.length;
|
|
51
60
|
t[$TRACK];
|
|
52
61
|
// top level tracking
|
|
53
|
-
runWithOwner(this
|
|
54
|
-
let i, e,
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
runWithOwner(this.jt, () => {
|
|
63
|
+
let i, e, r, n,
|
|
64
|
+
// Mappers write freshly-created row/index signals into the STAGE
|
|
65
|
+
// arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
|
|
66
|
+
h = this.Jt ? this.Yt ? () => {
|
|
67
|
+
r[e] = signal(t[e], pureOptions);
|
|
68
|
+
return this.$t(accessor(r[e]), e);
|
|
57
69
|
} : () => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return this
|
|
61
|
-
} : this.
|
|
70
|
+
r[e] = signal(t[e], pureOptions);
|
|
71
|
+
n && (n[e] = signal(e, pureOptions));
|
|
72
|
+
return this.$t(accessor(r[e]), n ? accessor(n[e]) : undefined);
|
|
73
|
+
} : this.Xt ? () => {
|
|
62
74
|
const s = t[e];
|
|
63
|
-
|
|
64
|
-
return this
|
|
75
|
+
n[e] = signal(e, pureOptions);
|
|
76
|
+
return this.$t(s, accessor(n[e]));
|
|
65
77
|
} : () => {
|
|
66
78
|
const s = t[e];
|
|
67
|
-
return this
|
|
79
|
+
return this.$t(s);
|
|
68
80
|
};
|
|
69
81
|
// fast path for empty arrays
|
|
70
82
|
if (s === 0) {
|
|
71
|
-
if (this.
|
|
72
|
-
this
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
77
|
-
this.
|
|
78
|
-
this.
|
|
83
|
+
if (this.Wt !== 0) {
|
|
84
|
+
this.jt.dispose(false);
|
|
85
|
+
this.zt = [];
|
|
86
|
+
this.xt = [];
|
|
87
|
+
this.qt = [];
|
|
88
|
+
this.Wt = 0;
|
|
89
|
+
this.Jt && (this.Jt = []);
|
|
90
|
+
this.Xt && (this.Xt = []);
|
|
79
91
|
}
|
|
80
|
-
if (this.
|
|
81
|
-
//
|
|
82
|
-
|
|
92
|
+
if (this.Zt && !this.qt[0]) {
|
|
93
|
+
// an aborted fallback attempt leaves an owner without a mapping;
|
|
94
|
+
// dispose it before re-creating
|
|
95
|
+
this.zt[0]?.dispose();
|
|
96
|
+
this.qt[0] = runWithOwner(this.zt[0] = createOwner(), this.Zt);
|
|
83
97
|
}
|
|
84
98
|
}
|
|
85
99
|
// fast path for new create
|
|
86
|
-
else if (this.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
else if (this.Wt === 0) {
|
|
101
|
+
const o = new Array(s);
|
|
102
|
+
const c = new Array(s);
|
|
103
|
+
r = this.Jt && new Array(s);
|
|
104
|
+
n = this.Xt && new Array(s);
|
|
105
|
+
try {
|
|
106
|
+
for (e = 0; e < s; e++) o[e] = runWithOwner(c[e] = createOwner(), h);
|
|
107
|
+
} catch (t) {
|
|
108
|
+
for (i = 0; i <= e; i++) c[i]?.dispose();
|
|
109
|
+
throw t;
|
|
93
110
|
}
|
|
94
|
-
|
|
111
|
+
// commit
|
|
112
|
+
if (this.zt[0]) this.zt[0].dispose();
|
|
113
|
+
// previous fallback
|
|
114
|
+
this.qt = o;
|
|
115
|
+
this.zt = c;
|
|
116
|
+
r && (this.Jt = r);
|
|
117
|
+
n && (this.Xt = n);
|
|
118
|
+
this.xt = t.slice(0);
|
|
119
|
+
this.Wt = s;
|
|
95
120
|
} else {
|
|
96
|
-
let
|
|
121
|
+
let o, c, a, f, u, p, w, l, d, O = new Array(s), m = new Array(s);
|
|
122
|
+
r = this.Jt ? new Array(s) : undefined;
|
|
123
|
+
n = this.Xt ? new Array(s) : undefined;
|
|
97
124
|
// skip common prefix
|
|
98
|
-
for (
|
|
99
|
-
if (this.
|
|
125
|
+
for (o = 0, c = Math.min(this.Wt, s); o < c && (this.xt[o] === t[o] || this.Jt && compare(this.Ht, this.xt[o], t[o])); o++) {
|
|
126
|
+
if (this.Jt) setSignal(this.Jt[o], t[o]);
|
|
100
127
|
}
|
|
101
128
|
// common suffix
|
|
102
|
-
for (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
129
|
+
for (c = this.Wt - 1, a = s - 1; c >= o && a >= o && (this.xt[c] === t[a] || this.Jt && compare(this.Ht, this.xt[c], t[a])); c--,
|
|
130
|
+
a--) {
|
|
131
|
+
O[a] = this.qt[c];
|
|
132
|
+
m[a] = this.zt[c];
|
|
133
|
+
r && (r[a] = this.Jt[c]);
|
|
134
|
+
n && (n[a] = this.Xt[c]);
|
|
108
135
|
}
|
|
109
136
|
// 0) prepare a map of all indices in newItems, scanning backwards so we encounter them in natural order
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
for (e =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
i =
|
|
116
|
-
|
|
117
|
-
|
|
137
|
+
p = new Map;
|
|
138
|
+
w = new Array(a + 1);
|
|
139
|
+
for (e = a; e >= o; e--) {
|
|
140
|
+
f = t[e];
|
|
141
|
+
u = this.Ht ? this.Ht(f) : f;
|
|
142
|
+
i = p.get(u);
|
|
143
|
+
w[e] = i === undefined ? -1 : i;
|
|
144
|
+
p.set(u, e);
|
|
118
145
|
}
|
|
119
|
-
// 1) step through all old items and see if they can be found in the new set; if so, save them in a temp array and mark them moved; if not,
|
|
120
|
-
for (i =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
e =
|
|
146
|
+
// 1) step through all old items and see if they can be found in the new set; if so, save them in a temp array and mark them moved; if not, queue them for disposal at commit
|
|
147
|
+
for (i = o; i <= c; i++) {
|
|
148
|
+
f = this.xt[i];
|
|
149
|
+
u = this.Ht ? this.Ht(f) : f;
|
|
150
|
+
e = p.get(u);
|
|
124
151
|
if (e !== undefined && e !== -1) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
e =
|
|
130
|
-
|
|
131
|
-
} else this.
|
|
152
|
+
O[e] = this.qt[i];
|
|
153
|
+
m[e] = this.zt[i];
|
|
154
|
+
r && (r[e] = this.Jt[i]);
|
|
155
|
+
n && (n[e] = this.Xt[i]);
|
|
156
|
+
e = w[e];
|
|
157
|
+
p.set(u, e);
|
|
158
|
+
} else (l ??= []).push(this.zt[i]);
|
|
132
159
|
}
|
|
133
|
-
// 2)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
this.cs[e] = w[e];
|
|
140
|
-
setSignal(this.cs[e], t[e]);
|
|
141
|
-
}
|
|
142
|
-
if (O) {
|
|
143
|
-
this.fs[e] = O[e];
|
|
144
|
-
setSignal(this.fs[e], e);
|
|
145
|
-
}
|
|
146
|
-
} else {
|
|
147
|
-
this.hs[e] = runWithOwner(this.rs[e] = createOwner(), h);
|
|
160
|
+
// 2) create new rows into the temp arrays; an abort disposes only these
|
|
161
|
+
try {
|
|
162
|
+
for (e = o; e < s; e++) {
|
|
163
|
+
if (e in O) continue;
|
|
164
|
+
(d ??= []).push(m[e] = createOwner());
|
|
165
|
+
O[e] = runWithOwner(m[e], h);
|
|
148
166
|
}
|
|
167
|
+
} catch (t) {
|
|
168
|
+
if (d) for (i = 0; i < d.length; i++) d[i].dispose();
|
|
169
|
+
throw t;
|
|
149
170
|
}
|
|
150
|
-
// 3)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
171
|
+
// 3) commit: land positions, then dispose exited rows
|
|
172
|
+
for (e = o; e < s; e++) {
|
|
173
|
+
this.qt[e] = O[e];
|
|
174
|
+
this.zt[e] = m[e];
|
|
175
|
+
if (r) {
|
|
176
|
+
this.Jt[e] = r[e];
|
|
177
|
+
setSignal(this.Jt[e], t[e]);
|
|
178
|
+
}
|
|
179
|
+
if (n) {
|
|
180
|
+
this.Xt[e] = n[e];
|
|
181
|
+
setSignal(this.Xt[e], e);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (l) for (i = 0; i < l.length; i++) l[i].dispose();
|
|
185
|
+
// 4) in case the new set is shorter than the old, set the length of the mapped array
|
|
186
|
+
this.qt = this.qt.slice(0, this.Wt = s);
|
|
187
|
+
// 5) save a copy of the mapped items for the next update
|
|
188
|
+
this.xt = t.slice(0);
|
|
154
189
|
}
|
|
155
190
|
});
|
|
156
|
-
return this.
|
|
191
|
+
return this.qt;
|
|
157
192
|
}
|
|
158
193
|
|
|
159
194
|
/**
|
|
@@ -172,89 +207,83 @@ function updateKeyedMap() {
|
|
|
172
207
|
* @description https://docs.solidjs.com/reference/reactive-utilities/repeat
|
|
173
208
|
*/ function repeat(t, s, i) {
|
|
174
209
|
const e = s;
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
210
|
+
const r = {
|
|
211
|
+
jt: createOwner(),
|
|
212
|
+
Wt: 0,
|
|
213
|
+
ts: 0,
|
|
214
|
+
ss: t,
|
|
215
|
+
$t: e,
|
|
216
|
+
zt: [],
|
|
217
|
+
qt: [],
|
|
218
|
+
es: i?.from,
|
|
219
|
+
Zt: i?.fallback
|
|
220
|
+
};
|
|
221
|
+
const n = computed(updateRepeat.bind(r));
|
|
222
|
+
// Same as mapArray: untracked reads inside the internal owner resolve via
|
|
223
|
+
// _parentComputed, so async reads in row callbacks register with the node
|
|
224
|
+
// (pending tracking + post-settle retry) instead of vanishing.
|
|
225
|
+
r.jt.Ct = n;
|
|
226
|
+
n.U &= ~CONFIG_AUTO_DISPOSE;
|
|
227
|
+
return accessor(n);
|
|
188
228
|
}
|
|
189
229
|
|
|
230
|
+
// Same staged-commit discipline as `updateKeyedMap` (#2903): the retained
|
|
231
|
+
// window overlap is copied into fresh arrays, missing indexes are created
|
|
232
|
+
// into them, and `this` is only touched — including disposal of rows leaving
|
|
233
|
+
// the window — after every `_map` call succeeded. A NotReadyError mid-pass
|
|
234
|
+
// disposes only the owners this pass created and leaves prior state intact
|
|
235
|
+
// for the post-settle retry. The overlap math also subsumes the previous
|
|
236
|
+
// disjoint-window/front-clear/end-clear/shift special cases.
|
|
190
237
|
function updateRepeat() {
|
|
191
|
-
const t = this.
|
|
192
|
-
const s = this.
|
|
193
|
-
runWithOwner(this
|
|
238
|
+
const t = this.ss();
|
|
239
|
+
const s = this.es?.() || 0;
|
|
240
|
+
runWithOwner(this.jt, () => {
|
|
194
241
|
if (t === 0) {
|
|
195
|
-
if (this.
|
|
196
|
-
this
|
|
197
|
-
this.
|
|
198
|
-
this.
|
|
199
|
-
this.
|
|
200
|
-
// Reset offset to match the cleared data
|
|
201
|
-
|
|
202
|
-
// with `prevTo = stale_offset + 0` > `to` and dispose `_nodes[-1]`
|
|
203
|
-
// (#2767, repro 2).
|
|
204
|
-
this.ls = 0;
|
|
242
|
+
if (this.Wt !== 0) {
|
|
243
|
+
this.jt.dispose(false);
|
|
244
|
+
this.zt = [];
|
|
245
|
+
this.qt = [];
|
|
246
|
+
this.Wt = 0;
|
|
247
|
+
// Reset offset to match the cleared data (#2767, repro 2).
|
|
248
|
+
this.ts = 0;
|
|
205
249
|
}
|
|
206
|
-
if (this.
|
|
207
|
-
//
|
|
208
|
-
|
|
250
|
+
if (this.Zt && !this.qt[0]) {
|
|
251
|
+
// an aborted fallback attempt leaves an owner without a mapping;
|
|
252
|
+
// dispose it before re-creating
|
|
253
|
+
this.zt[0]?.dispose();
|
|
254
|
+
this.qt[0] = runWithOwner(this.zt[0] = createOwner(), this.Zt);
|
|
209
255
|
}
|
|
210
256
|
return;
|
|
211
257
|
}
|
|
212
258
|
const i = s + t;
|
|
213
|
-
const e = this.
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
this.
|
|
223
|
-
this.Xt = t;
|
|
224
|
-
return;
|
|
259
|
+
const e = this.ts + this.Wt;
|
|
260
|
+
// Retained overlap [keepStart, keepEnd) in global indexes; empty when the
|
|
261
|
+
// windows are disjoint or when coming from empty/fallback.
|
|
262
|
+
const r = Math.max(s, this.ts);
|
|
263
|
+
const n = Math.min(i, e);
|
|
264
|
+
const h = new Array(t);
|
|
265
|
+
const o = new Array(t);
|
|
266
|
+
for (let t = r; t < n; t++) {
|
|
267
|
+
o[t - s] = this.zt[t - this.ts];
|
|
268
|
+
h[t - s] = this.qt[t - this.ts];
|
|
225
269
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
// front sit at local positions 0..(from - _offset), clamped to old len.
|
|
231
|
-
const t = s - this.ls;
|
|
232
|
-
for (let s = 0; s < t && s < this.Xt; s++) this.rs[s].dispose();
|
|
233
|
-
// shift indexes
|
|
234
|
-
this.rs.splice(0, t);
|
|
235
|
-
this.hs.splice(0, t);
|
|
236
|
-
} else if (this.ls > s) {
|
|
237
|
-
// shift indexes
|
|
238
|
-
let i = e - this.ls - 1;
|
|
239
|
-
let h = this.ls - s;
|
|
240
|
-
this.rs.length = this.hs.length = t;
|
|
241
|
-
while (i >= h) {
|
|
242
|
-
this.rs[i] = this.rs[i - h];
|
|
243
|
-
this.hs[i] = this.hs[i - h];
|
|
244
|
-
i--;
|
|
245
|
-
}
|
|
246
|
-
for (let t = 0; t < h; t++) {
|
|
247
|
-
this.hs[t] = runWithOwner(this.rs[t] = createOwner(), () => this.es(t + s));
|
|
270
|
+
try {
|
|
271
|
+
for (let t = s; t < i; t++) {
|
|
272
|
+
if (t >= r && t < n) continue;
|
|
273
|
+
h[t - s] = runWithOwner(o[t - s] = createOwner(), () => this.$t(t));
|
|
248
274
|
}
|
|
275
|
+
} catch (t) {
|
|
276
|
+
for (let t = s; t < i; t++) if ((t < r || t >= n) && o[t - s]) o[t - s].dispose();
|
|
277
|
+
throw t;
|
|
249
278
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this.
|
|
254
|
-
this.
|
|
255
|
-
this.
|
|
279
|
+
// commit: dispose the previous fallback or the rows leaving the window
|
|
280
|
+
if (this.Wt === 0) this.zt[0]?.dispose(); else for (let t = this.ts; t < e; t++) if (t < s || t >= i) this.zt[t - this.ts].dispose();
|
|
281
|
+
this.qt = h;
|
|
282
|
+
this.zt = o;
|
|
283
|
+
this.ts = s;
|
|
284
|
+
this.Wt = t;
|
|
256
285
|
});
|
|
257
|
-
return this.
|
|
286
|
+
return this.qt;
|
|
258
287
|
}
|
|
259
288
|
|
|
260
289
|
function compare(t, s, i) {
|
package/dist/prod/signals.js
CHANGED
|
@@ -4,7 +4,7 @@ import { cleanup, createRoot, getOwner, dispose } from "./core/owner.js";
|
|
|
4
4
|
|
|
5
5
|
import { globalQueue } from "./core/scheduler.js";
|
|
6
6
|
|
|
7
|
-
import { CONFIG_CHILDREN_FORBIDDEN, EFFECT_USER, $REFRESH
|
|
7
|
+
import { CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, EFFECT_USER, $REFRESH } from "./core/constants.js";
|
|
8
8
|
|
|
9
9
|
import "./core/invariants.js";
|
|
10
10
|
|