@solidjs/signals 2.0.0-beta.20 → 2.0.0-beta.22
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 +267 -307
- package/dist/node.cjs +1125 -1168
- package/dist/prod/affects.js +71 -163
- package/dist/prod/boundaries.js +141 -137
- package/dist/prod/core/action.js +50 -12
- package/dist/prod/core/async.js +83 -99
- package/dist/prod/core/core.js +255 -298
- package/dist/prod/core/effect.js +46 -46
- package/dist/prod/core/external.js +4 -4
- package/dist/prod/core/graph.js +54 -46
- package/dist/prod/core/heap.js +58 -50
- package/dist/prod/core/lanes.js +34 -34
- package/dist/prod/core/optimistic.js +64 -106
- package/dist/prod/core/owner.js +52 -52
- package/dist/prod/core/scheduler.js +217 -211
- package/dist/prod/core/verdict.js +144 -78
- package/dist/prod/map.js +101 -101
- package/dist/prod/signals.js +23 -5
- package/dist/prod/store/optimistic.js +11 -11
- package/dist/prod/store/projection.js +2 -2
- package/dist/prod/store/store.js +14 -14
- package/dist/types/affects.d.ts +9 -9
- package/dist/types/core/action.d.ts +16 -0
- package/dist/types/core/async.d.ts +1 -1
- package/dist/types/core/error.d.ts +7 -0
- package/dist/types/core/scheduler.d.ts +1 -6
- package/dist/types/core/types.d.ts +6 -11
- package/dist/types-cjs/affects.d.cts +9 -9
- package/dist/types-cjs/core/action.d.cts +16 -0
- package/dist/types-cjs/core/async.d.cts +1 -1
- package/dist/types-cjs/core/error.d.cts +7 -0
- package/dist/types-cjs/core/scheduler.d.cts +1 -6
- package/dist/types-cjs/core/types.d.cts +6 -11
- package/package.json +1 -1
package/dist/prod/core/async.js
CHANGED
|
@@ -22,79 +22,75 @@ import { globalQueue, GlobalQueue, clock, schedule, flush, queuePendingNode, ins
|
|
|
22
22
|
// overlapping source landed beside the Set and removePendingSource refused
|
|
23
23
|
// to clear it, stranding the Set members' pending forever (#2893).
|
|
24
24
|
function addPendingSource(e, n) {
|
|
25
|
-
if (e.
|
|
26
|
-
(e.
|
|
25
|
+
if (e.oe?.has(n)) return false;
|
|
26
|
+
(e.oe ??= new Set).add(n);
|
|
27
27
|
return true;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function removePendingSource(e, n) {
|
|
31
|
-
if (!e.
|
|
32
|
-
if (e.
|
|
31
|
+
if (!e.oe?.delete(n)) return false;
|
|
32
|
+
if (e.oe.size === 0) e.oe = undefined;
|
|
33
33
|
return true;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function clearPendingSources(e) {
|
|
37
|
-
e.
|
|
38
|
-
e.
|
|
37
|
+
e.oe?.clear();
|
|
38
|
+
e.oe = undefined;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function setPendingError(e, n, r) {
|
|
42
42
|
if (!n) {
|
|
43
|
-
e.
|
|
43
|
+
e._ = null;
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
if (r instanceof NotReadyError && r.source === n) {
|
|
47
|
-
e.
|
|
47
|
+
e._ = r;
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
-
const t = e.
|
|
50
|
+
const t = e._;
|
|
51
51
|
if (!(t instanceof NotReadyError) || t.source !== n) {
|
|
52
|
-
e.
|
|
52
|
+
e._ = new NotReadyError(n);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function forEachDependent(e, n) {
|
|
57
|
-
for (let r = e.
|
|
57
|
+
for (let r = e.o; r !== null; r = r.ue) n(r.le, r);
|
|
58
58
|
// `?? null`: affects() marks route plain signals (no `_child` slot) through here.
|
|
59
|
-
for (let r = e.
|
|
60
|
-
for (let e = r.
|
|
59
|
+
for (let r = e.u ?? null; r !== null; r = r.fe) {
|
|
60
|
+
for (let e = r.o; e !== null; e = e.ue) n(e.le, e);
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// Queue a node to re-run on the next flush (used both when a pending source
|
|
65
65
|
// settles and when an `isPending` observer must re-evaluate after a real error):
|
|
66
66
|
// shared scheduling helper in heap.ts (tracked effects bypass the heap).
|
|
67
|
-
function settlePendingSource(e
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const r = e.m?.values().next().value;
|
|
81
|
-
if (r) {
|
|
82
|
-
setPendingError(e, r);
|
|
83
|
-
u !== null && u(e);
|
|
67
|
+
function settlePendingSource(e) {
|
|
68
|
+
let n = false;
|
|
69
|
+
const r = new Set;
|
|
70
|
+
// Companion updates no-op without the verdict layer (null hook).
|
|
71
|
+
const t = GlobalQueue.ae;
|
|
72
|
+
const settle = o => {
|
|
73
|
+
if (r.has(o) || !removePendingSource(o, e)) return;
|
|
74
|
+
r.add(o);
|
|
75
|
+
o.ce = clock;
|
|
76
|
+
const u = o.oe?.values().next().value;
|
|
77
|
+
if (u) {
|
|
78
|
+
setPendingError(o, u);
|
|
79
|
+
t !== null && t(o);
|
|
84
80
|
} else {
|
|
85
|
-
|
|
86
|
-
setPendingError(
|
|
87
|
-
|
|
88
|
-
if (
|
|
89
|
-
enqueueSub(
|
|
90
|
-
|
|
81
|
+
o.S &= ~STATUS_PENDING;
|
|
82
|
+
setPendingError(o);
|
|
83
|
+
t !== null && t(o);
|
|
84
|
+
if (o.Se) {
|
|
85
|
+
enqueueSub(o);
|
|
86
|
+
n = true;
|
|
91
87
|
}
|
|
92
|
-
|
|
88
|
+
o.Se = false;
|
|
93
89
|
}
|
|
94
|
-
forEachDependent(
|
|
90
|
+
forEachDependent(o, settle);
|
|
95
91
|
};
|
|
96
92
|
forEachDependent(e, settle);
|
|
97
|
-
if (
|
|
93
|
+
if (n) schedule();
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
// Object-thenable detection (Promises/A+ shape).
|
|
@@ -112,34 +108,34 @@ function handleAsync(e, n, r) {
|
|
|
112
108
|
});
|
|
113
109
|
}
|
|
114
110
|
if (!o && !t) {
|
|
115
|
-
e.
|
|
111
|
+
e.Te = null;
|
|
116
112
|
return n;
|
|
117
113
|
}
|
|
118
|
-
e.
|
|
114
|
+
e.Te = n;
|
|
119
115
|
let u;
|
|
120
116
|
const handleError = r => {
|
|
121
|
-
if (e.
|
|
117
|
+
if (e.Te !== n) return;
|
|
122
118
|
globalQueue.initTransition(resolveTransition(e));
|
|
123
119
|
// NotReadyError from rejected promises should be treated as pending, not error
|
|
124
120
|
notifyStatus(e, r instanceof NotReadyError ? STATUS_PENDING : STATUS_ERROR, r);
|
|
125
|
-
e.
|
|
121
|
+
e.ce = clock;
|
|
126
122
|
};
|
|
127
123
|
const asyncWrite = (t, o) => {
|
|
128
|
-
if (e.
|
|
124
|
+
if (e.Te !== n) return;
|
|
129
125
|
// If the node was dirtied by a newer write (optimistic override or regular),
|
|
130
126
|
// skip this stale async result — the upcoming flush will recompute the node
|
|
131
127
|
// with the new value, creating a fresh Promise that supersedes this one.
|
|
132
|
-
if (e.
|
|
128
|
+
if (e.se & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY)) return;
|
|
133
129
|
globalQueue.initTransition(resolveTransition(e));
|
|
134
|
-
const u = !!(e.
|
|
130
|
+
const u = !!(e.S & STATUS_UNINITIALIZED);
|
|
135
131
|
trimStaleDeps(e);
|
|
136
132
|
clearStatus(e);
|
|
137
133
|
const l = resolveLane(e);
|
|
138
|
-
if (l) l.
|
|
134
|
+
if (l) l.de.delete(e);
|
|
139
135
|
if (r) {
|
|
140
136
|
r(t);
|
|
141
137
|
if (u) clearStatus(e, true);
|
|
142
|
-
} else if (e.
|
|
138
|
+
} else if (e.Ee !== undefined) {
|
|
143
139
|
// Optimistic node — resting OR covered by an active override — holds
|
|
144
140
|
// through the shared pending-node path, exactly like a plain async memo,
|
|
145
141
|
// so the commit clears STATUS_UNINITIALIZED (#2806) and elevation to
|
|
@@ -149,8 +145,8 @@ function handleAsync(e, n, r) {
|
|
|
149
145
|
// (A17 — every reader sees the override); the revert reveals whatever
|
|
150
146
|
// has committed by then, so corrections reveal atomically with their
|
|
151
147
|
// transition rather than escaping it.
|
|
152
|
-
if (e.
|
|
153
|
-
e.
|
|
148
|
+
if (e.Ne === NOT_PENDING) queuePendingNode(e);
|
|
149
|
+
e.Ne = t;
|
|
154
150
|
// The hold is a companion-visible write like any other (A13/A19): the
|
|
155
151
|
// clearStatus() above computed its verdict before the hold existed, so
|
|
156
152
|
// isPending must re-derive (the value is not final until commit — V1)
|
|
@@ -158,22 +154,22 @@ function handleAsync(e, n, r) {
|
|
|
158
154
|
// only notified when the hold is visible to them: under an active
|
|
159
155
|
// override every reader sees the override (A17), so waking subs would
|
|
160
156
|
// re-show an unchanged view — the revert is the notification point.
|
|
161
|
-
GlobalQueue.
|
|
157
|
+
GlobalQueue.Ie !== null && GlobalQueue.Ie(e, t);
|
|
162
158
|
if (!hasActiveOverride(e)) insertSubs(e);
|
|
163
|
-
e.
|
|
159
|
+
e.ce = clock;
|
|
164
160
|
} else if (l) {
|
|
165
161
|
// Route through lane's effect queue for independent flushing
|
|
166
|
-
const n = e.
|
|
167
|
-
const r = e.
|
|
168
|
-
const o = e.
|
|
162
|
+
const n = e.Ae;
|
|
163
|
+
const r = e.Re;
|
|
164
|
+
const o = e.Pe;
|
|
169
165
|
try {
|
|
170
166
|
if (!n && u || !o || !o(t, r)) {
|
|
171
|
-
e.
|
|
172
|
-
e.
|
|
167
|
+
e.Re = t;
|
|
168
|
+
e.ce = clock;
|
|
173
169
|
// The latest() shadow write gives latest() effects independent lanes; the
|
|
174
170
|
// _pendingSignal update is a no-op repeat of the clearStatus() call above
|
|
175
171
|
// (computePendingState doesn't read _value).
|
|
176
|
-
GlobalQueue.
|
|
172
|
+
GlobalQueue.Ie !== null && GlobalQueue.Ie(e, t);
|
|
177
173
|
insertSubs(e, true);
|
|
178
174
|
}
|
|
179
175
|
} catch (n) {
|
|
@@ -242,7 +238,7 @@ function handleAsync(e, n, r) {
|
|
|
242
238
|
i = r;
|
|
243
239
|
f = true;
|
|
244
240
|
if (r.done) o = true;
|
|
245
|
-
} else if (e.
|
|
241
|
+
} else if (e.Te !== n) {
|
|
246
242
|
return;
|
|
247
243
|
} else if (!r.done) {
|
|
248
244
|
t = true;
|
|
@@ -261,7 +257,7 @@ function handleAsync(e, n, r) {
|
|
|
261
257
|
if (c) {
|
|
262
258
|
s = r;
|
|
263
259
|
a = true;
|
|
264
|
-
} else if (e.
|
|
260
|
+
} else if (e.Te === n) {
|
|
265
261
|
o = true;
|
|
266
262
|
handleError(r);
|
|
267
263
|
}
|
|
@@ -293,86 +289,74 @@ function handleAsync(e, n, r) {
|
|
|
293
289
|
}
|
|
294
290
|
|
|
295
291
|
function clearStatus(e, n = false) {
|
|
296
|
-
if (e.
|
|
297
|
-
if (e.
|
|
292
|
+
if (e.oe) clearPendingSources(e);
|
|
293
|
+
if (e.Se) e.Se = false;
|
|
298
294
|
// The pending window is over; its quiet classification dies with it.
|
|
299
295
|
// (Unconditional: _reask is baked into the node literals, so this is a
|
|
300
296
|
// plain store to an existing slot — no shape change.)
|
|
301
|
-
e.
|
|
302
|
-
e.
|
|
303
|
-
if (e.
|
|
297
|
+
e.be = false;
|
|
298
|
+
e.S = n ? 0 : e.S & STATUS_UNINITIALIZED;
|
|
299
|
+
if (e._) setPendingError(e);
|
|
304
300
|
// Update pending signal for isPending() reactivity (companions only exist
|
|
305
301
|
// once the verdict layer created them, which installs the hooks).
|
|
306
|
-
if (e.
|
|
307
|
-
if (e.
|
|
308
|
-
if (e.
|
|
302
|
+
if (e.ge || e.he) GlobalQueue.ae(e);
|
|
303
|
+
if (e.u && GlobalQueue._e !== null) GlobalQueue._e(e);
|
|
304
|
+
if (e.i) e.i();
|
|
309
305
|
}
|
|
310
306
|
|
|
311
307
|
function notifyStatus(e, n, r, t, o) {
|
|
312
308
|
// Wrap regular errors to track source node
|
|
313
309
|
if (n === STATUS_ERROR && !(r instanceof StatusError) && !(r instanceof NotReadyError)) r = new StatusError(e, r);
|
|
314
310
|
const u = n === STATUS_PENDING && r instanceof NotReadyError ? r.source : undefined;
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
// freeze unrelated writes that share a downstream memo until the action
|
|
319
|
-
// settles. Real async keeps queuing (its commits ride the transition).
|
|
320
|
-
const l = u?.l !== undefined;
|
|
321
|
-
// A real error is a settled verdict a mark must not erase (#2893): landing
|
|
322
|
-
// STATUS_PENDING here would clobber `_error` with the sentinel's
|
|
323
|
-
// NotReadyError, and unlike real async there is no arriving value whose
|
|
324
|
-
// recompute would surface the error again. Descent stops too — everything
|
|
325
|
-
// downstream holds the propagated error for the same reason.
|
|
326
|
-
if (l && e.i & STATUS_ERROR) return;
|
|
327
|
-
const i = u === e;
|
|
328
|
-
const s = n === STATUS_PENDING && e.be !== undefined && !i;
|
|
329
|
-
const f = s && hasActiveOverride(e);
|
|
311
|
+
const l = u === e;
|
|
312
|
+
const i = n === STATUS_PENDING && e.Ee !== undefined && !l;
|
|
313
|
+
const s = i && hasActiveOverride(e);
|
|
330
314
|
if (!t) {
|
|
331
315
|
if (n === STATUS_PENDING && u) {
|
|
332
316
|
addPendingSource(e, u);
|
|
333
|
-
e.
|
|
317
|
+
e.S = STATUS_PENDING | e.S & STATUS_UNINITIALIZED;
|
|
334
318
|
// Preserve the current source on this propagation so render-effect notification
|
|
335
319
|
// can register every distinct pending source with the transition.
|
|
336
320
|
setPendingError(e, u, r);
|
|
337
321
|
} else {
|
|
338
322
|
clearPendingSources(e);
|
|
339
|
-
e.
|
|
340
|
-
e.
|
|
323
|
+
e.S = n | (n !== STATUS_ERROR ? e.S & STATUS_UNINITIALIZED : 0);
|
|
324
|
+
e._ = r;
|
|
341
325
|
}
|
|
342
|
-
GlobalQueue.
|
|
343
|
-
if (e.
|
|
326
|
+
GlobalQueue.ae !== null && GlobalQueue.ae(e);
|
|
327
|
+
if (e.u && GlobalQueue._e !== null) GlobalQueue._e(e);
|
|
344
328
|
}
|
|
345
329
|
if (o && !t) {
|
|
346
330
|
assignOrMergeLane(e, o);
|
|
347
331
|
}
|
|
348
|
-
const
|
|
349
|
-
const
|
|
350
|
-
if (e.
|
|
332
|
+
const f = t || s;
|
|
333
|
+
const a = t || i ? undefined : o;
|
|
334
|
+
if (e.i) {
|
|
351
335
|
if (t && n === STATUS_PENDING) {
|
|
352
336
|
return;
|
|
353
337
|
}
|
|
354
|
-
if (
|
|
355
|
-
e.
|
|
338
|
+
if (f) {
|
|
339
|
+
e.i(n, r);
|
|
356
340
|
} else {
|
|
357
|
-
e.
|
|
341
|
+
e.i();
|
|
358
342
|
}
|
|
359
343
|
return;
|
|
360
344
|
}
|
|
361
345
|
forEachDependent(e, (e, t) => {
|
|
362
|
-
e.
|
|
363
|
-
if (n === STATUS_PENDING && u && !e.
|
|
346
|
+
e.ce = clock;
|
|
347
|
+
if (n === STATUS_PENDING && u && !e.oe?.has(u) || n !== STATUS_PENDING && (e._ !== r || e.oe)) {
|
|
364
348
|
// A pending-observer link is the subscription an `isPending` read created.
|
|
365
349
|
// It exists so the observer re-runs when the source settles, but it must
|
|
366
350
|
// not carry a real (non-NotReadyError) error — the synchronous `isPending`
|
|
367
351
|
// read swallows those, and the async path must match. Re-run the observer
|
|
368
352
|
// so `isPending` re-evaluates (to not-pending) instead of forwarding.
|
|
369
|
-
if (t.
|
|
353
|
+
if (t.De && n !== STATUS_PENDING && !(r instanceof NotReadyError)) {
|
|
370
354
|
enqueueSub(e);
|
|
371
355
|
schedule();
|
|
372
356
|
return;
|
|
373
357
|
}
|
|
374
|
-
if (!
|
|
375
|
-
notifyStatus(e, n, r,
|
|
358
|
+
if (!f && !e.Ue) queuePendingNode(e);
|
|
359
|
+
notifyStatus(e, n, r, f, a);
|
|
376
360
|
}
|
|
377
361
|
});
|
|
378
362
|
}
|