@solidjs/signals 2.0.0-rc.19 → 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 (74) hide show
  1. package/dist/dev-shared.js +553 -264
  2. package/dist/dev.attribution.js +18 -18
  3. package/dist/dev.js +1030 -439
  4. package/dist/observe/affects.js +12 -2
  5. package/dist/observe/boundaries.js +168 -115
  6. package/dist/observe/core/async.js +57 -37
  7. package/dist/observe/core/attribution.js +6 -6
  8. package/dist/observe/core/constants.js +9 -1
  9. package/dist/observe/core/copies.js +10 -0
  10. package/dist/observe/core/core.js +261 -181
  11. package/dist/observe/core/effect.js +32 -27
  12. package/dist/observe/core/graph.js +7 -7
  13. package/dist/observe/core/heap.js +29 -29
  14. package/dist/observe/core/lanes.js +301 -101
  15. package/dist/observe/core/owner.js +13 -13
  16. package/dist/observe/core/scheduler.js +124 -69
  17. package/dist/observe/core/truth.js +9 -7
  18. package/dist/observe/core/verdict.js +160 -98
  19. package/dist/observe/deferred.js +1 -1
  20. package/dist/observe/index.js +2 -0
  21. package/dist/observe/map.js +120 -116
  22. package/dist/observe/reveal.js +48 -48
  23. package/dist/observe/signals.js +5 -5
  24. package/dist/observe/store/affects.js +2 -2
  25. package/dist/observe/store/optimistic.js +272 -176
  26. package/dist/observe/store/projection.js +21 -10
  27. package/dist/observe/store/reconcile.js +8 -2
  28. package/dist/observe/store/store.js +91 -55
  29. package/dist/observe/store/types.js +11 -1
  30. package/dist/observe/store/utils.js +1 -1
  31. package/dist/prod/affects.js +12 -2
  32. package/dist/prod/boundaries.js +164 -109
  33. package/dist/prod/core/async.js +201 -181
  34. package/dist/prod/core/constants.js +9 -1
  35. package/dist/prod/core/copies.js +10 -0
  36. package/dist/prod/core/core.js +244 -164
  37. package/dist/prod/core/dev.js +108 -3
  38. package/dist/prod/core/effect.js +28 -23
  39. package/dist/prod/core/graph.js +9 -9
  40. package/dist/prod/core/heap.js +16 -16
  41. package/dist/prod/core/identities.js +1 -1
  42. package/dist/prod/core/lanes.js +307 -95
  43. package/dist/prod/core/owner.js +22 -22
  44. package/dist/prod/core/scheduler.js +266 -211
  45. package/dist/prod/core/truth.js +9 -7
  46. package/dist/prod/core/verdict.js +161 -99
  47. package/dist/prod/deferred.js +1 -1
  48. package/dist/prod/index.js +2 -0
  49. package/dist/prod/map.js +78 -74
  50. package/dist/prod/reveal.js +34 -34
  51. package/dist/prod/signals.js +3 -3
  52. package/dist/prod/store/affects.js +15 -15
  53. package/dist/prod/store/optimistic.js +185 -89
  54. package/dist/prod/store/projection.js +49 -38
  55. package/dist/prod/store/reconcile.js +8 -2
  56. package/dist/prod/store/store.js +99 -63
  57. package/dist/prod/store/types.js +11 -1
  58. package/dist/types/affects.d.ts +3 -2
  59. package/dist/types/boundaries.d.ts +14 -2
  60. package/dist/types/core/async.d.ts +2 -1
  61. package/dist/types/core/constants.d.ts +8 -0
  62. package/dist/types/core/copies.d.ts +54 -0
  63. package/dist/types/core/core.d.ts +15 -0
  64. package/dist/types/core/dev.d.ts +1 -1
  65. package/dist/types/core/lanes.d.ts +8 -1
  66. package/dist/types/core/scheduler.d.ts +36 -4
  67. package/dist/types/core/truth.d.ts +3 -1
  68. package/dist/types/core/types.d.ts +6 -0
  69. package/dist/types/index.d.ts +2 -0
  70. package/dist/types/store/hooks.d.ts +15 -1
  71. package/dist/types/store/store.d.ts +2 -1
  72. package/dist/types/store/target.d.ts +5 -0
  73. package/dist/types/store/types.d.ts +7 -0
  74. package/package.json +1 -1
@@ -70,4 +70,14 @@ function setWriteOverride(e) {
70
70
  writeOverride = e;
71
71
  }
72
72
 
