@angular-architects/ngrx-toolkit 20.0.2 → 20.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.
Files changed (84) hide show
  1. package/fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs +119 -0
  2. package/fesm2022/angular-architects-ngrx-toolkit-redux-connector.mjs.map +1 -0
  3. package/fesm2022/angular-architects-ngrx-toolkit.mjs +1888 -0
  4. package/fesm2022/angular-architects-ngrx-toolkit.mjs.map +1 -0
  5. package/index.d.ts +1084 -0
  6. package/package.json +21 -4
  7. package/redux-connector/index.d.ts +59 -0
  8. package/eslint.config.cjs +0 -43
  9. package/jest.config.ts +0 -22
  10. package/ng-package.json +0 -7
  11. package/project.json +0 -37
  12. package/redux-connector/docs/README.md +0 -131
  13. package/redux-connector/index.ts +0 -6
  14. package/redux-connector/ng-package.json +0 -5
  15. package/redux-connector/src/lib/create-redux.ts +0 -102
  16. package/redux-connector/src/lib/model.ts +0 -89
  17. package/redux-connector/src/lib/rxjs-interop/redux-method.ts +0 -66
  18. package/redux-connector/src/lib/signal-redux-store.ts +0 -59
  19. package/redux-connector/src/lib/util.ts +0 -22
  20. package/src/index.ts +0 -43
  21. package/src/lib/assertions/assertions.ts +0 -9
  22. package/src/lib/devtools/features/with-disabled-name-indicies.ts +0 -31
  23. package/src/lib/devtools/features/with-glitch-tracking.ts +0 -35
  24. package/src/lib/devtools/features/with-mapper.ts +0 -34
  25. package/src/lib/devtools/internal/current-action-names.ts +0 -1
  26. package/src/lib/devtools/internal/default-tracker.ts +0 -60
  27. package/src/lib/devtools/internal/devtools-feature.ts +0 -37
  28. package/src/lib/devtools/internal/devtools-syncer.service.ts +0 -202
  29. package/src/lib/devtools/internal/glitch-tracker.service.ts +0 -61
  30. package/src/lib/devtools/internal/models.ts +0 -29
  31. package/src/lib/devtools/provide-devtools-config.ts +0 -32
  32. package/src/lib/devtools/rename-devtools-name.ts +0 -21
  33. package/src/lib/devtools/tests/action-name.spec.ts +0 -48
  34. package/src/lib/devtools/tests/basic.spec.ts +0 -111
  35. package/src/lib/devtools/tests/connecting.spec.ts +0 -37
  36. package/src/lib/devtools/tests/helpers.spec.ts +0 -43
  37. package/src/lib/devtools/tests/naming.spec.ts +0 -216
  38. package/src/lib/devtools/tests/provide-devtools-config.spec.ts +0 -25
  39. package/src/lib/devtools/tests/types.spec.ts +0 -19
  40. package/src/lib/devtools/tests/update-state.spec.ts +0 -29
  41. package/src/lib/devtools/tests/with-devtools.spec.ts +0 -5
  42. package/src/lib/devtools/tests/with-glitch-tracking.spec.ts +0 -272
  43. package/src/lib/devtools/tests/with-mapper.spec.ts +0 -69
  44. package/src/lib/devtools/update-state.ts +0 -38
  45. package/src/lib/devtools/with-dev-tools-stub.ts +0 -6
  46. package/src/lib/devtools/with-devtools.ts +0 -81
  47. package/src/lib/immutable-state/deep-freeze.ts +0 -43
  48. package/src/lib/immutable-state/is-dev-mode.ts +0 -6
  49. package/src/lib/immutable-state/tests/with-immutable-state.spec.ts +0 -278
  50. package/src/lib/immutable-state/with-immutable-state.ts +0 -150
  51. package/src/lib/shared/prettify.ts +0 -3
  52. package/src/lib/shared/signal-store-models.ts +0 -30
  53. package/src/lib/shared/throw-if-null.ts +0 -7
  54. package/src/lib/storage-sync/features/with-indexed-db.ts +0 -81
  55. package/src/lib/storage-sync/features/with-local-storage.ts +0 -58
  56. package/src/lib/storage-sync/internal/indexeddb.service.ts +0 -124
  57. package/src/lib/storage-sync/internal/local-storage.service.ts +0 -19
  58. package/src/lib/storage-sync/internal/models.ts +0 -62
  59. package/src/lib/storage-sync/internal/session-storage.service.ts +0 -18
  60. package/src/lib/storage-sync/tests/indexeddb.service.spec.ts +0 -99
  61. package/src/lib/storage-sync/tests/with-storage-async.spec.ts +0 -305
  62. package/src/lib/storage-sync/tests/with-storage-sync.spec.ts +0 -273
  63. package/src/lib/storage-sync/with-storage-sync.ts +0 -236
  64. package/src/lib/with-call-state.spec.ts +0 -42
  65. package/src/lib/with-call-state.ts +0 -195
  66. package/src/lib/with-conditional.spec.ts +0 -125
  67. package/src/lib/with-conditional.ts +0 -74
  68. package/src/lib/with-data-service.spec.ts +0 -564
  69. package/src/lib/with-data-service.ts +0 -433
  70. package/src/lib/with-feature-factory.spec.ts +0 -69
  71. package/src/lib/with-feature-factory.ts +0 -56
  72. package/src/lib/with-pagination.spec.ts +0 -135
  73. package/src/lib/with-pagination.ts +0 -373
  74. package/src/lib/with-redux.spec.ts +0 -258
  75. package/src/lib/with-redux.ts +0 -387
  76. package/src/lib/with-reset.spec.ts +0 -112
  77. package/src/lib/with-reset.ts +0 -62
  78. package/src/lib/with-undo-redo.spec.ts +0 -274
  79. package/src/lib/with-undo-redo.ts +0 -200
  80. package/src/test-setup.ts +0 -6
  81. package/tsconfig.json +0 -29
  82. package/tsconfig.lib.json +0 -17
  83. package/tsconfig.lib.prod.json +0 -9
  84. package/tsconfig.spec.json +0 -17
