@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
@@ -0,0 +1,71 @@
1
+ import type { Owner } from "./types.js";
2
+ /**
3
+ * The client error hook — the prod-tier seam through which an app or an
4
+ * error monitor hears the one failure nothing else can see: an error
5
+ * boundary (`createErrorBoundary`, `<Errored>`) collected it and is rendering
6
+ * its fallback. The browser's global handlers hear what reaches
7
+ * `window.onerror`; a rendered fallback never does. An UNCAUGHT error is not
8
+ * this hook's: the halt (`REACTIVITY_HALTED`) hands its cause to the
9
+ * platform's `reportError`, the channel every monitor already listens on —
10
+ * one event, not two.
11
+ *
12
+ * Called once per error object: a boundary's `reset()` recomputing the same
13
+ * failing node re-collects the same error and does not report it again.
14
+ * Two tiers: ambient (`configureClientErrors`) and per root
15
+ * (`render`/`hydrate`'s `onError` in `@solidjs/web`), the nearest root's
16
+ * winning. Fires in every tier; no return — the client has no wire to map
17
+ * for. `ownerPath` carries the component labels where the runtime keeps
18
+ * owner names (the observe and dev artifacts).
19
+ *
20
+ * Pay-for-use: this module is retained by `createErrorBoundary` (which
21
+ * reports here) or the app's own `configureClientErrors` import. A root's
22
+ * hook is parked ON the root owner under a registered symbol
23
+ * (`ROOT_ERROR_HOOK`, defined in the scheduler), so `render` writes it
24
+ * without importing anything: an app that configures no hook and renders no
25
+ * boundary carries none of this.
26
+ */
27
+ export interface ClientErrorContext {
28
+ /**
29
+ * Where the error was THROWN: labels root-first up the owner chain of the
30
+ * computation that threw — component labels and named primitives — when
31
+ * the runtime keeps owner names (the observe and dev artifacts). The
32
+ * boundary's own chain when the thrower is unknown (a value thrown
33
+ * outside any computation).
34
+ */
35
+ ownerPath?: string[];
36
+ /**
37
+ * Where the error was MET: the same labels up the chain of the `<Errored>`
38
+ * that rendered its fallback for it — what the user saw, as against
39
+ * `ownerPath`, which is what broke.
40
+ */
41
+ boundaryPath?: string[];
42
+ }
43
+ export type ClientErrorHook = (error: unknown, context: ClientErrorContext) => void;
44
+ export interface ClientErrorsConfig {
45
+ /** The hook, or `undefined` to clear it. */
46
+ onError?: ClientErrorHook;
47
+ }
48
+ /**
49
+ * Registers the ambient client error hook — the one call a browser `init()`
50
+ * makes to see every failure a boundary renders a fallback for, in
51
+ * production. (Uncaught errors reach `reportError` / `window.onerror`.)
52
+ *
53
+ * ```ts
54
+ * configureClientErrors({
55
+ * onError: (error, { ownerPath }) =>
56
+ * Sentry.captureException(error, {
57
+ * mechanism: { type: "solid.error_boundary", handled: true }
58
+ * })
59
+ * });
60
+ * ```
61
+ */
62
+ export declare function configureClientErrors(config: ClientErrorsConfig): void;
63
+ /**
64
+ * Tells the client error hook about `error`, caught by the boundary whose
65
+ * owner is `owner`, thrown by `thrower` (the computation the engine's status
66
+ * wrapper named; unknown for a value that never crossed one) — once per
67
+ * error object. A throwing hook is reported on the console and otherwise
68
+ * ignored — a monitor must never take the app down.
69
+ * @internal
70
+ */
71
+ export declare function reportClientError(error: unknown, owner: Owner | null | undefined, thrower?: Owner | null): void;
@@ -39,9 +39,26 @@ export declare class StatusError extends Error {
39
39
  }
40
40
  /** Return the user's error from an internal status wrapper. */
41
41
  export declare function unwrapStatusError(error: unknown): unknown;
