@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
@@ -2,7 +2,7 @@ import type { OptimisticLane } from "./lanes.js";
2
2
  import type { Computed, Signal } from "./types.js";
3
3
  /**
4
4
  * Test-mode invariant checks for the async/transition/lane machinery.
5
- * Catalog and rationale: packages/solid-signals/INTERNALS-ASYNC-STATE.md.
5
+ * Catalog and rationale: packages/signals/docs/INTERNALS-ASYNC-STATE.md.
6
6
  *
7
7
  * These are implementation self-consistency checks, not semantic rules: a
8
8
  * violation means the reactive system contradicted itself.
@@ -25,6 +25,10 @@ export declare const InvariantHooks: {
25
25
  };
26
26
  export declare function devTrackHeldPending(node: AnyNode): void;
27
27
  export declare function devTrackCompanionOwner(node: AnyNode): void;
28
+ /** #3503: a firewall child the store released (unobserved sweep) leaves the
29
+ * registry with it — the runtime drops it from `_companionChildren` so the
30
+ * projection stops retaining it; the test-only set must not either. */
31
+ export declare function devUntrackCompanionOwner(node: AnyNode): void;
28
32
  export declare function devTrackOptimistic(node: AnyNode): void;
29
33
  export declare function devTrackAffects(node: AnyNode): void;
30
34
  /**
@@ -1,3 +1,5 @@
1
+ import { hasActiveOverride } from "./core.js";
2
+ export { hasActiveOverride };
1
3
  import { type QueueCallback, type Transition } from "./scheduler.js";
2
4
  import type { Computed, Signal } from "./types.js";
3
5
  /**
@@ -24,6 +26,52 @@ export declare function getOrCreateLane(signal: Signal<any>): OptimisticLane;
24
26
  * Union-find: find the root lane.
25
27
  */
26
28
  export declare function findLane(lane: OptimisticLane): OptimisticLane;
29
+ /**
30
+ * Is the lane held? `_pendingAsync` records the async the lane OWNS (derived
31
+ * under it); a transaction's reporter map records the async a render effect
32
+ * OBSERVED pending with no boundary taking it (INV-3, the one registration
33
+ * site). A hold needs both — the same rule the transaction itself uses, so a
34
+ * memo nobody renders, or one a fallback-showing boundary caught, cannot tear
35
+ * a frame and holds nothing (#3289). An orphan lane has no observation record
36
+ * and never holds.
37
+ *
38
+ * The observation is looked up per NODE, in whichever live transaction
39
+ * recorded it — not in this lane's transaction. Lanes merge across
40
+ * transactions (#2912: ownership never travels through lanes), so after a
41
+ * merge the root's transaction holds the observations of only one member;
42
+ * the async the other member's transaction observed must hold the merged
43
+ * reveal just the same (A15 for lanes, #3335).
44
+ */
45
+ export declare function laneHeld(lane: OptimisticLane): boolean;
46
+ /**
47
+ * Lanes mirror transitions (#3460): a render effect OFF a HELD lane that reads
48
+ * a value the lane is revealing — an override, a `latest()` shadow — sees the
49
+ * committed value, exactly as a stale reader of a held transaction does
50
+ * (A15 reveal corollary): it publishes now, with the frame that is on screen
51
+ * (the lane defers its own readers' runs, so the committed value is what is
52
+ * visible), entangles nothing — a sync write is never held by a lane — and
53
+ * re-derives at the release. The release re-run rides the lane's own render
54
+ * queue, which runs when the lane reveals (runLaneEffects) or its transaction
55
+ * commits (cleanupCompletedLanes). A reader ON the lane computes the lane's
56
+ * reveal and takes the value as before.
57
+ *
58
+ * OFF the lane is provenance, not membership — the transaction mirror
59
+ * exactly: a stale reader of a transaction is a pass that runs outside it. A
60
+ * pass under the lane's own transaction is the lane's work — its write (lane
61
+ * posture), or the landing of its async, which re-enters the transaction
62
+ * (#3334) and runs a member with no ambient lane. Read as an outsider, that
63
+ * pass published the committed view and queued a replay that revealed the
64
+ * override beside its unready derivation at the release (`1:0` for an
65
+ * optimistic frame that never became ready; #3479 review). Membership is the
66
+ * wrong test the other way: a member re-run by a sibling's sync write is a
67
+ * mainline pass and shows the committed view.
68
+ */
69
+ export declare function readsHeldCommitted(owner: Computed<any>, c: Computed<any>): boolean;
70
+ /** The ownership relation for a lane hold (core `ownsHold`, §6 ruling 2): the
71
+ * running pass owns `lane`'s hold if it runs under the transition that owns
72
+ * the lane (the node's, resolved through override ownership and merges) or
73
+ * inside the lane itself. */
74
+ export declare function ownsLane(lane: OptimisticLane, owner: Computed<any>): boolean;
27
75
  /**
28
76
  * Merge two lanes when their dependency graphs overlap.
29
77
  */
