@solidjs/signals 2.0.0-beta.15 → 2.0.0-beta.16
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 +700 -385
- package/dist/node.cjs +1865 -1592
- package/dist/prod.js +1496 -1232
- package/dist/types/boundaries.d.ts +3 -3
- package/dist/types/core/async.d.ts +1 -0
- package/dist/types/core/core.d.ts +25 -1
- package/dist/types/core/dev.d.ts +10 -2
- package/dist/types/core/effect.d.ts +1 -3
- package/dist/types/core/graph.d.ts +1 -1
- package/dist/types/core/index.d.ts +2 -2
- package/dist/types/core/invariants.d.ts +49 -0
- package/dist/types/core/scheduler.d.ts +8 -0
- package/dist/types/core/types.d.ts +19 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/signals.d.ts +39 -2
- package/dist/types/store/projection.d.ts +2 -2
- package/dist/types/store/store.d.ts +28 -1
- package/dist/types-cjs/boundaries.d.cts +3 -3
- package/dist/types-cjs/core/async.d.cts +1 -0
- package/dist/types-cjs/core/core.d.cts +25 -1
- package/dist/types-cjs/core/dev.d.cts +10 -2
- package/dist/types-cjs/core/effect.d.cts +1 -3
- package/dist/types-cjs/core/graph.d.cts +1 -1
- package/dist/types-cjs/core/index.d.cts +2 -2
- package/dist/types-cjs/core/invariants.d.cts +49 -0
- package/dist/types-cjs/core/scheduler.d.cts +8 -0
- package/dist/types-cjs/core/types.d.cts +19 -0
- package/dist/types-cjs/index.d.cts +1 -1
- package/dist/types-cjs/signals.d.cts +39 -2
- package/dist/types-cjs/store/projection.d.cts +2 -2
- package/dist/types-cjs/store/store.d.cts +28 -1
- package/package.json +1 -1
- package/dist/types/src/boundaries.d.ts +0 -173
- package/dist/types/src/core/action.d.ts +0 -35
- package/dist/types/src/core/async.d.ts +0 -6
- package/dist/types/src/core/constants.d.ts +0 -51
- package/dist/types/src/core/context.d.ts +0 -36
- package/dist/types/src/core/core.d.ts +0 -174
- package/dist/types/src/core/dev.d.ts +0 -49
- package/dist/types/src/core/effect.d.ts +0 -32
- package/dist/types/src/core/error.d.ts +0 -38
- package/dist/types/src/core/external.d.ts +0 -45
- package/dist/types/src/core/graph.d.ts +0 -5
- package/dist/types/src/core/heap.d.ts +0 -14
- package/dist/types/src/core/index.d.ts +0 -12
- package/dist/types/src/core/lanes.d.ts +0 -54
- package/dist/types/src/core/owner.d.ts +0 -116
- package/dist/types/src/core/scheduler.d.ts +0 -122
- package/dist/types/src/core/types.d.ts +0 -85
- package/dist/types/src/index.d.ts +0 -9
- package/dist/types/src/map.d.ts +0 -53
- package/dist/types/src/signals.d.ts +0 -512
- package/dist/types/src/store/index.d.ts +0 -9
- package/dist/types/src/store/optimistic.d.ts +0 -45
- package/dist/types/src/store/projection.d.ts +0 -66
- package/dist/types/src/store/reconcile.d.ts +0 -23
- package/dist/types/src/store/store.d.ts +0 -125
- package/dist/types/src/store/storePath.d.ts +0 -58
- package/dist/types/src/store/utils.d.ts +0 -114
- package/dist/types-cjs/src/boundaries.d.cts +0 -173
- package/dist/types-cjs/src/core/action.d.cts +0 -35
- package/dist/types-cjs/src/core/async.d.cts +0 -6
- package/dist/types-cjs/src/core/constants.d.cts +0 -51
- package/dist/types-cjs/src/core/context.d.cts +0 -36
- package/dist/types-cjs/src/core/core.d.cts +0 -174
- package/dist/types-cjs/src/core/dev.d.cts +0 -49
- package/dist/types-cjs/src/core/effect.d.cts +0 -32
- package/dist/types-cjs/src/core/error.d.cts +0 -38
- package/dist/types-cjs/src/core/external.d.cts +0 -45
- package/dist/types-cjs/src/core/graph.d.cts +0 -5
- package/dist/types-cjs/src/core/heap.d.cts +0 -14
- package/dist/types-cjs/src/core/index.d.cts +0 -12
- package/dist/types-cjs/src/core/lanes.d.cts +0 -54
- package/dist/types-cjs/src/core/owner.d.cts +0 -116
- package/dist/types-cjs/src/core/scheduler.d.cts +0 -122
- package/dist/types-cjs/src/core/types.d.cts +0 -85
- package/dist/types-cjs/src/index.d.cts +0 -9
- package/dist/types-cjs/src/map.d.cts +0 -53
- package/dist/types-cjs/src/signals.d.cts +0 -512
- package/dist/types-cjs/src/store/index.d.cts +0 -9
- package/dist/types-cjs/src/store/optimistic.d.cts +0 -45
- package/dist/types-cjs/src/store/projection.d.cts +0 -66
- package/dist/types-cjs/src/store/reconcile.d.cts +0 -23
- package/dist/types-cjs/src/store/store.d.cts +0 -125
- package/dist/types-cjs/src/store/storePath.d.cts +0 -58
- package/dist/types-cjs/src/store/utils.d.cts +0 -114
|
@@ -73,9 +73,9 @@ export declare class CollectionQueue extends Queue {
|
|
|
73
73
|
* }
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
|
-
export declare function createLoadingBoundary(fn: () =>
|
|
76
|
+
export declare function createLoadingBoundary<T, U>(fn: () => T, fallback: () => U, options?: {
|
|
77
77
|
on?: () => any;
|
|
78
|
-
}):
|
|
78
|
+
}): Accessor<T | U>;
|
|
79
79
|
/**
|
|
80
80
|
* Lower-level primitive that backs the `<Errored>` flow control. Catches
|
|
81
81
|
* thrown errors inside `fn` and invokes `fallback(error, reset)` instead.
|
|
@@ -99,7 +99,7 @@ export declare function createLoadingBoundary(fn: () => any, fallback: () => any
|
|
|
99
99
|
* }
|
|
100
100
|
* ```
|
|
101
101
|
*/
|
|
102
|
-
export declare function createErrorBoundary<U>(fn: () =>
|
|
102
|
+
export declare function createErrorBoundary<T, U>(fn: () => T, fallback: (error: Accessor<unknown>, reset: () => void) => U): Accessor<T | U>;
|
|
103
103
|
/**
|
|
104
104
|
* Coordinate the reveal timing of sibling loading boundaries.
|
|
105
105
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type OptimisticLane } from "./lanes.js";
|
|
2
2
|
import type { Computed } from "./types.js";
|
|
3
3
|
export declare function settlePendingSource(el: Computed<any>): void;
|
|
4
|
+
export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
|
|
4
5
|
export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void): T;
|
|
5
6
|
export declare function clearStatus(el: Computed<any>, clearUninitialized?: boolean): void;
|
|
6
7
|
export declare function notifyStatus(el: Computed<any>, status: number, error: any, blockStatus?: boolean, lane?: OptimisticLane): void;
|
|
@@ -7,7 +7,6 @@ export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE: string;
|
|
|
7
7
|
export declare let tracking: boolean;
|
|
8
8
|
export declare let stale: boolean;
|
|
9
9
|
export declare let pendingCheckActive: boolean;
|
|
10
|
-
export declare let foundPending: boolean;
|
|
11
10
|
export declare let latestReadActive: boolean;
|
|
12
11
|
export declare let context: Owner | null;
|
|
13
12
|
export declare let currentOptimisticLane: OptimisticLane | null;
|
|
@@ -98,12 +97,37 @@ export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
|
|
|
98
97
|
* ```
|
|
99
98
|
*/
|
|
100
99
|
export declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
|
|
100
|
+
/**
|
|
101
|
+
* Keep the lazily-created isPending()/latest() companion nodes in sync with a
|
|
102
|
+
* new value. Every path that produces a value for `el` — direct set, async
|
|
103
|
+
* resolution, transition-held sync recompute — must route through here so a
|
|
104
|
+
* new write path can't silently skip the companions (#2831).
|
|
105
|
+
*/
|
|
106
|
+
export declare function syncCompanions<T>(el: Signal<T> | Computed<T>, value: T): void;
|
|
101
107
|
/**
|
|
102
108
|
* Update _pendingSignal when pending state changes. When the override clears
|
|
103
109
|
* (pending -> not pending), merge the sub-lane into the source's lane so
|
|
104
110
|
* isPending effects are blocked until the full scope resolves.
|
|
105
111
|
*/
|
|
106
112
|
export declare function updatePendingSignal(el: Signal<any> | Computed<any>): void;
|
|
113
|
+
/**
|
|
114
|
+
* A firewall's status change re-derives the verdicts of its probed leaves:
|
|
115
|
+
* leaf companions consult the firewall (broad inheritance), so async
|
|
116
|
+
* starting/settling on the firewall must poke them or they keep a stale
|
|
117
|
+
* verdict forever (V4 stuck-companion class, #2838).
|
|
118
|
+
*/
|
|
119
|
+
export declare function updateChildCompanions(el: Computed<any>): void;
|
|
120
|
+
/**
|
|
121
|
+
* Settlement checkpoint (#2838): re-derive a node's companions directly from
|
|
122
|
+
* its committed state. Called when the transition machinery for the node is
|
|
123
|
+
* done with it — a pending commit or an optimistic revert. Verdicts are
|
|
124
|
+
* written committed (not through setSignal) because a transition-scoped
|
|
125
|
+
* override window opened here would itself need a settlement, re-scheduling
|
|
126
|
+
* forever while async is still in flight. This is what keeps companions
|
|
127
|
+
* coherent past transition completion: a verdict is a property of the data
|
|
128
|
+
* (A19), so it must survive the transition that happened to produce it.
|
|
129
|
+
*/
|
|
130
|
+
export declare function snapCompanionsToState(owner: Signal<any> | Computed<any>): void;
|
|
107
131
|
export declare function staleValues<T>(fn: () => T, set?: boolean): T;
|
|
108
132
|
/**
|
|
109
133
|
* Reads reactive expressions while bypassing any pending async overlay — i.e.
|
package/dist/types/core/dev.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export interface DevHooks {
|
|
|
6
6
|
onStoreNodeUpdate?: (state: any, property: PropertyKey, value: any, prev: any) => void;
|
|
7
7
|
}
|
|
8
8
|
export type DiagnosticSeverity = "warn" | "error";
|
|
9
|
-
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "INVALID_REFRESH_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC";
|
|
10
|
-
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner";
|
|
9
|
+
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "INVALID_REFRESH_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION";
|
|
10
|
+
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner" | "error";
|
|
11
11
|
export interface DiagnosticEvent {
|
|
12
12
|
sequence: number;
|
|
13
13
|
code: DiagnosticCode;
|
|
@@ -39,6 +39,14 @@ export interface Dev {
|
|
|
39
39
|
getObservers: typeof getObservers;
|
|
40
40
|
}
|
|
41
41
|
export declare const DEV: Dev;
|
|
42
|
+
/**
|
|
43
|
+
* Dev-mode internal consistency check. A failure means the reactive system
|
|
44
|
+
* contradicted itself (not that user code misbehaved) — see
|
|
45
|
+
* INTERNALS-ASYNC-STATE.md for the invariant catalog. Throws under __TEST__
|
|
46
|
+
* so the suite (and fuzzing) treats any violation as a hard failure; logs in
|
|
47
|
+
* dev builds so user apps degrade instead of crashing.
|
|
48
|
+
*/
|
|
49
|
+
export declare function assertInvariant(condition: boolean, name: string, message: string): void;
|
|
42
50
|
export declare function emitDiagnostic(event: Omit<DiagnosticEvent, "sequence">): DiagnosticEvent;
|
|
43
51
|
export declare function registerGraph(value: any, owner: Owner | null): void;
|
|
44
52
|
export declare function clearSignals(node: Owner): void;
|
|
@@ -2,11 +2,10 @@ import type { Computed, NodeOptions, Owner } from "./types.js";
|
|
|
2
2
|
export interface Effect<T> extends Computed<T>, Owner {
|
|
3
3
|
_effectFn: (val: T, prev: T | undefined) => void | (() => void);
|
|
4
4
|
_errorFn?: (err: unknown, cleanup: () => void) => void;
|
|
5
|
-
_cleanup?: () => void;
|
|
6
|
-
_cleanupRegistered?: boolean;
|
|
7
5
|
_modified: boolean;
|
|
8
6
|
_prevValue: T | undefined;
|
|
9
7
|
_type: number;
|
|
8
|
+
_boundRunEffect?: () => void;
|
|
10
9
|
}
|
|
11
10
|
/**
|
|
12
11
|
* Effects are the leaf nodes of our reactive graph. When their sources change, they are
|
|
@@ -19,7 +18,6 @@ export declare function effect<T>(compute: (prev: T | undefined) => T, effect: (
|
|
|
19
18
|
schedule?: boolean;
|
|
20
19
|
}): void;
|
|
21
20
|
export interface TrackedEffect extends Computed<void> {
|
|
22
|
-
_cleanup?: () => void;
|
|
23
21
|
_modified: boolean;
|
|
24
22
|
_type: number;
|
|
25
23
|
_run: () => void;
|
|
@@ -2,4 +2,4 @@ import type { Computed, Link, Signal } from "./types.js";
|
|
|
2
2
|
export declare function unlinkSubs(link: Link): Link | null;
|
|
3
3
|
export declare function trimStaleDeps(el: Computed<any>): void;
|
|
4
4
|
export declare function unobserved(el: Computed<unknown>): void;
|
|
5
|
-
export declare function link(dep: Signal<any> | Computed<any>, sub: Computed<any
|
|
5
|
+
export declare function link(dep: Signal<any> | Computed<any>, sub: Computed<any>, pendingObserver?: boolean): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ContextNotFoundError, NoOwnerError, NotReadyError } from "./error.js";
|
|
2
|
-
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed, isPending, latest, refresh, staleValues, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots } from "./core.js";
|
|
2
|
+
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed, isPending, latest, updatePendingSignal, updateChildCompanions, refresh, staleValues, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots } from "./core.js";
|
|
3
3
|
export { enableExternalSource, _resetExternalSourceConfig, type ExternalSourceFactory, type ExternalSource, type ExternalSourceConfig } from "./external.js";
|
|
4
4
|
export { createOwner, createRoot, dispose, getNextChildId, getObserver, getOwner, isDisposed, cleanup, peekNextChildId } from "./owner.js";
|
|
5
5
|
export { createContext, getContext, setContext, type Context, type ContextRecord } from "./context.js";
|
|
@@ -7,6 +7,6 @@ export { handleAsync } from "./async.js";
|
|
|
7
7
|
export type { Computed, Disposable, FirewallSignal, Link, Owner, Root, Signal, NodeOptions } from "./types.js";
|
|
8
8
|
export { effect, trackedEffect, type Effect, type TrackedEffect } from "./effect.js";
|
|
9
9
|
export { action } from "./action.js";
|
|
10
|
-
export { flush, Queue, GlobalQueue, trackOptimisticStore, enforceLoadingBoundary, type IQueue, type QueueCallback } from "./scheduler.js";
|
|
10
|
+
export { flush, Queue, GlobalQueue, trackOptimisticStore, enforceLoadingBoundary, resetErrorHalt, type IQueue, type QueueCallback } from "./scheduler.js";
|
|
11
11
|
export { DEV, type Dev, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type Diagnostics, type DiagnosticSeverity } from "./dev.js";
|
|
12
12
|
export * from "./constants.js";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { OptimisticLane } from "./lanes.js";
|
|
2
|
+
import type { Computed, Signal } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Test-mode invariant checks for the async/transition/lane machinery.
|
|
5
|
+
* Catalog and rationale: packages/solid-signals/INTERNALS-ASYNC-STATE.md.
|
|
6
|
+
*
|
|
7
|
+
* These are implementation self-consistency checks, not semantic rules: a
|
|
8
|
+
* violation means the reactive system contradicted itself.
|
|
9
|
+
*
|
|
10
|
+
* They are gated on `__TEST__` (not just `__DEV__`): the per-write Set
|
|
11
|
+
* tracking and per-flush quiescence sweep are too expensive for shipped dev
|
|
12
|
+
* builds and for benchmarks (they showed up as a 5-21% hit across the
|
|
13
|
+
* CodSpeed suite when they ran under `__DEV__`). Call sites stay `__DEV__`
|
|
14
|
+
* guarded so production tree-shakes the calls; each entry point here
|
|
15
|
+
* early-returns unless `__TEST__` is set, so dev builds pay only a no-op
|
|
16
|
+
* call. The test suite (vitest run) defines `__TEST__: true`; benchmark mode
|
|
17
|
+
* defines `__TEST__: false`.
|
|
18
|
+
*/
|
|
19
|
+
type AnyNode = Signal<any> | Computed<any>;
|
|
20
|
+
/** Wired by core.ts at module init to avoid import cycles. */
|
|
21
|
+
export declare const InvariantHooks: {
|
|
22
|
+
pendingProbeActive: (() => boolean) | null;
|
|
23
|
+
/** Fresh oracle for what an isPending companion SHOULD read right now. */
|
|
24
|
+
computePendingState: ((node: AnyNode) => boolean) | null;
|
|
25
|
+
};
|
|
26
|
+
export declare function devTrackHeldPending(node: AnyNode): void;
|
|
27
|
+
export declare function devTrackCompanionOwner(node: AnyNode): void;
|
|
28
|
+
export declare function devTrackOptimistic(node: AnyNode): void;
|
|
29
|
+
/**
|
|
30
|
+
* Open/close the sanctioned registration window. Call sites are `__DEV__`
|
|
31
|
+
* guarded (no prod cost); the code inside the window must not throw.
|
|
32
|
+
*/
|
|
33
|
+
export declare function beginAsyncReporterWrites(): void;
|
|
34
|
+
export declare function endAsyncReporterWrites(): void;
|
|
35
|
+
export declare function createAsyncReporters(): Map<Computed<any>, Set<Computed<any>>>;
|
|
36
|
+
export declare function devCheckActiveOverrides(isRegisteredForRevert: (node: AnyNode) => boolean): void;
|
|
37
|
+
/** INV-1: an isPending() probe must never leak past its own call. */
|
|
38
|
+
export declare function devCheckFlushStart(): void;
|
|
39
|
+
/** INV-5: a merged lane's work moved to its root on merge and must stay empty. */
|
|
40
|
+
export declare function devCheckMergedLaneEmpty(lane: OptimisticLane): void;
|
|
41
|
+
export declare function devCensusCompanions(isQueuedForCommit?: (node: AnyNode) => boolean): void;
|
|
42
|
+
/**
|
|
43
|
+
* Quiescence checks. Run only when the system is fully drained: nothing
|
|
44
|
+
* scheduled, no active/stashed transitions, no live lanes. At that point no
|
|
45
|
+
* transition-scoped state may survive, and the lazily-created companions must
|
|
46
|
+
* agree with a fresh computation of their owner's state.
|
|
47
|
+
*/
|
|
48
|
+
export declare function devCheckQuiescent(isQueuedForCommit: (node: AnyNode) => boolean): void;
|
|
49
|
+
export {};
|
|
@@ -41,6 +41,14 @@ export interface Transition {
|
|
|
41
41
|
_gatedSubs: Set<Computed<any>>;
|
|
42
42
|
}
|
|
43
43
|
export declare function schedule(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Permanently halts the reactive system. Called when a user error escapes
|
|
46
|
+
* every boundary — app state is undefined at that point, so scheduling stops
|
|
47
|
+
* entirely rather than limping along with a half-applied update.
|
|
48
|
+
*/
|
|
49
|
+
export declare function haltReactivity(): void;
|
|
50
|
+
/** @internal Test/dev-reload hook. Revives scheduling after a halt. */
|
|
51
|
+
export declare function resetErrorHalt(): void;
|
|
44
52
|
export interface IQueue {
|
|
45
53
|
enqueue(type: number, fn: QueueCallback): void;
|
|
46
54
|
run(type: number): boolean | void;
|
|
@@ -10,6 +10,14 @@ export interface Link {
|
|
|
10
10
|
_nextDep: Link | null;
|
|
11
11
|
_prevSub: Link | null;
|
|
12
12
|
_nextSub: Link | null;
|
|
13
|
+
/**
|
|
14
|
+
* `_sub._depGen` at the time this link was created or last revalidated
|
|
15
|
+
* in-order. A link stamped with the subscriber's current pass generation is
|
|
16
|
+
* inside the validated `[deps.._depsTail]` prefix — an O(1) replacement for
|
|
17
|
+
* scanning the dep list to answer membership (see `link()`).
|
|
18
|
+
*/
|
|
19
|
+
_gen: number;
|
|
20
|
+
_pendingObserver?: boolean;
|
|
13
21
|
}
|
|
14
22
|
export interface NodeOptions<T> {
|
|
15
23
|
id?: string;
|
|
@@ -50,6 +58,8 @@ export interface Owner {
|
|
|
50
58
|
id?: string;
|
|
51
59
|
_config: number;
|
|
52
60
|
_snapshotScope?: boolean;
|
|
61
|
+
/** Effect-returned cleanup; managed across reruns, invoked at true disposal */
|
|
62
|
+
_cleanup?: () => void;
|
|
53
63
|
_disposal: Disposable | Disposable[] | null;
|
|
54
64
|
_parent: Owner | null;
|
|
55
65
|
_context: Record<symbol | string, unknown>;
|
|
@@ -64,6 +74,8 @@ export interface Owner {
|
|
|
64
74
|
export interface Computed<T> extends RawSignal<T>, Owner {
|
|
65
75
|
_deps: Link | null;
|
|
66
76
|
_depsTail: Link | null;
|
|
77
|
+
/** Recompute-pass counter; bumped when dep revalidation starts. */
|
|
78
|
+
_depGen: number;
|
|
67
79
|
_flags: number;
|
|
68
80
|
_blocked?: boolean;
|
|
69
81
|
_pendingSource?: Computed<any>;
|
|
@@ -77,6 +89,13 @@ export interface Computed<T> extends RawSignal<T>, Owner {
|
|
|
77
89
|
_inFlight: PromiseLike<T> | AsyncIterable<T> | null;
|
|
78
90
|
_child: FirewallSignal<any> | null;
|
|
79
91
|
_notifyStatus?: (status?: number, error?: any) => void;
|
|
92
|
+
/**
|
|
93
|
+
* Store-wide optimistic mask (count of this firewall's store targets with
|
|
94
|
+
* live optimistic writes). Non-zero decrees the whole store settled for
|
|
95
|
+
* `isPending` — the store is the primitive the mask covers (A20 re-rule
|
|
96
|
+
* 2026-07-07c).
|
|
97
|
+
*/
|
|
98
|
+
_optimisticMask?: number;
|
|
80
99
|
}
|
|
81
100
|
export interface Root extends Owner {
|
|
82
101
|
_root: true;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { $REFRESH, ContextNotFoundError, NoOwnerError, NotReadyError, action, createContext, createOwner, createRoot, runWithOwner, flush, getNextChildId, peekNextChildId, getContext, setContext, getOwner, isDisposed, getObserver, isEqual, untrack, isPending, latest, refresh, SUPPORTS_PROXY, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots, enforceLoadingBoundary, enableExternalSource } from "./core/index.js";
|
|
1
|
+
export { $REFRESH, ContextNotFoundError, NoOwnerError, NotReadyError, action, createContext, createOwner, createRoot, runWithOwner, flush, getNextChildId, peekNextChildId, getContext, setContext, getOwner, isDisposed, getObserver, isEqual, untrack, isPending, latest, refresh, SUPPORTS_PROXY, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots, enforceLoadingBoundary, enableExternalSource, resetErrorHalt } from "./core/index.js";
|
|
2
2
|
import { type Dev } from "./core/index.js";
|
|
3
3
|
export declare const DEV: Dev | undefined;
|
|
4
4
|
export type { Owner, Context, ContextRecord, IQueue, ExternalSourceFactory, ExternalSource, ExternalSourceConfig, Refreshable, Dev, DevHooks, DiagnosticCapture, DiagnosticCode, DiagnosticEvent, DiagnosticKind, Diagnostics, DiagnosticSeverity } from "./core/index.js";
|
package/dist/types/signals.d.ts
CHANGED
|
@@ -69,6 +69,17 @@ export type ComputeFunction<Prev, Next extends Prev = Prev> = (v: Prev) => Promi
|
|
|
69
69
|
export type EffectFunction<Prev, Next extends Prev = Prev> = (v: Next, p?: Prev) => (() => void) | void;
|
|
70
70
|
export type EffectBundle<Prev, Next extends Prev = Prev> = {
|
|
71
71
|
effect: EffectFunction<Prev, Next>;
|
|
72
|
+
/**
|
|
73
|
+
* Intercepts compute-phase errors (thrown by the compute function or arriving
|
|
74
|
+
* from upstream sources). Effect-phase throws are NOT routed here — they are
|
|
75
|
+
* your own imperative code and escalate to the nearest error boundary.
|
|
76
|
+
*
|
|
77
|
+
* This is the error arm of the effect phase: it runs on the same queue and
|
|
78
|
+
* in the same imperative, writable scope as `effect` (signal writes are
|
|
79
|
+
* legal), receives the error the user code threw, and observes settled
|
|
80
|
+
* outcomes — an error that recovers before the effect phase runs the
|
|
81
|
+
* `effect` arm instead, and a held transition defers it like `effect`.
|
|
82
|
+
*/
|
|
72
83
|
error: (err: unknown, cleanup: () => void) => void;
|
|
73
84
|
};
|
|
74
85
|
/** Options shared by every effect primitive. */
|
|
@@ -245,7 +256,24 @@ export declare function createMemo<T>(compute: ComputeFunction<undefined | NoInf
|
|
|
245
256
|
* `createTrackedEffect` (with the tradeoffs noted there).
|
|
246
257
|
*
|
|
247
258
|
* Pass an `EffectBundle` (`{ effect, error }`) instead of a plain function to
|
|
248
|
-
* intercept errors thrown
|
|
259
|
+
* intercept **compute-phase** errors — errors thrown by `compute` or arriving
|
|
260
|
+
* from upstream reactive sources (including async rejections), which your own
|
|
261
|
+
* code has no frame to `try/catch`. The `error` handler is the error arm of
|
|
262
|
+
* the effect phase: it runs on the same schedule and in the same imperative,
|
|
263
|
+
* writable scope as `effect` (setting error state via signals is fine), and
|
|
264
|
+
* only for *settled* errors — a transient error that recovers before the
|
|
265
|
+
* effect phase runs `effect` with the recovered value instead, and a held
|
|
266
|
+
* transition defers it exactly as it defers `effect`. Without an `error`
|
|
267
|
+
* handler a compute-phase error is logged and the effect simply skips that
|
|
268
|
+
* run — a non-render effect's reactivity failing does not crash the app.
|
|
269
|
+
* Rethrowing from `error` escalates it to the nearest error boundary
|
|
270
|
+
* (halting the system if none exists).
|
|
271
|
+
*
|
|
272
|
+
* The **effect phase is different**: it is your own imperative code, so handle
|
|
273
|
+
* failures with `try/catch` where they occur. An uncaught effect-phase throw
|
|
274
|
+
* is treated as an unhandled application error — caught by the nearest
|
|
275
|
+
* `createErrorBoundary`/`<Errored>`, and permanently halting the reactive
|
|
276
|
+
* system if there is none. It is *not* routed to the bundle's `error` handler.
|
|
249
277
|
*
|
|
250
278
|
* ```typescript
|
|
251
279
|
* createEffect<T>(compute, effectFn | { effect, error }, options?: EffectOptions);
|
|
@@ -383,7 +411,9 @@ export declare function createReaction(effectFn: EffectFunction<undefined> | Eff
|
|
|
383
411
|
* Awaits a reactive expression and returns its first fully-settled value as a
|
|
384
412
|
* `Promise`. Pending async reads (`createMemo` returning a promise, etc.) are
|
|
385
413
|
* waited on; once the expression returns synchronously without `NotReadyError`
|
|
386
|
-
* the promise resolves with that value.
|
|
414
|
+
* the promise resolves with that value. If the expression settles with an
|
|
415
|
+
* error instead — including an async source that rejects — the promise
|
|
416
|
+
* rejects with it.
|
|
387
417
|
*
|
|
388
418
|
* Must be called *outside* a tracking scope — it doesn't subscribe, it just
|
|
389
419
|
* resolves the current value once.
|
|
@@ -459,6 +489,13 @@ export declare function createOptimistic<T>(fn: ComputeFunction<T>, options?: Si
|
|
|
459
489
|
* `onCleanup` is **not** allowed inside the callback — return a cleanup
|
|
460
490
|
* function instead. The returned cleanup runs on owner disposal.
|
|
461
491
|
*
|
|
492
|
+
* A cleanup return is only honored when `onSettled` is called from an **owned**
|
|
493
|
+
* scope (e.g. a component body). When it fires out of band from an *unowned*
|
|
494
|
+
* scope — an event handler, a tracked effect, or another `onSettled` — there is
|
|
495
|
+
* no owner lifecycle to bind a cleanup to; returning one is a dev-mode error
|
|
496
|
+
* (and is dropped in production). Use the post-settle/event-handler forms below
|
|
497
|
+
* for one-shot work, and keep setup-with-teardown in an owned scope.
|
|
498
|
+
*
|
|
462
499
|
* @example
|
|
463
500
|
* ```tsx
|
|
464
501
|
* // Component-level setup + teardown — replaces onMount + onCleanup.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Computed, type Refreshable } from "../core/index.js";
|
|
2
|
-
import { type ProjectionOptions, type Store } from "./store.js";
|
|
2
|
+
import { type NoFn, type ProjectionOptions, type Store } from "./store.js";
|
|
3
3
|
export declare function createProjectionInternal<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T>, options?: ProjectionOptions): {
|
|
4
4
|
store: Refreshable<Store<T>>;
|
|
5
5
|
node: Computed<void | T>;
|
|
@@ -47,7 +47,7 @@ export declare function createProjectionInternal<T extends object = {}>(fn: (dra
|
|
|
47
47
|
*
|
|
48
48
|
* @see {@link https://github.com/solidjs/x-reactivity#createprojection}
|
|
49
49
|
*/
|
|
50
|
-
export declare function createProjection<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T
|
|
50
|
+
export declare function createProjection<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): Refreshable<Store<T>>;
|
|
51
51
|
/**
|
|
52
52
|
* Shared projection computed body used by both `createProjection` and the derived
|
|
53
53
|
* form of `createOptimisticStore`. Encapsulates the write-trap draft, `storeSetter`
|
|
@@ -41,7 +41,7 @@ type DataNodes = Record<PropertyKey, DataNode>;
|
|
|
41
41
|
* @internal
|
|
42
42
|
*/
|
|
43
43
|
export declare const $TRACK: unique symbol, $TARGET: unique symbol, $PROXY: unique symbol, $DELETED: unique symbol;
|
|
44
|
-
export declare const STORE_VALUE = "v", STORE_OVERRIDE = "o", STORE_OPTIMISTIC_OVERRIDE = "x", STORE_NODE = "n", STORE_HAS = "h", STORE_CUSTOM_PROTO = "c", STORE_WRAP = "w", STORE_LOOKUP = "l", STORE_FIREWALL = "f", STORE_OPTIMISTIC = "p";
|
|
44
|
+
export declare const STORE_VALUE = "v", STORE_OVERRIDE = "o", STORE_OPTIMISTIC_OVERRIDE = "x", STORE_NODE = "n", STORE_HAS = "h", STORE_CUSTOM_PROTO = "c", STORE_WRAP = "w", STORE_LOOKUP = "l", STORE_FIREWALL = "f", STORE_OPTIMISTIC = "p", STORE_MASKED = "m";
|
|
45
45
|
export type StoreNode = {
|
|
46
46
|
[$PROXY]: any;
|
|
47
47
|
[STORE_VALUE]: Record<PropertyKey, any>;
|
|
@@ -54,6 +54,8 @@ export type StoreNode = {
|
|
|
54
54
|
[STORE_LOOKUP]?: WeakMap<any, any>;
|
|
55
55
|
[STORE_FIREWALL]?: Computed<any>;
|
|
56
56
|
[STORE_OPTIMISTIC]?: boolean;
|
|
57
|
+
/** This target currently contributes to its firewall's store-wide mask. */
|
|
58
|
+
[STORE_MASKED]?: boolean;
|
|
57
59
|
[STORE_SNAPSHOT_PROPS]?: Record<PropertyKey, any>;
|
|
58
60
|
};
|
|
59
61
|
export declare namespace SolidStore {
|
|
@@ -63,13 +65,38 @@ export declare namespace SolidStore {
|
|
|
63
65
|
export type NotWrappable = string | number | bigint | symbol | boolean | Function | null | undefined | SolidStore.Unwrappable[keyof SolidStore.Unwrappable];
|
|
64
66
|
export declare function createStoreProxy<T extends object>(value: T, traps?: ProxyHandler<StoreNode>, extend?: (target: StoreNode) => void): any;
|
|
65
67
|
export declare const storeLookup: WeakMap<WeakKey, any>;
|
|
68
|
+
export declare const symbolKeyedRecords: WeakSet<object>;
|
|
66
69
|
export declare function wrap<T extends Record<PropertyKey, any>>(value: T, target?: StoreNode): T;
|
|
67
70
|
export declare function isWrappable<T>(obj: T | NotWrappable): obj is T;
|
|
68
71
|
export declare function setWriteOverride(value: boolean): void;
|
|
72
|
+
export declare function ownEnumerableKeys(o: object): (string | symbol)[];
|
|
73
|
+
/**
|
|
74
|
+
* Single chokepoint for the store's layered value resolution: returns the
|
|
75
|
+
* override layer (optimistic first, then regular) that shadows `property`, or
|
|
76
|
+
* `undefined` when the base `STORE_VALUE` is authoritative. Every trap must
|
|
77
|
+
* resolve through this — hand-inlining the layer order is how the optimistic
|
|
78
|
+
* layer gets missed (#2850).
|
|
79
|
+
*/
|
|
80
|
+
export declare function getOverlayLayer(target: StoreNode, property: PropertyKey): Record<PropertyKey, any> | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* The value a store leaf's backing signal currently shows to readers: active
|
|
83
|
+
* override, else held pending value, else committed value.
|
|
84
|
+
*/
|
|
85
|
+
export declare function visibleNodeValue(node: DataNode): any;
|
|
69
86
|
export declare function trackSelf(target: StoreNode, symbol?: symbol): void;
|
|
70
87
|
export declare function notifySelf(target: StoreNode): void;
|
|
71
88
|
export declare function getKeys(source: Record<PropertyKey, any>, override: Record<PropertyKey, any> | undefined, enumerable?: boolean): PropertyKey[];
|
|
72
89
|
export declare function getPropertyDescriptor(source: Record<PropertyKey, any>, override: Record<PropertyKey, any> | undefined, property: PropertyKey): PropertyDescriptor | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Store-wide mask bookkeeping (A20 re-rule 2026-07-07c): the store is the
|
|
92
|
+
* primitive, so an optimistic write decrees the WHOLE store settled for
|
|
93
|
+
* `isPending` — firewall, written leaves, untouched siblings, structural
|
|
94
|
+
* reads — for the lifetime of the override/transition. The firewall carries a
|
|
95
|
+
* count of masked targets (nested objects mask independently); companions of
|
|
96
|
+
* the firewall and its probed leaves are poked on 0↔1 transitions so an
|
|
97
|
+
* already-materialized verdict flips without waiting for another write.
|
|
98
|
+
*/
|
|
99
|
+
export declare function maskStoreTarget(target: StoreNode, on: boolean): void;
|
|
73
100
|
export declare const storeTraps: ProxyHandler<StoreNode>;
|
|
74
101
|
export declare function storeSetter<T extends object>(store: Store<T>, fn: (draft: T) => T | void): void;
|
|
75
102
|
/**
|
|
@@ -73,9 +73,9 @@ export declare class CollectionQueue extends Queue {
|
|
|
73
73
|
* }
|
|
74
74
|
* ```
|
|
75
75
|
*/
|
|
76
|
-
export declare function createLoadingBoundary(fn: () =>
|
|
76
|
+
export declare function createLoadingBoundary<T, U>(fn: () => T, fallback: () => U, options?: {
|
|
77
77
|
on?: () => any;
|
|
78
|
-
}):
|
|
78
|
+
}): Accessor<T | U>;
|
|
79
79
|
/**
|
|
80
80
|
* Lower-level primitive that backs the `<Errored>` flow control. Catches
|
|
81
81
|
* thrown errors inside `fn` and invokes `fallback(error, reset)` instead.
|
|
@@ -99,7 +99,7 @@ export declare function createLoadingBoundary(fn: () => any, fallback: () => any
|
|
|
99
99
|
* }
|
|
100
100
|
* ```
|
|
101
101
|
*/
|
|
102
|
-
export declare function createErrorBoundary<U>(fn: () =>
|
|
102
|
+
export declare function createErrorBoundary<T, U>(fn: () => T, fallback: (error: Accessor<unknown>, reset: () => void) => U): Accessor<T | U>;
|
|
103
103
|
/**
|
|
104
104
|
* Coordinate the reveal timing of sibling loading boundaries.
|
|
105
105
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type OptimisticLane } from "./lanes.cjs";
|
|
2
2
|
import type { Computed } from "./types.cjs";
|
|
3
3
|
export declare function settlePendingSource(el: Computed<any>): void;
|
|
4
|
+
export declare function isThenable<T>(value: T | PromiseLike<T>): value is PromiseLike<T>;
|
|
4
5
|
export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void): T;
|
|
5
6
|
export declare function clearStatus(el: Computed<any>, clearUninitialized?: boolean): void;
|
|
6
7
|
export declare function notifyStatus(el: Computed<any>, status: number, error: any, blockStatus?: boolean, lane?: OptimisticLane): void;
|
|
@@ -7,7 +7,6 @@ export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE: string;
|
|
|
7
7
|
export declare let tracking: boolean;
|
|
8
8
|
export declare let stale: boolean;
|
|
9
9
|
export declare let pendingCheckActive: boolean;
|
|
10
|
-
export declare let foundPending: boolean;
|
|
11
10
|
export declare let latestReadActive: boolean;
|
|
12
11
|
export declare let context: Owner | null;
|
|
13
12
|
export declare let currentOptimisticLane: OptimisticLane | null;
|
|
@@ -98,12 +97,37 @@ export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
|
|
|
98
97
|
* ```
|
|
99
98
|
*/
|
|
100
99
|
export declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
|
|
100
|
+
/**
|
|
101
|
+
* Keep the lazily-created isPending()/latest() companion nodes in sync with a
|
|
102
|
+
* new value. Every path that produces a value for `el` — direct set, async
|
|
103
|
+
* resolution, transition-held sync recompute — must route through here so a
|
|
104
|
+
* new write path can't silently skip the companions (#2831).
|
|
105
|
+
*/
|
|
106
|
+
export declare function syncCompanions<T>(el: Signal<T> | Computed<T>, value: T): void;
|
|
101
107
|
/**
|
|
102
108
|
* Update _pendingSignal when pending state changes. When the override clears
|
|
103
109
|
* (pending -> not pending), merge the sub-lane into the source's lane so
|
|
104
110
|
* isPending effects are blocked until the full scope resolves.
|
|
105
111
|
*/
|
|
106
112
|
export declare function updatePendingSignal(el: Signal<any> | Computed<any>): void;
|
|
113
|
+
/**
|
|
114
|
+
* A firewall's status change re-derives the verdicts of its probed leaves:
|
|
115
|
+
* leaf companions consult the firewall (broad inheritance), so async
|
|
116
|
+
* starting/settling on the firewall must poke them or they keep a stale
|
|
117
|
+
* verdict forever (V4 stuck-companion class, #2838).
|
|
118
|
+
*/
|
|
119
|
+
export declare function updateChildCompanions(el: Computed<any>): void;
|
|
120
|
+
/**
|
|
121
|
+
* Settlement checkpoint (#2838): re-derive a node's companions directly from
|
|
122
|
+
* its committed state. Called when the transition machinery for the node is
|
|
123
|
+
* done with it — a pending commit or an optimistic revert. Verdicts are
|
|
124
|
+
* written committed (not through setSignal) because a transition-scoped
|
|
125
|
+
* override window opened here would itself need a settlement, re-scheduling
|
|
126
|
+
* forever while async is still in flight. This is what keeps companions
|
|
127
|
+
* coherent past transition completion: a verdict is a property of the data
|
|
128
|
+
* (A19), so it must survive the transition that happened to produce it.
|
|
129
|
+
*/
|
|
130
|
+
export declare function snapCompanionsToState(owner: Signal<any> | Computed<any>): void;
|
|
107
131
|
export declare function staleValues<T>(fn: () => T, set?: boolean): T;
|
|
108
132
|
/**
|
|
109
133
|
* Reads reactive expressions while bypassing any pending async overlay — i.e.
|
|
@@ -6,8 +6,8 @@ export interface DevHooks {
|
|
|
6
6
|
onStoreNodeUpdate?: (state: any, property: PropertyKey, value: any, prev: any) => void;
|
|
7
7
|
}
|
|
8
8
|
export type DiagnosticSeverity = "warn" | "error";
|
|
9
|
-
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "INVALID_REFRESH_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC";
|
|
10
|
-
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner";
|
|
9
|
+
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "INVALID_REFRESH_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION";
|
|
10
|
+
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner" | "error";
|
|
11
11
|
export interface DiagnosticEvent {
|
|
12
12
|
sequence: number;
|
|
13
13
|
code: DiagnosticCode;
|
|
@@ -39,6 +39,14 @@ export interface Dev {
|
|
|
39
39
|
getObservers: typeof getObservers;
|
|
40
40
|
}
|
|
41
41
|
export declare const DEV: Dev;
|
|
42
|
+
/**
|
|
43
|
+
* Dev-mode internal consistency check. A failure means the reactive system
|
|
44
|
+
* contradicted itself (not that user code misbehaved) — see
|
|
45
|
+
* INTERNALS-ASYNC-STATE.md for the invariant catalog. Throws under __TEST__
|
|
46
|
+
* so the suite (and fuzzing) treats any violation as a hard failure; logs in
|
|
47
|
+
* dev builds so user apps degrade instead of crashing.
|
|
48
|
+
*/
|
|
49
|
+
export declare function assertInvariant(condition: boolean, name: string, message: string): void;
|
|
42
50
|
export declare function emitDiagnostic(event: Omit<DiagnosticEvent, "sequence">): DiagnosticEvent;
|
|
43
51
|
export declare function registerGraph(value: any, owner: Owner | null): void;
|
|
44
52
|
export declare function clearSignals(node: Owner): void;
|
|
@@ -2,11 +2,10 @@ import type { Computed, NodeOptions, Owner } from "./types.cjs";
|
|
|
2
2
|
export interface Effect<T> extends Computed<T>, Owner {
|
|
3
3
|
_effectFn: (val: T, prev: T | undefined) => void | (() => void);
|
|
4
4
|
_errorFn?: (err: unknown, cleanup: () => void) => void;
|
|
5
|
-
_cleanup?: () => void;
|
|
6
|
-
_cleanupRegistered?: boolean;
|
|
7
5
|
_modified: boolean;
|
|
8
6
|
_prevValue: T | undefined;
|
|
9
7
|
_type: number;
|
|
8
|
+
_boundRunEffect?: () => void;
|
|
10
9
|
}
|
|
11
10
|
/**
|
|
12
11
|
* Effects are the leaf nodes of our reactive graph. When their sources change, they are
|
|
@@ -19,7 +18,6 @@ export declare function effect<T>(compute: (prev: T | undefined) => T, effect: (
|
|
|
19
18
|
schedule?: boolean;
|
|
20
19
|
}): void;
|
|
21
20
|
export interface TrackedEffect extends Computed<void> {
|
|
22
|
-
_cleanup?: () => void;
|
|
23
21
|
_modified: boolean;
|
|
24
22
|
_type: number;
|
|
25
23
|
_run: () => void;
|
|
@@ -2,4 +2,4 @@ import type { Computed, Link, Signal } from "./types.cjs";
|
|
|
2
2
|
export declare function unlinkSubs(link: Link): Link | null;
|
|
3
3
|
export declare function trimStaleDeps(el: Computed<any>): void;
|
|
4
4
|
export declare function unobserved(el: Computed<unknown>): void;
|
|
5
|
-
export declare function link(dep: Signal<any> | Computed<any>, sub: Computed<any
|
|
5
|
+
export declare function link(dep: Signal<any> | Computed<any>, sub: Computed<any>, pendingObserver?: boolean): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ContextNotFoundError, NoOwnerError, NotReadyError } from "./error.cjs";
|
|
2
|
-
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed, isPending, latest, refresh, staleValues, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots } from "./core.cjs";
|
|
2
|
+
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed, isPending, latest, updatePendingSignal, updateChildCompanions, 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";
|
|
@@ -7,6 +7,6 @@ export { handleAsync } from "./async.cjs";
|
|
|
7
7
|
export type { Computed, Disposable, FirewallSignal, Link, Owner, Root, Signal, NodeOptions } from "./types.cjs";
|
|
8
8
|
export { effect, trackedEffect, type Effect, type TrackedEffect } from "./effect.cjs";
|
|
9
9
|
export { action } from "./action.cjs";
|
|
10
|
-
export { flush, Queue, GlobalQueue, trackOptimisticStore, enforceLoadingBoundary, type IQueue, type QueueCallback } from "./scheduler.cjs";
|
|
10
|
+
export { flush, Queue, GlobalQueue, trackOptimisticStore, enforceLoadingBoundary, resetErrorHalt, type IQueue, type QueueCallback } from "./scheduler.cjs";
|
|
11
11
|
export { DEV, type Dev, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type Diagnostics, type DiagnosticSeverity } from "./dev.cjs";
|
|
12
12
|
export * from "./constants.cjs";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { OptimisticLane } from "./lanes.cjs";
|
|
2
|
+
import type { Computed, Signal } from "./types.cjs";
|
|
3
|
+
/**
|
|
4
|
+
* Test-mode invariant checks for the async/transition/lane machinery.
|
|
5
|
+
* Catalog and rationale: packages/solid-signals/INTERNALS-ASYNC-STATE.md.
|
|
6
|
+
*
|
|
7
|
+
* These are implementation self-consistency checks, not semantic rules: a
|
|
8
|
+
* violation means the reactive system contradicted itself.
|
|
9
|
+
*
|
|
10
|
+
* They are gated on `__TEST__` (not just `__DEV__`): the per-write Set
|
|
11
|
+
* tracking and per-flush quiescence sweep are too expensive for shipped dev
|
|
12
|
+
* builds and for benchmarks (they showed up as a 5-21% hit across the
|
|
13
|
+
* CodSpeed suite when they ran under `__DEV__`). Call sites stay `__DEV__`
|
|
14
|
+
* guarded so production tree-shakes the calls; each entry point here
|
|
15
|
+
* early-returns unless `__TEST__` is set, so dev builds pay only a no-op
|
|
16
|
+
* call. The test suite (vitest run) defines `__TEST__: true`; benchmark mode
|
|
17
|
+
* defines `__TEST__: false`.
|
|
18
|
+
*/
|
|
19
|
+
type AnyNode = Signal<any> | Computed<any>;
|
|
20
|
+
/** Wired by core.ts at module init to avoid import cycles. */
|
|
21
|
+
export declare const InvariantHooks: {
|
|
22
|
+
pendingProbeActive: (() => boolean) | null;
|
|
23
|
+
/** Fresh oracle for what an isPending companion SHOULD read right now. */
|
|
24
|
+
computePendingState: ((node: AnyNode) => boolean) | null;
|
|
25
|
+
};
|
|
26
|
+
export declare function devTrackHeldPending(node: AnyNode): void;
|
|
27
|
+
export declare function devTrackCompanionOwner(node: AnyNode): void;
|
|
28
|
+
export declare function devTrackOptimistic(node: AnyNode): void;
|
|
29
|
+
/**
|
|
30
|
+
* Open/close the sanctioned registration window. Call sites are `__DEV__`
|
|
31
|
+
* guarded (no prod cost); the code inside the window must not throw.
|
|
32
|
+
*/
|
|
33
|
+
export declare function beginAsyncReporterWrites(): void;
|
|
34
|
+
export declare function endAsyncReporterWrites(): void;
|
|
35
|
+
export declare function createAsyncReporters(): Map<Computed<any>, Set<Computed<any>>>;
|
|
36
|
+
export declare function devCheckActiveOverrides(isRegisteredForRevert: (node: AnyNode) => boolean): void;
|
|
37
|
+
/** INV-1: an isPending() probe must never leak past its own call. */
|
|
38
|
+
export declare function devCheckFlushStart(): void;
|
|
39
|
+
/** INV-5: a merged lane's work moved to its root on merge and must stay empty. */
|
|
40
|
+
export declare function devCheckMergedLaneEmpty(lane: OptimisticLane): void;
|
|
41
|
+
export declare function devCensusCompanions(isQueuedForCommit?: (node: AnyNode) => boolean): void;
|
|
42
|
+
/**
|
|
43
|
+
* Quiescence checks. Run only when the system is fully drained: nothing
|
|
44
|
+
* scheduled, no active/stashed transitions, no live lanes. At that point no
|
|
45
|
+
* transition-scoped state may survive, and the lazily-created companions must
|
|
46
|
+
* agree with a fresh computation of their owner's state.
|
|
47
|
+
*/
|
|
48
|
+
export declare function devCheckQuiescent(isQueuedForCommit: (node: AnyNode) => boolean): void;
|
|
49
|
+
export {};
|
|
@@ -41,6 +41,14 @@ export interface Transition {
|
|
|
41
41
|
_gatedSubs: Set<Computed<any>>;
|
|
42
42
|
}
|
|
43
43
|
export declare function schedule(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Permanently halts the reactive system. Called when a user error escapes
|
|
46
|
+
* every boundary — app state is undefined at that point, so scheduling stops
|
|
47
|
+
* entirely rather than limping along with a half-applied update.
|
|
48
|
+
*/
|
|
49
|
+
export declare function haltReactivity(): void;
|
|
50
|
+
/** @internal Test/dev-reload hook. Revives scheduling after a halt. */
|
|
51
|
+
export declare function resetErrorHalt(): void;
|
|
44
52
|
export interface IQueue {
|
|
45
53
|
enqueue(type: number, fn: QueueCallback): void;
|
|
46
54
|
run(type: number): boolean | void;
|