@solidjs/signals 2.0.0-rc.8 → 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 +1399 -285
- package/dist/dev.attribution.js +459 -307
- package/dist/dev.js +1864 -435
- package/dist/observe/affects.js +3 -1
- package/dist/observe/attribution.js +7 -1
- package/dist/observe/boundaries.js +209 -154
- package/dist/observe/core/action.js +18 -8
- package/dist/observe/core/async.js +220 -110
- 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 +23 -1
- package/dist/observe/core/attribution-queries.js +28 -0
- package/dist/observe/core/attribution.js +262 -485
- package/dist/observe/core/constants.js +34 -1
- package/dist/observe/core/context.js +3 -3
- package/dist/observe/core/core.js +867 -367
- package/dist/observe/core/dev.js +78 -17
- package/dist/observe/core/effect.js +67 -51
- package/dist/observe/core/error-hooks.js +71 -0
- package/dist/observe/core/external.js +4 -4
- package/dist/observe/core/graph.js +37 -37
- package/dist/observe/core/heap.js +45 -45
- package/dist/observe/core/invariants.js +2 -0
- package/dist/observe/core/lanes.js +86 -49
- package/dist/observe/core/optimistic.js +242 -95
- package/dist/observe/core/owner.js +98 -84
- package/dist/observe/core/scheduler.js +543 -305
- package/dist/observe/core/verdict.js +247 -129
- package/dist/observe/index.js +7 -3
- package/dist/observe/map.js +126 -124
- package/dist/observe/signals.js +33 -17
- package/dist/observe/store/index.js +2 -0
- package/dist/observe/store/next/optimistic.js +141 -132
- package/dist/observe/store/next/projection.js +34 -21
- package/dist/observe/store/next/reconcile.js +58 -56
- package/dist/observe/store/next/store.js +260 -146
- package/dist/observe/store/store.js +5 -3
- package/dist/observe/store/utils.js +948 -135
- package/dist/prod/attribution.js +26 -17
- package/dist/prod/boundaries.js +128 -76
- package/dist/prod/core/action.js +16 -8
- package/dist/prod/core/async.js +251 -143
- package/dist/prod/core/constants.js +34 -1
- package/dist/prod/core/context.js +3 -3
- package/dist/prod/core/core.js +843 -347
- package/dist/prod/core/dev.js +17 -1
- package/dist/prod/core/effect.js +48 -34
- 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 +45 -45
- package/dist/prod/core/lanes.js +90 -53
- package/dist/prod/core/optimistic.js +247 -100
- package/dist/prod/core/owner.js +57 -45
- package/dist/prod/core/scheduler.js +543 -305
- package/dist/prod/core/verdict.js +245 -127
- package/dist/prod/index.js +7 -3
- package/dist/prod/map.js +112 -112
- package/dist/prod/signals.js +28 -12
- package/dist/prod/store/next/optimistic.js +135 -128
- package/dist/prod/store/next/projection.js +31 -20
- package/dist/prod/store/next/store.js +325 -252
- package/dist/prod/store/store.js +2 -2
- package/dist/prod/store/utils.js +946 -135
- package/dist/types/attribution.d.ts +7 -2
- package/dist/types/attribution.prod.d.ts +10 -1
- package/dist/types/boundaries.d.ts +10 -1
- package/dist/types/core/action.d.ts +12 -5
- 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 +28 -3
- package/dist/types/core/attribution-queries.d.ts +10 -0
- package/dist/types/core/attribution.d.ts +51 -172
- package/dist/types/core/constants.d.ts +33 -0
- package/dist/types/core/core.d.ts +186 -5
- package/dist/types/core/dev.d.ts +129 -9
- package/dist/types/core/error-hooks.d.ts +71 -0
- package/dist/types/core/index.d.ts +3 -1
- package/dist/types/core/invariants.d.ts +4 -0
- package/dist/types/core/lanes.d.ts +31 -4
- package/dist/types/core/scheduler.d.ts +95 -2
- package/dist/types/core/types.d.ts +3 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/signals.d.ts +8 -0
- package/dist/types/store/index.d.ts +2 -1
- package/dist/types/store/next/optimistic.d.ts +1 -1
- package/dist/types/store/next/store.d.ts +6 -5
- package/dist/types/store/next/target.d.ts +1 -1
- package/dist/types/store/utils.d.ts +177 -6
- package/package.json +1 -1
package/dist/observe/index.js
CHANGED
|
@@ -14,7 +14,9 @@ import "./core/invariants.js";
|
|
|
14
14
|
|
|
15
15
|
import { OBSERVE as OBSERVE$1 } from "./core/dev.js";
|
|
16
16
|
|
|
17
|
-
export {
|
|
17
|
+
export { ownerPath } from "./core/dev.js";
|
|
18
|
+
|
|
19
|
+
export { ROOT_ERROR_HOOK, enforceLoadingBoundary, flush, resetErrorHalt } from "./core/scheduler.js";
|
|
18
20
|
|
|
19
21
|
export { isPending, latest } from "./core/verdict.js";
|
|
20
22
|
|
|
@@ -22,6 +24,8 @@ import "./core/effect.js";
|
|
|
22
24
|
|
|
23
25
|
export { action } from "./core/action.js";
|
|
24
26
|
|
|
27
|
+
export { configureClientErrors } from "./core/error-hooks.js";
|
|
28
|
+
|
|
25
29
|
export { createEffect, createMemo, createOptimistic, createReaction, createRenderEffect, createSignal, createTrackedEffect, onCleanup, onSettled, refresh, resolve, until } from "./signals.js";
|
|
26
30
|
|
|
27
31
|
export { affects } from "./affects.js";
|
|
@@ -34,12 +38,12 @@ export { createErrorBoundary, createLoadingBoundary, createRevealOrder, flatten
|
|
|
34
38
|
|
|
35
39
|
export { $PROXY, $TARGET, $TRACK, isWrappable } from "./store/store.js";
|
|
36
40
|
|
|
41
|
+
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";
|
|
42
|
+
|
|
37
43
|
export { createOptimisticStoreNext as createOptimisticStore } from "./store/next/optimistic.js";
|
|
38
44
|
|
|
39
45
|
export { createProjectionNext as createProjection } from "./store/next/projection.js";
|
|
40
46
|
|
|
41
|
-
export { merge, mergeSources, omit } from "./store/utils.js";
|
|
42
|
-
|
|
43
47
|
export { storeHasFamily, storeHasOptimisticFamily, storeIsShallow } from "./store/next/store.js";
|
|
44
48
|
|
|
45
49
|
export { storePath } from "./store/storePath.js";
|
package/dist/observe/map.js
CHANGED
|
@@ -10,6 +10,8 @@ import { attrHooks } from "./core/attribution-hooks.js";
|
|
|
10
10
|
|
|
11
11
|
import "./core/invariants.js";
|
|
12
12
|
|
|
13
|
+
import "./core/dev.js";
|
|
14
|
+
|
|
13
15
|
import "./core/verdict.js";
|
|
14
16
|
|
|
15
17
|
import "./core/effect.js";
|
|
@@ -20,31 +22,31 @@ import { $TRACK } from "./store/store.js";
|
|
|
20
22
|
|
|
21
23
|
import "./store/next/store.js";
|
|
22
24
|
|
|
23
|
-
function mapArray(t, s,
|
|
24
|
-
const
|
|
25
|
+
function mapArray(t, s, e) {
|
|
26
|
+
const i = typeof e?.keyed === "function" ? e.keyed : undefined;
|
|
25
27
|
const r = s.length > 1;
|
|
26
28
|
const n = s;
|
|
27
29
|
const o = {
|
|
28
|
-
|
|
30
|
+
nt: createOwner(),
|
|
29
31
|
ts: 0,
|
|
30
32
|
ss: t,
|
|
31
33
|
es: [],
|
|
32
34
|
rs: n,
|
|
33
35
|
ns: [],
|
|
34
36
|
hs: [],
|
|
35
|
-
|
|
36
|
-
fs:
|
|
37
|
-
cs: r &&
|
|
38
|
-
us:
|
|
39
|
-
ls:
|
|
37
|
+
En: i,
|
|
38
|
+
fs: i || e?.keyed === false ? [] : undefined,
|
|
39
|
+
cs: r && e?.keyed !== false ? [] : undefined,
|
|
40
|
+
us: e?.keyed === false,
|
|
41
|
+
ls: e?.fallback
|
|
40
42
|
};
|
|
41
|
-
const h = computed(updateKeyedMap.bind(o),
|
|
42
|
-
name:
|
|
43
|
+
const h = computed(updateKeyedMap.bind(o), e?.name ? {
|
|
44
|
+
name: e.name
|
|
43
45
|
} : undefined);
|
|
44
46
|
// Untracked reads inside the internal owner resolve via _parentComputed; routing
|
|
45
47
|
// them through node lets store-proxy lookups see pending writes (not stale _value).
|
|
46
|
-
o.
|
|
47
|
-
h.
|
|
48
|
+
o.nt.fn = h;
|
|
49
|
+
h.C &= ~CONFIG_AUTO_DISPOSE;
|
|
48
50
|
return accessor(h);
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -52,7 +54,7 @@ const pureOptions = {
|
|
|
52
54
|
ownedWrite: true
|
|
53
55
|
};
|
|
54
56
|
|
|
55
|
-
function trySmallMove(t, s,
|
|
57
|
+
function trySmallMove(t, s, e, i) {
|
|
56
58
|
const r = t.es;
|
|
57
59
|
const n = t.ts - 1;
|
|
58
60
|
const o = [];
|
|
@@ -60,13 +62,13 @@ function trySmallMove(t, s, i, e) {
|
|
|
60
62
|
const f = [];
|
|
61
63
|
// flat triples: oldStart, newStart, length
|
|
62
64
|
let c = 256;
|
|
63
|
-
let a =
|
|
64
|
-
let u =
|
|
65
|
+
let a = i;
|
|
66
|
+
let u = i;
|
|
65
67
|
let l = false;
|
|
66
|
-
while (a <= n && u <=
|
|
68
|
+
while (a <= n && u <= e - 1) {
|
|
67
69
|
const t = r[a];
|
|
68
|
-
const
|
|
69
|
-
if (t ===
|
|
70
|
+
const i = s[u];
|
|
71
|
+
if (t === i) {
|
|
70
72
|
if (!l) {
|
|
71
73
|
f.push(a, u, 0);
|
|
72
74
|
l = true;
|
|
@@ -81,17 +83,17 @@ function trySmallMove(t, s, i, e) {
|
|
|
81
83
|
let d = -1;
|
|
82
84
|
let p = Math.min(32 - o.length, n - a, c);
|
|
83
85
|
for (let t = 1; t <= p; t++) {
|
|
84
|
-
if (r[a + t] ===
|
|
86
|
+
if (r[a + t] === i) {
|
|
85
87
|
d = t;
|
|
86
88
|
break;
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
c -= d === -1 ? p : d;
|
|
90
92
|
let w = -1;
|
|
91
|
-
p = Math.min(32 - h.length,
|
|
92
|
-
for (let
|
|
93
|
-
if (s[u +
|
|
94
|
-
w =
|
|
93
|
+
p = Math.min(32 - h.length, e - 1 - u, c);
|
|
94
|
+
for (let e = 1; e <= p; e++) {
|
|
95
|
+
if (s[u + e] === t) {
|
|
96
|
+
w = e;
|
|
95
97
|
break;
|
|
96
98
|
}
|
|
97
99
|
}
|
|
@@ -112,11 +114,11 @@ function trySmallMove(t, s, i, e) {
|
|
|
112
114
|
if (o.length === 32) return false;
|
|
113
115
|
o.push(a);
|
|
114
116
|
}
|
|
115
|
-
for (;u <=
|
|
117
|
+
for (;u <= e - 1; u++) {
|
|
116
118
|
if (h.length === 32) return false;
|
|
117
119
|
h.push(u);
|
|
118
120
|
}
|
|
119
|
-
return commitSmallMove(t, s,
|
|
121
|
+
return commitSmallMove(t, s, e, o, h, f);
|
|
120
122
|
}
|
|
121
123
|
|
|
122
124
|
/** PHASE 2 of the small-move path, in its OWN function so that a pass which
|
|
@@ -125,17 +127,17 @@ function trySmallMove(t, s, i, e) {
|
|
|
125
127
|
* per function, and cold `replace` measured +0.5 ms with both phases in one
|
|
126
128
|
* body. Pairs displaced sources with destinations (an unmatched destination
|
|
127
129
|
* is a replacement/insertion → general path), then commits: slice() the live
|
|
128
|
-
* arrays, copy shifted runs, patch displaced pairs, dispose leftovers. */ function commitSmallMove(t, s,
|
|
130
|
+
* arrays, copy shifted runs, patch displaced pairs, dispose leftovers. */ function commitSmallMove(t, s, e, i, r, n) {
|
|
129
131
|
const o = t.es;
|
|
130
132
|
let h;
|
|
131
133
|
let f;
|
|
132
134
|
let c;
|
|
133
135
|
if (r.length !== 0) {
|
|
134
|
-
c = new Array(
|
|
136
|
+
c = new Array(i.length);
|
|
135
137
|
for (f = 0; f < r.length; f++) {
|
|
136
138
|
let t = -1;
|
|
137
|
-
for (h = 0; h <
|
|
138
|
-
if (!c[h] && o[
|
|
139
|
+
for (h = 0; h < i.length; h++) {
|
|
140
|
+
if (!c[h] && o[i[h]] === s[r[f]]) {
|
|
139
141
|
t = h;
|
|
140
142
|
break;
|
|
141
143
|
}
|
|
@@ -152,42 +154,42 @@ function trySmallMove(t, s, i, e) {
|
|
|
152
154
|
// and if a displaced identity also occurs inside a run the two algorithms
|
|
153
155
|
// can hand different occurrences different owners (row-local state moves;
|
|
154
156
|
// a shrink could dispose the wrong one). Decline that case — general path.
|
|
155
|
-
if (
|
|
157
|
+
if (i.length !== 0 || r.length !== 0) {
|
|
156
158
|
const t = new Set;
|
|
157
|
-
for (h = 0; h <
|
|
159
|
+
for (h = 0; h < i.length; h++) t.add(o[i[h]]);
|
|
158
160
|
for (f = 0; f < r.length; f++) t.add(s[r[f] >> 6]);
|
|
159
161
|
for (let s = 0; s < n.length; s += 3) {
|
|
160
|
-
const
|
|
161
|
-
for (let
|
|
162
|
+
const e = n[s];
|
|
163
|
+
for (let i = 0, r = n[s + 2]; i < r; i++) if (t.has(o[e + i])) return false;
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
166
|
const a = t.ns;
|
|
165
167
|
const u = t.hs;
|
|
166
|
-
const l = a.slice(0,
|
|
167
|
-
const d = u.slice(0,
|
|
168
|
+
const l = a.slice(0, e);
|
|
169
|
+
const d = u.slice(0, e);
|
|
168
170
|
for (let t = 0; t < n.length; t += 3) {
|
|
169
171
|
const s = n[t];
|
|
170
|
-
const
|
|
171
|
-
if (s !==
|
|
172
|
-
for (let
|
|
173
|
-
l[
|
|
174
|
-
d[
|
|
172
|
+
const e = n[t + 1];
|
|
173
|
+
if (s !== e) {
|
|
174
|
+
for (let i = 0; i < n[t + 2]; i++) {
|
|
175
|
+
l[e + i] = a[s + i];
|
|
176
|
+
d[e + i] = u[s + i];
|
|
175
177
|
}
|
|
176
178
|
}
|
|
177
179
|
}
|
|
178
180
|
for (f = 0; f < r.length; f++) {
|
|
179
181
|
const t = r[f] >> 6;
|
|
180
|
-
const s =
|
|
182
|
+
const s = i[r[f] & 63];
|
|
181
183
|
l[t] = a[s];
|
|
182
184
|
d[t] = u[s];
|
|
183
185
|
}
|
|
184
186
|
t.ns = l;
|
|
185
187
|
t.hs = d;
|
|
186
|
-
t.ts =
|
|
188
|
+
t.ts = e;
|
|
187
189
|
t.es = s.slice(0);
|
|
188
190
|
// Dispose unmatched sources LAST (general-path ordering).
|
|
189
|
-
for (h = 0; h <
|
|
190
|
-
if (c === undefined || !c[h]) u[
|
|
191
|
+
for (h = 0; h < i.length; h++) {
|
|
192
|
+
if (c === undefined || !c[h]) u[i[h]].dispose();
|
|
191
193
|
}
|
|
192
194
|
return true;
|
|
193
195
|
}
|
|
@@ -196,29 +198,29 @@ function updateKeyedMap() {
|
|
|
196
198
|
const t = this.ss() || [], s = t.length;
|
|
197
199
|
t[$TRACK];
|
|
198
200
|
// top level tracking
|
|
199
|
-
runWithOwner(this.
|
|
200
|
-
let
|
|
201
|
+
runWithOwner(this.nt, () => {
|
|
202
|
+
let e, i, r, n,
|
|
201
203
|
// Mappers write freshly-created row/index signals into the STAGE
|
|
202
204
|
// arrays (`rows`/`indexes`), never into `this._rows`/`this._indexes`.
|
|
203
205
|
o = this.fs ? this.us ? () => {
|
|
204
|
-
r[
|
|
205
|
-
return this.rs(accessor(r[
|
|
206
|
+
r[i] = signal(t[i], pureOptions);
|
|
207
|
+
return this.rs(accessor(r[i]), i);
|
|
206
208
|
} : () => {
|
|
207
|
-
r[
|
|
208
|
-
n && (n[
|
|
209
|
-
return this.rs(accessor(r[
|
|
209
|
+
r[i] = signal(t[i], pureOptions);
|
|
210
|
+
n && (n[i] = signal(i, pureOptions));
|
|
211
|
+
return this.rs(accessor(r[i]), n ? accessor(n[i]) : undefined);
|
|
210
212
|
} : this.cs ? () => {
|
|
211
|
-
const s = t[
|
|
212
|
-
n[
|
|
213
|
-
return this.rs(s, accessor(n[
|
|
213
|
+
const s = t[i];
|
|
214
|
+
n[i] = signal(i, pureOptions);
|
|
215
|
+
return this.rs(s, accessor(n[i]));
|
|
214
216
|
} : () => {
|
|
215
|
-
const s = t[
|
|
217
|
+
const s = t[i];
|
|
216
218
|
return this.rs(s);
|
|
217
219
|
};
|
|
218
220
|
// fast path for empty arrays
|
|
219
221
|
if (s === 0) {
|
|
220
222
|
if (this.ts !== 0) {
|
|
221
|
-
this.
|
|
223
|
+
this.nt.dispose(false);
|
|
222
224
|
this.hs = [];
|
|
223
225
|
this.es = [];
|
|
224
226
|
this.ns = [];
|
|
@@ -240,9 +242,9 @@ function updateKeyedMap() {
|
|
|
240
242
|
r = this.fs && new Array(s);
|
|
241
243
|
n = this.cs && new Array(s);
|
|
242
244
|
try {
|
|
243
|
-
for (
|
|
245
|
+
for (i = 0; i < s; i++) h[i] = runWithOwner(f[i] = createOwner(), o);
|
|
244
246
|
} catch (t) {
|
|
245
|
-
for (
|
|
247
|
+
for (e = 0; e <= i; e++) f[e]?.dispose();
|
|
246
248
|
throw t;
|
|
247
249
|
}
|
|
248
250
|
// commit
|
|
@@ -260,12 +262,12 @@ function updateKeyedMap() {
|
|
|
260
262
|
// entered rows, for the list-identity census.
|
|
261
263
|
m, O;
|
|
262
264
|
// skip common prefix
|
|
263
|
-
for (h = 0, f = Math.min(this.ts, s); h < f && (this.es[h] === t[h] || this.fs && compare(this.
|
|
265
|
+
for (h = 0, f = Math.min(this.ts, s); h < f && (this.es[h] === t[h] || this.fs && compare(this.En, this.es[h], t[h])); h++) {
|
|
264
266
|
if (this.fs) setSignal(this.fs[h], t[h]);
|
|
265
267
|
}
|
|
266
268
|
// skip common suffix — counted only; retained entries land in one pass
|
|
267
269
|
// at commit instead of being staged and copied twice
|
|
268
|
-
for (f = this.ts - 1, c = s - 1; f >= h && c >= h && (this.es[f] === t[c] || this.fs && compare(this.
|
|
270
|
+
for (f = this.ts - 1, c = s - 1; f >= h && c >= h && (this.es[f] === t[c] || this.fs && compare(this.En, this.es[f], t[c])); f--,
|
|
269
271
|
c--) ;
|
|
270
272
|
// no structural change (every position matched in place at equal
|
|
271
273
|
// length — the common post-reconcile shape): keep the same mapped
|
|
@@ -287,11 +289,11 @@ function updateKeyedMap() {
|
|
|
287
289
|
// every page's first structural pass usually is) has it nowhere.
|
|
288
290
|
// ~65 compares, no allocation, and the scan function is never
|
|
289
291
|
// compiled for a replace (its cold first-call compile was the cost).
|
|
290
|
-
const
|
|
291
|
-
const
|
|
292
|
-
const r = Math.min(f,
|
|
293
|
-
let n = Math.max(h,
|
|
294
|
-
while (n <= r && this.es[n] !==
|
|
292
|
+
const e = h + (c - h >> 1);
|
|
293
|
+
const i = t[e];
|
|
294
|
+
const r = Math.min(f, e + 32);
|
|
295
|
+
let n = Math.max(h, e - 32);
|
|
296
|
+
while (n <= r && this.es[n] !== i) n++;
|
|
295
297
|
if (n <= r && trySmallMove(this, t, s, h)) return;
|
|
296
298
|
}
|
|
297
299
|
const _ = s - this.ts;
|
|
@@ -303,67 +305,67 @@ function updateKeyedMap() {
|
|
|
303
305
|
// scanning backwards so we encounter them in natural order
|
|
304
306
|
l = new Map;
|
|
305
307
|
d = new Array(c + 1);
|
|
306
|
-
for (
|
|
307
|
-
a = t[
|
|
308
|
-
u = this.
|
|
309
|
-
|
|
310
|
-
d[
|
|
311
|
-
l.set(u,
|
|
308
|
+
for (i = c; i >= h; i--) {
|
|
309
|
+
a = t[i];
|
|
310
|
+
u = this.En ? this.En(a) : a;
|
|
311
|
+
e = l.get(u);
|
|
312
|
+
d[i] = e === undefined ? -1 : e;
|
|
313
|
+
l.set(u, i);
|
|
312
314
|
}
|
|
313
315
|
// 1) step through the old changed window and see if items can be found
|
|
314
316
|
// in the new set; if so, stage them at their new positions; if not,
|
|
315
317
|
// queue them for disposal at commit
|
|
316
|
-
for (
|
|
317
|
-
a = this.es[
|
|
318
|
-
u = this.
|
|
319
|
-
|
|
320
|
-
if (
|
|
321
|
-
y[
|
|
322
|
-
A[
|
|
323
|
-
r && (r[
|
|
324
|
-
n && (n[
|
|
325
|
-
|
|
326
|
-
l.set(u,
|
|
318
|
+
for (e = h; e <= f; e++) {
|
|
319
|
+
a = this.es[e];
|
|
320
|
+
u = this.En ? this.En(a) : a;
|
|
321
|
+
i = l.get(u);
|
|
322
|
+
if (i !== undefined && i !== -1) {
|
|
323
|
+
y[i] = this.ns[e];
|
|
324
|
+
A[i] = this.hs[e];
|
|
325
|
+
r && (r[i] = this.fs[e]);
|
|
326
|
+
n && (n[i] = this.cs[e]);
|
|
327
|
+
i = d[i];
|
|
328
|
+
l.set(u, i);
|
|
327
329
|
} else {
|
|
328
|
-
(p ??= []).push(this.hs[
|
|
330
|
+
(p ??= []).push(this.hs[e]);
|
|
329
331
|
if (true && attrHooks !== null) (m ??= []).push(a);
|
|
330
332
|
}
|
|
331
333
|
}
|
|
332
334
|
// 2) create new rows into the temp arrays; an abort disposes only these
|
|
333
335
|
try {
|
|
334
|
-
for (
|
|
335
|
-
if (A[
|
|
336
|
-
(w ??= []).push(A[
|
|
337
|
-
if (true && attrHooks !== null) (O ??= []).push(t[
|
|
338
|
-
y[
|
|
336
|
+
for (i = h; i <= c; i++) {
|
|
337
|
+
if (A[i] !== undefined) continue;
|
|
338
|
+
(w ??= []).push(A[i] = createOwner());
|
|
339
|
+
if (true && attrHooks !== null) (O ??= []).push(t[i]);
|
|
340
|
+
y[i] = runWithOwner(A[i], o);
|
|
339
341
|
}
|
|
340
342
|
} catch (t) {
|
|
341
|
-
if (w) for (
|
|
343
|
+
if (w) for (e = 0; e < w.length; e++) w[e].dispose();
|
|
342
344
|
throw t;
|
|
343
345
|
}
|
|
344
346
|
// 3) commit: land the retained prefix and suffix plus the staged window
|
|
345
347
|
// into the fresh arrays, swap them in (new identity for downstream
|
|
346
348
|
// change propagation), then dispose exited rows
|
|
347
|
-
for (
|
|
348
|
-
y[
|
|
349
|
-
A[
|
|
350
|
-
r && (r[
|
|
351
|
-
n && (n[
|
|
349
|
+
for (e = 0; e < h; e++) {
|
|
350
|
+
y[e] = this.ns[e];
|
|
351
|
+
A[e] = this.hs[e];
|
|
352
|
+
r && (r[e] = this.fs[e]);
|
|
353
|
+
n && (n[e] = this.cs[e]);
|
|
352
354
|
}
|
|
353
|
-
for (
|
|
354
|
-
if (r) setSignal(r[
|
|
355
|
-
if (n) setSignal(n[
|
|
355
|
+
for (i = h; i <= c; i++) {
|
|
356
|
+
if (r) setSignal(r[i], t[i]);
|
|
357
|
+
if (n) setSignal(n[i], i);
|
|
356
358
|
}
|
|
357
|
-
for (
|
|
358
|
-
y[
|
|
359
|
-
A[
|
|
359
|
+
for (i = c + 1; i < s; i++) {
|
|
360
|
+
y[i] = this.ns[i - _];
|
|
361
|
+
A[i] = this.hs[i - _];
|
|
360
362
|
if (r) {
|
|
361
|
-
r[
|
|
362
|
-
setSignal(r[
|
|
363
|
+
r[i] = this.fs[i - _];
|
|
364
|
+
setSignal(r[i], t[i]);
|
|
363
365
|
}
|
|
364
366
|
if (n) {
|
|
365
|
-
n[
|
|
366
|
-
if (_ !== 0) setSignal(n[
|
|
367
|
+
n[i] = this.cs[i - _];
|
|
368
|
+
if (_ !== 0) setSignal(n[i], i);
|
|
367
369
|
}
|
|
368
370
|
}
|
|
369
371
|
this.ns = y;
|
|
@@ -373,8 +375,8 @@ function updateKeyedMap() {
|
|
|
373
375
|
this.ts = s;
|
|
374
376
|
// save a copy of the mapped items for the next update
|
|
375
377
|
this.es = t.slice(0);
|
|
376
|
-
if (p) for (
|
|
377
|
-
if (true && attrHooks !== null && m !== undefined && O !== undefined) attrHooks.listChurn(this.
|
|
378
|
+
if (p) for (e = 0; e < p.length; e++) p[e].dispose();
|
|
379
|
+
if (true && attrHooks !== null && m !== undefined && O !== undefined) attrHooks.listChurn(this.nt.fn, m, O, s, this.En !== undefined);
|
|
378
380
|
}
|
|
379
381
|
});
|
|
380
382
|
return this.ns;
|
|
@@ -394,25 +396,25 @@ function updateKeyedMap() {
|
|
|
394
396
|
* ```
|
|
395
397
|
*
|
|
396
398
|
* @description https://docs.solidjs.com/reference/reactive-utilities/repeat
|
|
397
|
-
*/ function repeat(t, s,
|
|
398
|
-
const
|
|
399
|
+
*/ function repeat(t, s, e) {
|
|
400
|
+
const i = s;
|
|
399
401
|
const r = {
|
|
400
|
-
|
|
402
|
+
nt: createOwner(),
|
|
401
403
|
ts: 0,
|
|
402
404
|
ds: 0,
|
|
403
405
|
ps: t,
|
|
404
|
-
rs:
|
|
406
|
+
rs: i,
|
|
405
407
|
hs: [],
|
|
406
408
|
ns: [],
|
|
407
|
-
ws:
|
|
408
|
-
ls:
|
|
409
|
+
ws: e?.from,
|
|
410
|
+
ls: e?.fallback
|
|
409
411
|
};
|
|
410
412
|
const n = computed(updateRepeat.bind(r));
|
|
411
413
|
// Same as mapArray: untracked reads inside the internal owner resolve via
|
|
412
414
|
// _parentComputed, so async reads in row callbacks register with the node
|
|
413
415
|
// (pending tracking + post-settle retry) instead of vanishing.
|
|
414
|
-
r.
|
|
415
|
-
n.
|
|
416
|
+
r.nt.fn = n;
|
|
417
|
+
n.C &= ~CONFIG_AUTO_DISPOSE;
|
|
416
418
|
return accessor(n);
|
|
417
419
|
}
|
|
418
420
|
|
|
@@ -426,10 +428,10 @@ function updateKeyedMap() {
|
|
|
426
428
|
function updateRepeat() {
|
|
427
429
|
const t = this.ps();
|
|
428
430
|
const s = this.ws?.() || 0;
|
|
429
|
-
runWithOwner(this.
|
|
431
|
+
runWithOwner(this.nt, () => {
|
|
430
432
|
if (t === 0) {
|
|
431
433
|
if (this.ts !== 0) {
|
|
432
|
-
this.
|
|
434
|
+
this.nt.dispose(false);
|
|
433
435
|
this.hs = [];
|
|
434
436
|
this.ns = [];
|
|
435
437
|
this.ts = 0;
|
|
@@ -444,12 +446,12 @@ function updateRepeat() {
|
|
|
444
446
|
}
|
|
445
447
|
return;
|
|
446
448
|
}
|
|
447
|
-
const
|
|
448
|
-
const
|
|
449
|
+
const e = s + t;
|
|
450
|
+
const i = this.ds + this.ts;
|
|
449
451
|
// Retained overlap [keepStart, keepEnd) in global indexes; empty when the
|
|
450
452
|
// windows are disjoint or when coming from empty/fallback.
|
|
451
453
|
const r = Math.max(s, this.ds);
|
|
452
|
-
const n = Math.min(
|
|
454
|
+
const n = Math.min(e, i);
|
|
453
455
|
const o = new Array(t);
|
|
454
456
|
const h = new Array(t);
|
|
455
457
|
for (let t = r; t < n; t++) {
|
|
@@ -457,16 +459,16 @@ function updateRepeat() {
|
|
|
457
459
|
o[t - s] = this.ns[t - this.ds];
|
|
458
460
|
}
|
|
459
461
|
try {
|
|
460
|
-
for (let t = s; t <
|
|
462
|
+
for (let t = s; t < e; t++) {
|
|
461
463
|
if (t >= r && t < n) continue;
|
|
462
464
|
o[t - s] = runWithOwner(h[t - s] = createOwner(), () => this.rs(t));
|
|
463
465
|
}
|
|
464
466
|
} catch (t) {
|
|
465
|
-
for (let t = s; t <
|
|
467
|
+
for (let t = s; t < e; t++) if ((t < r || t >= n) && h[t - s]) h[t - s].dispose();
|
|
466
468
|
throw t;
|
|
467
469
|
}
|
|
468
470
|
// commit: dispose the previous fallback or the rows leaving the window
|
|
469
|
-
if (this.ts === 0) this.hs[0]?.dispose(); else for (let t = this.ds; t <
|
|
471
|
+
if (this.ts === 0) this.hs[0]?.dispose(); else for (let t = this.ds; t < i; t++) if (t < s || t >= e) this.hs[t - this.ds].dispose();
|
|
470
472
|
this.ns = o;
|
|
471
473
|
this.hs = h;
|
|
472
474
|
this.ds = s;
|
|
@@ -475,8 +477,8 @@ function updateRepeat() {
|
|
|
475
477
|
return this.ns;
|
|
476
478
|
}
|
|
477
479
|
|
|
478
|
-
function compare(t, s,
|
|
479
|
-
return t ? t(s) === t(
|
|
480
|
+
function compare(t, s, e) {
|
|
481
|
+
return t ? t(s) === t(e) : true;
|
|
480
482
|
}
|
|
481
483
|
|
|
482
484
|
export { mapArray, repeat };
|
package/dist/observe/signals.js
CHANGED
|
@@ -4,7 +4,7 @@ import { computed, optimisticComputed, setSignal, optimisticSignal, runWithOwner
|
|
|
4
4
|
|
|
5
5
|
import { cleanup, createRoot, getOwner, dispose, getObserver } from "./core/owner.js";
|
|
6
6
|
|
|
7
|
-
import { globalQueue, Queue, entangleConfirmingTransitions, activeTransition } from "./core/scheduler.js";
|
|
7
|
+
import { globalQueue, dirtyQueue, Queue, entangleConfirmingTransitions, activeTransition } from "./core/scheduler.js";
|
|
8
8
|
|
|
9
9
|
import { CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, EFFECT_USER, $REFRESH, CONFIG_DIRECT_COMMIT, CONFIG_AUTHORITATIVE_READ, CONFIG_FRESH_READ } from "./core/constants.js";
|
|
10
10
|
|
|
@@ -69,7 +69,7 @@ function accessor(e) {
|
|
|
69
69
|
function createSignal(e, t) {
|
|
70
70
|
if (typeof e === "function") {
|
|
71
71
|
const r = computed(e, t);
|
|
72
|
-
r.
|
|
72
|
+
r.C &= ~CONFIG_AUTO_DISPOSE;
|
|
73
73
|
return [ accessor(r), setMemo.bind(null, r) ];
|
|
74
74
|
}
|
|
75
75
|
const r = signal(e, t);
|
|
@@ -330,9 +330,9 @@ function createMemo(e, t) {
|
|
|
330
330
|
// route through the inherited queue.
|
|
331
331
|
const i = getOwner();
|
|
332
332
|
const o = new MicrotaskQueue;
|
|
333
|
-
o.
|
|
333
|
+
o._parent = i.T;
|
|
334
334
|
// notify() forwards up the normal chain
|
|
335
|
-
i.
|
|
335
|
+
i.T = o;
|
|
336
336
|
// A user effect rather than a bare computed: computeds are pull-based and
|
|
337
337
|
// are only re-enqueued when a pending source *resolves* — a rejection just
|
|
338
338
|
// marks them errored, so nothing would re-run and the promise would never
|
|
@@ -352,7 +352,7 @@ function createMemo(e, t) {
|
|
|
352
352
|
// stale mainline value and resolves with old data.
|
|
353
353
|
{
|
|
354
354
|
user: true,
|
|
355
|
-
|
|
355
|
+
Xt: CONFIG_DIRECT_COMMIT
|
|
356
356
|
});
|
|
357
357
|
});
|
|
358
358
|
});
|
|
@@ -445,8 +445,8 @@ function createMemo(e, t) {
|
|
|
445
445
|
if (i === null) {
|
|
446
446
|
i = getOwner();
|
|
447
447
|
const e = new MicrotaskQueue;
|
|
448
|
-
e.
|
|
449
|
-
i.
|
|
448
|
+
e._parent = i.T;
|
|
449
|
+
i.T = e;
|
|
450
450
|
}
|
|
451
451
|
return read(t);
|
|
452
452
|
}, t => {
|
|
@@ -457,7 +457,7 @@ function createMemo(e, t) {
|
|
|
457
457
|
dispose(i);
|
|
458
458
|
}, {
|
|
459
459
|
user: true,
|
|
460
|
-
|
|
460
|
+
Xt: CONFIG_DIRECT_COMMIT | CONFIG_AUTHORITATIVE_READ | CONFIG_FRESH_READ
|
|
461
461
|
});
|
|
462
462
|
make();
|
|
463
463
|
});
|
|
@@ -508,12 +508,20 @@ function createMemo(e, t) {
|
|
|
508
508
|
*
|
|
509
509
|
* Must be called *outside* a tracking scope.
|
|
510
510
|
*
|
|
511
|
+
* Inside an action, call it from a step: after an `await`, put a bare `yield`
|
|
512
|
+
* before `yield until(...)`. The runtime cannot hook an async generator's
|
|
513
|
+
* `await` continuation, so the `until(...)` expression — which CREATES the
|
|
514
|
+
* predicate's reader — would otherwise run outside the transaction; created
|
|
515
|
+
* there it is born held (A29) and replays only at the commit its own promise
|
|
516
|
+
* holds open (#3482). See {@link action}.
|
|
517
|
+
*
|
|
511
518
|
* @example
|
|
512
519
|
* ```ts
|
|
513
520
|
* const send = action(async function* (text: string) {
|
|
514
521
|
* const clientId = crypto.randomUUID();
|
|
515
522
|
* setMessages(m => { m.push({ clientId, text, pending: true }); }); // optimistic
|
|
516
523
|
* await socket.send({ clientId, text }); // fire-and-forget transport
|
|
524
|
+
* yield; // re-enter the transaction after the await
|
|
517
525
|
* // Hold until the live source echoes the write (authoritative view —
|
|
518
526
|
* // the optimistic row above cannot satisfy this):
|
|
519
527
|
* yield until(() => messages.some(m => m.clientId === clientId), { timeout: 10_000 });
|
|
@@ -540,10 +548,10 @@ function createMemo(e, t) {
|
|
|
540
548
|
// microtask so the promise can settle while the transaction the caller
|
|
541
549
|
// yielded it into is still open — that transaction being open is the
|
|
542
550
|
// entire point of the hold.
|
|
543
|
-
const
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
|
|
551
|
+
const u = getOwner();
|
|
552
|
+
const s = new MicrotaskQueue;
|
|
553
|
+
s._parent = u.T;
|
|
554
|
+
u.T = s;
|
|
547
555
|
let f;
|
|
548
556
|
let a;
|
|
549
557
|
const settle = e => {
|
|
@@ -572,7 +580,7 @@ function createMemo(e, t) {
|
|
|
572
580
|
// the hold itself is keeping uncommitted.
|
|
573
581
|
{
|
|
574
582
|
user: true,
|
|
575
|
-
|
|
583
|
+
Xt: CONFIG_AUTHORITATIVE_READ | CONFIG_DIRECT_COMMIT
|
|
576
584
|
});
|
|
577
585
|
if (t?.timeout !== undefined) f = setTimeout(() => settle(() => i(new TimeoutError)), t.timeout);
|
|
578
586
|
if (o !== undefined) {
|
|
@@ -592,7 +600,7 @@ function createOptimistic(e, t) {
|
|
|
592
600
|
installOptimisticEngine();
|
|
593
601
|
if (typeof e === "function") {
|
|
594
602
|
const r = optimisticComputed(e, t);
|
|
595
|
-
r.
|
|
603
|
+
r.C &= ~CONFIG_AUTO_DISPOSE;
|
|
596
604
|
return [ accessor(r), setSignal.bind(null, r) ];
|
|
597
605
|
}
|
|
598
606
|
const r = optimisticSignal(e, t);
|
|
@@ -695,14 +703,22 @@ function createOptimistic(e, t) {
|
|
|
695
703
|
* on owner disposal
|
|
696
704
|
*/ function onSettled(e) {
|
|
697
705
|
const t = getOwner();
|
|
698
|
-
t && !(t.
|
|
706
|
+
t && !(t.C & CONFIG_CHILDREN_FORBIDDEN) ? trackedEffect(() => untrack(e), {
|
|
699
707
|
name: "onSettled"
|
|
700
|
-
}) : globalQueue.enqueue(EFFECT_USER, ()
|
|
708
|
+
}) : globalQueue.enqueue(EFFECT_USER, function fire() {
|
|
709
|
+
// Settled means derived. A settle that reverts optimism (or replays
|
|
710
|
+
// gated reads) only enqueues the affected subscribers; the pass after
|
|
711
|
+
// the commit re-derives them. Fired in the commit pass, the callback
|
|
712
|
+
// read the optimistic source already reverted beside a sync memo of it
|
|
713
|
+
// still holding the optimistic value — reads do not pull (#3411). Fall
|
|
714
|
+
// to the next pass while the heap has work; `run` swapped the queue,
|
|
715
|
+
// so this lands there, and `enqueue` keeps the drain alive.
|
|
716
|
+
if (dirtyQueue.EE >= dirtyQueue.Ct) return globalQueue.enqueue(EFFECT_USER, fire);
|
|
701
717
|
// Unowned, out-of-band fire (no owner, or a children-forbidden one this
|
|
702
718
|
// one-shot must not bind to): a returned cleanup has no lifecycle to
|
|
703
719
|
// attach to. Reject it in dev; in production the return is simply
|
|
704
720
|
// dropped — never bound to an unrelated owner or run eagerly.
|
|
705
|
-
|
|
721
|
+
e();
|
|
706
722
|
});
|
|
707
723
|
}
|
|
708
724
|
|