42
+ /**
43
+ * Rejection value of `until(fn, { timeout })` when the predicate does not turn
44
+ * truthy within the window. Inside an `action()`, the rejection is thrown back
45
+ * in at the `yield` point — catchable there, or the action fails and its
46
+ * optimistic state reverts.
47
+ */
48
+ export declare class TimeoutError extends Error {
49
+ constructor(message?: string);
50
+ }
42
51
  export declare class NoOwnerError extends Error {
43
52
  constructor();
44
53
  }
45
54
  export declare class ContextNotFoundError extends Error {
46
- constructor();
55
+ /**
56
+ * In dev, a read site passes the context (and whether a provider above set
57
+ * it to `undefined`) so the message can name it and say why it has no
58
+ * value (#4181). Read through `arguments` so production — where the message
59
+ * is empty — keeps the zero-parameter constructor byte for byte.
60
+ */
61
+ constructor(context?: {
62
+ id: symbol;
63
+ }, providedUndefined?: boolean);
47
64
  }
@@ -1,6 +1,45 @@
1
1
  import type { Computed, Link, Signal } from "./types.js";
2
+ /** The store's shared slot-node release handler (store/store.ts installs it
3
+ * once) — a live binding read directly by the sweep site: no wrapper frame,
4
+ * no null check (a CONFIG_SLOT_NODE node existing implies the store module
5
+ * loaded and registered it). */
6
+ export declare let slotUnobservedHook: (node: Signal<any>) => void;
7
+ export declare function setSlotUnobserved(fn: (node: Signal<any>) => void): void;
2
8
  export declare function unlinkSubs(link: Link): Link | null;
3
9
  export declare function trimStaleDeps(el: Computed<any>): void;
4
10
  export declare function clearDeps(el: Computed<unknown>): void;
11
+ /**
12
+ * Last-one-out releases held back while a pass tears down the frame of an
13
+ * earlier pass that never committed (#4142). The pass is about to rebuild
14
+ * the same children, which read the same lazy nodes again. Released on the
15
+ * spot, a lazy async memo whose only reader was the old frame's child memo
16
+ * was torn down, re-ran on the new child's read, went pending, and the cycle
17
+ * repeated forever. `recompute` collects them around that teardown and
18
+ * releases what is still unobserved when the pass ends.
19
+ */
20
+ export declare let deferredReleases: Computed<any>[] | null;
21
+ export declare const deferReleases: (list: Computed<any>[] | null) => Computed<any>[] | null;
5
22
  export declare function unobserved(el: Computed<unknown>): void;
6
- export declare function link(dep: Signal<any> | Computed<any>, sub: Computed<any>, pendingObserver?: boolean): void;
23
+ /**
24
+ * Deferred dormancy for never-observed auto-dispose computeds (#3078).
25
+ *
26
+ * An untracked top-level read of a subscriber-less observation-lifecycle memo
27
+ * used to call unobserved() inline at the end of read(). That kept the leak
28
+ * closed (the compute links the memo into its deps' sub lists — without a
29
+ * teardown point a never-observed memo is retained by its sources forever;
30
+ * upstream alien-signals has exactly this retention), but it made reads
31
+ * destructive: each read disposed the node, the next read revived it with a
32
+ * full recompute in whatever ambient transition/lane context happened to be
33
+ * current, so consecutive reads could return different answers with no write
34
+ * in between.
35
+ *
36
+ * Instead, reads queue the node here and the scheduler sweeps at the top of
37
+ * the next flush (before runHeap, so a same-tick dirtying is reclaimed
38
+ * instead of recomputed). Reads become idempotent within a tick (the node
39
+ * stays alive and serves its cache, uniform with observed memos) while
40
+ * reclamation still happens within one microtask — the enqueue site arms
41
+ * schedule(), so a flush is guaranteed even when no other work is queued.
42
+ */
43
+ export declare const dormantNodes: Set<Computed<unknown>>;
44
+ export declare function sweepDormant(): void;
45
+ export declare function link(dep: Signal<any> | Computed<any>, sub: Computed<any>): void;
@@ -1,10 +1,10 @@
1
1
  import type { Computed } from "./types.js";
