@solidjs/signals 2.0.0-beta.18 → 2.0.0-beta.19
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 +2743 -694
- package/dist/node.cjs +6419 -4234
- package/dist/prod/affects.js +222 -0
- package/dist/prod/boundaries.js +568 -0
- package/dist/prod/core/action.js +83 -0
- package/dist/prod/core/async.js +394 -0
- package/dist/prod/core/constants.js +78 -0
- package/dist/prod/core/context.js +67 -0
- package/dist/prod/core/core.js +772 -0
- package/dist/prod/core/dev.js +3 -0
- package/dist/prod/core/effect.js +145 -0
- package/dist/prod/core/error.js +59 -0
- package/dist/prod/core/external.js +98 -0
- package/dist/prod/core/graph.js +91 -0
- package/dist/prod/core/heap.js +132 -0
- package/dist/prod/core/invariants.js +42 -0
- package/dist/prod/core/lanes.js +130 -0
- package/dist/prod/core/optimistic.js +265 -0
- package/dist/prod/core/owner.js +293 -0
- package/dist/prod/core/scheduler.js +689 -0
- package/dist/prod/core/verdict.js +293 -0
- package/dist/prod/index.js +45 -0
- package/dist/prod/map.js +264 -0
- package/dist/prod/signals.js +389 -0
- package/dist/prod/store/optimistic.js +149 -0
- package/dist/prod/store/projection.js +184 -0
- package/dist/prod/store/reconcile.js +392 -0
- package/dist/prod/store/store.js +739 -0
- package/dist/prod/store/storePath.js +103 -0
- package/dist/prod/store/utils.js +297 -0
- package/dist/types/affects.d.ts +1 -1
- package/dist/types/boundaries.d.ts +6 -6
- package/dist/types/core/async.d.ts +4 -38
- package/dist/types/core/core.d.ts +12 -78
- package/dist/types/core/external.d.ts +0 -30
- package/dist/types/core/heap.d.ts +8 -0
- package/dist/types/core/index.d.ts +3 -2
- package/dist/types/core/optimistic.d.ts +6 -0
- package/dist/types/core/owner.d.ts +8 -0
- package/dist/types/core/scheduler.d.ts +39 -34
- package/dist/types/core/verdict.d.ts +2 -0
- package/dist/types/store/projection.d.ts +0 -1
- package/dist/types-cjs/affects.d.cts +1 -1
- package/dist/types-cjs/boundaries.d.cts +6 -6
- package/dist/types-cjs/core/async.d.cts +4 -38
- package/dist/types-cjs/core/core.d.cts +12 -78
- package/dist/types-cjs/core/external.d.cts +0 -30
- package/dist/types-cjs/core/heap.d.cts +8 -0
- package/dist/types-cjs/core/index.d.cts +3 -2
- package/dist/types-cjs/core/optimistic.d.cts +6 -0
- package/dist/types-cjs/core/owner.d.cts +8 -0
- package/dist/types-cjs/core/scheduler.d.cts +39 -34
- package/dist/types-cjs/core/verdict.d.cts +2 -0
- package/dist/types-cjs/store/projection.d.cts +0 -1
- package/package.json +8 -6
- package/dist/prod.js +0 -4637
|
@@ -9,6 +9,14 @@ export declare function disposeChildren(node: Owner, self?: boolean, zombie?: bo
|
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
11
11
|
export declare function getNextChildId(owner: Owner): string;
|
|
12
|
+
/**
|
|
13
|
+
* The id a freshly-created node inherits: an explicit `options.id` wins;
|
|
14
|
+
* transparent nodes share their parent's id; otherwise the parent's next
|
|
15
|
+
* child id is consumed (or `undefined` outside an id-carrying tree).
|
|
16
|
+
*/
|
|
17
|
+
export declare function inheritId(options: {
|
|
18
|
+
id?: string;
|
|
19
|
+
} | undefined, transparent: boolean, parent: Owner | null | undefined): string | undefined;
|
|
12
20
|
/**
|
|
13
21
|
* Returns the *next* child id for `owner` without consuming it. Used by
|
|
14
22
|
* hydration plumbing to peek at the id a future child will receive.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Heap } from "./heap.js";
|
|
2
|
-
import { activeLanes, assignOrMergeLane, findLane } from "./lanes.js";
|
|
2
|
+
import { activeLanes, assignOrMergeLane, findLane, type OptimisticLane } from "./lanes.js";
|
|
3
3
|
import type { Computed, Signal } from "./types.js";
|
|
4
4
|
export { activeLanes, assignOrMergeLane, findLane };
|
|
5
5
|
export { getOrCreateLane, hasActiveOverride, mergeLanes, resolveLane } from "./lanes.js";
|
|
@@ -20,7 +20,6 @@ export declare function resetUnhandledAsync(): void;
|
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
22
|
export declare function enforceLoadingBoundary(enabled: boolean): void;
|
|
23
|
-
export declare function shouldReadStashedOptimisticValue(node: Signal<any>): boolean;
|
|
24
23
|
export declare function setProjectionWriteActive(value: boolean): void;
|
|
25
24
|
export declare function setTrackedQueueCallback(value: boolean): void;
|
|
26
25
|
export type QueueCallback = (type: number) => void;
|
|
@@ -47,7 +46,7 @@ export declare function schedule(): void;
|
|
|
47
46
|
* every boundary — app state is undefined at that point, so scheduling stops
|
|
48
47
|
* entirely rather than limping along with a half-applied update.
|
|
49
48
|
*/
|
|
50
|
-
export declare function haltReactivity(): void;
|
|
49
|
+
export declare function haltReactivity(cause?: unknown): void;
|
|
51
50
|
/** @internal Test/dev-reload hook. Revives scheduling after a halt. */
|
|
52
51
|
export declare function resetErrorHalt(): void;
|
|
53
52
|
export interface IQueue {
|
|
@@ -84,10 +83,40 @@ export declare class GlobalQueue extends Queue {
|
|
|
84
83
|
static _update: (el: Computed<unknown>) => void;
|
|
85
84
|
static _dispose: (el: Computed<unknown>, self: boolean, zombie: boolean) => void;
|
|
86
85
|
static _runEffect: (el: Computed<unknown>) => void;
|
|
87
|
-
static
|
|
86
|
+
static _clearOptimisticStores: ((stores: Set<any>) => void) | null;
|
|
88
87
|
static _releaseAffectsScope: ((node: OptimisticNode) => void) | null;
|
|
89
|
-
static
|
|
90
|
-
static
|
|
88
|
+
static _applyAffectsReads: ((el: Computed<any>, sources: (Signal<any> | Computed<any>)[]) => void) | null;
|
|
89
|
+
static _releaseAffectsMarks: ((nodes: OptimisticNode[]) => void) | null;
|
|
90
|
+
static _markAffects: ((node: OptimisticNode) => void) | null;
|
|
91
|
+
static _releaseAffectsMark: ((node: OptimisticNode) => void) | null;
|
|
92
|
+
static _onlyMarkPending: ((el: Computed<any>) => boolean) | null;
|
|
93
|
+
static _collectMarkSources: ((el: Computed<any>, into: OptimisticNode[]) => void) | null;
|
|
94
|
+
static _wireExternalSource: ((self: Computed<any>) => void) | null;
|
|
95
|
+
static _externalUntrack: (<T>(fn: () => T) => T) | null;
|
|
96
|
+
static _syncCompanions: (<T>(el: Signal<T> | Computed<T>, value: T) => void) | null;
|
|
97
|
+
static _updatePendingSignal: ((el: OptimisticNode) => void) | null;
|
|
98
|
+
static _updateChildCompanions: ((el: Computed<any>) => void) | null;
|
|
99
|
+
static _snapCompanions: ((el: OptimisticNode) => void) | null;
|
|
100
|
+
static _latestRead: (<T>(el: Signal<T> | Computed<T>) => T) | null;
|
|
101
|
+
static _pendingCheck: ((el: OptimisticNode, c: Computed<any> | null, owner: OptimisticNode, firewall: Computed<any> | null) => void) | null;
|
|
102
|
+
static _recordFresh: ((el: OptimisticNode, value: any) => void) | null;
|
|
103
|
+
static _applyReask: ((el: Computed<any>, hadReask: boolean) => boolean) | null;
|
|
104
|
+
static _repollVerdicts: ((el: Computed<any>) => void) | null;
|
|
105
|
+
static _witnessAffects: ((node: OptimisticNode) => void) | null;
|
|
106
|
+
static _optimisticWrite: (<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)) => T) | null;
|
|
107
|
+
static _resolveOptimistic: ((nodes: OptimisticNode[]) => void) | null;
|
|
108
|
+
static _stashOptimistic: ((stashedTransition: Transition) => void) | null;
|
|
109
|
+
static _transitionBlocked: ((transition: Transition) => boolean) | null;
|
|
110
|
+
static _cleanupLanes: ((completingTransition: Transition | null) => void) | null;
|
|
111
|
+
static _runLaneEffects: ((type: number) => void) | null;
|
|
112
|
+
static _readStashed: ((el: Signal<any>) => boolean) | null;
|
|
113
|
+
static _gatedRead: ((el: Signal<any>, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
|
|
114
|
+
static _laneSuspends: ((owner: OptimisticNode) => boolean) | null;
|
|
115
|
+
static _laneReadsCommitted: ((el: OptimisticNode, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
|
|
116
|
+
static _recomputeLane: ((el: Computed<any>, own: boolean) => OptimisticLane | null) | null;
|
|
117
|
+
static _laneAsyncPending: ((el: Computed<any>) => void) | null;
|
|
118
|
+
static _laneAsyncSettled: ((el: Computed<any>) => void) | null;
|
|
119
|
+
static _trackOptimisticStore: ((store: any) => void) | null;
|
|
91
120
|
flush(): void;
|
|
92
121
|
notify(node: Computed<any>, mask: number, flags: number, error?: any): boolean;
|
|
93
122
|
initTransition(transition?: Transition | null): void;
|
|
@@ -96,7 +125,6 @@ export declare function queuePendingNode(node: Signal<any>): void;
|
|
|
96
125
|
export declare function armReaskClear(): void;
|
|
97
126
|
export declare function insertSubs(node: Signal<any> | Computed<any>, optimistic?: boolean): void;
|
|
98
127
|
export declare function finalizePureQueue(completingTransition?: Transition | null, incomplete?: boolean): void;
|
|
99
|
-
export declare function trackOptimisticStore(store: any): void;
|
|
100
128
|
/**
|
|
101
129
|
* Count of live `affects()` registrations across the system (including
|
|
102
130
|
* store-scope inherited marks). Gates the read-path mark check in `read()` so
|
|
@@ -104,36 +132,13 @@ export declare function trackOptimisticStore(store: any): void;
|
|
|
104
132
|
*/
|
|
105
133
|
export declare let activeAffectsMarks: number;
|
|
106
134
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* already-materialized `false` flips reactively.
|
|
135
|
+
* Counter mutation seam for the mark engine in affects.ts: an imported `let`
|
|
136
|
+
* binding is read-only, and the read-path gate above must stay a plain module
|
|
137
|
+
* variable so `read()` pays one integer compare, not a function call.
|
|
111
138
|
*
|
|
112
139
|
* @internal
|
|
113
140
|
*/
|
|
114
|
-
export declare function
|
|
115
|
-
/**
|
|
116
|
-
* Registers one `affects()` mark on a node: counts it, records the
|
|
117
|
-
* registration with the current transaction (after initTransition the queue's
|
|
118
|
-
* array aliases the active transition's, mirroring `_optimisticNodes`), and
|
|
119
|
-
* propagates STATUS_PENDING downstream on the status rails so everything
|
|
120
|
-
* DERIVED from the marked data reads pending too. Propagation runs on every
|
|
121
|
-
* registration (not just the first): subscribers gained since an earlier
|
|
122
|
-
* overlapping registration get covered, and dedup stops re-descent early.
|
|
123
|
-
*
|
|
124
|
-
* @internal
|
|
125
|
-
*/
|
|
126
|
-
export declare function registerAffectsMark(node: OptimisticNode): void;
|
|
127
|
-
/**
|
|
128
|
-
* Releases one registration. When the node's last mark drops, settles the
|
|
129
|
-
* mark's sentinel out of every downstream `_pendingSources` (waking blocked
|
|
130
|
-
* nodes and re-deriving verdicts along the walk). Companion writes go through
|
|
131
|
-
* the settlement snap (committed, not transition-scoped) so releasing a mark
|
|
132
|
-
* can't open a fresh override window that would itself need settlement.
|
|
133
|
-
*
|
|
134
|
-
* @internal
|
|
135
|
-
*/
|
|
136
|
-
export declare function releaseAffectsMark(node: OptimisticNode): void;
|
|
141
|
+
export declare function shiftAffectsMarks(delta: 1 | -1): void;
|
|
137
142
|
export declare const globalQueue: GlobalQueue;
|
|
138
143
|
/**
|
|
139
144
|
* Synchronously processes the pending reactive queue, or runs `fn` in a synchronous
|
|
@@ -63,4 +63,3 @@ export declare function createProjection<T extends object = {}>(fn: (draft: T) =
|
|
|
63
63
|
*/
|
|
64
64
|
export declare function runProjectionComputed<T extends object>(wrappedStore: Store<T>, fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, key: string | ((item: NonNullable<any>) => any), wrapCommit?: (write: () => void) => void, onDraftWrite?: () => void): Computed<void | T>;
|
|
65
65
|
export declare function createWriteTraps(isActive?: () => boolean, onDraftWrite?: () => void): ProxyHandler<any>;
|
|
66
|
-
export declare const writeTraps: ProxyHandler<any>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type Store } from "./store/store.cjs";
|
|
2
1
|
import type { Accessor } from "./signals.cjs";
|
|
2
|
+
import { type Store } from "./store/store.cjs";
|
|
3
3
|
/**
|
|
4
4
|
* Declares that in-flight work will change the targeted data: the named
|
|
5
5
|
* slot(s) — and everything DERIVED from them — read as pending
|
|
@@ -20,7 +20,7 @@ export declare class RevealController {
|
|
|
20
20
|
_evaluating: boolean;
|
|
21
21
|
constructor(order: OrderAccessor, collapsed: BoolAccessor);
|
|
22
22
|
_forEachOwnedSlot(fn: (slot: RevealSlot) => boolean | void): boolean;
|
|
23
|
-
|
|
23
|
+
_isReady(): boolean;
|
|
24
24
|
/**
|
|
25
25
|
* "Minimally ready" = this group has something visible to show under its own policy.
|
|
26
26
|
* Used by an enclosing `together` group to decide when it can release.
|
|
@@ -28,10 +28,10 @@ export declare class RevealController {
|
|
|
28
28
|
* - `sequential`: the first owned slot is minimally ready (frontier can advance).
|
|
29
29
|
* - `natural`: any owned slot is minimally ready.
|
|
30
30
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
_isMinimallyReady(): boolean;
|
|
32
|
+
_register(slot: RevealSlot): void;
|
|
33
|
+
_unregister(slot: RevealSlot): void;
|
|
34
|
+
_evaluate(disabledOverride?: boolean, collapsedOverride?: boolean): void;
|
|
35
35
|
}
|
|
36
36
|
export declare class CollectionQueue extends Queue {
|
|
37
37
|
_collectionType: number;
|
|
@@ -48,7 +48,7 @@ export declare class CollectionQueue extends Queue {
|
|
|
48
48
|
constructor(type: number);
|
|
49
49
|
run(type: number): void;
|
|
50
50
|
notify(node: Effect<any>, type: number, flags: number, error?: any): boolean;
|
|
51
|
-
|
|
51
|
+
_checkSources(): void;
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
54
|
* Lower-level primitive that backs the `<Loading>` flow control. Catches
|
|
@@ -1,44 +1,10 @@
|
|
|
1
1
|
import { type OptimisticLane } from "./lanes.cjs";
|
|
2
|
-
import type { Computed,
|
|
2
|
+
import type { Computed, Link } from "./types.cjs";
|
|
3
|
+
export declare function addPendingSource(el: Computed<any>, source: Computed<any>): boolean;
|
|
4
|
+
export declare function setPendingError(el: Computed<any>, source?: Computed<any>, error?: any): void;
|
|
5
|
+
export declare function forEachDependent(el: Computed<any>, fn: (node: Computed<any>, link: Link) => void): void;
|
|
3
6
|
export declare function settlePendingSource(el: Computed<any>, source?: Computed<any>, snap?: boolean): void;
|
|
4
7
|
export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
|
|
5
8
|
export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void): T;
|
|
6
9
|
export declare function clearStatus(el: Computed<any>, clearUninitialized?: boolean): void;
|
|
7
10
|
export declare function notifyStatus(el: Computed<any>, status: number, error: any, blockStatus?: boolean, lane?: OptimisticLane): void;
|
|
8
|
-
/**
|
|
9
|
-
* The pending-source identity of a live `affects()` mark on `node` (lazy,
|
|
10
|
-
* one per node, shared by overlapping registrations via the refcount).
|
|
11
|
-
*
|
|
12
|
-
* A mark rides the SAME status rails as real in-flight async — downstream
|
|
13
|
-
* subscribers hold the sentinel in `_pendingSources` — but under its own
|
|
14
|
-
* identity so the two channels can't clear each other:
|
|
15
|
-
* - `_reask` is permanently `false`: a mark is by definition a declared
|
|
16
|
-
* value change, so `quietPending` never silences a window it participates
|
|
17
|
-
* in — even when the mark rides over an otherwise-quiet `refresh()`
|
|
18
|
-
* re-ask of the same node (the whole point of declaring one).
|
|
19
|
-
* - A landing on the marked node settles only the node's OWN source entry;
|
|
20
|
-
* the sentinel entry survives until the mark's transaction releases it.
|
|
21
|
-
* - The sentinel itself never carries `STATUS_PENDING`, so
|
|
22
|
-
* `transitionComplete` never counts a mark as a blocker of its own
|
|
23
|
-
* transaction (release happens AT settle — self-blocking would deadlock),
|
|
24
|
-
* and reads of the marked node never throw (marks are value-transparent
|
|
25
|
-
* at the source; pendingness is what propagates).
|
|
26
|
-
*/
|
|
27
|
-
export declare function getAffectsSentinel(node: Signal<any> | Computed<any>): Computed<any>;
|
|
28
|
-
/**
|
|
29
|
-
* Push a live mark's pendingness downstream from the marked node through the
|
|
30
|
-
* normal status rails. Runs on every registration (dedup in `notifyStatus`
|
|
31
|
-
* stops re-descent at already-covered subscribers). Subscribers that
|
|
32
|
-
* recompute mid-window shed this via `clearStatus` and re-acquire it through
|
|
33
|
-
* the read path (`applyAffectsReads`) — the same shape as real async, where
|
|
34
|
-
* the re-throw on read re-establishes the source.
|
|
35
|
-
*/
|
|
36
|
-
export declare function propagateAffectsMark(node: Signal<any> | Computed<any>): void;
|
|
37
|
-
/**
|
|
38
|
-
* Re-establish mark pendingness on a computed that read marked sources
|
|
39
|
-
* during its recompute (`clearStatus` at the top of the commit path wiped
|
|
40
|
-
* any sentinel entries it held). Called by `recompute` after the commit —
|
|
41
|
-
* not before, because setting `_error` earlier would make the commit path
|
|
42
|
-
* treat the node as errored and skip the value write.
|
|
43
|
-
*/
|
|
44
|
-
export declare function applyAffectsReads(el: Computed<any>, sources: (Signal<any> | Computed<any>)[]): void;
|
|
@@ -5,6 +5,12 @@ export declare const PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE = "[PRIMITIVE_IN_FORBI
|
|
|
5
5
|
export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE: string;
|
|
6
6
|
export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE: string;
|
|
7
7
|
export declare let tracking: boolean;
|
|
8
|
+
/** @internal verdict-module glue */
|
|
9
|
+
export declare function setPendingCheckActive(v: boolean): void;
|
|
10
|
+
/** @internal verdict-module glue */
|
|
11
|
+
export declare function setLatestReadActive(v: boolean): void;
|
|
12
|
+
/** @internal verdict-module glue */
|
|
13
|
+
export declare function setContextInternal(v: Owner | null): void;
|
|
8
14
|
export declare let stale: boolean;
|
|
9
15
|
export declare let pendingCheckActive: boolean;
|
|
10
16
|
export declare let latestReadActive: boolean;
|
|
@@ -60,6 +66,12 @@ export declare function setStrictRead(v: string | false): string | false;
|
|
|
60
66
|
* ```
|
|
61
67
|
*/
|
|
62
68
|
export declare function untrack<T>(fn: () => T, strictReadLabel?: string | false): T;
|
|
69
|
+
/**
|
|
70
|
+
* Bring a computed to a readable state: lazy/disposed nodes are (re)computed;
|
|
71
|
+
* an isPending() probe (`refresh`) additionally pulls the node fully up to
|
|
72
|
+
* date so its status flags reflect the current graph.
|
|
73
|
+
*/
|
|
74
|
+
export declare function prepareComputed(comp: Computed<unknown>, refresh: boolean): void;
|
|
63
75
|
export declare function read<T>(el: Signal<T> | Computed<T>): T;
|
|
64
76
|
export declare function setSignal<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)): T;
|
|
65
77
|
/**
|
|
@@ -97,85 +109,7 @@ export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
|
|
|
97
109
|
* ```
|
|
98
110
|
*/
|
|
99
111
|
export declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
|
|
100
|
-
/**
|
|
101
|
-
* Adds a node to the active isPending() probe without reading it. The store's
|
|
102
|
-
* untracked-probe fallback (`witnessAffectsMark`) calls this with `affects()`
|
|
103
|
-
* carrier nodes: an untracked read through a marked record may touch no real
|
|
104
|
-
* signal node at all, so the probe collects the mark's carrier directly.
|
|
105
|
-
*
|
|
106
|
-
* @internal
|
|
107
|
-
*/
|
|
108
|
-
export declare function witnessAffects(node: Signal<any> | Computed<any>): void;
|
|
109
|
-
/**
|
|
110
|
-
* Keep the lazily-created isPending()/latest() companion nodes in sync with a
|
|
111
|
-
* new value. Every path that produces a value for `el` — direct set, async
|
|
112
|
-
* resolution, transition-held sync recompute — must route through here so a
|
|
113
|
-
* new write path can't silently skip the companions (#2831).
|
|
114
|
-
*/
|
|
115
|
-
export declare function syncCompanions<T>(el: Signal<T> | Computed<T>, value: T): void;
|
|
116
|
-
/**
|
|
117
|
-
* Update _pendingSignal when pending state changes. When the override clears
|
|
118
|
-
* (pending -> not pending), merge the sub-lane into the source's lane so
|
|
119
|
-
* isPending effects are blocked until the full scope resolves.
|
|
120
|
-
*/
|
|
121
|
-
export declare function updatePendingSignal(el: Signal<any> | Computed<any>): void;
|
|
122
|
-
/**
|
|
123
|
-
* A firewall's status change re-derives the verdicts of its probed leaves:
|
|
124
|
-
* leaf companions consult the firewall (broad inheritance), so async
|
|
125
|
-
* starting/settling on the firewall must poke them or they keep a stale
|
|
126
|
-
* verdict forever (V4 stuck-companion class, #2838).
|
|
127
|
-
*/
|
|
128
|
-
export declare function updateChildCompanions(el: Computed<any>): void;
|
|
129
|
-
/**
|
|
130
|
-
* Settlement checkpoint (#2838): re-derive a node's companions directly from
|
|
131
|
-
* its committed state. Called when the transition machinery for the node is
|
|
132
|
-
* done with it — a pending commit or an optimistic revert. Verdicts are
|
|
133
|
-
* written committed (not through setSignal) because a transition-scoped
|
|
134
|
-
* override window opened here would itself need a settlement, re-scheduling
|
|
135
|
-
* forever while async is still in flight. This is what keeps companions
|
|
136
|
-
* coherent past transition completion: a verdict is a property of the data
|
|
137
|
-
* (A19), so it must survive the transition that happened to produce it.
|
|
138
|
-
*/
|
|
139
|
-
export declare function snapCompanionsToState(owner: Signal<any> | Computed<any>): void;
|
|
140
112
|
export declare function staleValues<T>(fn: () => T, set?: boolean): T;
|
|
141
|
-
/**
|
|
142
|
-
* Reads reactive expressions while bypassing any pending async overlay — i.e.
|
|
143
|
-
* always returns the most-recently-committed value, even when newer reads
|
|
144
|
-
* inside `fn` are still in flight.
|
|
145
|
-
*
|
|
146
|
-
* Useful inside a `<Loading>` boundary's children when you want to keep
|
|
147
|
-
* showing the previous resolved data instead of the fallback while the next
|
|
148
|
-
* value loads.
|
|
149
|
-
*
|
|
150
|
-
* @example
|
|
151
|
-
* ```tsx
|
|
152
|
-
* <Loading fallback={<Skeleton />}>
|
|
153
|
-
* {/* During a transition, render the previous user instead of skeleton: *\/}
|
|
154
|
-
* <UserCard user={latest(() => user())} />
|
|
155
|
-
* </Loading>
|
|
156
|
-
* ```
|
|
157
|
-
*/
|
|
158
|
-
export declare function latest<T>(fn: () => T): T;
|
|
159
|
-
/**
|
|
160
|
-
* Returns `true` if any reactive read inside `fn` is showing a stale value
|
|
161
|
-
* while newer async work is pending. Does not subscribe — pair with a tracked
|
|
162
|
-
* memo if you want to react to pending status changes.
|
|
163
|
-
*
|
|
164
|
-
* Useful for showing inline transition indicators alongside the previous
|
|
165
|
-
* value (rather than swapping to a `<Loading>` fallback).
|
|
166
|
-
* Because `fn` is read normally, `isPending` participates in Loading/SSR
|
|
167
|
-
* readiness the same way the read itself would.
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```tsx
|
|
171
|
-
* const pending = createMemo(() => isPending(() => user()));
|
|
172
|
-
*
|
|
173
|
-
* <button disabled={pending()}>{pending() ? "Saving…" : "Save"}</button>
|
|
174
|
-
*
|
|
175
|
-
* <button disabled={isPending(() => user())}>Save</button>
|
|
176
|
-
* ```
|
|
177
|
-
*/
|
|
178
|
-
export declare function isPending(fn: () => any): boolean;
|
|
179
113
|
/**
|
|
180
114
|
* Invalidates one reactive source, forcing it to re-execute even if its inputs
|
|
181
115
|
* haven't changed.
|
|
@@ -11,35 +11,5 @@ export declare let externalSourceConfig: {
|
|
|
11
11
|
factory: ExternalSourceFactory;
|
|
12
12
|
untrack: <T>(fn: () => T) => T;
|
|
13
13
|
} | null;
|
|
14
|
-
/**
|
|
15
|
-
* Registers a factory that bridges external reactive systems (e.g. MobX, Vue refs)
|
|
16
|
-
* into Solid's tracking graph. Every computation will be wrapped so that the
|
|
17
|
-
* external library can track its own dependencies alongside Solid's.
|
|
18
|
-
*
|
|
19
|
-
* Multiple calls pipe together: each new factory wraps the previous one.
|
|
20
|
-
*
|
|
21
|
-
* @param config.factory receives `(fn, trigger)` — wrap fn execution in external tracking,
|
|
22
|
-
* call trigger when external deps change. Return `{ track, dispose }`.
|
|
23
|
-
* @param config.untrack optional wrapper for `untrack` — disables external tracking too.
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```ts
|
|
27
|
-
* // Bridge an external "subscribe / notify" library into Solid's graph.
|
|
28
|
-
* // `factory` wraps every Solid compute so the external library can attach
|
|
29
|
-
* // its own dependency tracker; `trigger` re-runs the compute on external
|
|
30
|
-
* // change. `untrack` mirrors Solid's `untrack()` into the external library
|
|
31
|
-
* // so that reads inside `untrack(...)` don't get tracked twice.
|
|
32
|
-
* enableExternalSource({
|
|
33
|
-
* factory: (compute, trigger) => {
|
|
34
|
-
* const sub = externalLib.subscribe(trigger);
|
|
35
|
-
* return {
|
|
36
|
-
* track: prev => externalLib.run(() => compute(prev)),
|
|
37
|
-
* dispose: () => sub.unsubscribe()
|
|
38
|
-
* };
|
|
39
|
-
* },
|
|
40
|
-
* untrack: fn => externalLib.untracked(fn)
|
|
41
|
-
* });
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
14
|
export declare function enableExternalSource(config: ExternalSourceConfig): void;
|
|
45
15
|
export declare function _resetExternalSourceConfig(): void;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { Computed } from "./types.cjs";
|
|
2
|
+
/** The queue a node belongs to, picked from its own zombie flag. */
|
|
3
|
+
export declare function queueFor(n: Computed<any>): Heap;
|
|
4
|
+
/**
|
|
5
|
+
* Schedule one subscriber to re-run on the next flush: tracked effects bypass
|
|
6
|
+
* the heap and go directly to their effect queue; everything else is inserted
|
|
7
|
+
* into its own (zombie-flag-routed) heap with the `_min` cursor pulled down.
|
|
8
|
+
*/
|
|
9
|
+
export declare function enqueueSub(node: Computed<any>): void;
|
|
2
10
|
export interface Heap {
|
|
3
11
|
_heap: (Computed<unknown> | undefined)[];
|
|
4
12
|
_marked: boolean;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
export { ContextNotFoundError, NoOwnerError, NotReadyError } from "./error.cjs";
|
|
2
|
-
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed,
|
|
2
|
+
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed, refresh, staleValues, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots } from "./core.cjs";
|
|
3
3
|
export { enableExternalSource, _resetExternalSourceConfig, type ExternalSourceFactory, type ExternalSource, type ExternalSourceConfig } from "./external.cjs";
|
|
4
4
|
export { createOwner, createRoot, dispose, getNextChildId, getObserver, getOwner, isDisposed, cleanup, peekNextChildId } from "./owner.cjs";
|
|
5
5
|
export { createContext, getContext, setContext, type Context, type ContextRecord } from "./context.cjs";
|
|
6
6
|
export { handleAsync } from "./async.cjs";
|
|
7
|
+
export { isPending, latest } from "./verdict.cjs";
|
|
7
8
|
export type { Computed, Disposable, FirewallSignal, Link, Owner, Root, Signal, NodeOptions } from "./types.cjs";
|
|
8
9
|
export { effect, trackedEffect, type Effect, type TrackedEffect } from "./effect.cjs";
|
|
9
10
|
export { action } from "./action.cjs";
|
|
10
|
-
export { flush, Queue, GlobalQueue,
|
|
11
|
+
export { flush, Queue, GlobalQueue, enforceLoadingBoundary, resetErrorHalt, type IQueue, type QueueCallback } from "./scheduler.cjs";
|
|
11
12
|
export { DEV, type Dev, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type Diagnostics, type DiagnosticSeverity } from "./dev.cjs";
|
|
12
13
|
export * from "./constants.cjs";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installs the engine's hooks. Idempotent; called by every module that can
|
|
3
|
+
* create optimistic state (verdict.ts at module top level, createOptimistic
|
|
4
|
+
* and createOptimisticStore at first call) BEFORE any optimistic node exists.
|
|
5
|
+
*/
|
|
6
|
+
export declare function installOptimisticEngine(): void;
|
|
@@ -9,6 +9,14 @@ export declare function disposeChildren(node: Owner, self?: boolean, zombie?: bo
|
|
|
9
9
|
* @internal
|
|
10
10
|
*/
|
|
11
11
|
export declare function getNextChildId(owner: Owner): string;
|
|
12
|
+
/**
|
|
13
|
+
* The id a freshly-created node inherits: an explicit `options.id` wins;
|
|
14
|
+
* transparent nodes share their parent's id; otherwise the parent's next
|
|
15
|
+
* child id is consumed (or `undefined` outside an id-carrying tree).
|
|
16
|
+
*/
|
|
17
|
+
export declare function inheritId(options: {
|
|
18
|
+
id?: string;
|
|
19
|
+
} | undefined, transparent: boolean, parent: Owner | null | undefined): string | undefined;
|
|
12
20
|
/**
|
|
13
21
|
* Returns the *next* child id for `owner` without consuming it. Used by
|
|
14
22
|
* hydration plumbing to peek at the id a future child will receive.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Heap } from "./heap.cjs";
|
|
2
|
-
import { activeLanes, assignOrMergeLane, findLane } from "./lanes.cjs";
|
|
2
|
+
import { activeLanes, assignOrMergeLane, findLane, type OptimisticLane } from "./lanes.cjs";
|
|
3
3
|
import type { Computed, Signal } from "./types.cjs";
|
|
4
4
|
export { activeLanes, assignOrMergeLane, findLane };
|
|
5
5
|
export { getOrCreateLane, hasActiveOverride, mergeLanes, resolveLane } from "./lanes.cjs";
|
|
@@ -20,7 +20,6 @@ export declare function resetUnhandledAsync(): void;
|
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
22
|
export declare function enforceLoadingBoundary(enabled: boolean): void;
|
|
23
|
-
export declare function shouldReadStashedOptimisticValue(node: Signal<any>): boolean;
|
|
24
23
|
export declare function setProjectionWriteActive(value: boolean): void;
|
|
25
24
|
export declare function setTrackedQueueCallback(value: boolean): void;
|
|
26
25
|
export type QueueCallback = (type: number) => void;
|
|
@@ -47,7 +46,7 @@ export declare function schedule(): void;
|
|
|
47
46
|
* every boundary — app state is undefined at that point, so scheduling stops
|
|
48
47
|
* entirely rather than limping along with a half-applied update.
|
|
49
48
|
*/
|
|
50
|
-
export declare function haltReactivity(): void;
|
|
49
|
+
export declare function haltReactivity(cause?: unknown): void;
|
|
51
50
|
/** @internal Test/dev-reload hook. Revives scheduling after a halt. */
|
|
52
51
|
export declare function resetErrorHalt(): void;
|
|
53
52
|
export interface IQueue {
|
|
@@ -84,10 +83,40 @@ export declare class GlobalQueue extends Queue {
|
|
|
84
83
|
static _update: (el: Computed<unknown>) => void;
|
|
85
84
|
static _dispose: (el: Computed<unknown>, self: boolean, zombie: boolean) => void;
|
|
86
85
|
static _runEffect: (el: Computed<unknown>) => void;
|
|
87
|
-
static
|
|
86
|
+
static _clearOptimisticStores: ((stores: Set<any>) => void) | null;
|
|
88
87
|
static _releaseAffectsScope: ((node: OptimisticNode) => void) | null;
|
|
89
|
-
static
|
|
90
|
-
static
|
|
88
|
+
static _applyAffectsReads: ((el: Computed<any>, sources: (Signal<any> | Computed<any>)[]) => void) | null;
|
|
89
|
+
static _releaseAffectsMarks: ((nodes: OptimisticNode[]) => void) | null;
|
|
90
|
+
static _markAffects: ((node: OptimisticNode) => void) | null;
|
|
91
|
+
static _releaseAffectsMark: ((node: OptimisticNode) => void) | null;
|
|
92
|
+
static _onlyMarkPending: ((el: Computed<any>) => boolean) | null;
|
|
93
|
+
static _collectMarkSources: ((el: Computed<any>, into: OptimisticNode[]) => void) | null;
|
|
94
|
+
static _wireExternalSource: ((self: Computed<any>) => void) | null;
|
|
95
|
+
static _externalUntrack: (<T>(fn: () => T) => T) | null;
|
|
96
|
+
static _syncCompanions: (<T>(el: Signal<T> | Computed<T>, value: T) => void) | null;
|
|
97
|
+
static _updatePendingSignal: ((el: OptimisticNode) => void) | null;
|
|
98
|
+
static _updateChildCompanions: ((el: Computed<any>) => void) | null;
|
|
99
|
+
static _snapCompanions: ((el: OptimisticNode) => void) | null;
|
|
100
|
+
static _latestRead: (<T>(el: Signal<T> | Computed<T>) => T) | null;
|
|
101
|
+
static _pendingCheck: ((el: OptimisticNode, c: Computed<any> | null, owner: OptimisticNode, firewall: Computed<any> | null) => void) | null;
|
|
102
|
+
static _recordFresh: ((el: OptimisticNode, value: any) => void) | null;
|
|
103
|
+
static _applyReask: ((el: Computed<any>, hadReask: boolean) => boolean) | null;
|
|
104
|
+
static _repollVerdicts: ((el: Computed<any>) => void) | null;
|
|
105
|
+
static _witnessAffects: ((node: OptimisticNode) => void) | null;
|
|
106
|
+
static _optimisticWrite: (<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)) => T) | null;
|
|
107
|
+
static _resolveOptimistic: ((nodes: OptimisticNode[]) => void) | null;
|
|
108
|
+
static _stashOptimistic: ((stashedTransition: Transition) => void) | null;
|
|
109
|
+
static _transitionBlocked: ((transition: Transition) => boolean) | null;
|
|
110
|
+
static _cleanupLanes: ((completingTransition: Transition | null) => void) | null;
|
|
111
|
+
static _runLaneEffects: ((type: number) => void) | null;
|
|
112
|
+
static _readStashed: ((el: Signal<any>) => boolean) | null;
|
|
113
|
+
static _gatedRead: ((el: Signal<any>, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
|
|
114
|
+
static _laneSuspends: ((owner: OptimisticNode) => boolean) | null;
|
|
115
|
+
static _laneReadsCommitted: ((el: OptimisticNode, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
|
|
116
|
+
static _recomputeLane: ((el: Computed<any>, own: boolean) => OptimisticLane | null) | null;
|
|
117
|
+
static _laneAsyncPending: ((el: Computed<any>) => void) | null;
|
|
118
|
+
static _laneAsyncSettled: ((el: Computed<any>) => void) | null;
|
|
119
|
+
static _trackOptimisticStore: ((store: any) => void) | null;
|
|
91
120
|
flush(): void;
|
|
92
121
|
notify(node: Computed<any>, mask: number, flags: number, error?: any): boolean;
|
|
93
122
|
initTransition(transition?: Transition | null): void;
|
|
@@ -96,7 +125,6 @@ export declare function queuePendingNode(node: Signal<any>): void;
|
|
|
96
125
|
export declare function armReaskClear(): void;
|
|
97
126
|
export declare function insertSubs(node: Signal<any> | Computed<any>, optimistic?: boolean): void;
|
|
98
127
|
export declare function finalizePureQueue(completingTransition?: Transition | null, incomplete?: boolean): void;
|
|
99
|
-
export declare function trackOptimisticStore(store: any): void;
|
|
100
128
|
/**
|
|
101
129
|
* Count of live `affects()` registrations across the system (including
|
|
102
130
|
* store-scope inherited marks). Gates the read-path mark check in `read()` so
|
|
@@ -104,36 +132,13 @@ export declare function trackOptimisticStore(store: any): void;
|
|
|
104
132
|
*/
|
|
105
133
|
export declare let activeAffectsMarks: number;
|
|
106
134
|
/**
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* already-materialized `false` flips reactively.
|
|
135
|
+
* Counter mutation seam for the mark engine in affects.ts: an imported `let`
|
|
136
|
+
* binding is read-only, and the read-path gate above must stay a plain module
|
|
137
|
+
* variable so `read()` pays one integer compare, not a function call.
|
|
111
138
|
*
|
|
112
139
|
* @internal
|
|
113
140
|
*/
|
|
114
|
-
export declare function
|
|
115
|
-
/**
|
|
116
|
-
* Registers one `affects()` mark on a node: counts it, records the
|
|
117
|
-
* registration with the current transaction (after initTransition the queue's
|
|
118
|
-
* array aliases the active transition's, mirroring `_optimisticNodes`), and
|
|
119
|
-
* propagates STATUS_PENDING downstream on the status rails so everything
|
|
120
|
-
* DERIVED from the marked data reads pending too. Propagation runs on every
|
|
121
|
-
* registration (not just the first): subscribers gained since an earlier
|
|
122
|
-
* overlapping registration get covered, and dedup stops re-descent early.
|
|
123
|
-
*
|
|
124
|
-
* @internal
|
|
125
|
-
*/
|
|
126
|
-
export declare function registerAffectsMark(node: OptimisticNode): void;
|
|
127
|
-
/**
|
|
128
|
-
* Releases one registration. When the node's last mark drops, settles the
|
|
129
|
-
* mark's sentinel out of every downstream `_pendingSources` (waking blocked
|
|
130
|
-
* nodes and re-deriving verdicts along the walk). Companion writes go through
|
|
131
|
-
* the settlement snap (committed, not transition-scoped) so releasing a mark
|
|
132
|
-
* can't open a fresh override window that would itself need settlement.
|
|
133
|
-
*
|
|
134
|
-
* @internal
|
|
135
|
-
*/
|
|
136
|
-
export declare function releaseAffectsMark(node: OptimisticNode): void;
|
|
141
|
+
export declare function shiftAffectsMarks(delta: 1 | -1): void;
|
|
137
142
|
export declare const globalQueue: GlobalQueue;
|
|
138
143
|
/**
|
|
139
144
|
* Synchronously processes the pending reactive queue, or runs `fn` in a synchronous
|
|
@@ -63,4 +63,3 @@ export declare function createProjection<T extends object = {}>(fn: (draft: T) =
|
|
|
63
63
|
*/
|
|
64
64
|
export declare function runProjectionComputed<T extends object>(wrappedStore: Store<T>, fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, key: string | ((item: NonNullable<any>) => any), wrapCommit?: (write: () => void) => void, onDraftWrite?: () => void): Computed<void | T>;
|
|
65
65
|
export declare function createWriteTraps(isActive?: () => boolean, onDraftWrite?: () => void): ProxyHandler<any>;
|
|
66
|
-
export declare const writeTraps: ProxyHandler<any>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/signals",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.19",
|
|
4
4
|
"description": "Solid's reactive primitives: signals, memos, effects, stores, and async-aware computations.",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
16
|
"main": "./dist/node.cjs",
|
|
17
|
-
"module": "./dist/prod.js",
|
|
17
|
+
"module": "./dist/prod/index.js",
|
|
18
|
+
"unpkg": "./dist/prod/index.js",
|
|
19
|
+
"jsdelivr": "./dist/prod/index.js",
|
|
18
20
|
"types": "./dist/types/index.d.ts",
|
|
19
21
|
"type": "module",
|
|
20
22
|
"sideEffects": false,
|
|
@@ -28,7 +30,7 @@
|
|
|
28
30
|
"types": "./dist/types/index.d.ts",
|
|
29
31
|
"test": "./dist/dev.js",
|
|
30
32
|
"development": "./dist/dev.js",
|
|
31
|
-
"default": "./dist/prod.js"
|
|
33
|
+
"default": "./dist/prod/index.js"
|
|
32
34
|
},
|
|
33
35
|
"require": {
|
|
34
36
|
"types": "./dist/types-cjs/index.d.cts",
|
|
@@ -40,12 +42,12 @@
|
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@ianvs/prettier-plugin-sort-imports": "^4.1.1",
|
|
42
44
|
"@rollup/plugin-replace": "^6.0.3",
|
|
43
|
-
"@rollup/plugin-terser": "^0.4.4",
|
|
44
45
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
45
46
|
"@types/node": "^25.0.8",
|
|
46
47
|
"rimraf": "^5.0.1",
|
|
47
48
|
"rollup": "^4.53.4",
|
|
48
49
|
"rollup-plugin-prettier": "^4.1.2",
|
|
50
|
+
"terser": "^5.49.0",
|
|
49
51
|
"tslib": "^2.8.1",
|
|
50
52
|
"typescript": "^6.0.3",
|
|
51
53
|
"vite": "^7.0.0",
|
|
@@ -53,8 +55,8 @@
|
|
|
53
55
|
},
|
|
54
56
|
"scripts": {
|
|
55
57
|
"build": "npm-run-all -nl build:* && pnpm types",
|
|
56
|
-
"build:clean": "rimraf dist/dev.js dist/prod.js dist/node.cjs",
|
|
57
|
-
"build:js": "rollup -c",
|
|
58
|
+
"build:clean": "rimraf dist/dev dist/prod dist/node dist/dev.js dist/prod.js dist/node.cjs",
|
|
59
|
+
"build:js": "rollup -c && node ./scripts/mangle-props.mjs dist/prod dist/node.cjs && node ./scripts/check-pure.mjs dist/prod",
|
|
58
60
|
"types": "tsc -p tsconfig.build.json && node ../../scripts/sync-dual-types.mjs ./dist/types ./dist/types-cjs",
|
|
59
61
|
"test": "vitest run",
|
|
60
62
|
"test:watch": "vitest watch tests",
|