@@ -31,26 +79,10 @@ export declare function mergeLanes(lane1: OptimisticLane, lane2: OptimisticLane)
31
79
  /**
32
80
  * Resolve a node's lane: follow union-find chain, verify active, clear if stale.
33
81
  */
34
- export declare function resolveLane(el: {
35
- _optimisticLane?: OptimisticLane;
36
- }): OptimisticLane | undefined;
37
- export declare function resolveTransition(el: {
38
- _optimisticLane?: OptimisticLane;
39
- _transition?: Transition | null;
40
- _overrideValue?: any;
41
- _overrideOwner?: Transition | null;
42
- }): Transition | null | undefined;
43
- /**
44
- * Check if a node has an active optimistic override.
45
- */
46
- export declare function hasActiveOverride(el: {
47
- _overrideValue?: any;
48
- }): boolean;
82
+ export declare function resolveLane(el: Signal<any> | Computed<any>): OptimisticLane | undefined;
83
+ export declare function resolveTransition(el: Signal<any> | Computed<any>): Transition | null | undefined;
49
84
  /**
50
85
  * Assign or merge a lane onto a node. At convergence points (node already has
51
86
  * a different active lane), merge unless the node has an active override.
52
87
  */
53
- export declare function assignOrMergeLane(el: {
54
- _optimisticLane?: OptimisticLane;
55
- _overrideValue?: any;
56
- }, sourceLane: OptimisticLane): void;
88
+ export declare function assignOrMergeLane(el: Signal<any> | Computed<any>, sourceLane: OptimisticLane): void;
@@ -2,6 +2,7 @@ import type { Computed, Disposable, Owner, Root } from "./types.js";
2
2
  export declare function markDisposal(el: Owner): void;
3
3
  export declare function dispose(node: Computed<unknown>): void;
4
4
  export declare function disposeChildren(node: Owner, self?: boolean, zombie?: boolean): void;
5
+ export declare function linkChild(parent: Owner, node: Owner): void;
5
6
  /**
6
7
  * Allocates and returns the next stable child id for `owner`. Used by
7
8
  * hydration plumbing and `createUniqueId`. Not part of the user-facing API.
@@ -95,9 +96,15 @@ export declare function createOwner(options?: {
95
96
  transparent?: boolean;
96
97
  }): Root;
97
98
  /**
98
- * Creates a detached reactive root. The callback receives a `dispose()`
99
- * function which, when called, tears down every signal, memo, effect, and
100
- * `onCleanup` registered inside the root.
99
+ * Creates a reactive root — an owner scope with its own `dispose()`. A root
100
+ * created inside an existing owner is owned by it and is disposed when the
101
+ * parent is disposed; call `dispose()` to tear it down earlier. To create a
102
+ * root that outlives its creator, detach explicitly:
103
+ * `runWithOwner(null, () => createRoot(...))`. Pass `id` to seed hydration
104
+ * ids for the tree it owns.
105
+ *
106
+ * `dispose()` tears down every signal, memo, effect, and `onCleanup`
107
+ * registered inside the root.
101
108
  *
102
109
  * Use this to host long-lived reactive scopes outside of a component (custom
103
110
  * controllers, app bootstrapping, tests). Inside a component, prefer
@@ -105,6 +112,7 @@ export declare function createOwner(options?: {
105
112
  *
106
113
  * @example
107
114
  * ```ts
115
+ * // At module level there is no owner, so this root lives until disposed.
108
116
  * const dispose = createRoot(dispose => {
109
117
  * const [n, setN] = createSignal(0);
110
118
  * createEffect(() => n(), value => console.log(value));
@@ -114,6 +122,10 @@ export declare function createOwner(options?: {
114
122
  *
115
123
  * // Later, to tear everything down:
116
124
  * dispose();
125
+ *
126
+ * // Inside an owner (component, effect, another root), detach explicitly
127
+ * // if the root must outlive its creator:
128
+ * const detached = runWithOwner(null, () => createRoot(d => d));
117
129
  * ```
118
130
  *
119
131
  * @description https://docs.solidjs.com/reference/reactive-utilities/create-root
@@ -3,13 +3,25 @@ import { activeLanes, assignOrMergeLane, findLane, type OptimisticLane } from ".
3
3
  import type { Computed, Signal } from "./types.js";
4
4
  export { activeLanes, assignOrMergeLane, findLane };
5
5
  export { getOrCreateLane, hasActiveOverride, mergeLanes, resolveLane } from "./lanes.js";
6
+ export declare const transitions: Set<Transition>;
6
7
  export declare const dirtyQueue: Heap;
7
8
  export declare const zombieQueue: Heap;
8
9
  export declare let clock: number;
9
10
  export declare let activeTransition: Transition | null;
10
11
  export declare let projectionWriteActive: boolean;
12
+ /** > 0 while an action's generator body is on the stack (the synchronous
13
+ * slice between yields). Maintained by action.ts around `it.next()`. */
14
+ export declare let actionStepDepth: number;
15
+ export declare function enterActionStep(): void;
16
+ export declare function exitActionStep(): void;
11
17
  export declare let _hitUnhandledAsync: boolean;
