@solidjs/signals 2.0.0-rc.2 → 2.0.0-rc.20
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 +6505 -0
- package/dist/dev.attribution.js +3484 -0
- package/dist/dev.js +10227 -9508
- package/dist/observe/affects-marks.js +86 -0
- package/dist/observe/affects.js +112 -0
- package/dist/observe/attribution.js +7 -0
- package/dist/observe/boundaries.js +696 -0
- package/dist/observe/core/action.js +182 -0
- package/dist/observe/core/async.js +824 -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 +3079 -0
- package/dist/observe/core/constants.js +269 -0
- package/dist/observe/core/context.js +63 -0
- package/dist/observe/core/copies.js +10 -0
- package/dist/observe/core/core.js +1707 -0
- package/dist/observe/core/dev.js +394 -0
- package/dist/observe/core/effect.js +193 -0
- package/dist/observe/core/error-hooks.js +71 -0
- package/dist/observe/core/error.js +82 -0
- package/dist/observe/core/external.js +97 -0
- package/dist/observe/core/graph.js +162 -0
- package/dist/observe/core/heap.js +124 -0
- package/dist/observe/core/identities.js +62 -0
- package/dist/observe/core/invariants.js +12 -0
- package/dist/observe/core/lanes.js +972 -0
- package/dist/observe/core/owner.js +371 -0
- package/dist/observe/core/scheduler.js +1157 -0
- package/dist/observe/core/truth.js +47 -0
- package/dist/observe/core/verdict.js +470 -0
- package/dist/observe/deferred.js +186 -0
- package/dist/observe/flatten.js +79 -0
- package/dist/observe/from.js +248 -0
- package/dist/observe/index.js +71 -0
- package/dist/observe/map.js +593 -0
- package/dist/observe/reveal.js +212 -0
- package/dist/observe/signals.js +717 -0
- package/dist/observe/store/affects.js +142 -0
- package/dist/observe/store/edges.js +39 -0
- package/dist/observe/store/hooks.js +16 -0
- package/dist/observe/store/index.js +47 -0
- package/dist/observe/store/optimistic.js +713 -0
- package/dist/observe/store/projection.js +345 -0
- package/dist/observe/store/reconcile.js +281 -0
- package/dist/observe/store/store.js +2127 -0
- package/dist/observe/store/storePath.js +103 -0
- package/dist/observe/store/target.js +46 -0
- package/dist/observe/store/types.js +83 -0
- package/dist/observe/store/utils.js +1063 -0
- package/dist/prod/affects-marks.js +86 -0
- package/dist/prod/affects.js +98 -112
- package/dist/prod/attribution.js +45 -0
- package/dist/prod/boundaries.js +578 -468
- package/dist/prod/core/action.js +92 -59
- package/dist/prod/core/async.js +522 -336
- package/dist/prod/core/attribution-hooks.js +3 -0
- package/dist/prod/core/constants.js +168 -44
- package/dist/prod/core/context.js +12 -16
- package/dist/prod/core/copies.js +10 -0
- package/dist/prod/core/core.js +1345 -627
- package/dist/prod/core/dev.js +123 -1
- package/dist/prod/core/effect.js +113 -80
- package/dist/prod/core/error-hooks.js +71 -0
- package/dist/prod/core/error.js +18 -4
- package/dist/prod/core/external.js +6 -7
- package/dist/prod/core/graph.js +119 -72
- package/dist/prod/core/heap.js +85 -109
- package/dist/prod/core/identities.js +62 -0
- package/dist/prod/core/invariants.js +1 -32
- package/dist/prod/core/lanes.js +931 -132
- package/dist/prod/core/owner.js +192 -129
- package/dist/prod/core/scheduler.js +948 -642
- package/dist/prod/core/truth.js +47 -0
- package/dist/prod/core/verdict.js +409 -420
- package/dist/prod/deferred.js +184 -0
- package/dist/prod/flatten.js +77 -0
- package/dist/prod/from.js +248 -0
- package/dist/prod/index.js +40 -16
- package/dist/prod/map.js +481 -211
- package/dist/prod/reveal.js +212 -0
- package/dist/prod/signals.js +401 -84
- package/dist/prod/store/affects.js +142 -0
- package/dist/prod/store/edges.js +39 -0
- package/dist/prod/store/hooks.js +16 -0
- package/dist/prod/store/index.js +27 -18
- package/dist/prod/store/optimistic.js +707 -0
- package/dist/prod/store/projection.js +331 -0
- package/dist/prod/store/reconcile.js +281 -0
- package/dist/prod/store/store.js +1952 -267
- package/dist/prod/store/storePath.js +1 -1
- package/dist/prod/store/target.js +43 -0
- package/dist/prod/store/types.js +83 -0
- package/dist/prod/store/utils.js +997 -138
- package/dist/types/affects-marks.d.ts +14 -0
- package/dist/types/affects.d.ts +12 -30
- package/dist/types/attribution.d.ts +19 -0
- package/dist/types/attribution.prod.d.ts +22 -0
- package/dist/types/boundaries.d.ts +99 -124
- package/dist/types/carved.d.ts +1 -0
- package/dist/types/core/action.d.ts +23 -9
- package/dist/types/core/async.d.ts +34 -6
- 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 +307 -8
- package/dist/types/core/attribution-queries.d.ts +24 -0
- package/dist/types/core/attribution.d.ts +802 -72
- package/dist/types/core/constants.d.ts +195 -38
- package/dist/types/core/copies.d.ts +54 -0
- package/dist/types/core/core.d.ts +295 -65
- package/dist/types/core/dev.d.ts +509 -22
- package/dist/types/core/effect.d.ts +1 -1
- package/dist/types/core/error-hooks.d.ts +71 -0
- package/dist/types/core/error.d.ts +18 -1
- package/dist/types/core/graph.d.ts +40 -1
- package/dist/types/core/heap.d.ts +5 -5
- package/dist/types/core/identities.d.ts +17 -0
- package/dist/types/core/index.d.ts +11 -7
- package/dist/types/core/invariants.d.ts +1 -26
- package/dist/types/core/lanes.d.ts +74 -43
- package/dist/types/core/owner.d.ts +27 -9
- package/dist/types/core/scheduler.d.ts +353 -102
- package/dist/types/core/truth.d.ts +18 -0
- package/dist/types/core/types.d.ts +97 -71
- package/dist/types/core/verdict.d.ts +35 -0
- package/dist/types/deferred.d.ts +28 -0
- package/dist/types/flatten.d.ts +8 -0
- package/dist/types/from.d.ts +47 -0
- package/dist/types/index.d.ts +33 -7
- package/dist/types/map.d.ts +4 -2
- package/dist/types/reveal.d.ts +19 -0
- package/dist/types/signals.d.ts +196 -45
- package/dist/types/store/affects.d.ts +12 -0
- package/dist/types/store/edges.d.ts +9 -0
- package/dist/types/store/hooks.d.ts +62 -0
- package/dist/types/store/index.d.ts +42 -15
- package/dist/types/store/optimistic.d.ts +24 -45
- package/dist/types/store/projection.d.ts +17 -68
- package/dist/types/store/reconcile.d.ts +3 -46
- package/dist/types/store/store.d.ts +133 -136
- package/dist/types/store/storePath.d.ts +1 -1
- package/dist/types/store/target.d.ts +166 -0
- package/dist/types/store/types.d.ts +105 -0
- package/dist/types/store/utils.d.ts +188 -0
- package/package.json +31 -26
- package/dist/node.cjs +0 -8745
- package/dist/prod/core/optimistic.js +0 -265
- package/dist/prod/store/next/optimistic.js +0 -385
- package/dist/prod/store/next/projection.js +0 -172
- package/dist/prod/store/next/reconcile.js +0 -331
- package/dist/prod/store/next/store.js +0 -1499
- package/dist/prod/store/next/target.js +0 -20
- package/dist/types/core/optimistic.d.ts +0 -6
- package/dist/types/store/next/optimistic.d.ts +0 -20
- package/dist/types/store/next/projection.d.ts +0 -8
- package/dist/types/store/next/reconcile.d.ts +0 -3
- package/dist/types/store/next/store.d.ts +0 -77
- package/dist/types/store/next/target.d.ts +0 -117
- 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/attribution-hooks.d.cts +0 -52
- package/dist/types-cjs/core/attribution.d.cts +0 -186
- package/dist/types-cjs/core/constants.d.cts +0 -97
- package/dist/types-cjs/core/context.d.cts +0 -36
- package/dist/types-cjs/core/core.d.cts +0 -163
- package/dist/types-cjs/core/dev.d.cts +0 -81
- 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 -6
- 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 -180
- package/dist/types-cjs/core/types.d.cts +0 -192
- 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 -624
- package/dist/types-cjs/store/index.d.cts +0 -19
- package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
- package/dist/types-cjs/store/next/projection.d.cts +0 -8
- package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
- package/dist/types-cjs/store/next/store.d.cts +0 -77
- package/dist/types-cjs/store/next/target.d.cts +0 -117
- 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 -138
- package/dist/types-cjs/store/storePath.d.cts +0 -58
- package/dist/types-cjs/store/utils.d.cts +0 -74
|
@@ -1,24 +1,75 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ChangeOrigin } from "./attribution.js";
|
|
2
|
+
import type { Transaction } from "./scheduler.js";
|
|
3
|
+
import type { Computed, Owner, Signal } from "./types.js";
|
|
4
|
+
/** The hold the engine records against (L2: scheduler.ts `Transaction`).
|
|
5
|
+
* Outward-facing language says *holds*; the engine's hook names keep their
|
|
6
|
+
* historical `transition` wording. */
|
|
7
|
+
export type Transition = Transaction;
|
|
2
8
|
/**
|
|
3
|
-
*
|
|
9
|
+
* Observe-tier hook points for the reactive core.
|
|
4
10
|
*
|
|
5
11
|
* Core's obligation is to call these with true facts at the moments they
|
|
6
12
|
* happen; ALL attribution semantics (stamps, cause chains, timings, warnings)
|
|
7
|
-
* live in the engine that installs them
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* live in the engine that installs them — `@solidjs/signals/attribution`, a
|
|
14
|
+
* separate entry so an observe build that never enables it never ships it
|
|
15
|
+
* (same pattern as the GlobalQueue._* feature slots). `attrHooks` is null
|
|
16
|
+
* unless an engine is installed, so the disabled cost is one null check per
|
|
17
|
+
* site, and prod builds fold every site out behind __OBSERVE__.
|
|
18
|
+
*
|
|
19
|
+
* The contract is internal: the built-in engine installs through
|
|
20
|
+
* `setAttributionHooks`, and nothing public names this interface
|
|
21
|
+
* (`OBSERVE.attribution.installed` exposes the installed table as an opaque
|
|
22
|
+
* object). It becomes public surface again the day a second engine exists.
|
|
11
23
|
*
|
|
12
24
|
* IMPORTANT for implementers of call sites: a hook call must never sit inside
|
|
13
25
|
* a `try` block — rollup's tryCatchDeoptimization retains functions referenced
|
|
14
|
-
* inside `try` even behind a folded
|
|
26
|
+
* inside `try` even behind a folded __OBSERVE__ guard, which re-couples the
|
|
15
27
|
* engine into prod bundles (#2883 harness). Set a local flag inside the try
|
|
16
28
|
* and call the hook after the catch.
|
|
17
29
|
*/
|
|
18
30
|
export interface AttributionHooks {
|
|
31
|
+
/**
|
|
32
|
+
* `withInteraction` opened a user-interaction frame: root writes until the
|
|
33
|
+
* matching `interactionEnd` were performed by the handler of `ref`. Frames
|
|
34
|
+
* nest strictly (synchronous dispatch), so the engine keeps a stack.
|
|
35
|
+
*/
|
|
36
|
+
interactionStart(ref: InteractionRef): void;
|
|
37
|
+
/**
|
|
38
|
+
* The handler returned. `returned` is its return value: a thenable means
|
|
39
|
+
* the handler continues past this frame (`async () => { await … }`), and
|
|
40
|
+
* the engine may keep the interaction's record open until it settles —
|
|
41
|
+
* the wait the person experiences is that continuation, not the frame.
|
|
42
|
+
*/
|
|
43
|
+
interactionEnd(returned?: unknown): void;
|
|
44
|
+
/**
|
|
45
|
+
* `withOrigin` opened a declared-origin frame: root writes until the
|
|
46
|
+
* matching `originEnd` are the unit of work `ref` describes (a router's
|
|
47
|
+
* navigation). Nests inside an interaction frame — a link click that
|
|
48
|
+
* navigates — or stands alone (a redirect from an action, a programmatic
|
|
49
|
+
* `navigate()`). Frames nest strictly, so the engine keeps a stack.
|
|
50
|
+
*/
|
|
51
|
+
originStart(ref: NavigationRef): void;
|
|
52
|
+
originEnd(): void;
|
|
53
|
+
/**
|
|
54
|
+
* A `flush()` drain is starting: work is scheduled or a transition is
|
|
55
|
+
* active, so the loop will run at least once. Always paired with
|
|
56
|
+
* `flushEnd` for the same drain, and never nested (`flush()` is a no-op
|
|
57
|
+
* while the queue is running), so start → end is the wall time of one
|
|
58
|
+
* drain — the scheduler's own span.
|
|
59
|
+
*/
|
|
60
|
+
flushStart(): void;
|
|
61
|
+
/**
|
|
62
|
+
* A `flush()` drain finished: every batch it processed either committed
|
|
63
|
+
* (its effects have run) or was parked in a held transition (`holdStart`
|
|
64
|
+
* fired for it). Fires once per drain, after the loop — not per batch, and
|
|
65
|
+
* not for a `flush()` call that found nothing to do. Gives the engine the
|
|
66
|
+
* "committed, screen updated" instant for writes no transition ever held.
|
|
67
|
+
*/
|
|
68
|
+
flushEnd(): void;
|
|
19
69
|
/**
|
|
20
70
|
* A recompute is starting; `el._deps` still holds the previous run's links.
|
|
21
|
-
* Always paired with `recomputeEnd` (recompute
|
|
71
|
+
* Always paired with `recomputeEnd` (recompute's one early return — a node
|
|
72
|
+
* disposed during its own pass, #3621 — fires it before leaving).
|
|
22
73
|
*/
|
|
23
74
|
recomputeStart(el: Computed<any>, create: boolean): void;
|
|
24
75
|
/**
|
|
@@ -36,6 +87,17 @@ export interface AttributionHooks {
|
|
|
36
87
|
write(el: Signal<any> | Computed<any>, prev: unknown, value: unknown): void;
|
|
37
88
|
/** refresh() invalidated this node (self-invalidation, no dep changed). */
|
|
38
89
|
refreshed(el: Computed<any>): void;
|
|
90
|
+
/**
|
|
91
|
+
* A new async flight entered the system (`_inFlight` was just assigned
|
|
92
|
+
* during a recompute of `el`). Always fired inside the owning recompute —
|
|
93
|
+
* both call paths (core's recompute and the projection self-registration)
|
|
94
|
+
* run within one — so the engine can read the current frame stack to link
|
|
95
|
+
* the flight to the change that caused it (waterfall chaining). `flight`
|
|
96
|
+
* is the registered thenable/iterable itself: the engine keys a first-seen
|
|
97
|
+
* origin registry on its identity, so shared and preloader-marked promises
|
|
98
|
+
* carry their true start time instead of the moment the graph saw them.
|
|
99
|
+
*/
|
|
100
|
+
flightStart(el: Computed<any>, flight: object): void;
|
|
39
101
|
/** An async landing is about to apply its value (before any branch). */
|
|
40
102
|
asyncStart(el: Computed<any>): void;
|
|
41
103
|
/**
|
|
@@ -47,6 +109,243 @@ export interface AttributionHooks {
|
|
|
47
109
|
* from the node's state against its asyncStart snapshot.
|
|
48
110
|
*/
|
|
49
111
|
asyncEnd(el: Computed<any>, prev: unknown, value: unknown, direct: boolean): void;
|
|
112
|
+
/**
|
|
113
|
+
* An effect's imperative half (its effect callback) is about to run /
|
|
114
|
+
* has run. Both fire outside the run's try; `effectRunEnd` fires whether
|
|
115
|
+
* or not the callback threw. Writes between the two are the effect's.
|
|
116
|
+
*/
|
|
117
|
+
effectRunStart(el: Computed<any>): void;
|
|
118
|
+
effectRunEnd(el: Computed<any>): void;
|
|
119
|
+
/**
|
|
120
|
+
* One synchronous step of an `action()` generator is about to run / has
|
|
121
|
+
* run (`it.next()`/`it.throw()` up to the next yield). `it` is the
|
|
122
|
+
* invocation's iterator — stable identity across its steps; `name` the
|
|
123
|
+
* generator function's name. Writes between the two are the action's.
|
|
124
|
+
*/
|
|
125
|
+
actionStepStart(it: object, name: string | undefined): void;
|
|
126
|
+
actionStepEnd(it: object): void;
|
|
127
|
+
/**
|
|
128
|
+
* A flush found `t` incomplete (transitionComplete's false verdict): its
|
|
129
|
+
* writes stay staged and its queues are about to be parked. Fired BEFORE
|
|
130
|
+
* this flush's lane effects (the visible acknowledgers — isPending
|
|
131
|
+
* companions, optimistic values) run; `holdEnd` fires from the root
|
|
132
|
+
* stashQueues call after them, so effect runs between the two are runs that
|
|
133
|
+
* painted *during* the hold.
|
|
134
|
+
*/
|
|
135
|
+
holdStart(t: Transition): void;
|
|
136
|
+
holdEnd(): void;
|
|
137
|
+
/**
|
|
138
|
+
* `t` was judged complete (transitionComplete's true verdict, before `_done`
|
|
139
|
+
* flips). Fired before its held writes commit, so `t._pendingNodes` still
|
|
140
|
+
* lists what was staged.
|
|
141
|
+
*/
|
|
142
|
+
transitionSettled(t: Transition): void;
|
|
143
|
+
/** `outgoing` was folded into `target` (`outgoing._done = target`). */
|
|
144
|
+
transitionMerged(target: Transition, outgoing: Transition): void;
|
|
145
|
+
/**
|
|
146
|
+
* A store setter batch replaced the container at `path` (e.g. `store.user`)
|
|
147
|
+
* with a different one (both non-null, same array-ness, not the same
|
|
148
|
+
* logical slot), and this is the leaf census of the new container against
|
|
149
|
+
* the old: `total` leaves (own keys, or items) in the new one, `unchanged`
|
|
150
|
+
* of which are the same value as before (identity, judged on unwrapped
|
|
151
|
+
* values — object keys compared by key, array items by membership), and
|
|
152
|
+
* `prevTotal` leaves in the old one. Containers above 64 leaves are not
|
|
153
|
+
* announced. Fired per written key from the write channel's notify. The
|
|
154
|
+
* engine decides whether the replacement was a spread-copy worth a
|
|
155
|
+
* diagnostic. `owner` is the owner the store root was created under
|
|
156
|
+
* (undefined when unrecorded): the finding is about the store, not about
|
|
157
|
+
* whoever wrote it, so an `OBSERVE.exclude`d panel's store stays silent
|
|
158
|
+
* however its writes arrive.
|
|
159
|
+
*/
|
|
160
|
+
storeReplaced(path: string, isArray: boolean, total: number, unchanged: number, prevTotal: number, owner: Owner | null | undefined): void;
|
|
161
|
+
/**
|
|
162
|
+
* A `mapArray` update both disposed and created rows: `removed` are the
|
|
163
|
+
* items whose rows were disposed, `created` the items that got new rows,
|
|
164
|
+
* `newLen` the list's new length, `keyed` whether a key function is in use
|
|
165
|
+
* (false = identity or by-index). Fired after commit. The engine judges
|
|
166
|
+
* whether the churn replaced equivalent records (unstable identity).
|
|
167
|
+
*/
|
|
168
|
+
listChurn(el: Computed<any>, removed: unknown[], created: unknown[], newLen: number, keyed: boolean): void;
|
|
169
|
+
/**
|
|
170
|
+
* A loading boundary started (`shown` true) or stopped showing its
|
|
171
|
+
* fallback. `boundary` is the boundary's queue (stable identity); `tree`
|
|
172
|
+
* its bound subtree computed when already constructed — the first show can
|
|
173
|
+
* fire while the subtree is still being built — whose owner chain names
|
|
174
|
+
* the boundary. Fired at the source-set transitions (first pending source
|
|
175
|
+
* registers / last one clears), not per flush.
|
|
176
|
+
*
|
|
177
|
+
* A show is the boundary's SWAP, a staged write: `transition` is the one
|
|
178
|
+
* it lands with (`transitionSettled` is its display instant), or `null`
|
|
179
|
+
* when this drain commits it (`flushEnd`) — the lane swap included, whose
|
|
180
|
+
* readers run in this drain. A hide before that commit means the fallback
|
|
181
|
+
* was never displayed — the content landed first and the sweep cleared the
|
|
182
|
+
* swap ahead of the frame (#3540).
|
|
183
|
+
*/
|
|
184
|
+
boundaryFallback(boundary: object, tree: Computed<any> | undefined, shown: boolean, transition?: Transition | null): void;
|
|
185
|
+
/**
|
|
186
|
+
* An optimistic override the screen displayed is being replaced by a
|
|
187
|
+
* different value. `"superseded"`: a new authoritative value landed that
|
|
188
|
+
* differs from the guess (tracked readers re-derive to it). `"reverted"`:
|
|
189
|
+
* nothing new landed and the guess lifts back to the committed value it
|
|
190
|
+
* covered (the action failed, or never wrote what it promised). `shown`
|
|
191
|
+
* is the override as displayed. Fired when the two differ by identity;
|
|
192
|
+
* the engine applies the node's own equality before judging.
|
|
193
|
+
*/
|
|
194
|
+
optimisticReverted(el: Signal<any> | Computed<any>, shown: unknown, truth: unknown, how: "superseded" | "reverted"): void;
|
|
195
|
+
/**
|
|
196
|
+
* The one query on the surface: the provenance a root write performed at
|
|
197
|
+
* this moment would be stamped with — the innermost open frame (an effect
|
|
198
|
+
* callback, an action step, a navigation), the interaction the handler
|
|
199
|
+
* runs under, or, inside a recompute, the origin of the change that caused
|
|
200
|
+
* it — or `undefined` when none applies (external). For a runtime that
|
|
201
|
+
* records a fact of its own beside the engine's records — `@solidjs/web`'s
|
|
202
|
+
* `"call"` record stamps the server-function call it is about to make —
|
|
203
|
+
* so the fact joins the engine's interaction and navigation records by the
|
|
204
|
+
* identity of the object returned, not by time.
|
|
205
|
+
*/
|
|
206
|
+
currentOrigin(): ChangeOrigin | undefined;
|
|
207
|
+
}
|
|
208
|
+
/** A user interaction, as a rendering runtime describes it to `withInteraction`. */
|
|
209
|
+
export interface InteractionRef {
|
|
210
|
+
/** Event type — `click`, `keydown`, `input`… */
|
|
211
|
+
type: string;
|
|
212
|
+
/**
|
|
213
|
+
* The element hit, e.g. `button#next "Next →"` — the tag, then `#id` or
|
|
214
|
+
* `[name=…]`, then the element's text in quotes. Describe fully; the
|
|
215
|
+
* engine keeps the quoted text as its `values` option allows (the
|
|
216
|
+
* record's `target` is its own string, this one is never mutated).
|
|
217
|
+
*/
|
|
218
|
+
target?: string;
|
|
219
|
+
/** Dispatch time on the `performance.now()` clock; defaults to now. */
|
|
220
|
+
at?: number;
|
|
221
|
+
/**
|
|
222
|
+
* The dispatch this frame handles — the DOM `Event` itself. Frames with the
|
|
223
|
+
* same `event` are one interaction: the first opens the record (its `type`,
|
|
224
|
+
* `target` and `at` describe it) and every later one re-enters it, so each
|
|
225
|
+
* listener of one dispatch adds its work to one record. Such a record stays
|
|
226
|
+
* open for joining until the next task — every listener of a dispatch runs
|
|
227
|
+
* within its task — and is recorded no earlier; a frame for the event after
|
|
228
|
+
* that opens a new interaction. Without `event` the record is the frame's
|
|
229
|
+
* alone and can settle as it closes.
|
|
230
|
+
*
|
|
231
|
+
* A join key only, compared by identity and held weakly: it is never
|
|
232
|
+
* recorded — no `InteractionEvent`, origin or other record carries it — and
|
|
233
|
+
* the engine keeps no strong reference to it.
|
|
234
|
+
*/
|
|
235
|
+
event?: object;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* A navigation, as a router describes it to `withOrigin` around the location
|
|
239
|
+
* write it is about to perform — what `withOrigin` accepts: a declared unit
|
|
240
|
+
* of work whose writes the engine attributes as a whole, discriminated by
|
|
241
|
+
* `kind` so another kind (a form submission, a tab switch) can join without
|
|
242
|
+
* the seam changing shape; the engine knows `navigation` today. Match
|
|
243
|
+
* eagerly and describe before writing: the engine keys the work the write
|
|
244
|
+
* causes — the hold behind route data, the re-runs, the verdicts — to this
|
|
245
|
+
* record, and names it by the parametrized route so occurrences fold
|
|
246
|
+
* together.
|
|
247
|
+
*
|
|
248
|
+
* The engine keeps the object and reads `name`, `to` and `params` again when
|
|
249
|
+
* the navigation settles (and when a hold on it is judged), so a router whose
|
|
250
|
+
* match is not final at write time — a lazy route subtree that resolves inside
|
|
251
|
+
* the hold — may describe coarsely (`/admin/*`) and assign the exact pattern
|
|
252
|
+
* and params onto the same object once it knows them. `from` and `at` are
|
|
253
|
+
* read once, when the frame opens.
|
|
254
|
+
*/
|
|
255
|
+
export interface NavigationRef {
|
|
256
|
+
kind: "navigation";
|
|
257
|
+
/** The matched route pattern — `/users/:id`. The name every consumer groups by. */
|
|
258
|
+
name?: string;
|
|
259
|
+
/** Concrete destination path. */
|
|
260
|
+
to?: string;
|
|
261
|
+
/** Concrete path being left. */
|
|
262
|
+
from?: string;
|
|
263
|
+
/** Route params the pattern bound — `{ id: "42" }` (optional params unbound: `undefined`). */
|
|
264
|
+
params?: Readonly<Record<string, string | undefined>>;
|
|
265
|
+
/**
|
|
266
|
+
* When the navigation was requested on the `performance.now()` clock;
|
|
267
|
+
* defaults to now. A router whose request predates the write (loaders
|
|
268
|
+
* awaited before the location moves) passes its own start here.
|
|
269
|
+
*/
|
|
270
|
+
at?: number;
|
|
271
|
+
/**
|
|
272
|
+
* `>= 1`: this frame is the Nth redirect hop of the navigation still
|
|
273
|
+
* pending — a guard or loader sent it elsewhere before it landed — not a
|
|
274
|
+
* new navigation. The engine folds it onto that pending record: the record
|
|
275
|
+
* keeps the user's request time and interaction, its destination becomes
|
|
276
|
+
* this one, and the abandoned destination is kept in `redirects`. Without
|
|
277
|
+
* a pending navigation to fold onto it opens a navigation of its own.
|
|
278
|
+
*/
|
|
279
|
+
redirect?: number;
|
|
280
|
+
/**
|
|
281
|
+
* The route the document arrived on — declared by the router around the
|
|
282
|
+
* work that establishes its initial match (building its context), not
|
|
283
|
+
* around a write: there is no location write on a fresh document, and
|
|
284
|
+
* without this a consumer has the route pattern for every navigation
|
|
285
|
+
* but the first. The record opens at `at`, which defaults to `0` (the
|
|
286
|
+
* `performance.now()` origin — the document's own navigation start, so
|
|
287
|
+
* the record joins Navigation Timing); a router mounted long after the
|
|
288
|
+
* document loaded passes its own start. It settles when the frame closes,
|
|
289
|
+
* `committed` with no writes: it declares the route, it does not time the
|
|
290
|
+
* mount — the holds the mount waits in are their own records. `from` is
|
|
291
|
+
* meaningless for it and ignored.
|
|
292
|
+
*/
|
|
293
|
+
initial?: boolean;
|
|
294
|
+
/**
|
|
295
|
+
* The interaction the navigation is for, when the router already knows it
|
|
296
|
+
* will not be on the stack at write time. A router that awaits between
|
|
297
|
+
* the request and the write (guards or loaders resolved in its core before
|
|
298
|
+
* it publishes the location) captures `OBSERVE.attribution.currentOrigin()`
|
|
299
|
+
* in the request and hands it back here, and the record — and every hold
|
|
300
|
+
* and re-run its write causes — joins the click as if the write had been
|
|
301
|
+
* synchronous. Any origin will do: the engine takes the interaction it
|
|
302
|
+
* carries. Declared beats ambient: the key's presence is the declaration
|
|
303
|
+
* — `interaction: currentOrigin()` with nothing in effect at the request
|
|
304
|
+
* (`undefined`) declares that the navigation was for no interaction, and an
|
|
305
|
+
* interaction on the stack at write time is used only when the key is absent.
|
|
306
|
+
*/
|
|
307
|
+
interaction?: ChangeOrigin;
|
|
50
308
|
}
|
|
51
309
|
export declare let attrHooks: AttributionHooks | null;
|
|
52
310
|
export declare function setAttributionHooks(hooks: AttributionHooks | null): void;
|
|
311
|
+
/**
|
|
312
|
+
* Run `fn` as the handler of a user interaction: every root write it performs
|
|
313
|
+
* (and every action step, effect or flight the write causes) is attributed to
|
|
314
|
+
* `ref` by whichever engine is installed. The web runtime wraps event
|
|
315
|
+
* dispatch in this; custom renderers and test harnesses call it themselves.
|
|
316
|
+
* With no engine installed it is `fn()` — the wiring, not the engine, so it
|
|
317
|
+
* lives in core and is reachable as `OBSERVE.attribution.withInteraction`.
|
|
318
|
+
*
|
|
319
|
+
* The `finally` is deliberate and safe under the try rule above: this
|
|
320
|
+
* function is referenced only from the `OBSERVE` object, which prod builds
|
|
321
|
+
* fold to `undefined`, so nothing retains it there.
|
|
322
|
+
*/
|
|
323
|
+
export declare function withInteraction<T>(ref: InteractionRef, fn: () => T): T;
|
|
324
|
+
/**
|
|
325
|
+
* Run `fn` as a declared unit of work — a router's navigation: every root
|
|
326
|
+
* write it performs is attributed to `ref` (and, through it, to the enclosing
|
|
327
|
+
* interaction when there is one), so the hold those writes wait in, the
|
|
328
|
+
* re-runs they cause and the verdicts on them all carry the route's name
|
|
329
|
+
* instead of a bare signal's. Same contract as `withInteraction`: the wiring,
|
|
330
|
+
* not the engine; `fn()` with no engine installed. Reachable as
|
|
331
|
+
* `OBSERVE.attribution.withOrigin`.
|
|
332
|
+
*
|
|
333
|
+
* ```ts
|
|
334
|
+
* OBSERVE
|
|
335
|
+
* ? OBSERVE.attribution.withOrigin(
|
|
336
|
+
* { kind: "navigation", name: match.pattern, to, from, params: match.params },
|
|
337
|
+
* () => setLocation(to)
|
|
338
|
+
* )
|
|
339
|
+
* : setLocation(to);
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
export declare function withOrigin<T>(ref: NavigationRef, fn: () => T): T;
|
|
343
|
+
/**
|
|
344
|
+
* The provenance a root write performed now would carry, as the installed
|
|
345
|
+
* engine sees it (`AttributionHooks.currentOrigin`); `undefined` with no
|
|
346
|
+
* engine, or when nothing is in effect. Reachable as
|
|
347
|
+
* `OBSERVE.attribution.currentOrigin` — how a runtime stamps a fact of its
|
|
348
|
+
* own (a server-function call) with the interaction or navigation it ran
|
|
349
|
+
* for, so an observer joins the two by identity.
|
|
350
|
+
*/
|
|
351
|
+
export declare function currentOrigin(): ChangeOrigin | undefined;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Point queries over the engine's live state — the devtools/console view of
|
|
3
|
+
* one scope. Their own module so a records-only consumer never ships them;
|
|
4
|
+
* they read the engine's ring buffer and the graph, and register nothing.
|
|
5
|
+
*/
|
|
6
|
+
import { type RerunEvent } from "./attribution.js";
|
|
7
|
+
/**
|
|
8
|
+
* Re-run history for one scope — pass a memo/effect accessor or raw node,
|
|
9
|
+
* or a scope's name as a string (an out-of-process consumer such as the
|
|
10
|
+
* diagnostics bridge holds no node, only the `nodeName` the records
|
|
11
|
+
* carry). Records name their scope by `nodeId`; a node that has never run
|
|
12
|
+
* under the engine has none, and no history. By name, every scope of that
|
|
13
|
+
* name answers. A view of `history("rerun")`, so it shares that buffer's
|
|
14
|
+
* gate: runs nothing wanted a record of (no `rerun` listener, fold or log
|
|
15
|
+
* at the time) left no record and are not here — a console session that
|
|
16
|
+
* wants them subscribes or imports a fold first.
|
|
17
|
+
*/
|
|
18
|
+
export declare function why(target: unknown): RerunEvent[];
|
|
19
|
+
/**
|
|
20
|
+
* Current dependency names of one scope — the devtools subscription view.
|
|
21
|
+
* Read from the graph, not a record, so it answers with or without an
|
|
22
|
+
* audience for re-run records (and with the engine disabled).
|
|
23
|
+
*/
|
|
24
|
+
export declare function subscriptions(target: unknown): string[];
|