2
- /** The queue a node belongs to, picked from its own zombie flag. */
3
- export declare function queueFor(n: Computed<any>): Heap;
4
2
  /**
5
- * Schedule one subscriber to re-run on the next flush: tracked effects bypass
6
- * the heap and go directly to their effect queue; everything else is inserted
7
- * into its own (zombie-flag-routed) heap with the `_min` cursor pulled down.
3
+ * Schedule one subscriber to re-run on the next flush: inserted into the
4
+ * dirty heap with the `_min` cursor pulled down. Tracked effects ride the
5
+ * heap too — the heap visit is their (empty) compute phase, which hands the
6
+ * callback to the user queue once the pass has committed (see
7
+ * GlobalQueue._update, #3291).
8
8
  */
9
9
  export declare function enqueueSub(node: Computed<any>): void;
10
10
  export interface Heap {
@@ -0,0 +1,17 @@
1
+ /** @internal The identity of a plain signal named while identities were on. */
2
+ export declare function signalName(node: object | undefined): string | undefined;
3
+ /** @internal Name plain signals from now on (`on`), or stop. */
4
+ export declare function setSignalIdentities(on: boolean): void;
5
+ /**
6
+ * @internal Called with every plain signal `createSignal` makes, and every
7
+ * plain store root `createStore` makes, while set (the namer above). Never
8
+ * set unless `setSignalIdentities` is imported, so a bundle without it keeps
9
+ * only a null check.
10
+ */
11
+ export declare let signalHook: ((node: object) => void) | null;
12
+ /**
13
+ * @internal Dev only: `watch` is called with every node read while set (the
14
+ * dev hook `onRead`) — the frames client's identity-drift check watches the
15
+ * named signals a deferred occurrence reads as it mounts. A no-op in prod.
16
+ */
17
+ export declare function setReadWatch(watch: ((node: object) => void) | null): void;
@@ -1,13 +1,17 @@
1
- export { ContextNotFoundError, NoOwnerError, NotReadyError } from "./error.js";
2
- export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setMemo, suppressComputedRecompute, optimisticSignal, optimisticComputed, refresh, staleValues, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots } from "./core.js";
1
+ export { ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError } from "./error.js";
2
+ export { isPending, latest } from "./verdict.js";
3
+ export { action } from "./action.js";
4
+ export { isEqual, untrack, runWithOwner, computed, signal, read, setSignal, setWriteHook, setMemo, markRefresh, staleValues, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots } from "./core.js";
3
5
  export { enableExternalSource, _resetExternalSourceConfig, type ExternalSourceFactory, type ExternalSource, type ExternalSourceConfig } from "./external.js";
4
6
  export { createOwner, createRoot, dispose, getNextChildId, getObserver, getOwner, isDisposed, cleanup, peekNextChildId } from "./owner.js";
7
+ export { setSignalIdentities, signalName, signalHook, setReadWatch } from "./identities.js";
5
8
  export { createContext, getContext, setContext, type Context, type ContextRecord } from "./context.js";
6
9
  export { handleAsync } from "./async.js";
7
- export { isPending, latest } from "./verdict.js";
8
- export type { Computed, Disposable, FirewallSignal, Link, Owner, Root, Signal, NodeOptions } from "./types.js";
10
+ export type { Computed, Disposable, Link, Owner, Root, Signal, NodeOptions } from "./types.js";
9
11
  export { effect, trackedEffect, type Effect, type TrackedEffect } from "./effect.js";