12
- export declare function resetUnhandledAsync(): void;
18
+ /** Slot hook's deferral: release this node when its carried state resolves. */
19
+ export declare function deferSlotRelease(node: Signal<any>): void;
20
+ /**
21
+ * Consume the unhandled-async hit. Returns whether this is the first report
22
+ * of the current enforcement window — the caller warns only then.
23
+ */
24
+ export declare function resetUnhandledAsync(): boolean;
13
25
  /**
14
26
  * Toggles the dev-mode "must be inside a `<Loading>` boundary" enforcement
15
27
  * window. Only `render()` calls this — wrapping the initial mount so that a
@@ -36,16 +48,100 @@ export interface Transition {
36
48
  _affectsNodes: OptimisticNode[];
37
49
  _optimisticStores: Set<any>;
38
50
  _actions: Array<Generator<any, any, any> | AsyncGenerator<any, any, any>>;
51
+ /** An action ran in this transaction (#3427, set by action()): once
52
+ * `_actions` drains, its bodies are OVER — as opposed to a transaction that
53
+ * never had one, whose bare optimistic writes live until it settles. */
54
+ _acted?: boolean;
39
55
  _queueStash: QueueStub;
40
56
  _done: boolean | Transition;
41
57
  _gatedSubs: Set<Computed<any>>;
58
+ /** Effects whose single value slot was written under this transaction AND
59
+ * another live one (#3322). Re-dirtied at commit, ahead of the effect
60
+ * phase, so the run publishes a value derived from the committed world
61
+ * rather than whichever transaction's staged view wrote last. */
62
+ _contested: Computed<any>[] | null;
42
63
  }
64
+ /**
65
+ * Flip-entanglement (#3164 follow-up): `until()` is a declaration of
66
+ * relatedness — the predicate names the condition that confirms the awaiting
67
+ * transaction. When the predicate settles truthy, every live foreign
68
+ * transition whose staged write it read IS the confirming event by the
69
+ * user's own definition, so it merges into the awaiting transaction and
70
+ * reveals at the joint settle — the cross-primitive twin of the family fold
71
+ * (a landing on an optimism-carrying family joins the retaining
72
+ * transaction). Non-flipping updates never pass through here: falsy
73
+ * evaluations don't entangle, so unrelated traffic on the watched sources
74
+ * reveals freely on its own schedule.
75
+ *
76
+ * Runs inside the predicate's compute (pure phase) — the confirming
77
+ * transition's stamps are still live and its commit decision hasn't run, so
78
+ * the merge lands before any reveal. Only the tree-shaken graphs that call
79
+ * `until()` retain this.
80
+ */
81
+ export declare function entangleConfirmingTransitions(obs: Computed<any>, target: Transition): void;
43
82
  export declare function schedule(): void;
