@solidjs/signals 2.0.0-rc.6 → 2.0.0-rc.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev-shared.js +5243 -0
- package/dist/dev.attribution.js +2333 -0
- package/dist/dev.js +1758 -6621
- package/dist/observe/affects.js +127 -0
- package/dist/observe/attribution.js +1 -0
- package/dist/observe/boundaries.js +586 -0
- package/dist/observe/core/action.js +167 -0
- package/dist/observe/core/async.js +736 -0
- package/dist/observe/core/attribution-hooks.js +60 -0
- package/dist/observe/core/attribution.js +2318 -0
- package/dist/{types-cjs/core/constants.d.cts → observe/core/constants.js} +135 -71
- package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
- package/dist/observe/core/core.js +1289 -0
- package/dist/observe/core/dev.js +232 -0
- package/dist/observe/core/effect.js +179 -0
- package/dist/observe/core/error.js +80 -0
- package/dist/observe/core/external.js +98 -0
- package/dist/observe/core/graph.js +155 -0
- package/dist/observe/core/heap.js +147 -0
- package/dist/observe/core/invariants.js +43 -0
- package/dist/observe/core/lanes.js +168 -0
- package/dist/observe/core/optimistic.js +438 -0
- package/dist/observe/core/owner.js +308 -0
- package/dist/observe/core/scheduler.js +1190 -0
- package/dist/observe/core/verdict.js +551 -0
- package/dist/observe/index.js +55 -0
- package/dist/observe/map.js +482 -0
- package/dist/{types-cjs/signals.d.cts → observe/signals.js} +305 -317
- package/dist/observe/store/index.js +38 -0
- package/dist/observe/store/next/optimistic.js +651 -0
- package/dist/observe/store/next/projection.js +242 -0
- package/dist/observe/store/next/reconcile.js +373 -0
- package/dist/observe/store/next/store.js +2213 -0
- package/dist/observe/store/next/target.js +51 -0
- package/dist/observe/store/store.js +323 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/utils.js +210 -0
- package/dist/prod/attribution.js +32 -0
- package/dist/prod/boundaries.js +3 -1
- package/dist/prod/core/action.js +52 -32
- package/dist/prod/core/async.js +177 -128
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +32 -1
- package/dist/prod/core/context.js +10 -16
- package/dist/prod/core/core.js +505 -286
- package/dist/prod/core/dev.js +2 -0
- package/dist/prod/core/effect.js +72 -43
- package/dist/prod/core/external.js +2 -2
- package/dist/prod/core/graph.js +40 -36
- package/dist/prod/core/heap.js +50 -51
- package/dist/prod/core/lanes.js +43 -22
- package/dist/prod/core/optimistic.js +224 -80
- package/dist/prod/core/owner.js +43 -39
- package/dist/prod/core/scheduler.js +347 -232
- package/dist/prod/core/verdict.js +71 -74
- package/dist/prod/index.js +9 -5
- package/dist/prod/map.js +311 -150
- package/dist/prod/signals.js +52 -38
- package/dist/prod/store/next/optimistic.js +127 -131
- package/dist/prod/store/next/projection.js +3 -3
- package/dist/prod/store/next/reconcile.js +149 -294
- package/dist/prod/store/next/store.js +694 -380
- package/dist/prod/store/next/target.js +32 -10
- package/dist/prod/store/store.js +12 -14
- package/dist/prod/store/utils.js +36 -27
- package/dist/types/attribution.d.ts +15 -0
- package/dist/types/attribution.prod.d.ts +13 -0
- package/dist/types/core/async.d.ts +1 -1
- package/dist/types/core/attribution-hooks.d.ts +183 -6
- package/dist/types/core/attribution.d.ts +435 -24
- package/dist/types/core/constants.d.ts +31 -0
- package/dist/types/core/core.d.ts +19 -3
- package/dist/types/core/dev.d.ts +165 -26
- package/dist/types/core/effect.d.ts +8 -1
- package/dist/types/core/heap.d.ts +5 -3
- package/dist/types/core/index.d.ts +2 -1
- package/dist/types/core/invariants.d.ts +1 -1
- package/dist/types/core/lanes.d.ts +17 -0
- package/dist/types/core/scheduler.d.ts +69 -4
- package/dist/types/core/types.d.ts +29 -9
- package/dist/types/index.d.ts +9 -2
- package/dist/types/map.d.ts +2 -0
- package/dist/types/signals.d.ts +10 -0
- package/dist/types/store/index.d.ts +4 -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 +8 -9
- package/dist/types/store/next/target.d.ts +56 -55
- package/dist/types/store/store.d.ts +14 -9
- package/dist/types/store/utils.d.ts +7 -0
- package/package.json +21 -16
- package/dist/node.cjs +0 -11121
- 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/affects.d.cts +0 -47
- package/dist/types-cjs/boundaries.d.cts +0 -175
- package/dist/types-cjs/core/action.d.cts +0 -64
- package/dist/types-cjs/core/async.d.cts +0 -23
- package/dist/types-cjs/core/attribution-hooks.d.cts +0 -63
- package/dist/types-cjs/core/attribution.d.cts +0 -239
- package/dist/types-cjs/core/core.d.cts +0 -176
- package/dist/types-cjs/core/dev.d.cts +0 -95
- package/dist/types-cjs/core/effect.d.cts +0 -30
- package/dist/types-cjs/core/error.d.cts +0 -56
- package/dist/types-cjs/core/external.d.cts +0 -15
- package/dist/types-cjs/core/graph.d.cts +0 -28
- package/dist/types-cjs/core/heap.d.cts +0 -22
- package/dist/types-cjs/core/index.d.cts +0 -13
- package/dist/types-cjs/core/invariants.d.cts +0 -59
- package/dist/types-cjs/core/lanes.d.cts +0 -44
- package/dist/types-cjs/core/optimistic.d.cts +0 -6
- package/dist/types-cjs/core/owner.d.cts +0 -124
- package/dist/types-cjs/core/scheduler.d.cts +0 -231
- package/dist/types-cjs/core/types.d.cts +0 -204
- package/dist/types-cjs/core/verdict.d.cts +0 -2
- package/dist/types-cjs/index.d.cts +0 -10
- package/dist/types-cjs/map.d.cts +0 -69
- package/dist/types-cjs/package.json +0 -3
- package/dist/types-cjs/store/index.d.cts +0 -21
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -23
- 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/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -17
- package/dist/types-cjs/store/next/store.d.cts +0 -127
- package/dist/types-cjs/store/next/target.d.cts +0 -192
- package/dist/types-cjs/store/store.d.cts +0 -138
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -74
package/dist/types/core/dev.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type { Computed,
|
|
1
|
+
import { type AttributionHooks, type InteractionRef, type OriginRef } from "./attribution-hooks.js";
|
|
2
|
+
import type { Computed, Owner, Signal } from "./types.js";
|
|
3
3
|
export interface DevHooks {
|
|
4
4
|
onOwner?: (owner: Owner) => void;
|
|
5
5
|
onGraph?: (value: any, owner: Owner | null) => void;
|
|
@@ -13,11 +13,13 @@ export interface DevHooks {
|
|
|
13
13
|
* `warn`/`error` as failures unless they opt in to `info`.
|
|
14
14
|
*/
|
|
15
15
|
export type DiagnosticSeverity = "info" | "warn" | "error";
|
|
16
|
-
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "ACTION_CALLED_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "SETTLE_WALK_UNINITIALIZED_SOURCE" | "FLUSH_IN_EFFECT_CALLBACK" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "INVALID_REFRESH_TARGET" | "INVALID_AFFECTS_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION" | "HUGE_FAN_OUT" | "HUGE_FAN_IN" | "HOT_SCOPE_RERUNS" | "HOT_SCOPE_TIME" | "WIDE_SCOPE_DEPS" | "UNSTABLE_MEMO_OUTPUT" | "WIDE_WRITE" | "ASYNC_WATERFALL" | "HOT_SCOPE_FANOUT";
|
|
17
|
-
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner" | "error" | "perf" | "graph"
|
|
18
|
-
/**
|
|
16
|
+
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "ACTION_CALLED_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "SETTLE_WALK_UNINITIALIZED_SOURCE" | "FLUSH_IN_EFFECT_CALLBACK" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "INVALID_REFRESH_TARGET" | "INVALID_AFFECTS_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION" | "HUGE_FAN_OUT" | "HUGE_FAN_IN" | "HOT_SCOPE_RERUNS" | "HOT_SCOPE_TIME" | "WIDE_SCOPE_DEPS" | "UNSTABLE_MEMO_OUTPUT" | "WIDE_WRITE" | "ASYNC_WATERFALL" | "HOT_SCOPE_FANOUT" | "SILENT_HOLD" | "LONG_HOLD" | "EFFECT_WRITES_OWN_SOURCE" | "EFFECT_RELAY_TEAR" | "IMMUTABLE_UPDATE_IN_STORE" | "UNSTABLE_LIST_IDENTITY";
|
|
17
|
+
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner" | "error" | "perf" | "graph"
|
|
18
|
+
/** Perceived responsiveness: the runtime behaved correctly but the user saw no feedback. */
|
|
19
|
+
| "responsiveness";
|
|
20
|
+
/** First warning when a change reaches (or a pass tracks) this many edges. */
|
|
19
21
|
export declare const GRAPH_SIZE_WARN_AT = 2000;
|
|
20
|
-
/**
|
|
22
|
+
/** Re-warn once the count has grown by this much since the last warning. */
|
|
21
23
|
export declare const GRAPH_SIZE_WARN_EVERY = 500;
|
|
22
24
|
export interface DiagnosticEvent {
|
|
23
25
|
sequence: number;
|
|
@@ -28,6 +30,15 @@ export interface DiagnosticEvent {
|
|
|
28
30
|
ownerId?: string;
|
|
29
31
|
ownerName?: string;
|
|
30
32
|
nodeName?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Root-first chain of named owners enclosing the subject of the event —
|
|
35
|
+
* component roots as `<Name>`, computations by their `name` option (or
|
|
36
|
+
* the `effect`/`computed` default) — e.g. `["<App>", "<TodoRow>", "effect"]`.
|
|
37
|
+
* Unnamed owners (plain roots) are skipped. Absent when the subject has no
|
|
38
|
+
* named owner at all (a top-level scope, or an unowned primitive — which
|
|
39
|
+
* is usually the finding itself).
|
|
40
|
+
*/
|
|
41
|
+
ownerPath?: string[];
|
|
31
42
|
data?: Record<string, unknown>;
|
|
32
43
|
}
|
|
33
44
|
export type DiagnosticListener = (event: DiagnosticEvent) => void;
|
|
@@ -40,25 +51,109 @@ export interface Diagnostics {
|
|
|
40
51
|
subscribe(listener: DiagnosticListener): () => void;
|
|
41
52
|
capture(): DiagnosticCapture;
|
|
42
53
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
54
|
+
* Records an event on the channel from outside the reactive core — a host
|
|
55
|
+
* runtime reporting its own findings (hydration mismatches, server render
|
|
56
|
+
* faults) so consumers see one stream. `subject` locates it like the
|
|
57
|
+
* internal sites do; a host whose owners are not signals' owners passes
|
|
58
|
+
* `ownerPath` on the event instead and it is used as-is.
|
|
48
59
|
*/
|
|
49
|
-
|
|
60
|
+
emit(event: Omit<DiagnosticEvent, "sequence">, subject?: DiagnosticSubject | null): DiagnosticEvent;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The core's side of attribution: the hook slot an engine installs into, and
|
|
64
|
+
* the interaction frame the rendering runtime opens around event dispatch.
|
|
65
|
+
* The engine itself — "why did this run", costs, holds, feedback — is
|
|
66
|
+
* `@solidjs/signals/attribution`, a separate entry so an observe build pays
|
|
67
|
+
* for it only when something imports it.
|
|
68
|
+
*/
|
|
69
|
+
export interface AttributionSlot {
|
|
70
|
+
/**
|
|
71
|
+
* Installs `hooks` as the engine the core reports facts to (`null`
|
|
72
|
+
* uninstalls). One engine at a time; the built-in engine's `enable()` calls
|
|
73
|
+
* this, and an external consumer (devtools) may install its own instead.
|
|
74
|
+
*/
|
|
75
|
+
install(hooks: AttributionHooks | null): void;
|
|
76
|
+
/** The installed engine's hooks, or `null` when none is installed. */
|
|
77
|
+
readonly installed: AttributionHooks | null;
|
|
78
|
+
/**
|
|
79
|
+
* Run `fn` as a user interaction's handler: root writes inside stamp it as
|
|
80
|
+
* their origin, and actions/effects/flights it causes carry it. The web
|
|
81
|
+
* runtime wraps every event dispatch in this; custom renderers and test
|
|
82
|
+
* harnesses call it themselves. `fn()` when no engine is installed.
|
|
83
|
+
*/
|
|
84
|
+
withInteraction<T>(ref: InteractionRef, fn: () => T): T;
|
|
85
|
+
/**
|
|
86
|
+
* Run `fn` as a declared unit of work — a router's navigation, described
|
|
87
|
+
* by the parametrized route it matched: root writes inside are attributed
|
|
88
|
+
* to it (under the enclosing interaction, if any), so the hold behind the
|
|
89
|
+
* route's data, the re-runs and the verdicts carry the route's name. Any
|
|
90
|
+
* router calls this around its location write; nothing else is
|
|
91
|
+
* router-specific. `fn()` when no engine is installed.
|
|
92
|
+
*/
|
|
93
|
+
withOrigin<T>(ref: OriginRef, fn: () => T): T;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The observe tier: the structured channel and the attribution wiring —
|
|
97
|
+
* everything a production observability consumer needs, and nothing that
|
|
98
|
+
* assumes a developer at a console. Present in dev and observe builds
|
|
99
|
+
* (`__OBSERVE__`); `undefined` in prod.
|
|
100
|
+
*/
|
|
101
|
+
export interface Observe {
|
|
102
|
+
diagnostics: Diagnostics;
|
|
103
|
+
/** The attribution hook slot and interaction frame — see `AttributionSlot`. */
|
|
104
|
+
attribution: AttributionSlot;
|
|
105
|
+
/**
|
|
106
|
+
* The live node an emitted event was about, when the emitter knew it.
|
|
107
|
+
* Events are serializable records and never carry the node; consumers that
|
|
108
|
+
* run in-process (devtools, the console reporter) look it up here.
|
|
109
|
+
*/
|
|
110
|
+
subjectOf(event: DiagnosticEvent): DiagnosticSubject | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* Marks `owner`'s subtree as the observer's own. A consumer that renders
|
|
113
|
+
* inside the app it watches — an APM adapter's panel, devtools — would
|
|
114
|
+
* otherwise see its own effects, stores and holds reported as findings about
|
|
115
|
+
* the app. Under an excluded owner: diagnostics whose subject sits in the
|
|
116
|
+
* subtree are neither delivered nor reported (the entry is still built, so
|
|
117
|
+
* a site that throws its message still throws), and the attribution engine
|
|
118
|
+
* records no runs for its computations. Mark the root as it is created
|
|
119
|
+
* (`createRoot(() => { OBSERVE.exclude(getOwner()!); … })`) and perform
|
|
120
|
+
* writes from outside the graph under it (`runWithOwner`), so the writer's
|
|
121
|
+
* context is excluded too. Irrevocable for the owner's lifetime.
|
|
122
|
+
*/
|
|
123
|
+
exclude(owner: Owner): void;
|
|
124
|
+
/** Whether `subject` sits under an excluded owner (itself included). */
|
|
125
|
+
isExcluded(subject: DiagnosticSubject | null | undefined): boolean;
|
|
50
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* The dev tier: devtools hooks, graph traversal, and the console face of the
|
|
129
|
+
* diagnostics channel. Present only in dev builds (`__DEV__`).
|
|
130
|
+
*/
|
|
51
131
|
export interface Dev {
|
|
52
132
|
hooks: DevHooks;
|
|
53
|
-
diagnostics: Diagnostics;
|
|
54
|
-
/** "Why did this run" re-run attribution — see attribution.ts. */
|
|
55
|
-
attribution: Attribution;
|
|
56
133
|
getChildren: typeof getChildren;
|
|
57
134
|
getSignals: typeof getSignals;
|
|
58
135
|
getParent: typeof getParent;
|
|
59
136
|
getSources: typeof getSources;
|
|
60
137
|
getObservers: typeof getObservers;
|
|
138
|
+
/** Console face of an emitted event — see `reportDiagnostic`. */
|
|
139
|
+
report(entry: DiagnosticEvent): void;
|
|
140
|
+
/**
|
|
141
|
+
* Registers a console footer appended to the first console report of
|
|
142
|
+
* each diagnostic code — a discovery pointer to deeper guidance (e.g.
|
|
143
|
+
* solid-js registers its shipped repair skill). Reported events carry
|
|
144
|
+
* it as trailing lines of the same console entry; events that surface as
|
|
145
|
+
* a thrown error instead get it as a follow-up line. Returning undefined
|
|
146
|
+
* for an event suppresses the footer. Passing undefined unregisters and
|
|
147
|
+
* resets the once-per-code memory.
|
|
148
|
+
*/
|
|
149
|
+
setConsoleFooter(footer: ((event: DiagnosticEvent) => string | undefined) | undefined): void;
|
|
61
150
|
}
|
|
151
|
+
export declare const OBSERVE: Observe;
|
|
152
|
+
export declare function isExcluded(subject: DiagnosticSubject | null | undefined): boolean;
|
|
153
|
+
/** For engines that cache the verdict per node: is anything excluded at all? */
|
|
154
|
+
export declare function anyExcluded(): boolean;
|
|
155
|
+
/** Was `entry` built for an excluded subject? Once-per-key reporters must not spend their slot on it. */
|
|
156
|
+
export declare function isSuppressed(entry: DiagnosticEvent): boolean;
|
|
62
157
|
export declare const DEV: Dev;
|
|
63
158
|
/**
|
|
64
159
|
* Dev-mode internal consistency check. A failure means the reactive system
|
|
@@ -68,14 +163,51 @@ export declare const DEV: Dev;
|
|
|
68
163
|
* dev builds so user apps degrade instead of crashing.
|
|
69
164
|
*/
|
|
70
165
|
export declare function assertInvariant(condition: boolean, name: string, message: string): void;
|
|
71
|
-
|
|
166
|
+
/** Anything a diagnostic can be about: an owner (root, computed, effect) or a signal. */
|
|
167
|
+
export type DiagnosticSubject = Owner | Signal<any> | Computed<any>;
|
|
168
|
+
/**
|
|
169
|
+
* Root-first names of the owners enclosing `subject` (inclusive when the
|
|
170
|
+
* subject is itself a named owner). Signals hop to their registering owner
|
|
171
|
+
* (`_owner`, set by registerGraph). Unnamed owners are skipped so the path
|
|
172
|
+
* reads as the component tree plus the scope: `<App> › <TodoRow> › effect`.
|
|
173
|
+
*/
|
|
174
|
+
export declare function ownerPath(subject: DiagnosticSubject | null | undefined): string[] | undefined;
|
|
175
|
+
/**
|
|
176
|
+
* Records a diagnostic on the structured channel (listeners, captures) and
|
|
177
|
+
* returns the entry. `subject` locates it: the current reactive `context` by
|
|
178
|
+
* default (right for the synchronous rule checks — they fire inside the
|
|
179
|
+
* scope that misbehaved); pass the node for scheduler-time findings whose
|
|
180
|
+
* ambient context is the flush, or `null` for events that have no location
|
|
181
|
+
* by nature. An `ownerPath` already on the event wins over the subject walk
|
|
182
|
+
* (hosts whose owners are not signals' owners compute their own). Console
|
|
183
|
+
* output is a separate, dev-tier step — see `reportDiagnostic`.
|
|
184
|
+
*/
|
|
185
|
+
export declare function emitDiagnostic(event: Omit<DiagnosticEvent, "sequence">, subject?: DiagnosticSubject | null | undefined): DiagnosticEvent;
|
|
186
|
+
/**
|
|
187
|
+
* The console face of a diagnostic — ONE entry per finding: the message, the
|
|
188
|
+
* owner path (`in <App> › <TodoRow> › effect`) so a human can locate it, the
|
|
189
|
+
* once-per-code footer as trailing lines, and — when the subject is a
|
|
190
|
+
* binding effect the rendering runtime tagged — the element it writes, as a
|
|
191
|
+
* second console argument (hover highlights it, click jumps to Elements).
|
|
192
|
+
* Severity picks the console method. Call sites report the entry
|
|
193
|
+
* `emitDiagnostic` returned so the structured and console channels never
|
|
194
|
+
* disagree. Dev-tier: in an observe build this is a no-op, so wiring paths
|
|
195
|
+
* that both emit and report (graph-size warnings) reach the channel only —
|
|
196
|
+
* production observability never writes to the console.
|
|
197
|
+
*/
|
|
198
|
+
export declare function reportDiagnostic(entry: DiagnosticEvent): void;
|
|
72
199
|
/**
|
|
73
200
|
* Shared strict-read diagnostics for core read() and the store proxy traps.
|
|
74
201
|
* Single source for the message text — the #2897 safeguard parity between
|
|
75
202
|
* memos and stores is exactly these firing identically from both paths.
|
|
76
203
|
*/
|
|
77
|
-
export declare function throwPendingUntrackedRead(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence" | "data">>): never;
|
|
78
|
-
export declare function warnStrictReadUntracked(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence">>): void;
|
|
204
|
+
export declare function throwPendingUntrackedRead(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence" | "data" | "ownerPath">>): never;
|
|
205
|
+
export declare function warnStrictReadUntracked(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence" | "ownerPath">>): void;
|
|
206
|
+
/**
|
|
207
|
+
* Observe-tier: stamp a signal with its creating owner so `ownerPath` can
|
|
208
|
+
* locate signal subjects. The per-owner `_signals` list and the devtools
|
|
209
|
+
* `onGraph` hook are dev-tier — the observe build pays one property write.
|
|
210
|
+
*/
|
|
79
211
|
export declare function registerGraph(value: any, owner: Owner | null): void;
|
|
80
212
|
export declare function clearSignals(node: Owner): void;
|
|
81
213
|
export declare function getChildren(owner: Owner): Owner[];
|
|
@@ -84,12 +216,19 @@ export declare function getParent(owner: Owner): Owner | null;
|
|
|
84
216
|
export declare function getSources(computation: Computed<any>): (Signal<any> | Computed<any>)[];
|
|
85
217
|
export declare function getObservers(node: Signal<any> | Computed<any>): Computed<any>[];
|
|
86
218
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* fan-
|
|
90
|
-
*
|
|
91
|
-
*
|
|
219
|
+
* Observe-tier: a committed change on `node` is about to re-run `count`
|
|
220
|
+
* subscribers (the notify walk in `insertSubs` counted them as it went —
|
|
221
|
+
* fan-out costs exactly one local increment in a loop that already visits
|
|
222
|
+
* every edge, and nothing at link time). Fires from GRAPH_SIZE_WARN_AT up,
|
|
223
|
+
* on the write rather than the link: a fan-out that is never written costs
|
|
224
|
+
* nothing, and one that is re-runs every subscriber this flush. Always-on
|
|
225
|
+
* wherever the channel exists — unlike the opt-in attribution engine, a
|
|
226
|
+
* graph-size pathology should surface without asking.
|
|
227
|
+
*/
|
|
228
|
+
export declare function noteFanOut(node: Signal<any> | Computed<any>, count: number): void;
|
|
229
|
+
/**
|
|
230
|
+
* Observe-tier: a recompute pass of `node` tracked `count` distinct sources
|
|
231
|
+
* (its trimmed dep list, walked once at the end of the pass — see recompute;
|
|
232
|
+
* no per-link work, no pass bracket). Fires from GRAPH_SIZE_WARN_AT up.
|
|
92
233
|
*/
|
|
93
|
-
export declare function
|
|
94
|
-
/** DEV-only: drop live edge counts when a link is removed. */
|
|
95
|
-
export declare function unnoteGraphLink(link: Link): void;
|
|
234
|
+
export declare function noteFanIn(node: Computed<any>, count: number): void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Transition } from "./scheduler.js";
|
|
1
2
|
import type { Computed, NodeOptions, Owner } from "./types.js";
|
|
2
3
|
export interface Effect<T> extends Computed<T>, Owner {
|
|
3
4
|
_effectFn: (val: T, prev: T | undefined) => void | (() => void);
|
|
@@ -5,7 +6,13 @@ export interface Effect<T> extends Computed<T>, Owner {
|
|
|
5
6
|
_modified: boolean;
|
|
6
7
|
_prevValue: T | undefined;
|
|
7
8
|
_type: number;
|
|
8
|
-
_boundRunEffect?: () => void;
|
|
9
|
+
_boundRunEffect?: (type: number) => void;
|
|
10
|
+
/** The transaction whose staged view produced `_value` (null = committed
|
|
11
|
+
* view). Effects have one value slot and do not entangle transactions, so
|
|
12
|
+
* a second transaction recomputing the same effect overwrites a value the
|
|
13
|
+
* first one still owes a run for; see the contested-effect arm of recompute
|
|
14
|
+
* (#3322). */
|
|
15
|
+
_valueTransition: Transition | null;
|
|
9
16
|
}
|
|
10
17
|
/**
|
|
11
18
|
* Effects are the leaf nodes of our reactive graph. When their sources change, they are
|
|
@@ -2,9 +2,11 @@ import type { Computed } from "./types.js";
|
|
|
2
2
|
/** The queue a node belongs to, picked from its own zombie flag. */
|
|
3
3
|
export declare function queueFor(n: Computed<any>): Heap;
|
|
4
4
|
/**
|
|
5
|
-
* Schedule one subscriber to re-run on the next flush:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Schedule one subscriber to re-run on the next flush: inserted into its own
|
|
6
|
+
* (zombie-flag-routed) heap with the `_min` cursor pulled down. Tracked
|
|
7
|
+
* effects ride the heap too — the heap visit is their (empty) compute phase,
|
|
8
|
+
* which hands the callback to the user queue once the pass has committed
|
|
9
|
+
* (see GlobalQueue._update, #3291).
|
|
8
10
|
*/
|
|
9
11
|
export declare function enqueueSub(node: Computed<any>): void;
|
|
10
12
|
export interface Heap {
|
|
@@ -9,5 +9,6 @@ export type { Computed, Disposable, FirewallSignal, Link, Owner, Root, Signal, N
|
|
|
9
9
|
export { effect, trackedEffect, type Effect, type TrackedEffect } from "./effect.js";
|
|
10
10
|
export { action } from "./action.js";
|
|
11
11
|
export { flush, Queue, GlobalQueue, enforceLoadingBoundary, resetErrorHalt, type IQueue, type QueueCallback } from "./scheduler.js";
|
|
12
|
-
export
|
|
12
|
+
export type { AttributionHooks, InteractionRef, NavigationRef, OriginRef } from "./attribution-hooks.js";
|
|
13
|
+
export { DEV, OBSERVE, type AttributionSlot, type Dev, type Observe, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type DiagnosticListener, type Diagnostics, type DiagnosticSeverity, type DiagnosticSubject } from "./dev.js";
|
|
13
14
|
export * from "./constants.js";
|
|
@@ -2,7 +2,7 @@ import type { OptimisticLane } from "./lanes.js";
|
|
|
2
2
|
import type { Computed, Signal } from "./types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Test-mode invariant checks for the async/transition/lane machinery.
|
|
5
|
-
* Catalog and rationale: packages/signals/INTERNALS-ASYNC-STATE.md.
|
|
5
|
+
* Catalog and rationale: packages/signals/docs/INTERNALS-ASYNC-STATE.md.
|
|
6
6
|
*
|
|
7
7
|
* These are implementation self-consistency checks, not semantic rules: a
|
|
8
8
|
* violation means the reactive system contradicted itself.
|
|
@@ -24,6 +24,23 @@ export declare function getOrCreateLane(signal: Signal<any>): OptimisticLane;
|
|
|
24
24
|
* Union-find: find the root lane.
|
|
25
25
|
*/
|
|
26
26
|
export declare function findLane(lane: OptimisticLane): OptimisticLane;
|
|
27
|
+
/**
|
|
28
|
+
* Is the lane held? `_pendingAsync` records the async the lane OWNS (derived
|
|
29
|
+
* under it); a transaction's reporter map records the async a render effect
|
|
30
|
+
* OBSERVED pending with no boundary taking it (INV-3, the one registration
|
|
31
|
+
* site). A hold needs both — the same rule the transaction itself uses, so a
|
|
32
|
+
* memo nobody renders, or one a fallback-showing boundary caught, cannot tear
|
|
33
|
+
* a frame and holds nothing (#3289). An orphan lane has no observation record
|
|
34
|
+
* and never holds.
|
|
35
|
+
*
|
|
36
|
+
* The observation is looked up per NODE, in whichever live transaction
|
|
37
|
+
* recorded it — not in this lane's transaction. Lanes merge across
|
|
38
|
+
* transactions (#2912: ownership never travels through lanes), so after a
|
|
39
|
+
* merge the root's transaction holds the observations of only one member;
|
|
40
|
+
* the async the other member's transaction observed must hold the merged
|
|
41
|
+
* reveal just the same (A15 for lanes, #3335).
|
|
42
|
+
*/
|
|
43
|
+
export declare function laneHeld(lane: OptimisticLane): boolean;
|
|
27
44
|
/**
|
|
28
45
|
* Merge two lanes when their dependency graphs overlap.
|
|
29
46
|
*/
|
|
@@ -8,8 +8,17 @@ export declare const zombieQueue: Heap;
|
|
|
8
8
|
export declare let clock: number;
|
|
9
9
|
export declare let activeTransition: Transition | null;
|
|
10
10
|
export declare let projectionWriteActive: boolean;
|
|
11
|
+
/** > 0 while an action's generator body is on the stack (the synchronous
|
|
12
|
+
* slice between yields). Maintained by action.ts around `it.next()`. */
|
|
13
|
+
export declare let actionStepDepth: number;
|
|
14
|
+
export declare function enterActionStep(): void;
|
|
15
|
+
export declare function exitActionStep(): void;
|
|
11
16
|
export declare let _hitUnhandledAsync: boolean;
|
|
12
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Consume the unhandled-async hit. Returns whether this is the first report
|
|
19
|
+
* of the current enforcement window — the caller warns only then.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resetUnhandledAsync(): boolean;
|
|
13
22
|
/**
|
|
14
23
|
* Toggles the dev-mode "must be inside a `<Loading>` boundary" enforcement
|
|
15
24
|
* window. Only `render()` calls this — wrapping the initial mount so that a
|
|
@@ -39,6 +48,11 @@ export interface Transition {
|
|
|
39
48
|
_queueStash: QueueStub;
|
|
40
49
|
_done: boolean | Transition;
|
|
41
50
|
_gatedSubs: Set<Computed<any>>;
|
|
51
|
+
/** Effects whose single value slot was written under this transaction AND
|
|
52
|
+
* another live one (#3322). Re-dirtied at commit, ahead of the effect
|
|
53
|
+
* phase, so the run publishes a value derived from the committed world
|
|
54
|
+
* rather than whichever transaction's staged view wrote last. */
|
|
55
|
+
_contested: Computed<any>[] | null;
|
|
42
56
|
}
|
|
43
57
|
/**
|
|
44
58
|
* Flip-entanglement (#3164 follow-up): `until()` is a declaration of
|
|
@@ -127,14 +141,40 @@ export declare class GlobalQueue extends Queue {
|
|
|
127
141
|
static _drainPatchOptimistic: (() => void) | null;
|
|
128
142
|
static _gatedRead: ((el: Signal<any>, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
|
|
129
143
|
static _laneSuspends: ((owner: OptimisticNode) => boolean) | null;
|
|
144
|
+
/** Is the node routed through a LIVE lane (`resolveLane`)? read()'s reveal
|
|
145
|
+
* carve-out asks before showing a foreign-held pending node's committed
|
|
146
|
+
* value: a lane-derived flight's inputs are already revealed through the
|
|
147
|
+
* lane (#3334). Gated on CONFIG_HAS_LANE, which only the engine sets. */
|
|
148
|
+
static _laneLive: ((el: Computed<any>) => boolean) | null;
|
|
130
149
|
static _laneReadsCommitted: ((el: OptimisticNode, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
|
|
131
150
|
static _recomputeLane: ((el: Computed<any>, own: boolean) => OptimisticLane | null | false) | null;
|
|
132
151
|
static _laneAsyncPending: ((el: Computed<any>) => void) | null;
|
|
133
|
-
/** Authoritative-view reader wakeup
|
|
134
|
-
* Call sites are gated by CONFIG_AUTHORITATIVE_OBSERVED, which
|
|
135
|
-
* carve-out read can set, so `!` invocations are safe once
|
|
152
|
+
/** Authoritative-view reader wakeup: installed by until() and refresh() before
|
|
153
|
+
* their first read. Call sites are gated by CONFIG_AUTHORITATIVE_OBSERVED, which
|
|
154
|
+
* only such a reader's carve-out read can set, so `!` invocations are safe once
|
|
155
|
+
* the gate holds (#3303). */
|
|
136
156
|
static _notifyAuthoritativeObservers: ((el: Signal<any> | Computed<any>) => void) | null;
|
|
137
157
|
static _laneAsyncSettled: ((el: Computed<any>) => void) | null;
|
|
158
|
+
/** A18 supersession (#3331): own-source truth `value` landed under an active
|
|
159
|
+
* override. The engine decides whether the graph re-derives — the value
|
|
160
|
+
* differs from the override and is not a stale (older-action) answer (mark
|
|
161
|
+
* the node, demote its lane cascade, notify), or returns to it after an
|
|
162
|
+
* earlier differing arrival (clear the mark, notify) — and owns the
|
|
163
|
+
* authoritative-observer wake for a silent confirm. Installed with the
|
|
164
|
+
* optimistic engine; only reachable on a node that has an override. */
|
|
165
|
+
static _supersedeOverride: ((el: Signal<any> | Computed<any>, value: unknown) => void) | null;
|
|
166
|
+
/** read()'s value for a TRACKED reader of a superseded node (#3331): the
|
|
167
|
+
* staged truth, unless the reader is a stale (render) reader of another
|
|
168
|
+
* transaction — then the displayed override, as it keeps a foreign
|
|
169
|
+
* transaction's committed value over its staged write. */
|
|
170
|
+
static _supersededRead: ((el: Signal<any> | Computed<any>) => unknown) | null;
|
|
171
|
+
/** setSignal's authoritative (projection-write) landing on an override-
|
|
172
|
+
* covered node (#3331 store twin): stage the truth for its transaction's
|
|
173
|
+
* commit whatever its relation to the committed value — a landing equal to
|
|
174
|
+
* committed still differs from the override — then _supersedeOverride
|
|
175
|
+
* decides. Installed with the optimistic engine; only reachable on a node
|
|
176
|
+
* that has an override. */
|
|
177
|
+
static _landOnOverride: (<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)) => T) | null;
|
|
138
178
|
static _trackOptimisticStore: ((store: any) => void) | null;
|
|
139
179
|
flush(): void;
|
|
140
180
|
notify(node: Computed<any>, mask: number, flags: number, error?: any): boolean;
|
|
@@ -149,6 +189,21 @@ export declare let reaskArmed: boolean;
|
|
|
149
189
|
export declare let notifyEpoch: number;
|
|
150
190
|
export declare function bumpNotifyEpoch(): void;
|
|
151
191
|
export declare function armReaskClear(): void;
|
|
192
|
+
/** Provenance of the work currently running (A18 supersession, #3331): the
|
|
193
|
+
* invocation sequence of the action whose ambient window this is — set by
|
|
194
|
+
* action() for each slice; the flush that ends the window clears it — or,
|
|
195
|
+
* inside an async landing, the sequence captured when that flight was
|
|
196
|
+
* registered (asyncWrite sets it for the landing's synchronous propagation,
|
|
197
|
+
* so a sync recompute downstream of the landing — an optimistic wrapper over
|
|
198
|
+
* the async source — derives under the flight's provenance, and flights it
|
|
199
|
+
* registers inherit it). 0 is mainline: no action, always the current
|
|
200
|
+
* question. An override stamps this at its write (`_overrideStamp`); an
|
|
201
|
+
* answer whose flight an OLDER action issued is a stale question the user
|
|
202
|
+
* has since changed — it holds silently to commit instead of superseding. A
|
|
203
|
+
* slow source must not leak back in over a newer intent. Transactions merge,
|
|
204
|
+
* so the transition object cannot say WHICH action asked; this can. */
|
|
205
|
+
export declare let origin: number;
|
|
206
|
+
export declare function setOrigin(seq: number): number;
|
|
152
207
|
export declare function insertSubs(node: Signal<any> | Computed<any>, optimistic?: boolean): void;
|
|
153
208
|
export declare let storeCommitHook: (() => void) | null;
|
|
154
209
|
export declare function setStoreCommitHook(fn: () => void): void;
|
|
@@ -215,6 +270,16 @@ export declare function flush<T>(fn: () => T): T;
|
|
|
215
270
|
* initTransition; it is a plain batch until then. */
|
|
216
271
|
export declare function createTransition(): Transition;
|
|
217
272
|
export declare function currentTransition(transition: Transition): Transition;
|
|
273
|
+
/**
|
|
274
|
+
* The live transition blocked on `source` — the one whose render reader
|
|
275
|
+
* observed it pending (INV-3 records the observation in whichever transaction
|
|
276
|
+
* was active when the reader was notified). The observation is a fact about
|
|
277
|
+
* the node, so a hold check must not assume it was recorded in the transaction
|
|
278
|
+
* it happens to hold — lanes merge across transactions (#2912), and a merged
|
|
279
|
+
* root's transaction knows nothing of the async its members' transactions
|
|
280
|
+
* observed (#3335). Null when nobody is waiting.
|
|
281
|
+
*/
|
|
282
|
+
export declare function waitingTransition(source: Computed<any>): Transition | null;
|
|
218
283
|
export declare function setActiveTransition(transition: Transition | null): void;
|
|
219
284
|
export declare function runInTransition<T>(transition: Transition, fn: () => T): T;
|
|
220
285
|
/** Run `fn` with `transition` as BOTH the ambient transaction and the
|
|
@@ -68,6 +68,16 @@ export interface NodeExtension {
|
|
|
68
68
|
* layer's STORE_OPTIMISTIC_OWNERS stamps (#2899). `null` = ambient write.
|
|
69
69
|
*/
|
|
70
70
|
_overrideOwner: Transition | null | undefined;
|
|
71
|
+
/** `clock` at the active override's write. A sync recompute in the same
|
|
72
|
+
* tick derives from inputs that predate the override and does not
|
|
73
|
+
* supersede it (A18 supersession ordering, #3331). */
|
|
74
|
+
_overrideTime: number;
|
|
75
|
+
/** Provenance of the active override's write: the scheduler's `origin` (the
|
|
76
|
+
* asking action's invocation sequence; 0 = mainline). An arriving answer
|
|
77
|
+
* whose flight an older action issued asked a question the override has
|
|
78
|
+
* since changed: it holds to commit instead of superseding (A18
|
|
79
|
+
* supersession provenance, #3331). */
|
|
80
|
+
_overrideStamp: number;
|
|
71
81
|
_optimisticLane: OptimisticLane | undefined;
|
|
72
82
|
_pendingSignal: Signal<boolean> | undefined;
|
|
73
83
|
_latestValueComputed: Computed<any> | undefined;
|
|
@@ -112,13 +122,19 @@ export interface NodeExtension {
|
|
|
112
122
|
export interface RawSignal<T> {
|
|
113
123
|
_subs: Link | null;
|
|
114
124
|
_subsTail: Link | null;
|
|
125
|
+
_value: T;
|
|
115
126
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
127
|
+
* Observe-tier label (`name` option, or the node kind: `signal`,
|
|
128
|
+
* `computed`, `effect`…). A slot in the observe/dev literals — never a
|
|
129
|
+
* post-construction write — and absent from the prod literals entirely.
|
|
118
130
|
*/
|
|
119
|
-
_subCount?: number;
|
|
120
|
-
_value: T;
|
|
121
131
|
_name?: string;
|
|
132
|
+
/**
|
|
133
|
+
* Observe-tier: the owner in scope when a user-facing signal was created
|
|
134
|
+
* (`registerGraph`), so diagnostics about the signal get an owner path.
|
|
135
|
+
* A slot in the observe/dev `signal()` literal; absent from prod.
|
|
136
|
+
*/
|
|
137
|
+
_owner?: Owner | null;
|
|
122
138
|
_equals: false | ((a: T, b: T) => boolean);
|
|
123
139
|
_config: number;
|
|
124
140
|
_time: number;
|
|
@@ -137,7 +153,10 @@ export interface RawSignal<T> {
|
|
|
137
153
|
}
|
|
138
154
|
export interface FirewallSignal<T> extends RawSignal<T> {
|
|
139
155
|
_firewall: Computed<any>;
|
|
156
|
+
/** Doubly-linked child chain on the firewall's extension (`_x._child` is
|
|
157
|
+
* the head): released leaves unlink in O(1) (#3351). */
|
|
140
158
|
_nextChild: FirewallSignal<unknown> | null;
|
|
159
|
+
_prevChild: FirewallSignal<unknown> | null;
|
|
141
160
|
}
|
|
142
161
|
export type Signal<T> = RawSignal<T> | FirewallSignal<T>;
|
|
143
162
|
export interface Owner {
|
|
@@ -156,15 +175,16 @@ export interface Owner {
|
|
|
156
175
|
_prevSibling: Owner | null;
|
|
157
176
|
/** Cold extension — see NodeExtension (owners use the zombie-pair slots). */
|
|
158
177
|
_x: NodeExtension | null;
|
|
178
|
+
/**
|
|
179
|
+
* Observe-tier label: the `name` option, the node kind (`computed`,
|
|
180
|
+
* `effect`…), or the component label the rendering layer writes on a root
|
|
181
|
+
* (`<App>`). A slot in the observe/dev literals; absent from prod.
|
|
182
|
+
*/
|
|
183
|
+
_name?: string;
|
|
159
184
|
}
|
|
160
185
|
export interface Computed<T> extends RawSignal<T>, Owner {
|
|
161
186
|
_deps: Link | null;
|
|
162
187
|
_depsTail: Link | null;
|
|
163
|
-
/**
|
|
164
|
-
* DEV-only live source count. Maintained by `link`/`unlinkSubs` for
|
|
165
|
-
* graph-size diagnostics; undefined in production.
|
|
166
|
-
*/
|
|
167
|
-
_depCount?: number;
|
|
168
188
|
/** Recompute-pass counter; bumped when dep revalidation starts. */
|
|
169
189
|
_depGen: number;
|
|
170
190
|
_flags: number;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
export { $REFRESH, ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError, action, createContext, createOwner, createRoot, runWithOwner, flush, getNextChildId, peekNextChildId, getContext, setContext, getOwner, isDisposed, getObserver, isEqual, untrack, isPending, latest, SUPPORTS_PROXY, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots, enforceLoadingBoundary, enableExternalSource, resetErrorHalt } from "./core/index.js";
|
|
2
|
-
import { type Dev } from "./core/index.js";
|
|
2
|
+
import { type Dev, type Observe } from "./core/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Observe tier (diagnostics channel, attribution hook slot + interaction
|
|
5
|
+
* frame): dev and observe builds. The attribution engine itself is the
|
|
6
|
+
* `@solidjs/signals/attribution` entry.
|
|
7
|
+
*/
|
|
8
|
+
export declare const OBSERVE: Observe | undefined;
|
|
9
|
+
/** Dev tier (devtools hooks, graph traversal, console reporting): dev builds only. */
|
|
3
10
|
export declare const DEV: Dev | undefined;
|
|
4
|
-
export type { Owner, Context, ContextRecord, IQueue, ExternalSourceFactory, ExternalSource, ExternalSourceConfig, Refreshable, Dev, DevHooks, DiagnosticCapture, DiagnosticCode, DiagnosticEvent, DiagnosticKind, Diagnostics, DiagnosticSeverity } from "./core/index.js";
|
|
11
|
+
export type { Owner, Context, ContextRecord, IQueue, ExternalSourceFactory, ExternalSource, ExternalSourceConfig, Refreshable, AttributionHooks, AttributionSlot, InteractionRef, NavigationRef, OriginRef, Dev, Observe, DevHooks, DiagnosticCapture, DiagnosticCode, DiagnosticEvent, DiagnosticKind, DiagnosticListener, Diagnostics, DiagnosticSeverity, DiagnosticSubject } from "./core/index.js";
|
|
5
12
|
export { createSignal, createMemo, createEffect, createRenderEffect, createTrackedEffect, createReaction, createOptimistic, refresh, resolve, until, onSettled, onCleanup } from "./signals.js";
|
|
6
13
|
export type { Truthy, UntilOptions, Accessor, SourceAccessor, Setter, Signal, ComputeFunction, EffectFunction, EffectBundle, EffectOptions, SignalOptions, MemoOptions, NoInfer } from "./signals.js";
|
|
7
14
|
export { affects } from "./affects.js";
|
package/dist/types/map.d.ts
CHANGED
|
@@ -47,6 +47,8 @@ export declare function mapArray<Item, MappedItem>(list: Accessor<Maybe<readonly
|
|
|
47
47
|
fallback?: Accessor<any>;
|
|
48
48
|
name?: string;
|
|
49
49
|
}): Accessor<MappedItem[]>;
|
|
50
|
+
/** @internal */
|
|
51
|
+
export declare function __smallMoveHits(): number;
|
|
50
52
|
/**
|
|
51
53
|
* Reactively renders a callback `count` times, reusing previously-rendered
|
|
52
54
|
* entries when only the count changes. Underlying helper for `<Repeat>`.
|
package/dist/types/signals.d.ts
CHANGED
|
@@ -399,6 +399,16 @@ export declare function createRenderEffect<T>(compute: ComputeFunction<undefined
|
|
|
399
399
|
* Creates a tracked reactive effect where dependency tracking and side effects happen
|
|
400
400
|
* in the same scope.
|
|
401
401
|
*
|
|
402
|
+
* @deprecated Do not use in new code. For a side effect that follows reactive
|
|
403
|
+
* state, use `createEffect(compute, effect)` — it separates tracking from the
|
|
404
|
+
* side effect, knows its dependencies before it runs, and participates in
|
|
405
|
+
* async and transitions. For one-time DOM work after render (measuring,
|
|
406
|
+
* attaching third-party widgets to a ref), use `onSettled`. Tracking from
|
|
407
|
+
* inside the effect phase — the only thing this primitive adds — is retained
|
|
408
|
+
* solely to ease 1.x migration: it runs beside user-effect callbacks after
|
|
409
|
+
* values commit, never holds a transition, and cannot observe a write staged
|
|
410
|
+
* earlier in the same flush by a signal it has not read yet.
|
|
411
|
+
*
|
|
402
412
|
* WARNING: Because tracking and effects happen in the same scope, this primitive
|
|
403
413
|
* may run multiple times for a single change or show tearing (reading inconsistent
|
|
404
414
|
* state). Use only when dynamic subscription patterns require same-scope tracking.
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
export type { Store, StoreReturn, ProjectionStoreReturn, StoreSetter, StoreNode, StoreOptions, ProjectionOptions, NotWrappable, SolidStore } from "./store.js";
|
|
2
2
|
export type { Merge, Omit } from "./utils.js";
|
|
3
3
|
export { isWrappable, $TRACK, $PROXY, $TARGET } from "./store.js";
|
|
4
|
+
export { mergeSources } from "./utils.js";
|
|
4
5
|
import type { NoFn, ProjectionOptions, Store, StoreOptions, StoreSetter } from "./store.js";
|
|
5
6
|
import type { Refreshable } from "../core/index.js";
|
|
6
7
|
export { createProjectionNext as createProjection } from "./next/projection.js";
|
|
7
|
-
export { registerPatch, registerRowOps, registerSlotPatchNext as registerSlotPatch, patchableRaw } from "./next/patch.js";
|
|
8
8
|
export { storeIsShallow, storeHasFamily, storeHasOptimisticFamily } from "./next/store.js";
|
|
9
9
|
export { createOptimisticStoreNext as createOptimisticStore } from "./next/optimistic.js";
|
|
10
|
-
/** Public createStore: plain form `(
|
|
10
|
+
/** Public createStore: plain form `(initialValue, options?)` and derived writable
|
|
11
11
|
* form `(fn, seed, options?)`. */
|
|
12
|
-
export declare function createStore<T extends object = {}>(
|
|
13
|
-
|
|
14
|
-
}): [get: Store<T>, set: StoreSetter<T>];
|
|
15
|
-
export declare function createStore<T extends object = {}>(fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, store: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
|
|
12
|
+
export declare function createStore<T extends object = {}>(initialValue: NoFn<T> | Store<NoFn<T>>, options?: StoreOptions): [get: Store<T>, set: StoreSetter<T>];
|
|
13
|
+
export declare function createStore<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
|
|
16
14
|
export declare function reconcile<T extends U, U>(value: T, key?: string | ((item: NonNullable<any>) => any) | null): (state: U) => T;
|
|
17
15
|
export declare function snapshot<T>(value: T): T;
|
|
18
16
|
export declare function deep<T>(value: T): T;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type Refreshable } from "../../core/index.js";
|
|
1
2
|
import { type Transition } from "../../core/scheduler.js";
|
|
2
|
-
import { type NoFn, type ProjectionOptions, type Store, type StoreSetter } from "../store.js";
|
|
3
|
+
import { type NoFn, type ProjectionOptions, type Store, type StoreOptions, type StoreSetter } from "../store.js";
|
|
3
4
|
import type { StoreNextTarget } from "./target.js";
|
|
4
5
|
/** #3164 fold: a stamped truth is HELD (masked from ordinary readers until
|
|
5
6
|
* the reveal) only while its transition is live AND retaining optimism —
|
|
@@ -8,7 +9,8 @@ import type { StoreNextTarget } from "./target.js";
|
|
|
8
9
|
* staged values to converge (normal speculation). Resolves merges first:
|
|
9
10
|
* merge unions optimistic nodes/stores into the target. */
|
|
10
11
|
export declare function transitionHoldsOptimism(transition: Transition): boolean;
|
|
11
|
-
export declare function createOptimisticStoreNext<T extends object = {}>(
|
|
12
|
+
export declare function createOptimisticStoreNext<T extends object = {}>(initialValue: NoFn<T> | Store<NoFn<T>>, options?: StoreOptions): [get: Store<T>, set: StoreSetter<T>];
|
|
13
|
+
export declare function createOptimisticStoreNext<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
|
|
12
14
|
/** Diff the draft against the current OPTIMISTIC VIEW (committed + active
|
|
13
15
|
* overrides — the same view the draft was seeded from) and emit engine writes
|
|
14
16
|
* for exactly the changed keys. Visible-view diffing keeps no-op writes from
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import type { RowOps } from "./patch.js";
|
|
2
|
-
import { type StoreNextTarget } from "./target.js";
|
|
3
1
|
type KeyFn = (item: any) => any;
|
|
4
2
|
export declare function reconcileNextState(value: any, state: any, key: string | KeyFn | null | undefined, replace?: boolean): void;
|
|
3
|
+
/** Setter-channel row ops (the fold site calls this for array targets with
|
|
4
|
+
* ops consumers): structural mutation through the setter — push/splice/index
|
|
5
5
|
/** Key equality for EVERY key comparison in this module (re-audit 2, P1-5):
|
|
6
|
-
* SameValueZero, matching the Map-based
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* row ops MUST agree on key equality or retained DOM rows go stale. */
|
|
6
|
+
* SameValueZero, matching the adoption window's Map-based matcher — NaN keys
|
|
7
|
+
* are equal to themselves, so aligned NaN rows stay aligned in the prefix
|
|
8
|
+
* walk instead of forever misaligning. */
|
|
10
9
|
export declare function sameKey(a: any, b: any): boolean;
|
|
11
|
-
export declare function emitSetterRowOps(t: StoreNextTarget, prevRows: any[], nextRows: any[]): void;
|
|
12
|
-
/** Identity-keyed structural diff, returned rather than emitted: shared by
|
|
13
|
-
* the setter channel (regular queue) and the OPTIMISTIC write channel (lane
|
|
14
|
-
* queue) — same retention semantics, different dispatch timing. Returns
|
|
15
|
-
* null when the lists are identity-aligned (no structure changed). */
|
|
16
|
-
export declare function buildIdentityRowOps(prevRows: any[], nextRows: any[]): RowOps | null;
|
|
17
10
|
export {};
|