@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.
Files changed (198) hide show
  1. package/dist/dev-shared.js +6505 -0
  2. package/dist/dev.attribution.js +3484 -0
  3. package/dist/dev.js +10227 -9508
  4. package/dist/observe/affects-marks.js +86 -0
  5. package/dist/observe/affects.js +112 -0
  6. package/dist/observe/attribution.js +7 -0
  7. package/dist/observe/boundaries.js +696 -0
  8. package/dist/observe/core/action.js +182 -0
  9. package/dist/observe/core/async.js +824 -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 +3079 -0
  15. package/dist/observe/core/constants.js +269 -0
  16. package/dist/observe/core/context.js +63 -0
  17. package/dist/observe/core/copies.js +10 -0
  18. package/dist/observe/core/core.js +1707 -0
  19. package/dist/observe/core/dev.js +394 -0
  20. package/dist/observe/core/effect.js +193 -0
  21. package/dist/observe/core/error-hooks.js +71 -0
  22. package/dist/observe/core/error.js +82 -0
  23. package/dist/observe/core/external.js +97 -0
  24. package/dist/observe/core/graph.js +162 -0
  25. package/dist/observe/core/heap.js +124 -0
  26. package/dist/observe/core/identities.js +62 -0
  27. package/dist/observe/core/invariants.js +12 -0
  28. package/dist/observe/core/lanes.js +972 -0
  29. package/dist/observe/core/owner.js +371 -0
  30. package/dist/observe/core/scheduler.js +1157 -0
  31. package/dist/observe/core/truth.js +47 -0
  32. package/dist/observe/core/verdict.js +470 -0
  33. package/dist/observe/deferred.js +186 -0
  34. package/dist/observe/flatten.js +79 -0
  35. package/dist/observe/from.js +248 -0
  36. package/dist/observe/index.js +71 -0
  37. package/dist/observe/map.js +593 -0
  38. package/dist/observe/reveal.js +212 -0
  39. package/dist/observe/signals.js +717 -0
  40. package/dist/observe/store/affects.js +142 -0
  41. package/dist/observe/store/edges.js +39 -0
  42. package/dist/observe/store/hooks.js +16 -0
  43. package/dist/observe/store/index.js +47 -0
  44. package/dist/observe/store/optimistic.js +713 -0
  45. package/dist/observe/store/projection.js +345 -0
  46. package/dist/observe/store/reconcile.js +281 -0
  47. package/dist/observe/store/store.js +2127 -0
  48. package/dist/observe/store/storePath.js +103 -0
  49. package/dist/observe/store/target.js +46 -0
  50. package/dist/observe/store/types.js +83 -0
  51. package/dist/observe/store/utils.js +1063 -0
  52. package/dist/prod/affects-marks.js +86 -0
  53. package/dist/prod/affects.js +98 -112
  54. package/dist/prod/attribution.js +45 -0
  55. package/dist/prod/boundaries.js +578 -468
  56. package/dist/prod/core/action.js +92 -59
  57. package/dist/prod/core/async.js +522 -336
  58. package/dist/prod/core/attribution-hooks.js +3 -0
  59. package/dist/prod/core/constants.js +168 -44
  60. package/dist/prod/core/context.js +12 -16
  61. package/dist/prod/core/copies.js +10 -0
  62. package/dist/prod/core/core.js +1345 -627
  63. package/dist/prod/core/dev.js +123 -1
  64. package/dist/prod/core/effect.js +113 -80
  65. package/dist/prod/core/error-hooks.js +71 -0
  66. package/dist/prod/core/error.js +18 -4
  67. package/dist/prod/core/external.js +6 -7
  68. package/dist/prod/core/graph.js +119 -72
  69. package/dist/prod/core/heap.js +85 -109
  70. package/dist/prod/core/identities.js +62 -0
  71. package/dist/prod/core/invariants.js +1 -32
  72. package/dist/prod/core/lanes.js +931 -132
  73. package/dist/prod/core/owner.js +192 -129
  74. package/dist/prod/core/scheduler.js +948 -642
  75. package/dist/prod/core/truth.js +47 -0
  76. package/dist/prod/core/verdict.js +409 -420
  77. package/dist/prod/deferred.js +184 -0
  78. package/dist/prod/flatten.js +77 -0
  79. package/dist/prod/from.js +248 -0
  80. package/dist/prod/index.js +40 -16
  81. package/dist/prod/map.js +481 -211
  82. package/dist/prod/reveal.js +212 -0
  83. package/dist/prod/signals.js +401 -84
  84. package/dist/prod/store/affects.js +142 -0
  85. package/dist/prod/store/edges.js +39 -0
  86. package/dist/prod/store/hooks.js +16 -0
  87. package/dist/prod/store/index.js +27 -18
  88. package/dist/prod/store/optimistic.js +707 -0
  89. package/dist/prod/store/projection.js +331 -0
  90. package/dist/prod/store/reconcile.js +281 -0
  91. package/dist/prod/store/store.js +1952 -267
  92. package/dist/prod/store/storePath.js +1 -1
  93. package/dist/prod/store/target.js +43 -0
  94. package/dist/prod/store/types.js +83 -0
  95. package/dist/prod/store/utils.js +997 -138
  96. package/dist/types/affects-marks.d.ts +14 -0
  97. package/dist/types/affects.d.ts +12 -30
  98. package/dist/types/attribution.d.ts +19 -0
  99. package/dist/types/attribution.prod.d.ts +22 -0
  100. package/dist/types/boundaries.d.ts +99 -124
  101. package/dist/types/carved.d.ts +1 -0
  102. package/dist/types/core/action.d.ts +23 -9
  103. package/dist/types/core/async.d.ts +34 -6
  104. package/dist/types/core/attribution-costs.d.ts +35 -0
  105. package/dist/types/core/attribution-feedback.d.ts +133 -0
  106. package/dist/types/core/attribution-hooks.d.ts +307 -8
  107. package/dist/types/core/attribution-queries.d.ts +24 -0
  108. package/dist/types/core/attribution.d.ts +802 -72
  109. package/dist/types/core/constants.d.ts +195 -38
  110. package/dist/types/core/copies.d.ts +54 -0
  111. package/dist/types/core/core.d.ts +295 -65
  112. package/dist/types/core/dev.d.ts +509 -22
  113. package/dist/types/core/effect.d.ts +1 -1
  114. package/dist/types/core/error-hooks.d.ts +71 -0
  115. package/dist/types/core/error.d.ts +18 -1
  116. package/dist/types/core/graph.d.ts +40 -1
  117. package/dist/types/core/heap.d.ts +5 -5
  118. package/dist/types/core/identities.d.ts +17 -0
  119. package/dist/types/core/index.d.ts +11 -7
  120. package/dist/types/core/invariants.d.ts +1 -26
  121. package/dist/types/core/lanes.d.ts +74 -43
  122. package/dist/types/core/owner.d.ts +27 -9
  123. package/dist/types/core/scheduler.d.ts +353 -102
  124. package/dist/types/core/truth.d.ts +18 -0
  125. package/dist/types/core/types.d.ts +97 -71
  126. package/dist/types/core/verdict.d.ts +35 -0
  127. package/dist/types/deferred.d.ts +28 -0
  128. package/dist/types/flatten.d.ts +8 -0
  129. package/dist/types/from.d.ts +47 -0
  130. package/dist/types/index.d.ts +33 -7
  131. package/dist/types/map.d.ts +4 -2
  132. package/dist/types/reveal.d.ts +19 -0
  133. package/dist/types/signals.d.ts +196 -45
  134. package/dist/types/store/affects.d.ts +12 -0
  135. package/dist/types/store/edges.d.ts +9 -0
  136. package/dist/types/store/hooks.d.ts +62 -0
  137. package/dist/types/store/index.d.ts +42 -15
  138. package/dist/types/store/optimistic.d.ts +24 -45
  139. package/dist/types/store/projection.d.ts +17 -68
  140. package/dist/types/store/reconcile.d.ts +3 -46
  141. package/dist/types/store/store.d.ts +133 -136
  142. package/dist/types/store/storePath.d.ts +1 -1
  143. package/dist/types/store/target.d.ts +166 -0
  144. package/dist/types/store/types.d.ts +105 -0
  145. package/dist/types/store/utils.d.ts +188 -0
  146. package/package.json +31 -26
  147. package/dist/node.cjs +0 -8745
  148. package/dist/prod/core/optimistic.js +0 -265
  149. package/dist/prod/store/next/optimistic.js +0 -385
  150. package/dist/prod/store/next/projection.js +0 -172
  151. package/dist/prod/store/next/reconcile.js +0 -331
  152. package/dist/prod/store/next/store.js +0 -1499
  153. package/dist/prod/store/next/target.js +0 -20
  154. package/dist/types/core/optimistic.d.ts +0 -6
  155. package/dist/types/store/next/optimistic.d.ts +0 -20
  156. package/dist/types/store/next/projection.d.ts +0 -8
  157. package/dist/types/store/next/reconcile.d.ts +0 -3
  158. package/dist/types/store/next/store.d.ts +0 -77
  159. package/dist/types/store/next/target.d.ts +0 -117
  160. package/dist/types-cjs/affects.d.cts +0 -47
  161. package/dist/types-cjs/boundaries.d.cts +0 -175
  162. package/dist/types-cjs/core/action.d.cts +0 -64
  163. package/dist/types-cjs/core/async.d.cts +0 -21
  164. package/dist/types-cjs/core/attribution-hooks.d.cts +0 -52
  165. package/dist/types-cjs/core/attribution.d.cts +0 -186
  166. package/dist/types-cjs/core/constants.d.cts +0 -97
  167. package/dist/types-cjs/core/context.d.cts +0 -36
  168. package/dist/types-cjs/core/core.d.cts +0 -163
  169. package/dist/types-cjs/core/dev.d.cts +0 -81
  170. package/dist/types-cjs/core/effect.d.cts +0 -30
  171. package/dist/types-cjs/core/error.d.cts +0 -47
  172. package/dist/types-cjs/core/external.d.cts +0 -15
  173. package/dist/types-cjs/core/graph.d.cts +0 -6
  174. package/dist/types-cjs/core/heap.d.cts +0 -22
  175. package/dist/types-cjs/core/index.d.cts +0 -13
  176. package/dist/types-cjs/core/invariants.d.cts +0 -59
  177. package/dist/types-cjs/core/lanes.d.cts +0 -44
  178. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  179. package/dist/types-cjs/core/owner.d.cts +0 -124
  180. package/dist/types-cjs/core/scheduler.d.cts +0 -180
  181. package/dist/types-cjs/core/types.d.cts +0 -192
  182. package/dist/types-cjs/core/verdict.d.cts +0 -2
  183. package/dist/types-cjs/index.d.cts +0 -10
  184. package/dist/types-cjs/map.d.cts +0 -69
  185. package/dist/types-cjs/package.json +0 -3
  186. package/dist/types-cjs/signals.d.cts +0 -624
  187. package/dist/types-cjs/store/index.d.cts +0 -19
  188. package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
  189. package/dist/types-cjs/store/next/projection.d.cts +0 -8
  190. package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
  191. package/dist/types-cjs/store/next/store.d.cts +0 -77
  192. package/dist/types-cjs/store/next/target.d.cts +0 -117
  193. package/dist/types-cjs/store/optimistic.d.cts +0 -45
  194. package/dist/types-cjs/store/projection.d.cts +0 -70
  195. package/dist/types-cjs/store/reconcile.d.cts +0 -46
  196. package/dist/types-cjs/store/store.d.cts +0 -138
  197. package/dist/types-cjs/store/storePath.d.cts +0 -58
  198. package/dist/types-cjs/store/utils.d.cts +0 -74
