@solidjs/signals 2.0.0-rc.1 → 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 (150) hide show
  1. package/dist/dev-shared.js +7138 -0
  2. package/dist/dev.attribution.js +3307 -0
  3. package/dist/dev.js +5691 -4491
  4. package/dist/observe/affects.js +129 -0
  5. package/dist/observe/attribution.js +7 -0
  6. package/dist/observe/boundaries.js +793 -0
  7. package/dist/observe/core/action.js +177 -0
  8. package/dist/observe/core/async.js +849 -0
  9. package/dist/observe/core/attribution-costs.js +66 -0
  10. package/dist/observe/core/attribution-feedback.js +280 -0
  11. package/dist/observe/core/attribution-hooks.js +83 -0
  12. package/dist/observe/core/attribution-queries.js +43 -0
  13. package/dist/observe/core/attribution.js +2904 -0
  14. package/dist/observe/core/constants.js +283 -0
  15. package/dist/{types-cjs/core/context.d.cts → observe/core/context.js} +37 -12
  16. package/dist/observe/core/core.js +1999 -0
  17. package/dist/observe/core/dev.js +343 -0
  18. package/dist/observe/core/effect.js +200 -0
  19. package/dist/observe/core/error-hooks.js +71 -0
  20. package/dist/observe/core/error.js +80 -0
  21. package/dist/observe/core/external.js +98 -0
  22. package/dist/observe/core/graph.js +155 -0
  23. package/dist/observe/core/heap.js +147 -0
  24. package/dist/observe/core/invariants.js +45 -0
  25. package/dist/observe/core/lanes.js +205 -0
  26. package/dist/observe/core/optimistic.js +627 -0
  27. package/dist/observe/core/owner.js +353 -0
  28. package/dist/observe/core/scheduler.js +1547 -0
  29. package/dist/observe/core/verdict.js +674 -0
  30. package/dist/observe/index.js +59 -0
  31. package/dist/observe/map.js +484 -0
  32. package/dist/observe/signals.js +731 -0
  33. package/dist/observe/store/index.js +44 -0
  34. package/dist/observe/store/next/optimistic.js +717 -0
  35. package/dist/observe/store/next/projection.js +266 -0
  36. package/dist/observe/store/next/reconcile.js +375 -0
  37. package/dist/observe/store/next/store.js +2480 -0
  38. package/dist/observe/store/next/target.js +51 -0
  39. package/dist/observe/store/store.js +331 -0
  40. package/dist/observe/store/storePath.js +103 -0
  41. package/dist/observe/store/utils.js +1070 -0
  42. package/dist/prod/affects.js +10 -9
  43. package/dist/prod/attribution.js +45 -0
  44. package/dist/prod/boundaries.js +388 -178
  45. package/dist/prod/core/action.js +65 -37
  46. package/dist/prod/core/async.js +378 -163
  47. package/dist/prod/core/attribution-hooks.js +3 -0
  48. package/dist/prod/core/constants.js +186 -1
  49. package/dist/prod/core/context.js +10 -16
  50. package/dist/prod/core/core.js +1546 -416
  51. package/dist/prod/core/dev.js +18 -1
  52. package/dist/prod/core/effect.js +119 -79
  53. package/dist/prod/core/error-hooks.js +71 -0
  54. package/dist/prod/core/error.js +13 -1
  55. package/dist/prod/core/external.js +4 -4
  56. package/dist/prod/core/graph.js +105 -54
  57. package/dist/prod/core/heap.js +72 -65
  58. package/dist/prod/core/invariants.js +3 -2
  59. package/dist/prod/core/lanes.js +117 -52
  60. package/dist/prod/core/optimistic.js +458 -104
  61. package/dist/prod/core/owner.js +131 -84
  62. package/dist/prod/core/scheduler.js +998 -241
  63. package/dist/prod/core/verdict.js +417 -112
  64. package/dist/prod/index.js +20 -8
  65. package/dist/prod/map.js +312 -151
  66. package/dist/prod/signals.js +363 -32
  67. package/dist/prod/store/index.js +2 -0
  68. package/dist/prod/store/next/optimistic.js +530 -197
  69. package/dist/prod/store/next/projection.js +142 -57
  70. package/dist/prod/store/next/reconcile.js +149 -103
  71. package/dist/prod/store/next/store.js +1470 -346
  72. package/dist/prod/store/next/target.js +40 -9
  73. package/dist/prod/store/store.js +23 -19
  74. package/dist/prod/store/utils.js +997 -130
  75. package/dist/types/attribution.d.ts +19 -0
  76. package/dist/types/attribution.prod.d.ts +22 -0
  77. package/dist/types/boundaries.d.ts +78 -5
  78. package/dist/types/core/action.d.ts +12 -5
  79. package/dist/types/core/async.d.ts +3 -1
  80. package/dist/types/core/attribution-costs.d.ts +35 -0
  81. package/dist/types/core/attribution-feedback.d.ts +133 -0
  82. package/dist/types/core/attribution-hooks.d.ts +304 -0
  83. package/dist/types/core/attribution-queries.d.ts +24 -0
  84. package/dist/types/core/attribution.d.ts +892 -0
  85. package/dist/types/core/constants.d.ts +179 -0
  86. package/dist/types/core/core.d.ts +299 -25
  87. package/dist/types/core/dev.d.ts +421 -8
  88. package/dist/types/core/effect.d.ts +8 -1
  89. package/dist/types/core/error-hooks.d.ts +71 -0
  90. package/dist/types/core/error.d.ts +9 -0
  91. package/dist/types/core/graph.d.ts +23 -0
  92. package/dist/types/core/heap.d.ts +5 -3
  93. package/dist/types/core/index.d.ts +6 -3
  94. package/dist/types/core/invariants.d.ts +5 -1
  95. package/dist/types/core/lanes.d.ts +51 -19
  96. package/dist/types/core/owner.d.ts +15 -3
  97. package/dist/types/core/scheduler.d.ts +248 -1
  98. package/dist/types/core/types.d.ts +124 -41
  99. package/dist/types/index.d.ts +18 -5
  100. package/dist/types/map.d.ts +2 -0
  101. package/dist/types/signals.d.ts +145 -13
  102. package/dist/types/store/index.d.ts +7 -6
  103. package/dist/types/store/next/optimistic.d.ts +18 -13
  104. package/dist/types/store/next/projection.d.ts +5 -2
  105. package/dist/types/store/next/reconcile.d.ts +7 -0
  106. package/dist/types/store/next/store.d.ts +83 -11
  107. package/dist/types/store/next/target.d.ts +108 -11
  108. package/dist/types/store/store.d.ts +20 -11
  109. package/dist/types/store/utils.d.ts +188 -0
  110. package/package.json +31 -26
  111. package/dist/node.cjs +0 -8137
  112. package/dist/types/store/optimistic.d.ts +0 -45
  113. package/dist/types/store/projection.d.ts +0 -70
  114. package/dist/types/store/reconcile.d.ts +0 -46
  115. package/dist/types-cjs/affects.d.cts +0 -47
  116. package/dist/types-cjs/boundaries.d.cts +0 -175
  117. package/dist/types-cjs/core/action.d.cts +0 -64
  118. package/dist/types-cjs/core/async.d.cts +0 -21
  119. package/dist/types-cjs/core/constants.d.cts +0 -71
  120. package/dist/types-cjs/core/core.d.cts +0 -156
  121. package/dist/types-cjs/core/dev.d.cts +0 -64
  122. package/dist/types-cjs/core/effect.d.cts +0 -30
  123. package/dist/types-cjs/core/error.d.cts +0 -47
  124. package/dist/types-cjs/core/external.d.cts +0 -15
  125. package/dist/types-cjs/core/graph.d.cts +0 -5
  126. package/dist/types-cjs/core/heap.d.cts +0 -22
  127. package/dist/types-cjs/core/index.d.cts +0 -13
  128. package/dist/types-cjs/core/invariants.d.cts +0 -59
  129. package/dist/types-cjs/core/lanes.d.cts +0 -56
  130. package/dist/types-cjs/core/optimistic.d.cts +0 -6
  131. package/dist/types-cjs/core/owner.d.cts +0 -124
  132. package/dist/types-cjs/core/scheduler.d.cts +0 -172
  133. package/dist/types-cjs/core/types.d.cts +0 -148
  134. package/dist/types-cjs/core/verdict.d.cts +0 -2
  135. package/dist/types-cjs/index.d.cts +0 -10
  136. package/dist/types-cjs/map.d.cts +0 -69
  137. package/dist/types-cjs/package.json +0 -3
  138. package/dist/types-cjs/signals.d.cts +0 -624
  139. package/dist/types-cjs/store/index.d.cts +0 -19
  140. package/dist/types-cjs/store/next/optimistic.d.cts +0 -20
  141. package/dist/types-cjs/store/next/projection.d.cts +0 -24
  142. package/dist/types-cjs/store/next/reconcile.d.cts +0 -3
  143. package/dist/types-cjs/store/next/store.d.cts +0 -71
  144. package/dist/types-cjs/store/next/target.d.cts +0 -99
  145. package/dist/types-cjs/store/optimistic.d.cts +0 -45
  146. package/dist/types-cjs/store/projection.d.cts +0 -70
  147. package/dist/types-cjs/store/reconcile.d.cts +0 -46
  148. package/dist/types-cjs/store/store.d.cts +0 -138
  149. package/dist/types-cjs/store/storePath.d.cts +0 -58
  150. package/dist/types-cjs/store/utils.d.cts +0 -74
