@ngrx/signals 21.0.0 → 21.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngrx-signals-entities.mjs +282 -0
- package/fesm2022/ngrx-signals-entities.mjs.map +1 -1
- package/fesm2022/ngrx-signals-events.mjs +4 -4
- package/fesm2022/ngrx-signals-events.mjs.map +1 -1
- package/fesm2022/ngrx-signals-rxjs-interop.mjs +40 -1
- package/fesm2022/ngrx-signals-rxjs-interop.mjs.map +1 -1
- package/fesm2022/ngrx-signals-testing.mjs +35 -0
- package/fesm2022/ngrx-signals-testing.mjs.map +1 -1
- package/fesm2022/ngrx-signals.mjs +353 -21
- package/fesm2022/ngrx-signals.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics-core/utility/libs-version.js +1 -1
- package/schematics-core/utility/libs-version.js.map +1 -1
- package/types/ngrx-signals-events.d.ts +4 -4
- package/types/ngrx-signals-rxjs-interop.d.ts +39 -0
- package/types/ngrx-signals-testing.d.ts +35 -0
- package/types/ngrx-signals.d.ts +243 -20
|
@@ -57,10 +57,63 @@ function isIterable(value) {
|
|
|
57
57
|
return typeof value?.[Symbol.iterator] === 'function';
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* @description
|
|
62
|
+
*
|
|
63
|
+
* Creates a computed signal with deeply nested signals for each property when
|
|
64
|
+
* the result is an object literal.
|
|
65
|
+
*
|
|
66
|
+
* @usageNotes
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* import { signal } from '@angular/core';
|
|
70
|
+
* import { deepComputed } from '@ngrx/signals';
|
|
71
|
+
*
|
|
72
|
+
* const limit = signal(10);
|
|
73
|
+
* const offset = signal(0);
|
|
74
|
+
*
|
|
75
|
+
* const pagination = deepComputed(() => ({
|
|
76
|
+
* currentPage: Math.floor(offset() / limit()) + 1,
|
|
77
|
+
* pageSize: limit(),
|
|
78
|
+
* }));
|
|
79
|
+
*
|
|
80
|
+
* console.log(pagination()); // { currentPage: 1, pageSize: 10 }
|
|
81
|
+
* console.log(pagination.currentPage()); // 1
|
|
82
|
+
* console.log(pagination.pageSize()); // 10
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
60
85
|
function deepComputed(computation) {
|
|
61
86
|
return toDeepSignal(computed(computation));
|
|
62
87
|
}
|
|
63
88
|
|
|
89
|
+
/**
|
|
90
|
+
* @description
|
|
91
|
+
*
|
|
92
|
+
* Creates a method for managing side effects with signals.
|
|
93
|
+
* The method accepts a signal, a computation function, or a static value.
|
|
94
|
+
*
|
|
95
|
+
* @usageNotes
|
|
96
|
+
*
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { Component, signal } from '@angular/core';
|
|
99
|
+
* import { signalMethod } from '@ngrx/signals';
|
|
100
|
+
*
|
|
101
|
+
* \@Component(...)
|
|
102
|
+
* export class Counter {
|
|
103
|
+
* readonly count = signal(1);
|
|
104
|
+
* readonly logDoubledNumber = signalMethod<number>(
|
|
105
|
+
* (num) => console.log(num * 2)
|
|
106
|
+
* );
|
|
107
|
+
*
|
|
108
|
+
* constructor() {
|
|
109
|
+
* this.logDoubledNumber(10); // logs: 20
|
|
110
|
+
*
|
|
111
|
+
* this.logDoubledNumber(this.count); // logs: 2
|
|
112
|
+
* setTimeout(() => this.count.set(2), 1_000); // logs: 4 (after 1s)
|
|
113
|
+
* }
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
64
117
|
function signalMethod(processingFn, config) {
|
|
65
118
|
if (typeof ngDevMode !== 'undefined' && ngDevMode && !config?.injector) {
|
|
66
119
|
assertInInjectionContext(signalMethod);
|
|
@@ -74,7 +127,7 @@ function signalMethod(processingFn, config) {
|
|
|
74
127
|
ngDevMode &&
|
|
75
128
|
config?.injector === undefined &&
|
|
76
129
|
callerInjector === undefined) {
|
|
77
|
-
console.warn('@ngrx/signals:
|
|
130
|
+
console.warn('@ngrx/signals: Calling signalMethod outside of an injection', 'context with a signal is deprecated. In a future version,', 'this will throw an error. Either call it within an injection', 'context (e.g. in a constructor or field initializer) or pass', 'an injector explicitly via the config parameter.', '\n\nFor more information, see:', 'https://ngrx.io/guide/signals/signal-method#automatic-cleanup');
|
|
78
131
|
}
|
|
79
132
|
const instanceInjector = config?.injector ?? callerInjector ?? sourceInjector;
|
|
80
133
|
const watcher = effect(() => {
|
|
@@ -125,6 +178,30 @@ function isWritableStateSource(stateSource) {
|
|
|
125
178
|
return isWritableSignal(signals[key]);
|
|
126
179
|
});
|
|
127
180
|
}
|
|
181
|
+
/**
|
|
182
|
+
* @description
|
|
183
|
+
*
|
|
184
|
+
* Updates the state of a SignalStore or SignalState.
|
|
185
|
+
* Accepts a sequence of partial state objects and partial state updaters.
|
|
186
|
+
*
|
|
187
|
+
* @usageNotes
|
|
188
|
+
*
|
|
189
|
+
* ```ts
|
|
190
|
+
* import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';
|
|
191
|
+
*
|
|
192
|
+
* export const CounterStore = signalStore(
|
|
193
|
+
* withState({ count1: 0, count2: 0 }),
|
|
194
|
+
* withMethods((store) => ({
|
|
195
|
+
* incrementFirst(): void {
|
|
196
|
+
* patchState(store, (state) => ({ count1: state.count1 + 1 }));
|
|
197
|
+
* },
|
|
198
|
+
* resetSecond(): void {
|
|
199
|
+
* patchState(store, { count2: 0 });
|
|
200
|
+
* },
|
|
201
|
+
* }))
|
|
202
|
+
* );
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
128
205
|
function patchState(stateSource, ...updaters) {
|
|
129
206
|
const currentState = untracked(() => getState(stateSource));
|
|
130
207
|
const newState = updaters.reduce((nextState, updater) => ({
|
|
@@ -146,6 +223,36 @@ function patchState(stateSource, ...updaters) {
|
|
|
146
223
|
}
|
|
147
224
|
notifyWatchers(stateSource);
|
|
148
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* @description
|
|
228
|
+
*
|
|
229
|
+
* Returns a snapshot of the current state from a SignalStore or SignalState.
|
|
230
|
+
* When used within a reactive context, state changes are automatically tracked.
|
|
231
|
+
*
|
|
232
|
+
* @usageNotes
|
|
233
|
+
*
|
|
234
|
+
* ```ts
|
|
235
|
+
* import { Component, effect, inject } from '@angular/core';
|
|
236
|
+
* import { getState, signalStore, withState } from '@ngrx/signals';
|
|
237
|
+
*
|
|
238
|
+
* export const CounterStore = signalStore(
|
|
239
|
+
* withState({ count1: 0, count2: 0 })
|
|
240
|
+
* );
|
|
241
|
+
*
|
|
242
|
+
* \@Component(...)
|
|
243
|
+
* export class Counter {
|
|
244
|
+
* readonly store = inject(CounterStore);
|
|
245
|
+
*
|
|
246
|
+
* constructor() {
|
|
247
|
+
* effect(() => {
|
|
248
|
+
* const state = getState(this.store);
|
|
249
|
+
* // 👇 Logs on state changes.
|
|
250
|
+
* console.log(state);
|
|
251
|
+
* });
|
|
252
|
+
* }
|
|
253
|
+
* }
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
149
256
|
function getState(stateSource) {
|
|
150
257
|
const signals = stateSource[STATE_SOURCE];
|
|
151
258
|
return Reflect.ownKeys(stateSource[STATE_SOURCE]).reduce((state, key) => {
|
|
@@ -156,6 +263,28 @@ function getState(stateSource) {
|
|
|
156
263
|
};
|
|
157
264
|
}, {});
|
|
158
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* @description
|
|
268
|
+
*
|
|
269
|
+
* Synchronously tracks state changes of a SignalStore or SignalState.
|
|
270
|
+
*
|
|
271
|
+
* @usageNotes
|
|
272
|
+
*
|
|
273
|
+
* ```ts
|
|
274
|
+
* import { Component } from '@angular/core';
|
|
275
|
+
* import { signalState, watchState } from '@ngrx/signals';
|
|
276
|
+
*
|
|
277
|
+
* \@Component(...)
|
|
278
|
+
* export class Counter {
|
|
279
|
+
* readonly state = signalState({ count1: 0, count2: 0 });
|
|
280
|
+
*
|
|
281
|
+
* constructor() {
|
|
282
|
+
* // 👇 Synchronously logs every state change without debouncing.
|
|
283
|
+
* watchState(this.state, console.log);
|
|
284
|
+
* }
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
159
288
|
function watchState(stateSource, watcher, config) {
|
|
160
289
|
if (typeof ngDevMode !== 'undefined' && ngDevMode && !config?.injector) {
|
|
161
290
|
assertInInjectionContext(watchState);
|
|
@@ -187,6 +316,32 @@ function removeWatcher(stateSource, watcher) {
|
|
|
187
316
|
STATE_WATCHERS.set(stateSource[STATE_SOURCE], watchers.filter((w) => w !== watcher));
|
|
188
317
|
}
|
|
189
318
|
|
|
319
|
+
/**
|
|
320
|
+
* @description
|
|
321
|
+
*
|
|
322
|
+
* Creates a state container with deeply nested signals for each property that
|
|
323
|
+
* is an object literal.
|
|
324
|
+
*
|
|
325
|
+
* @usageNotes
|
|
326
|
+
*
|
|
327
|
+
* ```ts
|
|
328
|
+
* import { Component } from '@angular/core';
|
|
329
|
+
* import { signalState, patchState } from '@ngrx/signals';
|
|
330
|
+
*
|
|
331
|
+
* \@Component(...)
|
|
332
|
+
* export class Counter {
|
|
333
|
+
* readonly state = signalState({ count: 0 });
|
|
334
|
+
*
|
|
335
|
+
* logCount(): void {
|
|
336
|
+
* console.log(this.state.count());
|
|
337
|
+
* }
|
|
338
|
+
*
|
|
339
|
+
* increment(): void {
|
|
340
|
+
* patchState(this.state, ({ count }) => ({ count: count + 1 }));
|
|
341
|
+
* }
|
|
342
|
+
* }
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
190
345
|
function signalState(initialState) {
|
|
191
346
|
const stateKeys = Reflect.ownKeys(initialState);
|
|
192
347
|
const stateSource = stateKeys.reduce((signalsDict, key) => ({
|
|
@@ -205,6 +360,44 @@ function signalState(initialState) {
|
|
|
205
360
|
return signalState;
|
|
206
361
|
}
|
|
207
362
|
|
|
363
|
+
/**
|
|
364
|
+
* @description
|
|
365
|
+
*
|
|
366
|
+
* Creates a store by composing features.
|
|
367
|
+
* Returns an injectable service that can be provided locally or globally.
|
|
368
|
+
*
|
|
369
|
+
* @usageNotes
|
|
370
|
+
*
|
|
371
|
+
* ```ts
|
|
372
|
+
* import { Component, inject } from '@angular/core';
|
|
373
|
+
* import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';
|
|
374
|
+
*
|
|
375
|
+
* export const CounterStore = signalStore(
|
|
376
|
+
* withState({ count: 0 }),
|
|
377
|
+
* withMethods((store) => ({
|
|
378
|
+
* increment(): void {
|
|
379
|
+
* patchState(store, ({ count }) => ({ count: count + 1 }));
|
|
380
|
+
* },
|
|
381
|
+
* }))
|
|
382
|
+
* );
|
|
383
|
+
*
|
|
384
|
+
* \@Component({
|
|
385
|
+
* // ...
|
|
386
|
+
* providers: [CounterStore],
|
|
387
|
+
* })
|
|
388
|
+
* export class Counter {
|
|
389
|
+
* readonly store = inject(CounterStore);
|
|
390
|
+
*
|
|
391
|
+
* logCount(): void {
|
|
392
|
+
* console.log(this.store.count());
|
|
393
|
+
* }
|
|
394
|
+
*
|
|
395
|
+
* increment(): void {
|
|
396
|
+
* this.store.increment();
|
|
397
|
+
* }
|
|
398
|
+
* }
|
|
399
|
+
* ```
|
|
400
|
+
*/
|
|
208
401
|
function signalStore(...args) {
|
|
209
402
|
const signalStoreArgs = [...args];
|
|
210
403
|
const config = typeof signalStoreArgs[0] === 'function'
|
|
@@ -251,6 +444,36 @@ function getInitialInnerStore() {
|
|
|
251
444
|
};
|
|
252
445
|
}
|
|
253
446
|
|
|
447
|
+
/**
|
|
448
|
+
* @description
|
|
449
|
+
*
|
|
450
|
+
* Combines multiple store features into a single feature.
|
|
451
|
+
*
|
|
452
|
+
* @usageNotes
|
|
453
|
+
*
|
|
454
|
+
* ```ts
|
|
455
|
+
* import {
|
|
456
|
+
* patchState,
|
|
457
|
+
* signalStore,
|
|
458
|
+
* signalStoreFeature,
|
|
459
|
+
* withMethods,
|
|
460
|
+
* withState,
|
|
461
|
+
* } from '@ngrx/signals';
|
|
462
|
+
*
|
|
463
|
+
* export function withCounter() {
|
|
464
|
+
* return signalStoreFeature(
|
|
465
|
+
* withState({ count: 0 }),
|
|
466
|
+
* withMethods((store) => ({
|
|
467
|
+
* increment(): void {
|
|
468
|
+
* patchState(store, ({ count }) => ({ count: count + 1 }));
|
|
469
|
+
* },
|
|
470
|
+
* }))
|
|
471
|
+
* );
|
|
472
|
+
* }
|
|
473
|
+
*
|
|
474
|
+
* export const CounterStore = signalStore(withCounter());
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
254
477
|
function signalStoreFeature(...args) {
|
|
255
478
|
const features = (typeof args[0] === 'function' ? args : args.slice(1));
|
|
256
479
|
return (inputStore) => features.reduce((store, feature) => feature(store), inputStore);
|
|
@@ -271,6 +494,25 @@ function assertUniqueStoreMembers(store, newMemberKeys) {
|
|
|
271
494
|
}
|
|
272
495
|
}
|
|
273
496
|
|
|
497
|
+
/**
|
|
498
|
+
* @description
|
|
499
|
+
*
|
|
500
|
+
* Adds custom properties to a SignalStore.
|
|
501
|
+
*
|
|
502
|
+
* @usageNotes
|
|
503
|
+
*
|
|
504
|
+
* ```ts
|
|
505
|
+
* import { toObservable } from '@angular/core/rxjs-interop';
|
|
506
|
+
* import { signalStore, withProps, withState } from '@ngrx/signals';
|
|
507
|
+
*
|
|
508
|
+
* export const TodosStore = signalStore(
|
|
509
|
+
* withState({ todos: [] as Todo[], isLoading: false }),
|
|
510
|
+
* withProps(({ isLoading }) => ({
|
|
511
|
+
* isLoading$: toObservable(isLoading),
|
|
512
|
+
* }))
|
|
513
|
+
* );
|
|
514
|
+
* ```
|
|
515
|
+
*/
|
|
274
516
|
function withProps(propsFactory) {
|
|
275
517
|
return (store) => {
|
|
276
518
|
const props = propsFactory({
|
|
@@ -289,6 +531,26 @@ function withProps(propsFactory) {
|
|
|
289
531
|
};
|
|
290
532
|
}
|
|
291
533
|
|
|
534
|
+
/**
|
|
535
|
+
* @description
|
|
536
|
+
*
|
|
537
|
+
* Adds computed signals to a SignalStore.
|
|
538
|
+
* Accepts a factory function that returns a dictionary of computed signals or
|
|
539
|
+
* computation functions.
|
|
540
|
+
*
|
|
541
|
+
* @usageNotes
|
|
542
|
+
*
|
|
543
|
+
* ```ts
|
|
544
|
+
* import { signalStore, withState, withComputed } from '@ngrx/signals';
|
|
545
|
+
*
|
|
546
|
+
* export const CounterStore = signalStore(
|
|
547
|
+
* withState({ count: 0 }),
|
|
548
|
+
* withComputed(({ count }) => ({
|
|
549
|
+
* doubleCount: () => count() * 2,
|
|
550
|
+
* }))
|
|
551
|
+
* );
|
|
552
|
+
* ```
|
|
553
|
+
*/
|
|
292
554
|
function withComputed(computedFactory) {
|
|
293
555
|
return withProps((store) => {
|
|
294
556
|
const computedResult = computedFactory(store);
|
|
@@ -307,25 +569,27 @@ function withComputed(computedFactory) {
|
|
|
307
569
|
|
|
308
570
|
/**
|
|
309
571
|
* @description
|
|
310
|
-
*
|
|
311
|
-
*
|
|
572
|
+
*
|
|
573
|
+
* Allows passing state signals, properties, and methods from a SignalStore
|
|
574
|
+
* instance to a custom feature.
|
|
312
575
|
*
|
|
313
576
|
* @usageNotes
|
|
314
|
-
*
|
|
315
|
-
*
|
|
577
|
+
*
|
|
578
|
+
* ```ts
|
|
579
|
+
* import { signalStore, withFeature, withMethods } from '@ngrx/signals';
|
|
580
|
+
*
|
|
581
|
+
* export const UserStore = signalStore(
|
|
316
582
|
* withMethods((store) => ({
|
|
317
|
-
*
|
|
318
|
-
* return
|
|
583
|
+
* loadById(id: number): Promise<User> {
|
|
584
|
+
* return Promise.resolve({ id, name: 'John' });
|
|
319
585
|
* },
|
|
320
586
|
* })),
|
|
321
587
|
* withFeature(
|
|
322
|
-
* // 👇
|
|
323
|
-
* (store) => withEntityLoader((id) =>
|
|
588
|
+
* // 👇 Has full access to store members.
|
|
589
|
+
* (store) => withEntityLoader((id) => store.loadById(id))
|
|
324
590
|
* )
|
|
325
591
|
* );
|
|
326
592
|
* ```
|
|
327
|
-
*
|
|
328
|
-
* @param featureFactory function returning the actual feature
|
|
329
593
|
*/
|
|
330
594
|
function withFeature(featureFactory) {
|
|
331
595
|
return (store) => {
|
|
@@ -339,6 +603,31 @@ function withFeature(featureFactory) {
|
|
|
339
603
|
};
|
|
340
604
|
}
|
|
341
605
|
|
|
606
|
+
/**
|
|
607
|
+
* @description
|
|
608
|
+
*
|
|
609
|
+
* Adds lifecycle hooks to a SignalStore.
|
|
610
|
+
* Supports an onInit hook that executes when the store is initialized.
|
|
611
|
+
* Supports an onDestroy hook for when the store is destroyed.
|
|
612
|
+
*
|
|
613
|
+
* @usageNotes
|
|
614
|
+
*
|
|
615
|
+
* ```ts
|
|
616
|
+
* import { signalStore, withHooks, withState } from '@ngrx/signals';
|
|
617
|
+
*
|
|
618
|
+
* export const UserStore = signalStore(
|
|
619
|
+
* withState({ firstName: 'Jimi', lastName: 'Hendrix' }),
|
|
620
|
+
* withHooks({
|
|
621
|
+
* onInit({ firstName }) {
|
|
622
|
+
* console.log('first name on init', firstName());
|
|
623
|
+
* },
|
|
624
|
+
* onDestroy({ lastName }) {
|
|
625
|
+
* console.log('last name on destroy', lastName());
|
|
626
|
+
* },
|
|
627
|
+
* })
|
|
628
|
+
* );
|
|
629
|
+
* ```
|
|
630
|
+
*/
|
|
342
631
|
function withHooks(hooksOrFactory) {
|
|
343
632
|
return (store) => {
|
|
344
633
|
const storeMembers = {
|
|
@@ -374,11 +663,17 @@ function withHooks(hooksOrFactory) {
|
|
|
374
663
|
* @description
|
|
375
664
|
*
|
|
376
665
|
* Adds linked state slices to a SignalStore.
|
|
666
|
+
* Accepts a factory function that returns a dictionary of linked signals or
|
|
667
|
+
* computation functions.
|
|
377
668
|
*
|
|
378
669
|
* @usageNotes
|
|
379
670
|
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
671
|
+
* ### Using a computation function
|
|
672
|
+
*
|
|
673
|
+
* ```ts
|
|
674
|
+
* import { signalStore, withLinkedState, withState } from '@ngrx/signals';
|
|
675
|
+
*
|
|
676
|
+
* export const OptionsStore = signalStore(
|
|
382
677
|
* withState({ options: [1, 2, 3] }),
|
|
383
678
|
* withLinkedState(({ options }) => ({
|
|
384
679
|
* selectedOption: () => options()[0],
|
|
@@ -386,15 +681,15 @@ function withHooks(hooksOrFactory) {
|
|
|
386
681
|
* );
|
|
387
682
|
* ```
|
|
388
683
|
*
|
|
389
|
-
*
|
|
390
|
-
* When the `options` signal changes, the `selectedOption` automatically updates.
|
|
684
|
+
* ### Using linkedSignal for advanced use cases
|
|
391
685
|
*
|
|
392
|
-
*
|
|
686
|
+
* ```ts
|
|
687
|
+
* import { linkedSignal } from '@angular/core';
|
|
688
|
+
* import { signalStore, withLinkedState, withState } from '@ngrx/signals';
|
|
393
689
|
*
|
|
394
|
-
* ```typescript
|
|
395
690
|
* type Option = { id: number; label: string };
|
|
396
691
|
*
|
|
397
|
-
* const OptionsStore = signalStore(
|
|
692
|
+
* export const OptionsStore = signalStore(
|
|
398
693
|
* withState({ options: [] as Option[] }),
|
|
399
694
|
* withLinkedState(({ options }) => ({
|
|
400
695
|
* selectedOption: linkedSignal<Option[], Option>({
|
|
@@ -403,12 +698,10 @@ function withHooks(hooksOrFactory) {
|
|
|
403
698
|
* const option = newOptions.find((o) => o.id === previous?.value.id);
|
|
404
699
|
* return option ?? newOptions[0];
|
|
405
700
|
* },
|
|
406
|
-
* })
|
|
701
|
+
* }),
|
|
407
702
|
* }))
|
|
408
703
|
* )
|
|
409
704
|
* ```
|
|
410
|
-
*
|
|
411
|
-
* @param linkedStateFactory A function that returns an object literal with properties containing an actual `linkedSignal` or the computation function.
|
|
412
705
|
*/
|
|
413
706
|
function withLinkedState(linkedStateFactory) {
|
|
414
707
|
return (store) => {
|
|
@@ -436,6 +729,29 @@ function withLinkedState(linkedStateFactory) {
|
|
|
436
729
|
};
|
|
437
730
|
}
|
|
438
731
|
|
|
732
|
+
/**
|
|
733
|
+
* @description
|
|
734
|
+
*
|
|
735
|
+
* Adds methods to a SignalStore.
|
|
736
|
+
*
|
|
737
|
+
* @usageNotes
|
|
738
|
+
*
|
|
739
|
+
* ```ts
|
|
740
|
+
* import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';
|
|
741
|
+
*
|
|
742
|
+
* export const CounterStore = signalStore(
|
|
743
|
+
* withState({ count: 0 }),
|
|
744
|
+
* withMethods((store) => ({
|
|
745
|
+
* increment(): void {
|
|
746
|
+
* patchState(store, ({ count }) => ({ count: count + 1 }));
|
|
747
|
+
* },
|
|
748
|
+
* decrement(): void {
|
|
749
|
+
* patchState(store, ({ count }) => ({ count: count - 1 }));
|
|
750
|
+
* },
|
|
751
|
+
* }))
|
|
752
|
+
* );
|
|
753
|
+
* ```
|
|
754
|
+
*/
|
|
439
755
|
function withMethods(methodsFactory) {
|
|
440
756
|
return (store) => {
|
|
441
757
|
const methods = methodsFactory({
|
|
@@ -454,6 +770,22 @@ function withMethods(methodsFactory) {
|
|
|
454
770
|
};
|
|
455
771
|
}
|
|
456
772
|
|
|
773
|
+
/**
|
|
774
|
+
* @description
|
|
775
|
+
*
|
|
776
|
+
* Adds state slices to a SignalStore.
|
|
777
|
+
* Accepts an object or a factory function that returns the initial state.
|
|
778
|
+
*
|
|
779
|
+
* @usageNotes
|
|
780
|
+
*
|
|
781
|
+
* ```ts
|
|
782
|
+
* import { signalStore, withState } from '@ngrx/signals';
|
|
783
|
+
*
|
|
784
|
+
* export const CounterStore = signalStore(
|
|
785
|
+
* withState({ count: 0 })
|
|
786
|
+
* );
|
|
787
|
+
* ```
|
|
788
|
+
*/
|
|
457
789
|
function withState(stateOrFactory) {
|
|
458
790
|
return (store) => {
|
|
459
791
|
const state = (typeof stateOrFactory === 'function' ? stateOrFactory() : stateOrFactory);
|