73
- export { $PROXY, $RECORD, $TARGET, $TRACK, isRawValue, isWrappable, markRaw, markRawIngest, markRawOne, ownEnumerableKeys, rawValuesUsed, setWriteOverride, writeOverride };
73
+ /** The list driver's view of a shallow store (map.ts): the backing a read of
74
+ * every slot serves this reader, or `undefined` when the list is no shallow
75
+ * store or a slot read could differ from it. Installed by store.ts's top
76
+ * level, so a `<For>` in an app without stores carries none of it; it lives
77
+ * beside `$TRACK` so map.ts reaches no other store module. */ let shallowView = null;
78
+
79
+ function installShallowView(e) {
80
+ shallowView = e;
81
+ }
82
+
83
+ export { $PROXY, $RECORD, $TARGET, $TRACK, installShallowView, isRawValue, isWrappable, markRaw, markRawIngest, markRawOne, ownEnumerableKeys, rawValuesUsed, setWriteOverride, shallowView, writeOverride };
@@ -3,8 +3,9 @@ import { type Store } from "./store/types.js";
3
3
  /**
4
4
  * Declares that in-flight work will change the targeted data: the source —
5
5
  * and everything derived from it — reads as pending (`isPending` → `true`)
6
- * from the declaration until the surrounding transaction settles. A mark is
7
- * a promise of change, not an absence of value: the marked values stay
6
+ * from the declaration until the surrounding transaction settles — or, if
7
+ * the source's own fetch is still in flight then (a declared reload's
8
+ * `refresh()`), until that fetch lands. A mark is a promise of change, not an absence of value: the marked values stay
8
9
  * readable, no reader suspends on one, and it holds nothing — the
9
10
  * transaction's completion never waits on a mark. Pendingness is additive:
10
11
  * a mark can turn pending on for data the graph cannot see changing yet
@@ -10,8 +10,9 @@ interface Boundary {
10
10
  /** Null during the output's first pass (its post-check decides then). */
11
11
  _output: Computed<any> | null;
12
12
  /** Frame readers under it carrying its status: caught, or (loading,
13
- * showing content) forwarded — the `on` re-arm collects those. */
14
- _readers: Set<Computed<any>>;
13
+ * showing content) forwarded — the `on` re-arm collects those. Each maps
14
+ * to what it waits on: itself, or (error) the source that threw. */
15
+ _readers: Map<Computed<any>, Computed<any>>;
15
16
  /** Loading: has shown content. Fresh again after an `on` re-arm found
16
17
  * something pending. */
17
18
  _initialized: boolean;
@@ -62,6 +63,17 @@ export declare let revealHooks: RevealHooks | null;
62
63
  export declare function setRevealHooks(h: RevealHooks): void;
63
64
  export type { Boundary };
64
65
  export declare function redraw(b: Boundary): void;
66
+ /** Drop the readers that settled or died. Settled: a loading reader no
67
+ * longer pending; an error's source neither errored nor in flight. A reader
68
+ * that landed but is held (its value staged in a transaction) is not: the
69
+ * content reveals at the commit, with its run. The tree is: the output reads
70
+ * it and enters the transaction itself (its committed value shows until the
71
+ * landing). The statuses that keep a reader: pending — and its error, for an
72
+ * error boundary (`_type` is the status it catches) — on the reader or its
73
+ * source. A reader pending again after the source that threw answered (it
74
+ * re-asks through a memo that carried the error) has no new answer yet: the
75
+ * error stays the display (D-39: a pending is not a value; async-gen 91501
76
+ * #1831). */
65
77
  export declare function prune(b: Boundary, pass: boolean): number;
66
78
  /** Reveal order: a slot is ready when its content can show — it has shown
67
79
  * content, or nothing under it is unready (the tree neither pending nor
@@ -1,6 +1,7 @@
1
1
  import { NotReadyError } from "./error.js";
2
2
  import type { Computed, Link } from "./types.js";
3
3
  export declare function addPendingSource(el: Computed<any>, source: Computed<any>): boolean;
4
+ export declare function removePendingSource(el: Computed<any>, source: Computed<any>): boolean;
4
5
  /**
5
6
  * A loading-window node hit an unready source (sync throw in recompute, or a
6
7
  * NotReadyError-rejected flight): register for the source's settle — the
@@ -39,7 +40,7 @@ export declare function releaseFlightTeardown(el: Computed<any>): void;
39
40
  export declare function onSupersede(fn: () => void): void;
40
41
  export declare function handleAsync<T>(el: Computed<T>, result: T | PromiseLike<T> | AsyncIterable<T>, setter?: (value: T) => void, onError?: (error: unknown, pending: boolean) => void): T;
41
42
  export declare function clearStatus(el: Computed<any>, clearUninitialized?: boolean): void;
42
- export declare function notifyStatus(el: Computed<any>, status: number, error: any): void;
43
+ export declare function notifyStatus(el: Computed<any>, status: number, error?: any): void;
43
44
  /** The dependents' half of `notifyStatus`: `el`'s status reaches each
44
45
  * subscriber as a propagated mark (or a re-derive). On its own for a store
45
46
  * family's leaves, which are not the derive's dependents — the family
@@ -68,6 +68,11 @@ export declare const REACTIVE_SCREEN_READ: number;
68
68
  * later read of the same pass routed it into a verdict lane — that was not
69
69
  * the probe's answer (lanes.ts). Per pass. */
