@fluixi/reactive 1.0.0-alpha.100
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 -0
- package/README.md +280 -0
- package/dist/cdn/reactive.cjs +2803 -0
- package/dist/cdn/reactive.d.ts +11 -0
- package/dist/cdn/reactive.d.ts.map +1 -0
- package/dist/cdn/reactive.global.js +2 -0
- package/dist/cdn/reactive.js +10 -0
- package/dist/cdn/reactive.mjs +2787 -0
- package/dist/cdn/signal.cjs +299 -0
- package/dist/cdn/signal.d.ts +19 -0
- package/dist/cdn/signal.d.ts.map +1 -0
- package/dist/cdn/signal.global.js +2 -0
- package/dist/cdn/signal.js +18 -0
- package/dist/cdn/signal.mjs +276 -0
- package/dist/index.cjs +2803 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +2787 -0
- package/dist/lib/index.cjs +2804 -0
- package/dist/lib/index.d.ts +8 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +11 -0
- package/dist/lib/index.mjs +2789 -0
- package/dist/lib/observable/index.cjs +386 -0
- package/dist/lib/observable/index.d.ts +4 -0
- package/dist/lib/observable/index.d.ts.map +1 -0
- package/dist/lib/observable/index.js +3 -0
- package/dist/lib/observable/index.mjs +364 -0
- package/dist/lib/observable/observable.cjs +384 -0
- package/dist/lib/observable/observable.d.ts +246 -0
- package/dist/lib/observable/observable.d.ts.map +1 -0
- package/dist/lib/observable/observable.js +268 -0
- package/dist/lib/observable/observable.mjs +361 -0
- package/dist/lib/observable/subscription.cjs +180 -0
- package/dist/lib/observable/subscription.d.ts +58 -0
- package/dist/lib/observable/subscription.d.ts.map +1 -0
- package/dist/lib/observable/subscription.js +177 -0
- package/dist/lib/observable/subscription.mjs +157 -0
- package/dist/lib/observable/types.cjs +18 -0
- package/dist/lib/observable/types.d.ts +44 -0
- package/dist/lib/observable/types.d.ts.map +1 -0
- package/dist/lib/observable/types.js +1 -0
- package/dist/lib/observable/types.mjs +0 -0
- package/dist/lib/predicates.cjs +44 -0
- package/dist/lib/predicates.d.ts +37 -0
- package/dist/lib/predicates.d.ts.map +1 -0
- package/dist/lib/predicates.js +62 -0
- package/dist/lib/predicates.mjs +23 -0
- package/dist/lib/signal/api.cjs +592 -0
- package/dist/lib/signal/api.d.ts +227 -0
- package/dist/lib/signal/api.d.ts.map +1 -0
- package/dist/lib/signal/api.js +228 -0
- package/dist/lib/signal/api.mjs +569 -0
- package/dist/lib/signal/cached-resource.cjs +726 -0
- package/dist/lib/signal/cached-resource.d.ts +86 -0
- package/dist/lib/signal/cached-resource.d.ts.map +1 -0
- package/dist/lib/signal/cached-resource.js +250 -0
- package/dist/lib/signal/cached-resource.mjs +704 -0
- package/dist/lib/signal/graph/children.cjs +326 -0
- package/dist/lib/signal/graph/children.d.ts +2 -0
- package/dist/lib/signal/graph/children.d.ts.map +1 -0
- package/dist/lib/signal/graph/children.js +30 -0
- package/dist/lib/signal/graph/children.mjs +303 -0
- package/dist/lib/signal/graph/compat.cjs +590 -0
- package/dist/lib/signal/graph/compat.d.ts +66 -0
- package/dist/lib/signal/graph/compat.d.ts.map +1 -0
- package/dist/lib/signal/graph/compat.js +197 -0
- package/dist/lib/signal/graph/compat.mjs +568 -0
- package/dist/lib/signal/graph/core.cjs +295 -0
- package/dist/lib/signal/graph/core.d.ts +99 -0
- package/dist/lib/signal/graph/core.d.ts.map +1 -0
- package/dist/lib/signal/graph/core.js +268 -0
- package/dist/lib/signal/graph/core.mjs +273 -0
- package/dist/lib/signal/graph/debounced.cjs +680 -0
- package/dist/lib/signal/graph/debounced.d.ts +67 -0
- package/dist/lib/signal/graph/debounced.d.ts.map +1 -0
- package/dist/lib/signal/graph/debounced.js +92 -0
- package/dist/lib/signal/graph/debounced.mjs +657 -0
- package/dist/lib/signal/graph/derived.cjs +508 -0
- package/dist/lib/signal/graph/derived.d.ts +14 -0
- package/dist/lib/signal/graph/derived.d.ts.map +1 -0
- package/dist/lib/signal/graph/derived.js +65 -0
- package/dist/lib/signal/graph/derived.mjs +485 -0
- package/dist/lib/signal/graph/detect.cjs +66 -0
- package/dist/lib/signal/graph/detect.d.ts +17 -0
- package/dist/lib/signal/graph/detect.d.ts.map +1 -0
- package/dist/lib/signal/graph/detect.js +39 -0
- package/dist/lib/signal/graph/detect.mjs +45 -0
- package/dist/lib/signal/graph/error-boundary.cjs +313 -0
- package/dist/lib/signal/graph/error-boundary.d.ts +16 -0
- package/dist/lib/signal/graph/error-boundary.d.ts.map +1 -0
- package/dist/lib/signal/graph/error-boundary.js +34 -0
- package/dist/lib/signal/graph/error-boundary.mjs +290 -0
- package/dist/lib/signal/graph/index.cjs +305 -0
- package/dist/lib/signal/graph/index.d.ts +22 -0
- package/dist/lib/signal/graph/index.d.ts.map +1 -0
- package/dist/lib/signal/graph/index.js +21 -0
- package/dist/lib/signal/graph/index.mjs +283 -0
- package/dist/lib/signal/graph/observe.cjs +198 -0
- package/dist/lib/signal/graph/observe.d.ts +185 -0
- package/dist/lib/signal/graph/observe.d.ts.map +1 -0
- package/dist/lib/signal/graph/observe.js +198 -0
- package/dist/lib/signal/graph/observe.mjs +175 -0
- package/dist/lib/signal/graph/resource.cjs +632 -0
- package/dist/lib/signal/graph/resource.d.ts +39 -0
- package/dist/lib/signal/graph/resource.d.ts.map +1 -0
- package/dist/lib/signal/graph/resource.js +165 -0
- package/dist/lib/signal/graph/resource.mjs +609 -0
- package/dist/lib/signal/graph/runtime.cjs +522 -0
- package/dist/lib/signal/graph/runtime.d.ts +80 -0
- package/dist/lib/signal/graph/runtime.d.ts.map +1 -0
- package/dist/lib/signal/graph/runtime.js +358 -0
- package/dist/lib/signal/graph/runtime.mjs +499 -0
- package/dist/lib/signal/graph/signal-next.cjs +1249 -0
- package/dist/lib/signal/graph/signal-next.d.ts +38 -0
- package/dist/lib/signal/graph/signal-next.d.ts.map +1 -0
- package/dist/lib/signal/graph/signal-next.js +44 -0
- package/dist/lib/signal/graph/signal-next.mjs +1227 -0
- package/dist/lib/signal/graph/ssr-hooks.cjs +89 -0
- package/dist/lib/signal/graph/ssr-hooks.d.ts +51 -0
- package/dist/lib/signal/graph/ssr-hooks.d.ts.map +1 -0
- package/dist/lib/signal/graph/ssr-hooks.js +80 -0
- package/dist/lib/signal/graph/ssr-hooks.mjs +68 -0
- package/dist/lib/signal/graph/state.cjs +72 -0
- package/dist/lib/signal/graph/state.d.ts +76 -0
- package/dist/lib/signal/graph/state.d.ts.map +1 -0
- package/dist/lib/signal/graph/state.js +99 -0
- package/dist/lib/signal/graph/state.mjs +49 -0
- package/dist/lib/signal/graph/suspense.cjs +313 -0
- package/dist/lib/signal/graph/suspense.d.ts +13 -0
- package/dist/lib/signal/graph/suspense.d.ts.map +1 -0
- package/dist/lib/signal/graph/suspense.js +36 -0
- package/dist/lib/signal/graph/suspense.mjs +290 -0
- package/dist/lib/signal/index-legacy.cjs +2582 -0
- package/dist/lib/signal/index-legacy.d.ts +12 -0
- package/dist/lib/signal/index-legacy.d.ts.map +1 -0
- package/dist/lib/signal/index-legacy.js +11 -0
- package/dist/lib/signal/index-legacy.mjs +2560 -0
- package/dist/lib/signal/index.cjs +1350 -0
- package/dist/lib/signal/index.d.ts +19 -0
- package/dist/lib/signal/index.d.ts.map +1 -0
- package/dist/lib/signal/index.js +19 -0
- package/dist/lib/signal/index.mjs +1328 -0
- package/dist/lib/signal/list.cjs +561 -0
- package/dist/lib/signal/list.d.ts +39 -0
- package/dist/lib/signal/list.d.ts.map +1 -0
- package/dist/lib/signal/list.js +172 -0
- package/dist/lib/signal/list.mjs +538 -0
- package/dist/lib/signal/resource-api.cjs +638 -0
- package/dist/lib/signal/resource-api.d.ts +19 -0
- package/dist/lib/signal/resource-api.d.ts.map +1 -0
- package/dist/lib/signal/resource-api.js +27 -0
- package/dist/lib/signal/resource-api.mjs +615 -0
- package/dist/lib/signal/signal.cjs +2035 -0
- package/dist/lib/signal/signal.d.ts +303 -0
- package/dist/lib/signal/signal.d.ts.map +1 -0
- package/dist/lib/signal/signal.js +1233 -0
- package/dist/lib/signal/signal.mjs +2012 -0
- package/dist/lib/signal/types.cjs +38 -0
- package/dist/lib/signal/types.d.ts +133 -0
- package/dist/lib/signal/types.d.ts.map +1 -0
- package/dist/lib/signal/types.js +38 -0
- package/dist/lib/signal/types.mjs +17 -0
- package/dist/lib/signal/utilities.cjs +1024 -0
- package/dist/lib/signal/utilities.d.ts +247 -0
- package/dist/lib/signal/utilities.d.ts.map +1 -0
- package/dist/lib/signal/utilities.js +346 -0
- package/dist/lib/signal/utilities.mjs +1002 -0
- package/dist/lib/store/api.cjs +662 -0
- package/dist/lib/store/api.d.ts +40 -0
- package/dist/lib/store/api.d.ts.map +1 -0
- package/dist/lib/store/api.js +63 -0
- package/dist/lib/store/api.mjs +646 -0
- package/dist/lib/store/index.cjs +741 -0
- package/dist/lib/store/index.d.ts +16 -0
- package/dist/lib/store/index.d.ts.map +1 -0
- package/dist/lib/store/index.js +13 -0
- package/dist/lib/store/index.mjs +726 -0
- package/dist/lib/store/setter.types.cjs +18 -0
- package/dist/lib/store/setter.types.d.ts +131 -0
- package/dist/lib/store/setter.types.d.ts.map +1 -0
- package/dist/lib/store/setter.types.js +65 -0
- package/dist/lib/store/setter.types.mjs +0 -0
- package/dist/lib/store/store.cjs +708 -0
- package/dist/lib/store/store.d.ts +142 -0
- package/dist/lib/store/store.d.ts.map +1 -0
- package/dist/lib/store/store.js +812 -0
- package/dist/lib/store/store.mjs +694 -0
- package/dist/lib/store/types.cjs +18 -0
- package/dist/lib/store/types.d.ts +57 -0
- package/dist/lib/store/types.d.ts.map +1 -0
- package/dist/lib/store/types.js +1 -0
- package/dist/lib/store/types.mjs +0 -0
- package/dist/lib/store/utils.cjs +43 -0
- package/dist/lib/store/utils.d.ts +13 -0
- package/dist/lib/store/utils.d.ts.map +1 -0
- package/dist/lib/store/utils.js +29 -0
- package/dist/lib/store/utils.mjs +22 -0
- package/dist/lib/subject.cjs +450 -0
- package/dist/lib/subject.d.ts +14 -0
- package/dist/lib/subject.d.ts.map +1 -0
- package/dist/lib/subject.js +81 -0
- package/dist/lib/subject.mjs +427 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/version.generated.cjs +27 -0
- package/dist/version.generated.d.ts +3 -0
- package/dist/version.generated.d.ts.map +1 -0
- package/dist/version.generated.js +3 -0
- package/dist/version.generated.mjs +7 -0
- package/package.json +115 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { type Accessor, type MemoOptions, type EnhancedSignal } from './signal.js';
|
|
2
|
+
import { Observable } from '../observable/observable.js';
|
|
3
|
+
/**
|
|
4
|
+
* Transform a signal value through a mapping function
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const count = createSignal(5);
|
|
9
|
+
* const doubled = map(count[0], x => x * 2);
|
|
10
|
+
* console.log(doubled()); // 10
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare function mapSignal<T, U>(signal: Accessor<T>, fn: (value: T) => U, options?: MemoOptions<U>): Accessor<U>;
|
|
14
|
+
/**
|
|
15
|
+
* Filter an array signal using a predicate function
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const [numbers] = createSignal([1, 2, 3, 4, 5]);
|
|
20
|
+
* const evens = filter(numbers, x => x % 2 === 0);
|
|
21
|
+
* console.log(evens()); // [2, 4]
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function filterSignal<T>(signal: Accessor<T[]>, predicate: (value: T, index: number) => boolean, options?: MemoOptions<T[]>): Accessor<T[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Reduce an array signal to a single value
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const [numbers] = createSignal([1, 2, 3, 4, 5]);
|
|
31
|
+
* const sum = reduce(numbers, (acc, x) => acc + x, 0);
|
|
32
|
+
* console.log(sum()); // 15
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function reduceSignal<T, U>(signal: Accessor<T[]>, reducer: (accumulator: U, current: T, index: number) => U, initialValue: U, options?: MemoOptions<U>): Accessor<U>;
|
|
36
|
+
/**
|
|
37
|
+
* Find first element in array signal matching predicate
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const [users] = createSignal([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]);
|
|
42
|
+
* const user = find(users, u => u.id === 2);
|
|
43
|
+
* console.log(user()?.name); // 'Bob'
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function findSignal<T>(signal: Accessor<T[]>, predicate: (value: T, index: number) => boolean, options?: MemoOptions<T | undefined>): Accessor<T | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Check if any element in array signal matches predicate
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const [numbers] = createSignal([1, 2, 3, 4, 5]);
|
|
53
|
+
* const hasEven = some(numbers, x => x % 2 === 0);
|
|
54
|
+
* console.log(hasEven()); // true
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function someSignal<T>(signal: Accessor<T[]>, predicate: (value: T, index: number) => boolean, options?: MemoOptions<boolean>): Accessor<boolean>;
|
|
58
|
+
/**
|
|
59
|
+
* Check if all elements in array signal match predicate
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const [numbers] = createSignal([2, 4, 6, 8]);
|
|
64
|
+
* const allEven = every(numbers, x => x % 2 === 0);
|
|
65
|
+
* console.log(allEven()); // true
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export declare function everySignal<T>(signal: Accessor<T[]>, predicate: (value: T, index: number) => boolean, options?: MemoOptions<boolean>): Accessor<boolean>;
|
|
69
|
+
/**
|
|
70
|
+
* Sort an array signal
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const [numbers] = createSignal([3, 1, 4, 1, 5]);
|
|
75
|
+
* const sorted = sort(numbers);
|
|
76
|
+
* console.log(sorted()); // [1, 1, 3, 4, 5]
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function sortSignal<T>(signal: Accessor<T[]>, compareFn?: (a: T, b: T) => number, options?: MemoOptions<T[]>): Accessor<T[]>;
|
|
80
|
+
/**
|
|
81
|
+
* Get unique values from array signal
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* const [numbers] = createSignal([1, 2, 2, 3, 3, 3, 4]);
|
|
86
|
+
* const unique = distinct(numbers);
|
|
87
|
+
* console.log(unique()); // [1, 2, 3, 4]
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare function distinctSignal<T>(signal: Accessor<T[]>, options?: MemoOptions<T[]>): Accessor<T[]>;
|
|
91
|
+
/**
|
|
92
|
+
* Combine multiple signals into a single computed signal
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const [a] = createSignal(1);
|
|
97
|
+
* const [b] = createSignal(2);
|
|
98
|
+
* const sum = combine([a, b], ([x, y]) => x + y);
|
|
99
|
+
* console.log(sum()); // 3
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export declare function combineSignal<T extends any[], U>(signals: {
|
|
103
|
+
[K in keyof T]: Accessor<T[K]>;
|
|
104
|
+
}, combiner: (values: T) => U, options?: MemoOptions<U>): Accessor<U>;
|
|
105
|
+
/**
|
|
106
|
+
* Combine multiple signals into observable
|
|
107
|
+
*/
|
|
108
|
+
export declare function combineSignals<T extends any[]>(...signals: {
|
|
109
|
+
[K in keyof T]: Accessor<T[K]> | EnhancedSignal<T[K]>;
|
|
110
|
+
}): Observable<T>;
|
|
111
|
+
/**
|
|
112
|
+
* Merge two signals, returning value from first truthy signal
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* const [user] = createSignal(null);
|
|
117
|
+
* const [guest] = createSignal({ name: 'Guest' });
|
|
118
|
+
* const current = merge(user, guest);
|
|
119
|
+
* console.log(current()?.name); // 'Guest'
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export declare function mergeSignal<T>(primary: Accessor<T>, fallback: Accessor<T>, options?: MemoOptions<T>): Accessor<T>;
|
|
123
|
+
/**
|
|
124
|
+
* Combine two signals using a binary operator
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const [x] = createSignal(5);
|
|
129
|
+
* const [y] = createSignal(3);
|
|
130
|
+
* const product = zip(x, y, (a, b) => a * b);
|
|
131
|
+
* console.log(product()); // 15
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare function zipSignal<T, U, V>(a: Accessor<T>, b: Accessor<U>, operator: (a: T, b: U) => V, options?: MemoOptions<V>): Accessor<V>;
|
|
135
|
+
/**
|
|
136
|
+
* Select a derived value from a signal with custom equality
|
|
137
|
+
* Only updates when selected value changes according to equals function
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const [user] = createSignal({ id: 1, name: 'Alice', age: 30 });
|
|
142
|
+
* const userName = select(user, u => u.name);
|
|
143
|
+
* // Only updates when name changes, not when age changes
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare function selectSignal<T, U>(signal: Accessor<T>, selector: (value: T) => U, equals?: (a: U, b: U) => boolean): Accessor<U>;
|
|
147
|
+
/**
|
|
148
|
+
* Pick specific properties from an object signal
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* const [user] = createSignal({ id: 1, name: 'Alice', age: 30, email: 'alice@example.com' });
|
|
153
|
+
* const userData = pick(user, ['name', 'email']);
|
|
154
|
+
* console.log(userData()); // { name: 'Alice', email: 'alice@example.com' }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export declare function pickSignal<T extends Record<string, any>, K extends keyof T>(signal: Accessor<T>, keys: K[], options?: MemoOptions<Pick<T, K>>): Accessor<Pick<T, K>>;
|
|
158
|
+
/**
|
|
159
|
+
* Omit specific properties from an object signal
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const [user] = createSignal({ id: 1, name: 'Alice', age: 30, password: 'secret' });
|
|
164
|
+
* const safeUser = omit(user, ['password']);
|
|
165
|
+
* console.log(safeUser()); // { id: 1, name: 'Alice', age: 30 }
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export declare function omitSignal<T extends Record<string, any>, K extends keyof T>(signal: Accessor<T>, keys: K[], options?: MemoOptions<Omit<T, K>>): Accessor<Omit<T, K>>;
|
|
169
|
+
/**
|
|
170
|
+
* Conditionally compute signal based on condition
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* const [isLoggedIn] = createSignal(false);
|
|
175
|
+
* const [user] = createSignal({ name: 'Alice' });
|
|
176
|
+
* const [guest] = createSignal({ name: 'Guest' });
|
|
177
|
+
* const currentUser = when(isLoggedIn, user, guest);
|
|
178
|
+
* console.log(currentUser()?.name); // 'Guest'
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
export declare function whenSignal<T>(condition: Accessor<boolean>, whenTrue: Accessor<T>, whenFalse: Accessor<T>, options?: MemoOptions<T>): Accessor<T>;
|
|
182
|
+
/**
|
|
183
|
+
* Compute signal only when condition is true, otherwise return undefined
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* const [showDetails] = createSignal(false);
|
|
188
|
+
* const [details] = createSignal({ info: 'Details here' });
|
|
189
|
+
* const visibleDetails = guard(showDetails, details);
|
|
190
|
+
* console.log(visibleDetails()); // undefined (when showDetails is false)
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
export declare function guardSignal<T>(condition: Accessor<boolean>, accessor: Accessor<T>, options?: MemoOptions<T | undefined>): Accessor<T | undefined>;
|
|
194
|
+
/**
|
|
195
|
+
* Debounce a signal - only update after delay period with no changes
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* const [search] = createSignal('');
|
|
200
|
+
* const debouncedSearch = debounce(search, 300);
|
|
201
|
+
* // debouncedSearch only updates 300ms after last search change
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export declare function debounceSignal<T>(signal: Accessor<T>, delay: number, options?: MemoOptions<T>): Accessor<T>;
|
|
205
|
+
/**
|
|
206
|
+
* Throttle a signal - limit update frequency
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* const [scroll] = createSignal(0);
|
|
211
|
+
* const throttledScroll = throttle(scroll, 100);
|
|
212
|
+
* // throttledScroll updates at most once per 100ms
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
export declare function throttleSignal<T>(signal: Accessor<T>, delay: number, options?: MemoOptions<T>): Accessor<T>;
|
|
216
|
+
export { type Accessor, type MemoOptions } from './signal.js';
|
|
217
|
+
/**
|
|
218
|
+
* Creates a deferred promise with exposed resolve and reject methods
|
|
219
|
+
*
|
|
220
|
+
* This utility function creates a Promise along with its resolver functions,
|
|
221
|
+
* allowing for more control over when and how the promise resolves or rejects.
|
|
222
|
+
* Useful for converting callback-based APIs to promises, implementing timeouts,
|
|
223
|
+
* or coordinating complex async flows.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```typescript
|
|
227
|
+
* // Create a promise with external controls
|
|
228
|
+
* const deferred = createDeferred<Response>();
|
|
229
|
+
*
|
|
230
|
+
* // Set up timeout
|
|
231
|
+
* const timeoutId = setTimeout(() => {
|
|
232
|
+
* deferred.reject(new Error('Request timed out'));
|
|
233
|
+
* }, 5000);
|
|
234
|
+
*
|
|
235
|
+
* // Make the request
|
|
236
|
+
* fetch('/api/data')
|
|
237
|
+
* .then(deferred.resolve)
|
|
238
|
+
* .catch(deferred.reject)
|
|
239
|
+
* .finally(() => clearTimeout(timeoutId));
|
|
240
|
+
*
|
|
241
|
+
* // Return the promise to the caller
|
|
242
|
+
* return deferred.promise;
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
export type ReadSignal<T, depth extends 0 | 1 | 2 | 3 | 4 = 0> = depth extends 4 ? T : T extends Accessor<infer U> ? U extends (() => any) ? ReadSignal<U, depth extends 4 ? 4 : depth extends 3 ? 3 : depth extends 2 ? 2 : depth extends 1 ? 1 : 0> : U : T;
|
|
246
|
+
export declare function readSignal<T>(signal?: Accessor<T> | T | null): ReadSignal<T>;
|
|
247
|
+
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../src/lib/signal/utilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { createSignal, createMemo, createEffect } from './graph/compat.js';
|
|
2
|
+
import { Observable } from '../observable/observable.js';
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// TRANSFORMATION UTILITIES
|
|
5
|
+
// ============================================================================
|
|
6
|
+
/**
|
|
7
|
+
* Transform a signal value through a mapping function
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const count = createSignal(5);
|
|
12
|
+
* const doubled = map(count[0], x => x * 2);
|
|
13
|
+
* console.log(doubled()); // 10
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function mapSignal(signal, fn, options) {
|
|
17
|
+
return createMemo(() => fn(signal()), undefined, options);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Filter an array signal using a predicate function
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const [numbers] = createSignal([1, 2, 3, 4, 5]);
|
|
25
|
+
* const evens = filter(numbers, x => x % 2 === 0);
|
|
26
|
+
* console.log(evens()); // [2, 4]
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function filterSignal(signal, predicate, options) {
|
|
30
|
+
return createMemo(() => signal().filter(predicate), undefined, options);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Reduce an array signal to a single value
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const [numbers] = createSignal([1, 2, 3, 4, 5]);
|
|
38
|
+
* const sum = reduce(numbers, (acc, x) => acc + x, 0);
|
|
39
|
+
* console.log(sum()); // 15
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export function reduceSignal(signal, reducer, initialValue, options) {
|
|
43
|
+
return createMemo(() => signal().reduce(reducer, initialValue), undefined, options);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Find first element in array signal matching predicate
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const [users] = createSignal([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]);
|
|
51
|
+
* const user = find(users, u => u.id === 2);
|
|
52
|
+
* console.log(user()?.name); // 'Bob'
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export function findSignal(signal, predicate, options) {
|
|
56
|
+
return createMemo(() => signal().find(predicate), undefined, options);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if any element in array signal matches predicate
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const [numbers] = createSignal([1, 2, 3, 4, 5]);
|
|
64
|
+
* const hasEven = some(numbers, x => x % 2 === 0);
|
|
65
|
+
* console.log(hasEven()); // true
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
export function someSignal(signal, predicate, options) {
|
|
69
|
+
return createMemo(() => signal().some(predicate), undefined, options);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if all elements in array signal match predicate
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const [numbers] = createSignal([2, 4, 6, 8]);
|
|
77
|
+
* const allEven = every(numbers, x => x % 2 === 0);
|
|
78
|
+
* console.log(allEven()); // true
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export function everySignal(signal, predicate, options) {
|
|
82
|
+
return createMemo(() => signal().every(predicate), undefined, options);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sort an array signal
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const [numbers] = createSignal([3, 1, 4, 1, 5]);
|
|
90
|
+
* const sorted = sort(numbers);
|
|
91
|
+
* console.log(sorted()); // [1, 1, 3, 4, 5]
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export function sortSignal(signal, compareFn, options) {
|
|
95
|
+
return createMemo(() => [...signal()].sort(compareFn), undefined, options);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get unique values from array signal
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* const [numbers] = createSignal([1, 2, 2, 3, 3, 3, 4]);
|
|
103
|
+
* const unique = distinct(numbers);
|
|
104
|
+
* console.log(unique()); // [1, 2, 3, 4]
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export function distinctSignal(signal, options) {
|
|
108
|
+
return createMemo(() => [...new Set(signal())], undefined, options);
|
|
109
|
+
}
|
|
110
|
+
// ============================================================================
|
|
111
|
+
// COMBINATION UTILITIES
|
|
112
|
+
// ============================================================================
|
|
113
|
+
/**
|
|
114
|
+
* Combine multiple signals into a single computed signal
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```typescript
|
|
118
|
+
* const [a] = createSignal(1);
|
|
119
|
+
* const [b] = createSignal(2);
|
|
120
|
+
* const sum = combine([a, b], ([x, y]) => x + y);
|
|
121
|
+
* console.log(sum()); // 3
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
export function combineSignal(signals, combiner, options) {
|
|
125
|
+
return createMemo(() => {
|
|
126
|
+
const values = signals.map((s) => s());
|
|
127
|
+
return combiner(values);
|
|
128
|
+
}, undefined, options);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Combine multiple signals into observable
|
|
132
|
+
*/
|
|
133
|
+
export function combineSignals(...signals) {
|
|
134
|
+
return new Observable((observer) => {
|
|
135
|
+
const getValues = () => signals.map((s) => (typeof s === 'function' ? s() : s.get()));
|
|
136
|
+
const disposers = signals.map((signal) => {
|
|
137
|
+
if (typeof signal === 'function' && signal.subscribe) {
|
|
138
|
+
return signal.subscribe(() => {
|
|
139
|
+
observer.next(getValues());
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
else if (typeof signal !== 'function') {
|
|
143
|
+
return signal.subscribe(() => {
|
|
144
|
+
observer.next(getValues());
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return createEffect(() => {
|
|
148
|
+
observer.next(getValues());
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
return () => {
|
|
152
|
+
disposers.forEach((dispose) => {
|
|
153
|
+
if (typeof dispose === 'function')
|
|
154
|
+
dispose();
|
|
155
|
+
else if (dispose && typeof dispose.unsubscribe === 'function') {
|
|
156
|
+
dispose.unsubscribe();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
// },
|
|
162
|
+
// pipe(...operators: any[]): Observable<any> {
|
|
163
|
+
// throw new Error('Pipe requires RxJS');
|
|
164
|
+
// }
|
|
165
|
+
// };
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Merge two signals, returning value from first truthy signal
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const [user] = createSignal(null);
|
|
173
|
+
* const [guest] = createSignal({ name: 'Guest' });
|
|
174
|
+
* const current = merge(user, guest);
|
|
175
|
+
* console.log(current()?.name); // 'Guest'
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
export function mergeSignal(primary, fallback, options) {
|
|
179
|
+
return createMemo(() => primary() || fallback(), undefined, options);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Combine two signals using a binary operator
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* const [x] = createSignal(5);
|
|
187
|
+
* const [y] = createSignal(3);
|
|
188
|
+
* const product = zip(x, y, (a, b) => a * b);
|
|
189
|
+
* console.log(product()); // 15
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
export function zipSignal(a, b, operator, options) {
|
|
193
|
+
return createMemo(() => operator(a(), b()), undefined, options);
|
|
194
|
+
}
|
|
195
|
+
// ============================================================================
|
|
196
|
+
// SELECTION UTILITIES
|
|
197
|
+
// ============================================================================
|
|
198
|
+
/**
|
|
199
|
+
* Select a derived value from a signal with custom equality
|
|
200
|
+
* Only updates when selected value changes according to equals function
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* ```typescript
|
|
204
|
+
* const [user] = createSignal({ id: 1, name: 'Alice', age: 30 });
|
|
205
|
+
* const userName = select(user, u => u.name);
|
|
206
|
+
* // Only updates when name changes, not when age changes
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
export function selectSignal(signal, selector, equals) {
|
|
210
|
+
return createMemo(() => selector(signal()), undefined, {
|
|
211
|
+
equals,
|
|
212
|
+
internal: true,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Pick specific properties from an object signal
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```typescript
|
|
220
|
+
* const [user] = createSignal({ id: 1, name: 'Alice', age: 30, email: 'alice@example.com' });
|
|
221
|
+
* const userData = pick(user, ['name', 'email']);
|
|
222
|
+
* console.log(userData()); // { name: 'Alice', email: 'alice@example.com' }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export function pickSignal(signal, keys, options) {
|
|
226
|
+
return createMemo(() => {
|
|
227
|
+
const obj = signal();
|
|
228
|
+
const result = {};
|
|
229
|
+
for (const key of keys) {
|
|
230
|
+
result[key] = obj[key];
|
|
231
|
+
}
|
|
232
|
+
return result;
|
|
233
|
+
}, undefined, options);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Omit specific properties from an object signal
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* const [user] = createSignal({ id: 1, name: 'Alice', age: 30, password: 'secret' });
|
|
241
|
+
* const safeUser = omit(user, ['password']);
|
|
242
|
+
* console.log(safeUser()); // { id: 1, name: 'Alice', age: 30 }
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
export function omitSignal(signal, keys, options) {
|
|
246
|
+
return createMemo(() => {
|
|
247
|
+
const obj = signal();
|
|
248
|
+
const result = { ...obj };
|
|
249
|
+
for (const key of keys) {
|
|
250
|
+
delete result[key];
|
|
251
|
+
}
|
|
252
|
+
return result;
|
|
253
|
+
}, undefined, options);
|
|
254
|
+
}
|
|
255
|
+
// ============================================================================
|
|
256
|
+
// CONDITIONAL UTILITIES
|
|
257
|
+
// ============================================================================
|
|
258
|
+
/**
|
|
259
|
+
* Conditionally compute signal based on condition
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* const [isLoggedIn] = createSignal(false);
|
|
264
|
+
* const [user] = createSignal({ name: 'Alice' });
|
|
265
|
+
* const [guest] = createSignal({ name: 'Guest' });
|
|
266
|
+
* const currentUser = when(isLoggedIn, user, guest);
|
|
267
|
+
* console.log(currentUser()?.name); // 'Guest'
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
export function whenSignal(condition, whenTrue, whenFalse, options) {
|
|
271
|
+
return createMemo(() => (condition() ? whenTrue() : whenFalse()), undefined, options);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Compute signal only when condition is true, otherwise return undefined
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```typescript
|
|
278
|
+
* const [showDetails] = createSignal(false);
|
|
279
|
+
* const [details] = createSignal({ info: 'Details here' });
|
|
280
|
+
* const visibleDetails = guard(showDetails, details);
|
|
281
|
+
* console.log(visibleDetails()); // undefined (when showDetails is false)
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
export function guardSignal(condition, accessor, options) {
|
|
285
|
+
return createMemo(() => (condition() ? accessor() : undefined), undefined, options);
|
|
286
|
+
}
|
|
287
|
+
// ============================================================================
|
|
288
|
+
// TIMING UTILITIES
|
|
289
|
+
// ============================================================================
|
|
290
|
+
/**
|
|
291
|
+
* Debounce a signal - only update after delay period with no changes
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```typescript
|
|
295
|
+
* const [search] = createSignal('');
|
|
296
|
+
* const debouncedSearch = debounce(search, 300);
|
|
297
|
+
* // debouncedSearch only updates 300ms after last search change
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
export function debounceSignal(signal, delay, options) {
|
|
301
|
+
const [debounced, setDebounced] = createSignal(signal());
|
|
302
|
+
let timeoutId;
|
|
303
|
+
createMemo(() => {
|
|
304
|
+
const value = signal();
|
|
305
|
+
clearTimeout(timeoutId);
|
|
306
|
+
timeoutId = setTimeout(() => setDebounced(() => value), delay);
|
|
307
|
+
});
|
|
308
|
+
return debounced;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Throttle a signal - limit update frequency
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```typescript
|
|
315
|
+
* const [scroll] = createSignal(0);
|
|
316
|
+
* const throttledScroll = throttle(scroll, 100);
|
|
317
|
+
* // throttledScroll updates at most once per 100ms
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
export function throttleSignal(signal, delay, options) {
|
|
321
|
+
const [throttled, setThrottled] = createSignal(signal());
|
|
322
|
+
let lastUpdate = 0;
|
|
323
|
+
let timeoutId;
|
|
324
|
+
createMemo(() => {
|
|
325
|
+
const value = signal();
|
|
326
|
+
const now = Date.now();
|
|
327
|
+
if (now - lastUpdate >= delay) {
|
|
328
|
+
lastUpdate = now;
|
|
329
|
+
setThrottled(() => value);
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
clearTimeout(timeoutId);
|
|
333
|
+
timeoutId = setTimeout(() => {
|
|
334
|
+
lastUpdate = Date.now();
|
|
335
|
+
setThrottled(() => value);
|
|
336
|
+
}, delay - (now - lastUpdate));
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
return throttled;
|
|
340
|
+
}
|
|
341
|
+
export function readSignal(signal) {
|
|
342
|
+
let value = signal;
|
|
343
|
+
while (typeof value === 'function')
|
|
344
|
+
value = value();
|
|
345
|
+
return value;
|
|
346
|
+
}
|