10
- export { action } from "./action.js";
11
- export { flush, Queue, GlobalQueue, enforceLoadingBoundary, resetErrorHalt, type IQueue, type QueueCallback } from "./scheduler.js";
12
- export { DEV, type Dev, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type Diagnostics, type DiagnosticSeverity } from "./dev.js";
12
+ export { flush, GlobalQueue, enforceLoadingBoundary, resetErrorHalt, type IQueue, type QueueCallback } from "./scheduler.js";
13
+ export type { InteractionRef, NavigationRef } from "./attribution-hooks.js";
14
+ export { ROOT_ERROR_HOOK, clock } from "./scheduler.js";
15
+ export { configureClientErrors, type ClientErrorContext, type ClientErrorHook, type ClientErrorsConfig } from "./error-hooks.js";
16
+ export { DEV, OBSERVE, setConsoleFooter, type AttributionSlot, type Dev, type Observe, type ServerObserve, type Records, type RecordTypes, type HostRecordTypes, type RecordType, type RecordEvent, type RecordLive, type RecordListener, type RecordSubscribeOptions, type DevHooks, type DiagnosticCapture, type DiagnosticCode, type DiagnosticEvent, type DiagnosticKind, type DiagnosticListener, type Diagnostics, type DiagnosticSeverity, type DiagnosticSubject } from "./dev.js";
13
17
  export * from "./constants.js";
@@ -1,8 +1,7 @@
1
- import type { OptimisticLane } from "./lanes.js";
2
1
  import type { Computed, Signal } from "./types.js";
3
2
  /**
4
3
  * Test-mode invariant checks for the async/transition/lane machinery.
5
- * Catalog and rationale: packages/solid-signals/INTERNALS-ASYNC-STATE.md.
4
+ * Catalog and rationale: packages/signals/docs/INTERNALS-ASYNC-STATE.md.
6
5
  *
7
6
  * These are implementation self-consistency checks, not semantic rules: a
8
7
  * violation means the reactive system contradicted itself.
@@ -17,16 +16,7 @@ import type { Computed, Signal } from "./types.js";
17
16
  * defines `__TEST__: false`.
18
17
  */
19
18
  type AnyNode = Signal<any> | Computed<any>;
20
- /** Wired by core.ts at module init to avoid import cycles. */
21
- export declare const InvariantHooks: {
22
- pendingProbeActive: (() => boolean) | null;
23
- /** Fresh oracle for what an isPending companion SHOULD read right now. */
24
- computePendingState: ((node: AnyNode) => boolean) | null;
25
- };
26
19
  export declare function devTrackHeldPending(node: AnyNode): void;
