@mmstack/primitives 19.3.6 → 19.3.8
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 +52 -0
- package/fesm2022/mmstack-primitives.mjs +511 -65
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/index.d.ts +2 -2
- package/lib/derived.d.ts +17 -7
- package/lib/mappers/key-array.d.ts +23 -0
- package/lib/mappers/map-object.d.ts +59 -0
- package/lib/pipeable/operators.d.ts +119 -11
- package/lib/pooled/index.d.ts +2 -0
- package/lib/{provided-pools.d.ts → pooled/provided-pools.d.ts} +1 -1
- package/lib/sensors/battery-status.d.ts +9 -0
- package/lib/sensors/focus-within.d.ts +9 -0
- package/lib/sensors/idle.d.ts +8 -0
- package/lib/sensors/network-status.d.ts +8 -0
- package/lib/sensors/orientation.d.ts +9 -0
- package/lib/sensors/sensor.d.ts +21 -0
- package/lib/store.d.ts +85 -11
- package/lib/util/index.d.ts +2 -0
- package/lib/util/is-index-prop.d.ts +7 -0
- package/lib/util/vivify.d.ts +63 -0
- package/package.json +1 -1
- /package/lib/{pooled.d.ts → pooled/pooled.d.ts} +0 -0
package/index.d.ts
CHANGED
|
@@ -6,12 +6,12 @@ export * from './lib/mappers';
|
|
|
6
6
|
export * from './lib/mutable';
|
|
7
7
|
export * from './lib/pipeable/public_api';
|
|
8
8
|
export * from './lib/pooled';
|
|
9
|
-
export * from './lib/provided-pools';
|
|
10
9
|
export * from './lib/sensors';
|
|
11
|
-
export
|
|
10
|
+
export { isStore, store, mutableStore, toStore, type SignalStore, type WritableSignalStore, type MutableSignalStore, } from './lib/store';
|
|
12
11
|
export * from './lib/stored';
|
|
13
12
|
export { tabSync } from './lib/tabSync';
|
|
14
13
|
export * from './lib/throttled';
|
|
15
14
|
export * from './lib/to-writable';
|
|
16
15
|
export * from './lib/until';
|
|
16
|
+
export type { Vivify, WithVivify } from './lib/util';
|
|
17
17
|
export * from './lib/with-history';
|
package/lib/derived.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CreateSignalOptions, type WritableSignal } from '@angular/core';
|
|
2
2
|
import { type MutableSignal } from './mutable';
|
|
3
|
+
import { type WithVivify } from './util';
|
|
3
4
|
/**
|
|
4
5
|
* Options for creating a derived signal using the full `derived` function signature.
|
|
5
6
|
* @typeParam T - The type of the source signal's value (parent).
|
|
@@ -62,7 +63,10 @@ export declare function derived<T, U>(source: WritableSignal<T>, opt: CreateDeri
|
|
|
62
63
|
* @typeParam TKey The key of the property to derive.
|
|
63
64
|
* @param source The source `WritableSignal` (holding an object).
|
|
64
65
|
* @param key The key of the property to derive.
|
|
65
|
-
* @param options Optional signal options for the derived signal.
|
|
66
|
+
* @param options Optional signal options for the derived signal. Also accepts a
|
|
67
|
+
* {@link Vivify} `vivify` flag (off by default) that, when set, creates the missing
|
|
68
|
+
* container instead of dropping a write made through a `null`/`undefined` source —
|
|
69
|
+
* e.g. `derived(user, 'name', { vivify: 'object' })`. See {@link WithVivify}.
|
|
66
70
|
* @returns A `DerivedSignal` instance.
|
|
67
71
|
*
|
|
68
72
|
* @example
|
|
@@ -78,7 +82,7 @@ export declare function derived<T, U>(source: WritableSignal<T>, opt: CreateDeri
|
|
|
78
82
|
* console.log(user().name); // Outputs: Jane
|
|
79
83
|
* ```
|
|
80
84
|
*/
|
|
81
|
-
export declare function derived<T extends object, TKey extends keyof T>(source: MutableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]>): DerivedSignal<T, T[TKey]> & MutableSignal<T[TKey]>;
|
|
85
|
+
export declare function derived<T extends object, TKey extends keyof T>(source: MutableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]> & WithVivify<T>): DerivedSignal<T, T[TKey]> & MutableSignal<T[TKey]>;
|
|
82
86
|
/**
|
|
83
87
|
* Creates a `DerivedSignal` that derives a property from an object held by the source signal.
|
|
84
88
|
* This overload is a convenient shorthand for accessing object properties.
|
|
@@ -87,7 +91,10 @@ export declare function derived<T extends object, TKey extends keyof T>(source:
|
|
|
87
91
|
* @typeParam TKey The key of the property to derive.
|
|
88
92
|
* @param source The source `WritableSignal` (holding an object).
|
|
89
93
|
* @param key The key of the property to derive.
|
|
90
|
-
* @param options Optional signal options for the derived signal.
|
|
94
|
+
* @param options Optional signal options for the derived signal. Also accepts a
|
|
95
|
+
* {@link Vivify} `vivify` flag (off by default) that, when set, creates the missing
|
|
96
|
+
* container instead of dropping a write made through a `null`/`undefined` source —
|
|
97
|
+
* e.g. `derived(user, 'name', { vivify: 'object' })`. See {@link WithVivify}.
|
|
91
98
|
* @returns A `DerivedSignal` instance.
|
|
92
99
|
*
|
|
93
100
|
* @example
|
|
@@ -103,7 +110,7 @@ export declare function derived<T extends object, TKey extends keyof T>(source:
|
|
|
103
110
|
* console.log(user().name); // Outputs: Jane
|
|
104
111
|
* ```
|
|
105
112
|
*/
|
|
106
|
-
export declare function derived<T extends object, TKey extends keyof T>(source: WritableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]>): DerivedSignal<T, T[TKey]>;
|
|
113
|
+
export declare function derived<T extends object, TKey extends keyof T>(source: WritableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]> & WithVivify<T>): DerivedSignal<T, T[TKey]>;
|
|
107
114
|
/**
|
|
108
115
|
* Creates a `DerivedSignal` that derives its value from another `MutableSignal`.
|
|
109
116
|
* Use mutuable signals with caution, but very useful for deeply nested structures.
|
|
@@ -126,7 +133,7 @@ export declare function derived<T extends object, TKey extends keyof T>(source:
|
|
|
126
133
|
* console.log(user().name); // Outputs: Jane
|
|
127
134
|
* ```
|
|
128
135
|
*/
|
|
129
|
-
export declare function derived<T, U>(source: MutableSignal<T>, optOrKey: CreateDerivedOptions<T, U> | keyof T, opt?: CreateSignalOptions<U>): DerivedSignal<T, U> & MutableSignal<U>;
|
|
136
|
+
export declare function derived<T, U>(source: MutableSignal<T>, optOrKey: CreateDerivedOptions<T, U> | keyof T, opt?: CreateSignalOptions<U> & WithVivify<T>): DerivedSignal<T, U> & MutableSignal<U>;
|
|
130
137
|
/**
|
|
131
138
|
* Creates a `DerivedSignal` from an array, deriving an element by its index.
|
|
132
139
|
* This overload is a convenient shorthand for accessing array elements.
|
|
@@ -134,7 +141,10 @@ export declare function derived<T, U>(source: MutableSignal<T>, optOrKey: Create
|
|
|
134
141
|
* @typeParam T The type of the source signal's value (must be an array).
|
|
135
142
|
* @param source The source `WritableSignal` (holding an array).
|
|
136
143
|
* @param index The index of the element to derive.
|
|
137
|
-
* @param options Optional signal options for the derived signal.
|
|
144
|
+
* @param options Optional signal options for the derived signal. Also accepts a
|
|
145
|
+
* {@link Vivify} `vivify` flag (off by default) that, when set, creates the missing
|
|
146
|
+
* container instead of dropping a write made through a `null`/`undefined` source —
|
|
147
|
+
* e.g. `derived(user, 'name', { vivify: 'object' })`. See {@link WithVivify}.
|
|
138
148
|
* @returns A `DerivedSignal` instance.
|
|
139
149
|
*
|
|
140
150
|
* @example
|
|
@@ -150,7 +160,7 @@ export declare function derived<T, U>(source: MutableSignal<T>, optOrKey: Create
|
|
|
150
160
|
* console.log(numbers()); // Outputs: [1, 5, 3]
|
|
151
161
|
* ```
|
|
152
162
|
*/
|
|
153
|
-
export declare function derived<T extends any[]>(source: WritableSignal<T>, index: number, opt?: CreateSignalOptions<T[number]>): DerivedSignal<T, T[number]>;
|
|
163
|
+
export declare function derived<T extends any[]>(source: WritableSignal<T>, index: number, opt?: CreateSignalOptions<T[number]> & WithVivify<T>): DerivedSignal<T, T[number]>;
|
|
154
164
|
/**
|
|
155
165
|
* Creates a "fake" `DerivedSignal` from a simple value. This is useful for creating
|
|
156
166
|
* `FormControlSignal` instances that are not directly derived from another signal.
|
|
@@ -15,7 +15,30 @@ import { type Signal } from '@angular/core';
|
|
|
15
15
|
* @param mapFn The mapping function. Receives the item and its index as a Signal.
|
|
16
16
|
* @param options Optional configuration:
|
|
17
17
|
* - `onDestroy`: A callback invoked when a mapped item is removed from the array.
|
|
18
|
+
* - `key`: A custom key extractor for identity matching (e.g. `(item) => item.id`)
|
|
19
|
+
* when item references change but conceptual identity is preserved.
|
|
18
20
|
* @returns A `Signal<U[]>` containing the mapped array.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const users = signal([
|
|
25
|
+
* { id: 1, name: 'Alice' },
|
|
26
|
+
* { id: 2, name: 'Bob' },
|
|
27
|
+
* ]);
|
|
28
|
+
*
|
|
29
|
+
* const rows = keyArray(
|
|
30
|
+
* users,
|
|
31
|
+
* (user, index) => ({
|
|
32
|
+
* label: computed(() => `#${index()} ${user.name}`),
|
|
33
|
+
* id: user.id,
|
|
34
|
+
* }),
|
|
35
|
+
* { key: (u) => u.id },
|
|
36
|
+
* );
|
|
37
|
+
*
|
|
38
|
+
* // Reordering users() rebuilds index signals only — `rows` entries
|
|
39
|
+
* // are matched by id and reused, not re-created.
|
|
40
|
+
* users.set([users()[1], users()[0]]);
|
|
41
|
+
* ```
|
|
19
42
|
*/
|
|
20
43
|
export declare function keyArray<T, U, K>(source: Signal<T[]> | (() => T[]), mapFn: (v: T, i: Signal<number>) => U, options?: {
|
|
21
44
|
onDestroy?: (value: U) => void;
|
|
@@ -3,12 +3,71 @@ import { type MutableSignal } from '../mutable';
|
|
|
3
3
|
type MappedObject<T extends object, U> = {
|
|
4
4
|
[K in keyof T]: U;
|
|
5
5
|
};
|
|
6
|
+
/**
|
|
7
|
+
* Reactively maps each property of an object signal into a new object,
|
|
8
|
+
* preserving the same set of keys. For each key, `mapFn` receives a stable
|
|
9
|
+
* per-key signal — outputs for keys that haven't been added or removed are
|
|
10
|
+
* reused on subsequent reads. Sibling to {@link indexArray} / {@link keyArray}
|
|
11
|
+
* but for object records.
|
|
12
|
+
*
|
|
13
|
+
* The type of per-key signal passed into `mapFn` depends on the source:
|
|
14
|
+
* - `MutableSignal<T>` source → `MutableSignal<T[K]>` (in-place mutation)
|
|
15
|
+
* - `WritableSignal<T>` source → `WritableSignal<T[K]>` (two-way binding)
|
|
16
|
+
* - read-only `Signal<T>` or `() => T` source → read-only `Signal<T[K]>`
|
|
17
|
+
*
|
|
18
|
+
* @typeParam T The object type held by the source signal.
|
|
19
|
+
* @typeParam U The type produced for each key by `mapFn`.
|
|
20
|
+
*
|
|
21
|
+
* @param source A `MutableSignal<T>` whose properties are mapped with full
|
|
22
|
+
* in-place mutation capability via the per-key `MutableSignal`.
|
|
23
|
+
* @param mapFn Receives each key and its per-key `MutableSignal<T[K]>`.
|
|
24
|
+
* @param options Optional `onDestroy(value)` callback fired when a key is
|
|
25
|
+
* removed from the source.
|
|
26
|
+
* @returns A read-only signal of the mapped object.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const state = mutable({ name: 'Alice', age: 30 });
|
|
31
|
+
* const view = mapObject(state, (key, prop) => ({
|
|
32
|
+
* label: key,
|
|
33
|
+
* current: computed(() => prop()),
|
|
34
|
+
* onInput: (next: any) => prop.set(next),
|
|
35
|
+
* }));
|
|
36
|
+
* view().age.onInput(31);
|
|
37
|
+
* state(); // { name: 'Alice', age: 31 }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
6
40
|
export declare function mapObject<T extends object, U>(source: MutableSignal<T>, mapFn: <K extends keyof T>(key: K, value: MutableSignal<T[K]>) => U, options?: {
|
|
7
41
|
onDestroy?: (value: U) => void;
|
|
8
42
|
}): Signal<MappedObject<T, U>>;
|
|
43
|
+
/**
|
|
44
|
+
* Reactively maps each property of a `WritableSignal<T>` into a new object.
|
|
45
|
+
* Each key's per-property signal supports `.set` / `.update` for two-way
|
|
46
|
+
* binding back into the parent object.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const user = signal({ name: 'Alice', age: 30 });
|
|
51
|
+
* const inputs = mapObject(user, (key, prop) => ({
|
|
52
|
+
* value: prop,
|
|
53
|
+
* setValue: (v: any) => prop.set(v),
|
|
54
|
+
* }));
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
9
57
|
export declare function mapObject<T extends object, U>(source: WritableSignal<T>, mapFn: <K extends keyof T>(key: K, value: WritableSignal<T[K]>) => U, options?: {
|
|
10
58
|
onDestroy?: (value: U) => void;
|
|
11
59
|
}): Signal<MappedObject<T, U>>;
|
|
60
|
+
/**
|
|
61
|
+
* Reactively maps each property of a read-only `Signal<T>` (or plain `() => T`
|
|
62
|
+
* accessor) into a new object. Per-key signals are read-only.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* const config = computed(() => ({ theme: 'dark', density: 'compact' }));
|
|
67
|
+
* const view = mapObject(config, (key, prop) => `${key}: ${prop()}`);
|
|
68
|
+
* view(); // { theme: 'theme: dark', density: 'density: compact' }
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
12
71
|
export declare function mapObject<T extends object, U>(source: (() => T) | Signal<T>, mapFn: <K extends keyof T>(key: K, value: Signal<T[K]>) => U, options?: {
|
|
13
72
|
onDestroy?: (value: U) => void;
|
|
14
73
|
}): Signal<MappedObject<T, U>>;
|
|
@@ -1,25 +1,133 @@
|
|
|
1
1
|
import { type CreateSignalOptions, type Injector, type Signal } from '@angular/core';
|
|
2
2
|
import { type Operator } from './types';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Synchronous projection of a signal value with optional `CreateSignalOptions`
|
|
5
|
+
* (custom `equal`, `debugName`, etc.). Equivalent to `map` plus the ability to
|
|
6
|
+
* pass signal options through to the underlying `computed()`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const user = piped({ id: 1, name: 'Alice' });
|
|
11
|
+
* const name = user.pipe(select((u) => u.name));
|
|
12
|
+
* name(); // 'Alice'
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
4
15
|
export declare const select: <I, O>(projector: (v: I) => O, opt?: CreateSignalOptions<O>) => Operator<I, O>;
|
|
5
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Combine the piped signal with another `Signal` using a projector. The result
|
|
18
|
+
* recomputes whenever either source changes.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const price = piped(10);
|
|
23
|
+
* const quantity = signal(3);
|
|
24
|
+
* const total = price.pipe(combineWith(quantity, (p, q) => p * q));
|
|
25
|
+
* total(); // 30
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
6
28
|
export declare const combineWith: <A, B, R>(other: Signal<B>, project: (a: A, b: B) => R, opt?: CreateSignalOptions<R>) => Operator<A, R>;
|
|
7
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Suppress emissions while consecutive values are considered equal. The
|
|
31
|
+
* comparator defaults to `Object.is`; pass a custom one for structural or
|
|
32
|
+
* key-based equality (e.g. compare by `id` only).
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const user = piped({ id: 1, lastSeen: Date.now() });
|
|
37
|
+
* const byId = user.pipe(distinct((a, b) => a.id === b.id));
|
|
38
|
+
* // byId only re-emits when `id` changes, not on every `lastSeen` update
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
8
41
|
export declare const distinct: <T>(equal?: (a: T, b: T) => boolean) => Operator<T, T>;
|
|
9
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* Pure synchronous transform from input to output. Equivalent to a `computed()`
|
|
44
|
+
* that reads the source and returns `fn(value)`.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* const count = piped(2);
|
|
49
|
+
* const doubled = count.pipe(map((n) => n * 2));
|
|
50
|
+
* doubled(); // 4
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
10
53
|
export declare const map: <I, O>(fn: (v: I) => O) => Operator<I, O>;
|
|
11
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Keep only values that pass the predicate. The result holds the last passing
|
|
56
|
+
* value across emissions; before any value passes, the result is `undefined` —
|
|
57
|
+
* see {@link filterWith} when you need a non-`undefined` seed.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const event = piped<MouseEvent | null>(null);
|
|
62
|
+
* const clicks = event.pipe(filter((e): e is MouseEvent => e?.type === 'click'));
|
|
63
|
+
* clicks(); // undefined until a click happens, then the last MouseEvent
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
12
66
|
export declare const filter: <T>(predicate: (v: T) => boolean) => Operator<T, T | undefined>;
|
|
13
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Run a side effect on every emission without altering the signal value. Wraps
|
|
69
|
+
* Angular's `effect()`, so it must run in an injection context or receive an
|
|
70
|
+
* explicit `injector`. Use for logging / analytics — not for setting other
|
|
71
|
+
* signals (that's what regular `effect()` is for).
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const count = piped(0);
|
|
76
|
+
* count.pipe(tap((n) => console.log('count:', n)));
|
|
77
|
+
* count.set(1); // logs 'count: 1'
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
14
80
|
export declare const tap: <T>(fn: (v: T) => void, injector?: Injector) => Operator<T, T>;
|
|
15
81
|
/**
|
|
16
|
-
* Like {@link filter}, but emits `initial` until a value passes the
|
|
17
|
-
*
|
|
82
|
+
* Like {@link filter}, but emits `initial` until a value first passes the
|
|
83
|
+
* predicate. Eliminates the `T | undefined` return type at the cost of an
|
|
84
|
+
* explicit seed value.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* const event = piped<MouseEvent | null>(null);
|
|
89
|
+
* const lastClick = event.pipe(filterWith((e) => e?.type === 'click', null));
|
|
90
|
+
* lastClick(); // null until the first click, then the most recent click event
|
|
91
|
+
* ```
|
|
18
92
|
*/
|
|
19
93
|
export declare const filterWith: <T>(predicate: (v: T) => boolean, initial: T) => Operator<T, T>;
|
|
20
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Emit `initial` on the first read, then mirror the source on every subsequent
|
|
96
|
+
* read. Useful for giving a pipeline a sensible seed value before the source
|
|
97
|
+
* is ready (e.g. loading state).
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* const data = piped<User | null>(null);
|
|
102
|
+
* const view = data.pipe(startWith<User | null, 'loading'>('loading'));
|
|
103
|
+
* view(); // 'loading' on first read, then User | null afterward
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
21
106
|
export declare const startWith: <T, U>(initial: U) => Operator<T, T | U>;
|
|
22
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* Emit `[prev, curr]` tuples so consumers can react to transitions instead of
|
|
109
|
+
* raw values. On the first emission `prev` is `undefined`.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const count = piped(0);
|
|
114
|
+
* const delta = count.pipe(pairwise(), map(([prev, curr]) => curr - (prev ?? 0)));
|
|
115
|
+
* count.set(5);
|
|
116
|
+
* delta(); // 5
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
23
119
|
export declare const pairwise: <T>() => Operator<T, [T | undefined, T]>;
|
|
24
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* Reduce-like accumulator that folds each emission into a running result.
|
|
122
|
+
* Behaves like `Array.prototype.reduce` but applied over time, with the
|
|
123
|
+
* accumulator persisted across emissions.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const delta = piped(0);
|
|
128
|
+
* const total = delta.pipe(scan((acc, n) => acc + n, 0));
|
|
129
|
+
* delta.set(5); // total() === 5
|
|
130
|
+
* delta.set(3); // total() === 8
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
25
133
|
export declare const scan: <T, R>(reducer: (acc: R, curr: T) => R, seed: R) => Operator<T, R>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CreateSignalOptions, Signal } from '@angular/core';
|
|
2
|
-
import { type Computation, type CreatePooledOptions } from '
|
|
2
|
+
import { type Computation, type CreatePooledOptions } from '.';
|
|
3
3
|
/**
|
|
4
4
|
* Options for the preset pool helpers. Same shape as
|
|
5
5
|
* {@link CreatePooledOptions}, with `create` and `reset` made optional — each
|
|
@@ -10,5 +10,14 @@ export type BatteryStatus = {
|
|
|
10
10
|
* Battery Status API. Returns `null` until the underlying `getBattery()`
|
|
11
11
|
* promise resolves, or permanently when the API is unsupported (Firefox /
|
|
12
12
|
* Safari at the time of writing). SSR-safe.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const battery = batteryStatus();
|
|
17
|
+
* effect(() => {
|
|
18
|
+
* const b = battery();
|
|
19
|
+
* if (b) console.log(`${Math.round(b.level * 100)}% • charging: ${b.charging}`);
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
13
22
|
*/
|
|
14
23
|
export declare function batteryStatus(debugName?: string): Signal<BatteryStatus | null>;
|
|
@@ -7,6 +7,15 @@ type FocusWithinTarget = ElementRef<Element> | Element | Signal<ElementRef<Eleme
|
|
|
7
7
|
* Defaults `target` to the current `ElementRef` so it can be used inline in a
|
|
8
8
|
* component's `class` field. SSR-safe — returns a constant `false` signal on
|
|
9
9
|
* the server.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* @Component({ ... })
|
|
14
|
+
* class MenuComponent {
|
|
15
|
+
* // Defaults to the host element — flips true when focus is inside.
|
|
16
|
+
* readonly hasFocus = focusWithin();
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
10
19
|
*/
|
|
11
20
|
export declare function focusWithin(target?: FocusWithinTarget): Signal<boolean>;
|
|
12
21
|
export {};
|
package/lib/sensors/idle.d.ts
CHANGED
|
@@ -23,5 +23,13 @@ export type IdleSignal = Signal<boolean> & {
|
|
|
23
23
|
* activity) resets the timer and flips the signal back to `false`.
|
|
24
24
|
*
|
|
25
25
|
* SSR-safe — always `false` with a frozen `since` date on the server.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* const isAway = idle({ ms: 30_000 });
|
|
30
|
+
* effect(() => {
|
|
31
|
+
* if (isAway()) console.log('idle since', isAway.since());
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
26
34
|
*/
|
|
27
35
|
export declare function idle(opt?: IdleOptions): IdleSignal;
|
|
@@ -16,5 +16,13 @@ export type NetworkStatusSignal = Signal<boolean> & {
|
|
|
16
16
|
*
|
|
17
17
|
* @param debugName Optional debug name for the signal.
|
|
18
18
|
* @returns A `NetworkStatusSignal` instance.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const online = networkStatus();
|
|
23
|
+
* effect(() => {
|
|
24
|
+
* if (!online()) console.log('offline since', online.since());
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
19
27
|
*/
|
|
20
28
|
export declare function networkStatus(debugName?: string): NetworkStatusSignal;
|
|
@@ -10,5 +10,14 @@ export type ScreenOrientation = {
|
|
|
10
10
|
*
|
|
11
11
|
* SSR-safe — returns a constant `portrait-primary / 0°` signal on the server
|
|
12
12
|
* and in environments without `screen.orientation` support.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const screenOrientation = orientation();
|
|
17
|
+
* effect(() => {
|
|
18
|
+
* const { type, angle } = screenOrientation();
|
|
19
|
+
* console.log(`${type} at ${angle}°`);
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
13
22
|
*/
|
|
14
23
|
export declare function orientation(debugName?: string): Signal<ScreenOrientation>;
|
package/lib/sensors/sensor.d.ts
CHANGED
|
@@ -226,5 +226,26 @@ type SensorsOptions<TKey extends keyof SensorTypedOptions> = {
|
|
|
226
226
|
type Sensors<TKey extends keyof SensorTypedOptions> = {
|
|
227
227
|
[K in TKey]: SensorTypedOptions[K]['returnType'];
|
|
228
228
|
};
|
|
229
|
+
/**
|
|
230
|
+
* Bulk sensor factory — creates several sensor signals at once and returns
|
|
231
|
+
* them keyed by sensor type. Convenient when a single consumer needs to react
|
|
232
|
+
* to multiple browser signals; for a single sensor prefer {@link sensor}
|
|
233
|
+
* directly.
|
|
234
|
+
*
|
|
235
|
+
* @typeParam TType The union of sensor keys being requested.
|
|
236
|
+
* @param track Array of sensor type keys to create.
|
|
237
|
+
* @param opt Optional per-sensor options keyed by sensor type.
|
|
238
|
+
* @returns A record `{ [key]: <SensorReturnType> }` for each requested key.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* const { windowSize, networkStatus } = sensors(
|
|
243
|
+
* ['windowSize', 'networkStatus'],
|
|
244
|
+
* { windowSize: { throttle: 200 } },
|
|
245
|
+
* );
|
|
246
|
+
*
|
|
247
|
+
* effect(() => console.log(windowSize(), networkStatus()));
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
229
250
|
export declare function sensors<const TType extends keyof SensorTypedOptions>(track: TType[], opt?: SensorsOptions<TType>): Sensors<TType>;
|
|
230
251
|
export {};
|
package/lib/store.d.ts
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
import { Injector, type CreateSignalOptions, type Signal, type WritableSignal } from '@angular/core';
|
|
2
2
|
import { type MutableSignal } from './mutable';
|
|
3
|
+
import { type Vivify } from './util';
|
|
3
4
|
type BaseType = string | number | boolean | symbol | undefined | null | Function | Date | RegExp;
|
|
4
5
|
type Key = string | number;
|
|
5
6
|
type AnyRecord = Record<Key, any>;
|
|
7
|
+
/**
|
|
8
|
+
* @internal
|
|
9
|
+
* Test-only handle on the proxy cache (deliberately NOT re-exported from the public barrel).
|
|
10
|
+
* Maps a store's backing signal to its lazily-built child proxies, each held via a `WeakRef`.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PROXY_CACHE: WeakMap<object, Map<PropertyKey, WeakRef<Signal<any>>>>;
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
* Test-only handle on the finalization registry (deliberately NOT re-exported from the public
|
|
16
|
+
* barrel). Prunes a cache entry once its proxy is reclaimed by the GC.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PROXY_CLEANUP: FinalizationRegistry<{
|
|
19
|
+
target: object;
|
|
20
|
+
prop: PropertyKey;
|
|
21
|
+
}>;
|
|
6
22
|
/**
|
|
7
23
|
* @internal
|
|
8
24
|
* Validates whether a value is a Signal Store.
|
|
@@ -25,28 +41,75 @@ type MutableArrayStore<T extends any[]> = MutableSignal<T> & {
|
|
|
25
41
|
readonly length: Signal<number>;
|
|
26
42
|
[Symbol.iterator](): Iterator<MutableSignalStore<T[number]>>;
|
|
27
43
|
};
|
|
28
|
-
|
|
44
|
+
/**
|
|
45
|
+
* @internal Resolves to `true` only for `any`. In a conditional type, `any` distributes across
|
|
46
|
+
* *both* branches (`unknown | object`), and `unknown | X` collapses to `unknown` — which would
|
|
47
|
+
* erase a store's property access and `extend`. Guarding on this routes an `any`-typed store to
|
|
48
|
+
* the full object shape instead.
|
|
49
|
+
*/
|
|
50
|
+
type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
51
|
+
/**
|
|
52
|
+
* @internal Flattens an intersection (`A & B & C`) into a single object literal so editor
|
|
53
|
+
* tooltips show the resolved members instead of the raw intersection chain. Display-only —
|
|
54
|
+
* structurally identical to its input.
|
|
55
|
+
*/
|
|
56
|
+
type Simplify<T> = {
|
|
57
|
+
[K in keyof T]: T[K];
|
|
58
|
+
} & {};
|
|
59
|
+
/** @internal The object shape of a readonly store: a child store per key, plus `extend`. */
|
|
60
|
+
type SignalStoreObject<T> = Simplify<Readonly<{
|
|
29
61
|
[K in keyof Required<T>]: SignalStore<NonNullable<T>[K]>;
|
|
30
|
-
}>
|
|
62
|
+
}> & {
|
|
63
|
+
readonly extend: {
|
|
64
|
+
<L extends AnyRecord>(source: Signal<L>): SignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
65
|
+
<L extends AnyRecord>(props: L): SignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
66
|
+
};
|
|
67
|
+
}>;
|
|
68
|
+
/** @internal The object shape of a writable store. */
|
|
69
|
+
type WritableSignalStoreObject<T> = Simplify<Readonly<{
|
|
70
|
+
[K in keyof Required<T>]: WritableSignalStore<NonNullable<T>[K]>;
|
|
71
|
+
}> & {
|
|
72
|
+
readonly extend: {
|
|
73
|
+
<L extends AnyRecord>(source: WritableSignal<L>): WritableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
74
|
+
<L extends AnyRecord>(props: L): WritableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
75
|
+
};
|
|
76
|
+
}>;
|
|
77
|
+
/** @internal The object shape of a mutable store. */
|
|
78
|
+
type MutableSignalStoreObject<T> = Simplify<Readonly<{
|
|
79
|
+
[K in keyof Required<T>]: MutableSignalStore<NonNullable<T>[K]>;
|
|
80
|
+
}> & {
|
|
81
|
+
readonly extend: {
|
|
82
|
+
<L extends AnyRecord>(source: MutableSignal<L>): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
83
|
+
<L extends AnyRecord>(props: L): MutableSignalStore<Simplify<Omit<NonNullable<T>, keyof L> & L>>;
|
|
84
|
+
};
|
|
85
|
+
}>;
|
|
86
|
+
export type SignalStore<T> = Signal<T> & (IsAny<T> extends true ? SignalStoreObject<T> : NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? SignalArrayStore<NonNullable<T>> : SignalStoreObject<T>);
|
|
31
87
|
export type WritableSignalStore<T> = WritableSignal<T> & {
|
|
32
88
|
readonly asReadonlyStore: () => SignalStore<T>;
|
|
33
|
-
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? WritableArrayStore<NonNullable<T>> :
|
|
34
|
-
[K in keyof Required<T>]: WritableSignalStore<NonNullable<T>[K]>;
|
|
35
|
-
}>);
|
|
89
|
+
} & (IsAny<T> extends true ? WritableSignalStoreObject<T> : NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? WritableArrayStore<NonNullable<T>> : WritableSignalStoreObject<T>);
|
|
36
90
|
export type MutableSignalStore<T> = MutableSignal<T> & {
|
|
37
91
|
readonly asReadonlyStore: () => SignalStore<T>;
|
|
38
|
-
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? MutableArrayStore<NonNullable<T>> :
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
export declare function toStore<T extends AnyRecord>(source:
|
|
42
|
-
export declare function toStore<T extends AnyRecord>(source: WritableSignal<T>, injector?: Injector): WritableSignalStore<T>;
|
|
43
|
-
export declare function toStore<T extends AnyRecord>(source: Signal<T>, injector?: Injector): SignalStore<T>;
|
|
92
|
+
} & (IsAny<T> extends true ? MutableSignalStoreObject<T> : NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? MutableArrayStore<NonNullable<T>> : MutableSignalStoreObject<T>);
|
|
93
|
+
export declare function toStore<T extends AnyRecord>(source: MutableSignal<T>, injector?: Injector, vivify?: Vivify): MutableSignalStore<T>;
|
|
94
|
+
export declare function toStore<T extends AnyRecord>(source: WritableSignal<T>, injector?: Injector, vivify?: Vivify): WritableSignalStore<T>;
|
|
95
|
+
export declare function toStore<T extends AnyRecord>(source: Signal<T>, injector?: Injector, vivify?: Vivify): SignalStore<T>;
|
|
44
96
|
/**
|
|
45
97
|
* Creates a WritableSignalStore from a value.
|
|
46
98
|
* @see {@link toStore}
|
|
47
99
|
*/
|
|
48
100
|
export declare function store<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
49
101
|
injector?: Injector;
|
|
102
|
+
/**
|
|
103
|
+
* Opt-in autovivification: when writing through a `null`/`undefined` path, create the
|
|
104
|
+
* missing intermediate containers instead of dropping the write. Off by default.
|
|
105
|
+
*
|
|
106
|
+
* Levels whose current value is a known object/array re-vivify as that same shape — the
|
|
107
|
+
* knowledge is captured when the path is first accessed and cached, so it holds even after
|
|
108
|
+
* the value is later nulled. This option governs only genuinely-unknown (currently
|
|
109
|
+
* `null`/`undefined`) levels: `'auto'` (an array for index keys, an object otherwise), an
|
|
110
|
+
* explicit `'object'`/`'array'`, or a `() => container` factory. See {@link Vivify}.
|
|
111
|
+
*/
|
|
112
|
+
vivify?: Vivify;
|
|
50
113
|
}): WritableSignalStore<T>;
|
|
51
114
|
/**
|
|
52
115
|
* Creates a MutableSignalStore from a value.
|
|
@@ -54,5 +117,16 @@ export declare function store<T extends AnyRecord>(value: T, opt?: CreateSignalO
|
|
|
54
117
|
*/
|
|
55
118
|
export declare function mutableStore<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
56
119
|
injector?: Injector;
|
|
120
|
+
/**
|
|
121
|
+
* Opt-in autovivification: when writing through a `null`/`undefined` path, create the
|
|
122
|
+
* missing intermediate containers instead of dropping the write. Off by default.
|
|
123
|
+
*
|
|
124
|
+
* Levels whose current value is a known object/array re-vivify as that same shape — the
|
|
125
|
+
* knowledge is captured when the path is first accessed and cached, so it holds even after
|
|
126
|
+
* the value is later nulled. This option governs only genuinely-unknown (currently
|
|
127
|
+
* `null`/`undefined`) levels: `'auto'` (an array for index keys, an object otherwise), an
|
|
128
|
+
* explicit `'object'`/`'array'`, or a `() => container` factory. See {@link Vivify}.
|
|
129
|
+
*/
|
|
130
|
+
vivify?: Vivify;
|
|
57
131
|
}): MutableSignalStore<T>;
|
|
58
132
|
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
* Type guard for an array-index-like property key: a non-empty string that parses to a finite
|
|
4
|
+
* number (e.g. `'0'`, `'42'`). Used to choose array-vs-object shape during autovivification and
|
|
5
|
+
* deep store proxying.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isIndexProp(prop: PropertyKey): prop is `${number}`;
|