@@ -18,6 +18,15 @@ export declare const REACTIVE_MANUAL_WRITE: number;
18
18
  * pending window does not read as pending (question-scoped pending model).
19
19
  */
20
20
  export declare const REACTIVE_REASK: number;
21
+ /**
22
+ * A dependency write landed while this subscriber was mid-recompute — a
23
+ * nested pull committed beneath one of its reads (#3037). The heap refuses
24
+ * RECOMPUTING nodes, so recompute's tail consumes this latch and reschedules:
25
+ * values the pass read before the nested commit are stale. Only set for
26
+ * links validated this pass (gen-current): a write to an untouched link is
27
+ * either re-read later in the pass (fresh) or trimmed with it (not a dep).
28
+ */
29
+ export declare const REACTIVE_MISSED_WAKE: number;
21
30
  export declare const CONFIG_OWNED_WRITE: number;
22
31
  export declare const CONFIG_NO_SNAPSHOT: number;
23
32
  export declare const CONFIG_TRANSPARENT: number;
@@ -25,6 +34,173 @@ export declare const CONFIG_IN_SNAPSHOT_SCOPE: number;
25
34
  export declare const CONFIG_CHILDREN_FORBIDDEN: number;
26
35
  export declare const CONFIG_AUTO_DISPOSE: number;
27
36
  export declare const CONFIG_SYNC: number;
