@solidjs/signals 2.0.0-rc.19 → 2.0.0-rc.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev-shared.js +553 -264
- package/dist/dev.attribution.js +18 -18
- package/dist/dev.js +1030 -439
- package/dist/observe/affects.js +12 -2
- package/dist/observe/boundaries.js +168 -115
- package/dist/observe/core/async.js +57 -37
- package/dist/observe/core/attribution.js +6 -6
- package/dist/observe/core/constants.js +9 -1
- package/dist/observe/core/copies.js +10 -0
- package/dist/observe/core/core.js +261 -181
- package/dist/observe/core/effect.js +32 -27
- package/dist/observe/core/graph.js +7 -7
- package/dist/observe/core/heap.js +29 -29
- package/dist/observe/core/lanes.js +301 -101
- package/dist/observe/core/owner.js +13 -13
- package/dist/observe/core/scheduler.js +124 -69
- package/dist/observe/core/truth.js +9 -7
- package/dist/observe/core/verdict.js +160 -98
- package/dist/observe/deferred.js +1 -1
- package/dist/observe/index.js +2 -0
- package/dist/observe/map.js +120 -116
- package/dist/observe/reveal.js +48 -48
- package/dist/observe/signals.js +5 -5
- package/dist/observe/store/affects.js +2 -2
- package/dist/observe/store/optimistic.js +272 -176
- package/dist/observe/store/projection.js +21 -10
- package/dist/observe/store/reconcile.js +8 -2
- package/dist/observe/store/store.js +91 -55
- package/dist/observe/store/types.js +11 -1
- package/dist/observe/store/utils.js +1 -1
- package/dist/prod/affects.js +12 -2
- package/dist/prod/boundaries.js +164 -109
- package/dist/prod/core/async.js +201 -181
- package/dist/prod/core/constants.js +9 -1
- package/dist/prod/core/copies.js +10 -0
- package/dist/prod/core/core.js +244 -164
- package/dist/prod/core/dev.js +108 -3
- package/dist/prod/core/effect.js +28 -23
- package/dist/prod/core/graph.js +9 -9
- package/dist/prod/core/heap.js +16 -16
- package/dist/prod/core/identities.js +1 -1
- package/dist/prod/core/lanes.js +307 -95
- package/dist/prod/core/owner.js +22 -22
- package/dist/prod/core/scheduler.js +266 -211
- package/dist/prod/core/truth.js +9 -7
- package/dist/prod/core/verdict.js +161 -99
- package/dist/prod/deferred.js +1 -1
- package/dist/prod/index.js +2 -0
- package/dist/prod/map.js +78 -74
- package/dist/prod/reveal.js +34 -34
- package/dist/prod/signals.js +3 -3
- package/dist/prod/store/affects.js +15 -15
- package/dist/prod/store/optimistic.js +185 -89
- package/dist/prod/store/projection.js +49 -38
- package/dist/prod/store/reconcile.js +8 -2
- package/dist/prod/store/store.js +99 -63
- package/dist/prod/store/types.js +11 -1
- package/dist/types/affects.d.ts +3 -2
- package/dist/types/boundaries.d.ts +14 -2
- package/dist/types/core/async.d.ts +2 -1
- package/dist/types/core/constants.d.ts +8 -0
- package/dist/types/core/copies.d.ts +54 -0
- package/dist/types/core/core.d.ts +15 -0
- package/dist/types/core/dev.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +8 -1
- package/dist/types/core/scheduler.d.ts +36 -4
- package/dist/types/core/truth.d.ts +3 -1
- package/dist/types/core/types.d.ts +6 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/store/hooks.d.ts +15 -1
- package/dist/types/store/store.d.ts +2 -1
- package/dist/types/store/target.d.ts +5 -0
- package/dist/types/store/types.d.ts +7 -0
- package/package.json +1 -1
package/dist/prod/map.js
CHANGED
|
@@ -14,7 +14,7 @@ import "./core/effect.js";
|
|
|
14
14
|
|
|
15
15
|
import { accessor } from "./signals.js";
|
|
16
16
|
|
|
17
|
-
import { $TRACK } from "./store/types.js";
|
|
17
|
+
import { $TRACK, shallowView, $TARGET } from "./store/types.js";
|
|
18
18
|
|
|
19
19
|
function mapArray(t, e, i) {
|
|
20
20
|
const s = typeof i?.keyed === "function" ? i.keyed : undefined;
|
|
@@ -28,7 +28,7 @@ function mapArray(t, e, i) {
|
|
|
28
28
|
ft: r,
|
|
29
29
|
ht: [],
|
|
30
30
|
tn: [],
|
|
31
|
-
|
|
31
|
+
Xe: s,
|
|
32
32
|
ct: s || i?.keyed === false ? [] : undefined,
|
|
33
33
|
lt: n && i?.keyed !== false ? [] : undefined,
|
|
34
34
|
ut: i?.keyed === false,
|
|
@@ -69,26 +69,26 @@ function trySmallMove(t, e, i, s) {
|
|
|
69
69
|
}
|
|
70
70
|
u = false;
|
|
71
71
|
// Bounded realignment lookahead, shorter distance wins.
|
|
72
|
-
let
|
|
73
|
-
let
|
|
74
|
-
for (let t = 1; t <=
|
|
72
|
+
let w = -1;
|
|
73
|
+
let d = Math.min(32 - o.length, r - a, c);
|
|
74
|
+
for (let t = 1; t <= d; t++) {
|
|
75
75
|
if (n[a + t] === s) {
|
|
76
|
-
|
|
76
|
+
w = t;
|
|
77
77
|
break;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
c -=
|
|
80
|
+
c -= w === -1 ? d : w;
|
|
81
81
|
let p = -1;
|
|
82
|
-
|
|
83
|
-
for (let i = 1; i <=
|
|
82
|
+
d = Math.min(32 - f.length, i - 1 - l, c);
|
|
83
|
+
for (let i = 1; i <= d; i++) {
|
|
84
84
|
if (e[l + i] === t) {
|
|
85
85
|
p = i;
|
|
86
86
|
break;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
c -= p === -1 ?
|
|
90
|
-
if (
|
|
91
|
-
while (
|
|
89
|
+
c -= p === -1 ? d : p;
|
|
90
|
+
if (w !== -1 && (p === -1 || w <= p)) {
|
|
91
|
+
while (w-- > 0) o.push(a++);
|
|
92
92
|
continue;
|
|
93
93
|
}
|
|
94
94
|
if (p !== -1) {
|
|
@@ -155,14 +155,14 @@ function trySmallMove(t, e, i, s) {
|
|
|
155
155
|
const a = t.ht;
|
|
156
156
|
const l = t.tn;
|
|
157
157
|
const u = a.slice(0, i);
|
|
158
|
-
const
|
|
158
|
+
const w = l.slice(0, i);
|
|
159
159
|
for (let t = 0; t < r.length; t += 3) {
|
|
160
160
|
const e = r[t];
|
|
161
161
|
const i = r[t + 1];
|
|
162
162
|
if (e !== i) {
|
|
163
163
|
for (let s = 0; s < r[t + 2]; s++) {
|
|
164
164
|
u[i + s] = a[e + s];
|
|
165
|
-
|
|
165
|
+
w[i + s] = l[e + s];
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
}
|
|
@@ -170,10 +170,10 @@ function trySmallMove(t, e, i, s) {
|
|
|
170
170
|
const t = n[h] >> 6;
|
|
171
171
|
const e = s[n[h] & 63];
|
|
172
172
|
u[t] = a[e];
|
|
173
|
-
|
|
173
|
+
w[t] = l[e];
|
|
174
174
|
}
|
|
175
175
|
t.ht = u;
|
|
176
|
-
t.tn =
|
|
176
|
+
t.tn = w;
|
|
177
177
|
t.it = i;
|
|
178
178
|
t.ot = e.slice(0);
|
|
179
179
|
// Dispose unmatched sources LAST (general-path ordering).
|
|
@@ -191,24 +191,24 @@ function trySmallMove(t, e, i, s) {
|
|
|
191
191
|
* the map path below starts from scratch (it rewrites every window slot of
|
|
192
192
|
* `temp` / `rows` / `indexes`, so only `tempNodes`' `!== undefined` probe
|
|
193
193
|
* needs the reset). The stage arrays are scratch — nothing live is touched. */ function stageRemoval(t, e, i, s, n, r, o, f, h) {
|
|
194
|
-
const c = t.
|
|
194
|
+
const c = t.Xe;
|
|
195
195
|
const a = t.ot;
|
|
196
196
|
const l = t.tn;
|
|
197
197
|
const u = [];
|
|
198
|
-
let
|
|
199
|
-
for (let
|
|
200
|
-
const n = c ? c(e[
|
|
201
|
-
while (
|
|
202
|
-
if (
|
|
198
|
+
let w = i;
|
|
199
|
+
for (let d = i; d <= n; w++, d++) {
|
|
200
|
+
const n = c ? c(e[d]) : e[d];
|
|
201
|
+
while (w <= s && (c ? c(a[w]) : a[w]) !== n) u.push(l[w++]);
|
|
202
|
+
if (w > s) {
|
|
203
203
|
o.fill(undefined);
|
|
204
204
|
return null;
|
|
205
205
|
}
|
|
206
|
-
r[
|
|
207
|
-
o[
|
|
208
|
-
if (f) f[
|
|
209
|
-
if (h) h[
|
|
206
|
+
r[d] = t.ht[w];
|
|
207
|
+
o[d - i] = l[w];
|
|
208
|
+
if (f) f[d - i] = t.ct[w];
|
|
209
|
+
if (h) h[d - i] = t.lt[w];
|
|
210
210
|
}
|
|
211
|
-
for (;
|
|
211
|
+
for (;w <= s; w++) u.push(l[w]);
|
|
212
212
|
return u;
|
|
213
213
|
}
|
|
214
214
|
|
|
@@ -222,24 +222,24 @@ function trySmallMove(t, e, i, s) {
|
|
|
222
222
|
const a = t.ct;
|
|
223
223
|
const l = t.lt;
|
|
224
224
|
const u = t.it;
|
|
225
|
-
const
|
|
226
|
-
let
|
|
227
|
-
if (
|
|
225
|
+
const w = i - u;
|
|
226
|
+
let d, p;
|
|
227
|
+
if (w > 0) {
|
|
228
228
|
// Grow first: a store past the end from the top is a third slower than
|
|
229
229
|
// filling a pre-sized tail (measured on 1k refs, 2026-10-15).
|
|
230
230
|
c.length = i;
|
|
231
231
|
if (a) a.length = i;
|
|
232
232
|
if (l) l.length = i;
|
|
233
|
-
for (
|
|
234
|
-
c[p] = c[
|
|
235
|
-
if (a) a[p] = a[
|
|
236
|
-
if (l) l[p] = l[
|
|
233
|
+
for (d = u - 1, p = i - 1; d > n; d--, p--) {
|
|
234
|
+
c[p] = c[d];
|
|
235
|
+
if (a) a[p] = a[d];
|
|
236
|
+
if (l) l[p] = l[d];
|
|
237
237
|
}
|
|
238
|
-
} else if (
|
|
239
|
-
for (
|
|
240
|
-
c[p] = c[
|
|
241
|
-
if (a) a[p] = a[
|
|
242
|
-
if (l) l[p] = l[
|
|
238
|
+
} else if (w < 0) {
|
|
239
|
+
for (d = n + 1, p = r + 1; d < u; d++, p++) {
|
|
240
|
+
c[p] = c[d];
|
|
241
|
+
if (a) a[p] = a[d];
|
|
242
|
+
if (l) l[p] = l[d];
|
|
243
243
|
}
|
|
244
244
|
c.length = i;
|
|
245
245
|
if (a) a.length = i;
|
|
@@ -252,7 +252,7 @@ function trySmallMove(t, e, i, s) {
|
|
|
252
252
|
}
|
|
253
253
|
for (p = r + 1; p < i; p++) {
|
|
254
254
|
if (a) setSignal(a[p], e[p]);
|
|
255
|
-
if (l &&
|
|
255
|
+
if (l && w !== 0) setSignal(l[p], p);
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
|
|
@@ -263,11 +263,15 @@ function updateKeyedMap() {
|
|
|
263
263
|
// the flight's reader (pending tracking + post-settle retry) instead of
|
|
264
264
|
// vanishing. Set per pass: the first pass runs inside `computed()`, before
|
|
265
265
|
// the node exists to the caller.
|
|
266
|
-
this.H.
|
|
267
|
-
|
|
266
|
+
this.H.Ke = getOwner();
|
|
267
|
+
let t = this.st() || [];
|
|
268
268
|
t[$TRACK];
|
|
269
269
|
// top level tracking (a store array's container node)
|
|
270
|
-
|
|
270
|
+
// A shallow store array diffs its backing: its slots are raw records, and
|
|
271
|
+
// a trap per slot read was most of a one-row write on a 1k-row list.
|
|
272
|
+
t = shallowView?.(t[$TARGET]) ?? t;
|
|
273
|
+
const e = t.length;
|
|
274
|
+
runWithOwner(this.H, () => {
|
|
271
275
|
let i, s,
|
|
272
276
|
// The stage slot a mapper writes its row/index signal into: `j` on the
|
|
273
277
|
// create-all path, `j - start` on the general path, whose stage arrays
|
|
@@ -333,7 +337,7 @@ function updateKeyedMap() {
|
|
|
333
337
|
this.ot = t.slice(0);
|
|
334
338
|
this.it = e;
|
|
335
339
|
} else {
|
|
336
|
-
let h, c, a, l, u,
|
|
340
|
+
let h, c, a, l, u, w, d, p, m,
|
|
337
341
|
// Dev (attribution engine installed): the items behind the exited and
|
|
338
342
|
// entered rows, for the list-identity census.
|
|
339
343
|
O, _;
|
|
@@ -360,12 +364,12 @@ function updateKeyedMap() {
|
|
|
360
364
|
// CARVE 2: the lane-slot arm (`_landOnOverride`, F1) went with the engine.
|
|
361
365
|
const y = setSignal;
|
|
362
366
|
// skip common prefix
|
|
363
|
-
for (h = 0, c = Math.min(this.it, e); h < c && (this.ot[h] === t[h] || this.ct && compare(this.
|
|
367
|
+
for (h = 0, c = Math.min(this.it, e); h < c && (this.ot[h] === t[h] || this.ct && compare(this.Xe, this.ot[h], t[h])); h++) {
|
|
364
368
|
if (this.ct) y(this.ct[h], t[h]);
|
|
365
369
|
}
|
|
366
370
|
// skip common suffix — counted only; retained entries land in one pass
|
|
367
371
|
// at commit instead of being staged and copied twice
|
|
368
|
-
for (c = this.it - 1, a = e - 1; c >= h && a >= h && (this.ot[c] === t[a] || this.ct && compare(this.
|
|
372
|
+
for (c = this.it - 1, a = e - 1; c >= h && a >= h && (this.ot[c] === t[a] || this.ct && compare(this.Xe, this.ot[c], t[a])); c--,
|
|
369
373
|
a--) ;
|
|
370
374
|
// no structural change (every position matched in place at equal
|
|
371
375
|
// length — the common post-reconcile shape): keep the same mapped
|
|
@@ -394,7 +398,7 @@ function updateKeyedMap() {
|
|
|
394
398
|
while (r <= n && this.ot[r] !== s) r++;
|
|
395
399
|
if (r <= n && trySmallMove(this, t, e, h)) return;
|
|
396
400
|
}
|
|
397
|
-
const
|
|
401
|
+
const A = e - this.it;
|
|
398
402
|
// WINDOW-SIZED STAGING, IN-PLACE COMMIT (2026-10-15). The strong-abort
|
|
399
403
|
// contract (#2903) only needs the pass to touch nothing live before
|
|
400
404
|
// every mapper has succeeded; it never needed four fresh newLen-sized
|
|
@@ -410,14 +414,14 @@ function updateKeyedMap() {
|
|
|
410
414
|
// staging plus a position-sized chain array per commit (uibench's
|
|
411
415
|
// one-item tree ops at 4–6× Octane, jfb-reorder `removefirst` at
|
|
412
416
|
// 2.5×); now it stages one slot.
|
|
413
|
-
const
|
|
417
|
+
const g = a - h + 1;
|
|
414
418
|
const S = new Array(e);
|
|
415
|
-
const M = new Array(
|
|
416
|
-
r = this.ct ? new Array(
|
|
417
|
-
o = this.lt ? new Array(
|
|
419
|
+
const M = new Array(g);
|
|
420
|
+
r = this.ct ? new Array(g) : undefined;
|
|
421
|
+
o = this.lt ? new Array(g) : undefined;
|
|
418
422
|
// A shrinking pass is tried as a pure removal first (stageRemoval: no
|
|
419
423
|
// key map, one key call per item); anything else takes the map path.
|
|
420
|
-
const k =
|
|
424
|
+
const k = A < 0 ? stageRemoval(this, t, h, c, a, S, M, r, o) : null;
|
|
421
425
|
if (k !== null) {
|
|
422
426
|
// (The list-churn census below wants removals AND creations in one
|
|
423
427
|
// pass; a pure removal has none, so no item ledger is kept here.)
|
|
@@ -425,29 +429,29 @@ function updateKeyedMap() {
|
|
|
425
429
|
} else {
|
|
426
430
|
// 0) prepare a map of all indices in the changed window of newItems,
|
|
427
431
|
// scanning backwards so we encounter them in natural order
|
|
428
|
-
|
|
429
|
-
|
|
432
|
+
w = new Map;
|
|
433
|
+
d = new Array(g);
|
|
430
434
|
for (s = a; s >= h; s--) {
|
|
431
435
|
l = t[s];
|
|
432
|
-
u = this.
|
|
433
|
-
i =
|
|
434
|
-
|
|
435
|
-
|
|
436
|
+
u = this.Xe ? this.Xe(l) : l;
|
|
437
|
+
i = w.get(u);
|
|
438
|
+
d[s - h] = i === undefined ? -1 : i;
|
|
439
|
+
w.set(u, s);
|
|
436
440
|
}
|
|
437
441
|
// 1) step through the old changed window and see if items can be found
|
|
438
442
|
// in the new set; if so, stage them at their new positions; if not,
|
|
439
443
|
// queue them for disposal at commit
|
|
440
444
|
for (i = h; i <= c; i++) {
|
|
441
445
|
l = this.ot[i];
|
|
442
|
-
u = this.
|
|
443
|
-
s =
|
|
446
|
+
u = this.Xe ? this.Xe(l) : l;
|
|
447
|
+
s = w.get(u);
|
|
444
448
|
if (s !== undefined && s !== -1) {
|
|
445
449
|
S[s] = this.ht[i];
|
|
446
450
|
M[s - h] = this.tn[i];
|
|
447
451
|
r && (r[s - h] = this.ct[i]);
|
|
448
452
|
o && (o[s - h] = this.lt[i]);
|
|
449
|
-
s =
|
|
450
|
-
|
|
453
|
+
s = d[s - h];
|
|
454
|
+
w.set(u, s);
|
|
451
455
|
} else {
|
|
452
456
|
(p ??= []).push(this.tn[i]);
|
|
453
457
|
if (false && attrHooks !== null) ;
|
|
@@ -472,7 +476,7 @@ function updateKeyedMap() {
|
|
|
472
476
|
// function: kept out of this body on purpose, see commitWindow); then
|
|
473
477
|
// the exited rows dispose
|
|
474
478
|
for (i = 0; i < h; i++) S[i] = this.ht[i];
|
|
475
|
-
for (s = a + 1; s < e; s++) S[s] = this.ht[s -
|
|
479
|
+
for (s = a + 1; s < e; s++) S[s] = this.ht[s - A];
|
|
476
480
|
commitWindow(this, t, e, h, c, a, M, r, o);
|
|
477
481
|
this.ht = S;
|
|
478
482
|
this.it = e;
|
|
@@ -504,8 +508,8 @@ function updateKeyedMap() {
|
|
|
504
508
|
const n = {
|
|
505
509
|
H: createOwner(),
|
|
506
510
|
it: 0,
|
|
507
|
-
|
|
508
|
-
|
|
511
|
+
wt: 0,
|
|
512
|
+
dt: t,
|
|
509
513
|
ft: s,
|
|
510
514
|
tn: [],
|
|
511
515
|
ht: [],
|
|
@@ -526,8 +530,8 @@ function updateKeyedMap() {
|
|
|
526
530
|
// disjoint-window/front-clear/end-clear/shift special cases.
|
|
527
531
|
function updateRepeat() {
|
|
528
532
|
// As in updateKeyedMap: the node is the row callbacks' reader, per pass.
|
|
529
|
-
this.H.
|
|
530
|
-
const t = this.
|
|
533
|
+
this.H.Ke = getOwner();
|
|
534
|
+
const t = this.dt();
|
|
531
535
|
const e = this.Ot?.() || 0;
|
|
532
536
|
runWithOwner(this.H, () => {
|
|
533
537
|
if (t === 0) {
|
|
@@ -537,7 +541,7 @@ function updateRepeat() {
|
|
|
537
541
|
this.ht = [];
|
|
538
542
|
this.it = 0;
|
|
539
543
|
// Reset offset to match the cleared data (#2767, repro 2).
|
|
540
|
-
this.
|
|
544
|
+
this.wt = 0;
|
|
541
545
|
}
|
|
542
546
|
if (this.L && !this.ht.length) {
|
|
543
547
|
// an aborted fallback attempt leaves an owner without a mapping;
|
|
@@ -548,16 +552,16 @@ function updateRepeat() {
|
|
|
548
552
|
return;
|
|
549
553
|
}
|
|
550
554
|
const i = e + t;
|
|
551
|
-
const s = this.
|
|
555
|
+
const s = this.wt + this.it;
|
|
552
556
|
// Retained overlap [keepStart, keepEnd) in global indexes; empty when the
|
|
553
557
|
// windows are disjoint or when coming from empty/fallback.
|
|
554
|
-
const n = Math.max(e, this.
|
|
558
|
+
const n = Math.max(e, this.wt);
|
|
555
559
|
const r = Math.min(i, s);
|
|
556
560
|
const o = new Array(t);
|
|
557
561
|
const f = new Array(t);
|
|
558
562
|
for (let t = n; t < r; t++) {
|
|
559
|
-
f[t - e] = this.tn[t - this.
|
|
560
|
-
o[t - e] = this.ht[t - this.
|
|
563
|
+
f[t - e] = this.tn[t - this.wt];
|
|
564
|
+
o[t - e] = this.ht[t - this.wt];
|
|
561
565
|
}
|
|
562
566
|
try {
|
|
563
567
|
for (let t = e; t < i; t++) {
|
|
@@ -569,10 +573,10 @@ function updateRepeat() {
|
|
|
569
573
|
throw t;
|
|
570
574
|
}
|
|
571
575
|
// commit: dispose the previous fallback or the rows leaving the window
|
|
572
|
-
if (this.it === 0) this.tn[0]?.dispose(); else for (let t = this.
|
|
576
|
+
if (this.it === 0) this.tn[0]?.dispose(); else for (let t = this.wt; t < s; t++) if (t < e || t >= i) this.tn[t - this.wt].dispose();
|
|
573
577
|
this.ht = o;
|
|
574
578
|
this.tn = f;
|
|
575
|
-
this.
|
|
579
|
+
this.wt = e;
|
|
576
580
|
this.it = t;
|
|
577
581
|
});
|
|
578
582
|
return this.ht;
|
package/dist/prod/reveal.js
CHANGED
|
@@ -59,37 +59,37 @@ const slotMinReady = t => isController(t) ? t.Rt() : ready(t);
|
|
|
59
59
|
|
|
60
60
|
class RevealController {
|
|
61
61
|
yt;
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
At;
|
|
63
|
+
kt=[];
|
|
64
64
|
/** The controller gating this one, until it releases this one. */
|
|
65
65
|
_parent=null;
|
|
66
66
|
/** The state a parent forces on this whole group. */
|
|
67
67
|
$=false;
|
|
68
68
|
ee=false;
|
|
69
69
|
Ct=true;
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
vt=true;
|
|
71
|
+
gt=false;
|
|
72
72
|
constructor(t, e) {
|
|
73
73
|
this.yt = t;
|
|
74
|
-
this.
|
|
74
|
+
this.At = e;
|
|
75
75
|
}
|
|
76
76
|
/** A slot that has left this controller's ownership: a boundary that has
|
|
77
77
|
* shown content, a nested group that is ready. Shown is shown — it counts
|
|
78
|
-
* as ready whatever happens to it later (a re-arm gates nobody else). */
|
|
78
|
+
* as ready whatever happens to it later (a re-arm gates nobody else). */ Lt(t) {
|
|
79
79
|
return (isController(t) ? t._parent : t.v) !== this;
|
|
80
80
|
}
|
|
81
81
|
/** The slots this controller still owns, in registration order — the
|
|
82
|
-
* ones the order's state is forced on. */
|
|
83
|
-
for (let e = 0; e < this.
|
|
84
|
-
const s = this.
|
|
85
|
-
if (!this.
|
|
82
|
+
* ones the order's state is forced on. */ Mt(t) {
|
|
83
|
+
for (let e = 0; e < this.kt.length; e++) {
|
|
84
|
+
const s = this.kt[e];
|
|
85
|
+
if (!this.Lt(s) && t(s) === false) return false;
|
|
86
86
|
}
|
|
87
87
|
return true;
|
|
88
88
|
}
|
|
89
89
|
/** Readiness is judged over every slot, done ones as ready. */ St() {
|
|
90
|
-
for (let t = 0; t < this.
|
|
91
|
-
const e = this.
|
|
92
|
-
if (!this.
|
|
90
|
+
for (let t = 0; t < this.kt.length; t++) {
|
|
91
|
+
const e = this.kt[t];
|
|
92
|
+
if (!this.Lt(e) && !slotReady(e)) return false;
|
|
93
93
|
}
|
|
94
94
|
return true;
|
|
95
95
|
}
|
|
@@ -97,21 +97,21 @@ class RevealController {
|
|
|
97
97
|
* `together` waits for: `together` — every slot minimally ready;
|
|
98
98
|
* `sequential` — the first slot; `natural` — any. */ Rt() {
|
|
99
99
|
const t = untrack(this.yt);
|
|
100
|
-
const e = this.
|
|
100
|
+
const e = this.kt;
|
|
101
101
|
if (e.length === 0) return true;
|
|
102
|
-
if (t === "sequential") return this.
|
|
102
|
+
if (t === "sequential") return this.Lt(e[0]) || slotMinReady(e[0]);
|
|
103
103
|
for (let s = 0; s < e.length; s++) {
|
|
104
|
-
const r = this.
|
|
104
|
+
const r = this.Lt(e[s]) || slotMinReady(e[s]);
|
|
105
105
|
if (t === "natural" ? r : !r) return t === "natural";
|
|
106
106
|
}
|
|
107
107
|
return t !== "natural";
|
|
108
108
|
}
|
|
109
109
|
te(t) {
|
|
110
|
-
if (this.
|
|
111
|
-
this.
|
|
110
|
+
if (this.kt.includes(t)) return;
|
|
111
|
+
this.kt.push(t);
|
|
112
112
|
// Gated from the start (collapsed in a collapsed sequential tail); the
|
|
113
113
|
// evaluation releases what the order allows.
|
|
114
|
-
const e = untrack(this.yt) === "sequential" && !!untrack(this.
|
|
114
|
+
const e = untrack(this.yt) === "sequential" && !!untrack(this.At);
|
|
115
115
|
if (isController(t)) {
|
|
116
116
|
t._parent = this;
|
|
117
117
|
t.$ = true;
|
|
@@ -125,31 +125,31 @@ class RevealController {
|
|
|
125
125
|
untrack(() => this._t());
|
|
126
126
|
}
|
|
127
127
|
oe(t) {
|
|
128
|
-
const e = this.
|
|
129
|
-
if (e >= 0) this.
|
|
128
|
+
const e = this.kt.indexOf(t);
|
|
129
|
+
if (e >= 0) this.kt.splice(e, 1);
|
|
130
130
|
untrack(() => this._t());
|
|
131
131
|
}
|
|
132
132
|
/** Apply the order to the owned slots — or, gated by a parent, its state
|
|
133
133
|
* to all of them. */ _t() {
|
|
134
|
-
if (this.
|
|
135
|
-
this.
|
|
134
|
+
if (this.gt) return;
|
|
135
|
+
this.gt = true;
|
|
136
136
|
const t = this.Ct;
|
|
137
|
-
const e = this.
|
|
137
|
+
const e = this.vt;
|
|
138
138
|
try {
|
|
139
139
|
const t = untrack(this.yt);
|
|
140
|
-
const e = t === "sequential" && !!untrack(this.
|
|
140
|
+
const e = t === "sequential" && !!untrack(this.At);
|
|
141
141
|
if (this.$) {
|
|
142
|
-
this.
|
|
142
|
+
this.Mt(t => setSlotState(t, this, true, this.ee));
|
|
143
143
|
} else if (t === "natural") {
|
|
144
|
-
this.
|
|
144
|
+
this.Mt(t => {
|
|
145
145
|
if (isController(t)) setSlotState(t, this, false, false); else setSlotState(t, this, !ready(t), false);
|
|
146
146
|
});
|
|
147
147
|
} else if (t === "together") {
|
|
148
|
-
const t = this.
|
|
149
|
-
this.
|
|
148
|
+
const t = this.Mt(slotMinReady);
|
|
149
|
+
this.Mt(e => setSlotState(e, this, !t, false));
|
|
150
150
|
} else {
|
|
151
151
|
let t = false;
|
|
152
|
-
this.
|
|
152
|
+
this.Mt(s => {
|
|
153
153
|
if (t) return setSlotState(s, this, true, e);
|
|
154
154
|
if (slotReady(s)) return setSlotState(s, this, false, false);
|
|
155
155
|
t = true;
|
|
@@ -160,10 +160,10 @@ class RevealController {
|
|
|
160
160
|
}
|
|
161
161
|
} finally {
|
|
162
162
|
this.Ct = this.St();
|
|
163
|
-
this.
|
|
164
|
-
this.
|
|
163
|
+
this.vt = this.Rt();
|
|
164
|
+
this.gt = false;
|
|
165
165
|
}
|
|
166
|
-
if (this._parent !== null && (t !== this.Ct || e !== this.
|
|
166
|
+
if (this._parent !== null && (t !== this.Ct || e !== this.vt)) this._parent._t();
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -189,7 +189,7 @@ class RevealController {
|
|
|
189
189
|
const e = t();
|
|
190
190
|
const s = computed(() => {
|
|
191
191
|
i.yt();
|
|
192
|
-
i.
|
|
192
|
+
i.At();
|
|
193
193
|
i._t();
|
|
194
194
|
});
|
|
195
195
|
if (false) ;
|
package/dist/prod/signals.js
CHANGED
|
@@ -363,7 +363,7 @@ function createMemo(e, t) {
|
|
|
363
363
|
o?.(u);
|
|
364
364
|
queueMicrotask(() => t(u));
|
|
365
365
|
}, {
|
|
366
|
-
|
|
366
|
+
xe: n
|
|
367
367
|
}).l |= CONFIG_REDERIVE;
|
|
368
368
|
}
|
|
369
369
|
|
|
@@ -541,7 +541,7 @@ function createMemo(e, t) {
|
|
|
541
541
|
// The flip, inside the pass of the flush carrying it: the flush
|
|
542
542
|
// joins the action's transaction, and what it staged is held and
|
|
543
543
|
// revealed with the action.
|
|
544
|
-
if (e && c !== null && globalQueue.
|
|
544
|
+
if (e && c !== null && globalQueue.Y && resolveTx(c).tt !== 0) joinFuture(c);
|
|
545
545
|
});
|
|
546
546
|
if (t?.timeout !== undefined) i = setTimeout(() => settle(() => n(new TimeoutError)), t.timeout);
|
|
547
547
|
if (o !== undefined) {
|
|
@@ -657,7 +657,7 @@ function createMemo(e, t) {
|
|
|
657
657
|
// still holding the optimistic value — reads do not pull (#3411). Fall
|
|
658
658
|
// to the next pass while the heap has work; `run` swapped the queue,
|
|
659
659
|
// so this lands there, and `enqueue` keeps the drain alive.
|
|
660
|
-
if (dirtyQueue.
|
|
660
|
+
if (dirtyQueue.Et >= dirtyQueue.Fe) return globalQueue.enqueue(EFFECT_USER, fire);
|
|
661
661
|
// Unowned, out-of-band fire (no owner, or a children-forbidden one this
|
|
662
662
|
// one-shot must not bind to): a returned cleanup has no lifecycle to
|
|
663
663
|
// attach to. Reject it in dev; in production the return is simply
|
|
@@ -38,24 +38,24 @@ const scopes = new Map;
|
|
|
38
38
|
function scopeOf(e, o) {
|
|
39
39
|
let n = scopes.get(e);
|
|
40
40
|
if (n === undefined) scopes.set(e, n = {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
oo: new Set,
|
|
42
|
+
no: [],
|
|
43
|
+
Xe: o
|
|
44
44
|
});
|
|
45
45
|
return n;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/** The nodes an `affects(store[, key])` declaration marks (affects.ts
|
|
49
49
|
* registers each). */ function storeMarks(e, o) {
|
|
50
|
-
const n = GlobalQueue.
|
|
50
|
+
const n = GlobalQueue.so(e, o === undefined ? $AFFECTS : o);
|
|
51
51
|
const t = scopeOf(n, o);
|
|
52
52
|
if (o === undefined) {
|
|
53
53
|
const o = [ n ];
|
|
54
54
|
walk(e.px, t, o, e.fam, new Set);
|
|
55
55
|
return o;
|
|
56
56
|
}
|
|
57
|
-
t.
|
|
58
|
-
if (e.pb !== null) t.
|
|
57
|
+
t.oo.add(e.v);
|
|
58
|
+
if (e.pb !== null) t.oo.add(e.pb);
|
|
59
59
|
return [ n ];
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -63,14 +63,14 @@ function scopeOf(e, o) {
|
|
|
63
63
|
* the committed backing both, when a draft is open; an optimistic family's
|
|
64
64
|
* view), every live node under each record into `found`. Untracked by
|
|
65
65
|
* construction: raws, never traps. */ function walk(e, o, n, t, s) {
|
|
66
|
-
if (!GlobalQueue.
|
|
66
|
+
if (!GlobalQueue.fo(e)) return;
|
|
67
67
|
const f = e[$TARGET] ?? lookupTarget(e, t);
|
|
68
68
|
let r = f !== undefined ? f.pb ?? f.v : e;
|
|
69
69
|
if (s.has(r)) return;
|
|
70
70
|
s.add(r);
|
|
71
|
-
o.
|
|
71
|
+
o.oo.add(r);
|
|
72
72
|
if (f !== undefined) {
|
|
73
|
-
if (f.pb !== null) o.
|
|
73
|
+
if (f.pb !== null) o.oo.add(f.v);
|
|
74
74
|
// The writer's view: the tick's own unflushed guesses are in motion too.
|
|
75
75
|
if (optHooks && f.fam?.opt === true) r = optHooks.view(f, r, true);
|
|
76
76
|
const e = f.n;
|
|
@@ -94,9 +94,9 @@ function scopeOf(e, o) {
|
|
|
94
94
|
* backings (§7b): a view's backing is another store's proxy — marks cover
|
|
95
95
|
* the BASE raw, so every identity along the chain is checked. */ function covering(e, o, n) {
|
|
96
96
|
for (const [t, s] of scopes) {
|
|
97
|
-
if (t === n || s.
|
|
97
|
+
if (t === n || s.Xe !== undefined && s.Xe !== o) continue;
|
|
98
98
|
for (let o = e.v; ;) {
|
|
99
|
-
if (s.
|
|
99
|
+
if (s.oo.has(o)) return t;
|
|
100
100
|
const e = o?.[$TARGET];
|
|
101
101
|
if (e === undefined) break;
|
|
102
102
|
const n = e.pb ?? e.v;
|
|
@@ -112,17 +112,17 @@ function scopeOf(e, o) {
|
|
|
112
112
|
* no work. */ const hooks = {
|
|
113
113
|
// A node born on a record a live mark covers inherits it (released with
|
|
114
114
|
// the carrier's last registration).
|
|
115
|
-
|
|
115
|
+
ro(e, o, n) {
|
|
116
116
|
if (scopes.size === 0 || n === $AFFECTS) return;
|
|
117
117
|
const t = covering(e, n, o);
|
|
118
118
|
if (!t) return;
|
|
119
119
|
GlobalQueue.N(o);
|
|
120
|
-
scopes.get(t).
|
|
120
|
+
scopes.get(t).no.push(o);
|
|
121
121
|
},
|
|
122
122
|
// An untracked probe (`isPending(() => s.x)` with no observer) reading a
|
|
123
123
|
// record a live mark covers: no node carries the mark for it — the
|
|
124
124
|
// verdict is told directly.
|
|
125
|
-
|
|
125
|
+
io(e, o) {
|
|
126
126
|
if (e.n?.[$AFFECTS]?.T?.I || covering(e, o)) GlobalQueue.rt();
|
|
127
127
|
}
|
|
128
128
|
};
|
|
@@ -136,7 +136,7 @@ function scopeOf(e, o) {
|
|
|
136
136
|
const o = scopes.get(e);
|
|
137
137
|
if (o === undefined) return;
|
|
138
138
|
scopes.delete(e);
|
|
139
|
-
releaseMarksHook(o.
|
|
139
|
+
releaseMarksHook(o.no);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
export { installStoreAffects, releaseMarkScope, storeMarks };
|