@mmstack/primitives 19.2.3 → 20.0.1
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/fesm2022/mmstack-primitives.mjs +98 -62
- package/fesm2022/mmstack-primitives.mjs.map +1 -1
- package/index.d.ts +1329 -11
- package/package.json +4 -4
- package/lib/debounced.d.ts +0 -97
- package/lib/derived.d.ts +0 -139
- package/lib/element-visibility.d.ts +0 -66
- package/lib/get-signal-equality.d.ts +0 -5
- package/lib/map-array.d.ts +0 -61
- package/lib/mutable.d.ts +0 -95
- package/lib/sensors/index.d.ts +0 -7
- package/lib/sensors/media-query.d.ts +0 -94
- package/lib/sensors/mouse-position.d.ts +0 -80
- package/lib/sensors/network-status.d.ts +0 -20
- package/lib/sensors/page-visibility.d.ts +0 -38
- package/lib/sensors/scroll-position.d.ts +0 -84
- package/lib/sensors/sensor.d.ts +0 -76
- package/lib/sensors/window-size.d.ts +0 -75
- package/lib/stored.d.ts +0 -136
- package/lib/throttled.d.ts +0 -75
- package/lib/to-writable.d.ts +0 -30
- package/lib/until.d.ts +0 -51
- package/lib/with-history.d.ts +0 -94
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmstack/primitives",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "20.0.1",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"angular",
|
|
6
6
|
"signals",
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
},
|
|
16
16
|
"homepage": "https://github.com/mihajm/mmstack/blob/master/packages/primitives",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@mmstack/object": "^
|
|
18
|
+
"@mmstack/object": "^20.0.0",
|
|
19
19
|
"tslib": "^2.3.0"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@angular/core": "~
|
|
23
|
-
"@angular/common": "~
|
|
22
|
+
"@angular/core": "~20.0.3",
|
|
23
|
+
"@angular/common": "~20.0.3"
|
|
24
24
|
},
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"module": "fesm2022/mmstack-primitives.mjs",
|
package/lib/debounced.d.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { type CreateSignalOptions, DestroyRef, type Signal, type WritableSignal } from '@angular/core';
|
|
2
|
-
/**
|
|
3
|
-
* Options for creating a debounced writable signal.
|
|
4
|
-
* Extends Angular's `CreateSignalOptions` with a debounce time setting.
|
|
5
|
-
*
|
|
6
|
-
* @template T The type of value held by the signal.
|
|
7
|
-
*/
|
|
8
|
-
export type CreateDebouncedOptions<T> = CreateSignalOptions<T> & {
|
|
9
|
-
/**
|
|
10
|
-
* The debounce delay in milliseconds. Specifies how long to wait after the
|
|
11
|
-
* last `set` or `update` call before the debounced signal reflects the new value.
|
|
12
|
-
*/
|
|
13
|
-
ms?: number;
|
|
14
|
-
/**
|
|
15
|
-
* Optional `DestroyRef` to clean up the debounce timer when the signal is destroyed.
|
|
16
|
-
* If provided, the timer will be cleared when the signal is destroyed.
|
|
17
|
-
* If the signal is called within a reactive context a DestroyRef is injected automatically.
|
|
18
|
-
* If it is not provided or injected, the timer will not be cleared automatically...which is usually fine :)
|
|
19
|
-
*/
|
|
20
|
-
destroyRef?: DestroyRef;
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* A specialized `WritableSignal` whose publicly readable value updates are debounced.
|
|
24
|
-
*
|
|
25
|
-
* It provides access to the underlying, non-debounced signal via the `original` property.
|
|
26
|
-
*
|
|
27
|
-
* @template T The type of value held by the signal.
|
|
28
|
-
*/
|
|
29
|
-
export type DebouncedSignal<T> = WritableSignal<T> & {
|
|
30
|
-
/**
|
|
31
|
-
* A reference to the original, inner `WritableSignal`.
|
|
32
|
-
* This signal's value is updated *immediately* upon calls to `set` or `update`
|
|
33
|
-
* on the parent `DebouncedSignal`. Useful for accessing the latest value
|
|
34
|
-
* without the debounce delay.
|
|
35
|
-
*/
|
|
36
|
-
original: Signal<T>;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* A convenience function that creates and debounces a new `WritableSignal` in one step.
|
|
40
|
-
*
|
|
41
|
-
* @see {debounce} for the core implementation details.
|
|
42
|
-
*
|
|
43
|
-
* @template T The type of value the signal holds.
|
|
44
|
-
* @param initial The initial value of the signal.
|
|
45
|
-
* @param opt Options for signal creation, including debounce time `ms`.
|
|
46
|
-
* @returns A `DebouncedSignal<T>` instance.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* // The existing example remains perfect here.
|
|
50
|
-
* const query = debounced('', { ms: 500 });
|
|
51
|
-
* effect(() => console.log('Debounced Query:', query()));
|
|
52
|
-
* query.set('abc');
|
|
53
|
-
* // ...500ms later...
|
|
54
|
-
* // Output: Debounced Query: abc
|
|
55
|
-
*/
|
|
56
|
-
export declare function debounced<T>(initial: T, opt?: CreateDebouncedOptions<T>): DebouncedSignal<T>;
|
|
57
|
-
/**
|
|
58
|
-
* Wraps an existing `WritableSignal` to create a new one whose readable value is debounced.
|
|
59
|
-
*
|
|
60
|
-
* This implementation avoids using `effect` by pairing a trigger signal with an `untracked`
|
|
61
|
-
* read of the source signal to control when the debounced value is re-evaluated.
|
|
62
|
-
*
|
|
63
|
-
* @template T The type of value the signal holds.
|
|
64
|
-
* @param source The source `WritableSignal` to wrap. Writes are applied to this signal immediately.
|
|
65
|
-
* @param opt Options for debouncing, including debounce time `ms` and an optional `DestroyRef`.
|
|
66
|
-
* @returns A new `DebouncedSignal<T>` whose read value is debounced. The `.original` property
|
|
67
|
-
* of the returned signal is a reference back to the provided `source` signal.
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```ts
|
|
71
|
-
* import { signal, effect } from '@angular/core';
|
|
72
|
-
*
|
|
73
|
-
* // 1. Create a standard source signal.
|
|
74
|
-
* const sourceQuery = signal('');
|
|
75
|
-
*
|
|
76
|
-
* // 2. Create a debounced version of it.
|
|
77
|
-
* const debouncedQuery = debounce(sourceQuery, { ms: 500 });
|
|
78
|
-
*
|
|
79
|
-
* // This effect tracks the original signal and runs immediately.
|
|
80
|
-
* effect(() => {
|
|
81
|
-
* console.log('Original Query:', debouncedQuery.original());
|
|
82
|
-
* });
|
|
83
|
-
*
|
|
84
|
-
* // This effect tracks the debounced signal and runs after the delay.
|
|
85
|
-
* effect(() => {
|
|
86
|
-
* console.log('Debounced Query:', debouncedQuery());
|
|
87
|
-
* });
|
|
88
|
-
*
|
|
89
|
-
* console.log('Setting query to "a"');
|
|
90
|
-
* debouncedQuery.set('a');
|
|
91
|
-
* // Output: Original Query: a
|
|
92
|
-
*
|
|
93
|
-
* // ...500ms later...
|
|
94
|
-
* // Output: Debounced Query: a
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
export declare function debounce<T>(source: WritableSignal<T>, opt?: CreateDebouncedOptions<T>): DebouncedSignal<T>;
|
package/lib/derived.d.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { CreateSignalOptions, type WritableSignal } from '@angular/core';
|
|
2
|
-
import type { UnknownObject } from '@mmstack/object';
|
|
3
|
-
/**
|
|
4
|
-
* Options for creating a derived signal using the full `derived` function signature.
|
|
5
|
-
* @typeParam T - The type of the source signal's value (parent).
|
|
6
|
-
* @typeParam U - The type of the derived signal's value (child).
|
|
7
|
-
*/
|
|
8
|
-
type CreateDerivedOptions<T, U> = CreateSignalOptions<U> & {
|
|
9
|
-
/**
|
|
10
|
-
* A function that extracts the derived value (`U`) from the source signal's value (`T`).
|
|
11
|
-
*/
|
|
12
|
-
from: (v: T) => U;
|
|
13
|
-
/**
|
|
14
|
-
* A function that updates the source signal's value (`T`) when the derived signal's value (`U`) changes.
|
|
15
|
-
* This establishes the two-way binding.
|
|
16
|
-
*/
|
|
17
|
-
onChange: (newValue: U) => void;
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* A `WritableSignal` that derives its value from another `WritableSignal` (the "source" signal).
|
|
21
|
-
* It provides two-way binding: changes to the source signal update the derived signal, and
|
|
22
|
-
* changes to the derived signal update the source signal.
|
|
23
|
-
*
|
|
24
|
-
* @typeParam T - The type of the source signal's value (parent).
|
|
25
|
-
* @typeParam U - The type of the derived signal's value (child).
|
|
26
|
-
*/
|
|
27
|
-
export type DerivedSignal<T, U> = WritableSignal<U> & {
|
|
28
|
-
/**
|
|
29
|
-
* The function used to derive the derived signal's value from the source signal's value.
|
|
30
|
-
* This is primarily for internal use and introspection.
|
|
31
|
-
*/
|
|
32
|
-
from: (v: T) => U;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Creates a `DerivedSignal` that derives its value from another `WritableSignal`.
|
|
36
|
-
* This overload provides the most flexibility, allowing you to specify custom `from` and `onChange` functions.
|
|
37
|
-
*
|
|
38
|
-
* @typeParam T The type of the source signal's value.
|
|
39
|
-
* @typeParam U The type of the derived signal's value.
|
|
40
|
-
* @param source The source `WritableSignal`.
|
|
41
|
-
* @param options An object containing the `from` and `onChange` functions, and optional signal options.
|
|
42
|
-
* @returns A `DerivedSignal` instance.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* const user = signal({ name: 'John', age: 30 });
|
|
47
|
-
* const name = derived(user, {
|
|
48
|
-
* from: (u) => u.name,
|
|
49
|
-
* onChange: (newName) => user.update((u) => ({ ...u, name: newName })),
|
|
50
|
-
* });
|
|
51
|
-
*
|
|
52
|
-
* name.set('Jane'); // Updates the original signal
|
|
53
|
-
* console.log(user().name); // Outputs: Jane
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export declare function derived<T, U>(source: WritableSignal<T>, opt: CreateDerivedOptions<T, U>): DerivedSignal<T, U>;
|
|
57
|
-
/**
|
|
58
|
-
* Creates a `DerivedSignal` that derives a property from an object held by the source signal.
|
|
59
|
-
* This overload is a convenient shorthand for accessing object properties.
|
|
60
|
-
*
|
|
61
|
-
* @typeParam T The type of the source signal's value (must be an object).
|
|
62
|
-
* @typeParam TKey The key of the property to derive.
|
|
63
|
-
* @param source The source `WritableSignal` (holding an object).
|
|
64
|
-
* @param key The key of the property to derive.
|
|
65
|
-
* @param options Optional signal options for the derived signal.
|
|
66
|
-
* @returns A `DerivedSignal` instance.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```ts
|
|
70
|
-
* const user = signal({ name: 'John', age: 30 });
|
|
71
|
-
* const name = derived(user, 'name');
|
|
72
|
-
*
|
|
73
|
-
* console.log(name()); // Outputs: John
|
|
74
|
-
*
|
|
75
|
-
* // Update the derived signal, which also updates the source
|
|
76
|
-
* name.set('Jane');
|
|
77
|
-
*
|
|
78
|
-
* console.log(user().name); // Outputs: Jane
|
|
79
|
-
* ```
|
|
80
|
-
*/
|
|
81
|
-
export declare function derived<T extends UnknownObject, TKey extends keyof T>(source: WritableSignal<T>, key: TKey, opt?: CreateSignalOptions<T[TKey]>): DerivedSignal<T, T[TKey]>;
|
|
82
|
-
/**
|
|
83
|
-
* Creates a `DerivedSignal` from an array, deriving an element by its index.
|
|
84
|
-
* This overload is a convenient shorthand for accessing array elements.
|
|
85
|
-
*
|
|
86
|
-
* @typeParam T The type of the source signal's value (must be an array).
|
|
87
|
-
* @param source The source `WritableSignal` (holding an array).
|
|
88
|
-
* @param index The index of the element to derive.
|
|
89
|
-
* @param options Optional signal options for the derived signal.
|
|
90
|
-
* @returns A `DerivedSignal` instance.
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```ts
|
|
94
|
-
* const numbers = signal([1, 2, 3]);
|
|
95
|
-
* const secondNumber = derived(numbers, 1);
|
|
96
|
-
*
|
|
97
|
-
* console.log(secondNumber()); // Outputs: 2
|
|
98
|
-
*
|
|
99
|
-
* // Update the derived signal, which also updates the source
|
|
100
|
-
* secondNumber.set(5);
|
|
101
|
-
*
|
|
102
|
-
* console.log(numbers()); // Outputs: [1, 5, 3]
|
|
103
|
-
* ```
|
|
104
|
-
*/
|
|
105
|
-
export declare function derived<T extends any[]>(source: WritableSignal<T>, index: number, opt?: CreateSignalOptions<T[number]>): DerivedSignal<T, T[number]>;
|
|
106
|
-
/**
|
|
107
|
-
* Creates a "fake" `DerivedSignal` from a simple value. This is useful for creating
|
|
108
|
-
* `FormControlSignal` instances that are not directly derived from another signal.
|
|
109
|
-
* The returned signal's `from` function will always return the initial value.
|
|
110
|
-
*
|
|
111
|
-
* @typeParam T - This type parameter is not used in the implementation but is kept for type compatibility with `DerivedSignal`.
|
|
112
|
-
* @typeParam U - The type of the signal's value.
|
|
113
|
-
* @param initial - The initial value of the signal.
|
|
114
|
-
* @returns A `DerivedSignal` instance.
|
|
115
|
-
* @internal
|
|
116
|
-
*/
|
|
117
|
-
export declare function toFakeDerivation<T, U>(initial: U): DerivedSignal<T, U>;
|
|
118
|
-
/**
|
|
119
|
-
* Creates a "fake" `DerivedSignal` from an existing `WritableSignal`. This is useful
|
|
120
|
-
* for treating a regular `WritableSignal` as a `DerivedSignal` without changing its behavior.
|
|
121
|
-
* The returned signal's `from` function returns the current value of signal, using `untracked`.
|
|
122
|
-
*
|
|
123
|
-
* @typeParam T - This type parameter is not used in the implementation but is kept for type compatibility with `DerivedSignal`.
|
|
124
|
-
* @typeParam U - The type of the signal's value.
|
|
125
|
-
* @param initial - The existing `WritableSignal`.
|
|
126
|
-
* @returns A `DerivedSignal` instance.
|
|
127
|
-
* @internal
|
|
128
|
-
*/
|
|
129
|
-
export declare function toFakeSignalDerivation<T, U>(initial: WritableSignal<U>): DerivedSignal<T, U>;
|
|
130
|
-
/**
|
|
131
|
-
* Type guard function to check if a given `WritableSignal` is a `DerivedSignal`.
|
|
132
|
-
*
|
|
133
|
-
* @typeParam T - The type of the source signal's value (optional, defaults to `any`).
|
|
134
|
-
* @typeParam U - The type of the derived signal's value (optional, defaults to `any`).
|
|
135
|
-
* @param sig - The `WritableSignal` to check.
|
|
136
|
-
* @returns `true` if the signal is a `DerivedSignal`, `false` otherwise.
|
|
137
|
-
*/
|
|
138
|
-
export declare function isDerivation<T, U>(sig: WritableSignal<U>): sig is DerivedSignal<T, U>;
|
|
139
|
-
export {};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { ElementRef, Signal } from '@angular/core';
|
|
2
|
-
/**
|
|
3
|
-
* Options for configuring the `elementVisibility` sensor, extending
|
|
4
|
-
* standard `IntersectionObserverInit` options.
|
|
5
|
-
*/
|
|
6
|
-
export type ElementVisibilityOptions = IntersectionObserverInit & {
|
|
7
|
-
/** Optional debug name for the internal signal. */
|
|
8
|
-
debugName?: string;
|
|
9
|
-
};
|
|
10
|
-
export type ElementVisibilitySignal = Signal<IntersectionObserverEntry | undefined> & {
|
|
11
|
-
readonly visible: Signal<boolean>;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Creates a read-only signal that tracks the intersection status of a target DOM element
|
|
15
|
-
* with the viewport or a specified root element, using the `IntersectionObserver` API.
|
|
16
|
-
*
|
|
17
|
-
* It can observe a static `ElementRef`/`Element` or a `Signal` that resolves to one,
|
|
18
|
-
* allowing for dynamic targets.
|
|
19
|
-
*
|
|
20
|
-
* @param target The DOM element (or `ElementRef`, or a `Signal` resolving to one) to observe.
|
|
21
|
-
* If the signal resolves to `null`, observation stops.
|
|
22
|
-
* @param options Optional `IntersectionObserverInit` options (e.g., `root`, `rootMargin`, `threshold`)
|
|
23
|
-
* and an optional `debugName`.
|
|
24
|
-
* @returns A `Signal<IntersectionObserverEntry | undefined>`. It emits `undefined` initially,
|
|
25
|
-
* on the server, or if the target is `null`. Otherwise, it emits the latest
|
|
26
|
-
* `IntersectionObserverEntry`. Consumers can derive a boolean `isVisible` from
|
|
27
|
-
* this entry's `isIntersecting` property.
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* ```ts
|
|
31
|
-
* import { Component, effect, ElementRef, viewChild } from '@angular/core';
|
|
32
|
-
* import { elementVisibility } from '@mmstack/primitives';
|
|
33
|
-
* import { computed } from '@angular/core'; // For derived boolean
|
|
34
|
-
*
|
|
35
|
-
* @Component({
|
|
36
|
-
* selector: 'app-lazy-image',
|
|
37
|
-
* template: `
|
|
38
|
-
* <div #imageContainer style="height: 200px; border: 1px dashed grey;">
|
|
39
|
-
* @if (isVisible()) {
|
|
40
|
-
* <img src="your-image-url.jpg" alt="Lazy loaded image" />
|
|
41
|
-
* <p>Image is VISIBLE!</p>
|
|
42
|
-
* } @else {
|
|
43
|
-
* <p>Scroll down to see the image...</p>
|
|
44
|
-
* }
|
|
45
|
-
* </div>
|
|
46
|
-
* `
|
|
47
|
-
* })
|
|
48
|
-
* export class LazyImageComponent {
|
|
49
|
-
* readonly imageContainer = viewChild.required<ElementRef<HTMLDivElement>>('imageContainer');
|
|
50
|
-
*
|
|
51
|
-
* // Observe the element, get the full IntersectionObserverEntry
|
|
52
|
-
* readonly intersectionEntry = elementVisibility(this.imageContainer);
|
|
53
|
-
*
|
|
54
|
-
* // Derive a simple boolean for visibility
|
|
55
|
-
* readonly isVisible = computed(() => this.intersectionEntry()?.isIntersecting ?? false);
|
|
56
|
-
*
|
|
57
|
-
* constructor() {
|
|
58
|
-
* effect(() => {
|
|
59
|
-
* console.log('Intersection Entry:', this.intersectionEntry());
|
|
60
|
-
* console.log('Is Visible:', this.isVisible());
|
|
61
|
-
* });
|
|
62
|
-
* }
|
|
63
|
-
* }
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export declare function elementVisibility(target?: ElementRef<Element> | Element | Signal<ElementRef<Element> | Element | null>, opt?: ElementVisibilityOptions): ElementVisibilitySignal;
|
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[]>;
|
package/lib/mutable.d.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { type CreateSignalOptions, type WritableSignal } from '@angular/core';
|
|
2
|
-
/**
|
|
3
|
-
* A `MutableSignal` is a special type of `WritableSignal` that allows for in-place mutation of its value.
|
|
4
|
-
* In addition to the standard `set` and `update` methods, it provides a `mutate` method. This is useful
|
|
5
|
-
* for performance optimization when dealing with complex objects or arrays, as it avoids unnecessary
|
|
6
|
-
* object copying.
|
|
7
|
-
*
|
|
8
|
-
* @typeParam T - The type of value held by the signal.
|
|
9
|
-
*/
|
|
10
|
-
export type MutableSignal<T> = WritableSignal<T> & {
|
|
11
|
-
/**
|
|
12
|
-
* Mutates the signal's value in-place. This is similar to `update`, but it's optimized for
|
|
13
|
-
* scenarios where you want to modify the existing object directly rather than creating a new one.
|
|
14
|
-
*
|
|
15
|
-
* @param updater - A function that takes the current value as input and modifies it directly.
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* const myArray = mutable([1, 2, 3]);
|
|
19
|
-
* myArray.mutate((arr) => {
|
|
20
|
-
* arr.push(4);
|
|
21
|
-
* return arr;
|
|
22
|
-
* }); // myArray() now returns [1, 2, 3, 4]
|
|
23
|
-
*/
|
|
24
|
-
mutate: WritableSignal<T>['update'];
|
|
25
|
-
/**
|
|
26
|
-
* Mutates the signal's value in-place, similar to `mutate`, but with a void-returning value in updater
|
|
27
|
-
* function. This further emphasizes that the mutation is happening inline, improving readability
|
|
28
|
-
* in some cases.
|
|
29
|
-
* @param updater - Function to change to the current value
|
|
30
|
-
* @example
|
|
31
|
-
* const myObject = mutable({ a: 1, b: 2 });
|
|
32
|
-
* myObject.inline((obj) => (obj.a = 3)); // myObject() now returns { a: 3, b: 2 }
|
|
33
|
-
*/
|
|
34
|
-
inline: (updater: (value: T) => void) => void;
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Creates a `MutableSignal`. This function overloads the standard `signal` function to provide
|
|
38
|
-
* the additional `mutate` and `inline` methods.
|
|
39
|
-
*
|
|
40
|
-
* @typeParam T The type of value held by the signal.
|
|
41
|
-
* @param initial The initial value of the signal.
|
|
42
|
-
* @param options Optional signal options, including a custom `equal` function.
|
|
43
|
-
* @returns A `MutableSignal` instance.
|
|
44
|
-
*
|
|
45
|
-
* ### Important Note on `computed` Signals
|
|
46
|
-
*
|
|
47
|
-
* When creating a `computed` signal that derives a non-primitive value (e.g., an object or array)
|
|
48
|
-
* from a `mutable` signal, you **must** provide the `{ equal: false }` option to the `computed`
|
|
49
|
-
* function.
|
|
50
|
-
*
|
|
51
|
-
* This is because a `.mutate()` call notifies its dependents that it has changed, but if the
|
|
52
|
-
* reference to a derived object hasn't changed, the `computed` signal will not trigger its
|
|
53
|
-
* own dependents by default.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* ```ts
|
|
57
|
-
* const state = mutable({ user: { name: 'John' }, lastUpdated: new Date() });
|
|
58
|
-
*
|
|
59
|
-
* // ✅ CORRECT: Deriving a primitive value works as expected.
|
|
60
|
-
* const name = computed(() => state().user.name);
|
|
61
|
-
*
|
|
62
|
-
* // ❌ INCORRECT: This will not update reliably after the first change.
|
|
63
|
-
* const userObject = computed(() => state().user);
|
|
64
|
-
*
|
|
65
|
-
* // ✅ CORRECT: For object derivations, `equal: false` is required.
|
|
66
|
-
* const userObjectFixed = computed(() => state().user, { equal: false });
|
|
67
|
-
*
|
|
68
|
-
* // This mutation will now correctly trigger effects depending on `userObjectFixed`.
|
|
69
|
-
* state.mutate(s => s.lastUpdated = new Date());
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
export declare function mutable<T>(): MutableSignal<T | undefined>;
|
|
73
|
-
export declare function mutable<T>(initial: T): MutableSignal<T>;
|
|
74
|
-
export declare function mutable<T>(initial: T, opt?: CreateSignalOptions<T>): MutableSignal<T>;
|
|
75
|
-
/**
|
|
76
|
-
* Type guard function to check if a given `WritableSignal` is a `MutableSignal`. This is useful
|
|
77
|
-
* for situations where you need to conditionally use the `mutate` or `inline` methods.
|
|
78
|
-
*
|
|
79
|
-
* @typeParam T - The type of the signal's value (optional, defaults to `any`).
|
|
80
|
-
* @param value - The `WritableSignal` to check.
|
|
81
|
-
* @returns `true` if the signal is a `MutableSignal`, `false` otherwise.
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* const mySignal = signal(0);
|
|
85
|
-
* const myMutableSignal = mutable(0);
|
|
86
|
-
*
|
|
87
|
-
* if (isMutable(mySignal)) {
|
|
88
|
-
* mySignal.mutate(x => x + 1); // This would cause a type error, as mySignal is not a MutableSignal.
|
|
89
|
-
* }
|
|
90
|
-
*
|
|
91
|
-
* if (isMutable(myMutableSignal)) {
|
|
92
|
-
* myMutableSignal.mutate(x => x + 1); // This is safe.
|
|
93
|
-
* }
|
|
94
|
-
*/
|
|
95
|
-
export declare function isMutable<T = any>(value: WritableSignal<T>): value is MutableSignal<T>;
|
package/lib/sensors/index.d.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { Signal } from '@angular/core';
|
|
2
|
-
/**
|
|
3
|
-
* Creates a read-only signal that reactively tracks whether a CSS media query
|
|
4
|
-
* string currently matches.
|
|
5
|
-
*
|
|
6
|
-
* It uses `window.matchMedia` to evaluate the query and listen for changes.
|
|
7
|
-
* The primitive is SSR-safe (defaults to `false` on the server) and automatically
|
|
8
|
-
* cleans up its event listeners when the creating context is destroyed.
|
|
9
|
-
*
|
|
10
|
-
* @param query The CSS media query string to evaluate (e.g., `'(min-width: 768px)'`, `'(prefers-color-scheme: dark)'`).
|
|
11
|
-
* @param debugName Optional debug name for the signal.
|
|
12
|
-
* @returns A read-only `Signal<boolean>` which is `true` if the media query
|
|
13
|
-
* currently matches, and `false` otherwise.
|
|
14
|
-
*
|
|
15
|
-
* @remarks
|
|
16
|
-
* - On the server, this signal will always return `false` by default.
|
|
17
|
-
* - It automatically updates if the match status of the media query changes in the browser.
|
|
18
|
-
* - Event listeners are cleaned up automatically via `DestroyRef` if created in an injection context.
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```ts
|
|
22
|
-
* import { Component, effect } from '@angular/core';
|
|
23
|
-
* import { mediaQuery } from '@mmstack/primitives';
|
|
24
|
-
*
|
|
25
|
-
* @Component({
|
|
26
|
-
* selector: 'app-responsive-layout',
|
|
27
|
-
* template: `
|
|
28
|
-
* @if (isDesktop()) {
|
|
29
|
-
* <p>Showing desktop layout.</p>
|
|
30
|
-
* } @else {
|
|
31
|
-
* <p>Showing mobile layout.</p>
|
|
32
|
-
* }
|
|
33
|
-
* `
|
|
34
|
-
* })
|
|
35
|
-
* export class ResponsiveLayoutComponent {
|
|
36
|
-
* readonly isDesktop = mediaQuery('(min-width: 1024px)');
|
|
37
|
-
*
|
|
38
|
-
* constructor() {
|
|
39
|
-
* effect(() => {
|
|
40
|
-
* console.log('Is desktop view:', this.isDesktop());
|
|
41
|
-
* });
|
|
42
|
-
* }
|
|
43
|
-
* }
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export declare function mediaQuery(query: string, debugName?: string): Signal<boolean>;
|
|
47
|
-
/**
|
|
48
|
-
* Creates a read-only signal that tracks the user's OS/browser preference
|
|
49
|
-
* for a dark color scheme using the `(prefers-color-scheme: dark)` media query.
|
|
50
|
-
*
|
|
51
|
-
* This is a convenience wrapper around the generic `mediaQuery` primitive.
|
|
52
|
-
* It's SSR-safe (defaults to `false` on the server) and automatically
|
|
53
|
-
* cleans up its event listeners.
|
|
54
|
-
*
|
|
55
|
-
* @param debugName Optional debug name for the signal.
|
|
56
|
-
* @returns A read-only `Signal<boolean>` which is `true` if a dark theme
|
|
57
|
-
* is preferred, and `false` otherwise.
|
|
58
|
-
* @see {mediaQuery} for the underlying implementation.
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```ts
|
|
62
|
-
* const isDarkMode = prefersDarkMode();
|
|
63
|
-
* effect(() => {
|
|
64
|
-
* document.body.classList.toggle('dark-theme', isDarkMode());
|
|
65
|
-
* });
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
export declare function prefersDarkMode(debugName?: string): Signal<boolean>;
|
|
69
|
-
/**
|
|
70
|
-
* Creates a read-only signal that tracks the user's OS/browser preference
|
|
71
|
-
* for reduced motion using the `(prefers-reduced-motion: reduce)` media query.
|
|
72
|
-
*
|
|
73
|
-
* This is a convenience wrapper around the generic `mediaQuery` primitive.
|
|
74
|
-
* It's SSR-safe (defaults to `false` on the server) and automatically
|
|
75
|
-
* cleans up its event listeners.
|
|
76
|
-
*
|
|
77
|
-
* @param debugName Optional debug name for the signal.
|
|
78
|
-
* @returns A read-only `Signal<boolean>` which is `true` if reduced motion
|
|
79
|
-
* is preferred, and `false` otherwise.
|
|
80
|
-
* @see {mediaQuery} for the underlying implementation.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```ts
|
|
84
|
-
* const reduceMotion = prefersReducedMotion();
|
|
85
|
-
* effect(() => {
|
|
86
|
-
* if (reduceMotion()) {
|
|
87
|
-
* // Apply simplified animations or disable them
|
|
88
|
-
* } else {
|
|
89
|
-
* // Apply full animations
|
|
90
|
-
* }
|
|
91
|
-
* });
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
export declare function prefersReducedMotion(debugName?: string): Signal<boolean>;
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { ElementRef, Signal } from '@angular/core';
|
|
2
|
-
type MousePosition = {
|
|
3
|
-
x: number;
|
|
4
|
-
y: number;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Options for configuring the `mousePosition` sensor.
|
|
8
|
-
*/
|
|
9
|
-
export type MousePositionOptions = {
|
|
10
|
-
/**
|
|
11
|
-
* The target element to listen for mouse movements on.
|
|
12
|
-
* Can be `window`, `document`, an `HTMLElement`, or an `ElementRef<HTMLElement>`.
|
|
13
|
-
* @default window
|
|
14
|
-
*/
|
|
15
|
-
target?: Window | Document | HTMLElement | ElementRef<HTMLElement>;
|
|
16
|
-
/**
|
|
17
|
-
* Defines the coordinate system for the reported position.
|
|
18
|
-
* - `'client'`: Coordinates relative to the viewport (`clientX`, `clientY`).
|
|
19
|
-
* - `'page'`: Coordinates relative to the entire document (`pageX`, `pageY`).
|
|
20
|
-
* @default 'client'
|
|
21
|
-
*/
|
|
22
|
-
coordinateSpace?: 'client' | 'page';
|
|
23
|
-
/**
|
|
24
|
-
* If `true`, the sensor will also listen to `touchmove` events and report
|
|
25
|
-
* the coordinates of the first touch point.
|
|
26
|
-
* @default false
|
|
27
|
-
*/
|
|
28
|
-
touch?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Optional debug name for the internal signal.
|
|
31
|
-
*/
|
|
32
|
-
debugName?: string;
|
|
33
|
-
/**
|
|
34
|
-
* Optional delay in milliseconds to throttle the updates.
|
|
35
|
-
* @default 100
|
|
36
|
-
*/
|
|
37
|
-
throttle?: number;
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* A specialized Signal that tracks mouse position within an element.
|
|
41
|
-
* It's a throttled signal of the mouse coordinates with an attached `unthrottled` signal.
|
|
42
|
-
*/
|
|
43
|
-
export type MousePositionSignal = Signal<MousePosition> & {
|
|
44
|
-
/** A signal providing the raw, unthrottled mouse position. */
|
|
45
|
-
readonly unthrottled: Signal<MousePosition>;
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* Creates a read-only signal that tracks the mouse cursor's position.
|
|
49
|
-
*
|
|
50
|
-
* It can track mouse movements on a specific target (window, document, or element)
|
|
51
|
-
* and optionally include touch movements. The coordinate space ('client' or 'page')
|
|
52
|
-
* can also be configured.
|
|
53
|
-
* The primitive is SSR-safe and automatically cleans up its event listeners.
|
|
54
|
-
*
|
|
55
|
-
* @param options Optional configuration for the sensor.
|
|
56
|
-
* @returns A read-only `Signal<MousePosition>`. On the server, it returns a static
|
|
57
|
-
* signal with `{ x: 0, y: 0 }`.
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```ts
|
|
61
|
-
* import { Component, effect } from '@angular/core';
|
|
62
|
-
* import { mousePosition } from '@mmstack/primitives';
|
|
63
|
-
*
|
|
64
|
-
* @Component({
|
|
65
|
-
* selector: 'app-mouse-tracker',
|
|
66
|
-
* template: `<p>Mouse Position: X: {{ pos().x }}, Y: {{ pos().y }}</p>`
|
|
67
|
-
* })
|
|
68
|
-
* export class MouseTrackerComponent {
|
|
69
|
-
* readonly pos = mousePosition({ coordinateSpace: 'page' });
|
|
70
|
-
*
|
|
71
|
-
* constructor() {
|
|
72
|
-
* effect(() => {
|
|
73
|
-
* console.log('Mouse moved to:', this.pos());
|
|
74
|
-
* });
|
|
75
|
-
* }
|
|
76
|
-
* }
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
export declare function mousePosition(opt?: MousePositionOptions): MousePositionSignal;
|
|
80
|
-
export {};
|