37
+ export declare const CONFIG_OPTIMISTIC: number;
38
+ export declare const CONFIG_HAS_COMPANIONS: number;
39
+ export declare const CONFIG_HAS_SNAPSHOT: number;
40
+ export declare const CONFIG_HAS_LANE: number;
41
+ /** Set on a FIREWALL computed when any of its child signals creates an
42
+ * isPending()/latest() companion. Gates the post-recompute child-companion
43
+ * walk (#3038): a store computed's `_child` chain holds one node per
44
+ * materialized leaf, so walking it unconditionally makes every update cost
45
+ * O(all leaves ever read). Sticky — set at companion creation, never
46
+ * cleared; sync-only apps never set it and never pay the walk. */
47
+ export declare const CONFIG_CHILD_COMPANIONS: number;
48
+ /** Set on a computed when its first firewall child signal is installed
49
+ * (projection machinery). Gates markNode's firewall-children walk with one
50
+ * masked read of the always-present _config — the walk's old `_child` read
51
+ * moved into the cold extension (§12), and an unconditional `_x` deref per
52
+ * marked node measurably taxed the propagation hot path (diamond -22%). */
53
+ export declare const CONFIG_FW_CHILDREN: number;
54
+ /** Authoritative-view reader (`until()`): while this node computes, reads
55
+ * dodge active optimistic OVERRIDES only — the predicate must observe
56
+ * arriving truth, never the caller's own tentative writes (which would
57
+ * trivially satisfy it). Everything else reads normally, INCLUDING
58
+ * transition-staged `_pendingValue`: staged data is authoritative (optimism
59
+ * lives only in override slots), and a hold that refused staged reads would
60
+ * deadlock on data the open transaction itself is holding (a refresh the
61
+ * action issued lands staged and cannot commit until the hold releases).
62
+ * read() checks the bit on the reading computation (`context`) directly — no
63
+ * ambient flag — so a shared computed the predicate pulls recomputes as
64
+ * itself (no bit) under the normal view, and its cache never forks. */
65
+ export declare const CONFIG_AUTHORITATIVE_READ: number;
66
+ /** Sticky mark: an authoritative-view reader read this node PAST an active
67
+ * override. The ack shape — an authoritative arrival EQUAL to the override —
68
+ * rides paths that are deliberately silent under A17 (every ordinary reader
69
+ * sees the override, so an equal landing changes nothing for them). A marked
70
+ * node notifies those readers on such paths anyway, so the landed truth is
71
+ * seen without re-firing ordinary subscribers. Never cleared — only nodes an
72
+ * until() predicate observed mid-override pay. */
73
+ export declare const CONFIG_AUTHORITATIVE_OBSERVED: number;
74
+ /** Promise-delivery effect (resolve()/until()): commits its computed value
75
+ * directly even when recomputing under its own held transition. These
76
+ * effects deliver applies on a microtask (#2930) instead of the stashed
77
+ * effect queues, so the value must ride the same immediate schedule — a
78
+ * staged value with an immediate apply delivers stale state (resolve) or
79
+ * deadlocks the hold (until). Safe because the node is a private leaf: no
80
+ * subscriber reads an effect's value, only its own apply does. */
81
+ export declare const CONFIG_DIRECT_COMMIT: number;
82
+ /** Fresh-pull reader (awaitable `refresh()`'s waiter effect): a read of a
83
+ * dirty source recomputes it inline even when the height gate defers to the
84
+ * flush. Closes the same-flush ordering race where a waiter created
85
+ * alongside a refresh() mark read the PRE-re-ask value as settled and
86
+ * delivered stale; with the pull, the waiter either parks on the re-ask's
87
+ * pending window (async — woken by the settle walk, which runs on every
88
+ * landing including equal-value ones) or serves its sync answer. resolve()
89
+ * deliberately keeps that race — its contract is "first settled value"
90
+ * (#2930), not "next quiescent state". */
91
+ export declare const CONFIG_FRESH_READ: number;
92
+ /** HELD truth (#3164): this node's staged `_pendingValue` is confirming
93
+ * truth riding a transaction that retains optimism, revealed only at that
94
+ * transaction's settle. Two arming sites, one meaning: the store fold
95
+ * (a landing staged into the retaining transaction) and until()'s
96
+ * flip-entanglement (a foreign carrier's staged write, stolen when it
97
+ * flipped the awaited predicate truthy). Override-covered nodes never
98
+ * arm: the override is their display and its revert their notification
99
+ * (A17).
100
+ *
101
+ * To a DERIVING reader the truth is a staged value like any other: a memo
102
+ * or user effect served it enters the transaction and is held with it
103
+ * (A29), so a pass that composes it with a superseded override's truth
104
+ * composes ONE staged world — never staged truth beside committed
105
+ * neighbours (#3568: the mask served the retaining transaction's own pass
106
+ * the landed `length` through the override while the rows past it stayed
107
+ * committed, and `<For>` walked into a hole). Stale readers of a foreign
108
+ * transaction keep committed through the stale-of-foreign clause,
109
+ * untracked reads keep committed (Rule 1), and latest() and until()'s
110
+ * predicate tunnel through — the exemption that keeps holds deadlock-free.
111
+ *
112
+ * The one reader the mark gates is a LANE pass, owning transaction or not
113
+ * (ruled 2026-09-22, superseding #3589's owner exemption): a lane applies
114
+ * its frame display-ahead at the park, so a lane pass served the truth
115
+ * would paint the confirmation beside the optimism it confirms —
116
+ * `saving=true` beside the saved row, a frame no timeline contains
117
+ * (GabbeV's union tear). It keeps committed and is re-run by the reveal's
118
+ * post-revert wake. A lane under the retaining transaction owns its
119
+ * overrides and its lane cargo (`ownsLane`), not the transaction's
120
+ * confirming truth. Cleared at commit (the commit IS the reveal);
121
+ * subscribers masked during the hold are woken by finalizePureQueue's
122
+ * post-revert pass. */
123
+ export declare const CONFIG_HELD_TRUTH: number;
124
+ /** SLOT node (store leaf): created through `slotSignal` with `_host`/`_key`
125
+ * backrefs baked into the literal. The unobserved sweep dispatches these to
126
+ * the ONE shared hook (`setSlotUnobserved`) instead of a per-node closure
127
+ * held in a per-node extension — store mounts materialize one signal per
128
+ * touched leaf, so per-node allocations (options object, equals closure,
129
+ * unobserved closure, NodeExtension) were the measured create-floor bytes
130
+ * (warm dbmon profile: store node machinery ~36% + GC ~29%). */
131
+ export declare const CONFIG_SLOT_NODE: number;
132
+ /** Optimistic node whose own source arrived with a value DIFFERENT from its
133
+ * active override (A18 supersession, #3331). The override survives only as
134
+ * the displayed value — untracked reads and the applied frame keep it until
135
+ * the owning transaction commits — while the graph has already moved to the
136
+ * staged truth in `_pendingValue`: tracked readers see it and the corrected
137
+ * cascade is that transaction's held work. Set by the two own-source write
138
+ * paths (asyncWrite, transition-held recompute); cleared by a fresh optimistic
139
+ * write (a new override re-masks) and by the revert. */
140
+ export declare const CONFIG_OVERRIDE_SUPERSEDED: number;
141
+ /** HELD children (#3404): this node's `_firstChild` chain (and `_disposal`
142
+ * list) was built by a recompute whose result has not committed — a staged
143
+ * value, a pending window, or a run under a held transaction. A later
144
+ * recompute may tear those children down immediately: nothing observable
145
+ * was ever built on them. Unset, the children belong to the committed frame
146
+ * and a recompute defers them as zombies (`_pendingFirstChild`) until this
147
+ * node commits — regardless of whether the recompute runs under a
148
+ * transaction. A parked node (status propagation stamps `_transition`
149
+ * without recomputing) recomputed when its source lands otherwise disposed
150
+ * its committed children mid-hold, running their cleanups before the
151
+ * transaction's atomic reveal. Cleared by `commitPendingNode`. */
152
+ export declare const CONFIG_HELD_CHILDREN: number;
153
+ /** The frame parked in `_pendingFirstChild` / `_pendingDisposal` is a LANE
154
+ * frame (#3662, A15 lanes corollary): an effect's lane pass direct-commits,
155
+ * so the frame it replaces leaves the screen when the lane's queue applies
156
+ * the run (A30) — not at the action's commit like #3404's transaction
157
+ * zombies, and not at the pass (a held lane defers the run). Drained by the
158
+ * lane's render entry the parking site pushed ahead of the new frame's
159
+ * effects (cleanups before side effects), by `commitPendingNode` if a hold
160
+ * commits the node first, or with the owner's death. While set the parked
161
+ * frame is not a hold (the node is not queued or stamped for it), a
162
+ * superseding pass disposes the never-shown live children on the spot, and a
163
+ * lane-channel dirty on a member is cancelled (`laneZombie`). Effects only: a
164
+ * memo's lane pass publishes an override (A17, #3479). */
165
+ export declare const CONFIG_LANE_FRAME: number;
166
+ /** In-flight async node whose inputs were PUBLISHED while it was pending: a
167
+ * batch or transaction committed with the node still `STATUS_PENDING` (an
168
+ * unobserved flight, #3305), so the inputs are on screen and the node's
169
+ * committed `_value` is stale against them. Governs read()'s reveal
170
+ * carve-out: a stale (render) reader in some OTHER transaction may show a
171
+ * foreign-held pending node's committed value — parallel transactions, no
172
+ * entanglement — only while that value is coherent with the visible frame,
173
+ * i.e. while the flight's inputs are themselves held (unpublished) and not
174
+ * lane-revealed. Set by `commitPendingNodes`; cleared when the node next
175
+ * enters pending fresh (a new flight from a settled state). */
176
+ export declare const CONFIG_INPUTS_PUBLISHED: number;
177
+ /** A28 (4): the node was written inside a recompute that ran OUTSIDE a flush
178
+ * (a creation-time compute — boundary machinery, a mapArray's first run). Such
179
+ * a write is promoted at that recompute's end: readers in the same block see
180
+ * it. Cleared when the next flush begins; set only on that rare path. */
181
+ export declare const CONFIG_PROMOTED: number;
182
+ /** A28 for same-tick adoption: the node was staged outside a flush and then
183
+ * adopted by a transaction (initTransition) before any flush carried the
184
+ * staging — the stamp says "held", but nothing flushed is staged for it, so
185
+ * on no channel is the write visible yet: `latest()` answers the committed
186
+ * value, the verdict sees nothing pending (as the store's leaves already did
187
+ * through their own selection). Cleared when the carrying flush re-stamps the
188
+ * transaction's pending nodes (reassignPendingTransition). */
189
+ export declare const CONFIG_ADOPTED_UNFLUSHED: number;
190
+ /** The node's active override is a DERIVED one: a lane pass published its
191
+ * speculative result into the override slot instead of `_value` (lanes
192
+ * stage — an optimistic derivation is an override, #3479). Its truth is not
193
+ * `_value` but a recompute from its inputs' truth, so the body-end
194
+ * supersession (`endOptimism`) and the authoritative-flight blockage
195
+ * (`transitionBlocked`) skip it; the revert drops the override and re-derives
196
+ * it (`resolveOptimisticNodes`). Cleared with the override. */
197
+ export declare const CONFIG_DERIVED_OVERRIDE: number;
198
+ /** Observe tiers only: the node is framework plumbing (the `solid-js/refresh`
199
+ * HMR memo between a component's root and its body) — it has no name, is no
200
+ * segment of any owner path, and the attribution engine records nothing about
201
+ * it (creation, re-runs, checks), while the nodes it owns stay fully observed.
202
+ * Set from the internal `_plumbing` option at creation; never set in prod. */
203
+ export declare const CONFIG_PLUMBING: number;
28
204
  export declare const STATUS_NONE = 0;