@@ -1,25 +1,39 @@
1
- import { type Refreshable } from "./constants.js";
2
- import { type OptimisticLane } from "./lanes.js";
3
- import type { Computed, FirewallSignal, NodeExtension, NodeOptions, Owner, Signal } from "./types.js";
1
+ import type { Transaction } from "./scheduler.js";
2
+ import type { Computed, NodeExtension, NodeOptions, Owner, Signal } from "./types.js";
4
3
  export declare const PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE = "[PRIMITIVE_IN_FORBIDDEN_SCOPE] Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled";
4
+ export declare const PRIMITIVE_IN_EFFECT_CALLBACK_MESSAGE: string;
5
+ /** Dev: the effect phase (render and user effects, their cleanups) runs with
6
+ * no ambient owner, and a computation created there with none is outside
7
+ * every owner and every hold (maintainer, 2026-10-01: ownerless only —
8
+ * `runWithOwner` in a callback is deliberate, Portal and createReaction do
9
+ * it; a bare createRoot is the mistake). Computeds and roots; a signal
10
+ * created there is inert and harmless. Tracked effects and onSettled are
11
+ * children-forbidden and refuse through PRIMITIVE_IN_FORBIDDEN_SCOPE. */
12
+ export declare function assertNotInEffectCallback(): void;
5
13
  export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE: string;
