@solidjs/signals 2.0.0-rc.14 → 2.0.0-rc.16
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.
- package/dist/dev-shared.js +882 -405
- package/dist/dev.attribution.js +172 -66
- package/dist/dev.js +1529 -745
- package/dist/observe/affects-marks.js +86 -0
- package/dist/observe/affects.js +32 -80
- package/dist/observe/boundaries.js +202 -166
- package/dist/observe/core/async.js +192 -141
- package/dist/observe/core/attribution-queries.js +1 -1
- package/dist/observe/core/attribution.js +315 -214
- package/dist/observe/core/constants.js +23 -4
- package/dist/observe/core/context.js +3 -3
- package/dist/observe/core/core.js +532 -360
- package/dist/observe/core/dev.js +63 -35
- package/dist/observe/core/effect.js +47 -47
- package/dist/observe/core/error.js +5 -3
- package/dist/observe/core/external.js +5 -6
- package/dist/observe/core/graph.js +56 -42
- package/dist/observe/core/heap.js +33 -33
- package/dist/observe/core/identities.js +62 -0
- package/dist/observe/core/lanes.js +242 -229
- package/dist/observe/core/owner.js +62 -50
- package/dist/observe/core/scheduler.js +322 -168
- package/dist/observe/core/truth.js +45 -0
- package/dist/observe/core/verdict.js +114 -64
- package/dist/observe/deferred.js +184 -0
- package/dist/observe/index.js +7 -1
- package/dist/observe/map.js +339 -254
- package/dist/observe/reveal.js +77 -77
- package/dist/observe/signals.js +54 -33
- package/dist/observe/store/affects.js +76 -69
- package/dist/observe/store/edges.js +39 -0
- package/dist/observe/store/hooks.js +13 -0
- package/dist/observe/store/index.js +0 -2
- package/dist/observe/store/optimistic.js +82 -44
- package/dist/observe/store/projection.js +83 -64
- package/dist/observe/store/reconcile.js +32 -30
- package/dist/observe/store/store.js +219 -123
- package/dist/prod/affects-marks.js +86 -0
- package/dist/prod/affects.js +33 -79
- package/dist/prod/boundaries.js +185 -149
- package/dist/prod/core/async.js +176 -135
- package/dist/prod/core/constants.js +23 -4
- package/dist/prod/core/context.js +3 -3
- package/dist/prod/core/core.js +521 -353
- package/dist/prod/core/effect.js +66 -66
- package/dist/prod/core/error.js +5 -3
- package/dist/prod/core/external.js +5 -6
- package/dist/prod/core/graph.js +56 -42
- package/dist/prod/core/heap.js +38 -38
- package/dist/prod/core/identities.js +62 -0
- package/dist/prod/core/lanes.js +237 -224
- package/dist/prod/core/owner.js +62 -51
- package/dist/prod/core/scheduler.js +312 -158
- package/dist/prod/core/truth.js +45 -0
- package/dist/prod/core/verdict.js +113 -63
- package/dist/prod/deferred.js +182 -0
- package/dist/prod/index.js +7 -1
- package/dist/prod/map.js +366 -281
- package/dist/prod/reveal.js +77 -77
- package/dist/prod/signals.js +59 -38
- package/dist/prod/store/affects.js +76 -69
- package/dist/prod/store/edges.js +39 -0
- package/dist/prod/store/hooks.js +13 -0
- package/dist/prod/store/index.js +0 -2
- package/dist/prod/store/optimistic.js +121 -84
- package/dist/prod/store/projection.js +46 -34
- package/dist/prod/store/reconcile.js +32 -30
- package/dist/prod/store/store.js +205 -116
- package/dist/types/affects-marks.d.ts +14 -0
- package/dist/types/boundaries.d.ts +5 -1
- package/dist/types/core/async.d.ts +10 -0
- package/dist/types/core/attribution.d.ts +6 -2
- package/dist/types/core/constants.d.ts +18 -1
- package/dist/types/core/core.d.ts +77 -5
- package/dist/types/core/dev.d.ts +43 -13
- package/dist/types/core/graph.d.ts +11 -0
- package/dist/types/core/identities.d.ts +17 -0
- package/dist/types/core/index.d.ts +2 -1
- package/dist/types/core/lanes.d.ts +2 -4
- package/dist/types/core/owner.d.ts +5 -3
- package/dist/types/core/scheduler.d.ts +59 -34
- package/dist/types/core/truth.d.ts +16 -0
- package/dist/types/core/types.d.ts +21 -6
- package/dist/types/core/verdict.d.ts +32 -0
- package/dist/types/deferred.d.ts +28 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/map.d.ts +2 -2
- package/dist/types/signals.d.ts +28 -7
- package/dist/types/store/affects.d.ts +11 -0
- package/dist/types/store/edges.d.ts +9 -0
- package/dist/types/store/hooks.d.ts +48 -0
- package/dist/types/store/index.d.ts +10 -4
- package/dist/types/store/optimistic.d.ts +3 -2
- package/dist/types/store/projection.d.ts +4 -3
- package/dist/types/store/store.d.ts +4 -39
- package/dist/types/store/target.d.ts +16 -8
- package/dist/types/store/types.d.ts +14 -0
- package/package.json +1 -1
|
@@ -20,6 +20,13 @@ export interface Link {
|
|
|
20
20
|
export interface NodeOptions<T> {
|
|
21
21
|
id?: string;
|
|
22
22
|
name?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Source location (`file:line:col`, root-relative) written by the
|
|
25
|
+
* compiler's `sourceNames` `locations` kind; dev and observe builds keep it
|
|
26
|
+
* for console reports and diagnostic events, production ignores it. Not
|
|
27
|
+
* meant to be written by hand.
|
|
28
|
+
*/
|
|
29
|
+
loc?: string;
|
|
23
30
|
transparent?: boolean;
|
|
24
31
|
equals?: ((prev: T, next: T) => boolean) | false;
|
|
25
32
|
ownedWrite?: boolean;
|
|
@@ -86,12 +93,6 @@ export interface NodeExtension {
|
|
|
86
93
|
/** L2 — the transaction holding this node while CONFIG_HELD is set
|
|
87
94
|
* (`holdNode`); resolved through merges by `txOf`. */
|
|
88
95
|
_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
96
|
/** The node's current flight re-asks the same question (a `refresh()`,
|
|
96
97
|
* A19 exc. 2 / A24): verdict-quiet — `isPending` reads false for it —
|
|
97
98
|
* through its landing until the commit. */
|
|
@@ -114,6 +115,11 @@ export interface NodeExtension {
|
|
|
114
115
|
* changes — `isPending` reads true for it and its derivations while any
|
|
115
116
|
* is live. A count, never a hold. */
|
|
116
117
|
_marks: number;
|
|
118
|
+
/** D-41: the error a node showed when a re-ask made it pending — still
|
|
119
|
+
* the display (D-39) until a new answer commits: an untracked read throws
|
|
120
|
+
* it, `isPending` reads a staged answer as a change over it, and a
|
|
121
|
+
* recovery equal to the last good value is still a new answer. */
|
|
122
|
+
_shownError: unknown;
|
|
117
123
|
}
|
|
118
124
|
export interface RawSignal<T> {
|
|
119
125
|
_subs: Link | null;
|
|
@@ -147,6 +153,8 @@ export type Signal<T> = RawSignal<T>;
|
|
|
147
153
|
export interface Owner {
|
|
148
154
|
id?: string;
|
|
149
155
|
_config: number;
|
|
156
|
+
/** Lifecycle flags (REACTIVE_*); roots carry only REACTIVE_DISPOSED. */
|
|
157
|
+
_flags: number;
|
|
150
158
|
_snapshotScope?: boolean;
|
|
151
159
|
/** Effect-returned cleanup; managed across reruns, invoked at true disposal */
|
|
152
160
|
_cleanup?: () => void;
|
|
@@ -165,6 +173,13 @@ export interface Owner {
|
|
|
165
173
|
* (`<App>`). A slot in the observe/dev literals; absent from prod.
|
|
166
174
|
*/
|
|
167
175
|
_name?: string;
|
|
176
|
+
/**
|
|
177
|
+
* Observe-tier source location (`file:line:col`): the `loc` option, or
|
|
178
|
+
* the JSX site the rendering layer writes on a component root. A slot
|
|
179
|
+
* beside `_name`; absent from prod. Reserved from property mangling, like
|
|
180
|
+
* `_name`, because solid-js writes it and the core's diagnostics read it.
|
|
181
|
+
*/
|
|
182
|
+
_loc?: string;
|
|
168
183
|
}
|
|
169
184
|
export interface Computed<T> extends RawSignal<T>, Owner {
|
|
170
185
|
_deps: Link | null;
|
|
@@ -2,4 +2,36 @@
|
|
|
2
2
|
* restores the dispatch it found — none inside a memo's pass a window
|
|
3
3
|
* pulled (`verdictValue`). */
|
|
4
4
|
export declare function latest<T>(fn: () => T): T;
|
|
5
|
+
/**
|
|
6
|
+
* Reports whether what `fn` reads is still waiting on an update. Read the
|
|
7
|
+
* values in question inside `fn`: the probe answers `true` while any of
|
|
8
|
+
* them depends on a change that is in flight — a write or an async source
|
|
9
|
+
* that has started producing a new value whose result has not landed yet —
|
|
10
|
+
* and `false` once the latest value is the one on screen. The answer is
|
|
11
|
+
* tracked like any read, so a memo or effect that calls `isPending` re-runs
|
|
12
|
+
* when it flips.
|
|
13
|
+
*
|
|
14
|
+
* A read that has no value yet is loading, not pending: inside `fn` it
|
|
15
|
+
* follows the surrounding `Loading` path like any other read, and the probe
|
|
16
|
+
* reports only updates to a value that already exists. A bare `refresh()`
|
|
17
|
+
* does not flip `isPending`; pair it with `affects()` to make the re-ask
|
|
18
|
+
* visible.
|
|
19
|
+
*
|
|
20
|
+
* @param fn expression to probe; read the values in question inside it
|
|
21
|
+
*
|
|
22
|
+
* @returns `true` while a read inside `fn` depends on a change that has not committed yet
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* const [query, setQuery] = createSignal("");
|
|
27
|
+
* const results = createMemo(() => searchProducts(query()));
|
|
28
|
+
* const stale = createMemo(() => isPending(results));
|
|
29
|
+
*
|
|
30
|
+
* setQuery("shoes");
|
|
31
|
+
* // stale() is true until the new results land, while results() keeps
|
|
32
|
+
* // serving the previous list — dim it instead of showing a spinner.
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @description https://v2.solidjs.com/reference/solid-js/reactivity/is-pending
|
|
36
|
+
*/
|
|
5
37
|
export declare function isPending(fn: () => any): boolean;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type MemoOptions, type SourceAccessor } from "./signals.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates an async memo that may lag, but never leads. Before its first
|
|
4
|
+
* answer it is an ordinary async memo: readers suspend to the nearest
|
|
5
|
+
* `<Loading>`. After it, a refetch holds nothing: readers keep the last
|
|
6
|
+
* committed value until the new one lands, and the rest of the screen moves
|
|
7
|
+
* on without it. `isPending` reports the refetch, on the node and on what
|
|
8
|
+
* derives from it. Use it for independent widgets (dashboards, feeds,
|
|
9
|
+
* search results) where the previous answer with a "refreshing" indicator is
|
|
10
|
+
* better than waiting with everything else.
|
|
11
|
+
*
|
|
12
|
+
* - It never shows a value ahead of a held change: a refetch that read a
|
|
13
|
+
* held value lands with that hold.
|
|
14
|
+
* - A rejected refetch errors like any memo; the stale value never masks it.
|
|
15
|
+
* - `refresh(d)` is a quiet re-ask, and `await refresh(d)` and `until`
|
|
16
|
+
* wait for the landing rather than the stale value.
|
|
17
|
+
* - Combine with `loadingValue` for a node that never suspends at all.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* const rows = createDeferred(() => fetchRows(store.period));
|
|
22
|
+
*
|
|
23
|
+
* <section class={{ stale: isPending(() => rows()) }}>
|
|
24
|
+
* <For each={rows()}>{row => <Row row={row} />}</For>
|
|
25
|
+
* </section>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function createDeferred<T>(fn: (prev?: T) => T | PromiseLike<T> | AsyncIterable<T>, options?: MemoOptions<T>): SourceAccessor<T>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -5,6 +5,11 @@ export { $REFRESH, action, ContextNotFoundError, NoOwnerError, NotReadyError, Ti
|
|
|
5
5
|
* outside dev builds.
|
|
6
6
|
*/
|
|
7
7
|
export { setConsoleFooter } from "./core/index.js";
|
|
8
|
+
/** @internal The pre-write hook (`setWriteHook` in core/core.ts); the server-components client's deferred hydration. */
|
|
9
|
+
/** @internal Plain-signal identities and the dev read watch (dependency edges; the server-components client). */
|
|
10
|
+
export { setWriteHook, setSignalIdentities, setReadWatch, signalName } from "./core/index.js";
|
|
11
|
+
/** @internal Store dependency edges: the name a store proxy's writes go by (the server-components client). */
|
|
12
|
+
export { storeName } from "./store/edges.js";
|
|
8
13
|
import { type Dev, type Observe } from "./core/index.js";
|
|
9
14
|
/**
|
|
10
15
|
* Observe tier (diagnostics channel, attribution hook slot + interaction
|
|
@@ -20,6 +25,7 @@ export type { Truthy, UntilOptions, Accessor, SourceAccessor, Setter, Signal, Co
|
|
|
20
25
|
export { mapArray, repeat, type Maybe } from "./map.js";
|
|
21
26
|
export * from "./store/index.js";
|
|
22
27
|
export { affects } from "./affects.js";
|
|
28
|
+
export { createDeferred } from "./deferred.js";
|
|
23
29
|
export { flatten } from "./flatten.js";
|
|
24
30
|
export { createLoadingBoundary, createErrorBoundary } from "./boundaries.js";
|
|
25
31
|
export { createRevealOrder, type RevealOrder } from "./reveal.js";
|
package/dist/types/map.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export type Maybe<T> = T | void | null | undefined | false;
|
|
|
30
30
|
* );
|
|
31
31
|
* ```
|
|
32
32
|
*
|
|
33
|
-
* @description https://
|
|
33
|
+
* @description https://v2.solidjs.com/reference/solid-js/advanced/jsx-component-primitives/map-array
|
|
34
34
|
*/
|
|
35
35
|
export declare function mapArray<Item, MappedItem>(list: Accessor<Maybe<readonly Item[]>>, map: (value: Item, index: Accessor<number>) => MappedItem, options?: {
|
|
36
36
|
keyed?: true;
|
|
@@ -62,7 +62,7 @@ export declare function __smallMoveHits(): number;
|
|
|
62
62
|
* const view = repeat(count, i => `Item ${i}`, { fallback: () => "empty" });
|
|
63
63
|
* ```
|
|
64
64
|
*
|
|
65
|
-
* @description https://
|
|
65
|
+
* @description https://v2.solidjs.com/reference/solid-js/advanced/jsx-component-primitives/repeat
|
|
66
66
|
*/
|
|
67
67
|
export declare function repeat(count: Accessor<number>, map: (index: number) => any, options?: {
|
|
68
68
|
from?: Accessor<number | undefined>;
|
package/dist/types/signals.d.ts
CHANGED
|
@@ -92,6 +92,13 @@ export type EffectBundle<Prev, Next extends Prev = Prev> = {
|
|
|
92
92
|
interface BaseEffectOptions {
|
|
93
93
|
/** Debug name (dev mode only) */
|
|
94
94
|
name?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Source location (`file:line:col`, root-relative) written by the
|
|
97
|
+
* compiler's `sourceNames` `locations` kind beside `name`; dev and observe
|
|
98
|
+
* builds keep it for console reports and diagnostic events, production
|
|
99
|
+
* ignores it. Not meant to be written by hand.
|
|
100
|
+
*/
|
|
101
|
+
loc?: string;
|
|
95
102
|
}
|
|
96
103
|
/** Options for effect primitives that support deferring/scheduling their initial run (`createEffect`, `createRenderEffect`, `createReaction`). */
|
|
97
104
|
export interface EffectOptions extends BaseEffectOptions {
|
|
@@ -144,6 +151,13 @@ export interface EffectOptions extends BaseEffectOptions {
|
|
|
144
151
|
export interface SignalOptions<T> {
|
|
145
152
|
/** Debug name (dev mode only) */
|
|
146
153
|
name?: string;
|
|
154
|
+
/**
|
|
155
|
+
* Source location (`file:line:col`, root-relative) written by the
|
|
156
|
+
* compiler's `sourceNames` `locations` kind beside `name`; dev and observe
|
|
157
|
+
* builds keep it for console reports and diagnostic events, production
|
|
158
|
+
* ignores it. Not meant to be written by hand.
|
|
159
|
+
*/
|
|
160
|
+
loc?: string;
|
|
147
161
|
/**
|
|
148
162
|
* Custom equality function, or `false` to always notify subscribers.
|
|
149
163
|
* Defaults to reference equality (`isEqual`). Pass a comparator (e.g.
|
|
@@ -166,6 +180,13 @@ export interface MemoOptions<T> {
|
|
|
166
180
|
id?: string;
|
|
167
181
|
/** Debug name (dev mode only) */
|
|
168
182
|
name?: string;
|
|
183
|
+
/**
|
|
184
|
+
* Source location (`file:line:col`, root-relative) written by the
|
|
185
|
+
* compiler's `sourceNames` `locations` kind beside `name`; dev and observe
|
|
186
|
+
* builds keep it for console reports and diagnostic events, production
|
|
187
|
+
* ignores it. Not meant to be written by hand.
|
|
188
|
+
*/
|
|
189
|
+
loc?: string;
|
|
169
190
|
/**
|
|
170
191
|
* Advanced (integration tier). When true, the memo is invisible to the
|
|
171
192
|
* hydration id scheme: it inherits its parent's id instead of consuming a
|
|
@@ -275,7 +296,7 @@ export type NoInfer<T extends any> = [T][T extends any ? 0 : never];
|
|
|
275
296
|
* setUser({ ...user(), name: "Alice" });
|
|
276
297
|
* ```
|
|
277
298
|
*
|
|
278
|
-
* @description https://
|
|
299
|
+
* @description https://v2.solidjs.com/reference/solid-js/reactivity/create-signal
|
|
279
300
|
*/
|
|
280
301
|
export declare function createSignal<T>(): Signal<T | undefined>;
|
|
281
302
|
export declare function createSignal<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
|
|
@@ -296,7 +317,7 @@ export declare function createSignal<T>(fn: ComputeFunction<T>, options?: Signal
|
|
|
296
317
|
* const [state, setState] = createOptimistic<T>(fn, options?: SignalOptions<T> & MemoOptions<T>);
|
|
297
318
|
* ```
|
|
298
319
|
*
|
|
299
|
-
* @description https://
|
|
320
|
+
* @description https://v2.solidjs.com/reference/solid-js/reactivity/create-optimistic
|
|
300
321
|
*/
|
|
301
322
|
export declare function createOptimistic<T>(): Signal<T | undefined>;
|
|
302
323
|
export declare function createOptimistic<T>(value: Exclude<T, Function>, options?: SignalOptions<T>): Signal<T>;
|
|
@@ -329,7 +350,7 @@ export declare function createOptimistic<T>(fn: ComputeFunction<T>, options?: Si
|
|
|
329
350
|
* });
|
|
330
351
|
* ```
|
|
331
352
|
*
|
|
332
|
-
* @description https://
|
|
353
|
+
* @description https://v2.solidjs.com/reference/solid-js/reactivity/create-memo
|
|
333
354
|
*/
|
|
334
355
|
export declare function createMemo<T>(compute: ComputeFunction<NoInfer<T>, T>, options: MemoOptions<T> & {
|
|
335
356
|
loadingValue: T;
|
|
@@ -401,7 +422,7 @@ export declare function createMemo<T>(compute: ComputeFunction<undefined | NoInf
|
|
|
401
422
|
* );
|
|
402
423
|
* ```
|
|
403
424
|
*
|
|
404
|
-
* @description https://
|
|
425
|
+
* @description https://v2.solidjs.com/reference/solid-js/reactivity/create-effect
|
|
405
426
|
*/
|
|
406
427
|
export declare function createEffect<const T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, effectFn: EffectFunction<NoInfer<T>, T> | EffectBundle<NoInfer<T>, T>, options?: EffectOptions): void;
|
|
407
428
|
/**
|
|
@@ -431,7 +452,7 @@ export declare function createEffect<const T>(compute: ComputeFunction<undefined
|
|
|
431
452
|
* }
|
|
432
453
|
* ```
|
|
433
454
|
*
|
|
434
|
-
* @description https://
|
|
455
|
+
* @description https://v2.solidjs.com/reference/solid-js/advanced/specialized-reactivity/create-render-effect
|
|
435
456
|
*/
|
|
436
457
|
export declare function createRenderEffect<const T>(compute: ComputeFunction<undefined | NoInfer<T>, T>, effectFn: EffectFunction<NoInfer<T>, T>, options?: EffectOptions): void;
|
|
437
458
|
/**
|
|
@@ -477,7 +498,7 @@ export declare function createRenderEffect<const T>(compute: ComputeFunction<und
|
|
|
477
498
|
* });
|
|
478
499
|
* ```
|
|
479
500
|
*
|
|
480
|
-
* @description https://
|
|
501
|
+
* @description https://v2.solidjs.com/reference/solid-js/advanced/specialized-reactivity/create-tracked-effect
|
|
481
502
|
*/
|
|
482
503
|
export declare function createTrackedEffect(compute: () => void | (() => void), options?: BaseEffectOptions): void;
|
|
483
504
|
/**
|
|
@@ -504,7 +525,7 @@ export declare function createTrackedEffect(compute: () => void | (() => void),
|
|
|
504
525
|
* setCount(1); // logs once, reaction re-armed for next change
|
|
505
526
|
* ```
|
|
506
527
|
*
|
|
507
|
-
* @description https://
|
|
528
|
+
* @description https://v2.solidjs.com/reference/solid-js/advanced/specialized-reactivity/create-reaction
|
|
508
529
|
*/
|
|
509
530
|
export declare function createReaction(effectFn: EffectFunction<undefined> | EffectBundle<undefined>, options?: EffectOptions): (tracking: () => void) => void;
|
|
510
531
|
/**
|
|
@@ -1 +1,12 @@
|
|
|
1
|
+
import type { Computed, Signal } from "../core/types.js";
|
|
2
|
+
import { type StoreTarget } from "./target.js";
|
|
3
|
+
type Marked = Signal<any> | Computed<any>;
|
|
4
|
+
/** The nodes an `affects(store[, key])` declaration marks (affects.ts
|
|
5
|
+
* registers each). */
|
|
6
|
+
export declare function storeMarks(t: StoreTarget, key: PropertyKey | undefined): Marked[];
|
|
7
|
+
/** `affects()` calls it before a store-targeted declaration (idempotent). */
|
|
8
|
+
export declare function installStoreAffects(): void;
|
|
9
|
+
/** The carrier's last mark released (affects.ts): its scope dies, and the
|
|
10
|
+
* nodes that inherited the mark release theirs. */
|
|
11
|
+
export declare function releaseMarkScope(carrier: Marked): void;
|
|
1
12
|
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal The name of the store `x` belongs to — `x` a store proxy (a
|
|
3
|
+
* setter's entry) or one of its property nodes (the setter notifying it) —
|
|
4
|
+
* or undefined when it has none or it cannot be placed: a projection or
|
|
5
|
+
* optimistic family, a store chained over another store's proxy, a root
|
|
6
|
+
* named twice, or a proxy reached through a store other than the one it
|
|
7
|
+
* was named as the root of.
|
|
8
|
+
*/
|
|
9
|
+
export declare function storeName(x: object | undefined): string | undefined;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Store — the engine's optional-machinery slots, in a module of their own so
|
|
3
|
+
* an installer reaches them without importing store.ts (whose top level
|
|
4
|
+
* installs the engine): the store half of `affects()` installs through here
|
|
5
|
+
* from `affects()`, and an app without stores carries none of the engine.
|
|
6
|
+
* A slot no installer reaches stays `null`, and a bundler folds its sites.
|
|
7
|
+
*/
|
|
8
|
+
import type { Signal } from "../core/types.js";
|
|
9
|
+
import type { StoreTarget } from "./target.js";
|
|
10
|
+
/** The optimistic machinery (optimistic.ts, S4), installed when it loads
|
|
11
|
+
* — a plain store pays nothing for it (#2883): the plain paths reach it
|
|
12
|
+
* only through a family with `opt` set, which only `createOptimisticStore`
|
|
13
|
+
* sets. */
|
|
14
|
+
export interface OptHooks {
|
|
15
|
+
/** A user setter's draft on an optimistic family: a clone of the
|
|
16
|
+
* writer's view (a staging already on the target is set aside). */
|
|
17
|
+
draft(t: StoreTarget): Record<PropertyKey, any>;
|
|
18
|
+
/** The setter's exit: the draft becomes guesses; returns the staging the
|
|
19
|
+
* draft set aside (`null`: none). */
|
|
20
|
+
writes(t: StoreTarget, pb: Record<PropertyKey, any>): Record<PropertyKey, any> | null;
|
|
21
|
+
/** `src` with the lanes' values over it (`writer`: the next write's base
|
|
22
|
+
* — the unflushed guesses too). */
|
|
23
|
+
view(t: StoreTarget, src: Record<PropertyKey, any>, writer?: boolean): Record<PropertyKey, any>;
|
|
24
|
+
/** An untracked `key in store`: the presence guess, or `undefined`. */
|
|
25
|
+
has(t: StoreTarget, key: PropertyKey): boolean | undefined;
|
|
26
|
+
/** A guessed key's descriptor (`null`: removed; `undefined`: no guess). */
|
|
27
|
+
descriptor(t: StoreTarget, key: PropertyKey): PropertyDescriptor | null | undefined;
|
|
28
|
+
/** The flush's commit: targets no lane holds leave `overlaid`. */
|
|
29
|
+
sweep(): void;
|
|
30
|
+
/** The container comparator's lane arm: an arrangement guess against a
|
|
31
|
+
* landing (or another arrangement), by row identity. */
|
|
32
|
+
arrangement(t: StoreTarget, a: any, b: any): boolean;
|
|
33
|
+
/** A user's `reconcile` on an optimistic family: the keyed diff written
|
|
34
|
+
* into the draft. */
|
|
35
|
+
reconcile(draft: any, incoming: any, keyFn: ((item: any) => any) | null): void;
|
|
36
|
+
}
|
|
37
|
+
export declare let optHooks: OptHooks | null;
|
|
38
|
+
export declare function installOptHooks(hooks: OptHooks): void;
|
|
39
|
+
/** The store half of `affects()` (store/affects.ts), installed by the first
|
|
40
|
+
* store-targeted declaration: a node born on a covered record inherits the
|
|
41
|
+
* live mark; an untracked verdict probe through a record with no node is
|
|
42
|
+
* witnessed. */
|
|
43
|
+
export interface AffectsHooks {
|
|
44
|
+
_born(t: StoreTarget, node: Signal<any>, key: PropertyKey): void;
|
|
45
|
+
_witness(t: StoreTarget, key: PropertyKey | undefined): void;
|
|
46
|
+
}
|
|
47
|
+
export declare let affectsHooks: AffectsHooks | null;
|
|
48
|
+
export declare function installAffectsHooks(hooks: AffectsHooks): void;
|
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
* (`createStore(fn, seed)`), projections, optimistic stores and reconcile
|
|
4
4
|
* return on later steps (plan sec. 31.5).
|
|
5
5
|
*/
|
|
6
|
-
export type { NoFn, NotWrappable, ProjectionOptions, ProjectionStoreReturn, SolidStore, Store, StoreOptions, StoreReturn, StoreSetter } from "./types.js";
|
|
6
|
+
export type { NoArray, NoFn, NotWrappable, ProjectionOptions, ProjectionStoreReturn, SolidStore, Store, StoreOptions, StoreReturn, StoreSetter } from "./types.js";
|
|
7
7
|
export { $PROXY, $RECORD, $TARGET, $TRACK, isWrappable, markRaw } from "./types.js";
|
|
8
8
|
export { storeIsShallow, storeHasFamily, storeHasOptimisticFamily } from "./store.js";
|
|
9
9
|
export { storePath } from "./storePath.js";
|
|
10
10
|
export type { StorePathRange, PathSetter, Part, CustomPartial, ArrayFilterFn } from "./storePath.js";
|
|
11
|
-
import "./affects.js";
|
|
12
11
|
import { createOptimisticStore } from "./optimistic.js";
|
|
13
12
|
import { createProjection } from "./projection.js";
|
|
14
|
-
import type { NoFn, ProjectionOptions, ProjectionStoreReturn, Store, StoreOptions, StoreReturn } from "./types.js";
|
|
13
|
+
import type { NoArray, NoFn, ProjectionOptions, ProjectionStoreReturn, Store, StoreOptions, StoreReturn } from "./types.js";
|
|
15
14
|
export { createOptimisticStore, createProjection };
|
|
16
15
|
/** The store's internal record behind a proxy (`store[$TARGET]`). Kept
|
|
17
16
|
* under `next`'s public name; its shape is the L2 target's (plan plan sec. 31–32:
|
|
@@ -24,9 +23,16 @@ export type { SourceKind } from "./utils.js";
|
|
|
24
23
|
* Create a reactive store: a proxy over plain data with fine-grained
|
|
25
24
|
* subscriptions per read path, written through its setter's draft — or, in
|
|
26
25
|
* the derived form, a projection with a setter.
|
|
26
|
+
*
|
|
27
|
+
* The derived form comes in two shapes. Seedless, `createStore(fn)`: `fn`
|
|
28
|
+
* takes no draft and every answer is a complete `T` (plain-object roots only;
|
|
29
|
+
* pass `undefined` for the seed to reach the options). Seeded,
|
|
30
|
+
* `createStore(fn, seed)`: the seed is a complete `T` the derive drafts
|
|
31
|
+
* against — `[]` for an array.
|
|
27
32
|
*/
|
|
28
33
|
export declare function createStore<T extends object = {}>(initialValue: NoFn<T>, options?: StoreOptions): StoreReturn<T>;
|
|
29
|
-
export declare function createStore<T extends object = {}>(fn: (
|
|
34
|
+
export declare function createStore<T extends object = {}>(fn: (() => T | Promise<T> | AsyncIterable<T>) & NoArray<T>, seed?: null, options?: Omit<ProjectionOptions, "seedLoadingValue">): ProjectionStoreReturn<T>;
|
|
35
|
+
export declare function createStore<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): ProjectionStoreReturn<T>;
|
|
30
36
|
/**
|
|
31
37
|
* A setter transform that reconciles `value` into the store by key
|
|
32
38
|
* (`"id"` by default; `null` positional), preserving store identity for
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Refreshable } from "../core/index.js";
|
|
2
2
|
import { type StoreTarget } from "./target.js";
|
|
3
|
-
import { type NoFn, type ProjectionOptions, type Store, type StoreOptions, type StoreSetter } from "./types.js";
|
|
3
|
+
import { type NoArray, type NoFn, type ProjectionOptions, type Store, type StoreOptions, type StoreSetter } from "./types.js";
|
|
4
4
|
export declare function notifyOptimisticWrites(t: StoreTarget, pb: Record<PropertyKey, any>): Record<PropertyKey, any> | null;
|
|
5
5
|
export declare function sweepOverlaid(): void;
|
|
6
6
|
/** An untracked `key in store` on an optimistic family: the presence guess
|
|
@@ -20,4 +20,5 @@ export declare function optimisticView(t: StoreTarget, src: Record<PropertyKey,
|
|
|
20
20
|
* guess is what lands). */
|
|
21
21
|
export declare function latestView(t: StoreTarget, src: Record<PropertyKey, any>): Record<PropertyKey, any>;
|
|
22
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: (
|
|
23
|
+
export declare function createOptimisticStore<T extends object = {}>(fn: (() => T | Promise<T> | AsyncIterable<T>) & NoArray<T>, seed?: null, options?: Omit<ProjectionOptions, "seedLoadingValue">): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
|
|
24
|
+
export declare function createOptimisticStore<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): [get: Refreshable<Store<T>>, set: StoreSetter<T>];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Computed } from "../core/types.js";
|
|
2
2
|
import type { Refreshable } from "../core/index.js";
|
|
3
|
-
import { type NoFn, type ProjectionOptions, type Store } from "./types.js";
|
|
3
|
+
import { type NoArray, type NoFn, type ProjectionOptions, type Store } from "./types.js";
|
|
4
4
|
/** The derive's pass: run `fn` against a draft of the store; commit its
|
|
5
5
|
* result (sync, or each async landing) through the reconcile channel.
|
|
6
6
|
* Draft validity is per run (R37): live from here until the NEXT run starts
|
|
@@ -13,6 +13,7 @@ export declare function runProjectionComputed<T extends object>(wrappedStore: St
|
|
|
13
13
|
* firewall). `fn` may be async or an async iterator; the seed is a draft,
|
|
14
14
|
* never an observable value, until the first landing (A25).
|
|
15
15
|
*/
|
|
16
|
-
export declare function createProjection<T extends object = {}>(fn: (
|
|
16
|
+
export declare function createProjection<T extends object = {}>(fn: (() => T | Promise<T> | AsyncIterable<T>) & NoArray<T>, seed?: null, options?: Omit<ProjectionOptions, "seedLoadingValue">): Refreshable<Store<T>>;
|
|
17
|
+
export declare function createProjection<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: NoFn<T> | Store<NoFn<T>>, options?: ProjectionOptions): Refreshable<Store<T>>;
|
|
17
18
|
/** `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:
|
|
19
|
+
export declare function createStoreDerived<T extends object = {}>(fn: (draft: T) => void | T | Promise<void | T> | AsyncIterable<void | T>, seed: T | null | undefined, options?: ProjectionOptions): [Refreshable<Store<T>>, (f: (draft: T) => T | void) => void];
|
|
@@ -1,43 +1,5 @@
|
|
|
1
1
|
import type { Signal } from "../core/types.js";
|
|
2
2
|
import { type StoreFamily, type StoreTarget } from "./target.js";
|
|
3
|
-
/** The optimistic machinery (optimistic.ts, S4), installed when it loads
|
|
4
|
-
* — a plain store pays nothing for it (#2883): the plain paths reach it
|
|
5
|
-
* only through a family with `opt` set, which only `createOptimisticStore`
|
|
6
|
-
* sets. */
|
|
7
|
-
export interface OptHooks {
|
|
8
|
-
/** A user setter's draft on an optimistic family: a clone of the
|
|
9
|
-
* writer's view (a staging already on the target is set aside). */
|
|
10
|
-
draft(t: StoreTarget): Record<PropertyKey, any>;
|
|
11
|
-
/** The setter's exit: the draft becomes guesses; returns the staging the
|
|
12
|
-
* draft set aside (`null`: none). */
|
|
13
|
-
writes(t: StoreTarget, pb: Record<PropertyKey, any>): Record<PropertyKey, any> | null;
|
|
14
|
-
/** `src` with the lanes' values over it (`writer`: the next write's base
|
|
15
|
-
* — the unflushed guesses too). */
|
|
16
|
-
view(t: StoreTarget, src: Record<PropertyKey, any>, writer?: boolean): Record<PropertyKey, any>;
|
|
17
|
-
/** An untracked `key in store`: the presence guess, or `undefined`. */
|
|
18
|
-
has(t: StoreTarget, key: PropertyKey): boolean | undefined;
|
|
19
|
-
/** A guessed key's descriptor (`null`: removed; `undefined`: no guess). */
|
|
20
|
-
descriptor(t: StoreTarget, key: PropertyKey): PropertyDescriptor | null | undefined;
|
|
21
|
-
/** The flush's commit: targets no lane holds leave `overlaid`. */
|
|
22
|
-
sweep(): void;
|
|
23
|
-
/** The container comparator's lane arm: an arrangement guess against a
|
|
24
|
-
* landing (or another arrangement), by row identity. */
|
|
25
|
-
arrangement(t: StoreTarget, a: any, b: any): boolean;
|
|
26
|
-
/** A user's `reconcile` on an optimistic family: the keyed diff written
|
|
27
|
-
* into the draft. */
|
|
28
|
-
reconcile(draft: any, incoming: any, keyFn: ((item: any) => any) | null): void;
|
|
29
|
-
}
|
|
30
|
-
export declare let optHooks: OptHooks | null;
|
|
31
|
-
export declare function installOptHooks(hooks: OptHooks): void;
|
|
32
|
-
/** The store half of `affects()` (store/affects.ts), installed with the
|
|
33
|
-
* stores: a node born on a covered record inherits the live mark; an
|
|
34
|
-
* untracked verdict probe through a record with no node is witnessed. */
|
|
35
|
-
export interface AffectsHooks {
|
|
36
|
-
born(t: StoreTarget, node: Signal<any>, key: PropertyKey): void;
|
|
37
|
-
witness(t: StoreTarget, key: PropertyKey | undefined): void;
|
|
38
|
-
}
|
|
39
|
-
export declare let affectsHooks: AffectsHooks | null;
|
|
40
|
-
export declare function installAffectsHooks(hooks: AffectsHooks): void;
|
|
41
3
|
import { type StoreOptions } from "./types.js";
|
|
42
4
|
export { $PROXY, $TARGET, $TRACK, markRaw } from "./types.js";
|
|
43
5
|
export type SetStoreFunction<T> = (fn: (draft: T) => T | void) => void;
|
|
@@ -84,7 +46,7 @@ export declare function getHasNode(target: StoreTarget, key: PropertyKey): Signa
|
|
|
84
46
|
* committed backing. */
|
|
85
47
|
export declare function getContainerNode(target: StoreTarget): Signal<any>;
|
|
86
48
|
export declare function bumpDeep(t: StoreTarget): void;
|
|
87
|
-
export declare function nameStore(proxy: any, name: string | undefined): void;
|
|
49
|
+
export declare function nameStore(proxy: any, name: string | undefined, loc?: string): void;
|
|
88
50
|
/** Shallow clone into store ownership. Plain data (grade 2) spreads; anything
|
|
89
51
|
* else copies descriptors (accessors kept, everything made configurable). */
|
|
90
52
|
export declare function cloneRaw(source: Record<PropertyKey, any>, t: StoreTarget): Record<PropertyKey, any>;
|
|
@@ -145,6 +107,9 @@ export declare function notifyFold(t: StoreTarget, old: Record<PropertyKey, any>
|
|
|
145
107
|
* "adoption is eager by contract" — and the node keeps the frame committed
|
|
146
108
|
* readers under a hold still see), `t.v` otherwise. */
|
|
147
109
|
export declare function committed(t: StoreTarget): Record<PropertyKey, any>;
|
|
110
|
+
/** The same row at a slot, as the adoption pairs rows (reconcile.ts): two
|
|
111
|
+
* objects whose keys agree — positionally for an unkeyed family. */
|
|
112
|
+
export declare function sameRow(pv: any, nv: any, keyFn: ((item: any) => any) | null): boolean;
|
|
148
113
|
/** A chained backing's child (§7b): a raw the inner family owns, or holds
|
|
149
114
|
* at this key, is served as the inner store's wrapper — never a fresh
|
|
150
115
|
* raw-keyed one — so the chained targets are the same objects across
|
|
@@ -42,6 +42,11 @@ export interface StoreFamily {
|
|
|
42
42
|
* (`settleFamily`). A sync commit with no wake behind it walks nothing. */
|
|
43
43
|
woke?: boolean;
|
|
44
44
|
}
|
|
45
|
+
/** One setter's written keys; `u` is the batch's earlier setters' (the
|
|
46
|
+
* fold's union), present only once a second setter writes the target. */
|
|
47
|
+
export interface WrittenKeys extends Set<PropertyKey> {
|
|
48
|
+
u?: WrittenKeys;
|
|
49
|
+
}
|
|
45
50
|
export interface StoreTarget {
|
|
46
51
|
/** Committed backing: source object (shared) or owned clone. */
|
|
47
52
|
v: Record<PropertyKey, any>;
|
|
@@ -59,19 +64,22 @@ export interface StoreTarget {
|
|
|
59
64
|
/** Lazy CONTAINER node: membership/iteration/`$TRACK`/`length`
|
|
60
65
|
* subscriptions (§6) and the backing's staging home (plan sec. 31.3). */
|
|
61
66
|
k: Signal<any> | null;
|
|
62
|
-
/** Keys written through the traps
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
67
|
+
/** Keys written through the traps by the current setter, with the earlier
|
|
68
|
+
* setters' of the batch chained behind (`u`) until the fold commit. Bounds
|
|
69
|
+
* the setter notify/hold-check to O(written) instead of O(subscribed
|
|
70
|
+
* nodes) — a record with thousands of per-key subscriptions (selection
|
|
71
|
+
* maps) would otherwise pay a full node scan on every write — and to THIS
|
|
72
|
+
* setter's keys (D-8: a key an earlier setter of the batch wrote is told
|
|
73
|
+
* once, #3743). null = no trap writes this batch (bulk paths fall back to
|
|
74
|
+
* the full scan); WK_ALL = bound unusable (array length write).
|
|
75
|
+
* LOAD-BEARING SHAPE RULE: array proxy targets carry their fields as named
|
|
76
|
+
* properties on a real array, and V8
|
|
69
77
|
* normalizes an array to dictionary properties as the named count grows
|
|
70
78
|
* (empirically at counts ≡ 0 mod 3 from 18 up on V8 13.x) — every trap
|
|
71
79
|
* field read then becomes a hash lookup (~15% uibench, tree suites
|
|
72
80
|
* worst). Future write-side state MUST ride an extension object, not new
|
|
73
81
|
* named fields. */
|
|
74
|
-
wk:
|
|
82
|
+
wk: WrittenKeys | null;
|
|
75
83
|
/** Lazy deep-witness node: `deep()` subscribes ONE node per record instead
|
|
76
84
|
* of one per path; write paths bump it only when it exists. Separate from
|
|
77
85
|
* `k` so $TRACK/mapArray never rerun on leaf value changes (R9). */
|
|
@@ -34,6 +34,13 @@ export interface StoreOptions {
|
|
|
34
34
|
* projection node carries the name itself.
|
|
35
35
|
*/
|
|
36
36
|
name?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Source location (`file:line:col`, root-relative) written by the
|
|
39
|
+
* compiler's `sourceNames` `locations` kind; dev and observe builds keep it
|
|
40
|
+
* for console reports and diagnostic events, production ignores it. Not
|
|
41
|
+
* meant to be written by hand.
|
|
42
|
+
*/
|
|
43
|
+
loc?: string;
|
|
37
44
|
/** Single-layer store: root keys reactive, values raw records replaced by reference */
|
|
38
45
|
shallow?: boolean;
|
|
39
46
|
}
|
|
@@ -60,7 +67,14 @@ export interface ProjectionOptions extends StoreOptions {
|
|
|
60
67
|
*/
|
|
61
68
|
seedLoadingValue?: boolean;
|
|
62
69
|
}
|
|
70
|
+
/** @internal */
|
|
63
71
|
export type NoFn<T> = T extends Function ? never : T;
|
|
72
|
+
/**
|
|
73
|
+
* Rejects array roots on the seedless derived form: a store's root shape is
|
|
74
|
+
* fixed when it is created, and `[]` is already a complete seed for an array.
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
export type NoArray<T> = Extract<T, readonly unknown[]> extends never ? unknown : never;
|
|
64
78
|
/** Brand keys the proxy answers directly (never user data). */
|
|
65
79
|
export declare const $TRACK: unique symbol, $TARGET: unique symbol, $PROXY: unique symbol, $RECORD: unique symbol;
|
|
66
80
|
export declare namespace SolidStore {
|
package/package.json
CHANGED