29
205
  export declare const STATUS_PENDING: number;
30
206
  export declare const STATUS_ERROR: number;
@@ -33,6 +209,9 @@ export declare const EFFECT_PURE = 0;
33
209
  export declare const EFFECT_RENDER = 1;
34
210
  export declare const EFFECT_USER = 2;
35
211
  export declare const EFFECT_TRACKED = 3;
212
+ /** OR-ed into the `type` a lane passes to its effect runners: lane runs
213
+ * apply ahead of their transaction and are exempt from ownership parking. */
214
+ export declare const LANE_RUN = 4;
36
215
  export declare const NOT_PENDING: {};
37
216
  export declare const NO_SNAPSHOT: {};
38
217
  /**
@@ -1,9 +1,10 @@
1
- import { type Refreshable } from "./constants.js";
2
1
  import { type OptimisticLane } from "./lanes.js";
3
- import type { Computed, FirewallSignal, NodeOptions, Owner, Signal } from "./types.js";
2
+ import type { Transition } from "./scheduler.js";
3
+ import type { Computed, FirewallSignal, NodeExtension, NodeOptions, Owner, Signal } from "./types.js";
4
4
  export declare const PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE = "[PRIMITIVE_IN_FORBIDDEN_SCOPE] Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled";
5
5
  export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE: string;
6
6
  export declare const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE: string;
7
+ export declare const ASYNC_STORE_SETTER_MESSAGE: string;
7
8
  export declare let tracking: boolean;
8
9
  /** @internal verdict-module glue */
9
10
  export declare function setPendingCheckActive(v: boolean): void;
@@ -16,6 +17,13 @@ export declare let pendingCheckActive: boolean;
16
17
  export declare let latestReadActive: boolean;
17
18
  export declare let context: Owner | null;
18
19
  export declare let currentOptimisticLane: OptimisticLane | null;
20
+ /** Notify `node`'s subscribers on `lane`'s channel: they recompute as the
21
+ * lane's passes — a memo publishes a derived override (lanes stage, #3479),
22
+ * an effect runs from the lane's queue, at the park, ahead of the
23
+ * transaction — the display-ahead view. The write itself is already staged
24
+ * (setSignal) and commits with the frame; this walk shows it now. Used by a
25
+ * boundary re-armed from a lane pass (boundaries.ts `_swap`, #3540). */
26
+ export declare function notifyOnLane(node: Signal<any>, lane: OptimisticLane): void;
19
27
  export declare let snapshotCaptureActive: boolean;