6
14
  export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE: string;
7
15
  export declare let tracking: boolean;
8
16
  /** @internal verdict-module glue */
9
- export declare function setPendingCheckActive(v: boolean): void;
10
- /** @internal verdict-module glue */
11
- export declare function setLatestReadActive(v: boolean): void;
12
- /** @internal verdict-module glue */
13
17
  export declare function setContextInternal(v: Owner | null): void;
14
18
  export declare let stale: boolean;
15
- export declare let pendingCheckActive: boolean;
16
- export declare let latestReadActive: boolean;
17
19
  export declare let context: Owner | null;
18
- export declare let currentOptimisticLane: OptimisticLane | null;
19
20
  export declare let snapshotCaptureActive: boolean;
20
21
  export declare let snapshotSources: Set<any> | null;
21
22
  export declare function setSnapshotCapture(active: boolean): void;
22
- export declare function markSnapshotScope(owner: Owner): void;
23
+ /**
24
+ * Marks `owner` a snapshot scope: while capture is on, the readers created
25
+ * under it serve each source's snapshot (the value it had when hydration
26
+ * began) and replay at `releaseSnapshotScope`.
27
+ *
28
+ * With `served` (hydration), `owner` is instead a hydrated computed and
29
+ * `served` its server answer — what the server rendered every reader of the
30
+ * node with — landing after the node was created pending (so the creation
31
+ * arm skipped it). It becomes the node's snapshot when it has none, whether
32
+ * the node committed the answer or a client write had already taken its
33
+ * compute over. A claim made later reads the value its markup shows, and
34
+ * replays the node's own value at its release, as for a written signal.
35
+ */
36
+ export declare function markSnapshotScope(owner: Owner, served?: unknown): void;
23
37
  export declare function releaseSnapshotScope(owner: Owner): void;
24
38
  export declare function clearSnapshots(): void;
25
39
  export declare function recompute(el: Computed<any>, create?: boolean): void;
