@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,274 +0,0 @@
1
- import { computed, inject } from '@angular/core';
2
- import { TestBed } from '@angular/core/testing';
3
- import {
4
- patchState,
5
- signalStore,
6
- type,
7
- withComputed,
8
- withMethods,
9
- withState,
10
- } from '@ngrx/signals';
11
- import { addEntity, withEntities } from '@ngrx/signals/entities';
12
- import { withCallState } from './with-call-state';
13
- import { withUndoRedo } from './with-undo-redo';
14
-
15
- const testState = { test: '' };
16
- const testKeys = ['test' as const];
17
- const newValue = 'new value';
18
- const newerValue = 'newer value';
19
-
20
- describe('withUndoRedo', () => {
21
- it('adds methods for undo, redo, canUndo, canRedo', () => {
22
- TestBed.runInInjectionContext(() => {
23
- const Store = signalStore(
24
- withState(testState),
25
- withUndoRedo({ keys: testKeys }),
26
- );
27
- const store = new Store();
28
-
29
- expect(Object.keys(store)).toEqual([
30
- 'test',
31
- 'canUndo',
32
- 'canRedo',
33
- 'undo',
34
- 'redo',
35
- 'clearStack',
36
- ]);
37
- });
38
- });
39
-
40
- it('should check keys and collection types', () => {
41
- signalStore(
42
- withState(testState),
43
- // @ts-expect-error - should not allow invalid keys
44
- withUndoRedo({ keys: ['tes'] }),
45
- );
46
- signalStore(
47
- withState(testState),
48
- withEntities({ entity: type(), collection: 'flight' }),
49
- // @ts-expect-error - should not allow invalid keys when entities are present
50
- withUndoRedo({ keys: ['flightIdsTest'] }),
51
- );
52
- signalStore(
53
- withState(testState),
54
- // @ts-expect-error - should not allow collections without named entities
55
- withUndoRedo({ collections: ['tee'] }),
56
- );
57
- signalStore(
58
- withState(testState),
59
- withComputed((store) => ({ testComputed: computed(() => store.test()) })),
60
- // @ts-expect-error - should not allow collections without named entities with other computed
61
- withUndoRedo({ collections: ['tested'] }),
62
- );
63
- signalStore(
64
- withEntities({ entity: type() }),
65
- // @ts-expect-error - should not allow collections without named entities
66
- withUndoRedo({ collections: ['test'] }),
67
- );
68
- signalStore(
69
- withEntities({ entity: type(), collection: 'flight' }),
70
- // @ts-expect-error - should not allow invalid collections
71
- withUndoRedo({ collections: ['test'] }),
72
- );
73
- });
74
-
75
- describe('undo and redo', () => {
76
- it('restores previous state for regular store key', () => {
77
- TestBed.runInInjectionContext(() => {
78
- const Store = signalStore(
79
- withState(testState),
80
- withMethods((store) => ({
81
- updateTest: (newTest: string) =>
82
- patchState(store, { test: newTest }),
83
- })),
84
- withUndoRedo({ keys: testKeys }),
85
- );
86
-
87
- const store = new Store();
88
-
89
- store.updateTest(newValue);
90
-
91
- expect(store.test()).toEqual(newValue);
92
- expect(store.canUndo()).toBe(true);
93
- expect(store.canRedo()).toBe(false);
94
-
95
- store.undo();
96
-
97
- expect(store.test()).toEqual('');
98
- expect(store.canUndo()).toBe(false);
99
- expect(store.canRedo()).toBe(true);
100
- });
101
- });
102
-
103
- it('restores previous state for regular store key and respects skip', () => {
104
- TestBed.runInInjectionContext(() => {
105
- const Store = signalStore(
106
- withState(testState),
107
- withMethods((store) => ({
108
- updateTest: (newTest: string) =>
109
- patchState(store, { test: newTest }),
110
- })),
111
- withUndoRedo({ keys: testKeys, skip: 1 }),
112
- );
113
-
114
- const store = new Store();
115
-
116
- store.updateTest(newValue);
117
-
118
- expect(store.test()).toEqual(newValue);
119
-
120
- store.updateTest(newerValue);
121
-
122
- store.undo();
123
-
124
- expect(store.test()).toEqual(newValue);
125
- expect(store.canUndo()).toBe(false);
126
-
127
- store.undo();
128
-
129
- // should not change
130
- expect(store.test()).toEqual(newValue);
131
- });
132
- });
133
-
134
- it('undoes and redoes previous state for entity', () => {
135
- const Store = signalStore(
136
- withEntities({ entity: type<{ id: string }>() }),
137
- withMethods((store) => ({
138
- addEntity: (newTest: string) =>
139
- patchState(store, addEntity({ id: newTest })),
140
- })),
141
- withUndoRedo(),
142
- );
143
- TestBed.configureTestingModule({ providers: [Store] });
144
- TestBed.runInInjectionContext(() => {
145
- const store = inject(Store);
146
-
147
- expect(store.entities()).toEqual([]);
148
- expect(store.canUndo()).toBe(false);
149
- expect(store.canRedo()).toBe(false);
150
-
151
- store.addEntity(newValue);
152
-
153
- expect(store.entities()).toEqual([{ id: newValue }]);
154
- expect(store.canUndo()).toBe(true);
155
- expect(store.canRedo()).toBe(false);
156
-
157
- store.addEntity(newerValue);
158
-
159
- expect(store.entities()).toEqual([
160
- { id: newValue },
161
- { id: newerValue },
162
- ]);
163
- expect(store.canUndo()).toBe(true);
164
- expect(store.canRedo()).toBe(false);
165
-
166
- store.undo();
167
-
168
- expect(store.entities()).toEqual([{ id: newValue }]);
169
- expect(store.canUndo()).toBe(true);
170
- expect(store.canRedo()).toBe(true);
171
-
172
- store.undo();
173
-
174
- expect(store.entities()).toEqual([]);
175
- expect(store.canUndo()).toBe(false);
176
- expect(store.canRedo()).toBe(true);
177
-
178
- store.redo();
179
-
180
- expect(store.entities()).toEqual([{ id: newValue }]);
181
- expect(store.canUndo()).toBe(true);
182
- expect(store.canRedo()).toBe(true);
183
-
184
- // should return canRedo=false after a change
185
- store.addEntity('newest');
186
-
187
- expect(store.canUndo()).toBe(true);
188
- expect(store.canRedo()).toBe(false);
189
- });
190
- });
191
-
192
- it('restores previous state for named entity', () => {
193
- TestBed.runInInjectionContext(() => {
194
- const Store = signalStore(
195
- withEntities({
196
- entity: type<{ id: string }>(),
197
- collection: 'flight',
198
- }),
199
- withMethods((store) => ({
200
- addEntity: (newTest: string) =>
201
- patchState(
202
- store,
203
- addEntity({ id: newTest }, { collection: 'flight' }),
204
- ),
205
- })),
206
- withCallState({ collection: 'flight' }),
207
- withUndoRedo({ collections: ['flight'] }),
208
- );
209
-
210
- const store = new Store();
211
-
212
- store.addEntity(newValue);
213
-
214
- expect(store.flightEntities()).toEqual([{ id: newValue }]);
215
- expect(store.canUndo()).toBe(true);
216
- expect(store.canRedo()).toBe(false);
217
-
218
- store.undo();
219
-
220
- expect(store.flightEntities()).toEqual([]);
221
- expect(store.canUndo()).toBe(false);
222
- expect(store.canRedo()).toBe(true);
223
- });
224
- });
225
-
226
- it('clears undo redo stack', () => {
227
- const Store = signalStore(
228
- { providedIn: 'root' },
229
- withState(testState),
230
- withMethods((store) => ({
231
- update: (value: string) => patchState(store, { test: value }),
232
- })),
233
- withUndoRedo({ keys: testKeys }),
234
- );
235
-
236
- const store = TestBed.inject(Store);
237
-
238
- store.update('Foo');
239
- store.update('Bar');
240
- store.undo();
241
- store.clearStack();
242
-
243
- expect(store.canUndo()).toBe(false);
244
- expect(store.canRedo()).toBe(false);
245
- });
246
-
247
- it('cannot undo after clearing and setting a new value', () => {
248
- const Store = signalStore(
249
- { providedIn: 'root' },
250
- withState(testState),
251
- withMethods((store) => ({
252
- update: (value: string) => patchState(store, { test: value }),
253
- })),
254
- withUndoRedo({ keys: testKeys }),
255
- );
256
-
257
- const store = TestBed.inject(Store);
258
-
259
- store.update('Alan');
260
-
261
- store.update('Gordon');
262
-
263
- store.clearStack();
264
-
265
- // After clearing the undo/redo stack, there is no previous item anymore.
266
- // The following update becomes the first value.
267
- // Since there is no other value before, it cannot be undone.
268
- store.update('Hugh');
269
-
270
- expect(store.canUndo()).toBe(false);
271
- expect(store.canRedo()).toBe(false);
272
- });
273
- });
274
- });
@@ -1,200 +0,0 @@
1
- import { Signal, isSignal, signal, untracked } from '@angular/core';
2
- import {
3
- EmptyFeatureResult,
4
- SignalStoreFeature,
5
- SignalStoreFeatureResult,
6
- patchState,
7
- signalStoreFeature,
8
- watchState,
9
- withComputed,
10
- withHooks,
11
- withMethods,
12
- } from '@ngrx/signals';
13
- import { capitalize } from './with-data-service';
14
-
15
- export type StackItem = Record<string, unknown>;
16
-
17
- export type NormalizedUndoRedoOptions = {
18
- maxStackSize: number;
19
- collections?: string[];
20
- keys: string[];
21
- skip: number;
22
- };
23
-
24
- const defaultOptions: NormalizedUndoRedoOptions = {
25
- maxStackSize: 100,
26
- keys: [],
27
- skip: 0,
28
- };
29
-
30
- export function getUndoRedoKeys(collections?: string[]): string[] {
31
- if (collections) {
32
- return collections.flatMap((c) => [
33
- `${c}EntityMap`,
34
- `${c}Ids`,
35
- `selected${capitalize(c)}Ids`,
36
- `${c}Filter`,
37
- ]);
38
- }
39
- return ['entityMap', 'ids', 'selectedIds', 'filter'];
40
- }
41
-
42
- type NonNever<T> = T extends never ? never : T;
43
-
44
- type ExtractEntityCollection<T> = T extends `${infer U}Entities` ? U : never;
45
-
46
- type ExtractEntityCollections<Store extends SignalStoreFeatureResult> =
47
- NonNever<
48
- {
49
- [K in keyof Store['props']]: ExtractEntityCollection<K>;
50
- }[keyof Store['props']]
51
- >;
52
-
53
- type OptionsForState<Store extends SignalStoreFeatureResult> = Partial<
54
- Omit<NormalizedUndoRedoOptions, 'collections' | 'keys'>
55
- > & {
56
- collections?: ExtractEntityCollections<Store>[];
57
- keys?: (keyof Store['state'])[];
58
- };
59
-
60
- export function withUndoRedo<Input extends EmptyFeatureResult>(
61
- options?: OptionsForState<Input>,
62
- ): SignalStoreFeature<
63
- Input,
64
- EmptyFeatureResult & {
65
- props: {
66
- canUndo: Signal<boolean>;
67
- canRedo: Signal<boolean>;
68
- };
69
- methods: {
70
- undo: () => void;
71
- redo: () => void;
72
- clearStack: () => void;
73
- };
74
- }
75
- > {
76
- let previous: StackItem | null = null;
77
- let skipOnce = false;
78
-
79
- const normalized = {
80
- ...defaultOptions,
81
- ...options,
82
- };
83
-
84
- //
85
- // Design Decision: This feature has its own
86
- // internal state.
87
- //
88
-
89
- const undoStack: StackItem[] = [];
90
- const redoStack: StackItem[] = [];
91
-
92
- const canUndo = signal(false);
93
- const canRedo = signal(false);
94
-
95
- const updateInternal = () => {
96
- canUndo.set(undoStack.length !== 0);
97
- canRedo.set(redoStack.length !== 0);
98
- };
99
-
100
- const keys = [...getUndoRedoKeys(normalized.collections), ...normalized.keys];
101
-
102
- return signalStoreFeature(
103
- withComputed(() => ({
104
- canUndo: canUndo.asReadonly(),
105
- canRedo: canRedo.asReadonly(),
106
- })),
107
- withMethods((store) => ({
108
- undo(): void {
109
- const item = undoStack.pop();
110
-
111
- if (item && previous) {
112
- redoStack.push(previous);
113
- }
114
-
115
- if (item) {
116
- skipOnce = true;
117
- patchState(store, item);
118
- previous = item;
119
- }
120
-
121
- updateInternal();
122
- },
123
- redo(): void {
124
- const item = redoStack.pop();
125
-
126
- if (item && previous) {
127
- undoStack.push(previous);
128
- }
129
-
130
- if (item) {
131
- skipOnce = true;
132
- patchState(store, item);
133
- previous = item;
134
- }
135
-
136
- updateInternal();
137
- },
138
- clearStack(): void {
139
- undoStack.splice(0);
140
- redoStack.splice(0);
141
- previous = null;
142
- updateInternal();
143
- },
144
- })),
145
- withHooks({
146
- onInit(store) {
147
- watchState(store, () => {
148
- const cand = keys.reduce((acc, key) => {
149
- const s = (store as Record<string | keyof Input['state'], unknown>)[
150
- key
151
- ];
152
- if (s && isSignal(s)) {
153
- return {
154
- ...acc,
155
- [key]: s(),
156
- };
157
- }
158
- return acc;
159
- }, {});
160
-
161
- if (normalized.skip > 0) {
162
- normalized.skip--;
163
- return;
164
- }
165
-
166
- if (skipOnce) {
167
- skipOnce = false;
168
- return;
169
- }
170
-
171
- //
172
- // Deep Comparison to prevent duplicated entries
173
- // on the stack. This can e.g. happen after an undo
174
- // if the component sends back the undone filter
175
- // to the store.
176
- //
177
- if (JSON.stringify(cand) === JSON.stringify(previous)) {
178
- return;
179
- }
180
-
181
- // Clear redoStack after recorded action
182
- redoStack.splice(0);
183
-
184
- if (previous) {
185
- undoStack.push(previous);
186
- }
187
-
188
- if (redoStack.length > normalized.maxStackSize) {
189
- undoStack.unshift();
190
- }
191
-
192
- previous = cand;
193
-
194
- // Don't propogate current reactive context
195
- untracked(() => updateInternal());
196
- });
197
- },
198
- }),
199
- );
200
- }
package/src/test-setup.ts DELETED
@@ -1,6 +0,0 @@
1
- import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
2
-
3
- setupZoneTestEnv({
4
- errorOnUnknownElements: true,
5
- errorOnUnknownProperties: true,
6
- });
package/tsconfig.json DELETED
@@ -1,29 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2022",
4
- "useDefineForClassFields": false,
5
- "forceConsistentCasingInFileNames": true,
6
- "strict": true,
7
- "noImplicitOverride": true,
8
- "noPropertyAccessFromIndexSignature": true,
9
- "noImplicitReturns": true,
10
- "noFallthroughCasesInSwitch": true
11
- },
12
- "files": [],
13
- "include": [],
14
- "references": [
15
- {
16
- "path": "./tsconfig.lib.json"
17
- },
18
- {
19
- "path": "./tsconfig.spec.json"
20
- }
21
- ],
22
- "extends": "../../tsconfig.base.json",
23
- "angularCompilerOptions": {
24
- "enableI18nLegacyMessageIdFormat": false,
25
- "strictInjectionParameters": true,
26
- "strictInputAccessModifiers": true,
27
- "strictTemplates": true
28
- }
29
- }
package/tsconfig.lib.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../../dist/out-tsc",
5
- "declaration": true,
6
- "declarationMap": true,
7
- "inlineSources": true,
8
- "types": []
9
- },
10
- "exclude": [
11
- "src/**/*.spec.ts",
12
- "src/test-setup.ts",
13
- "jest.config.ts",
14
- "src/**/*.test.ts"
15
- ],
16
- "include": ["src/**/*.ts"]
17
- }
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "./tsconfig.lib.json",
3
- "compilerOptions": {
4
- "declarationMap": false
5
- },
6
- "angularCompilerOptions": {
7
- "compilationMode": "partial"
8
- }
9
- }
@@ -1,17 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "../../dist/out-tsc",
5
- "module": "commonjs",
6
- "target": "es2016",
7
- "types": ["jest", "node"]
8
- },
9
- "files": ["src/test-setup.ts"],
10
- "include": [
11
- "jest.config.ts",
12
- "src/**/*.test.ts",
13
- "src/**/*.spec.ts",
14
- "src/**/*.d.ts",
15
- "src/lib/storage-sync/tests/with-storage-sync-indexedb.spec.ts"
16
- ]
17
- }