20
28
  export declare let snapshotSources: Set<any> | null;
21
29
  export declare function setSnapshotCapture(active: boolean): void;
@@ -25,15 +33,51 @@ export declare function clearSnapshots(): void;
25
33
  export declare function recompute(el: Computed<any>, create?: boolean): void;
26
34
  export declare function computed<T>(fn: (prev?: T) => T | PromiseLike<T> | AsyncIterable<T>): Computed<T>;
27
35
  export declare function computed<T>(fn: (prev: T) => T | PromiseLike<T> | AsyncIterable<T>, options?: NodeOptions<T>): Computed<T>;
36
+ /** Lazily allocate a node's cold extension (ONE shape for signals and
37
+ * computeds — `_x` access stays monomorphic). Installers write through
38
+ * this; hot paths read `el._x?._field` gated by the _config presence bits.
39
+ * Never call ext() just to store a field's default. */
40
+ export declare function ext(el: {
41
+ _x: NodeExtension | null;
42
+ }): NodeExtension;
28
43
  /**
29
44
  * Build an Effect node with all effect-specific fields baked into a single object literal,
30
45
  * so V8 sees the full hidden class shape at construction time. Effects always run in lazy
31
46
  * mode (recompute is called explicitly by `effect()`), so we hardcode the lazy bits and skip
32
47
  * the auto-dispose CONFIG bit (effect() previously cleared it post-construction).
33
48
  */
34
- 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;
49
+ 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;
50
+ /**
51
+ * The shared status notifier for effect nodes, installed once by effect.ts
52
+ * at module evaluation (`this`-dispatched — one function serves every
53
+ * effect, so nodes never store it). Boundary computeds keep their own
54
+ * per-node channel on `_x._notifyStatus`, which takes precedence.
55
+ */
56
+ export declare let effectStatusNotify: ((this: any, status?: number, error?: any) => void) | null;
57
+ export declare function setEffectStatusNotify(fn: NonNullable<typeof effectStatusNotify>): void;
58
+ /** Resolve a node's status notifier: an own `_x` channel (boundaries) wins;
59
+ * effect nodes (`_type` — EFFECT_PURE is 0, and only effect literals carry
60
+ * the field) fall back to the shared notifier. Presence doubles as the
61
+ * "display consumer" membership test in the status walks, exactly as the
62
+ * per-node field did when every effect carried one. */
63
+ export declare function statusNotifierOf(el: any): ((this: any, status?: number, error?: any) => void) | undefined;
35
64
  export declare function signal<T>(v: T, options?: NodeOptions<T>): Signal<T>;
36
65
  export declare function signal<T>(v: T, options?: NodeOptions<T>, firewall?: Computed<any>): FirewallSignal<T>;
66
+ /** The shared slot-node unobserved handler — a live binding read directly by
67
+ * the sweep sites (no wrapper frame, no null check: a CONFIG_SLOT_NODE node
68
+ * existing implies the store module loaded and registered the hook). */
69
+ export declare let slotUnobservedHook: (node: Signal<any>) => void;
70
+ /** Install the shared slot-node unobserved handler (store module, once). */
71
+ export declare function setSlotUnobserved(fn: (node: Signal<any>) => void): void;
72
+ /** Release a firewall child the store no longer addresses (unobserved sweep
73
+ * dropped it from its target's cache): unlink it from the chain so the
74
+ * projection stops retaining it and its last value. The node keeps its own
75
+ * `_nextChild` so a walk that is mid-chain on it still terminates. It also
76
+ * leaves `_companionChildren` (#3503): the companions themselves are
77
+ * permanent on the node, but the node is unreachable through the store, so
78
+ * the set would only retain it and its last value. */
79
+ export declare function unlinkFirewallChild(node: Signal<any>): void;
80
+ export declare function slotSignal<T>(v: T, equals: (a: T, b: T) => boolean, host: object, key: PropertyKey, acc: boolean, firewall?: Computed<unknown> | null): Signal<T>;
37
81
  export declare function optimisticSignal<T>(v: T, options?: NodeOptions<T>): Signal<T>;
38
82
  export declare function optimisticComputed<T>(fn: (prev?: T) => T | PromiseLike<T> | AsyncIterable<T>, options?: NodeOptions<T>): Computed<T>;
39
83
  export declare function isEqual<T>(a: T, b: T): boolean;
@@ -42,6 +86,30 @@ export declare function isEqual<T>(a: T, b: T): boolean;
42
86
  * scope will log a dev-mode warning. Managed automatically by `untrack(fn, strictReadLabel)`.
43
87
  */
44
88
  export declare let strictRead: string | false;
89
+ /** Dev-only: explicit untrack() nesting, so deliberate post-await reads stay quiet. */
90
+ export declare let untrackDepth: number;
91
+ /**
92
+ * Dev-only: > 0 while Solid runs user code that is imperative by construction
93
+ * — an effect callback (effect.ts) or an action body's synchronous slice
94
+ * (action.ts). Both run with no owner, exactly like an async continuation, so
95
+ * the post-await read check (dev.ts) consults this rather than blame the
96
+ * continuation that called flush() or invoked the action. Both sites bracket
97
+ * with try/finally, so a throw cannot leave it raised.
98
+ */
99
+ export declare let callbackDepth: number;
100
+ export declare function enterCallback(): void;
101
+ export declare function exitCallback(): void;
102
+ /**
103
+ * Dev-only: > 0 while owner teardown runs cleanups (`_disposal` entries and
104
+ * effect-returned cleanups — owner.ts), for the same reason. Kept apart from
105
+ * `callbackDepth` because its sites cannot use try/finally (the frame would
106
+ * survive into prod): a throwing cleanup leaves it raised, and dev.ts resets
107
+ * it on the next microtask, which teardown — synchronous — never spans.
108
+ */
109
+ export declare let disposalDepth: number;
110
+ export declare function enterDisposal(): void;
111
+ export declare function exitDisposal(): void;
112
+ export declare function resetDisposalDepth(): void;
45
113
  export declare function setStrictRead(v: string | false): string | false;
46
114
  /**
47
115
  * Runs `fn` outside of any reactive tracking — reads inside `fn` will not
@@ -66,6 +134,24 @@ export declare function setStrictRead(v: string | false): string | false;
66
134
  * ```
67
135
  */
68
136
  export declare function untrack<T>(fn: () => T, strictReadLabel?: string | false): T;