83
+ /** Arm the microtask `schedule()` withheld under projectionWriteActive. The
84
+ * projection draft calls this after a write made outside its run with no
85
+ * flight up (proj R37): nothing else will drain, and leaving `scheduled`
86
+ * armed with no microtask strands the whole scheduler — every later
87
+ * `schedule()` early-returns — until something calls `flush()` by hand.
88
+ * (`withheld` was set in the same synchronous slice as this call, so the
89
+ * syncDepth/_running gates it passed still hold; a stale mark left by a
90
+ * landing's own flush arms at worst one no-op drain.) */
91
+ export declare function scheduleWithheld(): void;
92
+ /**
93
+ * Parked transactions whose reporter set changed without a write. A
94
+ * transaction completes when nothing live reports a flight it waits on, but
95
+ * the flush only judges the ACTIVE transaction: a parked one is re-entered by
96
+ * a stamped node's landing or an action's resume. A reporter that stops
97
+ * counting for another reason — its loading boundary flipped to the fallback
98
+ * (#3375), or it was disposed by ambient work (#3372) — is neither: the
99
+ * pruning in `reporterBlocksSource` would drop it at the next check, but no
100
+ * check comes, and the writes held with it stay staged. Such sites record the
101
+ * transaction here (deduped: one idle pass per transaction, however many
102
+ * reporters changed); the flush re-enters it on an otherwise idle pass, so
103
+ * the re-evaluation adopts no unrelated ambient work.
104
+ */
105
+ export declare const wokenTransitions: Transition[];
106
+ /** Wake every parked transaction — for a site that knows a reporter stopped
107
+ * counting but not whose (a boundary reset). */
108
+ export declare function wakeParked(): void;
109
+ /** A boundary that can be re-armed (boundaries.ts `CollectionQueue._rearm`). */
110
+ export interface Rearmable {
111
+ _rearm(): void;
112
+ }
113
+ /**
114
+ * Boundaries whose `on` dependencies notified this flush (#3540; a Set:
115
+ * many notifications, one re-arm). The notification arrives inside a pass,
116
+ * at the height of the `on` reads — before the readers the write put in
117
+ * flight are registered — so the re-arm waits for the heap and runs before
118
+ * the verdict (GlobalQueue.run → drainRearms), still under the write's
119
+ * transaction: the release is seen by the verdict that follows, and the
120
+ * staged fallback swap lands with the write's frame.
121
+ */
122
+ export declare const pendingRearms: Set<Rearmable>;
123
+ export declare function queueRearm(boundary: Rearmable): void;
124
+ /** Transactions a mainline tick has PROPOSED against (A34, #3494): a write to a
125
+ * node one of them holds — the same value or another — is a second proposal
126
+ * on a contested node, and the tick reveals with the hold ("both are
127
+ * suggesting a value; if one finished before the other that would be odd").
128
+ * Entered at the next flush's start, where the ambient batch is adopted;
129
+ * never from the write itself, which left `activeTransition` set across the
130
+ * caller's block and made creation after the write the transaction's (A29). */
131
+ export declare const batchJoins: Transition[];
44
132
  /**
45
133
  * Permanently halts the reactive system. Called when a user error escapes
46
134
  * every boundary — app state is undefined at that point, so scheduling stops
47
135
  * entirely rather than limping along with a half-applied update.
48
136
  */
137
+ /**
138
+ * The key a root owner carries its client error hook under (`render`'s
139
+ * `onError`) — registered, so a runtime writes it with no import of the hook
140
+ * module (core/error-hooks.ts) and no property mangling in the way. Defined
141
+ * HERE, not there: a runtime that only writes the key must not retain the
142
+ * hook machinery (pay-for-use).
143
+ */
144
+ export declare const ROOT_ERROR_HOOK: unique symbol;
49
145
  export declare function haltReactivity(cause?: unknown): void;
50
146
  /** @internal Test/dev-reload hook. Revives scheduling after a halt. */
51
147
  export declare function resetErrorHalt(): void;
@@ -59,6 +155,11 @@ export interface IQueue {
59
155
  stashQueues(stub: QueueStub): void;
60
156
  restoreQueues(stub: QueueStub): void;
61
157
  _parent: IQueue | null;
158
+ /** Loading/error boundary queues (boundaries.ts): the status dimension the
159
+ * queue consumes, and whether it currently shows content (initialized) or
160
+ * its fallback (collecting). Read by `reporterBlocksSource`. */
161
+ _collectionType?: number;
162
+ _initialized?: boolean;
62
163
  }
