@mmstack/primitives 21.2.0 → 21.2.2
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/README.md +49 -10
- package/fesm2022/mmstack-primitives.mjs +612 -355
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mmstack-primitives.d.ts +265 -117
package/package.json
CHANGED
|
@@ -1,7 +1,94 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { InjectionToken, Injector, CreateComputedOptions, Signal, EffectCleanupRegisterFn, CreateEffectOptions, EffectRef, CreateSignalOptions, WritableSignal, Provider, ValueEqualityFn, ResourceRef, DestroyRef, ElementRef } from '@angular/core';
|
|
3
3
|
import * as _mmstack_primitives from '@mmstack/primitives';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* How a pausable primitive decides whether it is currently paused:
|
|
7
|
+
* - omitted (the default) or `true` — read the ambient {@link PAUSED_CONTEXT} (via `injector`, or the
|
|
8
|
+
* current injection context). Reaching for a `pausable*` primitive means you want it pausable, so
|
|
9
|
+
* this is the default; outside an Activity boundary there's no `PAUSED_CONTEXT`, so the primitive is
|
|
10
|
+
* returned unwrapped (never pauses, zero overhead). On the server it never pauses either.
|
|
11
|
+
* - a predicate `() => boolean` — used directly. A `Signal<boolean>` satisfies this (signals are
|
|
12
|
+
* callable), and a plain function works OUTSIDE an injection context.
|
|
13
|
+
* - `false` — the explicit opt-out: the primitive is returned UNWRAPPED (no `linkedSignal`, no gate),
|
|
14
|
+
* i.e. exactly the plain primitive with zero overhead.
|
|
15
|
+
*/
|
|
16
|
+
type PauseOption = boolean | (() => boolean);
|
|
17
|
+
type PausableOptions = {
|
|
18
|
+
/** Pause source — see {@link PauseOption}. Defaults to `true` (read the ambient `PAUSED_CONTEXT`). */
|
|
19
|
+
readonly pause?: PauseOption;
|
|
20
|
+
/**
|
|
21
|
+
* Injector used to resolve {@link PAUSED_CONTEXT} when `pause` is `true`/omitted and the primitive
|
|
22
|
+
* is created outside an injection context. Ignored for the `false` / predicate forms.
|
|
23
|
+
*/
|
|
24
|
+
readonly injector?: Injector;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* @internal Token carrying an app-wide default {@link PauseOption}, set via
|
|
28
|
+
* {@link providePausableOptions}. {@link resolvePause} consults it when the call site didn't
|
|
29
|
+
* specify `pause`, so users can opt every pausable-aware primitive in (or out) from one place.
|
|
30
|
+
*/
|
|
31
|
+
declare const PAUSABLE_OPTIONS: InjectionToken<{
|
|
32
|
+
pause?: PauseOption;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Provides an app-wide default {@link PauseOption} for every pausable-aware primitive (the public
|
|
36
|
+
* `pausable*` family plus the opt-in integrations like `stored` / `chunked`). A call-site `pause`
|
|
37
|
+
* always wins; this only fills in when the call didn't specify one.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Make everything that can pause honour the ambient Activity boundary by default:
|
|
41
|
+
* providePausableOptions({ pause: true })
|
|
42
|
+
*/
|
|
43
|
+
declare function providePausableOptions(opt: {
|
|
44
|
+
/** Default pause source for pausable-aware primitives that don't set their own. */
|
|
45
|
+
pause?: PauseOption;
|
|
46
|
+
}): Provider;
|
|
47
|
+
/**
|
|
48
|
+
* Resolve a {@link PauseOption} into a pause predicate, or `null` meaning "do not pause".
|
|
49
|
+
* `null` tells the caller to return the bare primitive — no wrapper is created.
|
|
50
|
+
*
|
|
51
|
+
* - omitted/`true` → the ambient {@link PAUSED_CONTEXT} if an Activity boundary provides one (via
|
|
52
|
+
* `opt.injector` or the current injection context), else `null` (the bare primitive, no allocation).
|
|
53
|
+
* The default, because an explicit `pausable*` call wants to be pausable. An explicit `pause: true`
|
|
54
|
+
* with no boundary dev-warns; the omitted default stays quiet. SSR → `null`.
|
|
55
|
+
* - a function → returned as-is (covers `Signal<boolean>`; usable outside an injection context).
|
|
56
|
+
* SSR → `null` here too, detected via `opt.injector` if given, else a `globalThis.window` probe.
|
|
57
|
+
* - `false` → `null` (the explicit opt-out).
|
|
58
|
+
*
|
|
59
|
+
* Encapsulating this here keeps every pausable primitive's branching identical and in one place.
|
|
60
|
+
*/
|
|
61
|
+
declare function resolvePause(opt?: PausableOptions, defaultPause?: PauseOption): (() => boolean) | null;
|
|
62
|
+
/**
|
|
63
|
+
* Like {@link nestedEffect}, but pausable. While paused the effect does NOT run its body — and,
|
|
64
|
+
* crucially, it reads the pause predicate FIRST, so while paused its dependency set collapses to just
|
|
65
|
+
* the predicate (no churn from the real deps); on resume it re-runs and re-tracks. With no `pause`
|
|
66
|
+
* option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false` makes it a plain `nestedEffect`
|
|
67
|
+
* with zero added overhead.
|
|
68
|
+
*/
|
|
69
|
+
declare function pausableEffect(effectFn: (registerCleanup: EffectCleanupRegisterFn) => void, options?: CreateEffectOptions & PausableOptions): EffectRef;
|
|
70
|
+
/**
|
|
71
|
+
* Like `signal`, but pausable. While paused, READS hold the last value; writes still land on the
|
|
72
|
+
* underlying signal and surface on resume. Built on the `keepPrevious`/`hold` shape — a
|
|
73
|
+
* `linkedSignal` gated on the pause predicate, with `set`/`update` forwarded to the source signal.
|
|
74
|
+
* `asReadonly()` returns the held (gated) view, so both views of the signal agree while paused.
|
|
75
|
+
* With no `pause` option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false`
|
|
76
|
+
* makes it a plain `signal` — no `linkedSignal` is created.
|
|
77
|
+
*
|
|
78
|
+
* NOTE: while paused, `set(x)` followed by a read returns the *held* (pre-pause) value, not `x` — the
|
|
79
|
+
* write lands on the source and surfaces on resume. That is the "freeze the displayed value while
|
|
80
|
+
* hidden" semantics; do not rely on read-after-write while paused.
|
|
81
|
+
*/
|
|
82
|
+
declare function pausableSignal<T>(initialValue: T, options?: CreateSignalOptions<T> & PausableOptions): WritableSignal<T>;
|
|
83
|
+
/**
|
|
84
|
+
* Like `computed`, but pausable. While paused it holds its last value AND does not recompute: the
|
|
85
|
+
* computation's dependencies are not read while paused, so a dependency change can't trigger work —
|
|
86
|
+
* on resume it recomputes and re-tracks. The very first read always computes, to seed a value. With
|
|
87
|
+
* no `pause` option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false` makes it a plain
|
|
88
|
+
* `computed`.
|
|
89
|
+
*/
|
|
90
|
+
declare function pausableComputed<T>(computation: () => T, options?: CreateComputedOptions<T> & PausableOptions): Signal<T>;
|
|
91
|
+
|
|
5
92
|
type CreateChunkedOptions<T> = {
|
|
6
93
|
/**
|
|
7
94
|
* The number of items to process in each chunk.
|
|
@@ -21,6 +108,12 @@ type CreateChunkedOptions<T> = {
|
|
|
21
108
|
* An optional `Injector` to use for the internal effect. This allows the effect to have access to dependency injection if needed.
|
|
22
109
|
*/
|
|
23
110
|
injector?: Injector;
|
|
111
|
+
/**
|
|
112
|
+
* Opt-in pause: gate the chunk-scheduling effect on an ambient Activity boundary (`true`), a
|
|
113
|
+
* custom predicate, or `false` (default — no pausing). While paused, scheduling stops and resumes
|
|
114
|
+
* from the current chunk on resume. See {@link PauseOption}.
|
|
115
|
+
*/
|
|
116
|
+
pause?: PauseOption;
|
|
24
117
|
};
|
|
25
118
|
/**
|
|
26
119
|
* Creates a new `Signal` that processes an array of items in time-sliced chunks. This is useful for handling large lists without blocking the main thread.
|
|
@@ -56,6 +149,7 @@ declare class MmActivity {
|
|
|
56
149
|
private readonly tpl;
|
|
57
150
|
private readonly vcr;
|
|
58
151
|
private readonly parent;
|
|
152
|
+
private readonly onServer;
|
|
59
153
|
/** When false, keep the content mounted but hidden + CD-detached. */
|
|
60
154
|
readonly visible: i0.InputSignal<boolean>;
|
|
61
155
|
/** Paused == not visible — handed to the kept subtree as PAUSED_CONTEXT. */
|
|
@@ -94,72 +188,6 @@ declare function providePaused(source: Signal<boolean>): Provider;
|
|
|
94
188
|
*/
|
|
95
189
|
declare function holdUntilReady<T>(target: Signal<T>, ready: () => boolean): Signal<T>;
|
|
96
190
|
|
|
97
|
-
/**
|
|
98
|
-
* How a pausable primitive decides whether it is currently paused:
|
|
99
|
-
* - omitted (the default) or `true` — read the ambient {@link PAUSED_CONTEXT} (via `injector`, or the
|
|
100
|
-
* current injection context). Reaching for a `pausable*` primitive means you want it pausable, so
|
|
101
|
-
* this is the default; outside an Activity boundary there's no `PAUSED_CONTEXT`, so the primitive is
|
|
102
|
-
* returned unwrapped (never pauses, zero overhead). On the server it never pauses either.
|
|
103
|
-
* - a predicate `() => boolean` — used directly. A `Signal<boolean>` satisfies this (signals are
|
|
104
|
-
* callable), and a plain function works OUTSIDE an injection context.
|
|
105
|
-
* - `false` — the explicit opt-out: the primitive is returned UNWRAPPED (no `linkedSignal`, no gate),
|
|
106
|
-
* i.e. exactly the plain primitive with zero overhead.
|
|
107
|
-
*/
|
|
108
|
-
type PauseOption = boolean | (() => boolean);
|
|
109
|
-
type PausableOptions = {
|
|
110
|
-
/** Pause source — see {@link PauseOption}. Defaults to `true` (read the ambient `PAUSED_CONTEXT`). */
|
|
111
|
-
readonly pause?: PauseOption;
|
|
112
|
-
/**
|
|
113
|
-
* Injector used to resolve {@link PAUSED_CONTEXT} when `pause` is `true`/omitted and the primitive
|
|
114
|
-
* is created outside an injection context. Ignored for the `false` / predicate forms.
|
|
115
|
-
*/
|
|
116
|
-
readonly injector?: Injector;
|
|
117
|
-
};
|
|
118
|
-
/**
|
|
119
|
-
* Resolve a {@link PauseOption} into a pause predicate, or `null` meaning "do not pause".
|
|
120
|
-
* `null` tells the caller to return the bare primitive — no wrapper is created.
|
|
121
|
-
*
|
|
122
|
-
* - omitted/`true` → the ambient {@link PAUSED_CONTEXT} if an Activity boundary provides one (via
|
|
123
|
-
* `opt.injector` or the current injection context), else `null` (the bare primitive, no allocation).
|
|
124
|
-
* The default, because an explicit `pausable*` call wants to be pausable. An explicit `pause: true`
|
|
125
|
-
* with no boundary dev-warns; the omitted default stays quiet. SSR → `null`.
|
|
126
|
-
* - a function → returned as-is (covers `Signal<boolean>`; usable outside an injection context).
|
|
127
|
-
* SSR → `null` here too, detected via `opt.injector` if given, else a `globalThis.window` probe.
|
|
128
|
-
* - `false` → `null` (the explicit opt-out).
|
|
129
|
-
*
|
|
130
|
-
* Encapsulating this here keeps every pausable primitive's branching identical and in one place.
|
|
131
|
-
*/
|
|
132
|
-
declare function resolvePause(opt?: PausableOptions): (() => boolean) | null;
|
|
133
|
-
/**
|
|
134
|
-
* Like {@link nestedEffect}, but pausable. While paused the effect does NOT run its body — and,
|
|
135
|
-
* crucially, it reads the pause predicate FIRST, so while paused its dependency set collapses to just
|
|
136
|
-
* the predicate (no churn from the real deps); on resume it re-runs and re-tracks. With no `pause`
|
|
137
|
-
* option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false` makes it a plain `nestedEffect`
|
|
138
|
-
* with zero added overhead.
|
|
139
|
-
*/
|
|
140
|
-
declare function pausableEffect(effectFn: (registerCleanup: EffectCleanupRegisterFn) => void, options?: CreateEffectOptions & PausableOptions): EffectRef;
|
|
141
|
-
/**
|
|
142
|
-
* Like `signal`, but pausable. While paused, READS hold the last value; writes still land on the
|
|
143
|
-
* underlying signal and surface on resume. Built on the `keepPrevious`/`hold` shape — a
|
|
144
|
-
* `linkedSignal` gated on the pause predicate, with `set`/`update` forwarded to the source signal.
|
|
145
|
-
* `asReadonly()` returns the held (gated) view, so both views of the signal agree while paused.
|
|
146
|
-
* With no `pause` option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false`
|
|
147
|
-
* makes it a plain `signal` — no `linkedSignal` is created.
|
|
148
|
-
*
|
|
149
|
-
* NOTE: while paused, `set(x)` followed by a read returns the *held* (pre-pause) value, not `x` — the
|
|
150
|
-
* write lands on the source and surfaces on resume. That is the "freeze the displayed value while
|
|
151
|
-
* hidden" semantics; do not rely on read-after-write while paused.
|
|
152
|
-
*/
|
|
153
|
-
declare function pausableSignal<T>(initialValue: T, options?: CreateSignalOptions<T> & PausableOptions): WritableSignal<T>;
|
|
154
|
-
/**
|
|
155
|
-
* Like `computed`, but pausable. While paused it holds its last value AND does not recompute: the
|
|
156
|
-
* computation's dependencies are not read while paused, so a dependency change can't trigger work —
|
|
157
|
-
* on resume it recomputes and re-tracks. The very first read always computes, to seed a value. With
|
|
158
|
-
* no `pause` option it defaults to the ambient `PAUSED_CONTEXT`; `pause: false` makes it a plain
|
|
159
|
-
* `computed`.
|
|
160
|
-
*/
|
|
161
|
-
declare function pausableComputed<T>(computation: () => T, options?: CreateComputedOptions<T> & PausableOptions): Signal<T>;
|
|
162
|
-
|
|
163
191
|
/**
|
|
164
192
|
* Handle for an in-progress transition: a `pending` signal (true while the transition's
|
|
165
193
|
* resources are in flight) and a `done` promise that resolves once they all settle.
|
|
@@ -287,6 +315,12 @@ declare function registerResource<T extends ResourceRef<any>>(res: T, opt?: Regi
|
|
|
287
315
|
*
|
|
288
316
|
* `type` selects what "not ready" means: `'value'` (default) suspends only until a first value lands
|
|
289
317
|
* then holds through reloads; `'loading'` suspends on every in-flight load (strict suspense).
|
|
318
|
+
*
|
|
319
|
+
* SSR: the server serializes whatever the scope reports at stabilization, so a registered resource
|
|
320
|
+
* must keep the app unstable until it settles or the placeholder is what gets serialized (then
|
|
321
|
+
* flashes/mismatches on hydration). HttpClient-backed resources, httpResource & all of `@mmstack/resource`
|
|
322
|
+
* do this automatically via the HTTP layer's `PendingTasks` + transfer cache. A custom loader (raw
|
|
323
|
+
* `fetch`/promise/timer) must opt in itself: wrap it with `inject(PendingTasks).run(() => promise)`.
|
|
290
324
|
*/
|
|
291
325
|
declare abstract class SuspenseBoundaryBase {
|
|
292
326
|
protected readonly scope: _mmstack_primitives.TransitionScope;
|
|
@@ -1878,6 +1912,73 @@ type ScreenOrientation = ScreenOrientationState;
|
|
|
1878
1912
|
*/
|
|
1879
1913
|
declare function orientation(opt?: string | SensorRunOptions): Signal<ScreenOrientationState>;
|
|
1880
1914
|
|
|
1915
|
+
type PointerPoint = {
|
|
1916
|
+
x: number;
|
|
1917
|
+
y: number;
|
|
1918
|
+
};
|
|
1919
|
+
type PointerModifiers = {
|
|
1920
|
+
shift: boolean;
|
|
1921
|
+
alt: boolean;
|
|
1922
|
+
ctrl: boolean;
|
|
1923
|
+
meta: boolean;
|
|
1924
|
+
};
|
|
1925
|
+
type PointerDragState = {
|
|
1926
|
+
/** A gesture is past the activation threshold (distinguishes a drag from a click). */
|
|
1927
|
+
active: boolean;
|
|
1928
|
+
/** Pointer position at the pointerdown that began the gesture. */
|
|
1929
|
+
start: PointerPoint;
|
|
1930
|
+
/** Latest pointer position. */
|
|
1931
|
+
current: PointerPoint;
|
|
1932
|
+
/** `current - start`, computed on the same update as `current` (never torn). */
|
|
1933
|
+
delta: PointerPoint;
|
|
1934
|
+
/** The captured pointer id, or `null` when idle. */
|
|
1935
|
+
pointerId: number | null;
|
|
1936
|
+
/** Modifier keys at the latest update. */
|
|
1937
|
+
modifiers: PointerModifiers;
|
|
1938
|
+
/** Mouse button that started the gesture (`-1` when idle). */
|
|
1939
|
+
button: number;
|
|
1940
|
+
};
|
|
1941
|
+
type PointerDragOptions = SensorRunOptions & {
|
|
1942
|
+
/**
|
|
1943
|
+
* Element that receives `pointerdown`. An `HTMLElement`, `ElementRef`, or a
|
|
1944
|
+
* `Signal` of one (listeners re-attach when it changes). Defaults to the host
|
|
1945
|
+
* `ElementRef`.
|
|
1946
|
+
*/
|
|
1947
|
+
target?: HTMLElement | ElementRef<HTMLElement> | Signal<HTMLElement | ElementRef<HTMLElement> | null | undefined>;
|
|
1948
|
+
/** `'client'` (viewport) or `'page'` coordinates. @default 'client' */
|
|
1949
|
+
coordinateSpace?: 'client' | 'page';
|
|
1950
|
+
/** Pixels the pointer must travel before `active` flips true. @default 3 */
|
|
1951
|
+
activationThreshold?: number;
|
|
1952
|
+
/** Throttle (ms) for `current`/`delta` updates. @default 16 */
|
|
1953
|
+
throttle?: number;
|
|
1954
|
+
/** Only start when the pointerdown target matches this selector (delegated handles). */
|
|
1955
|
+
handleSelector?: string;
|
|
1956
|
+
/** Mouse buttons that may start a gesture. @default [0] (primary) */
|
|
1957
|
+
buttons?: number[];
|
|
1958
|
+
};
|
|
1959
|
+
/** A gesture signal with an `unthrottled` view and an imperative `cancel()`. */
|
|
1960
|
+
type PointerDragSignal = Signal<PointerDragState> & {
|
|
1961
|
+
readonly unthrottled: Signal<PointerDragState>;
|
|
1962
|
+
/** Abort the current gesture and reset to idle (e.g. on Escape / programmatically). */
|
|
1963
|
+
cancel: () => void;
|
|
1964
|
+
};
|
|
1965
|
+
/**
|
|
1966
|
+
* Tracks a pointer *gesture* (pointerdown → capture → move → up) as a signal —
|
|
1967
|
+
* the foundation for pointer-based drag/move/resize/marquee on a canvas. Unlike
|
|
1968
|
+
* native HTML5 drag, pointer events fire continuously and coordinates are
|
|
1969
|
+
* reliable. SSR-safe; cleans up its listeners automatically.
|
|
1970
|
+
*
|
|
1971
|
+
* @example
|
|
1972
|
+
* ```ts
|
|
1973
|
+
* const drag = pointerDrag({ activationThreshold: 4 });
|
|
1974
|
+
* const position = computed(() => {
|
|
1975
|
+
* const d = drag();
|
|
1976
|
+
* return d.active ? { x: base.x + d.delta.x, y: base.y + d.delta.y } : base;
|
|
1977
|
+
* });
|
|
1978
|
+
* ```
|
|
1979
|
+
*/
|
|
1980
|
+
declare function pointerDrag(opt?: PointerDragOptions): PointerDragSignal;
|
|
1981
|
+
|
|
1881
1982
|
/**
|
|
1882
1983
|
* Creates a read-only signal that tracks the page's visibility state.
|
|
1883
1984
|
*
|
|
@@ -2079,6 +2180,10 @@ type SensorTypedOptions = {
|
|
|
2079
2180
|
opt: MousePositionOptions;
|
|
2080
2181
|
returnType: MousePositionSignal;
|
|
2081
2182
|
};
|
|
2183
|
+
pointerDrag: {
|
|
2184
|
+
opt: PointerDragOptions;
|
|
2185
|
+
returnType: PointerDragSignal;
|
|
2186
|
+
};
|
|
2082
2187
|
networkStatus: {
|
|
2083
2188
|
opt: SensorRunOptions;
|
|
2084
2189
|
returnType: NetworkStatusSignal;
|
|
@@ -2163,6 +2268,15 @@ declare function sensor(type: 'elementSize', options?: SensorTypedOptions['eleme
|
|
|
2163
2268
|
* @example const pos = sensor('mousePosition', { coordinateSpace: 'page', throttle: 50 });
|
|
2164
2269
|
*/
|
|
2165
2270
|
declare function sensor(type: 'mousePosition', options?: SensorTypedOptions['mousePosition']['opt']): MousePositionSignal;
|
|
2271
|
+
/**
|
|
2272
|
+
* Creates a sensor signal tracking a pointer drag gesture (down → move → up).
|
|
2273
|
+
* @param type Must be `'pointerDrag'`.
|
|
2274
|
+
* @param options Optional configuration (target, activationThreshold, throttle, …).
|
|
2275
|
+
* @returns A `PointerDragSignal` with `active`/`start`/`current`/`delta`, plus `unthrottled` and `cancel()`.
|
|
2276
|
+
* @see {pointerDrag} for detailed documentation and examples.
|
|
2277
|
+
* @example const drag = sensor('pointerDrag', { activationThreshold: 4 });
|
|
2278
|
+
*/
|
|
2279
|
+
declare function sensor(type: 'pointerDrag', options?: SensorTypedOptions['pointerDrag']['opt']): PointerDragSignal;
|
|
2166
2280
|
/**
|
|
2167
2281
|
* Creates a sensor signal that tracks the browser's online/offline status.
|
|
2168
2282
|
* @param type Must be `'networkStatus'`.
|
|
@@ -2326,6 +2440,32 @@ type ResolvableTarget = EventTargetLike | Signal<EventTargetLike | null>;
|
|
|
2326
2440
|
declare function signalFromEvent<TEvent extends Event>(target: ResolvableTarget, eventName: string, initial: TEvent | null, opt?: SignalFromEventOptions): Signal<TEvent | null>;
|
|
2327
2441
|
declare function signalFromEvent<TEvent extends Event, U>(target: ResolvableTarget, eventName: string, initial: U, project: (event: TEvent) => U, opt?: SignalFromEventOptions): Signal<U>;
|
|
2328
2442
|
|
|
2443
|
+
/**
|
|
2444
|
+
* @internal Runtime brand carrying a store node's lazily-built leaf probe. Exported (like
|
|
2445
|
+
* {@link OPAQUE}) only so the `{ readonly [LEAF]: () => boolean }` brand on the store types is
|
|
2446
|
+
* nameable in the emitted declarations — not part of the supported surface; use {@link isLeaf}.
|
|
2447
|
+
*/
|
|
2448
|
+
declare const LEAF: unique symbol;
|
|
2449
|
+
/**
|
|
2450
|
+
* Reports whether a store node is currently a **leaf** — a terminal value the store does not
|
|
2451
|
+
* descend into (a primitive, `Date`, `RegExp`, {@link opaque} object, class instance, or a
|
|
2452
|
+
* `null`/`undefined` hole when vivification is off) rather than a record/array substore.
|
|
2453
|
+
*
|
|
2454
|
+
* Leaf-ness reflects the node's **live** value: the probe is reactive and memoized, so calling
|
|
2455
|
+
* `isLeaf` inside a `computed`/`effect` re-evaluates when the node's shape changes.
|
|
2456
|
+
*
|
|
2457
|
+
* @internal Exposed for advanced/niche interop only — not part of the supported public surface
|
|
2458
|
+
* and may change without a major version bump.
|
|
2459
|
+
*
|
|
2460
|
+
* @example
|
|
2461
|
+
* const s = store({ name: 'Ada', address: { city: 'London' } });
|
|
2462
|
+
* isLeaf(s.name); // true
|
|
2463
|
+
* isLeaf(s.address); // false — a substore
|
|
2464
|
+
*/
|
|
2465
|
+
declare function isLeaf<T = unknown>(value: unknown): value is Signal<T> & {
|
|
2466
|
+
readonly [LEAF]: () => boolean;
|
|
2467
|
+
};
|
|
2468
|
+
|
|
2329
2469
|
/**
|
|
2330
2470
|
* Runtime marker + compile-time brand for an opaque value. A `const`-declared `Symbol`
|
|
2331
2471
|
* has a `unique symbol` type, so the same symbol serves as both the property key written
|
|
@@ -2359,31 +2499,6 @@ declare function opaque<T extends object>(value: T): Opaque<T>;
|
|
|
2359
2499
|
* }
|
|
2360
2500
|
*/
|
|
2361
2501
|
declare function isOpaque<T = object>(value: unknown): value is Opaque<T>;
|
|
2362
|
-
/**
|
|
2363
|
-
* @internal Runtime brand carrying a store node's lazily-built leaf probe. Exported (like
|
|
2364
|
-
* {@link OPAQUE}) only so the `{ readonly [LEAF]: () => boolean }` brand on the store types is
|
|
2365
|
-
* nameable in the emitted declarations — not part of the supported surface; use {@link isLeaf}.
|
|
2366
|
-
*/
|
|
2367
|
-
declare const LEAF: unique symbol;
|
|
2368
|
-
/**
|
|
2369
|
-
* Reports whether a store node is currently a **leaf** — a terminal value the store does not
|
|
2370
|
-
* descend into (a primitive, `Date`, `RegExp`, {@link opaque} object, class instance, or a
|
|
2371
|
-
* `null`/`undefined` hole when vivification is off) rather than a record/array substore.
|
|
2372
|
-
*
|
|
2373
|
-
* Leaf-ness reflects the node's **live** value: the probe is reactive and memoized, so calling
|
|
2374
|
-
* `isLeaf` inside a `computed`/`effect` re-evaluates when the node's shape changes.
|
|
2375
|
-
*
|
|
2376
|
-
* @internal Exposed for advanced/niche interop only — not part of the supported public surface
|
|
2377
|
-
* and may change without a major version bump.
|
|
2378
|
-
*
|
|
2379
|
-
* @example
|
|
2380
|
-
* const s = store({ name: 'Ada', address: { city: 'London' } });
|
|
2381
|
-
* isLeaf(s.name); // true
|
|
2382
|
-
* isLeaf(s.address); // false — a substore
|
|
2383
|
-
*/
|
|
2384
|
-
declare function isLeaf<T = unknown>(value: unknown): value is Signal<T> & {
|
|
2385
|
-
readonly [LEAF]: () => boolean;
|
|
2386
|
-
};
|
|
2387
2502
|
/**
|
|
2388
2503
|
* An object marked via {@link opaque} — the store treats it as an indivisible leaf
|
|
2389
2504
|
* (like a `Date`), returning it whole instead of deep-proxying its keys.
|
|
@@ -2395,16 +2510,27 @@ type Opaque<T> = T & {
|
|
|
2395
2510
|
type UnwrapOpaque<T> = T extends {
|
|
2396
2511
|
readonly [OPAQUE]: true;
|
|
2397
2512
|
} ? Omit<T, typeof OPAQUE> : T;
|
|
2513
|
+
|
|
2398
2514
|
type BaseType = string | number | boolean | symbol | bigint | undefined | null | Function | Date | RegExp | {
|
|
2399
2515
|
readonly [OPAQUE]: true;
|
|
2400
2516
|
};
|
|
2401
2517
|
type Key = string | number;
|
|
2402
2518
|
type AnyRecord = Record<Key, any>;
|
|
2403
2519
|
/**
|
|
2404
|
-
* @internal
|
|
2405
|
-
*
|
|
2520
|
+
* @internal Resolves to `true` only for `any`. In a conditional type, `any` distributes across
|
|
2521
|
+
* *both* branches (`unknown | object`), and `unknown | X` collapses to `unknown` — which would
|
|
2522
|
+
* erase a store's property access and `extend`. Guarding on this routes an `any`-typed store to
|
|
2523
|
+
* the full object shape instead.
|
|
2406
2524
|
*/
|
|
2407
|
-
|
|
2525
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
2526
|
+
/**
|
|
2527
|
+
* @internal Flattens an intersection (`A & B & C`) into a single object literal so editor
|
|
2528
|
+
* tooltips show the resolved members instead of the raw intersection chain. Display-only —
|
|
2529
|
+
* structurally identical to its input.
|
|
2530
|
+
*/
|
|
2531
|
+
type Simplify<T> = {
|
|
2532
|
+
[K in keyof T]: T[K];
|
|
2533
|
+
} & {};
|
|
2408
2534
|
type SignalArrayStore<T extends any[]> = Signal<T> & {
|
|
2409
2535
|
readonly [index: number]: SignalStore<T[number]>;
|
|
2410
2536
|
readonly length: Signal<number>;
|
|
@@ -2422,25 +2548,11 @@ type MutableArrayStore<T extends any[]> = MutableSignal<T> & {
|
|
|
2422
2548
|
readonly length: Signal<number>;
|
|
2423
2549
|
[Symbol.iterator](): Iterator<MutableSignalStore<T[number]>>;
|
|
2424
2550
|
};
|
|
2425
|
-
/**
|
|
2426
|
-
* @internal Resolves to `true` only for `any`. In a conditional type, `any` distributes across
|
|
2427
|
-
* *both* branches (`unknown | object`), and `unknown | X` collapses to `unknown` — which would
|
|
2428
|
-
* erase a store's property access and `extend`. Guarding on this routes an `any`-typed store to
|
|
2429
|
-
* the full object shape instead.
|
|
2430
|
-
*/
|
|
2431
|
-
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
2432
|
-
/**
|
|
2433
|
-
* @internal Flattens an intersection (`A & B & C`) into a single object literal so editor
|
|
2434
|
-
* tooltips show the resolved members instead of the raw intersection chain. Display-only —
|
|
2435
|
-
* structurally identical to its input.
|
|
2436
|
-
*/
|
|
2437
|
-
type Simplify<T> = {
|
|
2438
|
-
[K in keyof T]: T[K];
|
|
2439
|
-
} & {};
|
|
2440
2551
|
/** @internal The object shape of a readonly store: a child store per key, plus `extend`. */
|
|
2441
2552
|
type SignalStoreObject<T> = Simplify<Readonly<{
|
|
2442
2553
|
[K in keyof Required<T>]: SignalStore<NonNullable<T>[K]>;
|
|
2443
2554
|
}> & {
|
|
2555
|
+
/** @deprecated Use the standalone `extendStore(store, …)`; the `extend` key is removed next minor. */
|
|
2444
2556
|
readonly extend: {
|
|
2445
2557
|
<L extends AnyRecord>(source: Signal<L>): SignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2446
2558
|
<L extends AnyRecord>(props: L): SignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
@@ -2450,6 +2562,7 @@ type SignalStoreObject<T> = Simplify<Readonly<{
|
|
|
2450
2562
|
type WritableSignalStoreObject<T> = Simplify<Readonly<{
|
|
2451
2563
|
[K in keyof Required<T>]: WritableSignalStore<NonNullable<T>[K]>;
|
|
2452
2564
|
}> & {
|
|
2565
|
+
/** @deprecated Use the standalone `extendStore(store, …)`; the `extend` key is removed next minor. */
|
|
2453
2566
|
readonly extend: {
|
|
2454
2567
|
<L extends AnyRecord>(source: WritableSignal<L>): WritableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2455
2568
|
<L extends AnyRecord>(props: L): WritableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
@@ -2459,6 +2572,7 @@ type WritableSignalStoreObject<T> = Simplify<Readonly<{
|
|
|
2459
2572
|
type MutableSignalStoreObject<T> = Simplify<Readonly<{
|
|
2460
2573
|
[K in keyof Required<T>]: MutableSignalStore<NonNullable<T>[K]>;
|
|
2461
2574
|
}> & {
|
|
2575
|
+
/** @deprecated Use the standalone `extendStore(store, …)`; the `extend` key is removed next minor. */
|
|
2462
2576
|
readonly extend: {
|
|
2463
2577
|
<L extends AnyRecord>(source: MutableSignal<L>): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2464
2578
|
<L extends AnyRecord>(props: L): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
@@ -2477,9 +2591,19 @@ type MutableSignalStore<T> = MutableSignal<UnwrapOpaque<T>> & {
|
|
|
2477
2591
|
} & (IsAny<T> extends true ? MutableSignalStoreObject<T> : NonNullable<T> extends BaseType ? {
|
|
2478
2592
|
readonly [LEAF]: () => boolean;
|
|
2479
2593
|
} : NonNullable<T> extends any[] ? MutableArrayStore<NonNullable<T>> : MutableSignalStoreObject<T>);
|
|
2594
|
+
|
|
2595
|
+
/**
|
|
2596
|
+
* @internal
|
|
2597
|
+
* Validates whether a value is a Signal Store.
|
|
2598
|
+
*/
|
|
2599
|
+
declare function isStore<T>(value: unknown): value is SignalStore<T>;
|
|
2600
|
+
|
|
2480
2601
|
declare function toStore<T extends AnyRecord>(source: MutableSignal<T>, injector?: Injector, vivify?: Vivify, noUnionLeaves?: boolean): MutableSignalStore<T>;
|
|
2481
2602
|
declare function toStore<T extends AnyRecord>(source: WritableSignal<T>, injector?: Injector, vivify?: Vivify, noUnionLeaves?: boolean): WritableSignalStore<T>;
|
|
2482
2603
|
declare function toStore<T extends AnyRecord>(source: Signal<T>, injector?: Injector, vivify?: Vivify, noUnionLeaves?: boolean): SignalStore<T>;
|
|
2604
|
+
declare function extendStore<T extends AnyRecord, L extends AnyRecord>(store: MutableSignalStore<T>, source: MutableSignal<L> | L, injector?: Injector): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2605
|
+
declare function extendStore<T extends AnyRecord, L extends AnyRecord>(store: WritableSignalStore<T>, source: WritableSignal<L> | L, injector?: Injector): WritableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2606
|
+
declare function extendStore<T extends AnyRecord, L extends AnyRecord>(store: SignalStore<T>, source: Signal<L> | L, injector?: Injector): SignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
2483
2607
|
/**
|
|
2484
2608
|
* Creates a WritableSignalStore from a value.
|
|
2485
2609
|
* @see {@link toStore}
|
|
@@ -2676,6 +2800,18 @@ type CreateStoredOptions<T> = CreateSignalOptions<T> & {
|
|
|
2676
2800
|
* Optional validator, which is called on load of value. Store will be set to fallback if value is false
|
|
2677
2801
|
*/
|
|
2678
2802
|
validate?: (value: T) => boolean;
|
|
2803
|
+
/**
|
|
2804
|
+
* Opt-in pause: gate the persistence effect on an ambient Activity boundary (`true`), a custom
|
|
2805
|
+
* predicate, or `false` (default — no pausing). While paused the value stays live; persistence is
|
|
2806
|
+
* skipped and flushes the latest value on resume. The inbound `storage` listener stays live.
|
|
2807
|
+
* See {@link PauseOption}.
|
|
2808
|
+
*/
|
|
2809
|
+
pause?: PauseOption;
|
|
2810
|
+
/**
|
|
2811
|
+
* Injector used when `stored` is created outside an injection context, and to resolve the ambient
|
|
2812
|
+
* pause boundary when `pause` is `true`.
|
|
2813
|
+
*/
|
|
2814
|
+
injector?: Injector;
|
|
2679
2815
|
};
|
|
2680
2816
|
/**
|
|
2681
2817
|
* A specialized `WritableSignal` returned by the `stored()` function.
|
|
@@ -2747,13 +2883,21 @@ type StoredSignal<T> = WritableSignal<T> & {
|
|
|
2747
2883
|
* }
|
|
2748
2884
|
* ```
|
|
2749
2885
|
*/
|
|
2750
|
-
declare function stored<T>(fallback: T, { key, store: providedStore, serialize, deserialize, syncTabs, equal, onKeyChange, cleanupOldKey, validate, ...rest }: CreateStoredOptions<T>): StoredSignal<T>;
|
|
2886
|
+
declare function stored<T>(fallback: T, { key, store: providedStore, serialize, deserialize, syncTabs, equal, onKeyChange, cleanupOldKey, validate, pause, injector: providedInjector, ...rest }: CreateStoredOptions<T>): StoredSignal<T>;
|
|
2751
2887
|
|
|
2752
2888
|
type LegacySyncSignalOptions = {
|
|
2753
2889
|
id?: string;
|
|
2754
2890
|
};
|
|
2755
2891
|
type SyncSignalOptions = {
|
|
2756
2892
|
id: string;
|
|
2893
|
+
/**
|
|
2894
|
+
* Injector used when `tabSync` is called outside an injection context.
|
|
2895
|
+
*
|
|
2896
|
+
* NOTE: `tabSync` is intentionally NOT pausable. Pausing the outbound broadcast would let its
|
|
2897
|
+
* mount-time echo guard swallow a value changed while hidden, so other tabs would silently miss
|
|
2898
|
+
* it — a cross-tab consistency gap not worth the negligible saving. The channel stays live.
|
|
2899
|
+
*/
|
|
2900
|
+
injector?: Injector;
|
|
2757
2901
|
};
|
|
2758
2902
|
/**
|
|
2759
2903
|
* @example tabSync(signal('dark'), { id: 'theme' })
|
|
@@ -2802,12 +2946,16 @@ type CreateThrottledOptions<T> = CreateSignalOptions<T> & {
|
|
|
2802
2946
|
/**
|
|
2803
2947
|
* A specialized `WritableSignal` whose publicly readable value updates are throttled.
|
|
2804
2948
|
*
|
|
2805
|
-
*
|
|
2949
|
+
* Provides access to the underlying, non-throttled signal via `original`, and a
|
|
2950
|
+
* `flush()` that emits the current value immediately (clearing any open window) —
|
|
2951
|
+
* useful for terminal transitions that shouldn't wait for the trailing edge.
|
|
2806
2952
|
*
|
|
2807
2953
|
* @template T The type of value held by the signal.
|
|
2808
|
-
* @see {DebouncedSignal} as the output type has the same structure.
|
|
2809
2954
|
*/
|
|
2810
|
-
type ThrottledSignal<T> = DebouncedSignal<T
|
|
2955
|
+
type ThrottledSignal<T> = DebouncedSignal<T> & {
|
|
2956
|
+
/** Emit the latest value now, bypassing the remaining throttle window. */
|
|
2957
|
+
flush: () => void;
|
|
2958
|
+
};
|
|
2811
2959
|
/**
|
|
2812
2960
|
* A convenience function that creates and throttles a new `WritableSignal` in one step.
|
|
2813
2961
|
*
|
|
@@ -2828,7 +2976,7 @@ type ThrottledSignal<T> = DebouncedSignal<T>;
|
|
|
2828
2976
|
* // With a trailing-edge throttle, the final value 'c' would be set
|
|
2829
2977
|
* // after the 500ms cooldown.
|
|
2830
2978
|
*/
|
|
2831
|
-
declare function throttled<T>(initial: T, opt?: CreateThrottledOptions<T>):
|
|
2979
|
+
declare function throttled<T>(initial: T, opt?: CreateThrottledOptions<T>): ThrottledSignal<T>;
|
|
2832
2980
|
/**
|
|
2833
2981
|
* Wraps an existing `WritableSignal` to create a new one whose readable value is throttled.
|
|
2834
2982
|
*
|
|
@@ -3044,5 +3192,5 @@ type CreateHistoryOptions<T> = Omit<CreateSignalOptions<T[]>, 'equal'> & {
|
|
|
3044
3192
|
*/
|
|
3045
3193
|
declare function withHistory<T>(sourceOrValue: WritableSignal<T> | T, opt?: CreateHistoryOptions<T>): SignalWithHistory<T>;
|
|
3046
3194
|
|
|
3047
|
-
export { MmActivity, SuspenseBoundary, SuspenseBoundaryBase, UnscopedSuspenseBoundary, activeTransaction, batteryStatus, chunked, clipboard, combineWith, createForwardingScope, createTransaction, createTransitionScope, debounce, debounced, derived, distinct, elementSize, elementVisibility, filter, filterWith, focusWithin, forkStore, geolocation, getTransitionScope, holdUntilReady, idle, indexArray, injectPaused, injectRegisterResource, injectStartTransaction, injectStartTransition, injectTransitionScope, isDerivation, isLeaf, isMutable, isOpaque, isStore, keepPrevious, keyArray, map, mapArray, mapObject, mediaQuery, merge3, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, opaque, orientation, pageVisibility, pairwise, pausableComputed, pausableEffect, pausableSignal, pipeable, piped, pooled, pooledArray, pooledMap, pooledSet, prefersDarkMode, prefersReducedMotion, provideForwardingTransitionScope, providePaused, provideTransitionScope, registerResource, resolvePause, scan, scrollPosition, select, sensor, sensors, signalFromEvent, startWith, store, stored, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, until, windowSize, withHistory };
|
|
3048
|
-
export type { BatteryStatus, ClipboardSignal, Computation, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, Fork, ForkStrategy, ForwardingTransitionScope, Frame, GeolocationOptions, GeolocationSignal, IdleOptions, IdleSignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, Opaque, PausableOptions, PauseOption, PipeableSignal, ReconcileFn, RegisterOptions, ScreenOrientation, ScreenOrientationState, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SensorRunOptions, SignalFromEventOptions, SignalStore, SignalWithHistory, StoredSignal, SuspendType, ThrottledSignal, Transaction, TransactionRef, TransitionRef, TransitionScope, UntilOptions, Vivify, WindowSize, WindowSizeOptions, WindowSizeSignal, WithVivify, WritableSignalStore };
|
|
3195
|
+
export { MmActivity, PAUSABLE_OPTIONS, SuspenseBoundary, SuspenseBoundaryBase, UnscopedSuspenseBoundary, activeTransaction, batteryStatus, chunked, clipboard, combineWith, createForwardingScope, createTransaction, createTransitionScope, debounce, debounced, derived, distinct, elementSize, elementVisibility, extendStore, filter, filterWith, focusWithin, forkStore, geolocation, getTransitionScope, holdUntilReady, idle, indexArray, injectPaused, injectRegisterResource, injectStartTransaction, injectStartTransition, injectTransitionScope, isDerivation, isLeaf, isMutable, isOpaque, isStore, keepPrevious, keyArray, map, mapArray, mapObject, mediaQuery, merge3, mousePosition, mutable, mutableStore, nestedEffect, networkStatus, opaque, orientation, pageVisibility, pairwise, pausableComputed, pausableEffect, pausableSignal, pipeable, piped, pointerDrag, pooled, pooledArray, pooledMap, pooledSet, prefersDarkMode, prefersReducedMotion, provideForwardingTransitionScope, providePausableOptions, providePaused, provideTransitionScope, registerResource, resolvePause, scan, scrollPosition, select, sensor, sensors, signalFromEvent, startWith, store, stored, tabSync, tap, throttle, throttled, toFakeDerivation, toFakeSignalDerivation, toStore, toWritable, until, windowSize, withHistory };
|
|
3196
|
+
export type { BatteryStatus, ClipboardSignal, Computation, CreateChunkedOptions, CreateDebouncedOptions, CreateHistoryOptions, CreatePooledOptions, CreateProvidedPooledOptions, CreateStoredOptions, CreateThrottledOptions, DebouncedSignal, DerivedSignal, ElementSize, ElementSizeOptions, ElementSizeSignal, ElementVisibilityOptions, ElementVisibilitySignal, Fork, ForkStrategy, ForwardingTransitionScope, Frame, GeolocationOptions, GeolocationSignal, IdleOptions, IdleSignal, MousePositionOptions, MousePositionSignal, MutableSignal, MutableSignalStore, NetworkStatusSignal, Opaque, PausableOptions, PauseOption, PipeableSignal, PointerDragOptions, PointerDragSignal, PointerDragState, PointerModifiers, PointerPoint, ReconcileFn, RegisterOptions, ScreenOrientation, ScreenOrientationState, ScrollPosition, ScrollPositionOptions, ScrollPositionSignal, SensorRunOptions, SignalFromEventOptions, SignalStore, SignalWithHistory, StoredSignal, SuspendType, ThrottledSignal, Transaction, TransactionRef, TransitionRef, TransitionScope, UntilOptions, Vivify, WindowSize, WindowSizeOptions, WindowSizeSignal, WithVivify, WritableSignalStore };
|