137
+ /**
138
+ * Set while runtime bookkeeping reads a node inside another node's pass (a
139
+ * loading boundary priming its tree at creation, from whatever pass is
140
+ * mounting it). `context` is that node, but the read is nobody's: the value
141
+ * is probed, never derived from, so nothing the read would normally record
142
+ * on `context` may be recorded — not the untracked-pending re-run link
143
+ * (`read`, `!tracking`; #3528: a boundary's `on` key read this way from
144
+ * `notify` linked the key's source into an unrelated async memo, a cycle that
145
+ * never converged), and not a transaction entry (`enterStagedRead`; #3540: a
146
+ * born-held tree would otherwise pull the mounting pass into the hold).
147
+ */
148
+ export declare let spectating: boolean;
149
+ /**
150
+ * Evaluates `fn` untracked, recording nothing on the current `context`: no
151
+ * untracked-pending re-run link, no transaction entry. For bookkeeping reads
152
+ * made on behalf of no node — see `spectating`.
153
+ */
154
+ export declare function spectate<T>(fn: () => T): T;
69
155
  /**
70
156
  * Bring a computed to a readable state: lazy/disposed nodes are (re)computed;
71
157
  * an isPending() probe (`refresh`) additionally pulls the node fully up to
@@ -86,16 +172,198 @@ export declare const READ_SLOW: unique symbol;
86
172
  * snapshot / transition / lane / dev-strictRead state all take the full
87
173
  * resolution. Anything slow returns READ_SLOW; the caller then calls read().
88
174
  */
