@mmstack/primitives 19.2.3 → 19.3.0
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/LICENSE +21 -21
- package/README.md +1038 -621
- package/fesm2022/mmstack-primitives.mjs +1172 -198
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/index.d.ts +6 -2
- package/lib/chunked.d.ts +36 -0
- package/lib/derived.d.ts +51 -2
- package/lib/effect/frame-stack.d.ts +10 -0
- package/lib/effect/index.d.ts +1 -0
- package/lib/effect/nested-effect.d.ts +77 -0
- package/lib/get-signal-equality.d.ts +1 -1
- package/lib/mappers/index-array.d.ts +54 -0
- package/lib/mappers/index.d.ts +3 -0
- package/lib/mappers/key-array.d.ts +28 -0
- package/lib/mappers/map-object.d.ts +15 -0
- package/lib/mappers/util.d.ts +9 -0
- package/lib/pipeable/operators.d.ts +14 -0
- package/lib/pipeable/pipeble.d.ts +23 -0
- package/lib/pipeable/public_api.d.ts +3 -0
- package/lib/pipeable/types.d.ts +62 -0
- package/lib/sensors/element-size.d.ts +35 -0
- package/lib/{element-visibility.d.ts → sensors/element-visibility.d.ts} +1 -1
- package/lib/sensors/index.d.ts +2 -0
- package/lib/sensors/media-query.d.ts +1 -1
- package/lib/sensors/mouse-position.d.ts +1 -1
- package/lib/sensors/network-status.d.ts +1 -1
- package/lib/sensors/page-visibility.d.ts +1 -1
- package/lib/sensors/sensor.d.ts +108 -22
- package/lib/sensors/window-size.d.ts +1 -1
- package/lib/store.d.ts +58 -0
- package/lib/stored.d.ts +6 -2
- package/lib/tabSync.d.ts +56 -0
- package/lib/throttled.d.ts +1 -1
- package/lib/to-writable.d.ts +9 -2
- package/lib/until.d.ts +28 -23
- package/package.json +6 -7
- package/lib/map-array.d.ts +0 -61
package/lib/sensors/sensor.d.ts
CHANGED
|
@@ -1,8 +1,85 @@
|
|
|
1
|
-
import { Signal } from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { type ElementRef, type Signal } from '@angular/core';
|
|
2
|
+
import { type ElementSizeOptions as BaseElementSizeOptions, type ElementSizeSignal } from './element-size';
|
|
3
|
+
import { type ElementVisibilityOptions as BaseElementVisibilityOptions, type ElementVisibilitySignal } from './element-visibility';
|
|
4
|
+
import { type MousePositionOptions, type MousePositionSignal } from './mouse-position';
|
|
5
|
+
import { type NetworkStatusSignal } from './network-status';
|
|
6
|
+
import { type ScrollPositionOptions, type ScrollPositionSignal } from './scroll-position';
|
|
7
|
+
import { type WindowSizeOptions, type WindowSizeSignal } from './window-size';
|
|
8
|
+
type SensorTypedOptions = {
|
|
9
|
+
elementVisibility: {
|
|
10
|
+
opt: BaseElementVisibilityOptions & {
|
|
11
|
+
target?: ElementRef<Element> | Element | Signal<ElementRef<Element> | Element | null>;
|
|
12
|
+
};
|
|
13
|
+
returnType: ElementVisibilitySignal;
|
|
14
|
+
};
|
|
15
|
+
elementSize: {
|
|
16
|
+
opt: BaseElementSizeOptions & {
|
|
17
|
+
target?: ElementRef<Element> | Element | Signal<ElementRef<Element> | Element | null>;
|
|
18
|
+
};
|
|
19
|
+
returnType: ElementSizeSignal;
|
|
20
|
+
};
|
|
21
|
+
mousePosition: {
|
|
22
|
+
opt: MousePositionOptions;
|
|
23
|
+
returnType: MousePositionSignal;
|
|
24
|
+
};
|
|
25
|
+
networkStatus: {
|
|
26
|
+
opt: {
|
|
27
|
+
debugName?: string;
|
|
28
|
+
};
|
|
29
|
+
returnType: NetworkStatusSignal;
|
|
30
|
+
};
|
|
31
|
+
pageVisibility: {
|
|
32
|
+
opt: {
|
|
33
|
+
debugName?: string;
|
|
34
|
+
};
|
|
35
|
+
returnType: Signal<DocumentVisibilityState>;
|
|
36
|
+
};
|
|
37
|
+
darkMode: {
|
|
38
|
+
opt: {
|
|
39
|
+
debugName?: string;
|
|
40
|
+
};
|
|
41
|
+
returnType: Signal<boolean>;
|
|
42
|
+
};
|
|
43
|
+
reducedMotion: {
|
|
44
|
+
opt: {
|
|
45
|
+
debugName?: string;
|
|
46
|
+
};
|
|
47
|
+
returnType: Signal<boolean>;
|
|
48
|
+
};
|
|
49
|
+
scrollPosition: {
|
|
50
|
+
opt: ScrollPositionOptions;
|
|
51
|
+
returnType: ScrollPositionSignal;
|
|
52
|
+
};
|
|
53
|
+
windowSize: {
|
|
54
|
+
opt: WindowSizeOptions;
|
|
55
|
+
returnType: WindowSizeSignal;
|
|
56
|
+
};
|
|
57
|
+
mediaQuery: {
|
|
58
|
+
opt: {
|
|
59
|
+
query: string;
|
|
60
|
+
debugName?: string;
|
|
61
|
+
};
|
|
62
|
+
returnType: Signal<boolean>;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Creates a sensor signal that the elements visiblity within the viewport
|
|
67
|
+
* @param type Must be `'elementVisibility'`.
|
|
68
|
+
* @param options Optional configuration IntersectionObserver & target.
|
|
69
|
+
* @returns A `ElementVisibilitySignal` that tracks whether the Element is intersected.
|
|
70
|
+
* @see {elementVisibility} for detailed documentation and examples.
|
|
71
|
+
* @example const pos = sensor('elementVisibility');
|
|
72
|
+
*/
|
|
73
|
+
export declare function sensor(type: 'elementVisibility', options?: SensorTypedOptions['elementVisibility']['opt']): ElementVisibilitySignal;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a sensor signal that tracks the element's size dimensions.
|
|
76
|
+
* @param type Must be `'elementSize'`.
|
|
77
|
+
* @param options Optional configuration ResizeObserver & target.
|
|
78
|
+
* @returns A `ElementSizeSignal` that tracks the element's size ({ width, height }).
|
|
79
|
+
* @see {elementSize} for detailed documentation and examples.
|
|
80
|
+
* @example const size = sensor('elementSize');
|
|
81
|
+
*/
|
|
82
|
+
export declare function sensor(type: 'elementSize', options?: SensorTypedOptions['elementSize']['opt']): ElementSizeSignal;
|
|
6
83
|
/**
|
|
7
84
|
* Creates a sensor signal that tracks the mouse cursor's position.
|
|
8
85
|
* @param type Must be `'mousePosition'`.
|
|
@@ -11,7 +88,7 @@ import { WindowSizeOptions, WindowSizeSignal } from './window-size';
|
|
|
11
88
|
* @see {mousePosition} for detailed documentation and examples.
|
|
12
89
|
* @example const pos = sensor('mousePosition', { coordinateSpace: 'page', throttle: 50 });
|
|
13
90
|
*/
|
|
14
|
-
export declare function sensor(type: 'mousePosition', options?:
|
|
91
|
+
export declare function sensor(type: 'mousePosition', options?: SensorTypedOptions['mousePosition']['opt']): MousePositionSignal;
|
|
15
92
|
/**
|
|
16
93
|
* Creates a sensor signal that tracks the browser's online/offline status.
|
|
17
94
|
* @param type Must be `'networkStatus'`.
|
|
@@ -20,9 +97,7 @@ export declare function sensor(type: 'mousePosition', options?: MousePositionOpt
|
|
|
20
97
|
* @see {networkStatus} for detailed documentation and examples.
|
|
21
98
|
* @example const onlineStatus = sensor('networkStatus');
|
|
22
99
|
*/
|
|
23
|
-
export declare function sensor(type: 'networkStatus', options?:
|
|
24
|
-
debugName?: string;
|
|
25
|
-
}): NetworkStatusSignal;
|
|
100
|
+
export declare function sensor(type: 'networkStatus', options?: SensorTypedOptions['networkStatus']['opt']): NetworkStatusSignal;
|
|
26
101
|
/**
|
|
27
102
|
* Creates a sensor signal that tracks the page's visibility state (e.g., 'visible', 'hidden').
|
|
28
103
|
* @param type Must be `'pageVisibility'`.
|
|
@@ -31,31 +106,34 @@ export declare function sensor(type: 'networkStatus', options?: {
|
|
|
31
106
|
* @see {pageVisibility} for detailed documentation and examples.
|
|
32
107
|
* @example const visibility = sensor('pageVisibility');
|
|
33
108
|
*/
|
|
34
|
-
export declare function sensor(type: 'pageVisibility', options?:
|
|
35
|
-
debugName?: string;
|
|
36
|
-
}): Signal<DocumentVisibilityState>;
|
|
109
|
+
export declare function sensor(type: 'pageVisibility', options?: SensorTypedOptions['pageVisibility']['opt']): Signal<DocumentVisibilityState>;
|
|
37
110
|
/**
|
|
38
111
|
* Creates a sensor signal that tracks the user's OS/browser preference for a dark color scheme.
|
|
39
|
-
* @param type Must be `'
|
|
112
|
+
* @param type Must be `'darkMode'`.
|
|
40
113
|
* @param options Optional configuration, currently only `debugName`.
|
|
41
114
|
* @returns A `Signal<boolean>` which is `true` if a dark theme is preferred.
|
|
42
115
|
* @see {prefersDarkMode} for detailed documentation and examples.
|
|
43
116
|
* @example const isDarkMode = sensor('dark-mode');
|
|
44
117
|
*/
|
|
45
|
-
export declare function sensor(type: 'dark-mode', options?:
|
|
46
|
-
debugName?: string;
|
|
47
|
-
}): Signal<boolean>;
|
|
118
|
+
export declare function sensor(type: 'darkMode' | 'dark-mode', options?: SensorTypedOptions['darkMode']['opt']): Signal<boolean>;
|
|
48
119
|
/**
|
|
49
120
|
* Creates a sensor signal that tracks the user's OS/browser preference for reduced motion.
|
|
50
|
-
* @param type Must be `'
|
|
121
|
+
* @param type Must be `'reducedMotion'`.
|
|
51
122
|
* @param options Optional configuration, currently only `debugName`.
|
|
52
123
|
* @returns A `Signal<boolean>` which is `true` if reduced motion is preferred.
|
|
53
124
|
* @see {prefersReducedMotion} for detailed documentation and examples.
|
|
54
125
|
* @example const wantsReducedMotion = sensor('reduced-motion');
|
|
55
126
|
*/
|
|
56
|
-
export declare function sensor(type: 'reduced-motion', options?:
|
|
57
|
-
|
|
58
|
-
|
|
127
|
+
export declare function sensor(type: 'reducedMotion' | 'reduced-motion', options?: SensorTypedOptions['reducedMotion']['opt']): Signal<boolean>;
|
|
128
|
+
/**
|
|
129
|
+
* Creates a sensor signal that tracks the provided media query.
|
|
130
|
+
* @param type Must be `'mediaQuery'`.
|
|
131
|
+
* @param options Optional configuration for the media query sensor, including `query` and `debugName`.
|
|
132
|
+
* @returns A `Signal<boolean>` which is `true` if the media query currently matches.
|
|
133
|
+
* @see {mediaQuery} for detailed documentation and examples.
|
|
134
|
+
* @example const isDesktop = sensor('mediaQuery', { query: '(min-width: 1024px)' });
|
|
135
|
+
*/
|
|
136
|
+
export declare function sensor(type: 'mediaQuery', options?: SensorTypedOptions['mediaQuery']['opt']): Signal<boolean>;
|
|
59
137
|
/**
|
|
60
138
|
* Creates a sensor signal that tracks the browser window's inner dimensions (width and height).
|
|
61
139
|
* @param type Must be `'windowSize'`.
|
|
@@ -64,7 +142,7 @@ export declare function sensor(type: 'reduced-motion', options?: {
|
|
|
64
142
|
* @see {windowSize} for detailed documentation and examples.
|
|
65
143
|
* @example const size = sensor('windowSize', { throttle: 200 });
|
|
66
144
|
*/
|
|
67
|
-
export declare function sensor(type: 'windowSize', options?:
|
|
145
|
+
export declare function sensor(type: 'windowSize', options?: SensorTypedOptions['windowSize']['opt']): WindowSizeSignal;
|
|
68
146
|
/**
|
|
69
147
|
* Creates a sensor signal that tracks the scroll position (x, y) of the window or a specified element.
|
|
70
148
|
* @param type Must be `'scrollPosition'`.
|
|
@@ -73,4 +151,12 @@ export declare function sensor(type: 'windowSize', options?: WindowSizeOptions):
|
|
|
73
151
|
* @see {scrollPosition} for detailed documentation and examples.
|
|
74
152
|
* @example const pageScroll = sensor('scrollPosition', { throttle: 150 });
|
|
75
153
|
*/
|
|
76
|
-
export declare function sensor(type: 'scrollPosition', options?:
|
|
154
|
+
export declare function sensor(type: 'scrollPosition', options?: SensorTypedOptions['scrollPosition']['opt']): ScrollPositionSignal;
|
|
155
|
+
type SensorsOptions<TKey extends keyof SensorTypedOptions> = {
|
|
156
|
+
[K in TKey]: SensorTypedOptions[K]['opt'];
|
|
157
|
+
};
|
|
158
|
+
type Sensors<TKey extends keyof SensorTypedOptions> = {
|
|
159
|
+
[K in TKey]: SensorTypedOptions[K]['returnType'];
|
|
160
|
+
};
|
|
161
|
+
export declare function sensors<const TType extends keyof SensorTypedOptions>(track: TType[], opt?: SensorsOptions<TType>): Sensors<TType>;
|
|
162
|
+
export {};
|
package/lib/store.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Injector, type CreateSignalOptions, type Signal, type WritableSignal } from '@angular/core';
|
|
2
|
+
import { type MutableSignal } from './mutable';
|
|
3
|
+
type BaseType = string | number | boolean | symbol | undefined | null | Function | Date | RegExp;
|
|
4
|
+
type Key = string | number;
|
|
5
|
+
type AnyRecord = Record<Key, any>;
|
|
6
|
+
/**
|
|
7
|
+
* @internal
|
|
8
|
+
* Validates whether a value is a Signal Store.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isStore<T>(value: unknown): value is SignalStore<T>;
|
|
11
|
+
type SignalArrayStore<T extends any[]> = Signal<T> & {
|
|
12
|
+
readonly [index: number]: SignalStore<T[number]>;
|
|
13
|
+
readonly length: Signal<number>;
|
|
14
|
+
[Symbol.iterator](): Iterator<SignalStore<T[number]>>;
|
|
15
|
+
};
|
|
16
|
+
type WritableArrayStore<T extends any[]> = WritableSignal<T> & {
|
|
17
|
+
readonly asReadonlyStore: () => SignalArrayStore<T>;
|
|
18
|
+
readonly [index: number]: WritableSignalStore<T[number]>;
|
|
19
|
+
readonly length: Signal<number>;
|
|
20
|
+
[Symbol.iterator](): Iterator<WritableSignalStore<T[number]>>;
|
|
21
|
+
};
|
|
22
|
+
type MutableArrayStore<T extends any[]> = MutableSignal<T> & {
|
|
23
|
+
readonly asReadonlyStore: () => SignalArrayStore<T>;
|
|
24
|
+
readonly [index: number]: MutableSignalStore<T[number]>;
|
|
25
|
+
readonly length: Signal<number>;
|
|
26
|
+
[Symbol.iterator](): Iterator<MutableSignalStore<T[number]>>;
|
|
27
|
+
};
|
|
28
|
+
export type SignalStore<T> = Signal<T> & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? SignalArrayStore<NonNullable<T>> : Readonly<{
|
|
29
|
+
[K in keyof Required<T>]: SignalStore<NonNullable<T>[K]>;
|
|
30
|
+
}>);
|
|
31
|
+
export type WritableSignalStore<T> = WritableSignal<T> & {
|
|
32
|
+
readonly asReadonlyStore: () => SignalStore<T>;
|
|
33
|
+
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? WritableArrayStore<NonNullable<T>> : Readonly<{
|
|
34
|
+
[K in keyof Required<T>]: WritableSignalStore<NonNullable<T>[K]>;
|
|
35
|
+
}>);
|
|
36
|
+
export type MutableSignalStore<T> = MutableSignal<T> & {
|
|
37
|
+
readonly asReadonlyStore: () => SignalStore<T>;
|
|
38
|
+
} & (NonNullable<T> extends BaseType ? unknown : NonNullable<T> extends Array<any> ? MutableArrayStore<NonNullable<T>> : Readonly<{
|
|
39
|
+
[K in keyof Required<T>]: MutableSignalStore<NonNullable<T>[K]>;
|
|
40
|
+
}>);
|
|
41
|
+
export declare function toStore<T extends AnyRecord>(source: MutableSignal<T>, injector?: Injector): MutableSignalStore<T>;
|
|
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>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates a WritableSignalStore from a value.
|
|
46
|
+
* @see {@link toStore}
|
|
47
|
+
*/
|
|
48
|
+
export declare function store<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
49
|
+
injector?: Injector;
|
|
50
|
+
}): WritableSignalStore<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Creates a MutableSignalStore from a value.
|
|
53
|
+
* @see {@link toStore}
|
|
54
|
+
*/
|
|
55
|
+
export declare function mutableStore<T extends AnyRecord>(value: T, opt?: CreateSignalOptions<T> & {
|
|
56
|
+
injector?: Injector;
|
|
57
|
+
}): MutableSignalStore<T>;
|
|
58
|
+
export {};
|
package/lib/stored.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type CreateSignalOptions, type Signal, type WritableSignal } from '@angular/core';
|
|
2
2
|
/**
|
|
3
3
|
* Interface for storage mechanisms compatible with the `stored` signal.
|
|
4
4
|
* Matches the essential parts of the `Storage` interface (`localStorage`, `sessionStorage`).
|
|
@@ -61,6 +61,10 @@ export type CreateStoredOptions<T> = CreateSignalOptions<T> & {
|
|
|
61
61
|
* If 'true', the signal will remove the old key from storage when the key changes, defaults to `false`.
|
|
62
62
|
*/
|
|
63
63
|
cleanupOldKey?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Optional validator, which is called on load of value. Store will be set to fallback if value is false
|
|
66
|
+
*/
|
|
67
|
+
validate?: (value: T) => boolean;
|
|
64
68
|
};
|
|
65
69
|
/**
|
|
66
70
|
* A specialized `WritableSignal` returned by the `stored()` function.
|
|
@@ -132,5 +136,5 @@ export type StoredSignal<T> = WritableSignal<T> & {
|
|
|
132
136
|
* }
|
|
133
137
|
* ```
|
|
134
138
|
*/
|
|
135
|
-
export declare function stored<T>(fallback: T, { key, store: providedStore, serialize, deserialize, syncTabs, equal, onKeyChange, cleanupOldKey, ...rest }: CreateStoredOptions<T>): StoredSignal<T>;
|
|
139
|
+
export declare function stored<T>(fallback: T, { key, store: providedStore, serialize, deserialize, syncTabs, equal, onKeyChange, cleanupOldKey, validate, ...rest }: CreateStoredOptions<T>): StoredSignal<T>;
|
|
136
140
|
export {};
|
package/lib/tabSync.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type WritableSignal } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class MessageBus {
|
|
4
|
+
private readonly channel;
|
|
5
|
+
private readonly listeners;
|
|
6
|
+
subscribe<T>(id: string, listener: (data: T) => void): {
|
|
7
|
+
unsub: () => void;
|
|
8
|
+
post: (value: T) => void;
|
|
9
|
+
};
|
|
10
|
+
private unsubscribe;
|
|
11
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MessageBus, never>;
|
|
12
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<MessageBus>;
|
|
13
|
+
}
|
|
14
|
+
export declare function generateDeterministicID(): string;
|
|
15
|
+
type SyncSignalOptions = {
|
|
16
|
+
id?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Synchronizes a WritableSignal across browser tabs using BroadcastChannel API.
|
|
20
|
+
*
|
|
21
|
+
* Creates a shared signal that automatically syncs its value between all tabs
|
|
22
|
+
* of the same application. When the signal is updated in one tab, all other
|
|
23
|
+
* tabs will receive the new value automatically.
|
|
24
|
+
*
|
|
25
|
+
* @template T - The type of the WritableSignal
|
|
26
|
+
* @param sig - The WritableSignal to synchronize across tabs
|
|
27
|
+
* @param opt - Optional configuration object
|
|
28
|
+
* @param opt.id - Explicit channel ID for synchronization. If not provided,
|
|
29
|
+
* a deterministic ID is generated based on the call site.
|
|
30
|
+
* Use explicit IDs in production for reliability.
|
|
31
|
+
*
|
|
32
|
+
* @returns The same WritableSignal instance, now synchronized across tabs
|
|
33
|
+
*
|
|
34
|
+
* @throws {Error} When deterministic ID generation fails and no explicit ID is provided
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* // Basic usage - auto-generates channel ID from call site
|
|
39
|
+
* const theme = tabSync(signal('dark'));
|
|
40
|
+
*
|
|
41
|
+
* // With explicit ID (recommended for production)
|
|
42
|
+
* const userPrefs = tabSync(signal({ lang: 'en' }), { id: 'user-preferences' });
|
|
43
|
+
*
|
|
44
|
+
* // Changes in one tab will sync to all other tabs
|
|
45
|
+
* theme.set('light'); // All tabs will update to 'light'
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* - Only works in browser environments (returns original signal on server)
|
|
50
|
+
* - Uses a single BroadcastChannel for all synchronized signals
|
|
51
|
+
* - Automatically cleans up listeners when the injection context is destroyed
|
|
52
|
+
* - Initial signal value after sync setup is not broadcasted to prevent loops
|
|
53
|
+
*
|
|
54
|
+
*/
|
|
55
|
+
export declare function tabSync<T extends WritableSignal<any>>(sig: T, opt?: SyncSignalOptions): T;
|
|
56
|
+
export {};
|
package/lib/throttled.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CreateSignalOptions, DestroyRef, type WritableSignal } from '@angular/core';
|
|
2
|
-
import { DebouncedSignal } from './debounced';
|
|
2
|
+
import { type DebouncedSignal } from './debounced';
|
|
3
3
|
/**
|
|
4
4
|
* Options for creating a throttled writable signal.
|
|
5
5
|
* Extends Angular's `CreateSignalOptions` with a throttle time setting.
|
package/lib/to-writable.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Signal, WritableSignal } from '@angular/core';
|
|
1
|
+
import { type CreateSignalOptions, type Signal, type WritableSignal } from '@angular/core';
|
|
2
2
|
/**
|
|
3
3
|
* Converts a read-only `Signal` into a `WritableSignal` by providing custom `set` and, optionally, `update` functions.
|
|
4
4
|
* This can be useful for creating controlled write access to a signal that is otherwise read-only.
|
|
@@ -27,4 +27,11 @@ import { Signal, WritableSignal } from '@angular/core';
|
|
|
27
27
|
*
|
|
28
28
|
* writableSignal.set(5); // sets value of originalValue.a to 5 & triggers all signals
|
|
29
29
|
*/
|
|
30
|
-
export declare function toWritable<T>(
|
|
30
|
+
export declare function toWritable<T>(source: Signal<T>, set: (value: T) => void, update?: (updater: (value: T) => T) => void, opt?: CreateSignalOptions<T> & {
|
|
31
|
+
/**
|
|
32
|
+
* If `true` (the default), the returned signal will be a computed signal that depends on the source signal.
|
|
33
|
+
* If `false`, the returned signal will be a direct wrapper around the source signal without creating a new computed signal.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
pure?: boolean;
|
|
37
|
+
}): WritableSignal<T>;
|
package/lib/until.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DestroyRef, Injector, Signal } from '@angular/core';
|
|
1
|
+
import { DestroyRef, Injector, type Signal } from '@angular/core';
|
|
2
2
|
export type UntilOptions = {
|
|
3
3
|
/**
|
|
4
4
|
* Optional timeout in milliseconds. If the condition is not met
|
|
@@ -14,38 +14,43 @@ export type UntilOptions = {
|
|
|
14
14
|
injector?: Injector;
|
|
15
15
|
};
|
|
16
16
|
/**
|
|
17
|
-
* Creates a Promise that resolves when a signal's value satisfies a
|
|
17
|
+
* Creates a Promise that resolves when a signal's value satisfies a type predicate.
|
|
18
18
|
*
|
|
19
|
-
* This is
|
|
20
|
-
*
|
|
19
|
+
* This overload is used when the predicate function is a type guard (e.g., `(v): v is MyType`).
|
|
20
|
+
* The returned promise will resolve with the narrowed type.
|
|
21
21
|
*
|
|
22
|
-
* @template T The type of the signal's value.
|
|
22
|
+
* @template T The base type of the signal's value.
|
|
23
|
+
* @template U The narrowed type asserted by the predicate.
|
|
23
24
|
* @param sourceSignal The signal to observe.
|
|
24
|
-
* @param predicate A function that
|
|
25
|
+
* @param predicate A type guard function that returns `true` if the value is of type `U`.
|
|
25
26
|
* @param options Optional configuration for timeout and explicit destruction.
|
|
26
|
-
* @returns A Promise that resolves with the signal's value
|
|
27
|
-
* or rejects on timeout or context destruction.
|
|
27
|
+
* @returns A Promise that resolves with the signal's value, narrowed to type `U`.
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
30
|
* ```ts
|
|
31
|
-
* const
|
|
31
|
+
* const event = signal<Event | null>(null);
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* console.error(e.message); // e.g., "until: Timeout after 5000ms."
|
|
40
|
-
* }
|
|
33
|
+
* // The returned promise is `Promise<MouseEvent>`
|
|
34
|
+
* const mouseEventPromise = until(event, (e): e is MouseEvent => e instanceof MouseEvent);
|
|
35
|
+
*
|
|
36
|
+
* async function logMouseEvent() {
|
|
37
|
+
* const me = await mouseEventPromise;
|
|
38
|
+
* console.log(me.clientX); // `me` is correctly typed as MouseEvent
|
|
41
39
|
* }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function until<T, U extends T>(sourceSignal: Signal<T>, predicate: (value: T) => value is U, options?: UntilOptions): Promise<U>;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a Promise that resolves when a signal's value satisfies a given predicate.
|
|
42
45
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* setTimeout(() => count.set(2), 1000);
|
|
46
|
-
* setTimeout(() => count.set(3), 1500);
|
|
46
|
+
* This is useful for imperatively waiting for a reactive state to change,
|
|
47
|
+
* for example, in tests or to orchestrate complex asynchronous operations.
|
|
47
48
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
49
|
+
* @template T The type of the signal's value.
|
|
50
|
+
* @param sourceSignal The signal to observe.
|
|
51
|
+
* @param predicate A function that takes the signal's value and returns `true` if the condition is met.
|
|
52
|
+
* @param options Optional configuration for timeout and explicit destruction.
|
|
53
|
+
* @returns A Promise that resolves with the signal's value when the predicate is true,
|
|
54
|
+
* or rejects on timeout or context destruction.
|
|
50
55
|
*/
|
|
51
56
|
export declare function until<T>(sourceSignal: Signal<T>, predicate: (value: T) => boolean, options?: UntilOptions): Promise<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmstack/primitives",
|
|
3
|
-
"version": "19.
|
|
3
|
+
"version": "19.3.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"angular",
|
|
6
6
|
"signals",
|
|
@@ -14,13 +14,9 @@
|
|
|
14
14
|
"url": "https://github.com/mihajm/mmstack"
|
|
15
15
|
},
|
|
16
16
|
"homepage": "https://github.com/mihajm/mmstack/blob/master/packages/primitives",
|
|
17
|
-
"dependencies": {
|
|
18
|
-
"@mmstack/object": "^19.2.0",
|
|
19
|
-
"tslib": "^2.3.0"
|
|
20
|
-
},
|
|
21
17
|
"peerDependencies": {
|
|
22
|
-
"@angular/core": "
|
|
23
|
-
"@angular/common": "
|
|
18
|
+
"@angular/core": ">=19 <20",
|
|
19
|
+
"@angular/common": ">=19 <20"
|
|
24
20
|
},
|
|
25
21
|
"sideEffects": false,
|
|
26
22
|
"module": "fesm2022/mmstack-primitives.mjs",
|
|
@@ -33,5 +29,8 @@
|
|
|
33
29
|
"types": "./index.d.ts",
|
|
34
30
|
"default": "./fesm2022/mmstack-primitives.mjs"
|
|
35
31
|
}
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"tslib": "^2.3.0"
|
|
36
35
|
}
|
|
37
36
|
}
|
package/lib/map-array.d.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { type CreateSignalOptions, type Signal } from '@angular/core';
|
|
2
|
-
/**
|
|
3
|
-
* Reactively maps items from a source array (or signal of an array) using a provided mapping function.
|
|
4
|
-
*
|
|
5
|
-
* This function serves a similar purpose to SolidJS's `mapArray` by providing stability
|
|
6
|
-
* for mapped items. It receives a source function returning an array (or a Signal<T[]>)
|
|
7
|
-
* and a mapping function.
|
|
8
|
-
*
|
|
9
|
-
* For each item in the source array, it creates a stable `computed` signal representing
|
|
10
|
-
* that item's value at its current index. This stable signal (`Signal<T>`) is passed
|
|
11
|
-
* to the mapping function. This ensures that downstream computations or components
|
|
12
|
-
* depending on the mapped result only re-render or re-calculate for the specific items
|
|
13
|
-
* that have changed, or when items are added/removed, rather than re-evaluating everything
|
|
14
|
-
* when the source array reference changes but items remain the same.
|
|
15
|
-
*
|
|
16
|
-
* It efficiently handles changes in the source array's length by reusing existing mapped
|
|
17
|
-
* results when possible, slicing when the array shrinks, and appending new mapped items
|
|
18
|
-
* when it grows.
|
|
19
|
-
*
|
|
20
|
-
* @template T The type of items in the source array.
|
|
21
|
-
* @template U The type of items in the resulting mapped array.
|
|
22
|
-
*
|
|
23
|
-
* @param source A function returning the source array `T[]`, or a `Signal<T[]>` itself.
|
|
24
|
-
* The `mapArray` function will reactively update based on changes to this source.
|
|
25
|
-
* @param map The mapping function. It is called for each item in the source array.
|
|
26
|
-
* It receives:
|
|
27
|
-
* - `value`: A stable `Signal<T>` representing the item at the current index.
|
|
28
|
-
* Use this signal within your mapping logic if you need reactivity
|
|
29
|
-
* tied to the specific item's value changes.
|
|
30
|
-
* - `index`: The number index of the item in the array.
|
|
31
|
-
* It should return the mapped value `U`.
|
|
32
|
-
* @param [opt] Optional `CreateSignalOptions<T>`. These options are passed directly
|
|
33
|
-
* to the `computed` signal created for each individual item (`Signal<T>`).
|
|
34
|
-
* This allows specifying options like a custom `equal` function for item comparison.
|
|
35
|
-
*
|
|
36
|
-
* @returns A `Signal<U[]>` containing the mapped array. This signal updates whenever
|
|
37
|
-
* the source array changes (either length or the values of its items).
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```ts
|
|
41
|
-
* const sourceItems = signal([
|
|
42
|
-
* { id: 1, name: 'Apple' },
|
|
43
|
-
* { id: 2, name: 'Banana' }
|
|
44
|
-
* ]);
|
|
45
|
-
*
|
|
46
|
-
* const mappedItems = mapArray(
|
|
47
|
-
* sourceItems,
|
|
48
|
-
* (itemSignal, index) => {
|
|
49
|
-
* // itemSignal is stable for a given item based on its index.
|
|
50
|
-
* // We create a computed here to react to changes in the item's name.
|
|
51
|
-
* return computed(() => `${index}: ${itemSignal().name.toUpperCase()}`);
|
|
52
|
-
* },
|
|
53
|
-
* // Example optional options (e.g., custom equality for item signals)
|
|
54
|
-
* { equal: (a, b) => a.id === b.id && a.name === b.name }
|
|
55
|
-
* );
|
|
56
|
-
* ```
|
|
57
|
-
* @remarks
|
|
58
|
-
* This function achieves its high performance by leveraging the new `linkedSignal`
|
|
59
|
-
* API from Angular, which allows for efficient memoization and reuse of array items.
|
|
60
|
-
*/
|
|
61
|
-
export declare function mapArray<T, U>(source: () => T[], map: (value: Signal<T>, index: number) => U, opt?: CreateSignalOptions<T>): Signal<U[]>;
|