@solidjs/signals 2.0.0-rc.11 → 2.0.0-rc.14

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 (118) hide show
  1. package/dist/dev-shared.js +2056 -3773
  2. package/dist/dev.attribution.js +159 -91
  3. package/dist/dev.js +7263 -8384
  4. package/dist/observe/affects.js +125 -104
  5. package/dist/observe/boundaries.js +458 -665
  6. package/dist/observe/core/action.js +63 -66
  7. package/dist/observe/core/async.js +240 -383
  8. package/dist/observe/core/attribution-queries.js +1 -1
  9. package/dist/observe/core/attribution.js +271 -199
  10. package/dist/observe/core/constants.js +115 -178
  11. package/dist/observe/core/context.js +3 -3
  12. package/dist/observe/core/core.js +840 -1428
  13. package/dist/observe/core/dev.js +41 -18
  14. package/dist/observe/core/effect.js +75 -86
  15. package/dist/observe/core/external.js +5 -5
  16. package/dist/observe/core/graph.js +61 -70
  17. package/dist/observe/core/heap.js +75 -98
  18. package/dist/observe/core/invariants.js +1 -34
  19. package/dist/observe/core/lanes.js +704 -181
  20. package/dist/observe/core/owner.js +80 -101
  21. package/dist/observe/core/scheduler.js +708 -1351
  22. package/dist/observe/core/verdict.js +302 -621
  23. package/dist/observe/flatten.js +79 -0
  24. package/dist/observe/index.js +15 -13
  25. package/dist/observe/map.js +232 -235
  26. package/dist/observe/reveal.js +212 -0
  27. package/dist/observe/signals.js +133 -215
  28. package/dist/observe/store/affects.js +135 -0
  29. package/dist/observe/store/index.js +29 -24
  30. package/dist/observe/store/optimistic.js +538 -0
  31. package/dist/observe/store/projection.js +302 -0
  32. package/dist/observe/store/reconcile.js +257 -0
  33. package/dist/observe/store/store.js +1945 -277
  34. package/dist/observe/store/storePath.js +1 -1
  35. package/dist/{prod/store/next → observe/store}/target.js +17 -18
  36. package/dist/observe/store/types.js +73 -0
  37. package/dist/observe/store/utils.js +1 -13
  38. package/dist/prod/affects.js +127 -106
  39. package/dist/prod/boundaries.js +442 -654
  40. package/dist/prod/core/action.js +71 -74
  41. package/dist/prod/core/async.js +307 -442
  42. package/dist/prod/core/constants.js +112 -177
  43. package/dist/prod/core/context.js +3 -3
  44. package/dist/prod/core/core.js +852 -1448
  45. package/dist/prod/core/effect.js +88 -99
  46. package/dist/prod/core/external.js +5 -5
  47. package/dist/prod/core/graph.js +61 -70
  48. package/dist/prod/core/heap.js +75 -98
  49. package/dist/prod/core/invariants.js +1 -32
  50. package/dist/prod/core/lanes.js +666 -181
  51. package/dist/prod/core/owner.js +75 -96
  52. package/dist/prod/core/scheduler.js +677 -1332
  53. package/dist/prod/core/verdict.js +297 -621
  54. package/dist/prod/flatten.js +77 -0
  55. package/dist/prod/index.js +15 -13
  56. package/dist/prod/map.js +143 -146
  57. package/dist/prod/reveal.js +212 -0
  58. package/dist/prod/signals.js +144 -226
  59. package/dist/prod/store/affects.js +135 -0
  60. package/dist/prod/store/index.js +28 -19
  61. package/dist/prod/store/optimistic.js +533 -0
  62. package/dist/prod/store/projection.js +295 -0
  63. package/dist/prod/store/reconcile.js +257 -0
  64. package/dist/prod/store/store.js +1840 -272
  65. package/dist/prod/store/storePath.js +1 -1
  66. package/dist/{observe/store/next → prod/store}/target.js +13 -17
  67. package/dist/prod/store/types.js +73 -0
  68. package/dist/prod/store/utils.js +1 -11
  69. package/dist/types/affects.d.ts +11 -30
  70. package/dist/types/boundaries.d.ts +62 -176
  71. package/dist/types/carved.d.ts +1 -0
  72. package/dist/types/core/action.d.ts +5 -6
  73. package/dist/types/core/async.d.ts +10 -5
  74. package/dist/types/core/attribution-hooks.d.ts +48 -1
  75. package/dist/types/core/attribution.d.ts +29 -9
  76. package/dist/types/core/constants.d.ts +125 -171
  77. package/dist/types/core/core.d.ts +104 -264
  78. package/dist/types/core/dev.d.ts +60 -7
  79. package/dist/types/core/effect.d.ts +0 -7
  80. package/dist/types/core/graph.d.ts +7 -1
  81. package/dist/types/core/heap.d.ts +5 -7
  82. package/dist/types/core/index.d.ts +6 -6
  83. package/dist/types/core/invariants.d.ts +0 -29
  84. package/dist/types/core/lanes.d.ts +65 -87
  85. package/dist/types/core/owner.d.ts +3 -3
  86. package/dist/types/core/scheduler.d.ts +249 -331
  87. package/dist/types/core/types.d.ts +51 -85
  88. package/dist/types/core/verdict.d.ts +3 -0
  89. package/dist/types/flatten.d.ts +8 -0
  90. package/dist/types/index.d.ts +7 -5
  91. package/dist/types/reveal.d.ts +19 -0
  92. package/dist/types/signals.d.ts +53 -92
  93. package/dist/types/store/affects.d.ts +1 -0
  94. package/dist/types/store/index.d.ts +35 -15
  95. package/dist/types/store/optimistic.d.ts +23 -0
  96. package/dist/types/store/projection.d.ts +18 -0
  97. package/dist/types/store/reconcile.d.ts +3 -0
  98. package/dist/types/store/store.d.ts +165 -143
  99. package/dist/types/store/storePath.d.ts +1 -1
  100. package/dist/types/store/target.d.ts +151 -0
  101. package/dist/types/store/types.d.ts +84 -0
  102. package/package.json +1 -1
  103. package/dist/observe/core/optimistic.js +0 -669
  104. package/dist/observe/store/next/optimistic.js +0 -717
  105. package/dist/observe/store/next/projection.js +0 -266
  106. package/dist/observe/store/next/reconcile.js +0 -375
  107. package/dist/observe/store/next/store.js +0 -2480
  108. package/dist/prod/core/optimistic.js +0 -658
  109. package/dist/prod/store/next/optimistic.js +0 -710
  110. package/dist/prod/store/next/projection.js +0 -257
  111. package/dist/prod/store/next/reconcile.js +0 -373
  112. package/dist/prod/store/next/store.js +0 -2356
  113. package/dist/types/core/optimistic.d.ts +0 -6
  114. package/dist/types/store/next/optimistic.d.ts +0 -25
  115. package/dist/types/store/next/projection.d.ts +0 -27
  116. package/dist/types/store/next/reconcile.d.ts +0 -10
  117. package/dist/types/store/next/store.d.ts +0 -143
  118. package/dist/types/store/next/target.d.ts +0 -196