175
+ /**
176
+ * Wake only authoritative-view readers (until() predicates) subscribed to `el`.
177
+ * The A17-silent ack paths — an authoritative arrival equal to the active
178
+ * override — use this so the predicate re-evaluates without re-firing
179
+ * ordinary subscribers whose visible (override) value did not change.
180
+ * Pay-for-use: reached through GlobalQueue._notifyAuthoritativeObservers,
181
+ * installed at first until() call — apps that never use until() shake it.
182
+ */
183
+ export declare function notifyAuthoritativeObservers(el: Signal<any> | Computed<any>): void;
184
+ /** Installs the authoritative-reader wakeup hook. Idempotent; called by every
185
+ * creator of a CONFIG_AUTHORITATIVE_READ computation — until() and refresh() —
186
+ * before its first read (same late-binding contract as the optimistic engine;
187
+ * the gating bit is only ever set by such a read, so the `!` call sites are
188
+ * safe once every setter installs, #3303). */
189
+ export declare function installAuthoritativeRead(): void;
190
+ /**
191
+ * Stale-reader term of the value selections below: a render effect reading a
192
+ * node some OTHER live transaction has staged sees the committed value. The
193
+ * commit is silent — the staging walk was the notification — so a reader
194
+ * that linked AFTER that walk (an effect created during the hold, a store
195
+ * key first read under it) would show the old value past the reveal: record
196
+ * it for the transaction's commit replay (the `_gatedSubs` contract lanes
197
+ * already use). An effect the transaction itself computed re-derives at its
198
+ * commit on its own (parked run, or the contested re-derive, #3322) and is
199
+ * not recorded — replaying it too would publish the frame twice.
200
+ *
201
+ * Flight twin (the pending-branch carve-out): the reader is served the
202
+ * node's committed, pre-flight value and now observes that flight — A15:
203
+ * async work observed by a reader settles as one unit with the writes that
204
+ * asked it — so it joins the transaction's reporters for the node. The
205
+ * reporter the transaction recorded when the flight started may be gone (a
206
+ * keyed remount disposed it, #3374); a completion check that found no live
207
+ * reporter committed the writes ahead of the answer, tearing the new
208
+ * reader's frame (`Count: 1` beside `Details: 0`). Joins an entry the
209
+ * transaction already holds; a flight nobody had observed yet has none (the
210
+ * reader is its first observer — a conditional that just revealed it, #3458)
211
+ * and is notified up the reader's own queue chain under that transaction,
212
+ * the one sanctioned registration site (INV-3): a collecting boundary above
213
+ * the reader consumes it as it would any pending, an unboundaried reader
214
+ * opens the entry — and the transaction, judged complete on its other
215
+ * flights, revealed the inputs beside the reader's pre-flight value
216
+ * otherwise (`Count: 1 | A: 1` beside `B: 0`). A staged signal or a settled
217
+ * node registers nothing. Every reporter dies with its reader
218
+ * (reporterBlocksSource: the read linked it as a dep). The node's own entry
219
+ * is the only one that can matter: a chain's intermediate memo is re-pulled
220
+ * by the read (updateIfNecessary's retry) and enters the transaction, so the
221
+ * reader holds through the normal path; a node with its own flight that is
222
+ * also pending on an upstream re-ask blocks through that flight until it
223
+ * lands, and its landing re-runs the reader into the normal path.
224
+ */
225
+ /** The replay half of the stale-of-foreign clause (A15 / A26): a stale reader
226
+ * served the committed value because `txn` holds what it read re-runs at
227
+ * txn's commit, when the value it was denied becomes the frame — unless its
228
+ * own last value already came from that transaction. One registration for
229
+ * the node path (heldFromStale) and the store's backing paths, which have
230
+ * no node to carry the hold (heldFromReader, the adoption hold view). */
231
+ export declare function recordStaleReplay(txn: Transition, c: Computed<any>): void;
232
+ /**
233
+ * The ownership relation (DESIGN-CONSOLIDATION §6, ruled 2026-09-17): is
234
+ * `hold` part of the running pass's world? A plain reader's world is the
235
+ * transaction it runs under, through merges. A lane reader's world is its
236
+ * lane AND the transition that owns the lane — the one asymmetry between a
237
+ * lane and a separate transaction (a lane sees what lands from its parent as
238
+ * its own; a separate transaction would wait for the parent to settle) —
239
+ * see `ownsLane` in lanes.ts, built on this. One relation for the
240
+ * stale-of-foreign clause (heldFromStale), the lane arm (readsHeldCommitted)
241
+ * and the store's backing holds (foreignHold); `serve` has no lane arm of
242
+ * its own, the lane's extra visibility lives here.
243
+ */
244
+ export declare function ownsHold(hold: Transition): boolean;
245
+ export declare function enterStagedRead(el: Signal<any> | Computed<any> | null, t?: Transition | null | undefined): void;
246
+ /**
247
+ * Rule 1 (value selection), the full arm: does this reader see a STAGED
248
+ * node's COMMITTED value? One implementation of the rule the fast paths
249
+ * (readNodeFast, read's fast block) carry as their trivial ternary and that
250
+ * every slow site — read's tail, the store's backing selection, the lane and
251
+ * verdict arms — used to restate by hand (docs/DESIGN-CONSOLIDATION.md, move 3b). In order:
252
+ * - no reader at all (an untracked read) — the committed frame;
253
+ * - a reader under an optimistic lane the engine says reads committed
254
+ * (laneReadsCommitted: another lane's hold, #3460);
255
+ * - nothing staged;
256
+ * - a children-forbidden reader (createTrackedEffect / onSettled: the frame,
257
+ * never the graph — A32);
258
+ * - a stale reader (render effect) of a FOREIGN transaction's staged write —
259
+ * committed, no entanglement (heldFromStale registers the replay; a node
260
+ * born held has no committed frame to fall back to, `noCommitted`);
261
+ * - HELD truth (#3164, CONFIG_HELD_TRUTH) read by a LANE pass: staged
262
+ * confirming truth — fold-staged onto an armed family, or entangle-stolen
263
+ * by an awaited until() — is masked from lane passes only, owning
264
+ * transaction or not. A lane applies its frame display-ahead at the park,
265
+ * so a lane pass served the truth would paint the confirmation beside the
266
+ * optimism it confirms (`saving=true` beside the saved row — the #3164
267
+ * tear); it keeps committed and is re-run by the reveal's post-revert
268
+ * wake. Every other deriving reader falls through to A29 below: the truth
269
+ * is a staged value like any other, and the pass that derives from it is
270
+ * held with it — including the retaining transaction's own passes, which
271
+ * a superseded override already hands the truth (#3568: masking them
272
+ * composed the landed `length` with rows still masked to committed).
273
+ * latest() and authoritative readers (until()'s predicate) tunnel
274
+ * through — the tunnel that keeps the hold deadlock-free.
275
+ * False means the reader derives from the staged value and enters its
276
+ * transaction (enterStagedRead, A29).
277
+ */
278
+ export declare function readerSeesCommitted(el: Signal<any> | Computed<any>, c: Computed<any> | null, owner: Signal<any> | Computed<any>, noCommitted: boolean): boolean;
279
+ /** A28 — set when a node is staged (queuePendingNode) or a held node rewritten
280
+ * (stashHeldRewrite) OUTSIDE a flush; cleared when the next flush begins. The
281
+ * read sites test this one module boolean instead of `globalQueue._running`:
282
+ * inside a flush it is false and the A28 arm costs nothing; outside, only a
283
+ * tick with unflushed writes pays the staged-node check. */
284
+ export declare let unflushedStaged: boolean;
285
+ export declare function markUnflushedStaged(): void;
286
+ /** A28 — a write becomes visible at flush. Outside a flush, a node holding an
287
+ * AMBIENT staged value (no transaction stamp) was written since the last
288
+ * flush: ambient staging commits at flush end, so nothing else leaves a node
289
+ * in this state; a stamped value is the flushed held world, which A28 says
290
+ * latest() serves. Inside a flush the rule does not apply (A28 (4): promoted
291
+ * within the round). Structural — no marker on the write path. */
292
+ export declare function unflushed(el: Signal<any> | Computed<any>): boolean;
293
+ /** The value an unflushed node serves — the committed value for an ambient
294
+ * write, the flushed staged value for a rewrite of a held node — or
295
+ * NOT_PENDING when nothing is unflushed. Exempt: owned-write nodes (A28 (4):
296
+ * a write issued inside a recompute is promoted at that recompute's end —
297
+ * boundary and loading machinery, until()'s internals, signals declared for
298
+ * in-computation writes) and engine companions (the isPending() verdict
299
+ * signal, the latest() shadow: the system's own writes, made at the source's
300
+ * write to mirror it, installing eagerly — A28, A8). */
301
+ export declare function unflushedValue(el: Signal<any> | Computed<any>, committed?: any): unknown;
302
+ /** A28 (5): an optimistic write becomes the ACTIVE override at the flush that
303
+ * carries it. `_overrideTime` is stamped with `clock` at the write and `clock`
304
+ * advances after every flush, so "this tick, outside a flush" is unflushed. */
305
+ export declare function unflushedOverride(el: Signal<any> | Computed<any>): boolean;
306
+ /** Active optimistic override on an armed node (an armed slot idles at
307
+ * NOT_PENDING; undefined = unarmed plain node). The writer's own channels —
308
+ * the draft, `in`/keys inside the setter — compose on this regardless of
309
+ * flush state. */
310
+ export declare function hasActiveOverride(el: Signal<any> | Computed<any>): boolean;
311
+ /** The override a READER sees: installed, and carried by a flush (A28 (5) —
312
+ * an optimistic write is a write; until its flush no reader sees it). One
313
+ * implementation for read()'s override arm, the verdict channels
314
+ * (latestRead, computePendingState) and the store's selection
315
+ * (docs/DESIGN-CONSOLIDATION.md, move 3b). */
316
+ export declare function visibleOverride(el: Signal<any> | Computed<any>): boolean;
317
+ /** A derivation served the committed value because of an unflushed write
318
+ * (A28) must run again in the flush that carries it — the late-linker case
319
+ * (#3337's reason to defer the walk): it linked after the write walked. */
320
+ export declare function markLateLinker(c: Computed<any>): true;
321
+ /** Companion-bearing nodes written outside a flush (setSignal); the flush
322
+ * that carries their writes re-syncs their companions (A28). */
323
+ export declare const unflushedCompanions: Array<Signal<any> | Computed<any>>;
324
+ export declare function resyncUnflushedCompanions(): void;
89
325
  export declare function readNodeFast<T>(el: Signal<T>): T | typeof READ_SLOW;
90
326
  export declare function read<T>(el: Signal<T> | Computed<T>): T;
