@sergeydus/ng-signals-utils 0.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/README.md +261 -0
- package/fesm2022/ng-signals-utils.mjs +303 -0
- package/fesm2022/ng-signals-utils.mjs.map +1 -0
- package/fesm2022/sergeydus-ng-signals-utils.mjs +303 -0
- package/fesm2022/sergeydus-ng-signals-utils.mjs.map +1 -0
- package/package.json +30 -0
- package/types/ng-signals-utils.d.ts +176 -0
- package/types/sergeydus-ng-signals-utils.d.ts +176 -0
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# ng-signals-utils
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/ng-signals-utils)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://angular.io/)
|
|
7
|
+
|
|
8
|
+
**Powerful utility functions for Angular signals that make reactive programming easier and more intuitive.**
|
|
9
|
+
|
|
10
|
+
Stop writing repetitive signal manipulation code. `ng-signals-utils` provides a comprehensive set of utilities for transforming, filtering, and managing signals in your Angular applications.
|
|
11
|
+
|
|
12
|
+
## 🚀 Why ng-signals-utils?
|
|
13
|
+
|
|
14
|
+
Angular's signals are powerful, but common operations require boilerplate code. This library provides:
|
|
15
|
+
|
|
16
|
+
- ✅ **Signal Transformations** - Map, filter, debounce, and combine signals effortlessly
|
|
17
|
+
- ✅ **Array Operations** - Work with array signals using familiar array methods
|
|
18
|
+
- ✅ **Object Utilities** - Update and transform object signals with ease
|
|
19
|
+
- ✅ **Effect Helpers** - Advanced effect management with debouncing, throttling, and more
|
|
20
|
+
- ✅ **Type-Safe** - Full TypeScript support with proper type inference
|
|
21
|
+
- ✅ **Tree-Shakeable** - Only bundle what you use
|
|
22
|
+
- ✅ **Zero Dependencies** - Except Angular core, of course
|
|
23
|
+
|
|
24
|
+
## 📦 Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install ng-signals-utils
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
yarn add ng-signals-utils
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add ng-signals-utils
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 🎯 Quick Examples
|
|
39
|
+
|
|
40
|
+
### Before vs After
|
|
41
|
+
|
|
42
|
+
**Without ng-signals-utils:**
|
|
43
|
+
```typescript
|
|
44
|
+
// Debouncing a search signal
|
|
45
|
+
const searchTerm = signal('');
|
|
46
|
+
const debouncedSearch = signal('');
|
|
47
|
+
let timeoutId: any;
|
|
48
|
+
|
|
49
|
+
effect(() => {
|
|
50
|
+
const value = searchTerm();
|
|
51
|
+
clearTimeout(timeoutId);
|
|
52
|
+
timeoutId = setTimeout(() => {
|
|
53
|
+
debouncedSearch.set(value);
|
|
54
|
+
}, 300);
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**With ng-signals-utils:**
|
|
59
|
+
```typescript
|
|
60
|
+
import { debounceSignal } from 'ng-signals-utils';
|
|
61
|
+
|
|
62
|
+
const searchTerm = signal('');
|
|
63
|
+
const debouncedSearch = debounceSignal(searchTerm, 300);
|
|
64
|
+
// Done! 🎉
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
**Without ng-signals-utils:**
|
|
70
|
+
```typescript
|
|
71
|
+
// Filtering an array signal
|
|
72
|
+
const allTodos = signal<Todo[]>([]);
|
|
73
|
+
const completedTodos = computed(() =>
|
|
74
|
+
allTodos().filter(todo => todo.completed)
|
|
75
|
+
);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**With ng-signals-utils:**
|
|
79
|
+
```typescript
|
|
80
|
+
import { arraySignalFilter } from 'ng-signals-utils';
|
|
81
|
+
|
|
82
|
+
const allTodos = signal<Todo[]>([]);
|
|
83
|
+
const completedTodos = arraySignalFilter(allTodos, todo => todo.completed);
|
|
84
|
+
// More expressive and reusable! ✨
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 💡 Common Use Cases
|
|
88
|
+
|
|
89
|
+
### Real-time Search with Debouncing
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import { Component, signal } from '@angular/core';
|
|
93
|
+
import { debounceSignal } from 'ng-signals-utils';
|
|
94
|
+
|
|
95
|
+
@Component({
|
|
96
|
+
selector: 'app-search',
|
|
97
|
+
template: `
|
|
98
|
+
<input [value]="searchTerm()" (input)="onSearch($event)" />
|
|
99
|
+
<p>Searching for: {{ debouncedSearch() }}</p>
|
|
100
|
+
`
|
|
101
|
+
})
|
|
102
|
+
export class SearchComponent {
|
|
103
|
+
searchTerm = signal('');
|
|
104
|
+
debouncedSearch = debounceSignal(this.searchTerm, 300);
|
|
105
|
+
|
|
106
|
+
// API calls automatically debounced!
|
|
107
|
+
constructor() {
|
|
108
|
+
effect(() => {
|
|
109
|
+
const query = this.debouncedSearch();
|
|
110
|
+
if (query) this.searchAPI(query);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Managing Todo Lists
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { arraySignalPush, arraySignalRemoveAt, arraySignalFilter } from 'ng-signals-utils';
|
|
120
|
+
|
|
121
|
+
export class TodoComponent {
|
|
122
|
+
todos = signal<Todo[]>([]);
|
|
123
|
+
completedTodos = arraySignalFilter(this.todos, t => t.completed);
|
|
124
|
+
pendingTodos = arraySignalFilter(this.todos, t => !t.completed);
|
|
125
|
+
|
|
126
|
+
addTodo(text: string) {
|
|
127
|
+
arraySignalPush(this.todos, { id: Date.now(), text, completed: false });
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
removeTodo(index: number) {
|
|
131
|
+
arraySignalRemoveAt(this.todos, index);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Form State Management
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { patchSignal, pickSignal } from 'ng-signals-utils';
|
|
140
|
+
|
|
141
|
+
export class UserFormComponent {
|
|
142
|
+
user = signal({
|
|
143
|
+
id: 1,
|
|
144
|
+
name: '',
|
|
145
|
+
email: '',
|
|
146
|
+
password: '',
|
|
147
|
+
role: 'user'
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Only expose safe fields
|
|
151
|
+
publicUser = pickSignal(this.user, 'id', 'name', 'email');
|
|
152
|
+
|
|
153
|
+
updateField(field: string, value: any) {
|
|
154
|
+
patchSignal(this.user, { [field]: value });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Combining Multiple Signals
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import { combineSignals } from 'ng-signals-utils';
|
|
163
|
+
|
|
164
|
+
export class CheckoutComponent {
|
|
165
|
+
items = signal<Item[]>([]);
|
|
166
|
+
tax = signal(0.08);
|
|
167
|
+
shipping = signal(10);
|
|
168
|
+
|
|
169
|
+
// Automatically recalculates when any signal changes
|
|
170
|
+
orderSummary = computed(() => {
|
|
171
|
+
const [itemList, taxRate, shippingCost] = combineSignals([
|
|
172
|
+
this.items,
|
|
173
|
+
this.tax,
|
|
174
|
+
this.shipping
|
|
175
|
+
])();
|
|
176
|
+
|
|
177
|
+
const subtotal = itemList.reduce((sum, item) => sum + item.price, 0);
|
|
178
|
+
return {
|
|
179
|
+
subtotal,
|
|
180
|
+
tax: subtotal * taxRate,
|
|
181
|
+
shipping: shippingCost,
|
|
182
|
+
total: subtotal * (1 + taxRate) + shippingCost
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 📚 API Reference
|
|
189
|
+
|
|
190
|
+
### Signal Transformations
|
|
191
|
+
|
|
192
|
+
| Function | Description |
|
|
193
|
+
|----------|-------------|
|
|
194
|
+
| `mapSignal<T, R>(source, fn)` | Transform signal values to another type |
|
|
195
|
+
| `filterSignal<T>(source, predicate, initial)` | Filter signal updates based on a condition |
|
|
196
|
+
| `debounceSignal<T>(source, ms)` | Debounce signal updates |
|
|
197
|
+
| `combineSignals<T>(signals)` | Combine multiple signals into one |
|
|
198
|
+
| `distinctSignal<T>(source, compareFn?)` | Emit only distinct consecutive values |
|
|
199
|
+
|
|
200
|
+
### Array Utilities
|
|
201
|
+
|
|
202
|
+
| Function | Description |
|
|
203
|
+
|----------|-------------|
|
|
204
|
+
| `arraySignalPush<T>(signal, item)` | Add item to array signal |
|
|
205
|
+
| `arraySignalRemoveAt<T>(signal, index)` | Remove item at index |
|
|
206
|
+
| `arraySignalFilter<T>(signal, predicate)` | Create filtered computed signal |
|
|
207
|
+
| `arraySignalMap<T, R>(signal, fn)` | Create mapped computed signal |
|
|
208
|
+
| `arraySignalSort<T>(signal, compareFn?)` | Create sorted computed signal |
|
|
209
|
+
| `arraySignalFind<T>(signal, predicate)` | Find item in array signal |
|
|
210
|
+
| `arraySignalLength<T>(signal)` | Get array length as signal |
|
|
211
|
+
| `arraySignalIsEmpty<T>(signal)` | Check if array is empty |
|
|
212
|
+
|
|
213
|
+
### Object Utilities
|
|
214
|
+
|
|
215
|
+
| Function | Description |
|
|
216
|
+
|----------|-------------|
|
|
217
|
+
| `patchSignal<T>(signal, partial)` | Update object signal with partial values |
|
|
218
|
+
| `pickSignal<T, K>(signal, ...keys)` | Pick specific keys from object |
|
|
219
|
+
| `omitSignal<T, K>(signal, ...keys)` | Omit specific keys from object |
|
|
220
|
+
| `pluckSignal<T, K>(signal, key)` | Extract single property as signal |
|
|
221
|
+
| `objectSignalKeys<T>(signal)` | Get object keys as signal |
|
|
222
|
+
| `objectSignalValues<T>(signal)` | Get object values as signal |
|
|
223
|
+
| `objectSignalEntries<T>(signal)` | Get object entries as signal |
|
|
224
|
+
|
|
225
|
+
### Effect Helpers
|
|
226
|
+
|
|
227
|
+
| Function | Description |
|
|
228
|
+
|----------|-------------|
|
|
229
|
+
| `watchSignal<T>(source, fn, options?)` | Watch signal with access to previous value |
|
|
230
|
+
| `watchUntil<T>(source, predicate, fn, options?)` | Run effect once when condition is met |
|
|
231
|
+
| `throttleEffect<T>(source, fn, ms, options?)` | Throttle effect execution |
|
|
232
|
+
| `debounceEffect<T>(source, fn, ms, options?)` | Debounce effect execution |
|
|
233
|
+
|
|
234
|
+
## 📖 Full Documentation
|
|
235
|
+
|
|
236
|
+
For comprehensive examples and advanced usage patterns, see [EXAMPLES.md](./EXAMPLES.md).
|
|
237
|
+
|
|
238
|
+
## 🔧 Requirements
|
|
239
|
+
|
|
240
|
+
- Angular 17.0.0 or higher
|
|
241
|
+
- TypeScript 5.0 or higher
|
|
242
|
+
|
|
243
|
+
## 🤝 Contributing
|
|
244
|
+
|
|
245
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
246
|
+
|
|
247
|
+
## 📄 License
|
|
248
|
+
|
|
249
|
+
MIT © [Your Name]
|
|
250
|
+
|
|
251
|
+
## 🌟 Show Your Support
|
|
252
|
+
|
|
253
|
+
If you find this library helpful, please give it a star on GitHub!
|
|
254
|
+
|
|
255
|
+
## 📮 Feedback & Issues
|
|
256
|
+
|
|
257
|
+
Found a bug or have a feature request? [Open an issue](https://github.com/yourusername/ng-signals-utils/issues)
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
Made with ❤️ for the Angular community
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { computed, signal, effect } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Maps a signal value to another type
|
|
5
|
+
* @param source - Source signal
|
|
6
|
+
* @param fn - Mapping function
|
|
7
|
+
* @returns Computed signal with mapped value
|
|
8
|
+
*/
|
|
9
|
+
function mapSignal(source, fn) {
|
|
10
|
+
return computed(() => fn(source()));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Filters signal updates based on a predicate
|
|
14
|
+
* @param source - Source signal
|
|
15
|
+
* @param predicate - Filter predicate
|
|
16
|
+
* @param initialValue - Initial value to use if predicate fails
|
|
17
|
+
* @returns Signal that only updates when predicate returns true
|
|
18
|
+
*/
|
|
19
|
+
function filterSignal(source, predicate, initialValue) {
|
|
20
|
+
const filtered = signal(initialValue, ...(ngDevMode ? [{ debugName: "filtered" }] : []));
|
|
21
|
+
effect(() => {
|
|
22
|
+
const value = source();
|
|
23
|
+
if (predicate(value)) {
|
|
24
|
+
filtered.set(value);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return filtered.asReadonly();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Debounces signal updates
|
|
31
|
+
* @param source - Source signal
|
|
32
|
+
* @param ms - Debounce delay in milliseconds
|
|
33
|
+
* @returns Debounced signal
|
|
34
|
+
*/
|
|
35
|
+
function debounceSignal(source, ms) {
|
|
36
|
+
const debounced = signal(source(), ...(ngDevMode ? [{ debugName: "debounced" }] : []));
|
|
37
|
+
let timeoutId;
|
|
38
|
+
effect(() => {
|
|
39
|
+
const value = source();
|
|
40
|
+
clearTimeout(timeoutId);
|
|
41
|
+
timeoutId = setTimeout(() => {
|
|
42
|
+
debounced.set(value);
|
|
43
|
+
}, ms);
|
|
44
|
+
});
|
|
45
|
+
return debounced.asReadonly();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Combines multiple signals into a single signal
|
|
49
|
+
* @param signals - Array of signals to combine
|
|
50
|
+
* @returns Combined signal with array of values
|
|
51
|
+
*/
|
|
52
|
+
function combineSignals(signals) {
|
|
53
|
+
return computed(() => signals.map(s => s()));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates a signal that emits distinct values only
|
|
57
|
+
* @param source - Source signal
|
|
58
|
+
* @param compareFn - Optional comparison function
|
|
59
|
+
* @returns Signal that only updates on distinct values
|
|
60
|
+
*/
|
|
61
|
+
function distinctSignal(source, compareFn = (a, b) => a === b) {
|
|
62
|
+
const distinct = signal(source(), ...(ngDevMode ? [{ debugName: "distinct" }] : []));
|
|
63
|
+
let lastValue = source();
|
|
64
|
+
effect(() => {
|
|
65
|
+
const value = source();
|
|
66
|
+
if (!compareFn(value, lastValue)) {
|
|
67
|
+
lastValue = value;
|
|
68
|
+
distinct.set(value);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return distinct.asReadonly();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Pushes an item to an array signal
|
|
76
|
+
* @param arraySignal - Writable array signal
|
|
77
|
+
* @param item - Item to push
|
|
78
|
+
*/
|
|
79
|
+
function arraySignalPush(arraySignal, item) {
|
|
80
|
+
arraySignal.update(arr => [...arr, item]);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Removes an item from an array signal at the specified index
|
|
84
|
+
* @param arraySignal - Writable array signal
|
|
85
|
+
* @param index - Index to remove
|
|
86
|
+
*/
|
|
87
|
+
function arraySignalRemoveAt(arraySignal, index) {
|
|
88
|
+
arraySignal.update(arr => arr.filter((_, i) => i !== index));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Filters an array signal
|
|
92
|
+
* @param arraySignal - Array signal
|
|
93
|
+
* @param predicate - Filter predicate
|
|
94
|
+
* @returns Computed signal with filtered array
|
|
95
|
+
*/
|
|
96
|
+
function arraySignalFilter(arraySignal, predicate) {
|
|
97
|
+
return computed(() => arraySignal().filter(predicate));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Maps an array signal
|
|
101
|
+
* @param arraySignal - Array signal
|
|
102
|
+
* @param fn - Mapping function
|
|
103
|
+
* @returns Computed signal with mapped array
|
|
104
|
+
*/
|
|
105
|
+
function arraySignalMap(arraySignal, fn) {
|
|
106
|
+
return computed(() => arraySignal().map(fn));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Sorts an array signal
|
|
110
|
+
* @param arraySignal - Array signal
|
|
111
|
+
* @param compareFn - Optional comparison function
|
|
112
|
+
* @returns Computed signal with sorted array
|
|
113
|
+
*/
|
|
114
|
+
function arraySignalSort(arraySignal, compareFn) {
|
|
115
|
+
return computed(() => [...arraySignal()].sort(compareFn));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Finds an item in an array signal
|
|
119
|
+
* @param arraySignal - Array signal
|
|
120
|
+
* @param predicate - Find predicate
|
|
121
|
+
* @returns Computed signal with found item or undefined
|
|
122
|
+
*/
|
|
123
|
+
function arraySignalFind(arraySignal, predicate) {
|
|
124
|
+
return computed(() => arraySignal().find(predicate));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Gets the length of an array signal
|
|
128
|
+
* @param arraySignal - Array signal
|
|
129
|
+
* @returns Computed signal with array length
|
|
130
|
+
*/
|
|
131
|
+
function arraySignalLength(arraySignal) {
|
|
132
|
+
return computed(() => arraySignal().length);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Checks if an array signal is empty
|
|
136
|
+
* @param arraySignal - Array signal
|
|
137
|
+
* @returns Computed signal indicating if array is empty
|
|
138
|
+
*/
|
|
139
|
+
function arraySignalIsEmpty(arraySignal) {
|
|
140
|
+
return computed(() => arraySignal().length === 0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Patches an object signal with partial values
|
|
145
|
+
* @param objectSignal - Writable object signal
|
|
146
|
+
* @param partial - Partial object to merge
|
|
147
|
+
*/
|
|
148
|
+
function patchSignal(objectSignal, partial) {
|
|
149
|
+
objectSignal.update(obj => ({ ...obj, ...partial }));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Picks specific keys from an object signal
|
|
153
|
+
* @param objectSignal - Object signal
|
|
154
|
+
* @param keys - Keys to pick
|
|
155
|
+
* @returns Computed signal with picked keys
|
|
156
|
+
*/
|
|
157
|
+
function pickSignal(objectSignal, ...keys) {
|
|
158
|
+
return computed(() => {
|
|
159
|
+
const obj = objectSignal();
|
|
160
|
+
const result = {};
|
|
161
|
+
for (const key of keys) {
|
|
162
|
+
result[key] = obj[key];
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Omits specific keys from an object signal
|
|
169
|
+
* @param objectSignal - Object signal
|
|
170
|
+
* @param keys - Keys to omit
|
|
171
|
+
* @returns Computed signal with omitted keys
|
|
172
|
+
*/
|
|
173
|
+
function omitSignal(objectSignal, ...keys) {
|
|
174
|
+
return computed(() => {
|
|
175
|
+
const obj = objectSignal();
|
|
176
|
+
const result = { ...obj };
|
|
177
|
+
for (const key of keys) {
|
|
178
|
+
delete result[key];
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Gets a property value from an object signal
|
|
185
|
+
* @param objectSignal - Object signal
|
|
186
|
+
* @param key - Property key
|
|
187
|
+
* @returns Computed signal with property value
|
|
188
|
+
*/
|
|
189
|
+
function pluckSignal(objectSignal, key) {
|
|
190
|
+
return computed(() => objectSignal()[key]);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Gets the keys of an object signal
|
|
194
|
+
* @param objectSignal - Object signal
|
|
195
|
+
* @returns Computed signal with object keys
|
|
196
|
+
*/
|
|
197
|
+
function objectSignalKeys(objectSignal) {
|
|
198
|
+
return computed(() => Object.keys(objectSignal()));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Gets the values of an object signal
|
|
202
|
+
* @param objectSignal - Object signal
|
|
203
|
+
* @returns Computed signal with object values
|
|
204
|
+
*/
|
|
205
|
+
function objectSignalValues(objectSignal) {
|
|
206
|
+
return computed(() => Object.values(objectSignal()));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Gets the entries of an object signal
|
|
210
|
+
* @param objectSignal - Object signal
|
|
211
|
+
* @returns Computed signal with object entries
|
|
212
|
+
*/
|
|
213
|
+
function objectSignalEntries(objectSignal) {
|
|
214
|
+
return computed(() => Object.entries(objectSignal()));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Creates an effect that runs only when the signal value changes
|
|
219
|
+
* @param source - Source signal to watch
|
|
220
|
+
* @param fn - Effect function
|
|
221
|
+
* @param options - Effect options
|
|
222
|
+
* @returns EffectRef
|
|
223
|
+
*/
|
|
224
|
+
function watchSignal(source, fn, options) {
|
|
225
|
+
let previousValue = undefined;
|
|
226
|
+
let isFirst = true;
|
|
227
|
+
return effect(() => {
|
|
228
|
+
const value = source();
|
|
229
|
+
if (!isFirst) {
|
|
230
|
+
fn(value, previousValue);
|
|
231
|
+
}
|
|
232
|
+
previousValue = value;
|
|
233
|
+
isFirst = false;
|
|
234
|
+
}, options);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Creates an effect that runs once when the signal meets a condition
|
|
238
|
+
* @param source - Source signal to watch
|
|
239
|
+
* @param predicate - Condition to check
|
|
240
|
+
* @param fn - Effect function
|
|
241
|
+
* @param options - Effect options
|
|
242
|
+
* @returns EffectRef
|
|
243
|
+
*/
|
|
244
|
+
function watchUntil(source, predicate, fn, options) {
|
|
245
|
+
let hasRun = false;
|
|
246
|
+
const effectRef = effect(() => {
|
|
247
|
+
if (hasRun)
|
|
248
|
+
return;
|
|
249
|
+
const value = source();
|
|
250
|
+
if (predicate(value)) {
|
|
251
|
+
fn(value);
|
|
252
|
+
hasRun = true;
|
|
253
|
+
effectRef.destroy();
|
|
254
|
+
}
|
|
255
|
+
}, options);
|
|
256
|
+
return effectRef;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Creates a throttled effect
|
|
260
|
+
* @param source - Source signal to watch
|
|
261
|
+
* @param fn - Effect function
|
|
262
|
+
* @param ms - Throttle delay in milliseconds
|
|
263
|
+
* @param options - Effect options
|
|
264
|
+
* @returns EffectRef
|
|
265
|
+
*/
|
|
266
|
+
function throttleEffect(source, fn, ms, options) {
|
|
267
|
+
let lastRun = 0;
|
|
268
|
+
return effect(() => {
|
|
269
|
+
const value = source();
|
|
270
|
+
const now = Date.now();
|
|
271
|
+
if (now - lastRun >= ms) {
|
|
272
|
+
fn(value);
|
|
273
|
+
lastRun = now;
|
|
274
|
+
}
|
|
275
|
+
}, options);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Creates a debounced effect
|
|
279
|
+
* @param source - Source signal to watch
|
|
280
|
+
* @param fn - Effect function
|
|
281
|
+
* @param ms - Debounce delay in milliseconds
|
|
282
|
+
* @param options - Effect options
|
|
283
|
+
* @returns EffectRef
|
|
284
|
+
*/
|
|
285
|
+
function debounceEffect(source, fn, ms, options) {
|
|
286
|
+
let timeoutId;
|
|
287
|
+
return effect(() => {
|
|
288
|
+
const value = source();
|
|
289
|
+
clearTimeout(timeoutId);
|
|
290
|
+
timeoutId = setTimeout(() => fn(value), ms);
|
|
291
|
+
}, options);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/*
|
|
295
|
+
* Public API Surface of ng-signals-utils
|
|
296
|
+
*/
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Generated bundle index. Do not edit.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
export { arraySignalFilter, arraySignalFind, arraySignalIsEmpty, arraySignalLength, arraySignalMap, arraySignalPush, arraySignalRemoveAt, arraySignalSort, combineSignals, debounceEffect, debounceSignal, distinctSignal, filterSignal, mapSignal, objectSignalEntries, objectSignalKeys, objectSignalValues, omitSignal, patchSignal, pickSignal, pluckSignal, throttleEffect, watchSignal, watchUntil };
|
|
303
|
+
//# sourceMappingURL=ng-signals-utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-signals-utils.mjs","sources":["../../../projects/ng-signals-utils/src/lib/signal-transformations.ts","../../../projects/ng-signals-utils/src/lib/signal-array-utils.ts","../../../projects/ng-signals-utils/src/lib/signal-object-utils.ts","../../../projects/ng-signals-utils/src/lib/signal-effect-utils.ts","../../../projects/ng-signals-utils/src/public-api.ts","../../../projects/ng-signals-utils/src/ng-signals-utils.ts"],"sourcesContent":["import { Signal, computed, signal, WritableSignal, effect } from '@angular/core';\r\n\r\n/**\r\n * Maps a signal value to another type\r\n * @param source - Source signal\r\n * @param fn - Mapping function\r\n * @returns Computed signal with mapped value\r\n */\r\nexport function mapSignal<T, R>(\r\n source: Signal<T>,\r\n fn: (value: T) => R\r\n): Signal<R> {\r\n return computed(() => fn(source()));\r\n}\r\n\r\n/**\r\n * Filters signal updates based on a predicate\r\n * @param source - Source signal\r\n * @param predicate - Filter predicate\r\n * @param initialValue - Initial value to use if predicate fails\r\n * @returns Signal that only updates when predicate returns true\r\n */\r\nexport function filterSignal<T>(\r\n source: Signal<T>,\r\n predicate: (value: T) => boolean,\r\n initialValue: T\r\n): Signal<T> {\r\n const filtered = signal(initialValue);\r\n \r\n effect(() => {\r\n const value = source();\r\n if (predicate(value)) {\r\n (filtered as WritableSignal<T>).set(value);\r\n }\r\n });\r\n \r\n return filtered.asReadonly();\r\n}\r\n\r\n/**\r\n * Debounces signal updates\r\n * @param source - Source signal\r\n * @param ms - Debounce delay in milliseconds\r\n * @returns Debounced signal\r\n */\r\nexport function debounceSignal<T>(\r\n source: Signal<T>,\r\n ms: number\r\n): Signal<T> {\r\n const debounced = signal(source());\r\n let timeoutId: any;\r\n \r\n effect(() => {\r\n const value = source();\r\n clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => {\r\n (debounced as WritableSignal<T>).set(value);\r\n }, ms);\r\n });\r\n \r\n return debounced.asReadonly();\r\n}\r\n\r\n/**\r\n * Combines multiple signals into a single signal\r\n * @param signals - Array of signals to combine\r\n * @returns Combined signal with array of values\r\n */\r\nexport function combineSignals<T extends readonly Signal<any>[]>(\r\n signals: T\r\n): Signal<{ [K in keyof T]: T[K] extends Signal<infer U> ? U : never }> {\r\n return computed(() => signals.map(s => s()) as any);\r\n}\r\n\r\n/**\r\n * Creates a signal that emits distinct values only\r\n * @param source - Source signal\r\n * @param compareFn - Optional comparison function\r\n * @returns Signal that only updates on distinct values\r\n */\r\nexport function distinctSignal<T>(\r\n source: Signal<T>,\r\n compareFn: (a: T, b: T) => boolean = (a, b) => a === b\r\n): Signal<T> {\r\n const distinct = signal(source());\r\n let lastValue = source();\r\n \r\n effect(() => {\r\n const value = source();\r\n if (!compareFn(value, lastValue)) {\r\n lastValue = value;\r\n (distinct as WritableSignal<T>).set(value);\r\n }\r\n });\r\n \r\n return distinct.asReadonly();\r\n}\r\n","import { Signal, WritableSignal, computed } from '@angular/core';\r\n\r\n/**\r\n * Pushes an item to an array signal\r\n * @param arraySignal - Writable array signal\r\n * @param item - Item to push\r\n */\r\nexport function arraySignalPush<T>(\r\n arraySignal: WritableSignal<T[]>,\r\n item: T\r\n): void {\r\n arraySignal.update(arr => [...arr, item]);\r\n}\r\n\r\n/**\r\n * Removes an item from an array signal at the specified index\r\n * @param arraySignal - Writable array signal\r\n * @param index - Index to remove\r\n */\r\nexport function arraySignalRemoveAt<T>(\r\n arraySignal: WritableSignal<T[]>,\r\n index: number\r\n): void {\r\n arraySignal.update(arr => arr.filter((_, i) => i !== index));\r\n}\r\n\r\n/**\r\n * Filters an array signal\r\n * @param arraySignal - Array signal\r\n * @param predicate - Filter predicate\r\n * @returns Computed signal with filtered array\r\n */\r\nexport function arraySignalFilter<T>(\r\n arraySignal: Signal<T[]>,\r\n predicate: (item: T, index: number) => boolean\r\n): Signal<T[]> {\r\n return computed(() => arraySignal().filter(predicate));\r\n}\r\n\r\n/**\r\n * Maps an array signal\r\n * @param arraySignal - Array signal\r\n * @param fn - Mapping function\r\n * @returns Computed signal with mapped array\r\n */\r\nexport function arraySignalMap<T, R>(\r\n arraySignal: Signal<T[]>,\r\n fn: (item: T, index: number) => R\r\n): Signal<R[]> {\r\n return computed(() => arraySignal().map(fn));\r\n}\r\n\r\n/**\r\n * Sorts an array signal\r\n * @param arraySignal - Array signal\r\n * @param compareFn - Optional comparison function\r\n * @returns Computed signal with sorted array\r\n */\r\nexport function arraySignalSort<T>(\r\n arraySignal: Signal<T[]>,\r\n compareFn?: (a: T, b: T) => number\r\n): Signal<T[]> {\r\n return computed(() => [...arraySignal()].sort(compareFn));\r\n}\r\n\r\n/**\r\n * Finds an item in an array signal\r\n * @param arraySignal - Array signal\r\n * @param predicate - Find predicate\r\n * @returns Computed signal with found item or undefined\r\n */\r\nexport function arraySignalFind<T>(\r\n arraySignal: Signal<T[]>,\r\n predicate: (item: T, index: number) => boolean\r\n): Signal<T | undefined> {\r\n return computed(() => arraySignal().find(predicate));\r\n}\r\n\r\n/**\r\n * Gets the length of an array signal\r\n * @param arraySignal - Array signal\r\n * @returns Computed signal with array length\r\n */\r\nexport function arraySignalLength<T>(\r\n arraySignal: Signal<T[]>\r\n): Signal<number> {\r\n return computed(() => arraySignal().length);\r\n}\r\n\r\n/**\r\n * Checks if an array signal is empty\r\n * @param arraySignal - Array signal\r\n * @returns Computed signal indicating if array is empty\r\n */\r\nexport function arraySignalIsEmpty<T>(\r\n arraySignal: Signal<T[]>\r\n): Signal<boolean> {\r\n return computed(() => arraySignal().length === 0);\r\n}\r\n","import { Signal, WritableSignal, computed } from '@angular/core';\r\n\r\n/**\r\n * Patches an object signal with partial values\r\n * @param objectSignal - Writable object signal\r\n * @param partial - Partial object to merge\r\n */\r\nexport function patchSignal<T extends object>(\r\n objectSignal: WritableSignal<T>,\r\n partial: Partial<T>\r\n): void {\r\n objectSignal.update(obj => ({ ...obj, ...partial }));\r\n}\r\n\r\n/**\r\n * Picks specific keys from an object signal\r\n * @param objectSignal - Object signal\r\n * @param keys - Keys to pick\r\n * @returns Computed signal with picked keys\r\n */\r\nexport function pickSignal<T extends object, K extends keyof T>(\r\n objectSignal: Signal<T>,\r\n ...keys: K[]\r\n): Signal<Pick<T, K>> {\r\n return computed(() => {\r\n const obj = objectSignal();\r\n const result = {} as Pick<T, K>;\r\n for (const key of keys) {\r\n result[key] = obj[key];\r\n }\r\n return result;\r\n });\r\n}\r\n\r\n/**\r\n * Omits specific keys from an object signal\r\n * @param objectSignal - Object signal\r\n * @param keys - Keys to omit\r\n * @returns Computed signal with omitted keys\r\n */\r\nexport function omitSignal<T extends object, K extends keyof T>(\r\n objectSignal: Signal<T>,\r\n ...keys: K[]\r\n): Signal<Omit<T, K>> {\r\n return computed(() => {\r\n const obj = objectSignal();\r\n const result = { ...obj } as any;\r\n for (const key of keys) {\r\n delete result[key];\r\n }\r\n return result;\r\n });\r\n}\r\n\r\n/**\r\n * Gets a property value from an object signal\r\n * @param objectSignal - Object signal\r\n * @param key - Property key\r\n * @returns Computed signal with property value\r\n */\r\nexport function pluckSignal<T extends object, K extends keyof T>(\r\n objectSignal: Signal<T>,\r\n key: K\r\n): Signal<T[K]> {\r\n return computed(() => objectSignal()[key]);\r\n}\r\n\r\n/**\r\n * Gets the keys of an object signal\r\n * @param objectSignal - Object signal\r\n * @returns Computed signal with object keys\r\n */\r\nexport function objectSignalKeys<T extends object>(\r\n objectSignal: Signal<T>\r\n): Signal<(keyof T)[]> {\r\n return computed(() => Object.keys(objectSignal()) as (keyof T)[]);\r\n}\r\n\r\n/**\r\n * Gets the values of an object signal\r\n * @param objectSignal - Object signal\r\n * @returns Computed signal with object values\r\n */\r\nexport function objectSignalValues<T extends object>(\r\n objectSignal: Signal<T>\r\n): Signal<T[keyof T][]> {\r\n return computed(() => Object.values(objectSignal()) as T[keyof T][]);\r\n}\r\n\r\n/**\r\n * Gets the entries of an object signal\r\n * @param objectSignal - Object signal\r\n * @returns Computed signal with object entries\r\n */\r\nexport function objectSignalEntries<T extends object>(\r\n objectSignal: Signal<T>\r\n): Signal<[keyof T, T[keyof T]][]> {\r\n return computed(() => Object.entries(objectSignal()) as [keyof T, T[keyof T]][]);\r\n}\r\n","import { Signal, effect, EffectRef, CreateEffectOptions } from '@angular/core';\r\n\r\n/**\r\n * Creates an effect that runs only when the signal value changes\r\n * @param source - Source signal to watch\r\n * @param fn - Effect function\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function watchSignal<T>(\r\n source: Signal<T>,\r\n fn: (value: T, previousValue: T | undefined) => void,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let previousValue: T | undefined = undefined;\r\n let isFirst = true;\r\n \r\n return effect(() => {\r\n const value = source();\r\n if (!isFirst) {\r\n fn(value, previousValue);\r\n }\r\n previousValue = value;\r\n isFirst = false;\r\n }, options);\r\n}\r\n\r\n/**\r\n * Creates an effect that runs once when the signal meets a condition\r\n * @param source - Source signal to watch\r\n * @param predicate - Condition to check\r\n * @param fn - Effect function\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function watchUntil<T>(\r\n source: Signal<T>,\r\n predicate: (value: T) => boolean,\r\n fn: (value: T) => void,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let hasRun = false;\r\n \r\n const effectRef = effect(() => {\r\n if (hasRun) return;\r\n \r\n const value = source();\r\n if (predicate(value)) {\r\n fn(value);\r\n hasRun = true;\r\n effectRef.destroy();\r\n }\r\n }, options);\r\n \r\n return effectRef;\r\n}\r\n\r\n/**\r\n * Creates a throttled effect\r\n * @param source - Source signal to watch\r\n * @param fn - Effect function\r\n * @param ms - Throttle delay in milliseconds\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function throttleEffect<T>(\r\n source: Signal<T>,\r\n fn: (value: T) => void,\r\n ms: number,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let lastRun = 0;\r\n \r\n return effect(() => {\r\n const value = source();\r\n const now = Date.now();\r\n \r\n if (now - lastRun >= ms) {\r\n fn(value);\r\n lastRun = now;\r\n }\r\n }, options);\r\n}\r\n\r\n/**\r\n * Creates a debounced effect\r\n * @param source - Source signal to watch\r\n * @param fn - Effect function\r\n * @param ms - Debounce delay in milliseconds\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function debounceEffect<T>(\r\n source: Signal<T>,\r\n fn: (value: T) => void,\r\n ms: number,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let timeoutId: any;\r\n \r\n return effect(() => {\r\n const value = source();\r\n clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => fn(value), ms);\r\n }, options);\r\n}\r\n","/*\r\n * Public API Surface of ng-signals-utils\r\n */\r\n\r\nexport * from './lib/signal-transformations';\r\nexport * from './lib/signal-array-utils';\r\nexport * from './lib/signal-object-utils';\r\nexport * from './lib/signal-effect-utils';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { computed, signal, effect } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Maps a signal value to another type
|
|
5
|
+
* @param source - Source signal
|
|
6
|
+
* @param fn - Mapping function
|
|
7
|
+
* @returns Computed signal with mapped value
|
|
8
|
+
*/
|
|
9
|
+
function mapSignal(source, fn) {
|
|
10
|
+
return computed(() => fn(source()));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Filters signal updates based on a predicate
|
|
14
|
+
* @param source - Source signal
|
|
15
|
+
* @param predicate - Filter predicate
|
|
16
|
+
* @param initialValue - Initial value to use if predicate fails
|
|
17
|
+
* @returns Signal that only updates when predicate returns true
|
|
18
|
+
*/
|
|
19
|
+
function filterSignal(source, predicate, initialValue) {
|
|
20
|
+
const filtered = signal(initialValue, ...(ngDevMode ? [{ debugName: "filtered" }] : []));
|
|
21
|
+
effect(() => {
|
|
22
|
+
const value = source();
|
|
23
|
+
if (predicate(value)) {
|
|
24
|
+
filtered.set(value);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
return filtered.asReadonly();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Debounces signal updates
|
|
31
|
+
* @param source - Source signal
|
|
32
|
+
* @param ms - Debounce delay in milliseconds
|
|
33
|
+
* @returns Debounced signal
|
|
34
|
+
*/
|
|
35
|
+
function debounceSignal(source, ms) {
|
|
36
|
+
const debounced = signal(source(), ...(ngDevMode ? [{ debugName: "debounced" }] : []));
|
|
37
|
+
let timeoutId;
|
|
38
|
+
effect(() => {
|
|
39
|
+
const value = source();
|
|
40
|
+
clearTimeout(timeoutId);
|
|
41
|
+
timeoutId = setTimeout(() => {
|
|
42
|
+
debounced.set(value);
|
|
43
|
+
}, ms);
|
|
44
|
+
});
|
|
45
|
+
return debounced.asReadonly();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Combines multiple signals into a single signal
|
|
49
|
+
* @param signals - Array of signals to combine
|
|
50
|
+
* @returns Combined signal with array of values
|
|
51
|
+
*/
|
|
52
|
+
function combineSignals(signals) {
|
|
53
|
+
return computed(() => signals.map(s => s()));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Creates a signal that emits distinct values only
|
|
57
|
+
* @param source - Source signal
|
|
58
|
+
* @param compareFn - Optional comparison function
|
|
59
|
+
* @returns Signal that only updates on distinct values
|
|
60
|
+
*/
|
|
61
|
+
function distinctSignal(source, compareFn = (a, b) => a === b) {
|
|
62
|
+
const distinct = signal(source(), ...(ngDevMode ? [{ debugName: "distinct" }] : []));
|
|
63
|
+
let lastValue = source();
|
|
64
|
+
effect(() => {
|
|
65
|
+
const value = source();
|
|
66
|
+
if (!compareFn(value, lastValue)) {
|
|
67
|
+
lastValue = value;
|
|
68
|
+
distinct.set(value);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return distinct.asReadonly();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Pushes an item to an array signal
|
|
76
|
+
* @param arraySignal - Writable array signal
|
|
77
|
+
* @param item - Item to push
|
|
78
|
+
*/
|
|
79
|
+
function arraySignalPush(arraySignal, item) {
|
|
80
|
+
arraySignal.update(arr => [...arr, item]);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Removes an item from an array signal at the specified index
|
|
84
|
+
* @param arraySignal - Writable array signal
|
|
85
|
+
* @param index - Index to remove
|
|
86
|
+
*/
|
|
87
|
+
function arraySignalRemoveAt(arraySignal, index) {
|
|
88
|
+
arraySignal.update(arr => arr.filter((_, i) => i !== index));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Filters an array signal
|
|
92
|
+
* @param arraySignal - Array signal
|
|
93
|
+
* @param predicate - Filter predicate
|
|
94
|
+
* @returns Computed signal with filtered array
|
|
95
|
+
*/
|
|
96
|
+
function arraySignalFilter(arraySignal, predicate) {
|
|
97
|
+
return computed(() => arraySignal().filter(predicate));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Maps an array signal
|
|
101
|
+
* @param arraySignal - Array signal
|
|
102
|
+
* @param fn - Mapping function
|
|
103
|
+
* @returns Computed signal with mapped array
|
|
104
|
+
*/
|
|
105
|
+
function arraySignalMap(arraySignal, fn) {
|
|
106
|
+
return computed(() => arraySignal().map(fn));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Sorts an array signal
|
|
110
|
+
* @param arraySignal - Array signal
|
|
111
|
+
* @param compareFn - Optional comparison function
|
|
112
|
+
* @returns Computed signal with sorted array
|
|
113
|
+
*/
|
|
114
|
+
function arraySignalSort(arraySignal, compareFn) {
|
|
115
|
+
return computed(() => [...arraySignal()].sort(compareFn));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Finds an item in an array signal
|
|
119
|
+
* @param arraySignal - Array signal
|
|
120
|
+
* @param predicate - Find predicate
|
|
121
|
+
* @returns Computed signal with found item or undefined
|
|
122
|
+
*/
|
|
123
|
+
function arraySignalFind(arraySignal, predicate) {
|
|
124
|
+
return computed(() => arraySignal().find(predicate));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Gets the length of an array signal
|
|
128
|
+
* @param arraySignal - Array signal
|
|
129
|
+
* @returns Computed signal with array length
|
|
130
|
+
*/
|
|
131
|
+
function arraySignalLength(arraySignal) {
|
|
132
|
+
return computed(() => arraySignal().length);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Checks if an array signal is empty
|
|
136
|
+
* @param arraySignal - Array signal
|
|
137
|
+
* @returns Computed signal indicating if array is empty
|
|
138
|
+
*/
|
|
139
|
+
function arraySignalIsEmpty(arraySignal) {
|
|
140
|
+
return computed(() => arraySignal().length === 0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Patches an object signal with partial values
|
|
145
|
+
* @param objectSignal - Writable object signal
|
|
146
|
+
* @param partial - Partial object to merge
|
|
147
|
+
*/
|
|
148
|
+
function patchSignal(objectSignal, partial) {
|
|
149
|
+
objectSignal.update(obj => ({ ...obj, ...partial }));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Picks specific keys from an object signal
|
|
153
|
+
* @param objectSignal - Object signal
|
|
154
|
+
* @param keys - Keys to pick
|
|
155
|
+
* @returns Computed signal with picked keys
|
|
156
|
+
*/
|
|
157
|
+
function pickSignal(objectSignal, ...keys) {
|
|
158
|
+
return computed(() => {
|
|
159
|
+
const obj = objectSignal();
|
|
160
|
+
const result = {};
|
|
161
|
+
for (const key of keys) {
|
|
162
|
+
result[key] = obj[key];
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Omits specific keys from an object signal
|
|
169
|
+
* @param objectSignal - Object signal
|
|
170
|
+
* @param keys - Keys to omit
|
|
171
|
+
* @returns Computed signal with omitted keys
|
|
172
|
+
*/
|
|
173
|
+
function omitSignal(objectSignal, ...keys) {
|
|
174
|
+
return computed(() => {
|
|
175
|
+
const obj = objectSignal();
|
|
176
|
+
const result = { ...obj };
|
|
177
|
+
for (const key of keys) {
|
|
178
|
+
delete result[key];
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Gets a property value from an object signal
|
|
185
|
+
* @param objectSignal - Object signal
|
|
186
|
+
* @param key - Property key
|
|
187
|
+
* @returns Computed signal with property value
|
|
188
|
+
*/
|
|
189
|
+
function pluckSignal(objectSignal, key) {
|
|
190
|
+
return computed(() => objectSignal()[key]);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Gets the keys of an object signal
|
|
194
|
+
* @param objectSignal - Object signal
|
|
195
|
+
* @returns Computed signal with object keys
|
|
196
|
+
*/
|
|
197
|
+
function objectSignalKeys(objectSignal) {
|
|
198
|
+
return computed(() => Object.keys(objectSignal()));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Gets the values of an object signal
|
|
202
|
+
* @param objectSignal - Object signal
|
|
203
|
+
* @returns Computed signal with object values
|
|
204
|
+
*/
|
|
205
|
+
function objectSignalValues(objectSignal) {
|
|
206
|
+
return computed(() => Object.values(objectSignal()));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Gets the entries of an object signal
|
|
210
|
+
* @param objectSignal - Object signal
|
|
211
|
+
* @returns Computed signal with object entries
|
|
212
|
+
*/
|
|
213
|
+
function objectSignalEntries(objectSignal) {
|
|
214
|
+
return computed(() => Object.entries(objectSignal()));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Creates an effect that runs only when the signal value changes
|
|
219
|
+
* @param source - Source signal to watch
|
|
220
|
+
* @param fn - Effect function
|
|
221
|
+
* @param options - Effect options
|
|
222
|
+
* @returns EffectRef
|
|
223
|
+
*/
|
|
224
|
+
function watchSignal(source, fn, options) {
|
|
225
|
+
let previousValue = undefined;
|
|
226
|
+
let isFirst = true;
|
|
227
|
+
return effect(() => {
|
|
228
|
+
const value = source();
|
|
229
|
+
if (!isFirst) {
|
|
230
|
+
fn(value, previousValue);
|
|
231
|
+
}
|
|
232
|
+
previousValue = value;
|
|
233
|
+
isFirst = false;
|
|
234
|
+
}, options);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Creates an effect that runs once when the signal meets a condition
|
|
238
|
+
* @param source - Source signal to watch
|
|
239
|
+
* @param predicate - Condition to check
|
|
240
|
+
* @param fn - Effect function
|
|
241
|
+
* @param options - Effect options
|
|
242
|
+
* @returns EffectRef
|
|
243
|
+
*/
|
|
244
|
+
function watchUntil(source, predicate, fn, options) {
|
|
245
|
+
let hasRun = false;
|
|
246
|
+
const effectRef = effect(() => {
|
|
247
|
+
if (hasRun)
|
|
248
|
+
return;
|
|
249
|
+
const value = source();
|
|
250
|
+
if (predicate(value)) {
|
|
251
|
+
fn(value);
|
|
252
|
+
hasRun = true;
|
|
253
|
+
effectRef.destroy();
|
|
254
|
+
}
|
|
255
|
+
}, options);
|
|
256
|
+
return effectRef;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Creates a throttled effect
|
|
260
|
+
* @param source - Source signal to watch
|
|
261
|
+
* @param fn - Effect function
|
|
262
|
+
* @param ms - Throttle delay in milliseconds
|
|
263
|
+
* @param options - Effect options
|
|
264
|
+
* @returns EffectRef
|
|
265
|
+
*/
|
|
266
|
+
function throttleEffect(source, fn, ms, options) {
|
|
267
|
+
let lastRun = 0;
|
|
268
|
+
return effect(() => {
|
|
269
|
+
const value = source();
|
|
270
|
+
const now = Date.now();
|
|
271
|
+
if (now - lastRun >= ms) {
|
|
272
|
+
fn(value);
|
|
273
|
+
lastRun = now;
|
|
274
|
+
}
|
|
275
|
+
}, options);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Creates a debounced effect
|
|
279
|
+
* @param source - Source signal to watch
|
|
280
|
+
* @param fn - Effect function
|
|
281
|
+
* @param ms - Debounce delay in milliseconds
|
|
282
|
+
* @param options - Effect options
|
|
283
|
+
* @returns EffectRef
|
|
284
|
+
*/
|
|
285
|
+
function debounceEffect(source, fn, ms, options) {
|
|
286
|
+
let timeoutId;
|
|
287
|
+
return effect(() => {
|
|
288
|
+
const value = source();
|
|
289
|
+
clearTimeout(timeoutId);
|
|
290
|
+
timeoutId = setTimeout(() => fn(value), ms);
|
|
291
|
+
}, options);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/*
|
|
295
|
+
* Public API Surface of ng-signals-utils
|
|
296
|
+
*/
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Generated bundle index. Do not edit.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
export { arraySignalFilter, arraySignalFind, arraySignalIsEmpty, arraySignalLength, arraySignalMap, arraySignalPush, arraySignalRemoveAt, arraySignalSort, combineSignals, debounceEffect, debounceSignal, distinctSignal, filterSignal, mapSignal, objectSignalEntries, objectSignalKeys, objectSignalValues, omitSignal, patchSignal, pickSignal, pluckSignal, throttleEffect, watchSignal, watchUntil };
|
|
303
|
+
//# sourceMappingURL=sergeydus-ng-signals-utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sergeydus-ng-signals-utils.mjs","sources":["../../../projects/ng-signals-utils/src/lib/signal-transformations.ts","../../../projects/ng-signals-utils/src/lib/signal-array-utils.ts","../../../projects/ng-signals-utils/src/lib/signal-object-utils.ts","../../../projects/ng-signals-utils/src/lib/signal-effect-utils.ts","../../../projects/ng-signals-utils/src/public-api.ts","../../../projects/ng-signals-utils/src/sergeydus-ng-signals-utils.ts"],"sourcesContent":["import { Signal, computed, signal, WritableSignal, effect } from '@angular/core';\r\n\r\n/**\r\n * Maps a signal value to another type\r\n * @param source - Source signal\r\n * @param fn - Mapping function\r\n * @returns Computed signal with mapped value\r\n */\r\nexport function mapSignal<T, R>(\r\n source: Signal<T>,\r\n fn: (value: T) => R\r\n): Signal<R> {\r\n return computed(() => fn(source()));\r\n}\r\n\r\n/**\r\n * Filters signal updates based on a predicate\r\n * @param source - Source signal\r\n * @param predicate - Filter predicate\r\n * @param initialValue - Initial value to use if predicate fails\r\n * @returns Signal that only updates when predicate returns true\r\n */\r\nexport function filterSignal<T>(\r\n source: Signal<T>,\r\n predicate: (value: T) => boolean,\r\n initialValue: T\r\n): Signal<T> {\r\n const filtered = signal(initialValue);\r\n \r\n effect(() => {\r\n const value = source();\r\n if (predicate(value)) {\r\n (filtered as WritableSignal<T>).set(value);\r\n }\r\n });\r\n \r\n return filtered.asReadonly();\r\n}\r\n\r\n/**\r\n * Debounces signal updates\r\n * @param source - Source signal\r\n * @param ms - Debounce delay in milliseconds\r\n * @returns Debounced signal\r\n */\r\nexport function debounceSignal<T>(\r\n source: Signal<T>,\r\n ms: number\r\n): Signal<T> {\r\n const debounced = signal(source());\r\n let timeoutId: any;\r\n \r\n effect(() => {\r\n const value = source();\r\n clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => {\r\n (debounced as WritableSignal<T>).set(value);\r\n }, ms);\r\n });\r\n \r\n return debounced.asReadonly();\r\n}\r\n\r\n/**\r\n * Combines multiple signals into a single signal\r\n * @param signals - Array of signals to combine\r\n * @returns Combined signal with array of values\r\n */\r\nexport function combineSignals<T extends readonly Signal<any>[]>(\r\n signals: T\r\n): Signal<{ [K in keyof T]: T[K] extends Signal<infer U> ? U : never }> {\r\n return computed(() => signals.map(s => s()) as any);\r\n}\r\n\r\n/**\r\n * Creates a signal that emits distinct values only\r\n * @param source - Source signal\r\n * @param compareFn - Optional comparison function\r\n * @returns Signal that only updates on distinct values\r\n */\r\nexport function distinctSignal<T>(\r\n source: Signal<T>,\r\n compareFn: (a: T, b: T) => boolean = (a, b) => a === b\r\n): Signal<T> {\r\n const distinct = signal(source());\r\n let lastValue = source();\r\n \r\n effect(() => {\r\n const value = source();\r\n if (!compareFn(value, lastValue)) {\r\n lastValue = value;\r\n (distinct as WritableSignal<T>).set(value);\r\n }\r\n });\r\n \r\n return distinct.asReadonly();\r\n}\r\n","import { Signal, WritableSignal, computed } from '@angular/core';\r\n\r\n/**\r\n * Pushes an item to an array signal\r\n * @param arraySignal - Writable array signal\r\n * @param item - Item to push\r\n */\r\nexport function arraySignalPush<T>(\r\n arraySignal: WritableSignal<T[]>,\r\n item: T\r\n): void {\r\n arraySignal.update(arr => [...arr, item]);\r\n}\r\n\r\n/**\r\n * Removes an item from an array signal at the specified index\r\n * @param arraySignal - Writable array signal\r\n * @param index - Index to remove\r\n */\r\nexport function arraySignalRemoveAt<T>(\r\n arraySignal: WritableSignal<T[]>,\r\n index: number\r\n): void {\r\n arraySignal.update(arr => arr.filter((_, i) => i !== index));\r\n}\r\n\r\n/**\r\n * Filters an array signal\r\n * @param arraySignal - Array signal\r\n * @param predicate - Filter predicate\r\n * @returns Computed signal with filtered array\r\n */\r\nexport function arraySignalFilter<T>(\r\n arraySignal: Signal<T[]>,\r\n predicate: (item: T, index: number) => boolean\r\n): Signal<T[]> {\r\n return computed(() => arraySignal().filter(predicate));\r\n}\r\n\r\n/**\r\n * Maps an array signal\r\n * @param arraySignal - Array signal\r\n * @param fn - Mapping function\r\n * @returns Computed signal with mapped array\r\n */\r\nexport function arraySignalMap<T, R>(\r\n arraySignal: Signal<T[]>,\r\n fn: (item: T, index: number) => R\r\n): Signal<R[]> {\r\n return computed(() => arraySignal().map(fn));\r\n}\r\n\r\n/**\r\n * Sorts an array signal\r\n * @param arraySignal - Array signal\r\n * @param compareFn - Optional comparison function\r\n * @returns Computed signal with sorted array\r\n */\r\nexport function arraySignalSort<T>(\r\n arraySignal: Signal<T[]>,\r\n compareFn?: (a: T, b: T) => number\r\n): Signal<T[]> {\r\n return computed(() => [...arraySignal()].sort(compareFn));\r\n}\r\n\r\n/**\r\n * Finds an item in an array signal\r\n * @param arraySignal - Array signal\r\n * @param predicate - Find predicate\r\n * @returns Computed signal with found item or undefined\r\n */\r\nexport function arraySignalFind<T>(\r\n arraySignal: Signal<T[]>,\r\n predicate: (item: T, index: number) => boolean\r\n): Signal<T | undefined> {\r\n return computed(() => arraySignal().find(predicate));\r\n}\r\n\r\n/**\r\n * Gets the length of an array signal\r\n * @param arraySignal - Array signal\r\n * @returns Computed signal with array length\r\n */\r\nexport function arraySignalLength<T>(\r\n arraySignal: Signal<T[]>\r\n): Signal<number> {\r\n return computed(() => arraySignal().length);\r\n}\r\n\r\n/**\r\n * Checks if an array signal is empty\r\n * @param arraySignal - Array signal\r\n * @returns Computed signal indicating if array is empty\r\n */\r\nexport function arraySignalIsEmpty<T>(\r\n arraySignal: Signal<T[]>\r\n): Signal<boolean> {\r\n return computed(() => arraySignal().length === 0);\r\n}\r\n","import { Signal, WritableSignal, computed } from '@angular/core';\r\n\r\n/**\r\n * Patches an object signal with partial values\r\n * @param objectSignal - Writable object signal\r\n * @param partial - Partial object to merge\r\n */\r\nexport function patchSignal<T extends object>(\r\n objectSignal: WritableSignal<T>,\r\n partial: Partial<T>\r\n): void {\r\n objectSignal.update(obj => ({ ...obj, ...partial }));\r\n}\r\n\r\n/**\r\n * Picks specific keys from an object signal\r\n * @param objectSignal - Object signal\r\n * @param keys - Keys to pick\r\n * @returns Computed signal with picked keys\r\n */\r\nexport function pickSignal<T extends object, K extends keyof T>(\r\n objectSignal: Signal<T>,\r\n ...keys: K[]\r\n): Signal<Pick<T, K>> {\r\n return computed(() => {\r\n const obj = objectSignal();\r\n const result = {} as Pick<T, K>;\r\n for (const key of keys) {\r\n result[key] = obj[key];\r\n }\r\n return result;\r\n });\r\n}\r\n\r\n/**\r\n * Omits specific keys from an object signal\r\n * @param objectSignal - Object signal\r\n * @param keys - Keys to omit\r\n * @returns Computed signal with omitted keys\r\n */\r\nexport function omitSignal<T extends object, K extends keyof T>(\r\n objectSignal: Signal<T>,\r\n ...keys: K[]\r\n): Signal<Omit<T, K>> {\r\n return computed(() => {\r\n const obj = objectSignal();\r\n const result = { ...obj } as any;\r\n for (const key of keys) {\r\n delete result[key];\r\n }\r\n return result;\r\n });\r\n}\r\n\r\n/**\r\n * Gets a property value from an object signal\r\n * @param objectSignal - Object signal\r\n * @param key - Property key\r\n * @returns Computed signal with property value\r\n */\r\nexport function pluckSignal<T extends object, K extends keyof T>(\r\n objectSignal: Signal<T>,\r\n key: K\r\n): Signal<T[K]> {\r\n return computed(() => objectSignal()[key]);\r\n}\r\n\r\n/**\r\n * Gets the keys of an object signal\r\n * @param objectSignal - Object signal\r\n * @returns Computed signal with object keys\r\n */\r\nexport function objectSignalKeys<T extends object>(\r\n objectSignal: Signal<T>\r\n): Signal<(keyof T)[]> {\r\n return computed(() => Object.keys(objectSignal()) as (keyof T)[]);\r\n}\r\n\r\n/**\r\n * Gets the values of an object signal\r\n * @param objectSignal - Object signal\r\n * @returns Computed signal with object values\r\n */\r\nexport function objectSignalValues<T extends object>(\r\n objectSignal: Signal<T>\r\n): Signal<T[keyof T][]> {\r\n return computed(() => Object.values(objectSignal()) as T[keyof T][]);\r\n}\r\n\r\n/**\r\n * Gets the entries of an object signal\r\n * @param objectSignal - Object signal\r\n * @returns Computed signal with object entries\r\n */\r\nexport function objectSignalEntries<T extends object>(\r\n objectSignal: Signal<T>\r\n): Signal<[keyof T, T[keyof T]][]> {\r\n return computed(() => Object.entries(objectSignal()) as [keyof T, T[keyof T]][]);\r\n}\r\n","import { Signal, effect, EffectRef, CreateEffectOptions } from '@angular/core';\r\n\r\n/**\r\n * Creates an effect that runs only when the signal value changes\r\n * @param source - Source signal to watch\r\n * @param fn - Effect function\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function watchSignal<T>(\r\n source: Signal<T>,\r\n fn: (value: T, previousValue: T | undefined) => void,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let previousValue: T | undefined = undefined;\r\n let isFirst = true;\r\n \r\n return effect(() => {\r\n const value = source();\r\n if (!isFirst) {\r\n fn(value, previousValue);\r\n }\r\n previousValue = value;\r\n isFirst = false;\r\n }, options);\r\n}\r\n\r\n/**\r\n * Creates an effect that runs once when the signal meets a condition\r\n * @param source - Source signal to watch\r\n * @param predicate - Condition to check\r\n * @param fn - Effect function\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function watchUntil<T>(\r\n source: Signal<T>,\r\n predicate: (value: T) => boolean,\r\n fn: (value: T) => void,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let hasRun = false;\r\n \r\n const effectRef = effect(() => {\r\n if (hasRun) return;\r\n \r\n const value = source();\r\n if (predicate(value)) {\r\n fn(value);\r\n hasRun = true;\r\n effectRef.destroy();\r\n }\r\n }, options);\r\n \r\n return effectRef;\r\n}\r\n\r\n/**\r\n * Creates a throttled effect\r\n * @param source - Source signal to watch\r\n * @param fn - Effect function\r\n * @param ms - Throttle delay in milliseconds\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function throttleEffect<T>(\r\n source: Signal<T>,\r\n fn: (value: T) => void,\r\n ms: number,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let lastRun = 0;\r\n \r\n return effect(() => {\r\n const value = source();\r\n const now = Date.now();\r\n \r\n if (now - lastRun >= ms) {\r\n fn(value);\r\n lastRun = now;\r\n }\r\n }, options);\r\n}\r\n\r\n/**\r\n * Creates a debounced effect\r\n * @param source - Source signal to watch\r\n * @param fn - Effect function\r\n * @param ms - Debounce delay in milliseconds\r\n * @param options - Effect options\r\n * @returns EffectRef\r\n */\r\nexport function debounceEffect<T>(\r\n source: Signal<T>,\r\n fn: (value: T) => void,\r\n ms: number,\r\n options?: CreateEffectOptions\r\n): EffectRef {\r\n let timeoutId: any;\r\n \r\n return effect(() => {\r\n const value = source();\r\n clearTimeout(timeoutId);\r\n timeoutId = setTimeout(() => fn(value), ms);\r\n }, options);\r\n}\r\n","/*\r\n * Public API Surface of ng-signals-utils\r\n */\r\n\r\nexport * from './lib/signal-transformations';\r\nexport * from './lib/signal-array-utils';\r\nexport * from './lib/signal-object-utils';\r\nexport * from './lib/signal-effect-utils';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sergeydus/ng-signals-utils",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Utility functions for Angular signals",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"angular",
|
|
7
|
+
"signals",
|
|
8
|
+
"utilities",
|
|
9
|
+
"reactive"
|
|
10
|
+
],
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"@angular/common": "^17.0.0 || ^18.0.0",
|
|
13
|
+
"@angular/core": "^17.0.0 || ^18.0.0"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"tslib": "^2.3.0"
|
|
17
|
+
},
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"module": "fesm2022/sergeydus-ng-signals-utils.mjs",
|
|
20
|
+
"typings": "types/sergeydus-ng-signals-utils.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
"./package.json": {
|
|
23
|
+
"default": "./package.json"
|
|
24
|
+
},
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./types/sergeydus-ng-signals-utils.d.ts",
|
|
27
|
+
"default": "./fesm2022/sergeydus-ng-signals-utils.mjs"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Signal, WritableSignal, CreateEffectOptions, EffectRef } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Maps a signal value to another type
|
|
5
|
+
* @param source - Source signal
|
|
6
|
+
* @param fn - Mapping function
|
|
7
|
+
* @returns Computed signal with mapped value
|
|
8
|
+
*/
|
|
9
|
+
declare function mapSignal<T, R>(source: Signal<T>, fn: (value: T) => R): Signal<R>;
|
|
10
|
+
/**
|
|
11
|
+
* Filters signal updates based on a predicate
|
|
12
|
+
* @param source - Source signal
|
|
13
|
+
* @param predicate - Filter predicate
|
|
14
|
+
* @param initialValue - Initial value to use if predicate fails
|
|
15
|
+
* @returns Signal that only updates when predicate returns true
|
|
16
|
+
*/
|
|
17
|
+
declare function filterSignal<T>(source: Signal<T>, predicate: (value: T) => boolean, initialValue: T): Signal<T>;
|
|
18
|
+
/**
|
|
19
|
+
* Debounces signal updates
|
|
20
|
+
* @param source - Source signal
|
|
21
|
+
* @param ms - Debounce delay in milliseconds
|
|
22
|
+
* @returns Debounced signal
|
|
23
|
+
*/
|
|
24
|
+
declare function debounceSignal<T>(source: Signal<T>, ms: number): Signal<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Combines multiple signals into a single signal
|
|
27
|
+
* @param signals - Array of signals to combine
|
|
28
|
+
* @returns Combined signal with array of values
|
|
29
|
+
*/
|
|
30
|
+
declare function combineSignals<T extends readonly Signal<any>[]>(signals: T): Signal<{
|
|
31
|
+
[K in keyof T]: T[K] extends Signal<infer U> ? U : never;
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a signal that emits distinct values only
|
|
35
|
+
* @param source - Source signal
|
|
36
|
+
* @param compareFn - Optional comparison function
|
|
37
|
+
* @returns Signal that only updates on distinct values
|
|
38
|
+
*/
|
|
39
|
+
declare function distinctSignal<T>(source: Signal<T>, compareFn?: (a: T, b: T) => boolean): Signal<T>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Pushes an item to an array signal
|
|
43
|
+
* @param arraySignal - Writable array signal
|
|
44
|
+
* @param item - Item to push
|
|
45
|
+
*/
|
|
46
|
+
declare function arraySignalPush<T>(arraySignal: WritableSignal<T[]>, item: T): void;
|
|
47
|
+
/**
|
|
48
|
+
* Removes an item from an array signal at the specified index
|
|
49
|
+
* @param arraySignal - Writable array signal
|
|
50
|
+
* @param index - Index to remove
|
|
51
|
+
*/
|
|
52
|
+
declare function arraySignalRemoveAt<T>(arraySignal: WritableSignal<T[]>, index: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Filters an array signal
|
|
55
|
+
* @param arraySignal - Array signal
|
|
56
|
+
* @param predicate - Filter predicate
|
|
57
|
+
* @returns Computed signal with filtered array
|
|
58
|
+
*/
|
|
59
|
+
declare function arraySignalFilter<T>(arraySignal: Signal<T[]>, predicate: (item: T, index: number) => boolean): Signal<T[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Maps an array signal
|
|
62
|
+
* @param arraySignal - Array signal
|
|
63
|
+
* @param fn - Mapping function
|
|
64
|
+
* @returns Computed signal with mapped array
|
|
65
|
+
*/
|
|
66
|
+
declare function arraySignalMap<T, R>(arraySignal: Signal<T[]>, fn: (item: T, index: number) => R): Signal<R[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Sorts an array signal
|
|
69
|
+
* @param arraySignal - Array signal
|
|
70
|
+
* @param compareFn - Optional comparison function
|
|
71
|
+
* @returns Computed signal with sorted array
|
|
72
|
+
*/
|
|
73
|
+
declare function arraySignalSort<T>(arraySignal: Signal<T[]>, compareFn?: (a: T, b: T) => number): Signal<T[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Finds an item in an array signal
|
|
76
|
+
* @param arraySignal - Array signal
|
|
77
|
+
* @param predicate - Find predicate
|
|
78
|
+
* @returns Computed signal with found item or undefined
|
|
79
|
+
*/
|
|
80
|
+
declare function arraySignalFind<T>(arraySignal: Signal<T[]>, predicate: (item: T, index: number) => boolean): Signal<T | undefined>;
|
|
81
|
+
/**
|
|
82
|
+
* Gets the length of an array signal
|
|
83
|
+
* @param arraySignal - Array signal
|
|
84
|
+
* @returns Computed signal with array length
|
|
85
|
+
*/
|
|
86
|
+
declare function arraySignalLength<T>(arraySignal: Signal<T[]>): Signal<number>;
|
|
87
|
+
/**
|
|
88
|
+
* Checks if an array signal is empty
|
|
89
|
+
* @param arraySignal - Array signal
|
|
90
|
+
* @returns Computed signal indicating if array is empty
|
|
91
|
+
*/
|
|
92
|
+
declare function arraySignalIsEmpty<T>(arraySignal: Signal<T[]>): Signal<boolean>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Patches an object signal with partial values
|
|
96
|
+
* @param objectSignal - Writable object signal
|
|
97
|
+
* @param partial - Partial object to merge
|
|
98
|
+
*/
|
|
99
|
+
declare function patchSignal<T extends object>(objectSignal: WritableSignal<T>, partial: Partial<T>): void;
|
|
100
|
+
/**
|
|
101
|
+
* Picks specific keys from an object signal
|
|
102
|
+
* @param objectSignal - Object signal
|
|
103
|
+
* @param keys - Keys to pick
|
|
104
|
+
* @returns Computed signal with picked keys
|
|
105
|
+
*/
|
|
106
|
+
declare function pickSignal<T extends object, K extends keyof T>(objectSignal: Signal<T>, ...keys: K[]): Signal<Pick<T, K>>;
|
|
107
|
+
/**
|
|
108
|
+
* Omits specific keys from an object signal
|
|
109
|
+
* @param objectSignal - Object signal
|
|
110
|
+
* @param keys - Keys to omit
|
|
111
|
+
* @returns Computed signal with omitted keys
|
|
112
|
+
*/
|
|
113
|
+
declare function omitSignal<T extends object, K extends keyof T>(objectSignal: Signal<T>, ...keys: K[]): Signal<Omit<T, K>>;
|
|
114
|
+
/**
|
|
115
|
+
* Gets a property value from an object signal
|
|
116
|
+
* @param objectSignal - Object signal
|
|
117
|
+
* @param key - Property key
|
|
118
|
+
* @returns Computed signal with property value
|
|
119
|
+
*/
|
|
120
|
+
declare function pluckSignal<T extends object, K extends keyof T>(objectSignal: Signal<T>, key: K): Signal<T[K]>;
|
|
121
|
+
/**
|
|
122
|
+
* Gets the keys of an object signal
|
|
123
|
+
* @param objectSignal - Object signal
|
|
124
|
+
* @returns Computed signal with object keys
|
|
125
|
+
*/
|
|
126
|
+
declare function objectSignalKeys<T extends object>(objectSignal: Signal<T>): Signal<(keyof T)[]>;
|
|
127
|
+
/**
|
|
128
|
+
* Gets the values of an object signal
|
|
129
|
+
* @param objectSignal - Object signal
|
|
130
|
+
* @returns Computed signal with object values
|
|
131
|
+
*/
|
|
132
|
+
declare function objectSignalValues<T extends object>(objectSignal: Signal<T>): Signal<T[keyof T][]>;
|
|
133
|
+
/**
|
|
134
|
+
* Gets the entries of an object signal
|
|
135
|
+
* @param objectSignal - Object signal
|
|
136
|
+
* @returns Computed signal with object entries
|
|
137
|
+
*/
|
|
138
|
+
declare function objectSignalEntries<T extends object>(objectSignal: Signal<T>): Signal<[keyof T, T[keyof T]][]>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Creates an effect that runs only when the signal value changes
|
|
142
|
+
* @param source - Source signal to watch
|
|
143
|
+
* @param fn - Effect function
|
|
144
|
+
* @param options - Effect options
|
|
145
|
+
* @returns EffectRef
|
|
146
|
+
*/
|
|
147
|
+
declare function watchSignal<T>(source: Signal<T>, fn: (value: T, previousValue: T | undefined) => void, options?: CreateEffectOptions): EffectRef;
|
|
148
|
+
/**
|
|
149
|
+
* Creates an effect that runs once when the signal meets a condition
|
|
150
|
+
* @param source - Source signal to watch
|
|
151
|
+
* @param predicate - Condition to check
|
|
152
|
+
* @param fn - Effect function
|
|
153
|
+
* @param options - Effect options
|
|
154
|
+
* @returns EffectRef
|
|
155
|
+
*/
|
|
156
|
+
declare function watchUntil<T>(source: Signal<T>, predicate: (value: T) => boolean, fn: (value: T) => void, options?: CreateEffectOptions): EffectRef;
|
|
157
|
+
/**
|
|
158
|
+
* Creates a throttled effect
|
|
159
|
+
* @param source - Source signal to watch
|
|
160
|
+
* @param fn - Effect function
|
|
161
|
+
* @param ms - Throttle delay in milliseconds
|
|
162
|
+
* @param options - Effect options
|
|
163
|
+
* @returns EffectRef
|
|
164
|
+
*/
|
|
165
|
+
declare function throttleEffect<T>(source: Signal<T>, fn: (value: T) => void, ms: number, options?: CreateEffectOptions): EffectRef;
|
|
166
|
+
/**
|
|
167
|
+
* Creates a debounced effect
|
|
168
|
+
* @param source - Source signal to watch
|
|
169
|
+
* @param fn - Effect function
|
|
170
|
+
* @param ms - Debounce delay in milliseconds
|
|
171
|
+
* @param options - Effect options
|
|
172
|
+
* @returns EffectRef
|
|
173
|
+
*/
|
|
174
|
+
declare function debounceEffect<T>(source: Signal<T>, fn: (value: T) => void, ms: number, options?: CreateEffectOptions): EffectRef;
|
|
175
|
+
|
|
176
|
+
export { arraySignalFilter, arraySignalFind, arraySignalIsEmpty, arraySignalLength, arraySignalMap, arraySignalPush, arraySignalRemoveAt, arraySignalSort, combineSignals, debounceEffect, debounceSignal, distinctSignal, filterSignal, mapSignal, objectSignalEntries, objectSignalKeys, objectSignalValues, omitSignal, patchSignal, pickSignal, pluckSignal, throttleEffect, watchSignal, watchUntil };
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Signal, WritableSignal, CreateEffectOptions, EffectRef } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Maps a signal value to another type
|
|
5
|
+
* @param source - Source signal
|
|
6
|
+
* @param fn - Mapping function
|
|
7
|
+
* @returns Computed signal with mapped value
|
|
8
|
+
*/
|
|
9
|
+
declare function mapSignal<T, R>(source: Signal<T>, fn: (value: T) => R): Signal<R>;
|
|
10
|
+
/**
|
|
11
|
+
* Filters signal updates based on a predicate
|
|
12
|
+
* @param source - Source signal
|
|
13
|
+
* @param predicate - Filter predicate
|
|
14
|
+
* @param initialValue - Initial value to use if predicate fails
|
|
15
|
+
* @returns Signal that only updates when predicate returns true
|
|
16
|
+
*/
|
|
17
|
+
declare function filterSignal<T>(source: Signal<T>, predicate: (value: T) => boolean, initialValue: T): Signal<T>;
|
|
18
|
+
/**
|
|
19
|
+
* Debounces signal updates
|
|
20
|
+
* @param source - Source signal
|
|
21
|
+
* @param ms - Debounce delay in milliseconds
|
|
22
|
+
* @returns Debounced signal
|
|
23
|
+
*/
|
|
24
|
+
declare function debounceSignal<T>(source: Signal<T>, ms: number): Signal<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Combines multiple signals into a single signal
|
|
27
|
+
* @param signals - Array of signals to combine
|
|
28
|
+
* @returns Combined signal with array of values
|
|
29
|
+
*/
|
|
30
|
+
declare function combineSignals<T extends readonly Signal<any>[]>(signals: T): Signal<{
|
|
31
|
+
[K in keyof T]: T[K] extends Signal<infer U> ? U : never;
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a signal that emits distinct values only
|
|
35
|
+
* @param source - Source signal
|
|
36
|
+
* @param compareFn - Optional comparison function
|
|
37
|
+
* @returns Signal that only updates on distinct values
|
|
38
|
+
*/
|
|
39
|
+
declare function distinctSignal<T>(source: Signal<T>, compareFn?: (a: T, b: T) => boolean): Signal<T>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Pushes an item to an array signal
|
|
43
|
+
* @param arraySignal - Writable array signal
|
|
44
|
+
* @param item - Item to push
|
|
45
|
+
*/
|
|
46
|
+
declare function arraySignalPush<T>(arraySignal: WritableSignal<T[]>, item: T): void;
|
|
47
|
+
/**
|
|
48
|
+
* Removes an item from an array signal at the specified index
|
|
49
|
+
* @param arraySignal - Writable array signal
|
|
50
|
+
* @param index - Index to remove
|
|
51
|
+
*/
|
|
52
|
+
declare function arraySignalRemoveAt<T>(arraySignal: WritableSignal<T[]>, index: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Filters an array signal
|
|
55
|
+
* @param arraySignal - Array signal
|
|
56
|
+
* @param predicate - Filter predicate
|
|
57
|
+
* @returns Computed signal with filtered array
|
|
58
|
+
*/
|
|
59
|
+
declare function arraySignalFilter<T>(arraySignal: Signal<T[]>, predicate: (item: T, index: number) => boolean): Signal<T[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Maps an array signal
|
|
62
|
+
* @param arraySignal - Array signal
|
|
63
|
+
* @param fn - Mapping function
|
|
64
|
+
* @returns Computed signal with mapped array
|
|
65
|
+
*/
|
|
66
|
+
declare function arraySignalMap<T, R>(arraySignal: Signal<T[]>, fn: (item: T, index: number) => R): Signal<R[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Sorts an array signal
|
|
69
|
+
* @param arraySignal - Array signal
|
|
70
|
+
* @param compareFn - Optional comparison function
|
|
71
|
+
* @returns Computed signal with sorted array
|
|
72
|
+
*/
|
|
73
|
+
declare function arraySignalSort<T>(arraySignal: Signal<T[]>, compareFn?: (a: T, b: T) => number): Signal<T[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Finds an item in an array signal
|
|
76
|
+
* @param arraySignal - Array signal
|
|
77
|
+
* @param predicate - Find predicate
|
|
78
|
+
* @returns Computed signal with found item or undefined
|
|
79
|
+
*/
|
|
80
|
+
declare function arraySignalFind<T>(arraySignal: Signal<T[]>, predicate: (item: T, index: number) => boolean): Signal<T | undefined>;
|
|
81
|
+
/**
|
|
82
|
+
* Gets the length of an array signal
|
|
83
|
+
* @param arraySignal - Array signal
|
|
84
|
+
* @returns Computed signal with array length
|
|
85
|
+
*/
|
|
86
|
+
declare function arraySignalLength<T>(arraySignal: Signal<T[]>): Signal<number>;
|
|
87
|
+
/**
|
|
88
|
+
* Checks if an array signal is empty
|
|
89
|
+
* @param arraySignal - Array signal
|
|
90
|
+
* @returns Computed signal indicating if array is empty
|
|
91
|
+
*/
|
|
92
|
+
declare function arraySignalIsEmpty<T>(arraySignal: Signal<T[]>): Signal<boolean>;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Patches an object signal with partial values
|
|
96
|
+
* @param objectSignal - Writable object signal
|
|
97
|
+
* @param partial - Partial object to merge
|
|
98
|
+
*/
|
|
99
|
+
declare function patchSignal<T extends object>(objectSignal: WritableSignal<T>, partial: Partial<T>): void;
|
|
100
|
+
/**
|
|
101
|
+
* Picks specific keys from an object signal
|
|
102
|
+
* @param objectSignal - Object signal
|
|
103
|
+
* @param keys - Keys to pick
|
|
104
|
+
* @returns Computed signal with picked keys
|
|
105
|
+
*/
|
|
106
|
+
declare function pickSignal<T extends object, K extends keyof T>(objectSignal: Signal<T>, ...keys: K[]): Signal<Pick<T, K>>;
|
|
107
|
+
/**
|
|
108
|
+
* Omits specific keys from an object signal
|
|
109
|
+
* @param objectSignal - Object signal
|
|
110
|
+
* @param keys - Keys to omit
|
|
111
|
+
* @returns Computed signal with omitted keys
|
|
112
|
+
*/
|
|
113
|
+
declare function omitSignal<T extends object, K extends keyof T>(objectSignal: Signal<T>, ...keys: K[]): Signal<Omit<T, K>>;
|
|
114
|
+
/**
|
|
115
|
+
* Gets a property value from an object signal
|
|
116
|
+
* @param objectSignal - Object signal
|
|
117
|
+
* @param key - Property key
|
|
118
|
+
* @returns Computed signal with property value
|
|
119
|
+
*/
|
|
120
|
+
declare function pluckSignal<T extends object, K extends keyof T>(objectSignal: Signal<T>, key: K): Signal<T[K]>;
|
|
121
|
+
/**
|
|
122
|
+
* Gets the keys of an object signal
|
|
123
|
+
* @param objectSignal - Object signal
|
|
124
|
+
* @returns Computed signal with object keys
|
|
125
|
+
*/
|
|
126
|
+
declare function objectSignalKeys<T extends object>(objectSignal: Signal<T>): Signal<(keyof T)[]>;
|
|
127
|
+
/**
|
|
128
|
+
* Gets the values of an object signal
|
|
129
|
+
* @param objectSignal - Object signal
|
|
130
|
+
* @returns Computed signal with object values
|
|
131
|
+
*/
|
|
132
|
+
declare function objectSignalValues<T extends object>(objectSignal: Signal<T>): Signal<T[keyof T][]>;
|
|
133
|
+
/**
|
|
134
|
+
* Gets the entries of an object signal
|
|
135
|
+
* @param objectSignal - Object signal
|
|
136
|
+
* @returns Computed signal with object entries
|
|
137
|
+
*/
|
|
138
|
+
declare function objectSignalEntries<T extends object>(objectSignal: Signal<T>): Signal<[keyof T, T[keyof T]][]>;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Creates an effect that runs only when the signal value changes
|
|
142
|
+
* @param source - Source signal to watch
|
|
143
|
+
* @param fn - Effect function
|
|
144
|
+
* @param options - Effect options
|
|
145
|
+
* @returns EffectRef
|
|
146
|
+
*/
|
|
147
|
+
declare function watchSignal<T>(source: Signal<T>, fn: (value: T, previousValue: T | undefined) => void, options?: CreateEffectOptions): EffectRef;
|
|
148
|
+
/**
|
|
149
|
+
* Creates an effect that runs once when the signal meets a condition
|
|
150
|
+
* @param source - Source signal to watch
|
|
151
|
+
* @param predicate - Condition to check
|
|
152
|
+
* @param fn - Effect function
|
|
153
|
+
* @param options - Effect options
|
|
154
|
+
* @returns EffectRef
|
|
155
|
+
*/
|
|
156
|
+
declare function watchUntil<T>(source: Signal<T>, predicate: (value: T) => boolean, fn: (value: T) => void, options?: CreateEffectOptions): EffectRef;
|
|
157
|
+
/**
|
|
158
|
+
* Creates a throttled effect
|
|
159
|
+
* @param source - Source signal to watch
|
|
160
|
+
* @param fn - Effect function
|
|
161
|
+
* @param ms - Throttle delay in milliseconds
|
|
162
|
+
* @param options - Effect options
|
|
163
|
+
* @returns EffectRef
|
|
164
|
+
*/
|
|
165
|
+
declare function throttleEffect<T>(source: Signal<T>, fn: (value: T) => void, ms: number, options?: CreateEffectOptions): EffectRef;
|
|
166
|
+
/**
|
|
167
|
+
* Creates a debounced effect
|
|
168
|
+
* @param source - Source signal to watch
|
|
169
|
+
* @param fn - Effect function
|
|
170
|
+
* @param ms - Debounce delay in milliseconds
|
|
171
|
+
* @param options - Effect options
|
|
172
|
+
* @returns EffectRef
|
|
173
|
+
*/
|
|
174
|
+
declare function debounceEffect<T>(source: Signal<T>, fn: (value: T) => void, ms: number, options?: CreateEffectOptions): EffectRef;
|
|
175
|
+
|
|
176
|
+
export { arraySignalFilter, arraySignalFind, arraySignalIsEmpty, arraySignalLength, arraySignalMap, arraySignalPush, arraySignalRemoveAt, arraySignalSort, combineSignals, debounceEffect, debounceSignal, distinctSignal, filterSignal, mapSignal, objectSignalEntries, objectSignalKeys, objectSignalValues, omitSignal, patchSignal, pickSignal, pluckSignal, throttleEffect, watchSignal, watchUntil };
|