70
70
  export declare const REACTIVE_PROBE_UNANSWERED: number;
71
+ /** The pass opened a verdict window of its own (`isPending`/`latest`) — not
72
+ * only read a verdict memo (F-6, core.ts `read`). An async memo whose pass
73
+ * did not is D-25's hold work while its flight is up (verdict.ts
74
+ * `holdWork`). Per pass (1 << 20 is lanes.ts's LEFT_SHOWN). */
75
+ export declare const REACTIVE_WINDOW: number;
71
76
  export declare const CONFIG_OWNED_WRITE: number;
72
77
  export declare const CONFIG_NO_SNAPSHOT: number;
73
78
  export declare const CONFIG_TRANSPARENT: number;
@@ -201,6 +206,9 @@ export declare const CONFIG_KEY_BAG: number;
201
206
  * joins nothing, so two mounts under one boundary made in separate flushes
202
207
  * keep their holds apart (D-4, S-5 rows 1′–3′, #4283). */
203
208
  export declare const CONFIG_FRAME: number;
209
+ /** The node's last answering pass registered a flight: an async memo. Kept
210
+ * by the verdict engine alone (verdict.ts `holdWork`), which reads it. */
211
+ export declare const CONFIG_ASYNC: number;
204
212
  export declare const STATUS_NONE = 0;
205
213
  export declare const STATUS_PENDING: number;
206
214
  export declare const STATUS_ERROR: number;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Dev: duplicate-copy detection.
3
+ *
4
+ * Two copies of Solid on a page are only a bug when they meet: one copy's
5
+ * code runs inside the other's computation or component and finds no owner
6
+ * or listener of its own (each copy keeps them in its own module state), so
7
+ * it neither reacts nor sees the other's providers. That is the shape of
8
+ * every duplicate report on record: a library's precompiled JSX on copy B
9
+ * reading the app's props or signals from copy A, a runtime that bundled its
10
+ * own solid-js. Copies that never meet (a devtools panel rendering into its
11
+ * own root, an isolated widget) are fine at any version, so nothing is
12
+ * checked when a copy loads.
13
+ *
14
+ * Every copy from 2.0 on shares one global record, `Solid$$copies`. It is a
15
+ * contract between all future versions of Solid, so its shape never changes:
16
+ *
17
+ * - `copies`: each copy adds 1 when it loads.
18
+ * - `running`: while `copies > 1`, each copy names itself here (an object
19
+ * with a `rooted` boolean, compared by identity) around its computations
20
+ * and components, and restores the previous value after.
21
+ *
22
+ * A copy that sees `copies < 2` skips the slot entirely, so a page with one
23
+ * copy pays one property read per check. v1 keeps its own load-time `Solid$$`
24
+ * check, which this never sets, so neither side warns about the other.
25
+ */
26
+ interface SolidCopy {
27
+ /** This copy has created a root of its own (it renders by itself). */
28
+ rooted: boolean;
29
+ }
30
+ interface SolidCopies {
31
+ copies: number;
32
+ running: SolidCopy | undefined;
33
+ }
34
+ declare global {
35
+ var Solid$$copies: SolidCopies | undefined;
36
+ }
37
+ export declare function markCopyRooted(): void;
38
+ /**
39
+ * Marks this copy as the one running; returns the slot's previous value. A
40
+ * nested run of the same copy (most runs inside a flush) only reads the slot.
41
+ */
42
+ export declare function enterCopy(): SolidCopy | undefined;
43
+ export declare function exitCopy(prev: SolidCopy | undefined): void;
44
+ /** @internal Runs `fn` with this copy marked as the one running. */
45
+ export declare function runAsSolidCopy<T>(fn: () => T): T;
46
+ /** @internal An ownerless component or context read: warns if another copy is running. */
47
+ export declare function checkForeignOwnerless(): void;
48
+ /**
49
+ * An untracked read: warns if another copy's computation is running, unless
50
+ * both copies render through roots of their own (an app calling into an
51
+ * isolated copy's API, which reads its own state untracked by design).
52
+ */
53
+ export declare function checkForeignRead(): void;
54
+ export {};
@@ -67,6 +67,14 @@ export declare function joinPassAt(c: Computed<any>, t: Transaction): void;
67
67
  * has no screen to read, so it reads `t`'s values, whichever flush runs it,
68
68
  * and keeps staging (#4010). */
69
69
  export declare function bornInto(c: Computed<any>, t: Transaction): unknown;
70
+ /** The computed whose pass a creation under `owner` belongs to (a root's is
71
+ * its nearest computed ancestor's), or null outside every pass. */
72
+ export declare function creatorPass(owner: Owner | null): Computed<any> | null;
73
+ /** What `born` and the passes still running around `p` read — its
74
+ * creator's, theirs — of the future or a staging (REACTIVE_JOINED |
75
+ * REACTIVE_STAGED_READ): a pass created by one that did has no screen; its
76
+ * branch exists only in that world (#4341). */
77
+ export declare function creatorReads(p: Computed<any> | null, born: number): number;
70
78
  /**
71
79
  * Build an Effect node with all effect-specific fields baked into a single object literal,
72
80
  * so V8 sees the full hidden class shape at construction time. Effects always run in lazy
@@ -258,6 +266,13 @@ export declare function resyncUnflushedCompanions(): void;
258
266
  * reached its height (or the reader is a fresh-pull waiter), and sit the
259
267
  * reader above it. */
260
268
  export declare function pullComputed(owner: Computed<any>, c: Computed<any>): void;
269
+ /**
270
+ * Dev only: a read's diagnostics — the devtools read hook, the foreign-read
271
+ * check and the post-await untracked-read check. Every caller guards with
272
+ * `__DEV__`: `read` here, and a store leaf's read that is served without
273
+ * `read` (`nodeValue`'s first landing), so no read goes unseen in dev.
274
+ */
275
+ export declare function devRead(el: Signal<any> | Computed<any>): void;
261
276
  export declare function read<T>(el: Signal<T> | Computed<T>): T;
262
277
  /**
263
278
  * Rule 1, the one slow implementation (DESIGN-CONSOLIDATION move 3b, step
@@ -16,7 +16,7 @@ export interface DevHooks {
16
16
  * `warn`/`error` as failures unless they opt in to `info`.
17
17
  */
18
18
  export type DiagnosticSeverity = "info" | "warn" | "error";
19
- export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "ASYNC_STORE_SETTER" | "STORE_WRITE_OUTSIDE_SETTER" | "ACTION_CALLED_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "ON_FLUSH_IN_OWNED_SCOPE" | "SETTLE_WALK_UNINITIALIZED_SOURCE" | "FLUSH_IN_EFFECT_CALLBACK" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "PRIMITIVE_IN_EFFECT_CALLBACK" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "LOADING_ON_OUTSIDE_HOLD" | "INVALID_REFRESH_TARGET" | "INVALID_AFFECTS_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "UNTRACKED_READ_AFTER_AWAIT" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION" | "HUGE_FAN_OUT" | "HUGE_FAN_IN" | "GRAPH_GROWTH" | "HOT_SCOPE_RERUNS" | "HOT_SCOPE_TIME" | "WIDE_SCOPE_DEPS" | "UNSTABLE_MEMO_OUTPUT" | "WASTED_RECOMPUTE" | "ASYNC_WATERFALL" | "HOT_SCOPE_FANOUT" | "SILENT_HOLD" | "LONG_HOLD" | "UNTRACKED_ASYNC_HANDLER" | "ABANDONED_FLIGHTS" | "FALLBACK_FLASH" | "STACKED_HOLDS" | "OPTIMISTIC_REVERTED" | "EFFECT_WRITES_OWN_SOURCE" | "EFFECT_RELAY_TEAR" | "IMMUTABLE_UPDATE_IN_STORE" | "UNSTABLE_LIST_IDENTITY" | "SSR_RENDER_ERROR_CONTAINED" | "SSR_SUBTREE_ABANDONED" | "SSR_STREAM_ABANDONED" | "SSR_CLIENT_CONTENT_MASKED" | "LATE_HEADER_WRITE" | "SERVER_ERROR_SANITIZED" | "SSR_BOUNDARY_WATERFALL" | "SSR_UNDECLARED_LIVE_SOURCE" | "SSR_LIVE_HOLE_LATCHED" | "SERVER_WRITE" | "REVEAL_IN_RENDER_TO_STRING" | "LAZY_ASSET_UNMAPPED" | "PRELOAD_DESCRIPTOR_INVALID" | "HEAD_TAG_INVALID" | "UNRECOGNIZED_INSERT_VALUE" | "UNSCOPED_HOLE_ALLOCATED_IDS" | "LOWERCASE_EVENT_ATTRIBUTE" | "UNCOMMITTED_INPUT_OVERWRITTEN" | "FRAME_MARKER_CORRUPTED" | "DYNAMIC_ASYNC_COMPONENT" | "ASYNC_MEMO_ELEMENT";
19
+ export type DiagnosticCode = "STRICT_READ_UNTRACKED" | "PENDING_ASYNC_UNTRACKED_READ" | "PENDING_ASYNC_FORBIDDEN_SCOPE" | "REACTIVE_WRITE_IN_OWNED_SCOPE" | "ASYNC_STORE_SETTER" | "STORE_WRITE_OUTSIDE_SETTER" | "ACTION_CALLED_IN_OWNED_SCOPE" | "RUN_WITH_DISPOSED_OWNER" | "NO_OWNER_CLEANUP" | "CLEANUP_IN_FORBIDDEN_SCOPE" | "SETTLED_CLEANUP_UNOWNED" | "ON_FLUSH_IN_OWNED_SCOPE" | "SETTLE_WALK_UNINITIALIZED_SOURCE" | "FLUSH_IN_EFFECT_CALLBACK" | "PRIMITIVE_IN_FORBIDDEN_SCOPE" | "PRIMITIVE_IN_EFFECT_CALLBACK" | "NO_OWNER_EFFECT" | "NO_OWNER_BOUNDARY" | "ASYNC_OUTSIDE_LOADING_BOUNDARY" | "LOADING_ON_OUTSIDE_HOLD" | "LOADING_ON_ACCESSOR" | "INVALID_REFRESH_TARGET" | "INVALID_AFFECTS_TARGET" | "MISSING_EFFECT_FN" | "SYNC_NODE_RECEIVED_ASYNC" | "UNTRACKED_READ_AFTER_AWAIT" | "REACTIVITY_HALTED" | "INVARIANT_VIOLATION" | "HUGE_FAN_OUT" | "HUGE_FAN_IN" | "GRAPH_GROWTH" | "HOT_SCOPE_RERUNS" | "HOT_SCOPE_TIME" | "WIDE_SCOPE_DEPS" | "UNSTABLE_MEMO_OUTPUT" | "WASTED_RECOMPUTE" | "ASYNC_WATERFALL" | "HOT_SCOPE_FANOUT" | "SILENT_HOLD" | "LONG_HOLD" | "UNTRACKED_ASYNC_HANDLER" | "ABANDONED_FLIGHTS" | "FALLBACK_FLASH" | "STACKED_HOLDS" | "OPTIMISTIC_REVERTED" | "EFFECT_WRITES_OWN_SOURCE" | "EFFECT_RELAY_TEAR" | "IMMUTABLE_UPDATE_IN_STORE" | "UNSTABLE_LIST_IDENTITY" | "SSR_RENDER_ERROR_CONTAINED" | "SSR_SUBTREE_ABANDONED" | "SSR_STREAM_ABANDONED" | "SSR_CLIENT_CONTENT_MASKED" | "LATE_HEADER_WRITE" | "SERVER_ERROR_SANITIZED" | "SSR_BOUNDARY_WATERFALL" | "SSR_UNDECLARED_LIVE_SOURCE" | "SSR_LIVE_HOLE_LATCHED" | "SERVER_WRITE" | "REVEAL_IN_RENDER_TO_STRING" | "LAZY_ASSET_UNMAPPED" | "PRELOAD_DESCRIPTOR_INVALID" | "HEAD_TAG_INVALID" | "UNRECOGNIZED_INSERT_VALUE" | "UNSCOPED_HOLE_ALLOCATED_IDS" | "LOWERCASE_EVENT_ATTRIBUTE" | "UNCOMMITTED_INPUT_OVERWRITTEN" | "FRAME_MARKER_CORRUPTED" | "DYNAMIC_ASYNC_COMPONENT" | "ASYNC_MEMO_ELEMENT";
20
20
  export type DiagnosticKind = "strict-read" | "async" | "write" | "lifecycle" | "owner" | "error" | "perf" | "graph"
21
21
  /** Perceived responsiveness: the runtime behaved correctly but the user saw no feedback. */
22
22
  | "responsiveness"
@@ -3,7 +3,8 @@ import { type Transaction } from "./scheduler.js";
3
3
  import type { Computed, Signal } from "./types.js";
4
4
  export { laneValueOf };
5
5
  /** What the screen shows for a lane's node: the lane's value once the lane
6
- * has revealed, the committed truth before. */
6
+ * has revealed, the committed truth before — NOT_PENDING when there is none
7
+ * (uninitialized, as `laneValueOf`): its read throws NotReady. */
7
8
  export declare function display(el: Signal<any> | Computed<any>): unknown;
8
9
  /** What the writer sees of a node: an unflushed guess to it, else the
9
10
  * lane's value or the committed one — what an optimistic updater composes
@@ -11,6 +12,12 @@ export declare function display(el: Signal<any> | Computed<any>): unknown;
11
12
  export declare function guessedValueOf<T>(n: Signal<T> | Computed<T>): T;
12
13
  /** The unflushed guess to `n`, else NOT_PENDING. */
13
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;
14
21
  export declare function optimisticWrite<T>(n: Signal<T> | Computed<T>, v: T | ((prev: T) => T)): T;
15
22
  /** The running pass read lane `l`'s work as a derivation: it is `l`'s — or,
16
23
  * already another lane's, the frame it computes derives from both guesses
@@ -6,11 +6,22 @@ export declare let laneStageHook: ((el: Computed<any>, l: Transaction, create: b
6
6
  export declare let laneOutcomeHook: ((el: Computed<any>, value: unknown, errored: boolean) => boolean) | null;
7
7
  export declare let laneWriteHook: (<T>(el: Signal<T> | Computed<T>, v: T) => T) | null;
8
8
  export declare let applyGuessesHook: ((parent: Transaction | null) => void) | null;
9
- export declare let laneSeamsHook: ((leaks: Computed<any>[] | null) => void) | null;
9
+ export declare let laneSeamsHook: ((t: Transaction | null) => void) | null;
10
10
  export declare let laneCorrectionsHook: (() => boolean) | null;
11
11
  export declare let endLanesHook: ((u: Transaction) => void) | null;
12
12
  export declare let lanesBlockedHook: ((t: Transaction) => boolean) | null;
13
- export declare function installLaneHooks(read: NonNullable<typeof laneReadHook>, stage: NonNullable<typeof laneStageHook>, outcome: NonNullable<typeof laneOutcomeHook>, write: NonNullable<typeof laneWriteHook>, applyGuesses: NonNullable<typeof applyGuessesHook>, seams: NonNullable<typeof laneSeamsHook>, corrections: NonNullable<typeof laneCorrectionsHook>, end: NonNullable<typeof endLanesHook>, blocked: NonNullable<typeof lanesBlockedHook>): void;
13
+ /** R5 (lanes.ts `laneSeams` parks a frame flight): the landing's re-derive
14
+ * of a reader adopts the flight instead (true: adopted, nothing to queue). */
15
+ export declare let laneAdoptHook: ((r: Computed<any>) => boolean) | null;
16
+ /** core.ts `frameRead` served lane work or a verdict reader a held node's
17
+ * committed value (lanes.ts `laneServed`). */
18
+ export declare let laneServedHook: ((c: Computed<any>, el: Signal<any> | Computed<any>) => void) | null;
19
+ /** A guess was written (lanes.ts `optimisticWrite`): the arms only a guess
20
+ * reaches (CONFIG_GUESS) — a build without `createOptimistic` or
21
+ * `createOptimisticStore` never sets it, and its bundler folds them. */
22
+ export declare let guessing: boolean;
23
+ export declare function armGuessing(): void;
24
+ export declare function installLaneHooks(read: NonNullable<typeof laneReadHook>, stage: NonNullable<typeof laneStageHook>, outcome: NonNullable<typeof laneOutcomeHook>, write: NonNullable<typeof laneWriteHook>, applyGuesses: NonNullable<typeof applyGuessesHook>, seams: NonNullable<typeof laneSeamsHook>, corrections: NonNullable<typeof laneCorrectionsHook>, end: NonNullable<typeof endLanesHook>, blocked: NonNullable<typeof lanesBlockedHook>, adopt: NonNullable<typeof laneAdoptHook>, served: NonNullable<typeof laneServedHook>): void;
14
25
  export declare let catchHook: ((node: Computed<any>, flags: number, error: unknown) => unknown) | null;
15
26
  export declare let freshHook: ((node: Computed<any>, held?: unknown) => unknown) | null;
16
27
  export declare let hiddenHook: ((r: Computed<any>) => unknown) | null;
@@ -33,7 +44,10 @@ export declare let releaseAmbientMarksHook: ((parked: Transaction | null) => voi
33
44
  export declare function installMarkHooks(release: NonNullable<typeof releaseMarksHook>, releaseAmbient: NonNullable<typeof releaseAmbientMarksHook>): void;
34
45
  /** Verdicts (verdict.ts). */
35
46
  export declare let observeFlightHook: ((c: Computed<any>, el: Computed<any>) => boolean) | null;
36
- export declare function installVerdictHooks(observeFlight: NonNullable<typeof observeFlightHook>): void;
47
+ /** D-25's hold work (verdict.ts `holdWork`): on `source` going pending,
48
+ * whether verdict reader `n` waits on it instead of re-deriving. */
49
+ export declare let holdWorkHook: ((n: Computed<any>, source: Computed<any>) => unknown) | null;
50
+ export declare function installVerdictHooks(observeFlight: NonNullable<typeof observeFlightHook>, holdWork: NonNullable<typeof holdWorkHook>): void;
37
51
  /** External-source bridge (wired by enableExternalSource(); undefined while
38
52
  * no config is active — including after _resetExternalSourceConfig()). */
39
53
  export declare let wireExternalSourceHook: ((self: Computed<any>) => void) | undefined;
@@ -106,6 +120,11 @@ export declare function setPassLane(l: Transaction | null): void;
106
120
  * schedules the seam that consumes it: membership is the tick's — the same
107
121
  * synchronous frame — and the next tick's writes are not this one's. */
108
122
  export declare let flushTransaction: Transaction | null;
123
+ /** The flush's transaction while only a `latest()` read of a staging opened
124
+ * it (verdict.ts `provisionalVerdict`): it holds nothing, and a verdict
125
+ * reader's plain read of a staging in it is the frame's read (D-22). */
126
+ export declare let latestOpened: Transaction | null;
127
+ export declare function openedByLatest(): void;
109
128
  /** The transaction the passes running OUTSIDE a flush this tick derive from
110
129
  * (a mainline mount, a mainline re-pass): the passes' own (A29, creation-
111
130
  * time form — "the entry is the pass's alone"): their results are staged
@@ -258,6 +277,11 @@ export declare class GlobalQueue implements IQueue {
258
277
  static _runEffect: (el: Computed<unknown>) => void;
259
278
  /** A slot node's truth is in flight (its family's derive — store/store.ts). */
260
279
  static _slotFlight: ((n: Signal<any>) => boolean) | undefined;
280
+ /** A write to a slot node's guess (lanes.ts `laneWrite`): true when the
281
+ * store made the slot its derive's lane's derivation (optimistic.ts);
282
+ * `back`: the slot's node now, for a guess that comes back (lanes.ts
283
+ * `endLanes`). */
284
+ static _slotTake: ((n: Signal<any>, back?: boolean) => any) | undefined;
261
285
  /** The value a slot node's guess covered: its committed value — a chained
262
286
  * link's refreshed from the inner store, whose commits it never learned
263
287
  * while the guess served the reads (store/store.ts, §7b). */
@@ -353,7 +377,15 @@ export declare function insertSubs(node: Signal<any> | Computed<any>): void;
353
377
  * inert for its pass (`recompute` seats a lane only from its own `_x`), it
354
378
  * is a live write if the effect becomes a zombie later this flush — an
355
379
  * on-screen reader whose removal an adopted write stages follows the lane
356
- * (the lane-membership ruling, 2026-10-05; `_update`). */
380
+ * (the lane-membership ruling, 2026-10-05; `_update`).
381
+ *
382
+ * A render effect re-run by a verdict memo's change (`createMemo(() =>
383
+ * latest(x))`, CONFIG_VERDICT) is the verdict reader the same read inline
384
+ * makes it, for that pass (F-6; D-26 `[s(), L()]`, #4284): a frame reader
385
+ * of its other reads — a staging's screen, a flight's committed value. One
386
+ * an earlier propagation this flush seated in another lane leaves that
387
+ * seat: its pass starts from the frame's, as the inline effect's does, and
388
+ * `laneRead` re-derives it on the screen if that lane holds (`entered`). */
357
389
  export declare function laneDirty(node: Signal<any> | Computed<any>, l: Transaction): void;
358
390
  /** One lane, or two of one link group (#3335): one reveal unit. */
359
391
  export declare function sameLane(a: Transaction, b: Transaction): boolean;
@@ -2,7 +2,9 @@ import type { Transaction } from "./scheduler.js";
2
2
  import type { Computed, Signal } from "./types.js";
3
3
  /** A lane node's current value: its guess, or the latest it derived — the
4
4
  * staging a shown lane holds for its next reveal, else its slot; the
5
- * committed value while it has none (its first lane pass in flight). */
5
+ * committed value while it has none (its first lane pass in flight) —
6
+ * NOT_PENDING for a node with no committed value either (born in the lane,
7
+ * uninitialized: its reads throw NotReady, A7; #4363). */
6
8
  export declare function laneValueOf(el: Signal<any> | Computed<any>): unknown;
7
9
  /** Truth readers (`until`, `refresh`; CONFIG_AUTHORITATIVE) — pay-for-use:
8
10
  * the first one installs these on GlobalQueue (signals.ts `watch`).
@@ -120,6 +120,12 @@ export interface NodeExtension {
120
120
  * it, `isPending` reads a staged answer as a change over it, and a
121
121
  * recovery equal to the last good value is still a new answer. */
122
122
  _shownError: unknown;
123
+ /** R5: the frame pass's flight of a `latest()`/`isPending()` reader the
124
+ * seam re-derived in the verdict lane (lanes.ts `laneSeams`) — the
125
+ * frame's answer to the question it asked, which the transaction's
126
+ * landing adopts instead of asking it again (lanes.ts `adoptParked`, F-9). Cleared
127
+ * by any later pass. */
128
+ _parked?: PromiseLike<any>;
123
129
  }
124
130
  export interface RawSignal<T> {
125
131
  _subs: Link | null;
@@ -7,6 +7,8 @@ export { $REFRESH, action, ContextNotFoundError, NoOwnerError, NotReadyError, Ti
7
7
  export { setConsoleFooter } from "./core/index.js";
8
8
  /** @internal The flush round counter (scheduler.ts): hydration's served pass tells its own round from a later one. */
9
9
  export { clock } from "./core/index.js";
10
+ /** @internal Dev duplicate-copy check: solid-js marks components and context reads. */
11
+ export { runAsSolidCopy, checkForeignOwnerless } from "./core/copies.js";
10
12
  /** @internal The pre-write hook (`setWriteHook` in core/core.ts); the server-components client's deferred hydration. */
11
13
  /** @internal Plain-signal identities and the dev read watch (dependency edges; the server-components client). */
12
14
  export { setWriteHook, setSignalIdentities, setReadWatch, signalName } from "./core/index.js";
@@ -5,8 +5,9 @@
5
5
  * from `affects()`, and an app without stores carries none of the engine.
6
6
  * A slot no installer reaches stays `null`, and a bundler folds its sites.
7
7
  */
8
+ import type { Transaction } from "../core/scheduler.js";
8
9
  import type { Signal } from "../core/types.js";
9
- import type { StoreTarget } from "./target.js";
10
+ import type { StoreFamily, StoreTarget } from "./target.js";
10
11
  /** The optimistic machinery (optimistic.ts, S4), installed when it loads
11
12
  * — a plain store pays nothing for it (#2883): the plain paths reach it
12
13
  * only through a family with `opt` set, which only `createOptimisticStore`
@@ -33,6 +34,19 @@ export interface OptHooks {
33
34
  /** A user's `reconcile` on an optimistic family: the keyed diff written
34
35
  * into the draft. */
35
36
  reconcile(draft: any, incoming: any, keyFn: ((item: any) => any) | null): void;
37
+ /** The derive's draft wrote `pb` on `t`: the new object at a guessed
38
+ * row's slot (by key in a keyed list) is adopted by that row's target. */
39
+ pair(t: StoreTarget, pb: Record<PropertyKey, any>): void;
40
+ /** The derive of `fam` went in flight (#4336): a new question asked over
41
+ * the family's guesses is judged by its reads (`stands`) and at the seam
42
+ * (`park`). */
43
+ ask(fam: StoreFamily): void;
44
+ /** The flush parks with `t`: a guess a frame still reads, over a family
45
+ * asked a new question this flush, holds `t` with its action (D-34). */
46
+ park(t: Transaction): void;
47
+ /** A read of `t` while its family's derive is in flight: the family's
48
+ * guesses stand in for the flight (no suspension). */
49
+ stands(t: StoreTarget): boolean;
36
50
  }
37
51
  export declare let optHooks: OptHooks | null;
38
52
  export declare function installOptHooks(hooks: OptHooks): void;
@@ -87,7 +87,8 @@ export declare function notifyKeyValue(node: Signal<any>, key: PropertyKey, ov:
87
87
  * unrelated `a.value` stayed stale until the action settled). A real
88
88
  * change still writes, and on a held node still proposes. A live chained
89
89
  * `old` (a store proxy, §7b) reflects the inner store, not what the node
90
- * was last told — written unconditionally, as before.
90
+ * was last told — written unconditionally, as before; its container too
91
+ * (#4361).
91
92
  *
92
93
  * The container is told of an arrangement change when it has structural
93
94
  * subscribers OR carries an arrangement guess (S4): for a guessed
@@ -25,6 +25,11 @@ export interface StoreFamily {
25
25
  /** Targets carrying a lane value on one of their nodes (reads compose the
26
26
  * view over the truth — optimistic.ts); dropped lazily once none is. */
27
27
  overlaid?: Set<StoreTarget>;
28
+ /** The derive asked a new question over the family's guesses, stamped
29
+ * with that flush's clock (#4336, optimistic.ts `ask`): `clock + 1` from
30
+ * mainline over a live guess, `~clock` otherwise (a lane's work over no
31
+ * guess of its own, or no live guess left). */
32
+ asked?: number;
28
33
  /** Normalized row-key fn (`options.key`, "id" default, null = unkeyed). */
29
34
  key?: ((item: any) => any) | null;
30
35
  map: WeakMap<object, StoreTarget>;
@@ -96,3 +96,10 @@ export declare function isWrappable<T>(obj: T | NotWrappable): obj is T;
96
96
  export declare function ownEnumerableKeys(o: object): (string | symbol)[];
97
97
  export declare let writeOverride: boolean;
98
98
  export declare function setWriteOverride(value: boolean): void;
99
+ /** The list driver's view of a shallow store (map.ts): the backing a read of
100
+ * every slot serves this reader, or `undefined` when the list is no shallow
101
+ * store or a slot read could differ from it. Installed by store.ts's top
102
+ * level, so a `<For>` in an app without stores carries none of it; it lives
103
+ * beside `$TRACK` so map.ts reaches no other store module. */
104
+ export declare let shallowView: ((t: any) => any[] | undefined) | null;
105
+ export declare function installShallowView(view: (t: any) => any[] | undefined): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidjs/signals",
3
- "version": "2.0.0-rc.19",
3
+ "version": "2.0.0-rc.20",
4
4
  "description": "Solid's reactive primitives: signals, memos, effects, stores, and async-aware computations.",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",