27
- export declare function devTrackCompanionOwner(node: AnyNode): void;
28
- export declare function devTrackOptimistic(node: AnyNode): void;
29
- export declare function devTrackAffects(node: AnyNode): void;
30
20
  /**
31
21
  * Open/close the sanctioned registration window. Call sites are `__DEV__`
32
22
  * guarded (no prod cost); the code inside the window must not throw.
@@ -34,21 +24,6 @@ export declare function devTrackAffects(node: AnyNode): void;
34
24
  export declare function beginAsyncReporterWrites(): void;
35
25
  export declare function endAsyncReporterWrites(): void;
36
26
  export declare function createAsyncReporters(): Map<Computed<any>, Set<Computed<any>>>;
37
- /**
38
- * INV-2: a node with an *active* override must be registered for reversion in
39
- * the queue's or a transition's `_optimisticNodes`. An unregistered active
40
- * override would survive transition completion forever. Runs at the end of
41
- * every flush (not just quiescence — the invariant holds mid-transition).
42
- * (There is no revert-target requirement: authoritative values commit
43
- * silently into `_value` under the override mask — A17 — so reverting is
44
- * just dropping the override.)
45
- */
46
- export declare function devCheckActiveOverrides(isRegisteredForRevert: (node: AnyNode) => boolean): void;
47
- /** INV-1: an isPending() probe must never leak past its own call. */
48
- export declare function devCheckFlushStart(): void;
49
- /** INV-5: a merged lane's work moved to its root on merge and must stay empty. */
50
- export declare function devCheckMergedLaneEmpty(lane: OptimisticLane): void;
51
- export declare function devCensusCompanions(isQueuedForCommit?: (node: AnyNode) => boolean): void;
52
27
  /**
53
28
  * Quiescence checks. Run only when the system is fully drained: nothing
54
29
  * scheduled, no active/stashed transitions, no live lanes. At that point no
@@ -1,44 +1,75 @@
1
- import { type QueueCallback, type Transition } from "./scheduler.js";
1
+ import { laneValueOf } from "./truth.js";
2
+ import { type Transaction } from "./scheduler.js";
2
3
  import type { Computed, Signal } from "./types.js";
3
- /**
4
- * OptimisticLane represents the context for a single optimistic write.
5
- * Each optimistic signal creates its own lane. Lanes merge when their
6
- * dependency graphs overlap.
7
- */
8
- export interface OptimisticLane {
9
- _source: Signal<any>;
10
- _pendingAsync: Set<Computed<any>>;
11
- _effectQueues: [QueueCallback[], QueueCallback[]];
12
- _mergedInto: OptimisticLane | null;
13
- _transition: Transition | null;
14
- _parentLane: OptimisticLane | null;
15
- }
16
- export declare const signalLanes: WeakMap<Signal<any>, OptimisticLane>;
17
- export declare const activeLanes: Set<OptimisticLane>;
18
- /**
19
- * Get an existing lane for a signal or create a new one.
20
- * Reuses lane for multiple writes to the same signal.
21
- */
22
- export declare function getOrCreateLane(signal: Signal<any>): OptimisticLane;
23
- /**
24
- * Union-find: find the root lane.
25
- */
26
- export declare function findLane(lane: OptimisticLane): OptimisticLane;
27
- /**
28
- * Merge two lanes when their dependency graphs overlap.
29
- */
30
- export declare function mergeLanes(lane1: OptimisticLane, lane2: OptimisticLane): OptimisticLane;
31
- /**
32
- * Resolve a node's lane: follow union-find chain, verify active, clear if stale.
33
- */
34
- export declare function resolveLane(el: Signal<any> | Computed<any>): OptimisticLane | undefined;
35
- export declare function resolveTransition(el: Signal<any> | Computed<any>): Transition | null | undefined;
36
- /**
37
- * Check if a node has an active optimistic override.
38
- */
39
- export declare function hasActiveOverride(el: Signal<any> | Computed<any>): boolean;
40
- /**
41
- * Assign or merge a lane onto a node. At convergence points (node already has
42
- * a different active lane), merge unless the node has an active override.
43
- */
44
- export declare function assignOrMergeLane(el: Signal<any> | Computed<any>, sourceLane: OptimisticLane): void;
4
+ export { laneValueOf };
5
+ /** What the screen shows for a lane's node: the lane's value once the lane
6
+ * has revealed, the committed truth before — NOT_PENDING when there is none
7
+ * (uninitialized, as `laneValueOf`): its read throws NotReady. */
8
+ export declare function display(el: Signal<any> | Computed<any>): unknown;
9
+ /** What the writer sees of a node: an unflushed guess to it, else the
10
+ * lane's value or the committed one — what an optimistic updater composes
11
+ * on (a store setter's draft too, store/optimistic.ts). */
12
+ export declare function guessedValueOf<T>(n: Signal<T> | Computed<T>): T;
13
+ /** The unflushed guess to `n`, else NOT_PENDING. */
14
+ export declare function pendingGuessOf(n: Signal<any> | Computed<any>): unknown;
15
+ /** Lane `l` takes `n`'s guess (another action's), kept to come back if `l`
16
+ * reverts. Its readers saw the guess: they re-derive at the lane's reveal
17
+ * (and, a flight's, hold the lane while they would show it). `d`: a guess
18
+ * `l` takes without writing it (a store target's other slots) — the node
19
+ * shows its truth in `l`'s world until the guess comes back. */
20
+ export declare function take(n: Signal<any>, l: Transaction, d?: boolean): void;
21
+ export declare function optimisticWrite<T>(n: Signal<T> | Computed<T>, v: T | ((prev: T) => T)): T;
22
+ /** The running pass read lane `l`'s work as a derivation: it is `l`'s — or,
23
+ * already another lane's, the frame it computes derives from both guesses
24
+ * and cannot show one without the other (#3335, A15 for lanes): the two
25
+ * lanes are linked — one reveal unit, each blocked while any is — while
26
+ * their lifetimes stay their own (#2912: a guess reverts with its own
27
+ * action, not with the one it shares a reader with). A nested lane reading
28
+ * through an ancestor's guess stays its own (the screen plus its own
29
+ * guesses). */
30
+ export declare function enterLane(l: Transaction, c: Computed<any>): void;
31
+ /** Verdicts (maintainer, 2026-10-01): `isPending` and `latest` are
32
+ * optimistic state the system supplies — a verdict is a guess ("pending,
33
+ * until this lands"; "the proposal is the value") decided at the seam like
34
+ * a user's, and its readers break out of the hold the same way: work of a
35
+ * lane under the holder, shown now, re-derived at the landing, ending with
36
+ * it. Judged at the seam like any lane: blocked while a verdict reader's
37
+ * own derivation is in flight (lane rule 3), shown otherwise. */
38
+ export declare function verdictLane(t: Transaction): Transaction;
39
+ /** A lane pass's node (core.ts `recompute`, before its staging; a pending
40
+ * propagation under a lane pass, async.ts): listed, carrying the lane's
41
+ * value from now (a derivation of a guess — its readers become lane work).
42
+ * Entering the lane supersedes a frame staging the node carried: this
43
+ * pass's answer replaces it, and the frame's hold on it is over. An
44
+ * effect's value slot is private (no lane value). A pass in a lane's seat
45
+ * that read none of the lane's world has left it (false): its result is the
46
+ * frame's — a derivation whose branch no longer reaches the guess — and no
47
+ * hold the lane took over from a transaction stays on it (#3698: lane work
48
+ * never makes its node transaction work; a born-held effect's hold went to
49
+ * the lane). A pass interrupted before it got there (pending, errored) did
50
+ * not leave (A30: it never got there). A first pass under a lane is the
51
+ * lane's (ruling A); a guess is written, not derived — it never leaves this
52
+ * way. `errored`: the pass has no answer — or, a lane pass's pending
53
+ * propagation (async.ts `propagateStatus`), the node gone pending. */
54
+ export declare function laneStage(el: Computed<any>, l: Transaction, create: boolean, errored: boolean | Computed<any>): boolean;
55
+ export declare function supersede(n: Signal<any> | Computed<any>, value: unknown, changed: boolean): void;
56
+ /** Lanes. A lane's node is read by its reader's kind: an authoritative
57
+ * reader (`until`) sees the truth — staged beneath a guess, else committed
58
+ * — and is no lane's; an untracked read sees the lane's latest value (A17:
59
+ * "direct read shows optimistic"; A28); a children-forbidden reader sees
60
+ * the frame (A32). A render effect in the frame's seat reading a lane the
61
+ * seam found blocked, or a member whose own flight is up (held or not — the
62
+ * lane-membership ruling, 2026-10-05), sees the screen, re-derived at the
63
+ * reveal (#3460's stale reader) — or, the node a
64
+ * flight that has never shown (nothing to show), waits on it: its own frame
65
+ * holds (A15, #3334), not the lane's parent. Any other tracked reader is
66
+ * the lane's work from this read — a derivation; a leaf reading a lane that
67
+ * has shown, or one the seam has not judged yet (its run waits on the
68
+ * verdict: released if the lane shows, held if it blocks) — and sees the
69
+ * lane's latest. NOT_PENDING falls through: lane work's read of a pending
70
+ * member throws like any. A verdict reader entering a lane the seam has
71
+ * not judged reads ahead of it like a staging read: if the seam holds the
72
+ * lane, the pass re-derives on the screen (`entered`, #4284) — `latest()`
73
+ * beside the lane's nodes tears ahead of the hold however the reads are
74
+ * grouped into effects. */
75
+ export declare function laneRead(c: Computed<any> | null, el: Signal<any> | Computed<any>): unknown;
@@ -1,7 +1,12 @@
1
1
  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
