@solidjs/signals 2.0.0-rc.5 → 2.0.0-rc.7
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.js +2467 -1322
- package/dist/node.cjs +2037 -2428
- package/dist/node.dev.cjs +13724 -0
- package/dist/prod/boundaries.js +3 -1
- package/dist/prod/core/async.js +47 -20
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +9 -1
- package/dist/prod/core/context.js +10 -16
- package/dist/prod/core/core.js +260 -188
- package/dist/prod/core/dev.js +2 -0
- package/dist/prod/core/effect.js +41 -32
- package/dist/prod/core/external.js +2 -2
- package/dist/prod/core/graph.js +35 -31
- package/dist/prod/core/heap.js +34 -40
- package/dist/prod/core/lanes.js +44 -30
- package/dist/prod/core/optimistic.js +55 -45
- package/dist/prod/core/owner.js +35 -35
- package/dist/prod/core/scheduler.js +176 -177
- package/dist/prod/core/verdict.js +53 -52
- package/dist/prod/index.js +0 -2
- package/dist/prod/map.js +104 -94
- package/dist/prod/signals.js +119 -35
- package/dist/prod/store/next/optimistic.js +217 -163
- package/dist/prod/store/next/projection.js +2 -2
- package/dist/prod/store/next/reconcile.js +140 -288
- package/dist/prod/store/next/store.js +338 -252
- package/dist/prod/store/store.js +2 -2
- package/dist/types/core/attribution-hooks.d.ts +75 -0
- package/dist/types/core/attribution.d.ts +313 -9
- package/dist/types/core/constants.d.ts +8 -0
- package/dist/types/core/core.d.ts +12 -3
- package/dist/types/core/dev.d.ts +56 -9
- package/dist/types/core/heap.d.ts +5 -3
- package/dist/types/core/invariants.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +10 -0
- package/dist/types/core/scheduler.d.ts +14 -4
- package/dist/types/signals.d.ts +10 -11
- package/dist/types/store/index.d.ts +3 -6
- package/dist/types/store/next/optimistic.d.ts +4 -2
- package/dist/types/store/next/reconcile.d.ts +5 -12
- package/dist/types/store/next/store.d.ts +3 -9
- package/dist/types/store/next/target.d.ts +30 -46
- package/dist/types/store/store.d.ts +14 -9
- package/dist/types-cjs/core/attribution-hooks.d.cts +75 -0
- package/dist/types-cjs/core/attribution.d.cts +313 -9
- package/dist/types-cjs/core/constants.d.cts +8 -0
- package/dist/types-cjs/core/core.d.cts +12 -3
- package/dist/types-cjs/core/dev.d.cts +56 -9
- package/dist/types-cjs/core/heap.d.cts +5 -3
- package/dist/types-cjs/core/invariants.d.cts +1 -1
- package/dist/types-cjs/core/lanes.d.cts +10 -0
- package/dist/types-cjs/core/scheduler.d.cts +14 -4
- package/dist/types-cjs/signals.d.cts +10 -11
- package/dist/types-cjs/store/index.d.cts +3 -6
- package/dist/types-cjs/store/next/optimistic.d.cts +4 -2
- package/dist/types-cjs/store/next/reconcile.d.cts +5 -12
- package/dist/types-cjs/store/next/store.d.cts +3 -9
- package/dist/types-cjs/store/next/target.d.cts +30 -46
- package/dist/types-cjs/store/store.d.cts +14 -9
- package/package.json +3 -2
- package/dist/prod/store/next/patch-hooks.js +0 -13
- package/dist/prod/store/next/patch.js +0 -614
- package/dist/types/store/next/patch-hooks.d.ts +0 -41
- package/dist/types/store/next/patch.d.ts +0 -91
- package/dist/types-cjs/store/next/patch-hooks.d.cts +0 -41
- package/dist/types-cjs/store/next/patch.d.cts +0 -91
package/dist/prod/boundaries.js
CHANGED
|
@@ -291,7 +291,9 @@ class CollectionQueue extends Queue {
|
|
|
291
291
|
if (t) {
|
|
292
292
|
const e = this.v.size === 0;
|
|
293
293
|
this.v.add(t);
|
|
294
|
-
if (e)
|
|
294
|
+
if (e) {
|
|
295
|
+
setSignal(this.D, true);
|
|
296
|
+
}
|
|
295
297
|
if (this.ee & STATUS_ERROR) {
|
|
296
298
|
setSignal(this._, unwrapStatusError(t.o?._));
|
|
297
299
|
}
|
package/dist/prod/core/async.js
CHANGED
|
@@ -28,13 +28,15 @@ function addPendingSource(e, n) {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
function removePendingSource(e, n) {
|
|
31
|
-
|
|
32
|
-
if (
|
|
31
|
+
const t = e.o?.le;
|
|
32
|
+
if (!t?.delete(n)) return false;
|
|
33
|
+
if (!t.size) e.o.le = undefined;
|
|
33
34
|
return true;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
function clearPendingSources(e) {
|
|
37
|
-
|
|
38
|
+
// This set is node-owned and never shared; dropping the sole reference
|
|
39
|
+
// releases the set and every entry without a redundant clear() walk.
|
|
38
40
|
if (e.o !== null) e.o.le = undefined;
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -140,6 +142,10 @@ function settleErroredDependents(e, n) {
|
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
function settlePendingSource(e) {
|
|
145
|
+
// The normal landing path already cleared the source's own set. Superseded
|
|
146
|
+
// re-parks arrive here with an abandoned self entry, which must retire in
|
|
147
|
+
// the same walk as its propagated copies.
|
|
148
|
+
removePendingSource(e, e);
|
|
143
149
|
let n = false;
|
|
144
150
|
let t;
|
|
145
151
|
const r = new Set;
|
|
@@ -253,6 +259,10 @@ function handleAsync(e, n, t) {
|
|
|
253
259
|
}
|
|
254
260
|
settleTransition();
|
|
255
261
|
notifyStatus(e, r ? STATUS_PENDING : STATUS_ERROR, t);
|
|
262
|
+
// A NotReady rejection is a landing into another pending source. The
|
|
263
|
+
// rejected flight will never settle its self entry, so transfer ownership
|
|
264
|
+
// after notifyStatus has propagated the replacement source.
|
|
265
|
+
if (r) settlePendingSource(e);
|
|
256
266
|
e.Te = clock;
|
|
257
267
|
// A real error settles derivatively-pending dependents (notifyStatus
|
|
258
268
|
// cleared their pending sources), so stranded lazy ones release here —
|
|
@@ -267,14 +277,27 @@ function handleAsync(e, n, t) {
|
|
|
267
277
|
if (e.ie & (REACTIVE_DIRTY | REACTIVE_OPTIMISTIC_DIRTY)) return;
|
|
268
278
|
settleTransition();
|
|
269
279
|
const i = !!(e.S & STATUS_UNINITIALIZED);
|
|
280
|
+
// Captured before clearStatus wipes it: a quiet re-ask's landing may be
|
|
281
|
+
// transition-held below, and the displayed value keeps answering the same
|
|
282
|
+
// question until the hold commits — the classification must survive to
|
|
283
|
+
// that reveal or companion synchronization briefly classifies the held
|
|
284
|
+
// old value as pending, a one-frame pulse to direct observers (#3178).
|
|
285
|
+
// A truthy capture implies `_x` exists, so the restore writes it directly.
|
|
286
|
+
const l = e.o?.De;
|
|
270
287
|
trimStaleDeps(e);
|
|
271
288
|
clearStatus(e);
|
|
272
|
-
|
|
273
|
-
|
|
289
|
+
if (l) e.o.De = true;
|
|
290
|
+
const s = resolveLane(e);
|
|
291
|
+
if (s) s.Oe.delete(e);
|
|
274
292
|
if (t) {
|
|
275
|
-
|
|
293
|
+
try {
|
|
294
|
+
t(r);
|
|
295
|
+
} catch (e) {
|
|
296
|
+
handleError(e);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
276
299
|
if (i) clearStatus(e, true);
|
|
277
|
-
} else if (e.o?.
|
|
300
|
+
} else if (e.o?.Pe !== undefined) {
|
|
278
301
|
// Optimistic node — resting OR covered by an active override — holds
|
|
279
302
|
// through the shared pending-node path, exactly like a plain async memo,
|
|
280
303
|
// so the commit clears STATUS_UNINITIALIZED (#2806) and elevation to
|
|
@@ -284,8 +307,8 @@ function handleAsync(e, n, t) {
|
|
|
284
307
|
// (A17 — every reader sees the override); the revert reveals whatever
|
|
285
308
|
// has committed by then, so corrections reveal atomically with their
|
|
286
309
|
// transition rather than escaping it.
|
|
287
|
-
if (e.
|
|
288
|
-
e.
|
|
310
|
+
if (e.Re === NOT_PENDING) queuePendingNode(e);
|
|
311
|
+
e.Re = r;
|
|
289
312
|
// The hold is a companion-visible write like any other (A13/A19): the
|
|
290
313
|
// clearStatus() above computed its verdict before the hold existed, so
|
|
291
314
|
// isPending must re-derive (the value is not final until commit — V1)
|
|
@@ -293,7 +316,7 @@ function handleAsync(e, n, t) {
|
|
|
293
316
|
// only notified when the hold is visible to them: under an active
|
|
294
317
|
// override every reader sees the override (A17), so waking subs would
|
|
295
318
|
// re-show an unchanged view — the revert is the notification point.
|
|
296
|
-
GlobalQueue.
|
|
319
|
+
GlobalQueue.Ue?.(e, r);
|
|
297
320
|
if (!hasActiveOverride(e)) {
|
|
298
321
|
insertSubs(e);
|
|
299
322
|
} else if (e.T & CONFIG_AUTHORITATIVE_OBSERVED) {
|
|
@@ -306,14 +329,14 @@ function handleAsync(e, n, t) {
|
|
|
306
329
|
// branch in recompute(). Optional call: the bit implies the
|
|
307
330
|
// optimistic engine WAS consulted, but the hook only installs with
|
|
308
331
|
// it — a bare-core build must not crash here.
|
|
309
|
-
GlobalQueue.
|
|
332
|
+
GlobalQueue.he?.(e);
|
|
310
333
|
}
|
|
311
334
|
e.Te = clock;
|
|
312
|
-
} else if (
|
|
335
|
+
} else if (s) {
|
|
313
336
|
// Route through lane's effect queue for independent flushing
|
|
314
|
-
const n = e.
|
|
337
|
+
const n = e.ge;
|
|
315
338
|
const t = e.be;
|
|
316
|
-
const o = e.
|
|
339
|
+
const o = e.pe;
|
|
317
340
|
try {
|
|
318
341
|
if (!n && i || !o || !o(r, t)) {
|
|
319
342
|
e.be = r;
|
|
@@ -321,7 +344,7 @@ function handleAsync(e, n, t) {
|
|
|
321
344
|
// The latest() shadow write gives latest() effects independent lanes; the
|
|
322
345
|
// _pendingSignal update is a no-op repeat of the clearStatus() call above
|
|
323
346
|
// (computePendingState doesn't read _value).
|
|
324
|
-
GlobalQueue.
|
|
347
|
+
GlobalQueue.Ue?.(e, r);
|
|
325
348
|
insertSubs(e, true);
|
|
326
349
|
}
|
|
327
350
|
} catch (n) {
|
|
@@ -345,8 +368,12 @@ function handleAsync(e, n, t) {
|
|
|
345
368
|
// (`_pendingValue` set above or inside setSignal) is not — the verdict's
|
|
346
369
|
// held-value branch is window-gated, and commitPendingNode closes the
|
|
347
370
|
// window when the hold commits, so no one-frame isPending pulse can leak
|
|
348
|
-
// to live observers between the landing and its commit (#2990).
|
|
349
|
-
|
|
371
|
+
// to live observers between the landing and its commit (#2990). The
|
|
372
|
+
// quiet re-ask classification follows the same schedule (#3178).
|
|
373
|
+
if (e.Re === NOT_PENDING) {
|
|
374
|
+
e.Ne = false;
|
|
375
|
+
if (l) e.o.De = false;
|
|
376
|
+
}
|
|
350
377
|
settlePendingSource(e);
|
|
351
378
|
schedule();
|
|
352
379
|
flush();
|
|
@@ -505,7 +532,7 @@ function handleAsync(e, n, t) {
|
|
|
505
532
|
// becomes disposal-bearing, which is exactly the class a directly
|
|
506
533
|
// returned iterable already occupies.
|
|
507
534
|
const registerDeferredClose = n => {
|
|
508
|
-
if (!e.
|
|
535
|
+
if (!e.Ge) e.Ge = n; else if (Array.isArray(e.Ge)) e.Ge.push(n); else e.Ge = [ e.Ge, n ];
|
|
509
536
|
};
|
|
510
537
|
n.then(r => {
|
|
511
538
|
if (l) {
|
|
@@ -568,7 +595,7 @@ function clearStatus(e, n = false) {
|
|
|
568
595
|
// The pending window is over; its quiet classification dies with it.
|
|
569
596
|
// (Unconditional: _reask is baked into the node literals, so this is a
|
|
570
597
|
// plain store to an existing slot — no shape change.)
|
|
571
|
-
if (e.o !== null) e.o.
|
|
598
|
+
if (e.o !== null) e.o.De = false;
|
|
572
599
|
e.S = n ? 0 : e.S & STATUS_UNINITIALIZED;
|
|
573
600
|
if (e.o?._) setPendingError(e);
|
|
574
601
|
// Update pending signal for isPending() reactivity (companions only exist
|
|
@@ -584,7 +611,7 @@ function notifyStatus(e, n, t, r, o) {
|
|
|
584
611
|
if (n === STATUS_ERROR && !(t instanceof StatusError) && !(t instanceof NotReadyError)) t = new StatusError(e, t);
|
|
585
612
|
const i = n === STATUS_PENDING && t instanceof NotReadyError ? t.source : undefined;
|
|
586
613
|
const l = i === e;
|
|
587
|
-
const s = n === STATUS_PENDING && e.o?.
|
|
614
|
+
const s = n === STATUS_PENDING && e.o?.Pe !== undefined && !l;
|
|
588
615
|
const u = s && hasActiveOverride(e);
|
|
589
616
|
if (!r) {
|
|
590
617
|
if (n === STATUS_PENDING && i) {
|
|
@@ -137,6 +137,14 @@ const CONFIG_HAS_LANE = 1 << 10;
|
|
|
137
137
|
* (A17). Cleared at commit (the commit IS the reveal); subscribers masked
|
|
138
138
|
* during the hold are woken by finalizePureQueue's post-revert pass. */ const CONFIG_HELD_TRUTH = 1 << 17;
|
|
139
139
|
|
|
140
|
+
/** SLOT node (store leaf): created through `slotSignal` with `_host`/`_key`
|
|
141
|
+
* backrefs baked into the literal. The unobserved sweep dispatches these to
|
|
142
|
+
* the ONE shared hook (`setSlotUnobserved`) instead of a per-node closure
|
|
143
|
+
* held in a per-node extension — store mounts materialize one signal per
|
|
144
|
+
* touched leaf, so per-node allocations (options object, equals closure,
|
|
145
|
+
* unobserved closure, NodeExtension) were the measured create-floor bytes
|
|
146
|
+
* (warm dbmon profile: store node machinery ~36% + GC ~29%). */ const CONFIG_SLOT_NODE = 1 << 18;
|
|
147
|
+
|
|
140
148
|
const STATUS_PENDING = 1 << 0;
|
|
141
149
|
|
|
142
150
|
const STATUS_ERROR = 1 << 1;
|
|
@@ -181,4 +189,4 @@ const defaultContext = {};
|
|
|
181
189
|
* @internal
|
|
182
190
|
*/ const $REFRESH = Symbol("refresh");
|
|
183
191
|
|
|
184
|
-
export { $REFRESH, CONFIG_AUTHORITATIVE_OBSERVED, CONFIG_AUTHORITATIVE_READ, CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_CHILD_COMPANIONS, CONFIG_DIRECT_COMMIT, CONFIG_FRESH_READ, CONFIG_FW_CHILDREN, CONFIG_HAS_COMPANIONS, CONFIG_HAS_LANE, CONFIG_HAS_SNAPSHOT, CONFIG_HELD_TRUTH, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_NO_SNAPSHOT, CONFIG_OPTIMISTIC, CONFIG_OWNED_WRITE, CONFIG_SYNC, CONFIG_TRANSPARENT, EFFECT_RENDER, EFFECT_TRACKED, EFFECT_USER, NOT_PENDING, NO_SNAPSHOT, OVERRIDE_UNDEFINED, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_DISPOSED, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, REACTIVE_LAZY, REACTIVE_MANUAL_WRITE, REACTIVE_MISSED_WAKE, REACTIVE_NONE, REACTIVE_OPTIMISTIC_DIRTY, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, REACTIVE_SNAPSHOT_STALE, REACTIVE_ZOMBIE, STATUS_ERROR, STATUS_PENDING, STATUS_UNINITIALIZED, STORE_SNAPSHOT_PROPS, SUPPORTS_PROXY, defaultContext, unwrapOverride };
|
|
192
|
+
export { $REFRESH, CONFIG_AUTHORITATIVE_OBSERVED, CONFIG_AUTHORITATIVE_READ, CONFIG_AUTO_DISPOSE, CONFIG_CHILDREN_FORBIDDEN, CONFIG_CHILD_COMPANIONS, CONFIG_DIRECT_COMMIT, CONFIG_FRESH_READ, CONFIG_FW_CHILDREN, CONFIG_HAS_COMPANIONS, CONFIG_HAS_LANE, CONFIG_HAS_SNAPSHOT, CONFIG_HELD_TRUTH, CONFIG_IN_SNAPSHOT_SCOPE, CONFIG_NO_SNAPSHOT, CONFIG_OPTIMISTIC, CONFIG_OWNED_WRITE, CONFIG_SLOT_NODE, CONFIG_SYNC, CONFIG_TRANSPARENT, EFFECT_RENDER, EFFECT_TRACKED, EFFECT_USER, NOT_PENDING, NO_SNAPSHOT, OVERRIDE_UNDEFINED, REACTIVE_CHECK, REACTIVE_DIRTY, REACTIVE_DISPOSED, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, REACTIVE_LAZY, REACTIVE_MANUAL_WRITE, REACTIVE_MISSED_WAKE, REACTIVE_NONE, REACTIVE_OPTIMISTIC_DIRTY, REACTIVE_REASK, REACTIVE_RECOMPUTING_DEPS, REACTIVE_SNAPSHOT_STALE, REACTIVE_ZOMBIE, STATUS_ERROR, STATUS_PENDING, STATUS_UNINITIALIZED, STORE_SNAPSHOT_PROPS, SUPPORTS_PROXY, defaultContext, unwrapOverride };
|
|
@@ -29,11 +29,13 @@ import { getOwner } from "./owner.js";
|
|
|
29
29
|
if (!t) {
|
|
30
30
|
throw new NoOwnerError;
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
// `undefined` alone means unset — a provided `null` is a value (no `??`).
|
|
33
|
+
let r = t.we[e.id];
|
|
34
|
+
if (r === undefined) r = e.defaultValue;
|
|
35
|
+
if (r === undefined) {
|
|
34
36
|
throw new ContextNotFoundError;
|
|
35
37
|
}
|
|
36
|
-
return
|
|
38
|
+
return r;
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
/**
|
|
@@ -44,24 +46,16 @@ import { getOwner } from "./owner.js";
|
|
|
44
46
|
* @throws `NoOwnerError` if there's no owner at the time of call.
|
|
45
47
|
*
|
|
46
48
|
* @internal
|
|
47
|
-
*/ function setContext(e, t,
|
|
48
|
-
if (!
|
|
49
|
+
*/ function setContext(e, t, r = getOwner()) {
|
|
50
|
+
if (!r) {
|
|
49
51
|
throw new NoOwnerError;
|
|
50
52
|
}
|
|
51
53
|
// We're creating a new object to avoid child context values being exposed to parent owners. If
|
|
52
54
|
// we don't do this, everything will be a singleton and all hell will break lose.
|
|
53
|
-
|
|
54
|
-
...
|
|
55
|
-
[e.id]:
|
|
55
|
+
r.we = {
|
|
56
|
+
...r.we,
|
|
57
|
+
[e.id]: t === undefined ? e.defaultValue : t
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
|
|
59
|
-
function hasContext(e, t) {
|
|
60
|
-
return !isUndefined(t?.we[e.id]);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function isUndefined(e) {
|
|
64
|
-
return typeof e === "undefined";
|
|
65
|
-
}
|
|
66
|
-
|
|
67
61
|
export { createContext, getContext, setContext };
|