327
+ /**
328
+ * Rule 1, the one slow implementation (DESIGN-CONSOLIDATION move 3b, step
329
+ * 6c): the value a reader `c` (null = untracked, no pass) is served from
330
+ * `el`, whose committed value is `committed` — the node's own `_value` for
331
+ * a signal or memo, the BACKING for a store property node (single-home rule,
332
+ * O6: committed truth lives in the backing and a node's `_value` is never
333
+ * served for one). Called by read()'s slow tail and by the store's untracked
334
+ * node path (nodeValue); the fast paths (readNodeFast, read's fast block)
335
+ * keep their trivial ternary by design (perf, see the doc). Arms, in order:
336
+ * - the override (A17), routed through the engine for a tracked reader under
337
+ * a lane or a supersession (A18), an authoritative reader marked instead;
338
+ * - the lane entanglement gate (committed, recorded for replay);
339
+ * - a node born held has nothing for an untracked reader (A19 exception 1);
340
+ * - an unflushed write serves committed and re-runs the reader in the
341
+ * carrying flush (A28);
342
+ * - readerSeesCommitted, else the staged value and the transaction (A29).
343
+ */
344
+ export declare function serve(el: Signal<any> | Computed<any>, c: Computed<any> | null, owner: Signal<any> | Computed<any>, committed: unknown): unknown;
91
345
  /**
92
346
  * Store-rewrite setter guard: the rewrite parks writes in a pending backing
93
347
  * (no setSignal at write time), so the owned-scope write protection must
94
- * fire at the setter entry instead. Mirrors setSignal's guard condition
348
+ * fire at the setter entry instead. Exactly setSignal's guard condition
95
349
  * minus the node-specific exemptions (ownedWrite/firewall), which don't
96
- * apply to plain store setters.
350
+ * apply to plain store setters. Roots are NOT exempt (#3500): a root body is
351
+ * tree construction — every dev component body, every context Provider, the
352
+ * top of `render()`, and the whole SSR pass run directly under one — and a
353
+ * write there re-runs what already read the old value (or on the server,
354
+ * can't). Same rule as setSignal, which never exempted roots.
97
355
  */
98
356
  export declare function devGuardStoreSetterWrite(): void;
357
+ /**
358
+ * Store setter result guard: the callback's return has one meaning — a
359
+ * replacement root to adopt — and a thenable can never be that. It is the
360
+ * signature of `setStore(async d => …)` (or a sync arrow whose helper is
361
+ * async): only the writes before the first `await` were in the transaction;
362
+ * the rest land on a closed draft and vanish. Setters are synchronous
363
+ * transactions; async orchestration is `action()`'s job. Store-specific —
364
+ * a signal may legitimately hold a promise, so its setter has no such rule.
365
+ */
366
+ export declare function devGuardStoreSetterResult(result: unknown): void;
99
367
  export declare function setSignal<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)): T;
100
368
  /**
101
369
  * Suppresses automatic recomputation of `el` until the scheduler drains. Used
@@ -105,11 +373,30 @@ export declare function setSignal<T>(el: Signal<T> | Computed<T>, v: T | ((prev:
105
373
  * cleanup point.
106
374
  */
107
375
  export declare function suppressComputedRecompute(el: Computed<unknown>): void;
376
+ /** A34 amendment (#3612) — is `el`'s staging a DERIVATION another transaction
377
+ * holds: stamped by a transaction that is not the writer's, and not a manual
378
+ * proposal (the mask, on the node or — a store leaf — its firewall)? #2692's
379
+ * "manual write wins" is a rule for one synchronous frame; across a hold the
380
+ * held pass result is nobody's proposal, and a user setter reaching it
381
+ * composes on the committed frame it was written against and becomes `prev`
382
+ * for the transaction's re-derivation (rederiveHeld) instead of replacing it.
383
+ * Writes made under the holding transaction masked the node and keep
384
+ * A34(1)'s last-write-wins. Only the user setters ask; an async landing or a
385
+ * companion writing a stamped node is the transaction's own work. */
386
+ export declare function heldDerivation(el: Signal<any> | Computed<any>): boolean;
387
+ /** The held-derivation write's second half: the node re-derives under its
388
+ * hold with the written staging as the pass's `prev`. Nothing is masked. The
389
+ * write took the A34 join (setSignal), which scheduled the flush that drains
390
+ * this; recompute re-enters the stamp. */
391
+ export declare function rederiveHeld(el: Computed<unknown>): void;
108
392
  /**
109
393
  * User-facing setter for the memo form of `createSignal(fn)`. Behaves like
110
394
  * `setSignal`, but also cancels any pending recompute of the memo so the
111
395
  * manual value wins over a value that would otherwise be produced by an
112
- * upstream change in the same tick.
396
+ * upstream change in the same tick. Across a hold the write is not a
397
+ * proposal: a memo another transaction holds as a pass result composes on the
398
+ * committed value and re-derives under the hold with the write as `prev`
399
+ * (A34 amendment, #3612; heldDerivation).
113
400
  */
114
401
  export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
115
402
  /**
@@ -134,23 +421,10 @@ export declare function setMemo<T>(el: Computed<T>, v: T | ((prev: T) => T)): T;
134
421
  export declare function runWithOwner<T>(owner: Owner | null, fn: () => T): T;
135
422
  export declare function staleValues<T>(fn: () => T, set?: boolean): T;
136
423
  /**
137
- * Invalidates one reactive source, forcing it to re-execute even if its inputs
138
- * haven't changed.
139
- *
140
- * Pass either a Solid-created accessor or a projected store created from
141
- * `createStore(fn, ...)` / `createProjection(...)`. `refresh()` is a
142
- * write-like invalidation operation: it does not read the target's value, and
143
- * refreshing a plain signal accessor is a no-op.
144
- *
145
- * Use it to invalidate cached async values (e.g. force a re-fetch) without
146
- * tearing the consumer down.
147
- *
148
- * @example
149
- * ```ts
150
- * const user = createMemo(async () => fetch(`/users/${id()}`).then(r => r.json()));
151
- *
152
- * // Re-fetch on demand
153
- * <button onClick={() => refresh(user)}>Reload</button>
154
- * ```
424
+ * Core marking half of `refresh()` (the public wrapper lives in signals.ts —
425
+ * it validates the target, marks through here, then builds the quiescence
426
+ * promise on the resolve()/until() effect machinery). Flags the node's next
427
+ * recompute as a quiet re-ask and schedules it; no-ops for non-derived or
428
+ * disposed targets and for same-tick manual writes.
155
429
  */
156
- export declare function refresh<T>(target: Refreshable<T>): void;
430
+ export declare function markRefresh(node: Computed<any>): void;