@angular-architects/ngrx-toolkit 20.0.2 → 20.0.3
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/angular-architects-ngrx-toolkit-redux-connector.mjs +119 -0
- package/fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs.map +1 -0
- package/fesm2022/angular-architects-ngrx-toolkit.mjs +1789 -0
- package/fesm2022/angular-architects-ngrx-toolkit.mjs.map +1 -0
- package/index.d.ts +945 -0
- package/package.json +21 -4
- package/redux-connector/index.d.ts +59 -0
- package/eslint.config.cjs +0 -43
- package/jest.config.ts +0 -22
- package/ng-package.json +0 -7
- package/project.json +0 -37
- package/redux-connector/docs/README.md +0 -131
- package/redux-connector/index.ts +0 -6
- package/redux-connector/ng-package.json +0 -5
- package/redux-connector/src/lib/create-redux.ts +0 -102
- package/redux-connector/src/lib/model.ts +0 -89
- package/redux-connector/src/lib/rxjs-interop/redux-method.ts +0 -66
- package/redux-connector/src/lib/signal-redux-store.ts +0 -59
- package/redux-connector/src/lib/util.ts +0 -22
- package/src/index.ts +0 -43
- package/src/lib/assertions/assertions.ts +0 -9
- package/src/lib/devtools/features/with-disabled-name-indicies.ts +0 -31
- package/src/lib/devtools/features/with-glitch-tracking.ts +0 -35
- package/src/lib/devtools/features/with-mapper.ts +0 -34
- package/src/lib/devtools/internal/current-action-names.ts +0 -1
- package/src/lib/devtools/internal/default-tracker.ts +0 -60
- package/src/lib/devtools/internal/devtools-feature.ts +0 -37
- package/src/lib/devtools/internal/devtools-syncer.service.ts +0 -202
- package/src/lib/devtools/internal/glitch-tracker.service.ts +0 -61
- package/src/lib/devtools/internal/models.ts +0 -29
- package/src/lib/devtools/provide-devtools-config.ts +0 -32
- package/src/lib/devtools/rename-devtools-name.ts +0 -21
- package/src/lib/devtools/tests/action-name.spec.ts +0 -48
- package/src/lib/devtools/tests/basic.spec.ts +0 -111
- package/src/lib/devtools/tests/connecting.spec.ts +0 -37
- package/src/lib/devtools/tests/helpers.spec.ts +0 -43
- package/src/lib/devtools/tests/naming.spec.ts +0 -216
- package/src/lib/devtools/tests/provide-devtools-config.spec.ts +0 -25
- package/src/lib/devtools/tests/types.spec.ts +0 -19
- package/src/lib/devtools/tests/update-state.spec.ts +0 -29
- package/src/lib/devtools/tests/with-devtools.spec.ts +0 -5
- package/src/lib/devtools/tests/with-glitch-tracking.spec.ts +0 -272
- package/src/lib/devtools/tests/with-mapper.spec.ts +0 -69
- package/src/lib/devtools/update-state.ts +0 -38
- package/src/lib/devtools/with-dev-tools-stub.ts +0 -6
- package/src/lib/devtools/with-devtools.ts +0 -81
- package/src/lib/immutable-state/deep-freeze.ts +0 -43
- package/src/lib/immutable-state/is-dev-mode.ts +0 -6
- package/src/lib/immutable-state/tests/with-immutable-state.spec.ts +0 -278
- package/src/lib/immutable-state/with-immutable-state.ts +0 -150
- package/src/lib/shared/prettify.ts +0 -3
- package/src/lib/shared/signal-store-models.ts +0 -30
- package/src/lib/shared/throw-if-null.ts +0 -7
- package/src/lib/storage-sync/features/with-indexed-db.ts +0 -81
- package/src/lib/storage-sync/features/with-local-storage.ts +0 -58
- package/src/lib/storage-sync/internal/indexeddb.service.ts +0 -124
- package/src/lib/storage-sync/internal/local-storage.service.ts +0 -19
- package/src/lib/storage-sync/internal/models.ts +0 -62
- package/src/lib/storage-sync/internal/session-storage.service.ts +0 -18
- package/src/lib/storage-sync/tests/indexeddb.service.spec.ts +0 -99
- package/src/lib/storage-sync/tests/with-storage-async.spec.ts +0 -305
- package/src/lib/storage-sync/tests/with-storage-sync.spec.ts +0 -273
- package/src/lib/storage-sync/with-storage-sync.ts +0 -236
- package/src/lib/with-call-state.spec.ts +0 -42
- package/src/lib/with-call-state.ts +0 -195
- package/src/lib/with-conditional.spec.ts +0 -125
- package/src/lib/with-conditional.ts +0 -74
- package/src/lib/with-data-service.spec.ts +0 -564
- package/src/lib/with-data-service.ts +0 -433
- package/src/lib/with-feature-factory.spec.ts +0 -69
- package/src/lib/with-feature-factory.ts +0 -56
- package/src/lib/with-pagination.spec.ts +0 -135
- package/src/lib/with-pagination.ts +0 -373
- package/src/lib/with-redux.spec.ts +0 -258
- package/src/lib/with-redux.ts +0 -387
- package/src/lib/with-reset.spec.ts +0 -112
- package/src/lib/with-reset.ts +0 -62
- package/src/lib/with-undo-redo.spec.ts +0 -274
- package/src/lib/with-undo-redo.ts +0 -200
- package/src/test-setup.ts +0 -6
- package/tsconfig.json +0 -29
- package/tsconfig.lib.json +0 -17
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -17
package/index.d.ts
ADDED
|
@@ -0,0 +1,945 @@
|
|
|
1
|
+
import * as _ngrx_signals from '@ngrx/signals';
|
|
2
|
+
import { StateSource, patchState as patchState$1, WritableStateSource, PartialStateUpdater, SignalStoreFeature, EmptyFeatureResult, SignalStoreFeatureResult, StateSignals } from '@ngrx/signals';
|
|
3
|
+
import { ValueProvider, Signal, ProviderToken, WritableSignal } from '@angular/core';
|
|
4
|
+
import { Observable } from 'rxjs';
|
|
5
|
+
import { EntityId, NamedEntityState } from '@ngrx/signals/entities';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Provides the configuration options for connecting to the Redux DevTools Extension.
|
|
9
|
+
*/
|
|
10
|
+
declare function provideDevtoolsConfig(config: ReduxDevtoolsConfig): ValueProvider;
|
|
11
|
+
/**
|
|
12
|
+
* Options for connecting to the Redux DevTools Extension.
|
|
13
|
+
* @example
|
|
14
|
+
* const devToolsOptions: ReduxDevtoolsConfig = {
|
|
15
|
+
* name: 'My App',
|
|
16
|
+
* };
|
|
17
|
+
*/
|
|
18
|
+
type ReduxDevtoolsConfig = {
|
|
19
|
+
/** Optional name for the devtools instance. If empty, "NgRx SignalStore" will be used. */
|
|
20
|
+
name?: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type Action = {
|
|
24
|
+
type: string;
|
|
25
|
+
};
|
|
26
|
+
type Connection = {
|
|
27
|
+
send: (action: Action, state: Record<string, unknown>) => void;
|
|
28
|
+
};
|
|
29
|
+
type ReduxDevtoolsExtension = {
|
|
30
|
+
connect: (options: ReduxDevtoolsConfig) => Connection;
|
|
31
|
+
};
|
|
32
|
+
type Tracker = {
|
|
33
|
+
track(id: string, store: StateSource<object>): void;
|
|
34
|
+
onChange(callback: (changedState: Record<string, object>) => void): void;
|
|
35
|
+
notifyRenamedStore(id: string): void;
|
|
36
|
+
removeStore(id: string): void;
|
|
37
|
+
get stores(): TrackerStores;
|
|
38
|
+
};
|
|
39
|
+
type TrackerStores = Record<string, StateSource<object>>;
|
|
40
|
+
|
|
41
|
+
declare const DEVTOOLS_FEATURE: unique symbol;
|
|
42
|
+
type Mapper = (state: object) => object;
|
|
43
|
+
type DevtoolsOptions = {
|
|
44
|
+
indexNames?: boolean;
|
|
45
|
+
map?: Mapper;
|
|
46
|
+
tracker?: new () => Tracker;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* A DevtoolsFeature adds or modifies the behavior of the
|
|
50
|
+
* devtools extension.
|
|
51
|
+
*
|
|
52
|
+
* We use them (function calls) instead of a config object,
|
|
53
|
+
* because of tree-shaking.
|
|
54
|
+
*/
|
|
55
|
+
type DevtoolsFeature = {
|
|
56
|
+
[DEVTOOLS_FEATURE]: true;
|
|
57
|
+
} & Partial<DevtoolsOptions>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* If multiple instances of the same SignalStore class
|
|
61
|
+
* exist, their devtool names are indexed.
|
|
62
|
+
*
|
|
63
|
+
* For example:
|
|
64
|
+
*
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const Store = signalStore(
|
|
67
|
+
* withDevtools('flights')
|
|
68
|
+
* )
|
|
69
|
+
*
|
|
70
|
+
* const store1 = new Store(); // will show up as 'flights'
|
|
71
|
+
* const store2 = new Store(); // will show up as 'flights-1'
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* With adding `withDisabledNameIndices` to the store:
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const Store = signalStore(
|
|
77
|
+
* withDevtools('flights', withDisabledNameIndices())
|
|
78
|
+
* )
|
|
79
|
+
*
|
|
80
|
+
* const store1 = new Store(); // will show up as 'flights'
|
|
81
|
+
* const store2 = new Store(); //💥 throws an error
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
*/
|
|
85
|
+
declare function withDisabledNameIndices(): DevtoolsFeature;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* It tracks all state changes of the State, including intermediary updates
|
|
89
|
+
* that are typically suppressed by Angular's glitch-free mechanism.
|
|
90
|
+
*
|
|
91
|
+
* This feature is especially useful for debugging.
|
|
92
|
+
*
|
|
93
|
+
* Example:
|
|
94
|
+
*
|
|
95
|
+
* ```typescript
|
|
96
|
+
* const Store = signalStore(
|
|
97
|
+
* { providedIn: 'root' },
|
|
98
|
+
* withState({ count: 0 }),
|
|
99
|
+
* withDevtools('counter', withGlitchTracking()),
|
|
100
|
+
* withMethods((store) => ({
|
|
101
|
+
* increase: () =>
|
|
102
|
+
* patchState(store, (value) => ({ count: value.count + 1 })),
|
|
103
|
+
* }))
|
|
104
|
+
* );
|
|
105
|
+
*
|
|
106
|
+
* // would show up in the DevTools with value 0
|
|
107
|
+
* const store = inject(Store);
|
|
108
|
+
*
|
|
109
|
+
* store.increase(); // would show up in the DevTools with value 1
|
|
110
|
+
* store.increase(); // would show up in the DevTools with value 2
|
|
111
|
+
* store.increase(); // would show up in the DevTools with value 3
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* Without `withGlitchTracking`, the DevTools would only show the final value of 3.
|
|
115
|
+
*/
|
|
116
|
+
declare function withGlitchTracking(): DevtoolsFeature;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Allows you to define a function to map the state.
|
|
120
|
+
*
|
|
121
|
+
* It is needed for huge states, that slows down the Devtools and where
|
|
122
|
+
* you don't need to see the whole state or other reasons.
|
|
123
|
+
*
|
|
124
|
+
* Example:
|
|
125
|
+
*
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const initialState = {
|
|
128
|
+
* id: 1,
|
|
129
|
+
* email: 'john.list@host.com',
|
|
130
|
+
* name: 'John List',
|
|
131
|
+
* enteredPassword: ''
|
|
132
|
+
* }
|
|
133
|
+
*
|
|
134
|
+
* const Store = signalStore(
|
|
135
|
+
* withState(initialState),
|
|
136
|
+
* withDevtools(
|
|
137
|
+
* 'user',
|
|
138
|
+
* withMapper(state => ({...state, enteredPassword: '***' }))
|
|
139
|
+
* )
|
|
140
|
+
* )
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @param map function which maps the state
|
|
144
|
+
*/
|
|
145
|
+
declare function withMapper<State extends object>(map: (state: State) => Record<string, unknown>): DevtoolsFeature;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Renames the name of a store how it appears in the Devtools.
|
|
149
|
+
* @param store instance of the SignalStore
|
|
150
|
+
* @param newName new name for the Devtools
|
|
151
|
+
*/
|
|
152
|
+
declare function renameDevtoolsName<State extends object>(store: StateSource<State>, newName: string): void;
|
|
153
|
+
|
|
154
|
+
type PatchFn = typeof patchState$1 extends (arg1: infer First, ...args: infer Rest) => infer Returner ? (state: First, action: string, ...rest: Rest) => Returner : never;
|
|
155
|
+
/**
|
|
156
|
+
* @deprecated Has been renamed to `updateState`
|
|
157
|
+
*/
|
|
158
|
+
declare const patchState: PatchFn;
|
|
159
|
+
/**
|
|
160
|
+
* Wrapper of `patchState` for DevTools integration. Next to updating the state,
|
|
161
|
+
* it also sends the action to the DevTools.
|
|
162
|
+
* @param stateSource state of Signal Store
|
|
163
|
+
* @param action name of action how it will show in DevTools
|
|
164
|
+
* @param updaters updater functions or objects
|
|
165
|
+
*/
|
|
166
|
+
declare function updateState<State extends object>(stateSource: WritableStateSource<State>, action: string, ...updaters: Array<Partial<NoInfer<State>> | PartialStateUpdater<NoInfer<State>>>): void;
|
|
167
|
+
|
|
168
|
+
declare global {
|
|
169
|
+
interface Window {
|
|
170
|
+
__REDUX_DEVTOOLS_EXTENSION__: ReduxDevtoolsExtension | undefined;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Adds this store as a feature state to the Redux DevTools.
|
|
175
|
+
*
|
|
176
|
+
* By default, the action name is 'Store Update'. You can
|
|
177
|
+
* change that via the {@link updateState} method, which has as second
|
|
178
|
+
* parameter the action name.
|
|
179
|
+
*
|
|
180
|
+
* The standalone function {@link renameDevtoolsName} can rename
|
|
181
|
+
* the store name.
|
|
182
|
+
*
|
|
183
|
+
* @param name name of the store as it should appear in the DevTools
|
|
184
|
+
* @param features features to extend or modify the behavior of the Devtools
|
|
185
|
+
*/
|
|
186
|
+
declare function withDevtools(name: string, ...features: DevtoolsFeature[]): SignalStoreFeature<EmptyFeatureResult, EmptyFeatureResult>;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Stub for DevTools integration. Can be used to disable DevTools in production.
|
|
190
|
+
*/
|
|
191
|
+
declare const withDevToolsStub: typeof withDevtools;
|
|
192
|
+
|
|
193
|
+
/** Actions **/
|
|
194
|
+
type Payload = Record<string, unknown>;
|
|
195
|
+
type ActionFn<Type extends string = string, ActionPayload extends Payload = Payload> = ((payload: ActionPayload) => ActionPayload & {
|
|
196
|
+
type: Type;
|
|
197
|
+
}) & {
|
|
198
|
+
type: Type;
|
|
199
|
+
};
|
|
200
|
+
type ActionFns = Record<string, ActionFn>;
|
|
201
|
+
type ActionsFnSpecs = Record<string, Payload>;
|
|
202
|
+
type ActionFnCreator<Spec extends ActionsFnSpecs> = {
|
|
203
|
+
[ActionName in keyof Spec]: (Record<never, never> extends Spec[ActionName] ? () => Spec[ActionName] & {
|
|
204
|
+
type: ActionName;
|
|
205
|
+
} : (payload: Spec[ActionName]) => Spec[ActionName] & {
|
|
206
|
+
type: ActionName;
|
|
207
|
+
}) & {
|
|
208
|
+
type: ActionName & string;
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
type ActionFnPayload<Action> = Action extends (payload: infer Payload) => void ? Payload : never;
|
|
212
|
+
type ActionFnsCreator<Spec extends ActionsFnSpecs> = Spec extends {
|
|
213
|
+
private: Record<string, Payload>;
|
|
214
|
+
public: Record<string, Payload>;
|
|
215
|
+
} ? ActionFnCreator<Spec['private']> & ActionFnCreator<Spec['public']> : ActionFnCreator<Spec>;
|
|
216
|
+
type PublicActionFns<Spec extends ActionsFnSpecs> = Spec extends {
|
|
217
|
+
public: Record<string, Payload>;
|
|
218
|
+
} ? ActionFnCreator<Spec['public']> : ActionFnCreator<Spec>;
|
|
219
|
+
declare function payload<Type extends Payload>(): Type;
|
|
220
|
+
declare const noPayload: {};
|
|
221
|
+
/** Reducer **/
|
|
222
|
+
type ReducerFunction<ReducerAction, State> = (state: State, action: ActionFnPayload<ReducerAction>) => void;
|
|
223
|
+
type ReducerFactory<StateActionFns extends ActionFns, State> = (actions: StateActionFns, on: <ReducerAction extends {
|
|
224
|
+
type: string;
|
|
225
|
+
}>(action: ReducerAction, reducerFn: ReducerFunction<ReducerAction, State>) => void) => void;
|
|
226
|
+
/**
|
|
227
|
+
* Creates a reducer function to separate the reducer logic into another file.
|
|
228
|
+
*
|
|
229
|
+
* ```typescript
|
|
230
|
+
* interface FlightState {
|
|
231
|
+
* flights: Flight[];
|
|
232
|
+
* effect1: boolean;
|
|
233
|
+
* effect2: boolean;
|
|
234
|
+
* }
|
|
235
|
+
*
|
|
236
|
+
* const initialState: FlightState = {
|
|
237
|
+
* flights: [],
|
|
238
|
+
* effect1: false,
|
|
239
|
+
* effect2: false,
|
|
240
|
+
* };
|
|
241
|
+
*
|
|
242
|
+
* const actions = {
|
|
243
|
+
* init: noPayload,
|
|
244
|
+
* updateEffect1: payload<{ value: boolean }>(),
|
|
245
|
+
* updateEffect2: payload<{ value: boolean }>(),
|
|
246
|
+
* };
|
|
247
|
+
*
|
|
248
|
+
* const reducer = createReducer<FlightState, typeof actions>((actions, on) => {
|
|
249
|
+
* on(actions.updateEffect1, (state, { value }) => {
|
|
250
|
+
* patchState(state, { effect1: value });
|
|
251
|
+
* });
|
|
252
|
+
*
|
|
253
|
+
* on(actions.updateEffect2, (state, { value }) => {
|
|
254
|
+
* patchState(state, { effect2: value });
|
|
255
|
+
* });
|
|
256
|
+
* });
|
|
257
|
+
*
|
|
258
|
+
* signalStore(
|
|
259
|
+
* withState(initialState),
|
|
260
|
+
* withRedux({
|
|
261
|
+
* actions,
|
|
262
|
+
* reducer,
|
|
263
|
+
* })
|
|
264
|
+
* );
|
|
265
|
+
* ```
|
|
266
|
+
* @param reducerFactory
|
|
267
|
+
*/
|
|
268
|
+
declare function createReducer<State extends object, Actions extends ActionsFnSpecs>(reducerFactory: ReducerFactory<ActionFnsCreator<Actions>, WritableStateSource<State>>): ReducerFactory<ActionFnsCreator<Actions>, WritableStateSource<State>>;
|
|
269
|
+
/** Effect **/
|
|
270
|
+
type EffectsFactory<StateActionFns extends ActionFns> = (actions: StateActionFns, create: <EffectAction extends {
|
|
271
|
+
type: string;
|
|
272
|
+
}>(action: EffectAction) => Observable<ActionFnPayload<EffectAction>>) => Record<string, Observable<unknown>>;
|
|
273
|
+
/**
|
|
274
|
+
* @deprecated Use NgRx's `@ngrx/signals/events` starting in 19.2
|
|
275
|
+
*
|
|
276
|
+
* Creates the effects function to separate the effects logic into another file.
|
|
277
|
+
*
|
|
278
|
+
* ```typescript
|
|
279
|
+
* interface FlightState {
|
|
280
|
+
* flights: Flight[];
|
|
281
|
+
* effect1: boolean;
|
|
282
|
+
* effect2: boolean;
|
|
283
|
+
* }
|
|
284
|
+
*
|
|
285
|
+
* const initialState: FlightState = {
|
|
286
|
+
* flights: [],
|
|
287
|
+
* effect1: false,
|
|
288
|
+
* effect2: false,
|
|
289
|
+
* };
|
|
290
|
+
*
|
|
291
|
+
* const actions = {
|
|
292
|
+
* init: noPayload,
|
|
293
|
+
* updateEffect1: payload<{ value: boolean }>(),
|
|
294
|
+
* updateEffect2: payload<{ value: boolean }>(),
|
|
295
|
+
* };
|
|
296
|
+
*
|
|
297
|
+
* const effects = createEffects(actions, (actions, create) => {
|
|
298
|
+
* return {
|
|
299
|
+
* init1$: create(actions.init).pipe(
|
|
300
|
+
* map(() => actions.updateEffect1({ value: true }))
|
|
301
|
+
* ),
|
|
302
|
+
* init2$: create(actions.init).pipe(
|
|
303
|
+
* map(() => actions.updateEffect2({ value: true }))
|
|
304
|
+
* ),
|
|
305
|
+
* };
|
|
306
|
+
* });
|
|
307
|
+
*
|
|
308
|
+
* signalStore(
|
|
309
|
+
* withState(initialState),
|
|
310
|
+
* withRedux({
|
|
311
|
+
* actions,
|
|
312
|
+
* effects,
|
|
313
|
+
* })
|
|
314
|
+
* );
|
|
315
|
+
* ```
|
|
316
|
+
* @param actions
|
|
317
|
+
* @param effectsFactory
|
|
318
|
+
*/
|
|
319
|
+
declare function createEffects<Actions extends ActionsFnSpecs>(actions: Actions, effectsFactory: EffectsFactory<ActionFnsCreator<Actions>>): EffectsFactory<ActionFnsCreator<Actions>>;
|
|
320
|
+
/**
|
|
321
|
+
* @param redux redux
|
|
322
|
+
*
|
|
323
|
+
* properties do not start with `with` since they are not extension functions on their own.
|
|
324
|
+
*
|
|
325
|
+
* no dependency to NgRx
|
|
326
|
+
*
|
|
327
|
+
* actions are passed to reducer and effects, but it is also possible to use other actions.
|
|
328
|
+
* effects provide forAction and do not return anything. that is important because effects should stay inaccessible
|
|
329
|
+
*/
|
|
330
|
+
declare function withRedux<Spec extends ActionsFnSpecs, Input extends SignalStoreFeatureResult, StateActionFns extends ActionFnsCreator<Spec> = ActionFnsCreator<Spec>, PublicStoreActionFns extends PublicActionFns<Spec> = PublicActionFns<Spec>>(redux: {
|
|
331
|
+
actions: Spec;
|
|
332
|
+
reducer: ReducerFactory<StateActionFns, WritableStateSource<Input['state']>>;
|
|
333
|
+
effects: EffectsFactory<StateActionFns>;
|
|
334
|
+
}): SignalStoreFeature<Input, EmptyFeatureResult & {
|
|
335
|
+
methods: PublicStoreActionFns;
|
|
336
|
+
}>;
|
|
337
|
+
|
|
338
|
+
type CallState = 'init' | 'loading' | 'loaded' | {
|
|
339
|
+
error: string;
|
|
340
|
+
};
|
|
341
|
+
type CallStateSlice = {
|
|
342
|
+
callState: CallState;
|
|
343
|
+
};
|
|
344
|
+
type NamedCallStateSlice<Collection extends string> = {
|
|
345
|
+
[K in keyof CallStateSlice as Collection extends '' ? `${Collection}${K}` : `${Collection}${Capitalize<K>}`]: CallStateSlice[K];
|
|
346
|
+
};
|
|
347
|
+
type CallStateSignals = {
|
|
348
|
+
loading: Signal<boolean>;
|
|
349
|
+
loaded: Signal<boolean>;
|
|
350
|
+
error: Signal<string | null>;
|
|
351
|
+
};
|
|
352
|
+
type NamedCallStateSignals<Prop extends string> = {
|
|
353
|
+
[K in keyof CallStateSignals as Prop extends '' ? `${Prop}${K}` : `${Prop}${Capitalize<K>}`]: CallStateSignals[K];
|
|
354
|
+
};
|
|
355
|
+
type SetCallState<Prop extends string | undefined> = Prop extends string ? NamedCallStateSlice<Prop> : CallStateSlice;
|
|
356
|
+
declare function deriveCallStateKeys<Collection extends string>(collection?: Collection): {
|
|
357
|
+
callStateKey: string;
|
|
358
|
+
loadingKey: string;
|
|
359
|
+
loadedKey: string;
|
|
360
|
+
errorKey: string;
|
|
361
|
+
};
|
|
362
|
+
declare function getCallStateKeys(config?: {
|
|
363
|
+
collection?: string;
|
|
364
|
+
}): {
|
|
365
|
+
callStateKey: string;
|
|
366
|
+
loadingKey: string;
|
|
367
|
+
loadedKey: string;
|
|
368
|
+
errorKey: string;
|
|
369
|
+
};
|
|
370
|
+
declare function getCollectionArray(config: {
|
|
371
|
+
collection?: string;
|
|
372
|
+
} | {
|
|
373
|
+
collections?: string[];
|
|
374
|
+
}): string[] | undefined;
|
|
375
|
+
declare function withCallState<Collection extends string>(config: {
|
|
376
|
+
collections: Collection[];
|
|
377
|
+
}): SignalStoreFeature<EmptyFeatureResult, EmptyFeatureResult & {
|
|
378
|
+
state: NamedCallStateSlice<Collection>;
|
|
379
|
+
props: NamedCallStateSignals<Collection>;
|
|
380
|
+
}>;
|
|
381
|
+
declare function withCallState<Collection extends string>(config: {
|
|
382
|
+
collection: Collection;
|
|
383
|
+
}): SignalStoreFeature<EmptyFeatureResult, EmptyFeatureResult & {
|
|
384
|
+
state: NamedCallStateSlice<Collection>;
|
|
385
|
+
props: NamedCallStateSignals<Collection>;
|
|
386
|
+
}>;
|
|
387
|
+
declare function withCallState(): SignalStoreFeature<EmptyFeatureResult, EmptyFeatureResult & {
|
|
388
|
+
state: CallStateSlice;
|
|
389
|
+
props: CallStateSignals;
|
|
390
|
+
}>;
|
|
391
|
+
declare function setLoading<Prop extends string | undefined = undefined>(prop?: Prop): SetCallState<Prop>;
|
|
392
|
+
declare function setLoaded<Prop extends string | undefined = undefined>(prop?: Prop): SetCallState<Prop>;
|
|
393
|
+
declare function setError<Prop extends string | undefined = undefined>(error: unknown, prop?: Prop): SetCallState<Prop>;
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* This file contains copies of types of the Signal Store which are not public.
|
|
397
|
+
*
|
|
398
|
+
* Since certain features depend on them, if we don't want to break
|
|
399
|
+
* the encapsulation of @ngrx/signals, we decided to copy them.
|
|
400
|
+
*
|
|
401
|
+
* Since TypeScript is based on structural typing, we can get away with it.
|
|
402
|
+
*
|
|
403
|
+
* If @ngrx/signals changes its internal types, we catch them via integration
|
|
404
|
+
* tests.
|
|
405
|
+
*
|
|
406
|
+
* Because of the "tight coupling", the toolkit doesn't have version range
|
|
407
|
+
* to @ngrx/signal, but is very precise.
|
|
408
|
+
*/
|
|
409
|
+
|
|
410
|
+
type EntityState<Entity> = {
|
|
411
|
+
entityMap: Record<EntityId, Entity>;
|
|
412
|
+
ids: EntityId[];
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
type Filter = Record<string, unknown>;
|
|
416
|
+
type Entity = {
|
|
417
|
+
id: EntityId;
|
|
418
|
+
};
|
|
419
|
+
interface DataService<E extends Entity, F extends Filter> {
|
|
420
|
+
load(filter: F): Promise<E[]>;
|
|
421
|
+
loadById(id: EntityId): Promise<E>;
|
|
422
|
+
create(entity: E): Promise<E>;
|
|
423
|
+
update(entity: E): Promise<E>;
|
|
424
|
+
updateAll(entity: E[]): Promise<E[]>;
|
|
425
|
+
delete(entity: E): Promise<void>;
|
|
426
|
+
}
|
|
427
|
+
declare function capitalize(str: string): string;
|
|
428
|
+
declare function getDataServiceKeys(options: {
|
|
429
|
+
collection?: string;
|
|
430
|
+
}): {
|
|
431
|
+
filterKey: string;
|
|
432
|
+
selectedIdsKey: string;
|
|
433
|
+
selectedEntitiesKey: string;
|
|
434
|
+
updateFilterKey: string;
|
|
435
|
+
updateSelectedKey: string;
|
|
436
|
+
loadKey: string;
|
|
437
|
+
entitiesKey: string;
|
|
438
|
+
entityMapKey: string;
|
|
439
|
+
idsKey: string;
|
|
440
|
+
currentKey: string;
|
|
441
|
+
loadByIdKey: string;
|
|
442
|
+
setCurrentKey: string;
|
|
443
|
+
createKey: string;
|
|
444
|
+
updateKey: string;
|
|
445
|
+
updateAllKey: string;
|
|
446
|
+
deleteKey: string;
|
|
447
|
+
};
|
|
448
|
+
type NamedDataServiceState<E extends Entity, F extends Filter, Collection extends string> = {
|
|
449
|
+
[K in Collection as `${K}Filter`]: F;
|
|
450
|
+
} & {
|
|
451
|
+
[K in Collection as `selected${Capitalize<K>}Ids`]: Record<EntityId, boolean>;
|
|
452
|
+
} & {
|
|
453
|
+
[K in Collection as `current${Capitalize<K>}`]: E;
|
|
454
|
+
};
|
|
455
|
+
type DataServiceState<E extends Entity, F extends Filter> = {
|
|
456
|
+
filter: F;
|
|
457
|
+
selectedIds: Record<EntityId, boolean>;
|
|
458
|
+
current: E;
|
|
459
|
+
};
|
|
460
|
+
type DataServiceComputed<E extends Entity> = {
|
|
461
|
+
selectedEntities: Signal<E[]>;
|
|
462
|
+
};
|
|
463
|
+
type NamedDataServiceComputed<E extends Entity, Collection extends string> = {
|
|
464
|
+
[K in Collection as `selected${Capitalize<K>}Entities`]: Signal<E[]>;
|
|
465
|
+
};
|
|
466
|
+
type NamedDataServiceMethods<E extends Entity, F extends Filter, Collection extends string> = {
|
|
467
|
+
[K in Collection as `update${Capitalize<K>}Filter`]: (filter: F) => void;
|
|
468
|
+
} & {
|
|
469
|
+
[K in Collection as `updateSelected${Capitalize<K>}Entities`]: (id: EntityId, selected: boolean) => void;
|
|
470
|
+
} & {
|
|
471
|
+
[K in Collection as `load${Capitalize<K>}Entities`]: () => Promise<void>;
|
|
472
|
+
} & {
|
|
473
|
+
[K in Collection as `setCurrent${Capitalize<K>}`]: (entity: E) => void;
|
|
474
|
+
} & {
|
|
475
|
+
[K in Collection as `load${Capitalize<K>}ById`]: (id: EntityId) => Promise<void>;
|
|
476
|
+
} & {
|
|
477
|
+
[K in Collection as `create${Capitalize<K>}`]: (entity: E) => Promise<void>;
|
|
478
|
+
} & {
|
|
479
|
+
[K in Collection as `update${Capitalize<K>}`]: (entity: E) => Promise<void>;
|
|
480
|
+
} & {
|
|
481
|
+
[K in Collection as `updateAll${Capitalize<K>}`]: (entity: E[]) => Promise<void>;
|
|
482
|
+
} & {
|
|
483
|
+
[K in Collection as `delete${Capitalize<K>}`]: (entity: E) => Promise<void>;
|
|
484
|
+
};
|
|
485
|
+
type DataServiceMethods<E extends Entity, F extends Filter> = {
|
|
486
|
+
updateFilter: (filter: F) => void;
|
|
487
|
+
updateSelected: (id: EntityId, selected: boolean) => void;
|
|
488
|
+
load: () => Promise<void>;
|
|
489
|
+
setCurrent(entity: E): void;
|
|
490
|
+
loadById(id: EntityId): Promise<void>;
|
|
491
|
+
create(entity: E): Promise<void>;
|
|
492
|
+
update(entity: E): Promise<void>;
|
|
493
|
+
updateAll(entities: E[]): Promise<void>;
|
|
494
|
+
delete(entity: E): Promise<void>;
|
|
495
|
+
};
|
|
496
|
+
declare function withDataService<E extends Entity, F extends Filter, Collection extends string>(options: {
|
|
497
|
+
dataServiceType: ProviderToken<DataService<E, F>>;
|
|
498
|
+
filter: F;
|
|
499
|
+
collection: Collection;
|
|
500
|
+
}): SignalStoreFeature<EmptyFeatureResult & {
|
|
501
|
+
state: NamedCallStateSlice<Collection> & NamedEntityState<E, Collection>;
|
|
502
|
+
}, {
|
|
503
|
+
state: NamedDataServiceState<E, F, Collection>;
|
|
504
|
+
props: NamedDataServiceComputed<E, Collection>;
|
|
505
|
+
methods: NamedDataServiceMethods<E, F, Collection>;
|
|
506
|
+
}>;
|
|
507
|
+
declare function withDataService<E extends Entity, F extends Filter>(options: {
|
|
508
|
+
dataServiceType: ProviderToken<DataService<E, F>>;
|
|
509
|
+
filter: F;
|
|
510
|
+
}): SignalStoreFeature<EmptyFeatureResult & {
|
|
511
|
+
state: {
|
|
512
|
+
callState: CallState;
|
|
513
|
+
} & EntityState<E>;
|
|
514
|
+
}, {
|
|
515
|
+
state: DataServiceState<E, F>;
|
|
516
|
+
props: DataServiceComputed<E>;
|
|
517
|
+
methods: DataServiceMethods<E, F>;
|
|
518
|
+
}>;
|
|
519
|
+
|
|
520
|
+
/** With pagination comes in two flavors the first one is local pagination or in memory pagination. For example we have 2000 items which we want
|
|
521
|
+
* to display in a table and the response payload is small enough to be stored in the memory. But we can not display all 2000 items at once
|
|
522
|
+
* so we need to paginate the data. The second flavor is server side pagination where the response payload is too large to be stored in the memory
|
|
523
|
+
* and we need to fetch the data from the server in chunks. In the second case we 'could' also cache the data in the memory but that could lead to
|
|
524
|
+
* other problems like memory leaks and stale data. So we will not cache the data in the memory in the second case.
|
|
525
|
+
* This feature implements the local pagination.
|
|
526
|
+
*/
|
|
527
|
+
|
|
528
|
+
type Page = {
|
|
529
|
+
label: string | number;
|
|
530
|
+
value: number;
|
|
531
|
+
};
|
|
532
|
+
type NamedPaginationServiceState<E, Collection extends string> = {
|
|
533
|
+
[K in Collection as `selectedPage${Capitalize<K>}Entities`]: Array<E>;
|
|
534
|
+
} & {
|
|
535
|
+
[K in Collection as `${Lowercase<K>}CurrentPage`]: number;
|
|
536
|
+
} & {
|
|
537
|
+
[K in Collection as `${Lowercase<K>}PageSize`]: number;
|
|
538
|
+
} & {
|
|
539
|
+
[K in Collection as `${Lowercase<K>}TotalCount`]: number;
|
|
540
|
+
} & {
|
|
541
|
+
[K in Collection as `${Lowercase<K>}PageCount`]: number;
|
|
542
|
+
} & {
|
|
543
|
+
[K in Collection as `${Lowercase<K>}PageNavigationArray`]: number;
|
|
544
|
+
} & {
|
|
545
|
+
[K in Collection as `${Lowercase<K>}PageNavigationArrayMax`]: number;
|
|
546
|
+
};
|
|
547
|
+
type NamedPaginationServiceSignals<E, Collection extends string> = {
|
|
548
|
+
[K in Collection as `selectedPage${Capitalize<K>}Entities`]: Signal<E[]>;
|
|
549
|
+
} & {
|
|
550
|
+
[K in Collection as `${Lowercase<K>}CurrentPage`]: Signal<number>;
|
|
551
|
+
} & {
|
|
552
|
+
[K in Collection as `${Lowercase<K>}PageSize`]: Signal<number>;
|
|
553
|
+
} & {
|
|
554
|
+
[K in Collection as `${Lowercase<K>}TotalCount`]: Signal<number>;
|
|
555
|
+
} & {
|
|
556
|
+
[K in Collection as `${Lowercase<K>}PageCount`]: Signal<number>;
|
|
557
|
+
} & {
|
|
558
|
+
[K in Collection as `${Lowercase<K>}PageNavigationArray`]: Signal<Page[]>;
|
|
559
|
+
} & {
|
|
560
|
+
[K in Collection as `${Lowercase<K>}PageNavigationArrayMax`]: Signal<number>;
|
|
561
|
+
} & {
|
|
562
|
+
[K in Collection as `hasNext${Capitalize<K>}Page`]: Signal<boolean>;
|
|
563
|
+
} & {
|
|
564
|
+
[K in Collection as `hasPrevious${Capitalize<K>}Page`]: Signal<boolean>;
|
|
565
|
+
};
|
|
566
|
+
type PaginationServiceState<E> = {
|
|
567
|
+
selectedPageEntities: Array<E>;
|
|
568
|
+
currentPage: number;
|
|
569
|
+
pageSize: number;
|
|
570
|
+
totalCount: number;
|
|
571
|
+
pageCount: number;
|
|
572
|
+
pageNavigationArray: Page[];
|
|
573
|
+
pageNavigationArrayMax: number;
|
|
574
|
+
};
|
|
575
|
+
type PaginationServiceSignals<E> = {
|
|
576
|
+
selectedPageEntities: Signal<E[]>;
|
|
577
|
+
currentPage: Signal<number>;
|
|
578
|
+
pageSize: Signal<number>;
|
|
579
|
+
totalCount: Signal<number>;
|
|
580
|
+
pageCount: Signal<number>;
|
|
581
|
+
pageNavigationArray: Signal<Page[]>;
|
|
582
|
+
pageNavigationArrayMax: Signal<number>;
|
|
583
|
+
hasNextPage: Signal<boolean>;
|
|
584
|
+
hasPreviousPage: Signal<boolean>;
|
|
585
|
+
};
|
|
586
|
+
type PageState<Collection extends string | undefined> = Collection extends string ? {
|
|
587
|
+
[K in Collection as `${Lowercase<K>}CurrentPage`]: number;
|
|
588
|
+
} : {
|
|
589
|
+
currentPage: number;
|
|
590
|
+
};
|
|
591
|
+
type PageSizeState<Collection extends string | undefined> = Collection extends string ? {
|
|
592
|
+
[K in Collection as `${Lowercase<K>}PageSize`]: number;
|
|
593
|
+
} : {
|
|
594
|
+
pageSize: number;
|
|
595
|
+
};
|
|
596
|
+
type SetPaginationState<E, Collection extends string | undefined> = Collection extends string ? NamedPaginationServiceState<E, Collection> : PaginationServiceState<E>;
|
|
597
|
+
declare function withPagination<E, Collection extends string>(options: {
|
|
598
|
+
entity: E;
|
|
599
|
+
collection: Collection;
|
|
600
|
+
}): SignalStoreFeature<EmptyFeatureResult, EmptyFeatureResult & {
|
|
601
|
+
state: NamedPaginationServiceState<E, Collection>;
|
|
602
|
+
props: NamedPaginationServiceSignals<E, Collection>;
|
|
603
|
+
}>;
|
|
604
|
+
declare function withPagination<E>(): SignalStoreFeature<EmptyFeatureResult, EmptyFeatureResult & {
|
|
605
|
+
state: PaginationServiceState<E>;
|
|
606
|
+
props: PaginationServiceSignals<E>;
|
|
607
|
+
}>;
|
|
608
|
+
declare function gotoPage<Collection extends string>(page: number, options?: {
|
|
609
|
+
collection: Collection;
|
|
610
|
+
}): PageState<Collection>;
|
|
611
|
+
declare function setPageSize<Collection extends string>(pageSize: number, options?: {
|
|
612
|
+
collection: Collection;
|
|
613
|
+
}): PageSizeState<Collection>;
|
|
614
|
+
type SetPageState<Collection extends string | undefined> = (state: PageState<Collection>) => PageState<Collection>;
|
|
615
|
+
declare function nextPage<Collection extends string>(options?: {
|
|
616
|
+
collection: Collection;
|
|
617
|
+
}): SetPageState<Collection>;
|
|
618
|
+
declare function previousPage<Collection extends string>(options?: {
|
|
619
|
+
collection: Collection;
|
|
620
|
+
}): SetPageState<Collection>;
|
|
621
|
+
declare function firstPage<Collection extends string>(options?: {
|
|
622
|
+
collection: Collection;
|
|
623
|
+
}): PageState<Collection>;
|
|
624
|
+
declare function setMaxPageNavigationArrayItems<E, Collection extends string>(maxPageNavigationArrayItems: number, options?: {
|
|
625
|
+
collection: Collection;
|
|
626
|
+
}): Partial<SetPaginationState<E, Collection>>;
|
|
627
|
+
declare function createPageArray(currentPage: number, itemsPerPage: number, totalItems: number, paginationRange: number): Page[];
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Adds a `resetState` method to the store, which resets the state
|
|
631
|
+
* to the initial state.
|
|
632
|
+
*
|
|
633
|
+
* If you want to set a custom initial state, you can use {@link setResetState}.
|
|
634
|
+
*/
|
|
635
|
+
declare function withReset(): _ngrx_signals.SignalStoreFeature<_ngrx_signals.EmptyFeatureResult, {
|
|
636
|
+
state: {};
|
|
637
|
+
props: {
|
|
638
|
+
_resetState: {
|
|
639
|
+
value: {};
|
|
640
|
+
};
|
|
641
|
+
};
|
|
642
|
+
methods: {
|
|
643
|
+
resetState: () => void;
|
|
644
|
+
};
|
|
645
|
+
}>;
|
|
646
|
+
/**
|
|
647
|
+
* Sets the reset state of the store to the given state.
|
|
648
|
+
*
|
|
649
|
+
* Throws an error if the store is not configured with {@link withReset}.
|
|
650
|
+
* @param store the instance of a SignalStore
|
|
651
|
+
* @param state the state to set as the reset state
|
|
652
|
+
*/
|
|
653
|
+
declare function setResetState<State extends object>(store: StateSource<State>, state: State): void;
|
|
654
|
+
|
|
655
|
+
type StackItem = Record<string, unknown>;
|
|
656
|
+
type NormalizedUndoRedoOptions = {
|
|
657
|
+
maxStackSize: number;
|
|
658
|
+
collections?: string[];
|
|
659
|
+
keys: string[];
|
|
660
|
+
skip: number;
|
|
661
|
+
};
|
|
662
|
+
declare function getUndoRedoKeys(collections?: string[]): string[];
|
|
663
|
+
type NonNever<T> = T extends never ? never : T;
|
|
664
|
+
type ExtractEntityCollection<T> = T extends `${infer U}Entities` ? U : never;
|
|
665
|
+
type ExtractEntityCollections<Store extends SignalStoreFeatureResult> = NonNever<{
|
|
666
|
+
[K in keyof Store['props']]: ExtractEntityCollection<K>;
|
|
667
|
+
}[keyof Store['props']]>;
|
|
668
|
+
type OptionsForState<Store extends SignalStoreFeatureResult> = Partial<Omit<NormalizedUndoRedoOptions, 'collections' | 'keys'>> & {
|
|
669
|
+
collections?: ExtractEntityCollections<Store>[];
|
|
670
|
+
keys?: (keyof Store['state'])[];
|
|
671
|
+
};
|
|
672
|
+
declare function withUndoRedo<Input extends EmptyFeatureResult>(options?: OptionsForState<Input>): SignalStoreFeature<Input, EmptyFeatureResult & {
|
|
673
|
+
props: {
|
|
674
|
+
canUndo: Signal<boolean>;
|
|
675
|
+
canRedo: Signal<boolean>;
|
|
676
|
+
};
|
|
677
|
+
methods: {
|
|
678
|
+
undo: () => void;
|
|
679
|
+
redo: () => void;
|
|
680
|
+
clearStack: () => void;
|
|
681
|
+
};
|
|
682
|
+
}>;
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Starting from v20, the root properties of the state object
|
|
686
|
+
* are all of type `WritableSignal`.
|
|
687
|
+
*
|
|
688
|
+
* That means, we cannot freeze root properties, which are of a
|
|
689
|
+
* primitive data type.
|
|
690
|
+
*
|
|
691
|
+
* This is a breaking change, because in v19 the state was a Signal.
|
|
692
|
+
* We had the possibility to freeze that Signal's
|
|
693
|
+
* object and could therefore provide immutability for
|
|
694
|
+
* root properties of primitive data types.
|
|
695
|
+
*
|
|
696
|
+
* For example:
|
|
697
|
+
*
|
|
698
|
+
* ```ts
|
|
699
|
+
* const state = {
|
|
700
|
+
* id: 1, // was frozen in v19, but not in >= v20
|
|
701
|
+
* address: {
|
|
702
|
+
* street: 'Main St',
|
|
703
|
+
* city: 'Springfield',
|
|
704
|
+
* }
|
|
705
|
+
* }
|
|
706
|
+
* ```
|
|
707
|
+
*/
|
|
708
|
+
/**
|
|
709
|
+
* Prevents mutation of the state.
|
|
710
|
+
*
|
|
711
|
+
* This is done by applying `Object.freeze` to each root
|
|
712
|
+
* property of the state. Any mutable change within
|
|
713
|
+
* or outside the `SignalStore` will throw an error.
|
|
714
|
+
*
|
|
715
|
+
* Root properties of the state having a primitive data type
|
|
716
|
+
* are not supported.
|
|
717
|
+
*
|
|
718
|
+
* * For example:
|
|
719
|
+
*
|
|
720
|
+
* ```ts
|
|
721
|
+
* const state = {
|
|
722
|
+
* // ⛔️ are not frozen -> mutable changes possible
|
|
723
|
+
* id: 1,
|
|
724
|
+
*
|
|
725
|
+
* // ✅ are frozen -> mutable changes throw
|
|
726
|
+
* address: {
|
|
727
|
+
* street: 'Main St',
|
|
728
|
+
* city: 'Springfield',
|
|
729
|
+
* }
|
|
730
|
+
* }
|
|
731
|
+
* ```
|
|
732
|
+
*
|
|
733
|
+
* @param state the state object
|
|
734
|
+
* @param options enable protection in production (default: false)
|
|
735
|
+
*/
|
|
736
|
+
declare function withImmutableState<State extends object>(state: State, options?: {
|
|
737
|
+
enableInProduction?: boolean;
|
|
738
|
+
}): SignalStoreFeature<SignalStoreFeatureResult, EmptyFeatureResult & {
|
|
739
|
+
state: State;
|
|
740
|
+
}>;
|
|
741
|
+
/**
|
|
742
|
+
* Prevents mutation of the state.
|
|
743
|
+
*
|
|
744
|
+
* This is done by applying `Object.freeze` to each root
|
|
745
|
+
* property of the state. Any mutable change within
|
|
746
|
+
* or outside the `SignalStore` will throw an error.
|
|
747
|
+
*
|
|
748
|
+
* Root properties of the state having a primitive data type
|
|
749
|
+
* are not supported.
|
|
750
|
+
*
|
|
751
|
+
* * For example:
|
|
752
|
+
*
|
|
753
|
+
* ```ts
|
|
754
|
+
* const state = {
|
|
755
|
+
* // ⛔️ are not frozen -> mutable changes possible
|
|
756
|
+
* id: 1,
|
|
757
|
+
*
|
|
758
|
+
* // ✅ are frozen -> mutable changes throw
|
|
759
|
+
* address: {
|
|
760
|
+
* street: 'Main St',
|
|
761
|
+
* city: 'Springfield',
|
|
762
|
+
* }
|
|
763
|
+
* }
|
|
764
|
+
* ```
|
|
765
|
+
*
|
|
766
|
+
* @param stateFactory a function returning the state object
|
|
767
|
+
* @param options enable protection in production (default: false)
|
|
768
|
+
*/
|
|
769
|
+
declare function withImmutableState<State extends object>(stateFactory: () => State, options?: {
|
|
770
|
+
enableInProduction?: boolean;
|
|
771
|
+
}): SignalStoreFeature<SignalStoreFeatureResult, EmptyFeatureResult & {
|
|
772
|
+
state: State;
|
|
773
|
+
}>;
|
|
774
|
+
|
|
775
|
+
type SyncConfig<State> = {
|
|
776
|
+
/**
|
|
777
|
+
* The key which is used to access the storage.
|
|
778
|
+
*/
|
|
779
|
+
key: string;
|
|
780
|
+
/**
|
|
781
|
+
* Flag indicating if the store should read from storage on init and write to storage on every state change.
|
|
782
|
+
*
|
|
783
|
+
* `true` by default
|
|
784
|
+
*/
|
|
785
|
+
autoSync?: boolean;
|
|
786
|
+
/**
|
|
787
|
+
* Function to select that portion of the state which should be stored.
|
|
788
|
+
*
|
|
789
|
+
* Returns the whole state object by default
|
|
790
|
+
*/
|
|
791
|
+
select?: (state: State) => unknown;
|
|
792
|
+
/**
|
|
793
|
+
* Function used to parse the state coming from storage.
|
|
794
|
+
*
|
|
795
|
+
* `JSON.parse()` by default
|
|
796
|
+
*/
|
|
797
|
+
parse?: (stateString: string) => State;
|
|
798
|
+
/**
|
|
799
|
+
* Function used to transform the state into a string representation.
|
|
800
|
+
*
|
|
801
|
+
* `JSON.stringify()` by default
|
|
802
|
+
*/
|
|
803
|
+
stringify?: (state: State) => string;
|
|
804
|
+
/**
|
|
805
|
+
* @deprecated Use {@link withSessionStorage} instead.
|
|
806
|
+
* Factory function used to switch to sessionStorage.
|
|
807
|
+
*
|
|
808
|
+
* `localStorage` by default
|
|
809
|
+
*/
|
|
810
|
+
storage?: () => Storage;
|
|
811
|
+
};
|
|
812
|
+
declare function withStorageSync<Input extends SignalStoreFeatureResult>(key: string): SignalStoreFeature<Input, SyncFeatureResult>;
|
|
813
|
+
declare function withStorageSync<Input extends SignalStoreFeatureResult>(key: string, storageStrategy: AsyncStorageStrategy<Input['state']>): SignalStoreFeature<Input, AsyncFeatureResult>;
|
|
814
|
+
declare function withStorageSync<Input extends SignalStoreFeatureResult>(key: string, storageStrategy: SyncStorageStrategy<Input['state']>): SignalStoreFeature<Input, SyncFeatureResult>;
|
|
815
|
+
declare function withStorageSync<Input extends SignalStoreFeatureResult>(config: SyncConfig<Input['state']>): SignalStoreFeature<Input, SyncFeatureResult>;
|
|
816
|
+
declare function withStorageSync<Input extends SignalStoreFeatureResult>(config: SyncConfig<Input['state']>, storageStrategy: AsyncStorageStrategy<Input['state']>): SignalStoreFeature<Input, AsyncFeatureResult>;
|
|
817
|
+
declare function withStorageSync<Input extends SignalStoreFeatureResult>(config: SyncConfig<Input['state']>, storageStrategy: SyncStorageStrategy<Input['state']>): SignalStoreFeature<Input, SyncFeatureResult>;
|
|
818
|
+
|
|
819
|
+
type SyncMethods = {
|
|
820
|
+
clearStorage(): void;
|
|
821
|
+
readFromStorage(): void;
|
|
822
|
+
writeToStorage(): void;
|
|
823
|
+
};
|
|
824
|
+
type SyncFeatureResult = EmptyFeatureResult & {
|
|
825
|
+
methods: SyncMethods;
|
|
826
|
+
};
|
|
827
|
+
type SyncStoreForFactory<State extends object> = WritableStateSource<State>;
|
|
828
|
+
type SyncStorageStrategy<State extends object> = ((config: Required<SyncConfig<State>>, store: SyncStoreForFactory<State>, useStubs: boolean) => SyncMethods) & {
|
|
829
|
+
type: 'sync';
|
|
830
|
+
};
|
|
831
|
+
type AsyncMethods = {
|
|
832
|
+
clearStorage(): Promise<void>;
|
|
833
|
+
readFromStorage(): Promise<void>;
|
|
834
|
+
writeToStorage(): Promise<void>;
|
|
835
|
+
};
|
|
836
|
+
/**
|
|
837
|
+
* AsyncFeatureResult is used as the public interface that users interact with
|
|
838
|
+
* when calling `withIndexedDB`. It intentionally omits the internal SYNC_STATUS
|
|
839
|
+
* property to avoid TypeScript error TS4058 (return type of public method
|
|
840
|
+
* includes private type).
|
|
841
|
+
*
|
|
842
|
+
* For internal implementation, we use AsyncStoreForFactory which includes
|
|
843
|
+
* the SYNC_STATUS property needed for state management.
|
|
844
|
+
*/
|
|
845
|
+
declare const SYNC_STATUS: unique symbol;
|
|
846
|
+
type SyncStatus = 'idle' | 'syncing' | 'synced';
|
|
847
|
+
type InternalAsyncProps = AsyncFeatureResult['props'] & {
|
|
848
|
+
[SYNC_STATUS]: WritableSignal<SyncStatus>;
|
|
849
|
+
};
|
|
850
|
+
type AsyncFeatureResult = EmptyFeatureResult & {
|
|
851
|
+
methods: AsyncMethods;
|
|
852
|
+
props: {
|
|
853
|
+
isSynced: Signal<boolean>;
|
|
854
|
+
whenSynced: () => Promise<void>;
|
|
855
|
+
};
|
|
856
|
+
};
|
|
857
|
+
type AsyncStoreForFactory<State extends object> = WritableStateSource<State> & InternalAsyncProps;
|
|
858
|
+
type AsyncStorageStrategy<State extends object> = ((config: Required<SyncConfig<State>>, store: AsyncStoreForFactory<State>, useStubs: boolean) => AsyncMethods) & {
|
|
859
|
+
type: 'async';
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
declare function withIndexedDB<State extends object>(): AsyncStorageStrategy<State>;
|
|
863
|
+
|
|
864
|
+
declare function withLocalStorage<State extends object>(): SyncStorageStrategy<State>;
|
|
865
|
+
declare function withSessionStorage<State extends object>(): SyncStorageStrategy<State>;
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* `withConditional` activates a feature based on a given condition.
|
|
869
|
+
*
|
|
870
|
+
* **Use Cases**
|
|
871
|
+
* - Conditionally activate features based on the **store state** or other criteria.
|
|
872
|
+
* - Choose between **two different implementations** of a feature.
|
|
873
|
+
*
|
|
874
|
+
* **Type Constraints**
|
|
875
|
+
* Both features must have **exactly the same state, props, and methods**.
|
|
876
|
+
* Otherwise, a type error will occur.
|
|
877
|
+
*
|
|
878
|
+
*
|
|
879
|
+
* **Usage**
|
|
880
|
+
*
|
|
881
|
+
* ```typescript
|
|
882
|
+
* const withUser = signalStoreFeature(
|
|
883
|
+
* withState({ id: 1, name: 'Konrad' }),
|
|
884
|
+
* withHooks(store => ({
|
|
885
|
+
* onInit() {
|
|
886
|
+
* // user loading logic
|
|
887
|
+
* }
|
|
888
|
+
* }))
|
|
889
|
+
* );
|
|
890
|
+
*
|
|
891
|
+
* function withFakeUser() {
|
|
892
|
+
* return signalStoreFeature(
|
|
893
|
+
* withState({ id: 0, name: 'anonymous' })
|
|
894
|
+
* );
|
|
895
|
+
* }
|
|
896
|
+
*
|
|
897
|
+
* signalStore(
|
|
898
|
+
* withMethods(() => ({
|
|
899
|
+
* useRealUser: () => true
|
|
900
|
+
* })),
|
|
901
|
+
* withConditional((store) => store.useRealUser(), withUser, withFakeUser)
|
|
902
|
+
* )
|
|
903
|
+
* ```
|
|
904
|
+
*
|
|
905
|
+
* @param condition - A function that determines which feature to activate based on the store state.
|
|
906
|
+
* @param featureIfTrue - The feature to activate if the condition evaluates to `true`.
|
|
907
|
+
* @param featureIfFalse - The feature to activate if the condition evaluates to `false`.
|
|
908
|
+
* @returns A `SignalStoreFeature` that applies the selected feature based on the condition.
|
|
909
|
+
*/
|
|
910
|
+
declare function withConditional<Input extends SignalStoreFeatureResult, Output extends SignalStoreFeatureResult>(condition: (store: StateSignals<Input['state']> & Input['props'] & Input['methods']) => boolean, featureIfTrue: SignalStoreFeature<NoInfer<Input>, Output>, featureIfFalse: SignalStoreFeature<NoInfer<Input>, NoInfer<Output>>): SignalStoreFeature<Input, Output>;
|
|
911
|
+
declare const emptyFeature: SignalStoreFeature<_ngrx_signals.EmptyFeatureResult, {
|
|
912
|
+
state: {};
|
|
913
|
+
props: {};
|
|
914
|
+
methods: {};
|
|
915
|
+
}>;
|
|
916
|
+
|
|
917
|
+
type StoreForFactory<Input extends SignalStoreFeatureResult> = StateSignals<Input['state']> & Input['props'] & Input['methods'];
|
|
918
|
+
/**
|
|
919
|
+
* @deprecated Use `import { withFeature } from '@ngrx/signals'` instead, starting with `ngrx/signals` 19.1: https://ngrx.io/guide/signals/signal-store/custom-store-features#connecting-a-custom-feature-with-the-store
|
|
920
|
+
*
|
|
921
|
+
* Allows to pass properties, methods, or signals from a SignalStore
|
|
922
|
+
* to a feature.
|
|
923
|
+
*
|
|
924
|
+
* Typically, a `signalStoreFeature` can have input constraints on
|
|
925
|
+
*
|
|
926
|
+
* ```typescript
|
|
927
|
+
* function withSum(a: Signal<number>, b: Signal<number>) {
|
|
928
|
+
* return signalStoreFeature(
|
|
929
|
+
* withComputed(() => ({
|
|
930
|
+
* sum: computed(() => a() + b())
|
|
931
|
+
* }))
|
|
932
|
+
* );
|
|
933
|
+
* }
|
|
934
|
+
*
|
|
935
|
+
* signalStore(
|
|
936
|
+
* withState({ a: 1, b: 2 }),
|
|
937
|
+
* withFeatureFactory((store) => withSum(store.a, store.b))
|
|
938
|
+
* );
|
|
939
|
+
* ```
|
|
940
|
+
* @param factoryFn
|
|
941
|
+
*/
|
|
942
|
+
declare function withFeatureFactory<Input extends SignalStoreFeatureResult, Output extends SignalStoreFeatureResult>(factoryFn: (store: StoreForFactory<Input>) => SignalStoreFeature<Input, Output>): SignalStoreFeature<Input, Output>;
|
|
943
|
+
|
|
944
|
+
export { capitalize, createEffects, createPageArray, createReducer, deriveCallStateKeys, emptyFeature, firstPage, getCallStateKeys, getCollectionArray, getDataServiceKeys, getUndoRedoKeys, gotoPage, nextPage, noPayload, patchState, payload, previousPage, provideDevtoolsConfig, renameDevtoolsName, setError, setLoaded, setLoading, setMaxPageNavigationArrayItems, setPageSize, setResetState, updateState, withCallState, withConditional, withDataService, withDevToolsStub, withDevtools, withDisabledNameIndices, withFeatureFactory, withGlitchTracking, withImmutableState, withIndexedDB, withIndexedDB as withIndexeddb, withLocalStorage, withMapper, withPagination, withRedux, withReset, withSessionStorage, withStorageSync, withUndoRedo };
|
|
945
|
+
export type { CallState, CallStateSignals, CallStateSlice, DataService, DataServiceComputed, DataServiceMethods, DataServiceState, Entity, Filter, NamedCallStateSignals, NamedCallStateSlice, NamedDataServiceComputed, NamedDataServiceMethods, NamedDataServiceState, NamedPaginationServiceSignals, NamedPaginationServiceState, NormalizedUndoRedoOptions, Page, PaginationServiceSignals, PaginationServiceState, ReduxDevtoolsConfig, SetCallState, SetPaginationState, StackItem, SyncConfig };
|