@solidjs/signals 2.0.0-rc.0 → 2.0.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/dev-shared.js +7138 -0
- package/dist/dev.attribution.js +3307 -0
- package/dist/dev.js +8076 -6692
- package/dist/observe/affects.js +129 -0
- package/dist/observe/attribution.js +7 -0
- package/dist/observe/boundaries.js +793 -0
- package/dist/observe/core/action.js +177 -0
- package/dist/observe/core/async.js +849 -0
- package/dist/observe/core/attribution-costs.js +66 -0
- package/dist/observe/core/attribution-feedback.js +280 -0
- package/dist/observe/core/attribution-hooks.js +83 -0
- package/dist/observe/core/attribution-queries.js +43 -0
- package/dist/observe/core/attribution.js +2904 -0
- package/dist/observe/core/constants.js +283 -0
- package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
- package/dist/observe/core/core.js +1999 -0
- package/dist/observe/core/dev.js +343 -0
- package/dist/observe/core/effect.js +200 -0
- package/dist/observe/core/error-hooks.js +71 -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 +45 -0
- package/dist/observe/core/lanes.js +205 -0
- package/dist/observe/core/optimistic.js +627 -0
- package/dist/observe/core/owner.js +353 -0
- package/dist/observe/core/scheduler.js +1547 -0
- package/dist/observe/core/verdict.js +674 -0
- package/dist/observe/index.js +59 -0
- package/dist/observe/map.js +484 -0
- package/dist/observe/signals.js +731 -0
- package/dist/observe/store/index.js +44 -0
- package/dist/observe/store/next/optimistic.js +717 -0
- package/dist/observe/store/next/projection.js +266 -0
- package/dist/observe/store/next/reconcile.js +375 -0
- package/dist/observe/store/next/store.js +2480 -0
- package/dist/observe/store/next/target.js +51 -0
- package/dist/observe/store/store.js +331 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/utils.js +1070 -0
- package/dist/prod/affects.js +10 -9
- package/dist/prod/attribution.js +45 -0
- package/dist/prod/boundaries.js +388 -178
- package/dist/prod/core/action.js +65 -37
- package/dist/prod/core/async.js +477 -208
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +186 -1
- package/dist/prod/core/context.js +10 -16
- package/dist/prod/core/core.js +1556 -415
- package/dist/prod/core/dev.js +18 -1
- package/dist/prod/core/effect.js +119 -79
- package/dist/prod/core/error-hooks.js +71 -0
- package/dist/prod/core/error.js +13 -1
- package/dist/prod/core/external.js +4 -4
- package/dist/prod/core/graph.js +105 -54
- package/dist/prod/core/heap.js +72 -65
- package/dist/prod/core/invariants.js +3 -2
- package/dist/prod/core/lanes.js +117 -52
- package/dist/prod/core/optimistic.js +474 -103
- package/dist/prod/core/owner.js +131 -84
- package/dist/prod/core/scheduler.js +1013 -248
- package/dist/prod/core/verdict.js +418 -113
- package/dist/prod/index.js +25 -13
- package/dist/prod/map.js +314 -151
- package/dist/prod/signals.js +382 -32
- package/dist/prod/store/index.js +38 -0
- package/dist/prod/store/next/optimistic.js +710 -0
- package/dist/prod/store/next/projection.js +257 -0
- package/dist/prod/store/next/reconcile.js +373 -0
- package/dist/prod/store/next/store.js +2356 -0
- package/dist/prod/store/next/target.js +51 -0
- package/dist/prod/store/store.js +129 -881
- package/dist/prod/store/utils.js +982 -242
- package/dist/types/attribution.d.ts +19 -0
- package/dist/types/attribution.prod.d.ts +22 -0
- package/dist/types/boundaries.d.ts +78 -5
- package/dist/types/core/action.d.ts +12 -5
- package/dist/types/core/async.d.ts +3 -1
- package/dist/types/core/attribution-costs.d.ts +35 -0
- package/dist/types/core/attribution-feedback.d.ts +133 -0
- package/dist/types/core/attribution-hooks.d.ts +304 -0
- package/dist/types/core/attribution-queries.d.ts +24 -0
- package/dist/types/core/attribution.d.ts +892 -0
- package/dist/types/core/constants.d.ts +179 -0
- package/dist/types/core/core.d.ts +305 -23
- package/dist/types/core/dev.d.ts +421 -8
- package/dist/types/core/effect.d.ts +8 -1
- package/dist/types/core/error-hooks.d.ts +71 -0
- package/dist/types/core/error.d.ts +9 -0
- package/dist/types/core/graph.d.ts +23 -0
- package/dist/types/core/heap.d.ts +5 -3
- package/dist/types/core/index.d.ts +6 -3
- package/dist/types/core/invariants.d.ts +5 -1
- package/dist/types/core/lanes.d.ts +51 -19
- package/dist/types/core/owner.d.ts +15 -3
- package/dist/types/core/scheduler.d.ts +252 -3
- package/dist/types/core/types.d.ts +124 -41
- package/dist/types/index.d.ts +18 -5
- package/dist/types/map.d.ts +2 -0
- package/dist/types/signals.d.ts +164 -13
- package/dist/types/store/index.d.ts +16 -5
- package/dist/types/store/next/optimistic.d.ts +25 -0
- package/dist/types/store/next/projection.d.ts +27 -0
- package/dist/types/store/next/reconcile.d.ts +10 -0
- package/dist/types/store/next/store.d.ts +143 -0
- package/dist/types/store/next/target.d.ts +196 -0
- package/dist/types/store/store.d.ts +46 -112
- package/dist/types/store/utils.d.ts +188 -40
- package/package.json +32 -26
- package/dist/node.cjs +0 -7938
- package/dist/prod/store/optimistic.js +0 -217
- package/dist/prod/store/projection.js +0 -231
- package/dist/prod/store/reconcile.js +0 -707
- package/dist/types/store/optimistic.d.ts +0 -45
- package/dist/types/store/projection.d.ts +0 -70
- package/dist/types/store/reconcile.d.ts +0 -46
- 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 -21
- package/dist/types-cjs/core/constants.d.cts +0 -71
- package/dist/types-cjs/core/core.d.cts +0 -148
- package/dist/types-cjs/core/dev.d.cts +0 -64
- package/dist/types-cjs/core/effect.d.cts +0 -30
- package/dist/types-cjs/core/error.d.cts +0 -47
- package/dist/types-cjs/core/external.d.cts +0 -15
- package/dist/types-cjs/core/graph.d.cts +0 -5
- 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 -56
- 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 -170
- package/dist/types-cjs/core/types.d.cts +0 -148
- 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/signals.d.cts +0 -605
- package/dist/types-cjs/store/index.d.cts +0 -9
- package/dist/types-cjs/store/optimistic.d.cts +0 -45
- package/dist/types-cjs/store/projection.d.cts +0 -70
- package/dist/types-cjs/store/reconcile.d.cts +0 -46
- package/dist/types-cjs/store/store.d.cts +0 -213
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -114
package/dist/types/core/dev.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type InteractionRef, type NavigationRef } from "./attribution-hooks.js";
|
|
2
|
+
import type { ChangeOrigin, CreateEvent, EffectRunEvent, FallbackEvent, FlightEvent, FlushEvent, GraphEvent, HoldEvent, InteractionEvent, NavigationEvent, RerunEvent } from "./attribution.js";
|
|
1
3
|
import type { Computed, Owner, Signal } from "./types.js";
|
|
2
4
|
export interface DevHooks {
|
|
3
5
|
onOwner?: (owner: Owner) => void;
|
|
@@ -5,9 +7,27 @@ export interface DevHooks {
|
|
|
5
7
|
onUpdate?: () => void;
|
|
6
8
|
onStoreNodeUpdate?: (state: any, property: PropertyKey, value: any, prev: any) => void;
|
|
7
9
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* `info` is the advisory tier: a structural fact worth surfacing that is not
|
|
12
|
+
* presumptively a bug (e.g. a 2-deep sequential fetch chain, which may be an
|
|
13
|
+
* intrinsic data dependency). Budget/assertion consumers should treat only
|
|
14
|
+
* `warn`/`error` as failures unless they opt in to `info`.
|
|
15
|
+
*/
|
|
16
|
+
export type DiagnosticSeverity = "info" | "warn" | "error";
|
|
17
|
+
export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "ASYNC_STORE_SETTER" | "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" | "LOADING_ON_OUTSIDE_HOLD" | "INVALID_REFRESH_TARGET" | "INVALID_AFFECTS_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "UNTRACKED_READ_AFTER_AWAIT" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION" | "HUGE_FAN_OUT" | "HUGE_FAN_IN" | "GRAPH_GROWTH" | "HOT_SCOPE_RERUNS" | "HOT_SCOPE_TIME" | "WIDE_SCOPE_DEPS" | "UNSTABLE_MEMO_OUTPUT" | "WASTED_RECOMPUTE" | "ASYNC_WATERFALL" | "HOT_SCOPE_FANOUT" | "SILENT_HOLD" | "LONG_HOLD" | "UNTRACKED_ASYNC_HANDLER" | "ABANDONED_FLIGHTS" | "FALLBACK_FLASH" | "STACKED_HOLDS" | "OPTIMISTIC_REVERTED" | "EFFECT_WRITES_OWN_SOURCE" | "EFFECT_RELAY_TEAR" | "IMMUTABLE_UPDATE_IN_STORE" | "UNSTABLE_LIST_IDENTITY" | "SSR_RENDER_ERROR_CONTAINED" | "SSR_SUBTREE_ABANDONED" | "SSR_STREAM_ABANDONED" | "SSR_CLIENT_CONTENT_MASKED" | "LATE_HEADER_WRITE" | "SERVER_ERROR_SANITIZED" | "SSR_BOUNDARY_WATERFALL" | "SSR_UNDECLARED_LIVE_SOURCE" | "SERVER_WRITE" | "REVEAL_IN_RENDER_TO_STRING" | "LAZY_ASSET_UNMAPPED" | "PRELOAD_DESCRIPTOR_INVALID" | "HEAD_TAG_INVALID" | "UNRECOGNIZED_INSERT_VALUE" | "UNSCOPED_HOLE_ALLOCATED_IDS" | "BEHAVIOR_CLAIM_DROPPED" | "FRAME_MARKER_CORRUPTED" | "DYNAMIC_ASYNC_COMPONENT";
|
|
18
|
+
export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner" | "error" | "perf" | "graph"
|
|
19
|
+
/** Perceived responsiveness: the runtime behaved correctly but the user saw no feedback. */
|
|
20
|
+
| "responsiveness"
|
|
21
|
+
/** Server rendering: boundaries, fragments, the stream, the server-function wire. */
|
|
22
|
+
| "ssr"
|
|
23
|
+
/** The response head: `<head>` tags, preload descriptors, HTTP headers. */
|
|
24
|
+
| "head"
|
|
25
|
+
/** The renderer's insert positions, on either platform: a value it has no rendering for. */
|
|
26
|
+
| "render";
|
|
27
|
+
/** First warning when a change reaches (or a pass tracks) this many edges. */
|
|
28
|
+
export declare const GRAPH_SIZE_WARN_AT = 2000;
|
|
29
|
+
/** Re-warn once the count has grown by this much since the last warning. */
|
|
30
|
+
export declare const GRAPH_SIZE_WARN_EVERY = 500;
|
|
11
31
|
export interface DiagnosticEvent {
|
|
12
32
|
sequence: number;
|
|
13
33
|
code: DiagnosticCode;
|
|
@@ -17,9 +37,26 @@ export interface DiagnosticEvent {
|
|
|
17
37
|
ownerId?: string;
|
|
18
38
|
ownerName?: string;
|
|
19
39
|
nodeName?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Root-first chain of named owners enclosing the subject of the event —
|
|
42
|
+
* component roots as `<Name>`, computations by their `name` option (or
|
|
43
|
+
* the `effect`/`computed` default) — e.g. `["<App>", "<TodoRow>", "effect"]`.
|
|
44
|
+
* Unnamed owners (plain roots) are skipped. Absent when the subject has no
|
|
45
|
+
* named owner at all (a top-level scope, or an unowned primitive — which
|
|
46
|
+
* is usually the finding itself).
|
|
47
|
+
*/
|
|
48
|
+
ownerPath?: string[];
|
|
20
49
|
data?: Record<string, unknown>;
|
|
21
50
|
}
|
|
22
|
-
|
|
51
|
+
/**
|
|
52
|
+
* A findings listener. `subject` is the live node the event is about, when
|
|
53
|
+
* the emitter located one — passed BESIDE the serializable event, the way
|
|
54
|
+
* the records channel passes `live` — for an in-process consumer that goes
|
|
55
|
+
* from a finding to the scope (devtools, a console task lookup);
|
|
56
|
+
* `undefined` for an event with no location, or a host event whose owners
|
|
57
|
+
* are not signals' owners.
|
|
58
|
+
*/
|
|
59
|
+
export type DiagnosticListener = (event: DiagnosticEvent, subject: DiagnosticSubject | undefined) => void;
|
|
23
60
|
export interface DiagnosticCapture {
|
|
24
61
|
readonly events: readonly DiagnosticEvent[];
|
|
25
62
|
clear(): void;
|
|
@@ -28,16 +65,302 @@ export interface DiagnosticCapture {
|
|
|
28
65
|
export interface Diagnostics {
|
|
29
66
|
subscribe(listener: DiagnosticListener): () => void;
|
|
30
67
|
capture(): DiagnosticCapture;
|
|
68
|
+
/**
|
|
69
|
+
* Records an event on the channel from outside the reactive core — a host
|
|
70
|
+
* runtime reporting its own findings (hydration mismatches, server render
|
|
71
|
+
* faults) so consumers see one stream. `subject` locates it like the
|
|
72
|
+
* internal sites do; a host whose owners are not signals' owners passes
|
|
73
|
+
* `ownerPath` on the event instead and it is used as-is.
|
|
74
|
+
*/
|
|
75
|
+
emit(event: Omit<DiagnosticEvent, "sequence">, subject?: DiagnosticSubject | null): DiagnosticEvent;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The core's side of attribution: the slot the engine installs into, and
|
|
79
|
+
* the interaction frame the rendering runtime opens around event dispatch.
|
|
80
|
+
* The engine itself — "why did this run", costs, holds, feedback — is
|
|
81
|
+
* `@solidjs/signals/attribution`, a separate entry so an observe build pays
|
|
82
|
+
* for it only when something imports it; enabling it is what installs.
|
|
83
|
+
*/
|
|
84
|
+
export interface AttributionSlot {
|
|
85
|
+
/**
|
|
86
|
+
* The installed engine, or `null` when none is enabled — the one fact a
|
|
87
|
+
* runtime reads off the slot (`solid-js` opens a `console.createTask` per
|
|
88
|
+
* component only while an engine is there to attribute to it). The
|
|
89
|
+
* object is the engine's hook table, opaque here: the hook contract is
|
|
90
|
+
* between the core and its engine, not public surface.
|
|
91
|
+
*/
|
|
92
|
+
readonly installed: object | null;
|
|
93
|
+
/**
|
|
94
|
+
* Run `fn` as a user interaction's handler: root writes inside stamp it as
|
|
95
|
+
* their origin, and actions/effects/flights it causes carry it. The web
|
|
96
|
+
* runtime wraps every event dispatch in this; custom renderers and test
|
|
97
|
+
* harnesses call it themselves. `fn()` when no engine is installed.
|
|
98
|
+
*/
|
|
99
|
+
withInteraction<T>(ref: InteractionRef, fn: () => T): T;
|
|
100
|
+
/**
|
|
101
|
+
* Run `fn` as a declared unit of work — a router's navigation, described
|
|
102
|
+
* by the parametrized route it matched: root writes inside are attributed
|
|
103
|
+
* to it (under the enclosing interaction, if any), so the hold behind the
|
|
104
|
+
* route's data, the re-runs and the verdicts carry the route's name. Any
|
|
105
|
+
* router calls this around its location write; nothing else is
|
|
106
|
+
* router-specific. `fn()` when no engine is installed.
|
|
107
|
+
*/
|
|
108
|
+
withOrigin<T>(ref: NavigationRef, fn: () => T): T;
|
|
109
|
+
/**
|
|
110
|
+
* The provenance a root write performed now would be stamped with — the
|
|
111
|
+
* interaction whose handler is running, the navigation or effect or action
|
|
112
|
+
* frame open, or inside a recompute the origin of the change that caused
|
|
113
|
+
* it — as the installed engine sees it; `undefined` with no engine, or when
|
|
114
|
+
* nothing is in effect (external). For a runtime recording a fact of its
|
|
115
|
+
* own beside the engine's records: `@solidjs/web` stamps its `"call"`
|
|
116
|
+
* record with this, so a server-function call joins the interaction or
|
|
117
|
+
* navigation it ran for by the identity of the object, not by time.
|
|
118
|
+
*/
|
|
119
|
+
currentOrigin(): ChangeOrigin | undefined;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The records delivered on `OBSERVE.records`, by type — each entry
|
|
123
|
+
* `{ event, live }`: the serializable record and the live handle (the node
|
|
124
|
+
* that ran, a thrown error, a request) an in-process consumer may want
|
|
125
|
+
* beside it. This package declares the attribution engine's records here —
|
|
126
|
+
* the engine ships in this package, behind its own entry, and emits on the
|
|
127
|
+
* same channel as every runtime — and the runtimes that emit declare theirs
|
|
128
|
+
* by augmentation, so the union of record types is whatever loaded.
|
|
129
|
+
* `solid-js` augments THIS interface (its `"boundary"` and `"recovery"`
|
|
130
|
+
* records); the runtimes above it — `@solidjs/web`'s `"invocation"`,
|
|
131
|
+
* `"frame"` and `"call"`, a router's — augment `HostRecordTypes`, reached
|
|
132
|
+
* through the `solid-js` re-export, which this interface extends so the
|
|
133
|
+
* channel sees one catalogue.
|
|
134
|
+
*
|
|
135
|
+
* Two interfaces, one augmenter each, by design: TypeScript merges an
|
|
136
|
+
* augmentation into a re-exported interface by following the alias, and
|
|
137
|
+
* two augmentations reaching the same interface through DIFFERENT aliases
|
|
138
|
+
* (`"@solidjs/signals"` from solid-js, `"solid-js"` from web) merge
|
|
139
|
+
* order-dependently — one set is lost. So each layer augments an interface
|
|
140
|
+
* of its own, through one module name.
|
|
141
|
+
*
|
|
142
|
+
* The engine's records (`@solidjs/signals/attribution`; none is emitted
|
|
143
|
+
* until `attribution.enable()`): `live` is the computation the record is
|
|
144
|
+
* about where there is one — the node that ran for `rerun`, `create` and
|
|
145
|
+
* `effect`, the async node for `flight`, the boundary's subtree for
|
|
146
|
+
* `fallback` (when the boundary reported one), the first held root signal
|
|
147
|
+
* for `hold` (the subject the SILENT_HOLD finding names) — and `undefined`
|
|
148
|
+
* for the records with no single subject (`flush`, `interaction`,
|
|
149
|
+
* `navigation`, `graph`). The records are the same objects the engine's
|
|
150
|
+
* ring buffers hold (`attribution.history(type)`), delivered synchronously
|
|
151
|
+
* the moment each is complete — a re-run at recompute end, a hold, a
|
|
152
|
+
* navigation, an interaction when it settles, bottom-up — so a listener
|
|
153
|
+
* runs inside the engine and must not write signals. The timeline records
|
|
154
|
+
* (`create`, `effect`, `flush`, `flight`, `fallback`) and `graph` enter no
|
|
155
|
+
* ring buffer and are built only while `observed(type)`: subscribing is
|
|
156
|
+
* what turns them on. `rerun` is built while something wants it — a
|
|
157
|
+
* listener, an imported fold (`costs`/`feedback`) or the console log; the
|
|
158
|
+
* engine's own checks read the facts, not the record.
|
|
159
|
+
*/
|
|
160
|
+
export interface RecordTypes extends HostRecordTypes {
|
|
161
|
+
rerun: {
|
|
162
|
+
event: RerunEvent;
|
|
163
|
+
live: Computed<any>;
|
|
164
|
+
};
|
|
165
|
+
create: {
|
|
166
|
+
event: CreateEvent;
|
|
167
|
+
live: Computed<any>;
|
|
168
|
+
};
|
|
169
|
+
effect: {
|
|
170
|
+
event: EffectRunEvent;
|
|
171
|
+
live: Computed<any>;
|
|
172
|
+
};
|
|
173
|
+
flush: {
|
|
174
|
+
event: FlushEvent;
|
|
175
|
+
live: undefined;
|
|
176
|
+
};
|
|
177
|
+
flight: {
|
|
178
|
+
event: FlightEvent;
|
|
179
|
+
live: Computed<any>;
|
|
180
|
+
};
|
|
181
|
+
fallback: {
|
|
182
|
+
event: FallbackEvent;
|
|
183
|
+
live: Computed<any> | undefined;
|
|
184
|
+
};
|
|
185
|
+
interaction: {
|
|
186
|
+
event: InteractionEvent;
|
|
187
|
+
live: undefined;
|
|
188
|
+
};
|
|
189
|
+
hold: {
|
|
190
|
+
event: HoldEvent;
|
|
191
|
+
live: Signal<any>;
|
|
192
|
+
};
|
|
193
|
+
navigation: {
|
|
194
|
+
event: NavigationEvent;
|
|
195
|
+
live: undefined;
|
|
196
|
+
};
|
|
197
|
+
graph: {
|
|
198
|
+
event: GraphEvent;
|
|
199
|
+
live: undefined;
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/** The record types host runtimes declare — see `RecordTypes`. */
|
|
203
|
+
export interface HostRecordTypes {
|
|
31
204
|
}
|
|
205
|
+
export type RecordType = keyof RecordTypes & string;
|
|
206
|
+
export type RecordEvent<K extends RecordType> = RecordTypes[K] extends {
|
|
207
|
+
event: infer E;
|
|
208
|
+
} ? E : never;
|
|
209
|
+
export type RecordLive<K extends RecordType> = RecordTypes[K] extends {
|
|
210
|
+
live: infer L;
|
|
211
|
+
} ? L : never;
|
|
212
|
+
export type RecordListener<K extends RecordType> = (event: RecordEvent<K>, live: RecordLive<K>) => void;
|
|
213
|
+
/**
|
|
214
|
+
* The records channel — `OBSERVE.records`, on either platform: one place a
|
|
215
|
+
* consumer (an APM adapter's `init()`, devtools, the diagnostics harness)
|
|
216
|
+
* subscribes to the completed, serializable summaries of the things the
|
|
217
|
+
* runtimes did — a `<Loading>` boundary that waited on the server, a
|
|
218
|
+
* server-function execution or call, a frame stream produced or applied,
|
|
219
|
+
* and the attribution engine's: a re-run, a hold, an interaction — each
|
|
220
|
+
* delivered synchronously the moment it is complete, with its live handle
|
|
221
|
+
* passed BESIDE it. Any number of listeners; none can alter what it
|
|
222
|
+
* observes; one that throws is reported and the rest run. The engine's
|
|
223
|
+
* records are declared here and emitted only while the engine
|
|
224
|
+
* (`@solidjs/signals/attribution`, a separate entry the observe build pays
|
|
225
|
+
* for only when imported) is enabled; `observed(type)` is the one gate an
|
|
226
|
+
* emitter of either kind checks before building a record.
|
|
227
|
+
*
|
|
228
|
+
* The object is created once per PROCESS under a registered symbol, so a
|
|
229
|
+
* subscription made before the emitting runtime has loaded, or from a
|
|
230
|
+
* second bundled copy of the core, reaches the same listener set. Absent in
|
|
231
|
+
* prod with the rest of `OBSERVE`.
|
|
232
|
+
*/
|
|
233
|
+
export interface Records {
|
|
234
|
+
/**
|
|
235
|
+
* Deliver `type` records as they complete; returns the unsubscribe. The
|
|
236
|
+
* subscription is the channel's, not any emitter's: it outlives the
|
|
237
|
+
* attribution engine's `enable()`/`disable()` cycles and is dropped only
|
|
238
|
+
* by its own unsubscribe.
|
|
239
|
+
*/
|
|
240
|
+
subscribe<K extends RecordType>(type: K, listener: RecordListener<K>): () => void;
|
|
241
|
+
/**
|
|
242
|
+
* Whether anything is subscribed to `type` — an emitter's pre-check, so
|
|
243
|
+
* a record nobody will hear costs nothing to not build (no clock read).
|
|
244
|
+
*/
|
|
245
|
+
observed(type: RecordType): boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Delivers a completed record to `type`'s listeners, synchronously: how a
|
|
248
|
+
* runtime publishes. Snapshot semantics without a snapshot — the listener
|
|
249
|
+
* list is replaced, never mutated, on subscribe/unsubscribe — so a
|
|
250
|
+
* listener unsubscribing mid-delivery neither skips nor double-calls
|
|
251
|
+
* anyone this round, and delivery allocates nothing.
|
|
252
|
+
*/
|
|
253
|
+
emit<K extends RecordType>(type: K, event: RecordEvent<K>, live: RecordLive<K>): void;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* The server runtime's observe surface — where a server-side consumer
|
|
257
|
+
* installs what only the server has: the trace-context provider slot.
|
|
258
|
+
* Declared EMPTY here and typed by the runtime that owns the surface:
|
|
259
|
+
* `solid-js`'s server entry augments this interface with `trace:
|
|
260
|
+
* ServerTrace`, an interface of its own that `@solidjs/web`'s server
|
|
261
|
+
* entries fill in (`provide`) — so the core never learns that shape and
|
|
262
|
+
* the consumer still finds it on the one `OBSERVE`. One augmenter per
|
|
263
|
+
* interface: see `RecordTypes` for why.
|
|
264
|
+
*
|
|
265
|
+
* The OBJECT behind it is not the core's either: the core has one artifact
|
|
266
|
+
* per tier for both platforms, and the client would carry it for nothing.
|
|
267
|
+
* `solid-js`'s server entry replaces this empty literal with the
|
|
268
|
+
* process-wide slot the moment it evaluates (see `serverSlots` in
|
|
269
|
+
* solid-js/src/server/observe.ts), so a consumer that imports only
|
|
270
|
+
* `solid-js` can provide before the web runtime that reads it has loaded,
|
|
271
|
+
* and from a second copy when a host bundles one. On the client this stays
|
|
272
|
+
* `{}`.
|
|
273
|
+
*/
|
|
274
|
+
export interface ServerObserve {
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* The observe tier: the structured channel and the attribution wiring —
|
|
278
|
+
* everything a production observability consumer needs, and nothing that
|
|
279
|
+
* assumes a developer at a console. Present in dev and observe builds
|
|
280
|
+
* (`__OBSERVE__`); `undefined` in prod.
|
|
281
|
+
*/
|
|
282
|
+
export interface Observe {
|
|
283
|
+
diagnostics: Diagnostics;
|
|
284
|
+
/** Completed records from the runtimes, by type — see `Records`. */
|
|
285
|
+
records: Records;
|
|
286
|
+
/** The attribution hook slot and interaction frame — see `AttributionSlot`. */
|
|
287
|
+
attribution: AttributionSlot;
|
|
288
|
+
/** The server runtime's surface — see `ServerObserve`. */
|
|
289
|
+
server: ServerObserve;
|
|
290
|
+
/**
|
|
291
|
+
* Marks `owner`'s subtree as the observer's own. A consumer that renders
|
|
292
|
+
* inside the app it watches — an APM adapter's panel, devtools — would
|
|
293
|
+
* otherwise see its own effects, stores and holds reported as findings about
|
|
294
|
+
* the app. Under an excluded owner: diagnostics whose subject sits in the
|
|
295
|
+
* subtree are neither delivered nor reported (the entry is still built, so
|
|
296
|
+
* a site that throws its message still throws), and the attribution engine
|
|
297
|
+
* records no runs for its computations. Mark the root as it is created
|
|
298
|
+
* (`createRoot(() => { OBSERVE.exclude(getOwner()!); … })`); the signals
|
|
299
|
+
* and stores created under it are excluded subjects wherever their writes
|
|
300
|
+
* come from (a click handler, an adapter callback), so writes need no
|
|
301
|
+
* `runWithOwner` — and must not use one: a write under an owner is a write
|
|
302
|
+
* in an owned scope (REACTIVE_WRITE_IN_OWNED_SCOPE). Irrevocable for the
|
|
303
|
+
* owner's lifetime.
|
|
304
|
+
*/
|
|
305
|
+
exclude(owner: Owner): void;
|
|
306
|
+
/** Whether `subject` sits under an excluded owner (itself included). */
|
|
307
|
+
isExcluded(subject: DiagnosticSubject | null | undefined): boolean;
|
|
308
|
+
/**
|
|
309
|
+
* Root-first names of the owners enclosing `subject` (inclusive when the
|
|
310
|
+
* subject is itself a named owner) — component roots as `<Name>`,
|
|
311
|
+
* computations by their `name` option — the labels every finding and
|
|
312
|
+
* record carries as `ownerPath` (`["<App>", "<TodoRow>", "label"]`), from
|
|
313
|
+
* the one walk that stamps them, so a consumer locating a live node it
|
|
314
|
+
* was handed (`live`, a diagnostic's `subject`) reads the same path.
|
|
315
|
+
* Signals hop to their registering owner; unnamed owners are skipped;
|
|
316
|
+
* `undefined` when nothing on the chain is named. Names exist only in the
|
|
317
|
+
* observing tiers, which is why the walk lives here and not on the prod
|
|
318
|
+
* surface.
|
|
319
|
+
*/
|
|
320
|
+
ownerPath(subject: DiagnosticSubject | null | undefined): string[] | undefined;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* The dev tier: devtools hooks, graph traversal, and the console face of the
|
|
324
|
+
* diagnostics channel. Present only in dev builds (`__DEV__`).
|
|
325
|
+
*/
|
|
32
326
|
export interface Dev {
|
|
33
327
|
hooks: DevHooks;
|
|
34
|
-
diagnostics: Diagnostics;
|
|
35
328
|
getChildren: typeof getChildren;
|
|
36
329
|
getSignals: typeof getSignals;
|
|
37
330
|
getParent: typeof getParent;
|
|
38
331
|
getSources: typeof getSources;
|
|
39
332
|
getObservers: typeof getObservers;
|
|
333
|
+
/** Console face of an emitted event — see `reportDiagnostic`. */
|
|
334
|
+
report(entry: DiagnosticEvent): void;
|
|
335
|
+
/**
|
|
336
|
+
* The stable URL of `code`'s section in the repair guide — the
|
|
337
|
+
* `reactivity-diagnostics` skill shipped with `solid-js`, one section per
|
|
338
|
+
* code. The one place the URL is built: the console footer prints it and
|
|
339
|
+
* the performance tracks' Insights link (`learnMoreUrl`) reads it, so both
|
|
340
|
+
* name the same section. Dev-tier: it is guidance for a developer, and a
|
|
341
|
+
* URL string on a retained object is a cost every observe build would pay.
|
|
342
|
+
*/
|
|
343
|
+
guideUrl(code: DiagnosticCode): string;
|
|
40
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Registers the console footer appended to the first console report of
|
|
347
|
+
* each diagnostic code — a discovery pointer to deeper guidance. Reported
|
|
348
|
+
* events carry it as trailing lines of the same console entry; events that
|
|
349
|
+
* surface as a thrown error instead get it as a follow-up line. Returning
|
|
350
|
+
* undefined for an event suppresses the footer. Passing undefined
|
|
351
|
+
* unregisters and resets the once-per-code memory.
|
|
352
|
+
*
|
|
353
|
+
* @internal A seam for `solid-js`, which owns the repair skill the footer
|
|
354
|
+
* names and installs it from both of its entries; not part of `DEV`. No-op
|
|
355
|
+
* outside dev builds, where nothing reports to the console.
|
|
356
|
+
*/
|
|
357
|
+
export declare function setConsoleFooter(footer: ((event: DiagnosticEvent) => string | undefined) | undefined): void;
|
|
358
|
+
export declare const OBSERVE: Observe;
|
|
359
|
+
export declare function isExcluded(subject: DiagnosticSubject | null | undefined): boolean;
|
|
360
|
+
/** For engines that cache the verdict per node: is anything excluded at all? */
|
|
361
|
+
export declare function anyExcluded(): boolean;
|
|
362
|
+
/** Was `entry` built for an excluded subject? Once-per-key reporters must not spend their slot on it. */
|
|
363
|
+
export declare function isSuppressed(entry: DiagnosticEvent): boolean;
|
|
41
364
|
export declare const DEV: Dev;
|
|
42
365
|
/**
|
|
43
366
|
* Dev-mode internal consistency check. A failure means the reactive system
|
|
@@ -47,18 +370,108 @@ export declare const DEV: Dev;
|
|
|
47
370
|
* dev builds so user apps degrade instead of crashing.
|
|
48
371
|
*/
|
|
49
372
|
export declare function assertInvariant(condition: boolean, name: string, message: string): void;
|
|
50
|
-
|
|
373
|
+
/** Anything a diagnostic can be about: an owner (root, computed, effect) or a signal. */
|
|
374
|
+
export type DiagnosticSubject = Owner | Signal<any> | Computed<any>;
|
|
375
|
+
/**
|
|
376
|
+
* Root-first names of the owners enclosing `subject` (inclusive when the
|
|
377
|
+
* subject is itself a named owner). Signals hop to their registering owner
|
|
378
|
+
* (`_owner`, set by registerGraph). Unnamed owners are skipped so the path
|
|
379
|
+
* reads as the component tree plus the scope: `<App> › <TodoRow> › effect`.
|
|
380
|
+
* Public as `OBSERVE.ownerPath`; the core's own sites import it directly.
|
|
381
|
+
*/
|
|
382
|
+
export declare function ownerPath(subject: DiagnosticSubject | null | undefined): string[] | undefined;
|
|
383
|
+
/**
|
|
384
|
+
* Records a diagnostic on the structured channel (listeners, captures) and
|
|
385
|
+
* returns the entry. `subject` locates it: the current reactive `context` by
|
|
386
|
+
* default (right for the synchronous rule checks — they fire inside the
|
|
387
|
+
* scope that misbehaved); pass the node for scheduler-time findings whose
|
|
388
|
+
* ambient context is the flush, or `null` for events that have no location
|
|
389
|
+
* by nature. An `ownerPath` already on the event wins over the subject walk
|
|
390
|
+
* (hosts whose owners are not signals' owners compute their own). Console
|
|
391
|
+
* output is a separate, dev-tier step — see `reportDiagnostic`.
|
|
392
|
+
*/
|
|
393
|
+
export declare function emitDiagnostic(event: Omit<DiagnosticEvent, "sequence">, subject?: DiagnosticSubject | null | undefined): DiagnosticEvent;
|
|
394
|
+
/**
|
|
395
|
+
* The console face of a diagnostic — ONE entry per finding: the message, the
|
|
396
|
+
* owner path (`in <App> › <TodoRow> › effect`) so a human can locate it, the
|
|
397
|
+
* once-per-code footer as trailing lines, and — when the subject is a
|
|
398
|
+
* binding effect the rendering runtime tagged — the element it writes, as a
|
|
399
|
+
* second console argument (hover highlights it, click jumps to Elements).
|
|
400
|
+
* Severity picks the console method. Call sites report the entry
|
|
401
|
+
* `emitDiagnostic` returned so the structured and console channels never
|
|
402
|
+
* disagree. Dev-tier: in an observe build this is a no-op, so wiring paths
|
|
403
|
+
* that both emit and report (graph-size warnings) reach the channel only —
|
|
404
|
+
* production observability never writes to the console.
|
|
405
|
+
*/
|
|
406
|
+
export declare function reportDiagnostic(entry: DiagnosticEvent): void;
|
|
51
407
|
/**
|
|
52
408
|
* Shared strict-read diagnostics for core read() and the store proxy traps.
|
|
53
409
|
* Single source for the message text — the #2897 safeguard parity between
|
|
54
410
|
* memos and stores is exactly these firing identically from both paths.
|
|
55
411
|
*/
|
|
56
|
-
export declare function throwPendingUntrackedRead(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence" | "data">>): never;
|
|
57
|
-
export declare function warnStrictReadUntracked(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence">>): void;
|
|
412
|
+
export declare function throwPendingUntrackedRead(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence" | "data" | "ownerPath">>): never;
|
|
413
|
+
export declare function warnStrictReadUntracked(strictReadLabel: string, fields?: Partial<Omit<DiagnosticEvent, "sequence" | "ownerPath">>): void;
|
|
414
|
+
/**
|
|
415
|
+
* Observe-tier: stamp a signal with its creating owner so `ownerPath` can
|
|
416
|
+
* locate signal subjects. The per-owner `_signals` list and the devtools
|
|
417
|
+
* `onGraph` hook are dev-tier — the observe build pays one property write.
|
|
418
|
+
*/
|
|
58
419
|
export declare function registerGraph(value: any, owner: Owner | null): void;
|
|
59
420
|
export declare function clearSignals(node: Owner): void;
|
|
421
|
+
export declare function registerRoot(owner: Owner): void;
|
|
422
|
+
export declare function unregisterRoot(owner: Owner): void;
|
|
423
|
+
/**
|
|
424
|
+
* The live top-level roots, for a walk of the owner tree (the engine's
|
|
425
|
+
* `graphSize`): dead refs are dropped as they are met. Empty in prod.
|
|
426
|
+
*/
|
|
427
|
+
export declare function liveRootOwners(): Owner[];
|
|
60
428
|
export declare function getChildren(owner: Owner): Owner[];
|
|
61
429
|
export declare function getSignals(owner: Owner): any[];
|
|
62
430
|
export declare function getParent(owner: Owner): Owner | null;
|
|
63
431
|
export declare function getSources(computation: Computed<any>): (Signal<any> | Computed<any>)[];
|
|
64
432
|
export declare function getObservers(node: Signal<any> | Computed<any>): Computed<any>[];
|
|
433
|
+
/**
|
|
434
|
+
* The root invalidation a HUGE_FAN_OUT finding was priced on, when the
|
|
435
|
+
* attribution engine is the one reporting it: a signal/store write, a
|
|
436
|
+
* `refresh()`, or an async landing. The always-on core check counts the
|
|
437
|
+
* notify walk of any change and cannot tell — it reports no `write`.
|
|
438
|
+
*/
|
|
439
|
+
export type FanOutWrite = "write" | "refresh" | "async";
|
|
440
|
+
/**
|
|
441
|
+
* Observe-tier: a committed change on `node` is about to re-run `count`
|
|
442
|
+
* subscribers. Two reporters, one finding, one dedupe: the core counts the
|
|
443
|
+
* notify walk in `insertSubs` as it goes (fan-out costs exactly one local
|
|
444
|
+
* increment in a loop that already visits every edge, and nothing at link
|
|
445
|
+
* time) and fires from GRAPH_SIZE_WARN_AT up, always-on wherever the
|
|
446
|
+
* channel exists — a graph-size pathology should surface without asking.
|
|
447
|
+
* The attribution engine, while enabled, reports the same code from its
|
|
448
|
+
* lower `fanOut` threshold (default 250) on the root writes it stamps, with
|
|
449
|
+
* the write kind it knows, and hands over to the core at
|
|
450
|
+
* GRAPH_SIZE_WARN_AT so one change never carries two findings. Both fire on
|
|
451
|
+
* the write rather than the link: a fan-out that is never written costs
|
|
452
|
+
* nothing, and one that is re-runs every subscriber this flush. Once per
|
|
453
|
+
* node, re-warning only once the count has grown by GRAPH_SIZE_WARN_EVERY.
|
|
454
|
+
*/
|
|
455
|
+
export declare function noteFanOut(node: Signal<any> | Computed<any>, count: number, write?: FanOutWrite): void;
|
|
456
|
+
/**
|
|
457
|
+
* Observe-tier: a recompute pass of `node` tracked `count` distinct sources
|
|
458
|
+
* (its trimmed dep list, walked once at the end of the pass — see recompute;
|
|
459
|
+
* no per-link work, no pass bracket). Fires from GRAPH_SIZE_WARN_AT up.
|
|
460
|
+
*/
|
|
461
|
+
export declare function noteFanIn(node: Computed<any>, count: number): void;
|
|
462
|
+
/**
|
|
463
|
+
* Dev-only: attribute reads that run after an `await` inside an async compute.
|
|
464
|
+
* JS has no async context, so a native-promise flight is consumed by a uniquely
|
|
465
|
+
* named async function instead of `.then`; V8's async stack traces then carry a
|
|
466
|
+
* `__solidAsyncCompute_<id>` frame on every read in the compute's continuation.
|
|
467
|
+
* `await` on a native promise settles on the same tick as `.then`, so dev and
|
|
468
|
+
* prod timing match. Other thenables, and engines without async frames
|
|
469
|
+
* (Firefox, Safari), are left alone and never warn.
|
|
470
|
+
*/
|
|
471
|
+
export declare let asyncTailFlights: number;
|
|
472
|
+
export declare function watchAsyncTail<T>(el: Computed<T>, flight: PromiseLike<T>): PromiseLike<T>;
|
|
473
|
+
/**
|
|
474
|
+
* `dep` is the node a tracked read would have linked (undefined when a store key
|
|
475
|
+
* was never tracked); `holder`/`key` identify the read for once-only reporting.
|
|
476
|
+
*/
|
|
477
|
+
export declare function checkPostAwaitRead(dep: object | undefined, holder: object, key: PropertyKey | undefined, nodeName: string | undefined, throwsPending: boolean): 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
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Owner } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The client error hook — the prod-tier seam through which an app or an
|
|
4
|
+
* error monitor hears the one failure nothing else can see: an error
|
|
5
|
+
* boundary (`createErrorBoundary`, `<Errored>`) collected it and is rendering
|
|
6
|
+
* its fallback. The browser's global handlers hear what reaches
|
|
7
|
+
* `window.onerror`; a rendered fallback never does. An UNCAUGHT error is not
|
|
8
|
+
* this hook's: the halt (`REACTIVITY_HALTED`) hands its cause to the
|
|
9
|
+
* platform's `reportError`, the channel every monitor already listens on —
|
|
10
|
+
* one event, not two.
|
|
11
|
+
*
|
|
12
|
+
* Called once per error object: a boundary's `reset()` recomputing the same
|
|
13
|
+
* failing node re-collects the same error and does not report it again.
|
|
14
|
+
* Two tiers: ambient (`configureClientErrors`) and per root
|
|
15
|
+
* (`render`/`hydrate`'s `onError` in `@solidjs/web`), the nearest root's
|
|
16
|
+
* winning. Fires in every tier; no return — the client has no wire to map
|
|
17
|
+
* for. `ownerPath` carries the component labels where the runtime keeps
|
|
18
|
+
* owner names (the observe and dev artifacts).
|
|
19
|
+
*
|
|
20
|
+
* Pay-for-use: this module is retained by `createErrorBoundary` (which
|
|
21
|
+
* reports here) or the app's own `configureClientErrors` import. A root's
|
|
22
|
+
* hook is parked ON the root owner under a registered symbol
|
|
23
|
+
* (`ROOT_ERROR_HOOK`, defined in the scheduler), so `render` writes it
|
|
24
|
+
* without importing anything: an app that configures no hook and renders no
|
|
25
|
+
* boundary carries none of this.
|
|
26
|
+
*/
|
|
27
|
+
export interface ClientErrorContext {
|
|
28
|
+
/**
|
|
29
|
+
* Where the error was THROWN: labels root-first up the owner chain of the
|
|
30
|
+
* computation that threw — component labels and named primitives — when
|
|
31
|
+
* the runtime keeps owner names (the observe and dev artifacts). The
|
|
32
|
+
* boundary's own chain when the thrower is unknown (a value thrown
|
|
33
|
+
* outside any computation).
|
|
34
|
+
*/
|
|
35
|
+
ownerPath?: string[];
|
|
36
|
+
/**
|
|
37
|
+
* Where the error was MET: the same labels up the chain of the `<Errored>`
|
|
38
|
+
* that rendered its fallback for it — what the user saw, as against
|
|
39
|
+
* `ownerPath`, which is what broke.
|
|
40
|
+
*/
|
|
41
|
+
boundaryPath?: string[];
|
|
42
|
+
}
|
|
43
|
+
export type ClientErrorHook = (error: unknown, context: ClientErrorContext) => void;
|
|
44
|
+
export interface ClientErrorsConfig {
|
|
45
|
+
/** The hook, or `undefined` to clear it. */
|
|
46
|
+
onError?: ClientErrorHook;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Registers the ambient client error hook — the one call a browser `init()`
|
|
50
|
+
* makes to see every failure a boundary renders a fallback for, in
|
|
51
|
+
* production. (Uncaught errors reach `reportError` / `window.onerror`.)
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* configureClientErrors({
|
|
55
|
+
* onError: (error, { ownerPath }) =>
|
|
56
|
+
* Sentry.captureException(error, {
|
|
57
|
+
* mechanism: { type: "solid.error_boundary", handled: true }
|
|
58
|
+
* })
|
|
59
|
+
* });
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function configureClientErrors(config: ClientErrorsConfig): void;
|
|
63
|
+
/**
|
|
64
|
+
* Tells the client error hook about `error`, caught by the boundary whose
|
|
65
|
+
* owner is `owner`, thrown by `thrower` (the computation the engine's status
|
|
66
|
+
* wrapper named; unknown for a value that never crossed one) — once per
|
|
67
|
+
* error object. A throwing hook is reported on the console and otherwise
|
|
68
|
+
* ignored — a monitor must never take the app down.
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
export declare function reportClientError(error: unknown, owner: Owner | null | undefined, thrower?: Owner | null): void;
|
|
@@ -39,6 +39,15 @@ export declare class StatusError extends Error {
|
|
|
39
39
|
}
|
|
40
40
|
/** Return the user's error from an internal status wrapper. */
|
|
41
41
|
export declare function unwrapStatusError(error: unknown): unknown;
|
|
42
|
+
/**
|
|
43
|
+
* Rejection value of `until(fn, { timeout })` when the predicate does not turn
|
|
44
|
+
* truthy within the window. Inside an `action()`, the rejection is thrown back
|
|
45
|
+
* in at the `yield` point — catchable there, or the action fails and its
|
|
46
|
+
* optimistic state reverts.
|
|
47
|
+
*/
|
|
48
|
+
export declare class TimeoutError extends Error {
|
|
49
|
+
constructor(message?: string);
|
|
50
|
+
}
|
|
42
51
|
export declare class NoOwnerError extends Error {
|
|
43
52
|
constructor();
|
|
44
53
|
}
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
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
|
+
export declare function clearDeps(el: Computed<unknown>): void;
|
|
4
5
|
export declare function unobserved(el: Computed<unknown>): void;
|
|
6
|
+
/**
|
|
7
|
+
* Deferred dormancy for never-observed auto-dispose computeds (#3078).
|
|
8
|
+
*
|
|
9
|
+
* An untracked top-level read of a subscriber-less observation-lifecycle memo
|
|
10
|
+
* used to call unobserved() inline at the end of read(). That kept the leak
|
|
11
|
+
* closed (the compute links the memo into its deps' sub lists — without a
|
|
12
|
+
* teardown point a never-observed memo is retained by its sources forever;
|
|
13
|
+
* upstream alien-signals has exactly this retention), but it made reads
|
|
14
|
+
* destructive: each read disposed the node, the next read revived it with a
|
|
15
|
+
* full recompute in whatever ambient transition/lane context happened to be
|
|
16
|
+
* current, so consecutive reads could return different answers with no write
|
|
17
|
+
* in between.
|
|
18
|
+
*
|
|
19
|
+
* Instead, reads queue the node here and the scheduler sweeps at the top of
|
|
20
|
+
* the next flush (before runHeap, so a same-tick dirtying is reclaimed
|
|
21
|
+
* instead of recomputed). Reads become idempotent within a tick (the node
|
|
22
|
+
* stays alive and serves its cache, uniform with observed memos) while
|
|
23
|
+
* reclamation still happens within one microtask — the enqueue site arms
|
|
24
|
+
* schedule(), so a flush is guaranteed even when no other work is queued.
|
|
25
|
+
*/
|
|
26
|
+
export declare const dormantNodes: Set<Computed<unknown>>;
|
|
27
|
+
export declare function sweepDormant(): void;
|
|
5
28
|
export declare function link(dep: Signal<any> | Computed<any>, sub: Computed<any>, pendingObserver?: boolean): void;
|
|
@@ -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 {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ContextNotFoundError, NoOwnerError, NotReadyError } from "./error.js";
|
|
2
|
-
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo,
|
|
1
|
+
export { ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError } from "./error.js";
|
|
2
|
+
export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, optimisticSignal, optimisticComputed, installAuthoritativeRead, markRefresh, 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";
|
|
@@ -9,5 +9,8 @@ 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 { InteractionRef, NavigationRef } from "./attribution-hooks.js";
|
|
13
|
+
export { ROOT_ERROR_HOOK } from "./scheduler.js";
|
|
14
|
+
export { configureClientErrors, type ClientErrorContext, type ClientErrorHook, type ClientErrorsConfig } from "./error-hooks.js";
|
|
15
|
+
export { DEV, OBSERVE, setConsoleFooter, type AttributionSlot, type Dev, type Observe, type ServerObserve, type Records, type RecordTypes, type HostRecordTypes, type RecordType, type RecordEvent, type RecordLive, type RecordListener, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type DiagnosticListener, type Diagnostics, type DiagnosticSeverity, type DiagnosticSubject } from "./dev.js";
|
|
13
16
|
export * from "./constants.js";
|