+ /** Runs a cleanup or `unobserved` hook; a throw is collected, not raised. @internal */
5
+ export declare function runCleanup(fn: () => void): void;
6
+ /** Rethrows the error `runCleanup` collected, once; `drop` discards it. @internal */
7
+ export declare function rethrowCleanupError(drop?: boolean): void;
4
8
  export declare function disposeChildren(node: Owner, self?: boolean, zombie?: boolean): void;
9
+ export declare function linkChild(parent: Owner, node: Owner): void;
5
10
  /**
6
11
  * Allocates and returns the next stable child id for `owner`. Used by
7
12
  * hydration plumbing and `createUniqueId`. Not part of the user-facing API.
@@ -62,13 +67,15 @@ export declare function getOwner(): Owner | null;
62
67
  /**
63
68
  * Low-level: registers `fn` as a disposal callback on the current owner.
64
69
  * Most code should use `onCleanup()` from `solid-js`, which adds dev-mode
65
- * checks. `cleanup()` is the unchecked primitive used by internals.
70
+ * checks. `cleanup()` is the unchecked primitive used by internals; `owner`
71
+ * (internal) targets a specific owner's disposal list instead of the ambient
72
+ * one.
66
73
  */
67
- export declare function cleanup(fn: Disposable): Disposable;
74
+ export declare function cleanup(fn: Disposable, owner?: Owner | null): Disposable;
68
75
  /**
69
- * Returns `true` if the owner has been disposed (or marked zombie pending
70
- * disposal). Pair with a captured owner to bail out of late callbacks whose
71
- * surrounding component already unmounted.
76
+ * Returns `true` if the owner has been disposed. Pair with a captured owner
77
+ * to bail out of late callbacks whose surrounding component already
78
+ * unmounted.
72
79
  *
73
80
  * @example
74
81
  * ```ts
@@ -95,9 +102,15 @@ export declare function createOwner(options?: {
95
102
  transparent?: boolean;
96
103
  }): Root;
97
104
  /**
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.
105
+ * Creates a reactive root — an owner scope with its own `dispose()`. A root
106
+ * created inside an existing owner is owned by it and is disposed when the
107
+ * parent is disposed; call `dispose()` to tear it down earlier. To create a
108
+ * root that outlives its creator, detach explicitly:
109
+ * `runWithOwner(null, () => createRoot(...))`. Pass `id` to seed hydration
110
+ * ids for the tree it owns.
111
+ *
112
+ * `dispose()` tears down every signal, memo, effect, and `onCleanup`
113
+ * registered inside the root.
101
114
  *
102
115
  * Use this to host long-lived reactive scopes outside of a component (custom
103
116
  * controllers, app bootstrapping, tests). Inside a component, prefer
@@ -105,6 +118,7 @@ export declare function createOwner(options?: {
105
118
  *
106
119
  * @example
107
120
  * ```ts
121
+ * // At module level there is no owner, so this root lives until disposed.
108
122
  * const dispose = createRoot(dispose => {
109
123
  * const [n, setN] = createSignal(0);
110
124
  * createEffect(() => n(), value => console.log(value));
@@ -114,9 +128,13 @@ export declare function createOwner(options?: {
114
128
  *
115
129
  * // Later, to tear everything down:
116
130
  * dispose();
131
+ *
132
+ * // Inside an owner (component, effect, another root), detach explicitly
133
+ * // if the root must outlive its creator:
134
+ * const detached = runWithOwner(null, () => createRoot(d => d));
117
135
  * ```
118
136
  *
119
- * @description https://docs.solidjs.com/reference/reactive-utilities/create-root
137
+ * @description https://v2.solidjs.com/reference/solid-js/advanced/owner-introspection/create-root
120
138
  */
121
139
  export declare function createRoot<T>(init: ((dispose: () => void) => T) | (() => T), options?: {
122
140
  id?: string;