@@ -1,6 +1,5 @@
1
1
  import type { NOT_PENDING } from "./constants.js";
2
- import type { OptimisticLane } from "./lanes.js";
3
- import type { IQueue, Transition } from "./scheduler.js";
2
+ import type { Transaction } from "./scheduler.js";
4
3
  export interface Disposable {
5
4
  (): void;
6
5
  }
@@ -17,7 +16,6 @@ export interface Link {
17
16
  * scanning the dep list to answer membership (see `link()`).
18
17
  */
19
18
  _gen: number;
20
- _pendingObserver?: boolean;
21
19
  }
22
20
  export interface NodeOptions<T> {
23
21
  id?: string;
@@ -28,14 +26,21 @@ export interface NodeOptions<T> {
28
26
  /** Exclude this signal from snapshot capture (internal — not part of public API) */
29
27
  _noSnapshot?: boolean;
30
28
  /** Extra CONFIG_* bits OR'd into the node's config at creation (internal —
31
- * not part of public API). Used by resolve()/until() for
32
- * CONFIG_DIRECT_COMMIT / CONFIG_AUTHORITATIVE_READ, keeping the per-flag
33
- * option arms out of the core creation path. */
29
+ * not part of public API). Used by refresh() for CONFIG_FRESH_READ,
30
+ * keeping the per-flag option arms out of the core creation path. */
34
31
  _extraConfig?: number;
35
32
  /** Observe tiers: framework plumbing — no name, no owner-path segment, no
36
33
  * attribution records of its own; its children stay observed (internal —
37
34
  * not part of public API; see CONFIG_PLUMBING). */
38
35
  _plumbing?: boolean;
36
+ /** Observe tiers: a framework scope wide by construction — exempt from
37
+ * WIDE_SCOPE_DEPS, never from HUGE_FAN_IN (internal — not part of public
38
+ * API; see CONFIG_WIDE). */
39
+ _wide?: boolean;
40
+ /** Observe tiers: a framework async node that supersedes its own flights by
41
+ * design — exempt from ABANDONED_FLIGHTS (internal — not part of public
42
+ * API; see CONFIG_SUPERSEDES). */
43
+ _supersedes?: boolean;
39
44
  unobserved?: () => void;
40
45
  lazy?: boolean;
41
46
  sync?: boolean;
@@ -62,69 +67,53 @@ export interface NodeOptions<T> {
62
67
  * hot-path gates — a bit says "consult _x", never the reverse.
63
68
  */
64
69
  export interface NodeExtension {
65
- _overrideValue: unknown | typeof NOT_PENDING;
66
- /**
67
- * The transaction that owns the active override (stamped at optimistic
68
- * write, cleared at settle). Ownership must live on the node: a lane's
69
- * _transition is a scheduling affinity that a shared subscriber can merge
70
- * across transactions (#2912) — following it would let one action's settle
71
- * revert another action's live override. Node-level sibling of the store
72
- * layer's STORE_OPTIMISTIC_OWNERS stamps (#2899). `null` = ambient write.
73
- */
74
- _overrideOwner: Transition | null | undefined;
75
- /** `clock` at the active override's write. A sync recompute in the same
76
- * tick derives from inputs that predate the override and does not
77
- * supersede it (A18 supersession ordering, #3331). */
78
- _overrideTime: number;
79
- /** A28: the staged value the last flush left on a HELD node that has since
80
- * been rewritten (latest() keeps answering with it); NOT_PENDING otherwise. */
81
- _flushedStaged: unknown;
82
- /** Provenance of the active override's write: the scheduler's `origin` (the
83
- * asking action's invocation sequence; 0 = mainline). An arriving answer
84
- * whose flight an older action issued asked a question the override has
85
- * since changed: it holds to commit instead of superseding (A18
86
- * supersession provenance, #3331). */
87
- _overrideStamp: number;
88
- _optimisticLane: OptimisticLane | undefined;
89
- _pendingSignal: Signal<boolean> | undefined;
90
- _latestValueComputed: Computed<any> | undefined;
91
- _parentSource: Signal<any> | Computed<any> | undefined;
92
- /**
93
- * Live `affects()` marks on this node (refcount). Non-zero is declared
94
- * motion — see affects(); the count is the mark's only graph state.
95
- */
96
- _affectsCount: number;
97
70
  _inFlight: PromiseLike<any> | AsyncIterable<any> | null;
98
71
  /** Cancellation for the CURRENT iterator flight (#3122): closes the
99
72
  * iterator (`it.return()`), idempotent. Fired at the sites that release
100
- * `_inFlight` so a superseded stream stops at supersede time — its owner
101
- * cleanup registration may ride the zombie-disposal channel, which a held
102
- * transition defers until the SUPERSEDING flight settles. Null for plain
103
- * promise flights (no cancellation hook exists). */
73
+ * `_inFlight` so a superseded stream stops at supersede time. Null for
74
+ * plain promise flights (no cancellation hook exists). */
104
75
  _flightTeardown: (() => void) | null;
105
76
  _error: unknown;
106
77
  _blocked: boolean | undefined;
107
78
  _pendingSources: Set<Computed<any>> | undefined;
108
- _notifyStatus: ((status?: number, error?: any) => void) | undefined;
109
- /** Question-scoped re-ask classification of the current pending window
110
- * (see the former Computed._x?._reask doc): set by recompute from
111
- * REACTIVE_REASK, cleared on landing; meaningless while not pending. */
112
- _reask: boolean;
113
- _child: FirewallSignal<any> | null;
114
79
  _unobserved: (() => void) | undefined;
115
80
  _snapshotValue: any;
116
- /** Zombie staging (staged disposal): a recompute of an owner that HAS
117
- * children/disposal parks them here until the flush commits (or a
118
- * transition reverts). Childless nodes — the common case — never write
119
- * these. */
120
- _pendingDisposal: Disposable | Disposable[] | null;
81
+ /** L2 — the previous pass's frame, parked for this node's commit: its child
82
+ * chain and `_disposal` list, still reacting until the commit disposes
83
+ * them (or the owner's death does). */
121
84
  _pendingFirstChild: Owner | null;
122
- /** #3038: the firewall children that actually carry isPending()/latest()
123
- * companions. The post-recompute companion snap iterates THIS set —
124
- * O(companions asked for) — never the full `_child` chain (one entry per
125
- * materialized leaf). Populated at companion creation; entries live as
126
- * long as their companions (which are permanent once created). */
127
- _companionChildren: Set<FirewallSignal<any>> | undefined;
85
+ _pendingDisposal: Disposable | Disposable[] | null;
86
+ /** L2 — the transaction holding this node while CONFIG_HELD is set
87
+ * (`holdNode`); resolved through merges by `txOf`. */
88
+ _transaction: Transaction | null;
89
+ /** L2 — the transaction a first pass that went pending was born into (it
90
+ * read a held node, or a verdict lane's mount read a staging of the
91
+ * flush — the born-held arm's conditions): its first answer lands into it
92
+ * while it is live; the hold never waits for the node's first load (the
93
+ * direction rule, #3800). Consumed at the landing. */
94
+ _bornIn: Transaction | null;
95
+ /** The node's current flight re-asks the same question (a `refresh()`,
96
+ * A19 exc. 2 / A24): verdict-quiet — `isPending` reads false for it —
97
+ * through its landing until the commit. */
98
+ _reask: boolean;
99
+ /** A28: the staging the last flush left on a held node, kept across an
100
+ * unflushed rewrite — what `latest()` and a tracked reader see until the
101
+ * flush that carries the rewrite; valid while `_flushedAt` is the current
102
+ * clock (that flush advances it). */
103
+ _flushed: unknown;
104
+ _flushedAt: number;
105
+ /** Provenance (A18, #3331): the question this node's guess or latest
106
+ * flight answers (`scheduler.question`); 0 when unstamped. */
107
+ _q: number;
108
+ /** Lanes (plan sec. 28) — the lane's value for this node while CONFIG_OVERRIDE is
109
+ * set: a written guess, or a lane pass's derivation. `NOT_PENDING` when
110
+ * none. The screen shows it once the lane has revealed (`_shown`); a
111
+ * direct read sees it throughout; the committed truth stays `_value`. */
112
+ _lane: unknown;
113
+ /** `affects()` marks live on this node (affects.ts): declared in-flight
114
+ * changes — `isPending` reads true for it and its derivations while any
115
+ * is live. A count, never a hold. */
116
+ _marks: number;
128
117
  }
129
118
  export interface RawSignal<T> {
130
119
  _subs: Link | null;
@@ -145,10 +134,6 @@ export interface RawSignal<T> {
145
134
  _equals: false | ((a: T, b: T) => boolean);
146
135
  _config: number;
147
136
  _time: number;
148
- /** IN CORE, not the extension (stage-3 §12c): consulted on EVERY write
149
- * (setSignal's transition-init check) and on recompute scheduling — the
150
- * per-write extension chase measurably taxed propagation chains. */
151
- _transition: Transition | null;
152
137
  /** Notify-epoch stamp of the last subscriber walk (§12d). A re-write to an
153
138
  * already-staged node whose stamp still equals the global epoch skips the
154
139
  * whole walk — marking is idempotent, and the epoch bumps on every
@@ -158,14 +143,7 @@ export interface RawSignal<T> {
158
143
  /** Cold extension — see NodeExtension. */
159
144
  _x: NodeExtension | null;
160
145
  }
161
- export interface FirewallSignal<T> extends RawSignal<T> {
162
- _firewall: Computed<any>;
163
- /** Doubly-linked child chain on the firewall's extension (`_x._child` is
164
- * the head): released leaves unlink in O(1) (#3351). */
165
- _nextChild: FirewallSignal<unknown> | null;
166
- _prevChild: FirewallSignal<unknown> | null;
167
- }
168
- export type Signal<T> = RawSignal<T> | FirewallSignal<T>;
146
+ export type Signal<T> = RawSignal<T>;
169
147
  export interface Owner {
170
148
  id?: string;
171
149
  _config: number;
@@ -176,11 +154,10 @@ export interface Owner {
176
154
  _parent: Owner | null;
177
155
  _context: Record<symbol | string, unknown>;
178
156
  _childCount: number;
179
- _queue: IQueue;
180
157
  _firstChild: Owner | null;
181
158
  _nextSibling: Owner | null;
182
159
  _prevSibling: Owner | null;
183
- /** Cold extension — see NodeExtension (owners use the zombie-pair slots). */
160
+ /** Cold extension — see NodeExtension. */
184
161
  _x: NodeExtension | null;
185
162
  /**
186
163
  * Observe-tier label: the `name` option, the node kind (`computed`,
@@ -200,22 +177,11 @@ export interface Computed<T> extends RawSignal<T>, Owner {
200
177
  _nextHeap: Computed<any> | undefined;
201
178
  _prevHeap: Computed<any>;
202
179
  _fn: (prev?: T) => T;
203
- /**
204
- * Clock tick at which REACTIVE_MANUAL_WRITE was last applied
205
- * (`suppressComputedRecompute`). Lets `refresh()` distinguish a same-tick
206
- * manual write (which wins over the refresh, #2692) from a mask carried
207
- * across ticks by a transaction (which an explicit refresh lifts, #3026).
208
- * Only meaningful while REACTIVE_MANUAL_WRITE is set.
209
- */
210
- _manualWriteTime?: number;
211
180
  /**
212
181
  * True while a `loadingValue` node's first real answer hasn't landed: the
213
182
  * node was born committed (commit #0 = the loading value) and `handleAsync`
214
183
  * serves that committed value instead of throwing NotReadyError, so first
215
- * flights never suspend readers, trip boundaries, or hold transitions.
216
- * The window is verdict-quiet: `isPending` stays false, because commit #0
217
- * answers the question by declaration (first-load affordances belong to
218
- * the value channel). Cleared by the first value landing on any path (sync
184
+ * flights never suspend readers or trip boundaries. Cleared by the first value landing on any path (sync
219
185
  * return, sync-resolved promise, first iterator yield, async settle); a
220
186
  * real error leaves it set — errors answer reads but don't enter the value
221
187
  * lineage, so a retry serves the loading value again. Once cleared, normal
@@ -1,2 +1,5 @@
1
+ /** The windows. `read` dispatches to `verdictValue` while one is open; each
2
+ * restores the dispatch it found — none inside a memo's pass a window
3
+ * pulled (`verdictValue`). */
1
4
  export declare function latest<T>(fn: () => T): T;
2
5
  export declare function isPending(fn: () => any): boolean;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Resolves nested accessors and arrays in a children tree to their rendered
3
+ * values. See the `children()` helper in solid-js for the memoized form.
4
+ */
5
+ export declare function flatten(children: any, options?: {
6
+ skipNonRendered?: boolean;
7
+ doNotUnwrap?: boolean;
8
+ }): any;
@@ -1,4 +1,4 @@
1
- export { $REFRESH, ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError, action, createContext, createOwner, createRoot, runWithOwner, flush, getNextChildId, peekNextChildId, getContext, setContext, getOwner, isDisposed, getObserver, isEqual, untrack, isPending, latest, SUPPORTS_PROXY, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots, enforceLoadingBoundary, enableExternalSource, resetErrorHalt, configureClientErrors, ROOT_ERROR_HOOK } from "./core/index.js";
1
+ export { $REFRESH, action, ContextNotFoundError, NoOwnerError, NotReadyError, TimeoutError, createContext, createOwner, createRoot, runWithOwner, flush, getNextChildId, peekNextChildId, getContext, setContext, getOwner, isDisposed, getObserver, isEqual, untrack, isPending, latest, SUPPORTS_PROXY, setSnapshotCapture, markSnapshotScope, releaseSnapshotScope, clearSnapshots, enforceLoadingBoundary, enableExternalSource, resetErrorHalt, configureClientErrors, ROOT_ERROR_HOOK } from "./core/index.js";
2
2
  /**
3
3
  * @internal The dev console footer seam — registered by `solid-js`, which
4
4
  * owns the repair skill the footer points at. Not part of `DEV`; a no-op
@@ -14,10 +14,12 @@ import { type Dev, type Observe } from "./core/index.js";
14
14
  export declare const OBSERVE: Observe | undefined;
15
15
  /** Dev tier (devtools hooks, graph traversal, console reporting): dev builds only. */
16
16
  export declare const DEV: Dev | undefined;
17
- export type { Owner, Context, ContextRecord, IQueue, ExternalSourceFactory, ExternalSource, ExternalSourceConfig, Refreshable, AttributionSlot, ClientErrorContext, ClientErrorHook, ClientErrorsConfig, InteractionRef, NavigationRef, Dev, Observe, ServerObserve, Records, RecordTypes, HostRecordTypes, RecordType, RecordEvent, RecordLive, RecordListener, DevHooks, DiagnosticCapture, DiagnosticCode, DiagnosticEvent, DiagnosticKind, DiagnosticListener, Diagnostics, DiagnosticSeverity, DiagnosticSubject } from "./core/index.js";
18
- export { createSignal, createMemo, createEffect, createRenderEffect, createTrackedEffect, createReaction, createOptimistic, refresh, resolve, until, onSettled, onCleanup } from "./signals.js";
17
+ export type { Owner, Context, ContextRecord, IQueue, ExternalSourceFactory, ExternalSource, ExternalSourceConfig, Refreshable, AttributionSlot, ClientErrorContext, ClientErrorHook, ClientErrorsConfig, InteractionRef, NavigationRef, Dev, Observe, ServerObserve, Records, RecordTypes, HostRecordTypes, RecordType, RecordEvent, RecordLive, RecordListener, RecordSubscribeOptions, DevHooks, DiagnosticCapture, DiagnosticCode, DiagnosticEvent, DiagnosticKind, DiagnosticListener, Diagnostics, DiagnosticSeverity, DiagnosticSubject } from "./core/index.js";
18
+ export { createSignal, createOptimistic, createMemo, createEffect, createRenderEffect, createTrackedEffect, createReaction, refresh, resolve, until, onSettled, onCleanup } from "./signals.js";
19
19
  export type { Truthy, UntilOptions, Accessor, SourceAccessor, Setter, Signal, ComputeFunction, EffectFunction, EffectBundle, EffectOptions, SignalOptions, MemoOptions, NoInfer } from "./signals.js";
20
- export { affects } from "./affects.js";
21
20
  export { mapArray, repeat, type Maybe } from "./map.js";
22
21
  export * from "./store/index.js";
23
- export { createLoadingBoundary, createErrorBoundary, createRevealOrder, flatten, type RevealOrder } from "./boundaries.js";
22
+ export { affects } from "./affects.js";
23
+ export { flatten } from "./flatten.js";
24
+ export { createLoadingBoundary, createErrorBoundary } from "./boundaries.js";
25
+ export { createRevealOrder, type RevealOrder } from "./reveal.js";
@@ -0,0 +1,19 @@
1
+ export type RevealOrder = "sequential" | "together" | "natural";
2
+ type OrderAccessor = () => RevealOrder;
3
+ type BoolAccessor = () => boolean;
4
+ /**
5
+ * Lower-level primitive behind `<Reveal>`: coordinates the order in which the
6
+ * Loading boundaries created directly inside `fn` reveal their content.
7
+ *
8
+ * @param fn the subtree; the Loading boundaries it creates directly are the
9
+ * group's slots, a nested `createRevealOrder` a composite slot
10
+ * @param options `order` — `"sequential"` (default: front to back, the
11
+ * first unready slot showing its fallback), `"together"` (all at once),
12
+ * `"natural"` (each on its own); `collapsed` — in a sequential group, the
13
+ * slots behind the frontier render nothing instead of their fallbacks
14
+ */
15
+ export declare function createRevealOrder<T>(fn: () => T, options?: {
16
+ order?: OrderAccessor;
17
+ collapsed?: BoolAccessor;
18
+ }): T;
19
+ export {};
@@ -267,10 +267,11 @@ export type NoInfer<T extends any> = [T][T extends any ? 0 : never];
267
267
  * // Writable memo: derives from `fn()` and can be written like a signal.
268
268
  * const [user, setUser] = createSignal(() => fetchUser(userId()));
269
269
  *
270
- * // Within the frame the write wins over a same-tick recompute; the next
271
- * // change to `userId` re-derives (the compute receives the written value
272
- * // as `prev`). While a transaction holds a re-derived value, a write from
273
- * // outside it does not replace that derivation — it becomes its `prev`.
270
+ * // A write lands at once and never re-runs `fn` on its own; when `userId`
271
+ * // changes, in the same update or later, `fn` re-runs and receives the
272
+ * // written value as `prev`. While a transaction holds a re-derived value, a
273
+ * // write from outside it does not replace that derivation — it becomes its
274
+ * // `prev`.
274
275
  * setUser({ ...user(), name: "Alice" });
275
276
  * ```
276
277
  *
@@ -279,6 +280,27 @@ export type NoInfer<T extends any> = [T][T extends any ? 0 : never];
279
280
  export declare function createSignal<T>(): Signal<T | undefined>;
280
281
  export declare function createSignal<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
281
282
  export declare function createSignal<T>(fn: ComputeFunction<T>, options?: SignalOptions<T> & MemoOptions<T>): Signal<T>;
283
+ /**
284
+ * Creates an optimistic signal: a value that can be set optimistically inside
285
+ * a transition and reverts to the value it covered when the transition ends.
286
+ *
287
+ * The write is a guess over the transition of the frame it is made in — the
288
+ * frame's held writes are its base, and it shows at once while they wait.
289
+ * Outside such a frame (nothing is held) the write is as if it never
290
+ * happened. With a function, the memo form: its own recompute is the truth
291
+ * — equal to the guess it confirms silently, different it corrects at the
292
+ * transition's commit.
293
+ *
294
+ * ```typescript
295
+ * const [state, setState] = createOptimistic<T>(value, options?: SignalOptions<T>);
296
+ * const [state, setState] = createOptimistic<T>(fn, options?: SignalOptions<T> & MemoOptions<T>);
297
+ * ```
298
+ *
299
+ * @description https://docs.solidjs.com/reference/basic-reactivity/create-optimistic-signal
300
+ */
301
+ export declare function createOptimistic<T>(): Signal<T | undefined>;
302
+ export declare function createOptimistic<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
303
+ export declare function createOptimistic<T>(fn: ComputeFunction<T>, options?: SignalOptions<T> & MemoOptions<T>): Signal<T>;
282
304
  /**
283
305
  * Creates a readonly derived reactive memoized signal.
284
306
  *
@@ -381,7 +403,7 @@ export declare function createMemo<T>(compute: ComputeFunction<undefined | NoInf
381
403
  *
382
404
  * @description https://docs.solidjs.com/reference/basic-reactivity/create-effect
383
405
  */
384
- export declare function createEffect<T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, effectFn: EffectFunction<NoInfer<T>, T> | EffectBundle<NoInfer<T>, T>, options?: EffectOptions): void;
406
+ export declare function createEffect<const T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, effectFn: EffectFunction<NoInfer<T>, T> | EffectBundle<NoInfer<T>, T>, options?: EffectOptions): void;
385
407
  /**
386
408
  * Creates a reactive computation that runs during the render phase as DOM elements
387
409
  * are created and updated but not necessarily connected.
@@ -411,7 +433,7 @@ export declare function createEffect<T>(compute: ComputeFunction<undefined | NoI
411
433
  *
412
434
  * @description https://docs.solidjs.com/reference/secondary-primitives/create-render-effect
413
435
  */
414
- export declare function createRenderEffect<T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, effectFn: EffectFunction<NoInfer<T>, T>, options?: EffectOptions): void;
436
+ export declare function createRenderEffect<const T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, effectFn: EffectFunction<NoInfer<T>, T>, options?: EffectOptions): void;
415
437
  /**
416
438
  * Creates a tracked reactive effect where dependency tracking and side effects happen
417
439
  * in the same scope.
@@ -523,19 +545,10 @@ export declare function resolve<T>(fn: () => T): Promise<T>;
523
545
  * read:
524
546
  * - Accessor targets resolve with the settled value; store targets resolve
525
547
  * with the store node passed (reads through it are fresh after the await).
526
- * - A failed re-ask rejects with the error (inside an action's generator,
527
- * `yield refresh(x)` throws back at the yield point and the action reverts
528
- * like any other failure).
548
+ * - A failed re-ask rejects with the error.
529
549
  * - Semantics are quiescence, not flight identity: if another refresh (or
530
550
  * any invalidation) supersedes this one mid-flight, the promise waits for
531
551
  * — and delivers — whatever finally lands.
532
- * - Inside an action, truth landing into the held transaction is STAGED;
533
- * the promise still settles then (matching `resolve()`/`until()`, #2930)
534
- * and delivers the staged value — the caller's own optimistic override is
535
- * never the delivered value.
536
- * - The re-ask itself stays verdict-quiet exactly as before: `isPending`
537
- * does not flip for a bare refresh (pair with `affects()` for a visible
538
- * pending window).
539
552
  *
540
553
  * @example
541
554
  * ```ts
@@ -551,13 +564,30 @@ export declare function resolve<T>(fn: () => T): Promise<T>;
551
564
  export declare function refresh<T>(target: Refreshable<T>): Promise<T extends (...args: any) => infer V ? V : T>;
552
565
  /** Falsy values a truthy predicate result is narrowed against. */
553
566
  export type Truthy<T> = Exclude<T, false | 0 | 0n | "" | null | undefined>;
567
+ /**
568
+ * The global `AbortSignal` when the consumer's libs declare one (DOM,
569
+ * WebWorker, `@types/node`), else the surface `until` uses — so these
570
+ * declarations check under neither lib without widening the global type.
571
+ */
572
+ type GlobalAbortSignal = typeof globalThis extends {
573
+ AbortSignal: {
574
+ prototype: infer S;
575
+ };
576
+ } ? S : {
577
+ readonly aborted: boolean;
578
+ readonly reason: any;
579
+ addEventListener(type: "abort", listener: () => void, options?: {
580
+ once?: boolean;
581
+ }): void;
582
+ removeEventListener(type: "abort", listener: () => void): void;
583
+ };
554
584
  export interface UntilOptions {
555
585
  /** Reject with `TimeoutError` if the predicate has not turned truthy within
556
586
  * this many milliseconds. Strongly recommended when the confirming truth
557
587
  * arrives over a transport that can drop (sockets, subscriptions). */
558
588
  timeout?: number;
559
589
  /** Reject with `signal.reason` on abort. */
560
- signal?: AbortSignal;
590
+ signal?: GlobalAbortSignal;
561
591
  }
562
592
  /**
563
593
  * Awaits a reactive predicate and resolves the first time it settles *truthy*,
@@ -568,96 +598,27 @@ export interface UntilOptions {
568
598
  *
569
599
  * Where {@link resolve} answers "what is this value" (first settled value,
570
600
  * whatever it is), `until` answers "when does the world confirm this
571
- * condition". The difference matters inside an `action()`: `yield until(...)`
572
- * holds the action's transaction — and any optimistic state riding it — open
573
- * until the condition is independently true.
574
- *
575
- * To make that sound, `until`'s predicate reads the AUTHORITATIVE view — and
576
- * this is the one read-semantics difference from `resolve`, which reads the
577
- * normal (transaction's own) view where overrides are visible:
578
- *
579
- * - **Optimistic overrides are invisible** to the predicate. Your own
580
- * tentative write can never satisfy your own ack, even on the
581
- * single-primitive shape where the optimistic store IS the live-fed store.
582
- * (Derived computeds serve their normal cached values — express the
583
- * condition over sources of truth, not derived views of the overlay.)
584
- * - **Everything else reads normally, including uncommitted transition-staged
585
- * data.** Real data is real wherever it currently lives. This is
586
- * load-bearing, not a loophole: truth that arrives *into* the open
587
- * transaction (a `refresh()` this action issued, an entangled landing)
588
- * stages and cannot commit until the hold releases — a predicate that
589
- * refused staged reads would deadlock on the very data it is waiting for.
601
+ * condition".
590
602
  *
591
603
  * This is the acknowledgment mechanism for mutations confirmed on a live data
592
604
  * channel (sockets, subscriptions, live queries) rather than by the mutation's
593
605
  * own response: correlate by a client-generated id or version in the predicate,
594
606
  * and let truth arrive however it arrives — push, refetch, or another tab.
595
607
  *
596
- * Failure composes with action semantics: a rejection is thrown back into the
597
- * generator at the `yield` point — catchable there, or the action fails and
598
- * its optimistic state reverts.
599
- *
600
608
  * Must be called *outside* a tracking scope.
601
609
  *
602
- * Inside an action, call it from a step: after an `await`, put a bare `yield`
603
- * before `yield until(...)`. The runtime cannot hook an async generator's
604
- * `await` continuation, so the `until(...)` expression — which CREATES the
605
- * predicate's reader — would otherwise run outside the transaction; created
606
- * there it is born held (A29) and replays only at the commit its own promise
607
- * holds open (#3482). See {@link action}.
608
- *
609
610
  * @example
610
611
  * ```ts
611
- * const send = action(async function* (text: string) {
612
- * const clientId = crypto.randomUUID();
613
- * setMessages(m => { m.push({ clientId, text, pending: true }); }); // optimistic
614
- * await socket.send({ clientId, text }); // fire-and-forget transport
615
- * yield; // re-enter the transaction after the await
616
- * // Hold until the live source echoes the write (authoritative view —
617
- * // the optimistic row above cannot satisfy this):
618
- * yield until(() => messages.some(m => m.clientId === clientId), { timeout: 10_000 });
619
- * });
612
+ * const clientId = crypto.randomUUID();
613
+ * await socket.send({ clientId, text }); // fire-and-forget transport
614
+ * // Wait until the live source echoes the write:
615
+ * await until(() => messages.some(m => m.clientId === clientId), { timeout: 10_000 });
620
616
  * ```
621
617
  *
622
- * @param fn a reactive predicate over authoritative state
618
+ * @param fn a reactive predicate
623
619
  * @param options optional `timeout` (ms) and abort `signal`
624
620
  */
625
621
  export declare function until<T>(fn: () => T, options?: UntilOptions): Promise<Truthy<T>>;
626
- /**
627
- * Creates an optimistic signal that can be used to optimistically update a value
628
- * and then revert it back to the previous value at end of transition.
629
- *
630
- * When called with a plain value, creates an optimistic signal with `SignalOptions` (name, equals, ownedWrite, unobserved).
631
- * When called with a function, creates a writable optimistic memo with `SignalOptions & MemoOptions` (adds id, lazy).
632
- *
633
- * ```typescript
634
- * // Plain optimistic signal
635
- * const [state, setState] = createOptimistic<T>(value, options?: SignalOptions<T>);
636
- * // Writable optimistic memo (function overload)
637
- * const [state, setState] = createOptimistic<T>(fn, options?: SignalOptions<T> & MemoOptions<T>);
638
- * ```
639
- * @param value initial value of the signal; if empty, the signal's type will automatically extended with undefined
640
- * @param options optional object with a name for debugging purposes and equals, a comparator function for the previous and next value to allow fine-grained control over the reactivity
641
- *
642
- * @returns `[state: Accessor<T>, setState: Setter<T>]`
643
- *
644
- * @example
645
- * ```ts
646
- * const [todos, setTodos] = createOptimistic(initialTodos);
647
- *
648
- * const addTodo = action(function* (text: string) {
649
- * const tempId = crypto.randomUUID();
650
- * setTodos(t => [...t, { id: tempId, text, pending: true }]); // optimistic
651
- * const saved = yield api.createTodo(text);
652
- * setTodos(t => t.map(x => (x.id === tempId ? saved : x))); // reconcile
653
- * });
654
- * ```
655
- *
656
- * @description https://docs.solidjs.com/reference/basic-reactivity/create-optimistic-signal
657
- */
658
- export declare function createOptimistic<T>(): Signal<T | undefined>;
659
- export declare function createOptimistic<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
660
- export declare function createOptimistic<T>(fn: ComputeFunction<T>, options?: SignalOptions<T> & MemoOptions<T>): Signal<T>;
661
622
  /**
662
623
  * Schedules `callback` to run **once** after the reactive graph has fully
663
624
  * settled — i.e. once every pending async read inside the current owner has
@@ -0,0 +1 @@
1
+ export {};
@@ -1,20 +1,40 @@
1
- export type { Store, StoreReturn, ProjectionStoreReturn, StoreSetter, StoreNode, StoreOptions, ProjectionOptions, NotWrappable, SolidStore } from "./store.js";
1
+ /**
2
+ * Store — public surface. Plain stores (S1) are live; the derived form
3
+ * (`createStore(fn, seed)`), projections, optimistic stores and reconcile
4
+ * return on later steps (plan sec. 31.5).
5
+ */
6
+ export type { NoFn, NotWrappable, ProjectionOptions, ProjectionStoreReturn, SolidStore, Store, StoreOptions, StoreReturn, StoreSetter } from "./types.js";
7
+ export { $PROXY, $RECORD, $TARGET, $TRACK, isWrappable, markRaw } from "./types.js";
8
+ export { storeIsShallow, storeHasFamily, storeHasOptimisticFamily } from "./store.js";
9
+ export { storePath } from "./storePath.js";
10
+ export type { StorePathRange, PathSetter, Part, CustomPartial, ArrayFilterFn } from "./storePath.js";
11
+ import "./affects.js";
12
+ import { createOptimisticStore } from "./optimistic.js";
13
+ import { createProjection } from "./projection.js";
14
+ import type { NoFn, ProjectionOptions, ProjectionStoreReturn, Store, StoreOptions, StoreReturn } from "./types.js";
15
+ export { createOptimisticStore, createProjection };
16
+ /** The store's internal record behind a proxy (`store[$TARGET]`). Kept
17
+ * under `next`'s public name; its shape is the L2 target's (plan plan sec. 31–32:
18
+ * the symbol-keyed legacy record is gone with the representation). */
19
+ export type { StoreTarget as StoreNode } from "./target.js";
2
20
  export type { Merge, Omit } from "./utils.js";
3
- export { isWrappable, $TRACK, $PROXY, $TARGET, $RECORD } from "./store.js";
4
- export { mergeSources, mergeView, viewOf, omitView, sourceKeys, sourceHas, sourceGet, hasStaticKeys, isStatic, resolvedTable, OmitView, MergeView, SOURCE_PLAIN, SOURCE_OMIT, SOURCE_PROXY, SOURCE_MEMO, SOURCE_MERGE, sourceOwners } from "./utils.js";
21
+ export { mergeSources, mergeView, viewOf, omitView, sourceKeys, sourceHas, sourceGet, hasStaticKeys, isStatic, resolvedTable, OmitView, MergeView, SOURCE_PLAIN, SOURCE_OMIT, SOURCE_PROXY, SOURCE_MEMO, SOURCE_MERGE, sourceOwners, merge, omit } from "./utils.js";
5
22
  export type { SourceKind } from "./utils.js";
6
- import type { NoFn, ProjectionOptions, Store, StoreOptions, StoreSetter } from "./store.js";
7
- import type { Refreshable } from "../core/index.js";
8
- export { createProjectionNext as createProjection } from "./next/projection.js";
9
- export { storeIsShallow, storeHasFamily, storeHasOptimisticFamily } from "./next/store.js";
10
- export { createOptimisticStoreNext as createOptimisticStore } from "./next/optimistic.js";
11
- /** Public createStore: plain form `(initialValue, options?)` and derived writable
12
- * form `(fn, seed, options?)`. */
13
- export declare function createStore<T extends object = {}>(initialValue: NoFn<T> | Store<NoFn<T>>, options?: StoreOptions): [get: Store<T>, set: StoreSetter<T>];
14
- export declare function createStore<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
23
+ /**
24
+ * Create a reactive store: a proxy over plain data with fine-grained
25
+ * subscriptions per read path, written through its setter's draft — or, in
26
+ * the derived form, a projection with a setter.
27
+ */
28
+ export declare function createStore<T extends object = {}>(initialValue: NoFn<T>, options?: StoreOptions): StoreReturn<T>;
29
+ export declare function createStore<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): ProjectionStoreReturn<T>;
30
+ /**
31
+ * A setter transform that reconciles `value` into the store by key
32
+ * (`"id"` by default; `null` positional), preserving store identity for
33
+ * surviving rows.
34
+ */
15
35
  export declare function reconcile<T extends U, U>(value: T, key?: string | ((item: NonNullable<any>) => any) | null): (state: U) => T;
36
+ /** Non-tracking snapshot of a store's current value (source identity for
37
+ * unmodified subtrees). */
16
38
  export declare function snapshot<T>(value: T): T;
39
+ /** Tracking snapshot: subscribes to every reachable record. */
17
40
  export declare function deep<T>(value: T): T;
18
- export { storePath } from "./storePath.js";
19
- export type { PathSetter, Part, StorePathRange, ArrayFilterFn, CustomPartial } from "./storePath.js";
20
- export { merge, omit } from "./utils.js";
@@ -0,0 +1,23 @@
1
+ import type { Refreshable } from "../core/index.js";
2
+ import { type StoreTarget } from "./target.js";
3
+ import { type NoFn, type ProjectionOptions, type Store, type StoreOptions, type StoreSetter } from "./types.js";
4
+ export declare function notifyOptimisticWrites(t: StoreTarget, pb: Record<PropertyKey, any>): Record<PropertyKey, any> | null;
5
+ export declare function sweepOverlaid(): void;
6
+ /** An untracked `key in store` on an optimistic family: the presence guess
7
+ * (what its lane shows) when the key carries one; `undefined` when not —
8
+ * the backing answers. */
9
+ export declare function optimisticHas(t: StoreTarget, key: PropertyKey): boolean | undefined;
10
+ /** A descriptor read of a guessed key: synthesized from the lane's value
11
+ * (`null`: the guess removed the key; `undefined`: no guess — the backing
12
+ * describes it). */
13
+ export declare function optimisticOwnDescriptor(t: StoreTarget, key: PropertyKey): PropertyDescriptor | null | undefined;
14
+ /** The truth `src` with the target's lane values over it: each overlaid
15
+ * leaf's value (`pick`: what the lane shows, or — for `latest` — the lane's
16
+ * latest), each presence guess as a key added or removed, the array
17
+ * length. Returns `src` itself when nothing is overlaid. */
18
+ export declare function optimisticView(t: StoreTarget, src: Record<PropertyKey, any>, pick?: (n: any) => unknown, writer?: boolean): Record<PropertyKey, any>;
19
+ /** `latest()`'s view: the lanes' latest values (a landing staged beneath a
20
+ * guess is what lands). */
21
+ export declare function latestView(t: StoreTarget, src: Record<PropertyKey, any>): Record<PropertyKey, any>;
22
+ export declare function createOptimisticStore<T extends object = {}>(initialValue: NoFn<T> | Store<NoFn<T>>, options?: StoreOptions): [get: Store<T>, set: StoreSetter<T>];
23
+ export declare function createOptimisticStore<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
@@ -0,0 +1,18 @@
1
+ import type { Computed } from "../core/types.js";
2
+ import type { Refreshable } from "../core/index.js";
3
+ import { type NoFn, type ProjectionOptions, type Store } from "./types.js";
4
+ /** The derive's pass: run `fn` against a draft of the store; commit its
5
+ * result (sync, or each async landing) through the reconcile channel.
6
+ * Draft validity is per run (R37): live from here until the NEXT run starts
7
+ * — a sync derive that subscribes to an external source and pushes into
8
+ * the draft from the callback (#3585) is the model use. */
9
+ export declare function runProjectionComputed<T extends object>(wrappedStore: Store<T>, fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, key: string | ((item: NonNullable<any>) => any) | null, wrapCommit?: (write: () => void, value: T) => void, aroundDraftWrite?: (op: () => void) => void): Computed<void | T>;
10
+ /**
11
+ * A derived store: `fn` runs in a computed and writes its draft; readers of
12
+ * the store's keys re-run only when the keys they read change (the
13
+ * firewall). `fn` may be async or an async iterator; the seed is a draft,
14
+ * never an observable value, until the first landing (A25).
15
+ */
16
+ export declare function createProjection<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): Refreshable<Store<T>>;
17
+ /** `createStore(fn, seed, options)`: a projection with a user setter. */
18
+ export declare function createStoreDerived<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: Partial<T> | Store<NoFn<T>>, options?: ProjectionOptions): [Refreshable<Store<T>>, (f: (draft: T) => T | void) => void];
@@ -0,0 +1,3 @@
1
+ type KeyFn = (item: any) => any;
2
+ export declare function reconcileState(value: any, state: any, key: string | KeyFn | null | undefined, replace?: boolean): void;
3
+ export {};