63
164
  export declare class Queue implements IQueue {
64
165
  _parent: IQueue | null;
@@ -97,27 +198,119 @@ export declare class GlobalQueue extends Queue {
97
198
  static _applyReask: ((el: Computed<any>, hadReask: boolean) => boolean) | null;
98
199
  static _repollVerdicts: ((el: Computed<any>, snap?: boolean) => void) | null;
99
200
  static _witnessAffects: ((node: OptimisticNode) => void) | null;
201
+ static _wakeSuppressedProbes: ((transition: Transition) => void) | null;
100
202
  static _optimisticWrite: (<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)) => T) | null;
101
203
  static _resolveOptimistic: ((nodes: OptimisticNode[]) => void) | null;
102
204
  static _transitionBlocked: ((transition: Transition) => boolean) | null;
103
205
  static _cleanupLanes: ((completingTransition: Transition | null) => void) | null;
104
206
  static _runLaneEffects: ((type: number) => void) | null;
207
+ /** Patch-channel optimistic drain (next/patch.ts): optimistic emissions
208
+ * apply at lane-effect timing — visible in flight, unlike the regular
209
+ * effect queues an action stashes. Injected; null when unused. */
210
+ static _drainPatchOptimistic: (() => void) | null;
105
211
  static _gatedRead: ((el: Signal<any>, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
106
212
  static _laneSuspends: ((owner: OptimisticNode) => boolean) | null;
213
+ /** Is the node routed through a LIVE lane (`resolveLane`)? read()'s reveal
214
+ * carve-out asks before showing a foreign-held pending node's committed
215
+ * value: a lane-derived flight's inputs are already revealed through the
216
+ * lane (#3334). Gated on CONFIG_HAS_LANE, which only the engine sets. */
217
+ static _laneLive: ((el: Computed<any>) => boolean) | null;
107
218
  static _laneReadsCommitted: ((el: OptimisticNode, owner: OptimisticNode, c: Computed<any>) => boolean) | null;
108
219
  static _recomputeLane: ((el: Computed<any>, own: boolean) => OptimisticLane | null | false) | null;
109
220
  static _laneAsyncPending: ((el: Computed<any>) => void) | null;
221
+ /** Authoritative-view reader wakeup: installed by until() and refresh() before
222
+ * their first read. Call sites are gated by CONFIG_AUTHORITATIVE_OBSERVED, which
223
+ * only such a reader's carve-out read can set, so `!` invocations are safe once
224
+ * the gate holds (#3303). */
225
+ static _notifyAuthoritativeObservers: ((el: Signal<any> | Computed<any>) => void) | null;
110
226
  static _laneAsyncSettled: ((el: Computed<any>) => void) | null;
227
+ /** A18 supersession (#3331): own-source truth `value` landed under an active
228
+ * override. The engine decides whether the graph re-derives — the value
229
+ * differs from the override and is not a stale (older-action) answer (mark
230
+ * the node, demote its lane cascade, notify), or returns to it after an
231
+ * earlier differing arrival (clear the mark, notify) — and owns the
232
+ * authoritative-observer wake for a silent confirm. Installed with the
233
+ * optimistic engine; only reachable on a node that has an override. */
234
+ static _supersedeOverride: ((el: Signal<any> | Computed<any>, value: unknown) => void) | null;
235
+ /** The flush's pre-verdict step (#3427): once the transaction's action
236
+ * bodies have all ended and nothing authoritative is left in flight, the
237
+ * engine supersedes every override still in force with the truth it
238
+ * reverts to, so the graph re-derives from it now, as the transaction's
239
+ * held work, instead of after the flights the overrides fed have landed.
240
+ * True when it superseded something: the caller re-runs the heap ahead of
241
+ * the verdict. The engine owns every gate (acted, actions drained, has
242
+ * overrides, no store edits, no authoritative flight); null without it. */
243
+ static _endOptimism: ((transition: Transition) => boolean) | null;
244
+ /** read()'s value for a TRACKED reader of a superseded node (#3331): the
245
+ * staged truth, unless the reader is a stale (render) reader of another
246
+ * transaction — then the displayed override, as it keeps a foreign
247
+ * transaction's committed value over its staged write. */
248
+ /** A tracked read of an active override: the lane outside-view rule
249
+ * (#3460) and the A18 supersession selection (#3331) — see optimistic.ts. */
250
+ static _overrideRead: ((el: Computed<any>, c: Computed<any>) => unknown) | null;
251
+ /** A lane pass's publish for a memo (#3479, lanes stage): the speculative
252
+ * result becomes a DERIVED override, `_value` stays committed — see
253
+ * optimistic.ts laneOverride. Set with the engine, which a lane implies. */
254
+ static _laneOverride: ((el: Computed<any>, value: unknown, lane: OptimisticLane) => void) | null;
255
+ /** Verdict-layer recompute in progress (companion creation, latest()/
256
+ * isPending() pulls): never born held — see core.ts enterStagedRead. */
257
+ static _verdictPull: boolean;
258
+ /** setSignal's authoritative (projection-write) landing on an override-
259
+ * covered node (#3331 store twin): stage the truth for its transaction's
260
+ * commit whatever its relation to the committed value — a landing equal to
261
+ * committed still differs from the override — then _supersedeOverride
262
+ * decides. Installed with the optimistic engine; only reachable on a node
263
+ * that has an override. */
264
+ static _landOnOverride: (<T>(el: Signal<T> | Computed<T>, v: T | ((prev: T) => T)) => T) | null;
111
265
  static _trackOptimisticStore: ((store: any) => void) | null;
112
266
  flush(): void;
113
267
  notify(node: Computed<any>, mask: number, flags: number, error?: any): boolean;
114
268
  initTransition(transition?: Transition | null): void;
115
269
  }
116
270
  export declare function queuePendingNode(node: Signal<any>): void;
271
+ export declare let reaskArmed: boolean;
272
+ /** §12d: bumped by every recompute and every new subscriber edge. A node's
273
+ * staged-rewrite skip is sound only while NOTHING recomputed or linked since
274
+ * its last notify — a mid-batch pull can clean a marked subscriber, and a
275
+ * skipped re-write would leave it stale. */
276
+ export declare let notifyEpoch: number;
277
+ export declare function bumpNotifyEpoch(): void;
117
278
  export declare function armReaskClear(): void;
279
+ /** Provenance of the work currently running (A18 supersession, #3331): the
280
+ * invocation sequence of the action whose ambient window this is — set by
281
+ * action() for each slice; the flush that ends the window clears it — or,
282
+ * inside an async landing, the sequence captured when that flight was
283
+ * registered (asyncWrite sets it for the landing's synchronous propagation,
284
+ * so a sync recompute downstream of the landing — an optimistic wrapper over
285
+ * the async source — derives under the flight's provenance, and flights it
286
+ * registers inherit it). 0 is mainline: no action, always the current
287
+ * question. An override stamps this at its write (`_overrideStamp`); an
288
+ * answer whose flight an OLDER action issued is a stale question the user
289
+ * has since changed — it holds silently to commit instead of superseding. A
290
+ * slow source must not leak back in over a newer intent. Transactions merge,
291
+ * so the transition object cannot say WHICH action asked; this can. */
292
+ export declare let origin: number;
293
+ export declare function setOrigin(seq: number): number;
118
294
  export declare function insertSubs(node: Signal<any> | Computed<any>, optimistic?: boolean): void;
119
295
  export declare let storeCommitHook: (() => void) | null;
120
296
  export declare function setStoreCommitHook(fn: () => void): void;
297
+ /** Patch-channel release hook (next/patch.ts): transition-stamped patch
298
+ * emissions are released when THEIR batch commits. Transitions never
299
+ * abort: failed actions still commit (only optimistic overrides revert),
300
+ * and merged-away transitions hand their stash to the survivor
301
+ * (mergeTransitionState) — every stash drains exactly once. Injected like
302
+ * storeCommitHook to stay tree-shakeable. */
303
+ export declare let patchCommitHook: ((batch: Transition) => void) | null;
304
+ export declare function setPatchCommitHook(fn: (batch: Transition) => void): void;
305
+ /** Unchanged passes with a stale dependency tail, waiting on this flush's
306
+ * verdict (A30, #3469). A pass that changed nothing replaced nothing either —
307
+ * and cannot know at its own tail whether the flush that ran it will park:
308
+ * parked, its inputs are held and the committed frame still derives from the
309
+ * tail (`b() ? b() : a()` computed `1` from the held `b`, equal to the `1` it
310
+ * had from `a` — with `a` trimmed, the mainline `a = 2` never reached it).
311
+ * Trimmed when the flush commits; dropped with a park, the tail stays linked
312
+ * until a committing pass trims it (one spurious recompute at most). */
313
+ export declare const heldTrims: Computed<any>[];
121
314
  export declare function finalizePureQueue(completingTransition?: Transition | null, incomplete?: boolean): void;
122
315
  /**
123
316
  * Count of live `affects()` registrations across the system (including
@@ -167,6 +360,60 @@ export declare const globalQueue: GlobalQueue;
167
360
  */
168
361
  export declare function flush(): void;
169
362
  export declare function flush<T>(fn: () => T): T;
363
+ /** Does `reporter` still hold the transaction waiting on `source` — live,
364
+ * routed to no collecting loading boundary, and deriving from the source in
365
+ * its current pass? The verdict's per-reporter test (sourceObserved), also
366
+ * a boundary re-arm's (boundaries.ts `_rearm` runs before the verdict prunes
367
+ * registrations that stopped counting). */
368
+ export declare function reporterBlocksSource(reporter: Computed<any>, source: Computed<any>, verdict?: Transition): boolean;
369
+ /**
370
+ * Does a live reporter of `transition` still observe `source` pending? Dead
371
+ * reporters (disposed, behind a fallback, no longer reading the source) are
372
+ * pruned as they are found, and the source's entry with them. Shared by the
373
+ * settle verdict and the lane's hold check (`waitingTransition`): a live
374
+ * action parks its transaction without a verdict, so this prune is the only
375
+ * one an optimistic lane whose last async reader unmounted mid-action ever
376
+ * gets — without it the lane held on the dead reporter's registration until
377
+ * the flight it no longer observed landed (#3426).
378
+ */
379
+ export declare function sourceObserved(transition: Transition, source: Computed<any>, verdict?: Transition): boolean;
380
+ /** A fresh, unentered transaction (#3146): the optimistic store's truth
381
+ * flight DECLARES an owned transaction instead of relying on whatever the
382
+ * ambient adoption machinery stamped on its firewall. Activate it with
383
+ * initTransition; it is a plain batch until then. */
384
+ export declare function createTransition(): Transition;
170
385
  export declare function currentTransition(transition: Transition): Transition;
386
+ /**
387
+ * The live transition blocked on `source` — the one whose render reader
388
+ * observed it pending (INV-3 records the observation in whichever transaction
389
+ * was active when the reader was notified). The observation is a fact about
390
+ * the node, so a hold check must not assume it was recorded in the transaction
391
+ * it happens to hold — lanes merge across transactions (#2912), and a merged
392
+ * root's transaction knows nothing of the async its members' transactions
393
+ * observed (#3335). Null when nobody is waiting — a registration whose every
394
+ * reporter has since died is nobody (#3426).
395
+ */
396
+ export declare function waitingTransition(source: Computed<any>): Transition | null;
397
+ /** A landing enters EVERY parked transaction still waiting on `source`, folding
398
+ * them into the active one (A15: each reveal that discovered the flight
399
+ * completes at its landing). The fold used to happen as the waiters' stamped
400
+ * readers recomputed under the landing — recompute re-entering an effect's
401
+ * stamp — which also folded in writes those readers merely shared a hole
402
+ * with (#3407); effects no longer re-enter, so the landing folds explicitly.
403
+ * Live iteration is safe: a merge deletes the outgoing (active) entry and
404
+ * re-adds the visited one. */
405
+ export declare function enterWaiting(source: Computed<any>): void;
171
406
  export declare function setActiveTransition(transition: Transition | null): void;
172
407
  export declare function runInTransition<T>(transition: Transition, fn: () => T): T;
408
+ /** Run `fn` with `transition` as BOTH the ambient transaction and the
409
+ * registration batch, restoring both after. runInTransition alone is not
410
+ * enough for code that WRITES on behalf of a transaction from inside someone
411
+ * else's window (optimistic replay re-arming a still-open action's edits
412
+ * during a landing commit, #3123): registrations route through the queue's
413
+ * batch pointer, and a bare activeTransition swap leaves them in the ambient
414
+ * batch — a plain batch "completes" at the next flush and reverts optimistic
415
+ * registrations that were supposed to live with the transaction.
416
+ * initTransition is the wrong tool here: it MERGES the currently ambient
417
+ * transaction into the target, entangling whatever the interrupted window
418
+ * belonged to. */
419
+ export declare function runAsTransitionBatch<T>(transition: Transition, fn: () => T): T;