@@ -1,195 +0,0 @@
1
- import { Signal, computed } from '@angular/core';
2
- import {
3
- EmptyFeatureResult,
4
- SignalStoreFeature,
5
- signalStoreFeature,
6
- withComputed,
7
- withState,
8
- } from '@ngrx/signals';
9
-
10
- export type CallState = 'init' | 'loading' | 'loaded' | { error: string };
11
-
12
- export type CallStateSlice = {
13
- callState: CallState;
14
- };
15
-
16
- export type NamedCallStateSlice<Collection extends string> = {
17
- [K in keyof CallStateSlice as Collection extends ''
18
- ? `${Collection}${K}`
19
- : `${Collection}${Capitalize<K>}`]: CallStateSlice[K];
20
- };
21
-
22
- export type CallStateSignals = {
23
- loading: Signal<boolean>;
24
- loaded: Signal<boolean>;
25
- error: Signal<string | null>;
26
- };
27
-
28
- export type NamedCallStateSignals<Prop extends string> = {
29
- [K in keyof CallStateSignals as Prop extends ''
30
- ? `${Prop}${K}`
31
- : `${Prop}${Capitalize<K>}`]: CallStateSignals[K];
32
- };
33
-
34
- export type SetCallState<Prop extends string | undefined> = Prop extends string
35
- ? NamedCallStateSlice<Prop>
36
- : CallStateSlice;
37
-
38
- export function deriveCallStateKeys<Collection extends string>(
39
- collection?: Collection,
40
- ) {
41
- return {
42
- callStateKey: collection ? `${collection}CallState` : 'callState',
43
- loadingKey: collection ? `${collection}Loading` : 'loading',
44
- loadedKey: collection ? `${collection}Loaded` : 'loaded',
45
- errorKey: collection ? `${collection}Error` : 'error',
46
- };
47
- }
48
-
49
- export function getCallStateKeys(config?: { collection?: string }) {
50
- const prop = config?.collection;
51
- return deriveCallStateKeys(prop);
52
- }
53
-
54
- export function getCollectionArray(
55
- config: { collection?: string } | { collections?: string[] },
56
- ) {
57
- return 'collections' in config
58
- ? config.collections
59
- : 'collection' in config && config.collection
60
- ? [config.collection]
61
- : undefined;
62
- }
63
-
64
- export function withCallState<Collection extends string>(config: {
65
- collections: Collection[];
66
- }): SignalStoreFeature<
67
- EmptyFeatureResult,
68
- EmptyFeatureResult & {
69
- state: NamedCallStateSlice<Collection>;
70
- props: NamedCallStateSignals<Collection>;
71
- }
72
- >;
73
- export function withCallState<Collection extends string>(config: {
74
- collection: Collection;
75
- }): SignalStoreFeature<
76
- EmptyFeatureResult,
77
- EmptyFeatureResult & {
78
- state: NamedCallStateSlice<Collection>;
79
- props: NamedCallStateSignals<Collection>;
80
- }
81
- >;
82
- export function withCallState(): SignalStoreFeature<
83
- EmptyFeatureResult,
84
- EmptyFeatureResult & {
85
- state: CallStateSlice;
86
- props: CallStateSignals;
87
- }
88
- >;
89
- export function withCallState<Collection extends string>(
90
- config?:
91
- | {
92
- collection: Collection;
93
- }
94
- | {
95
- collections: Collection[];
96
- },
97
- ): SignalStoreFeature {
98
- return signalStoreFeature(
99
- withState(() => {
100
- if (!config) {
101
- return { callState: 'init' };
102
- }
103
- const collections = getCollectionArray(config);
104
- if (collections) {
105
- return collections.reduce(
106
- (acc, cur) => ({
107
- ...acc,
108
- ...{ [cur ? `${cur}CallState` : 'callState']: 'init' },
109
- }),
110
- {},
111
- );
112
- }
113
-
114
- return { callState: 'init' };
115
- }),
116
- withComputed((state: Record<string, Signal<unknown>>) => {
117
- if (config) {
118
- const collections = getCollectionArray(config);
119
- if (collections) {
120
- return collections.reduce<Record<string, Signal<unknown>>>(
121
- (acc, cur: string) => {
122
- const { callStateKey, errorKey, loadedKey, loadingKey } =
123
- deriveCallStateKeys(cur);
124
- const callState = state[callStateKey] as Signal<CallState>;
125
- return {
126
- ...acc,
127
- [loadingKey]: computed(() => callState() === 'loading'),
128
- [loadedKey]: computed(() => callState() === 'loaded'),
129
- [errorKey]: computed(() => {
130
- const v = callState();
131
- return typeof v === 'object' ? v.error : null;
132
- }),
133
- };
134
- },
135
- {},
136
- );
137
- }
138
- }
139
- const { callStateKey, errorKey, loadedKey, loadingKey } =
140
- deriveCallStateKeys();
141
- const callState = state[callStateKey] as Signal<CallState>;
142
- return {
143
- [loadingKey]: computed(() => callState() === 'loading'),
144
- [loadedKey]: computed(() => callState() === 'loaded'),
145
- [errorKey]: computed(() => {
146
- const v = callState();
147
- return typeof v === 'object' ? v.error : null;
148
- }),
149
- };
150
- }),
151
- );
152
- }
153
-
154
- export function setLoading<Prop extends string | undefined = undefined>(
155
- prop?: Prop,
156
- ): SetCallState<Prop> {
157
- if (prop) {
158
- return { [`${prop}CallState`]: 'loading' } as SetCallState<Prop>;
159
- }
160
-
161
- return { callState: 'loading' } as SetCallState<Prop>;
162
- }
163
-
164
- export function setLoaded<Prop extends string | undefined = undefined>(
165
- prop?: Prop,
166
- ): SetCallState<Prop> {
167
- if (prop) {
168
- return { [`${prop}CallState`]: 'loaded' } as SetCallState<Prop>;
169
- } else {
170
- return { callState: 'loaded' } as SetCallState<Prop>;
171
- }
172
- }
173
-
174
- export function setError<Prop extends string | undefined = undefined>(
175
- error: unknown,
176
- prop?: Prop,
177
- ): SetCallState<Prop> {
178
- let errorMessage: string;
179
-
180
- if (!error) {
181
- errorMessage = '';
182
- } else if (typeof error === 'object' && 'message' in error) {
183
- errorMessage = String(error.message);
184
- } else {
185
- errorMessage = String(error);
186
- }
187
-
188
- if (prop) {
189
- return {
190
- [`${prop}CallState`]: { error: errorMessage },
191
- } as SetCallState<Prop>;
192
- } else {
193
- return { callState: { error: errorMessage } } as SetCallState<Prop>;
194
- }
195
- }
@@ -1,125 +0,0 @@
1
- import { inject, InjectionToken } from '@angular/core';
2
- import { TestBed } from '@angular/core/testing';
3
- import {
4
- getState,
5
- patchState,
6
- signalStore,
7
- signalStoreFeature,
8
- withHooks,
9
- withMethods,
10
- withState,
11
- } from '@ngrx/signals';
12
- import { withDevtools } from './devtools/with-devtools';
13
- import { emptyFeature, withConditional } from './with-conditional';
14
-
15
- describe('withConditional', () => {
16
- const withUser = signalStoreFeature(
17
- withState({ id: 0, name: '' }),
18
- withHooks((store) => ({
19
- onInit() {
20
- patchState(store, { id: 1, name: 'Konrad' });
21
- },
22
- })),
23
- );
24
-
25
- const withFakeUser = signalStoreFeature(
26
- withState({ id: 0, name: 'Tommy Fake' }),
27
- );
28
-
29
- for (const isReal of [true, false]) {
30
- it(`should ${isReal ? '' : 'not '} enable withUser`, () => {
31
- const REAL_USER_TOKEN = new InjectionToken('REAL_USER', {
32
- providedIn: 'root',
33
- factory: () => isReal,
34
- });
35
- const UserStore = signalStore(
36
- { providedIn: 'root' },
37
- withConditional(() => inject(REAL_USER_TOKEN), withUser, withFakeUser),
38
- );
39
- const userStore = TestBed.inject(UserStore);
40
-
41
- if (isReal) {
42
- expect(getState(userStore)).toEqual({ id: 1, name: 'Konrad' });
43
- } else {
44
- expect(getState(userStore)).toEqual({ id: 0, name: 'Tommy Fake' });
45
- }
46
- });
47
- }
48
-
49
- it(`should access the store`, () => {
50
- const UserStore = signalStore(
51
- { providedIn: 'root' },
52
- withMethods(() => ({
53
- useRealUser: () => true,
54
- })),
55
- withConditional((store) => store.useRealUser(), withUser, withFakeUser),
56
- );
57
- const userStore = TestBed.inject(UserStore);
58
-
59
- expect(getState(userStore)).toEqual({ id: 1, name: 'Konrad' });
60
- });
61
-
62
- it('should be used inside a signalStoreFeature', () => {
63
- const withConditionalUser = (activate: boolean) =>
64
- signalStoreFeature(
65
- withConditional(() => activate, withUser, withFakeUser),
66
- );
67
-
68
- const UserStore = signalStore(
69
- { providedIn: 'root' },
70
- withConditionalUser(true),
71
- );
72
- const userStore = TestBed.inject(UserStore);
73
-
74
- expect(getState(userStore)).toEqual({ id: 1, name: 'Konrad' });
75
- });
76
-
77
- it('should ensure that both features return the same type', () => {
78
- const withUser = signalStoreFeature(
79
- withState({ id: 0, name: '' }),
80
- withHooks((store) => ({
81
- onInit() {
82
- patchState(store, { id: 1, name: 'Konrad' });
83
- },
84
- })),
85
- );
86
-
87
- const withFakeUser = signalStoreFeature(
88
- withState({ id: 0, firstname: 'Tommy Fake' }),
89
- );
90
-
91
- // @ts-expect-error withFakeUser has a different state shape
92
- signalStore(withConditional(() => true, withUser, withFakeUser));
93
- });
94
-
95
- it('should also work with empty features', () => {
96
- signalStore(
97
- withConditional(
98
- () => true,
99
- withDevtools('dummy'),
100
- signalStoreFeature(withState({})),
101
- ),
102
- );
103
- });
104
-
105
- it('should work with `emptyFeature` if falsy is skipped', () => {
106
- signalStore(
107
- withConditional(
108
- () => true,
109
- signalStoreFeature(withState({})),
110
- emptyFeature,
111
- ),
112
- );
113
- });
114
-
115
- it('should not work with `emptyFeature` if feature is not empty', () => {
116
- signalStore(
117
- withConditional(
118
- () => true,
119
- // @ts-expect-error feature is not empty
120
- () => signalStoreFeature(withState({ x: 1 })),
121
- emptyFeature,
122
- ),
123
- );
124
- });
125
- });
@@ -1,74 +0,0 @@
1
- import {
2
- signalStoreFeature,
3
- SignalStoreFeature,
4
- SignalStoreFeatureResult,
5
- StateSignals,
6
- withState,
7
- } from '@ngrx/signals';
8
-
9
- /**
10
- * `withConditional` activates a feature based on a given condition.
11
- *
12
- * **Use Cases**
13
- * - Conditionally activate features based on the **store state** or other criteria.
14
- * - Choose between **two different implementations** of a feature.
15
- *
16
- * **Type Constraints**
17
- * Both features must have **exactly the same state, props, and methods**.
18
- * Otherwise, a type error will occur.
19
- *
20
- *
21
- * **Usage**
22
- *
23
- * ```typescript
24
- * const withUser = signalStoreFeature(
25
- * withState({ id: 1, name: 'Konrad' }),
26
- * withHooks(store => ({
27
- * onInit() {
28
- * // user loading logic
29
- * }
30
- * }))
31
- * );
32
- *
33
- * function withFakeUser() {
34
- * return signalStoreFeature(
35
- * withState({ id: 0, name: 'anonymous' })
36
- * );
37
- * }
38
- *
39
- * signalStore(
40
- * withMethods(() => ({
41
- * useRealUser: () => true
42
- * })),
43
- * withConditional((store) => store.useRealUser(), withUser, withFakeUser)
44
- * )
45
- * ```
46
- *
47
- * @param condition - A function that determines which feature to activate based on the store state.
48
- * @param featureIfTrue - The feature to activate if the condition evaluates to `true`.
49
- * @param featureIfFalse - The feature to activate if the condition evaluates to `false`.
50
- * @returns A `SignalStoreFeature` that applies the selected feature based on the condition.
51
- */
52
- export function withConditional<
53
- Input extends SignalStoreFeatureResult,
54
- Output extends SignalStoreFeatureResult,
55
- >(
56
- condition: (
57
- store: StateSignals<Input['state']> & Input['props'] & Input['methods'],
58
- ) => boolean,
59
- featureIfTrue: SignalStoreFeature<NoInfer<Input>, Output>,
60
- featureIfFalse: SignalStoreFeature<NoInfer<Input>, NoInfer<Output>>,
61
- ): SignalStoreFeature<Input, Output> {
62
- return (store) => {
63
- const conditionStore = {
64
- ...store['stateSignals'],
65
- ...store['props'],
66
- ...store['methods'],
67
- };
68
- return condition(conditionStore)
69
- ? featureIfTrue(store)
70
- : featureIfFalse(store);
71
- };
72
- }
73
-
74
- export const emptyFeature = signalStoreFeature(withState({}));