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