@@ -32,24 +46,126 @@ export declare function computed<T>(fn: (prev: T) => T | PromiseLike<T> | AsyncI
32
46
  export declare function ext(el: {
33
47
  _x: NodeExtension | null;
34
48
  }): NodeExtension;
49
+ /** A tracked read of a held node (the reader derives from its transaction's
50
+ * world): the reading pass is marked as having read it (born-held decision
51
+ * in `recompute`), and the flush joins the node's transaction — unless the
52
+ * reader is a render effect. A render effect is the frame, not a derivation
53
+ * (rule 3): in that transaction's own flush, or born into it (uninitialized,
54
+ * A29), it reads the staged value and holds nothing of its own; otherwise it
55
+ * reads the committed value instead (`frameRead`). A node born into the
56
+ * future has no committed value: every reader joins it. A first pass is
57
+ * something not ready under a loading boundary that has not shown content:
58
+ * the boundary collects it and shows its fallback, and the pass is the
59
+ * boundary's, not the tick's (A29's boundary exemption, #3540). */
60
+ export declare function joinPass(c: Computed<any>, el: Signal<any> | Computed<any>): void;
61
+ /** `joinPass` into the hold `t` (a folded guess's: store/optimistic.ts
62
+ * `foldedRead`, D-34) — a reader is never a render effect there. */
63
+ export declare function joinPassAt(c: Computed<any>, t: Transaction): void;
64
+ /** A node born into transaction `t`: held by it and never committed (A29,
65
+ * ruling A) — uninitialized (born held), or a member of the frame one of its
66
+ * held passes built (CONFIG_HELD_FRAME). Its branch exists only in `t`: it
67
+ * has no screen to read, so it reads `t`'s values, whichever flush runs it,
68
+ * and keeps staging (#4010). */
69
+ export declare function bornInto(c: Computed<any>, t: Transaction): unknown;
70
+ /** The computed whose pass a creation under `owner` belongs to (a root's is
71
+ * its nearest computed ancestor's), or null outside every pass. */
72
+ export declare function creatorPass(owner: Owner | null): Computed<any> | null;
73
+ /** What `born` and the passes still running around `p` read — its
74
+ * creator's, theirs — of the future or a staging (REACTIVE_JOINED |
75
+ * REACTIVE_STAGED_READ): a pass created by one that did has no screen; its
76
+ * branch exists only in that world (#4341). */
77
+ export declare function creatorReads(p: Computed<any> | null, born: number): number;
35
78
  /**
36
79
  * Build an Effect node with all effect-specific fields baked into a single object literal,
37
80
  * so V8 sees the full hidden class shape at construction time. Effects always run in lazy
38
81
  * mode (recompute is called explicitly by `effect()`), so we hardcode the lazy bits and skip
39
82
  * the auto-dispose CONFIG bit (effect() previously cleared it post-construction).
40
83
  */
41
- export declare function createEffectNode<T>(fn: (prev?: T) => T, effectFn: (val: T, prev: T | undefined) => void | (() => void), errorFn: ((err: unknown, cleanup: () => void) => void | (() => void)) | undefined, type: number, notifyStatus: ((status?: number, error?: any) => void) | undefined, options: NodeOptions<T> | undefined): any;
84
+ export declare function createEffectNode<T>(fn: (prev?: T) => T, effectFn: (val: T, prev: T | undefined) => void | (() => void), errorFn: ((err: unknown, cleanup: () => void) => void | (() => void)) | undefined, type: number, options: NodeOptions<T> | undefined): any;
85
+ /**
86
+ * The shared status notifier for effect nodes, installed once by effect.ts
87
+ * at module evaluation (`this`-dispatched — one function serves every
88
+ * effect, so nodes never store it). CARVE 4: the boundaries' per-node
89
+ * channel (`_x._notifyStatus`) went with them; effects are the only
90
+ * display consumers.
91
+ */
92
+ export declare let effectStatusNotify: ((this: any) => void) | null;
93
+ export declare function setEffectStatusNotify(fn: NonNullable<typeof effectStatusNotify>): void;
94
+ /** Resolve a node's status notifier: effect nodes (`_type` — EFFECT_PURE is
95
+ * 0, and only effect literals carry the field) get the shared notifier.
96
+ * Presence doubles as the "display consumer" membership test in the status
97
+ * walks, exactly as the per-node field did when every effect carried one. */
98
+ export declare function statusNotifierOf(el: any): ((this: any) => void) | null;
42
99
  export declare function signal<T>(v: T, options?: NodeOptions<T>): Signal<T>;
43
- export declare function signal<T>(v: T, options?: NodeOptions<T>, firewall?: Computed<any>): FirewallSignal<T>;
44
- export declare function optimisticSignal<T>(v: T, options?: NodeOptions<T>): Signal<T>;
45
- export declare function optimisticComputed<T>(fn: (prev?: T) => T | PromiseLike<T> | AsyncIterable<T>, options?: NodeOptions<T>): Computed<T>;
46
100
  export declare function isEqual<T>(a: T, b: T): boolean;
101
+ /** A store slot node (CONFIG_SLOT_NODE): the whole node in ONE literal — the
102
+ * target and key as back-refs in place of closures (`equals` is a method
103
+ * call, `this` the node; the unobserved sweep dispatches to one shared hook,
104
+ * graph.ts), the store's wrap cache (`px`/`pxv`: the proxy last served for
105
+ * this key and the raw it wrapped — one pointer compare replaces a WeakMap
106
+ * lookup per read) and the accessor verdict (`acc`) pre-shaped. No options
107
+ * object, no NodeExtension, no post-construction expandos. `ownedWrite` is
108
+ * baked in: the setter carries the owned-scope guard; node-level writes are
109
+ * the store's notification machinery. The observe literal adds the label
110
+ * and location slots (the store relabels `store.<key>` and stamps the
111
+ * store's `loc` when the engine is installed). */
112
+ export declare function slotSignal<T>(v: T, equals: (a: T, b: T) => boolean, host: object, key: PropertyKey, acc: boolean): Signal<T>;
47
113
  /**
48
114
  * When set to a component name string, any reactive read that is not inside a nested tracking
49
115
  * scope will log a dev-mode warning. Managed automatically by `untrack(fn, strictReadLabel)`.
50
116
  */
117
+ /** The verdict windows' read (verdict.ts), installed while a `latest` or
118
+ * `isPending` window is open and null otherwise: `read` dispatches to it
119
+ * then, and a program that never imports them never has one. */
120
+ export declare let verdict: ((el: Signal<any> | Computed<any>, c: Computed<any> | null) => unknown) | null;
121
+ export declare function setVerdict(fn: typeof verdict): void;
51
122
  export declare let strictRead: string | false;
52
- export declare function setStrictRead(v: string | false): string | false;
123
+ /** Dev-only: explicit untrack() nesting, so deliberate post-await reads stay quiet. */
124
+ export declare let untrackDepth: number;
125
+ /**
126
+ * Dev-only: > 0 while Solid runs user code that is imperative by construction
127
+ * — an effect callback (effect.ts) or an action body's synchronous slice
128
+ * (action.ts). Both run with no owner, exactly like an async continuation, so
129
+ * the post-await read check (dev.ts) consults this rather than blame the
130
+ * continuation that called flush() or invoked the action. Both sites bracket
131
+ * with try/finally, so a throw cannot leave it raised.
132
+ */
133
+ export declare let callbackDepth: number;
134
+ export declare function enterCallback(): void;
135
+ export declare function exitCallback(): void;
136
+ /**
137
+ * Dev-only: > 0 while owner teardown runs cleanups (`_disposal` entries and
138
+ * effect-returned cleanups — owner.ts), for the same reason. The owned-scope
139
+ * write guard (setSignal, markRefresh, the store setter) stands down here
140
+ * too: a cleanup is teardown, not part of whichever computation is disposing
141
+ * its owner (a list pass removing a row, a branch switching away), so its
142
+ * writes are imperative like an effect callback's (#4165). Kept apart from
143
+ * `callbackDepth` because its sites cannot use try/finally (the frame would
144
+ * survive into prod). A throwing cleanup is caught (owner.ts `runCleanup`);
145
+ * anything else escaping a teardown leaves it raised, and dev.ts resets it on
146
+ * the next microtask, which teardown — synchronous — never spans.
147
+ */
148
+ export declare let disposalDepth: number;
149
+ export declare function enterDisposal(): void;
150
+ export declare function exitDisposal(): void;
151
+ export declare function resetDisposalDepth(): void;
152
+ /**
153
+ * Dev-only: the DOM event being dispatched when the open strict-read window
154
+ * opened (`globalThis.event`; null between dispatches and off the main
155
+ * thread's Window), or `ANY_EVENT` when the window did not record one. A DOM
156
+ * call made in an effect callback that dispatches events synchronously
157
+ * (`el.focus()`, `el.click()`, `dialog.showModal()`) runs that event's
158
+ * handlers inside the window; a handler is a one-shot snapshot whoever
159
+ * dispatched the event, so a read made while a different event is current is
160
+ * outside the window (#4235). Only queued effect runs record the event, read
161
+ * once per queue (the getter is costly under jsdom); `strictReadActive` is
162
+ * the check.
163
+ */
164
+ export declare let strictReadEvent: unknown;
165
+ export declare const dispatchingEvent: () => unknown;
166
+ export declare function setStrictRead(v: string | false, event?: unknown): string | false;
167
+ /** Dev-only: is the strict-read window open for a read made now? */
168
+ export declare function strictReadActive(): boolean;
53
169
  /**
54
170
  * Runs `fn` outside of any reactive tracking — reads inside `fn` will not
55
171
  * subscribe the current scope. Returns whatever `fn` returns.
@@ -57,6 +173,16 @@ export declare function setStrictRead(v: string | false): string | false;
57
173
  * Use `untrack` inside a memo or effect when you need to read a signal once
58
174
  * without making the surrounding computation depend on its future changes.
59
175
  *
176
+ * `untrack` stops dependency tracking, not async settlement. Reading an
177
+ * uninitialized async source still suspends the owning computation; it runs
178
+ * again when that source first resolves. Afterward, the untracked read is a
179
+ * snapshot and does not subscribe the computation to later changes.
180
+ *
181
+ * If the first read must return immediately, give the async source a
182
+ * `loadingValue` before reading it with `untrack`. `isPending` and `latest`
183
+ * inspect updates to an existing value; neither supplies a missing initial
184
+ * value.
185
+ *
60
186
  * Pass a `strictReadLabel` string to enable a dev-mode warning: any reactive
61
187
  * read inside `fn` that isn't inside a nested tracking scope will log a
62
188
  * warning naming the label.
@@ -70,53 +196,170 @@ export declare function setStrictRead(v: string | false): string | false;
70
196
  * log(snapshot);
71
197
  * }
72
198
  * );
199
+ *
200
+ * const color = createMemo<string>(() => fetchColor(), { loadingValue: "gray" });
201
+ * const initialColor = untrack(color); // "gray" while the fetch is unresolved
73
202
  * ```
74
203
  */
75
204
  export declare function untrack<T>(fn: () => T, strictReadLabel?: string | false): T;
205
+ /**
206
+ * Set while runtime bookkeeping reads a node inside another node's pass (a
207
+ * loading boundary priming its tree at creation, from whatever pass is
208
+ * mounting it). `context` is that node, but the read is nobody's: the value
209
+ * is probed, never derived from, so nothing the read would normally record
210
+ * on `context` may be recorded — not the untracked-pending re-run link
211
+ * (`read`, `!tracking`; #3528: a boundary's `on` key read this way from
212
+ * `notify` linked the key's source into an unrelated async memo, a cycle that
213
+ * never converged), and not a transaction entry (`enterStagedRead`; #3540: a
214
+ * born-held tree would otherwise pull the mounting pass into the hold).
215
+ */
216
+ export declare let spectating: boolean;
217
+ /**
218
+ * Evaluates `fn` untracked, recording nothing on the current `context`: no
219
+ * untracked-pending re-run link, no transaction entry. For bookkeeping reads
220
+ * made on behalf of no node — see `spectating`.
221
+ */
222
+ export declare function spectate<T>(fn: () => T): T;
76
223
  /**
77
224
  * Bring a computed to a readable state: lazy/disposed nodes are (re)computed;
78
- * an isPending() probe (`refresh`) additionally pulls the node fully up to
79
- * date so its status flags reflect the current graph.
225
+ * `refresh` additionally pulls the node fully up to date so its status flags
226
+ * reflect the current graph.
80
227
  */
81
228
  export declare function prepareComputed(comp: Computed<unknown>, refresh: boolean): void;
82
229
  /**
83
- * Sentinel returned by readNodeFast when the plain-signal fast path does not
84
- * apply and the caller must fall back to the full read().
230
+ * Rule 1 (value selection): does this reader see a STAGED node's COMMITTED
231
+ * value? One implementation of the rule the fast paths (read's fast block)
232
+ * carry as their trivial ternary. In order:
233
+ * - no reader at all (an untracked read) — the committed frame;
234
+ * - nothing staged;
235
+ * - a children-forbidden reader (createTrackedEffect / onSettled: the frame,
236
+ * never the graph — A32).
237
+ * False means the reader derives from the staged value.
85
238
  */
86
- export declare const READ_SLOW: unique symbol;
239
+ export declare function readerSeesCommitted(el: Signal<any> | Computed<any>, c: Computed<any> | null): boolean;
240
+ /** A28 — set when a node is staged (queuePendingNode) OUTSIDE a flush;
241
+ * cleared when the next flush begins. The read sites test this one module
242
+ * boolean instead of `globalQueue._running`: inside a flush it is false and
243
+ * the A28 arm costs nothing; outside, only a tick with unflushed writes pays
244
+ * the staged-node check. */
245
+ export declare let unflushedStaged: boolean;
246
+ export declare function markUnflushedStaged(): void;
247
+ /** A28 — a write becomes visible at flush. Outside a flush, a node holding a
248
+ * staged value was written since the last flush: staging commits at flush
249
+ * end, so nothing else leaves a node in this state. Inside a flush the rule
250
+ * does not apply (A28 (4): promoted within the round). The value an
251
+ * unflushed node serves is its committed value, or NOT_PENDING when nothing
252
+ * is unflushed. Exempt: promoted writes (A28 (4): a write issued inside a
253
+ * recompute is promoted at that recompute's end — boundary and loading
254
+ * machinery, signals declared for in-computation writes). */
255
+ export declare function unflushedValue(el: Signal<any> | Computed<any>): unknown;
256
+ /** A28: a held node rewritten outside a flush keeps the staging the last
257
+ * flush left (`_flushed`) until the flush that carries the rewrite — the
258
+ * stash is stamped with the clock, which that flush advances. */
259
+ export declare function stashFlushed(el: Signal<any> | Computed<any>): void;
260
+ /** A derivation served the committed value because of an unflushed write
261
+ * (A28) must run again in the flush that carries it — the late-linker case
262
+ * (#3337's reason to defer the walk): it linked after the write walked. */
263
+ export declare function markLateLinker(c: Computed<any>): true;
264
+ export declare function resyncUnflushedCompanions(): void;
265
+ /** A tracked read's pull of a computed: bring it current when the flush has
266
+ * reached its height (or the reader is a fresh-pull waiter), and sit the
267
+ * reader above it. */
268
+ export declare function pullComputed(owner: Computed<any>, c: Computed<any>): void;
87
269
  /**
88
- * read()'s plain-signal fast path as a standalone entry for hot callers
89
- * (store traps). Safe to substitute for read() only because the bail
90
- * conditions mirror read()'s prelude and fast-path guard exactly: the
91
- * latestRead and pendingCheck windows run side-effectful hooks before the
92
- * fast path, `_fn` nodes need prepareComputed, and firewall / override /
93
- * snapshot / transition / lane / dev-strictRead state all take the full
94
- * resolution. Anything slow returns READ_SLOW; the caller then calls read().
270
+ * Dev only: a read's diagnostics — the devtools read hook, the foreign-read
271
+ * check and the post-await untracked-read check. Every caller guards with
272
+ * `__DEV__`: `read` here, and a store leaf's read that is served without
273
+ * `read` (`nodeValue`'s first landing), so no read goes unseen in dev.
95
274
  */
96
- export declare function readNodeFast<T>(el: Signal<T>): T | typeof READ_SLOW;
275
+ export declare function devRead(el: Signal<any> | Computed<any>): void;
97
276
  export declare function read<T>(el: Signal<T> | Computed<T>): T;
98
277
  /**
99
- * Store-rewrite setter guard: the rewrite parks writes in a pending backing
100
- * (no setSignal at write time), so the owned-scope write protection must
101
- * fire at the setter entry instead. Mirrors setSignal's guard condition
102
- * minus the node-specific exemptions (ownedWrite/firewall), which don't
103
- * apply to plain store setters.
278
+ * Rule 1, the one slow implementation (DESIGN-CONSOLIDATION move 3b, step
279
+ * 6c): the value a reader `c` (null = untracked, no pass) is served from
280
+ * `el`. Called by read()'s slow tail; the fast path (read's fast block) keeps
281
+ * its trivial ternary by design (perf, see the doc). Arms, in order:
282
+ * - a node born staged has nothing for an untracked reader (A19 exception 1);
283
+ * - an unflushed write serves committed and re-runs the reader in the
284
+ * carrying flush (A28);
285
+ * - readerSeesCommitted, else the staged value.
104
286
  */
105
- export declare function devGuardStoreSetterWrite(): void;
106
- export declare function setSignal<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)): T;
287
+ export declare function serve(el: Signal<any> | Computed<any>, c: Computed<any> | null): unknown;
288
+ /** A pass read a staging of this flush: it derives from what the flush may
289
+ * yet hold (REACTIVE_STAGED_READ — the seam decides). Lane work too (plan sec. 28, a
290
+ * lane sees the screen plus its own guesses) — a folded lane's only before
291
+ * the frame has a transaction (after, it reads the screen like a verdict
292
+ * reader, `stagedScreen` — a list pass never pairs a held length with the
293
+ * guess's rows, D-34): the staging is the screen if
294
+ * the frame commits — one pass, the common case — and a held write if it
295
+ * parks, which the seam repairs (`stagedReaders`): the pass re-derives on
296
+ * the committed world and its lane's runs wait that round, so the held
297
+ * write never shows through the lane. A verdict lane's work likewise: the
298
+ * lane holds verdicts, not the frame's other stagings (#3851) — except a
299
+ * verdict reader, which answered for itself (the lane seam, lanes.ts). Not
300
+ * a read of a node born staged at all: it has no committed value to
301
+ * re-derive on, and a re-run would read the same staging and re-queue every
302
+ * round (#3969: nor does it make a later lane read a re-derive, `enterLane`). */
303
+ export declare function stagedRead(c: Computed<any>, el?: Signal<any> | Computed<any>): void;
304
+ /** A10 for a staged node: a verdict reader (the pass entered a window) that
305
+ * also reads a frame's proposal plainly sees the screen — `[latest(q), q()]`
306
+ * is `[b, a]` — once the frame has a transaction, and re-derives when it
307
+ * lands: at this very seam if nothing holds it (the stale run is void,
308
+ * #3322 — one run, on the committed world), or with the hold. Before any
309
+ * transaction the answer is the seam's and the reader watches it
310
+ * (verdict.ts). A node born into the future has no screen: its staging is
311
+ * its only value (A29). Nor has a reader born into the flush's transaction
312
+ * (`bornInto`, #4010): its branch exists only there. */
313
+ export declare function stagedScreen(c: Computed<any>): boolean;
314
+ export declare function ownedScopeWriteMessage(owner: Owner): string;
315
+ /** A28 (4) — written inside a recompute that runs OUTSIDE a flush (a
316
+ * creation-time compute): promoted at that pass's end, visible to the rest of
317
+ * the block. Cold: only contextual writes reach here. */
318
+ export declare function notePromotedWrite(el: Signal<any> | Computed<any>): void;
319
+ /** Cold half of setSignal's snapshot arm (see there), shared with a store
320
+ * container's structural notify: first write during capture to a plain
321
+ * signal without a live snapshot records the pre-write value. Only plain
322
+ * user signals qualify. Computeds reach setSignal from an
323
+ * async landing (asyncWrite), and a value arriving from async during the pass
324
+ * REVEALS — the creation-time arm skips pending computeds for the same
325
+ * reason. Firewall leaves belong to a projection whose compute is the tree's
326
+ * own work, captured (or deliberately not) at creation. */
327
+ export declare function captureWriteSnapshot<T>(el: Signal<T> | Computed<T>, current: T): void;
328
+ /**
329
+ * A callback run before every signal or store write lands, while set, with
330
+ * the written signal or the store proxy whose setter runs. The
331
+ * server-components client sets it while slot occurrences are left
332
+ * unmounted after hydration (deferred hydration): a write may be one an
333
+ * unmounted component would have observed, so the client mounts what is
334
+ * left before the write applies, and clears the hook. `null` otherwise.
335
+ */
336
+ export declare let writeHook: ((node?: object) => void) | null;
337
+ /** @internal */
338
+ export declare function setWriteHook(hook: ((node?: object) => void) | null): void;
107
339
  /**
108
- * Suppresses automatic recomputation of `el` until the scheduler drains. Used
109
- * when a manual write should win over dependency changes queued in the same
110
- * tick. The MANUAL_WRITE flag is cleared by the pending-node drain; projection
111
- * computeds don't commit values, but they still need the same end-of-tick
112
- * cleanup point.
340
+ * `el`'s comparator verdict (`_equals`), the one guarded call for recompute,
341
+ * setSignal (user setters and async landings) and the seam's
342
+ * staged-equals-committed check.
343
+ * - A comparator that read an unresolved async source has not shown the
344
+ * values equal (#4111): falsy, a change, whose readers suspend in their own
345
+ * tracked context.
346
+ * - Any other throw is an error of `el`'s computation (A3, #2837): routed
347
+ * through the status path so error boundaries contain it, instead of
348
+ * unwinding a flush or a setter; answered "same" so nothing commits.
349
+ * @internal
113
350
  */
114
- export declare function suppressComputedRecompute(el: Computed<unknown>): void;
351
+ export declare function isSame(el: Signal<any>, a: unknown, b: unknown): unknown;
352
+ export declare function setSignal<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)): T;
115
353
  /**
116
- * User-facing setter for the memo form of `createSignal(fn)`. Behaves like
117
- * `setSignal`, but also cancels any pending recompute of the memo so the
118
- * manual value wins over a value that would otherwise be produced by an
119
- * upstream change in the same tick.
354
+ * User-facing setter for the memo form of `createSignal(fn)`. A write applies
355
+ * first, then derivations re-run (A34 as amended 2026-10-01, rule B; core
356
+ * R31): the write stages like any other, and a source change — in this flush
357
+ * or a later one, under a hold or on mainline — re-derives with the staged
358
+ * write as `prev`. The write never refuses the re-run (the frame-scoped mask
359
+ * of #3733/#3740 and #2692's "write wins the tick" before it are gone; call
360
+ * order inside a flush was never observable) and on its own never causes one.
361
+ * REACTIVE_MANUAL_WRITE only marks the staging as a user proposal — the A34
362
+ * (1)/(3) discriminator — until a pass re-derives it or the commit lands it.
120
363
  */
121
364
  export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
122
365
  /**
@@ -141,23 +384,10 @@ export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
141
384
  export declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
142
385
  export declare function staleValues<T>(fn: () => T, set?: boolean): T;
143
386
  /**
144
- * Invalidates one reactive source, forcing it to re-execute even if its inputs
145
- * haven't changed.
146
- *
147
- * Pass either a Solid-created accessor or a projected store created from
148
- * `createStore(fn, ...)` / `createProjection(...)`. `refresh()` is a
149
- * write-like invalidation operation: it does not read the target's value, and
150
- * refreshing a plain signal accessor is a no-op.
151
- *
152
- * Use it to invalidate cached async values (e.g. force a re-fetch) without
153
- * tearing the consumer down.
154
- *
155
- * @example
156
- * ```ts
157
- * const user = createMemo(async () => fetch(`/users/${id()}`).then(r => r.json()));
158
- *
159
- * // Re-fetch on demand
160
- * <button onClick={() => refresh(user)}>Reload</button>
161
- * ```
387
+ * Core marking half of `refresh()` (the public wrapper lives in signals.ts —
388
+ * it validates the target, marks through here, then builds the quiescence
389
+ * promise on the resolve()/until() effect machinery). Flags the node's next
390
+ * recompute as a quiet re-ask and schedules it; no-ops for non-derived or
391
+ * disposed targets.
162
392
  */
163
- export declare function refresh<T>(target: Refreshable<T>): void;
393
+ export declare function markRefresh(node: Computed<any>): void;