@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,111 +0,0 @@
1
- import { createEnvironmentInjector, EnvironmentInjector } from '@angular/core';
2
- import { TestBed } from '@angular/core/testing';
3
- import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';
4
- import { renameDevtoolsName } from '../rename-devtools-name';
5
- import { withDevtools } from '../with-devtools';
6
- import { setupExtensions } from './helpers.spec';
7
-
8
- describe('Devtools Basics', () => {
9
- it('should dispatch update', () => {
10
- const { sendSpy } = setupExtensions();
11
- TestBed.inject(
12
- signalStore(
13
- { providedIn: 'root' },
14
- withDevtools('shop'),
15
- withState({ name: 'Car' }),
16
- ),
17
- );
18
- TestBed.flushEffects();
19
- expect(sendSpy).toHaveBeenCalledWith(
20
- { type: 'Store Update' },
21
- { shop: { name: 'Car' } },
22
- );
23
- });
24
-
25
- it('should add multiple stores as feature stores', () => {
26
- const { sendSpy } = setupExtensions();
27
- for (const name of ['category', 'booking']) {
28
- TestBed.inject(signalStore({ providedIn: 'root' }, withDevtools(name)));
29
- }
30
- TestBed.flushEffects();
31
- expect(sendSpy).toHaveBeenLastCalledWith(
32
- { type: 'Store Update' },
33
- {
34
- category: {},
35
- booking: {},
36
- },
37
- );
38
- });
39
-
40
- it('should remove the state once destroyed', () => {
41
- const { sendSpy } = setupExtensions();
42
-
43
- const Store = signalStore(withDevtools('flight'));
44
- const childInjector = createEnvironmentInjector(
45
- [Store],
46
- TestBed.inject(EnvironmentInjector),
47
- );
48
-
49
- childInjector.get(Store);
50
- TestBed.flushEffects();
51
-
52
- expect(sendSpy).toHaveBeenCalledWith(
53
- { type: 'Store Update' },
54
- { flight: {} },
55
- );
56
-
57
- childInjector.destroy();
58
- TestBed.flushEffects();
59
- expect(sendSpy).toHaveBeenCalledWith({ type: 'Store Update' }, {});
60
- });
61
-
62
- it('should remove a renamed state once destroyed', () => {
63
- const { sendSpy } = setupExtensions();
64
-
65
- const Store = signalStore(withDevtools('flight'));
66
- const childInjector = createEnvironmentInjector(
67
- [Store],
68
- TestBed.inject(EnvironmentInjector),
69
- );
70
-
71
- const store = childInjector.get(Store);
72
- TestBed.flushEffects();
73
-
74
- expect(sendSpy).toHaveBeenCalledWith(
75
- { type: 'Store Update' },
76
- { flight: {} },
77
- );
78
-
79
- renameDevtoolsName(store, 'flights');
80
- childInjector.destroy();
81
- TestBed.flushEffects();
82
- expect(sendSpy).toHaveBeenCalledWith({ type: 'Store Update' }, {});
83
- });
84
-
85
- it('should group multiple patchState running before the synchronization', () => {
86
- const { sendSpy } = setupExtensions();
87
- const store = TestBed.inject(
88
- signalStore(
89
- { providedIn: 'root' },
90
- withDevtools('shop'),
91
- withState({ name: 'Car', amount: 0 }),
92
- withMethods((store) => ({
93
- increment() {
94
- patchState(store, (value) => ({
95
- ...value,
96
- amount: value.amount + 1,
97
- }));
98
- },
99
- })),
100
- ),
101
- );
102
-
103
- store.increment();
104
- store.increment();
105
- TestBed.flushEffects();
106
-
107
- expect(sendSpy.mock.calls).toEqual([
108
- [{ type: 'Store Update' }, { shop: { name: 'Car', amount: 2 } }],
109
- ]);
110
- });
111
- });
@@ -1,37 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { signalStore } from '@ngrx/signals';
3
- import { withDevtools } from '../with-devtools';
4
- import { setupExtensions } from './helpers.spec';
5
-
6
- describe('connect & send', () => {
7
- it('should connect', () => {
8
- const Store = signalStore({ providedIn: 'root' }, withDevtools('flight'));
9
- const { connectSpy } = setupExtensions();
10
- TestBed.inject(Store);
11
- expect(connectSpy).toHaveBeenCalledTimes(1);
12
- });
13
-
14
- it('should not connect if Redux Devtools are not available', () => {
15
- const { connectSpy } = setupExtensions(true, false);
16
- expect(connectSpy).toHaveBeenCalledTimes(0);
17
- });
18
-
19
- it('should not throw if it runs on the server', () => {
20
- setupExtensions(true, false);
21
- const Store = signalStore({ providedIn: 'root' }, withDevtools('flight'));
22
- expect(() => TestBed.inject(Store)).not.toThrow();
23
- });
24
-
25
- it('should only send when store is initialized', () => {
26
- const { sendSpy } = setupExtensions();
27
- expect(sendSpy).toHaveBeenCalledTimes(0);
28
-
29
- const Store = signalStore({ providedIn: 'root' }, withDevtools('flight'));
30
- TestBed.flushEffects();
31
- expect(sendSpy).toHaveBeenCalledTimes(0);
32
-
33
- TestBed.inject(Store);
34
- TestBed.flushEffects();
35
- expect(sendSpy).toHaveBeenCalledTimes(1);
36
- });
37
- });
@@ -1,43 +0,0 @@
1
- import { PLATFORM_ID } from '@angular/core';
2
- import { TestBed } from '@angular/core/testing';
3
-
4
- export type Flight = {
5
- id: number;
6
- from: string;
7
- to: string;
8
- date: Date;
9
- delayed: boolean;
10
- };
11
-
12
- export function setupExtensions(
13
- isPlatformBrowser = true,
14
- isExtensionAvailable = true,
15
- ) {
16
- const sendSpy = jest.fn();
17
- const connection = {
18
- send: sendSpy,
19
- };
20
- const connectSpy = jest.fn(() => connection);
21
-
22
- if (isExtensionAvailable) {
23
- window.__REDUX_DEVTOOLS_EXTENSION__ = { connect: connectSpy };
24
- }
25
-
26
- if (isPlatformBrowser) {
27
- TestBed.configureTestingModule({
28
- providers: [
29
- {
30
- provide: PLATFORM_ID,
31
- useValue: isPlatformBrowser ? 'browser' : 'server',
32
- },
33
- ],
34
- });
35
- }
36
-
37
- return { sendSpy, connectSpy };
38
- }
39
-
40
- it('should initialize', () => {
41
- const { connectSpy } = setupExtensions();
42
- expect(connectSpy).not.toHaveBeenCalled();
43
- });
@@ -1,216 +0,0 @@
1
- import {
2
- createEnvironmentInjector,
3
- EnvironmentInjector,
4
- inject,
5
- runInInjectionContext,
6
- } from '@angular/core';
7
- import { TestBed } from '@angular/core/testing';
8
- import { signalStore, withState } from '@ngrx/signals';
9
- import { withDisabledNameIndices } from '../features/with-disabled-name-indicies';
10
- import { renameDevtoolsName } from '../rename-devtools-name';
11
- import { withDevtools } from '../with-devtools';
12
- import { setupExtensions } from './helpers.spec';
13
-
14
- describe('withDevtools / renaming', () => {
15
- it('should automatically index multiple instances', () => {
16
- const { sendSpy } = setupExtensions();
17
- const Store = signalStore(
18
- { providedIn: 'root' },
19
- withDevtools('flights'),
20
- withState({ airline: 'Lufthansa' }),
21
- );
22
-
23
- const childContext = createEnvironmentInjector(
24
- [Store],
25
- TestBed.inject(EnvironmentInjector),
26
- );
27
-
28
- TestBed.inject(Store);
29
- runInInjectionContext(childContext, () => inject(Store));
30
-
31
- TestBed.flushEffects();
32
-
33
- expect(sendSpy).toHaveBeenLastCalledWith(
34
- { type: 'Store Update' },
35
- {
36
- flights: { airline: 'Lufthansa' },
37
- 'flights-1': { airline: 'Lufthansa' },
38
- },
39
- );
40
- });
41
-
42
- it('not index, if multiple instances do not exist simultaneously', () => {
43
- const { sendSpy } = setupExtensions();
44
- const Store = signalStore(
45
- withDevtools('flights'),
46
- withState({ airline: 'Lufthansa' }),
47
- );
48
-
49
- const envInjector = TestBed.inject(EnvironmentInjector);
50
- const childContext1 = createEnvironmentInjector([Store], envInjector);
51
- const childContext2 = createEnvironmentInjector([Store], envInjector);
52
-
53
- runInInjectionContext(childContext1, () => inject(Store));
54
- TestBed.flushEffects();
55
- childContext1.destroy();
56
-
57
- expect(sendSpy.mock.calls).toEqual([
58
- [
59
- { type: 'Store Update' },
60
- {
61
- flights: { airline: 'Lufthansa' },
62
- },
63
- ],
64
- ]);
65
-
66
- runInInjectionContext(childContext2, () => inject(Store));
67
- TestBed.flushEffects();
68
- expect(sendSpy.mock.calls).toEqual([
69
- [
70
- { type: 'Store Update' },
71
- {
72
- flights: { airline: 'Lufthansa' },
73
- },
74
- ],
75
- [
76
- { type: 'Store Update' },
77
- {
78
- flights: { airline: 'Lufthansa' },
79
- },
80
- ],
81
- ]);
82
- });
83
-
84
- it('should throw if automatic indexing is disabled', () => {
85
- setupExtensions();
86
- const Store = signalStore(
87
- { providedIn: 'root' },
88
- withDevtools('flights', withDisabledNameIndices()),
89
- withState({ airline: 'Lufthansa' }),
90
- );
91
-
92
- const childContext = createEnvironmentInjector(
93
- [Store],
94
- TestBed.inject(EnvironmentInjector),
95
- );
96
-
97
- TestBed.inject(Store);
98
- expect(() =>
99
- runInInjectionContext(childContext, () => inject(Store)),
100
- ).toThrow(
101
- `An instance of the store flights already exists. \
102
- Enable automatic indexing via withDevTools('flights', { indexNames: true }), or rename it upon instantiation.`,
103
- );
104
- });
105
-
106
- it('should index for two different stores with same devtools name', () => {
107
- const { sendSpy } = setupExtensions();
108
-
109
- TestBed.inject(
110
- signalStore({ providedIn: 'root' }, withDevtools('flights')),
111
- );
112
- TestBed.inject(
113
- signalStore({ providedIn: 'root' }, withDevtools('flights')),
114
- );
115
-
116
- TestBed.flushEffects();
117
- expect(sendSpy.mock.calls).toEqual([
118
- [
119
- { type: 'Store Update' },
120
- {
121
- flights: {},
122
- 'flights-1': {},
123
- },
124
- ],
125
- ]);
126
- });
127
-
128
- it('should throw for two different stores when indexing is disabled', () => {
129
- setupExtensions();
130
-
131
- TestBed.inject(
132
- signalStore({ providedIn: 'root' }, withDevtools('flights')),
133
- );
134
- expect(() =>
135
- TestBed.inject(
136
- signalStore(
137
- { providedIn: 'root' },
138
- withDevtools('flights', withDisabledNameIndices()),
139
- ),
140
- ),
141
- ).toThrow();
142
- });
143
-
144
- it('should not throw for two different stores if only the first one has indexing disabled', () => {
145
- setupExtensions();
146
-
147
- TestBed.inject(
148
- signalStore(
149
- { providedIn: 'root' },
150
- withDevtools('flights', withDisabledNameIndices()),
151
- ),
152
- );
153
- expect(() =>
154
- TestBed.inject(
155
- signalStore({ providedIn: 'root' }, withDevtools('flights')),
156
- ),
157
- ).not.toThrow();
158
- });
159
-
160
- describe('renaming', () => {
161
- it('should allow to rename the store before first sync', () => {
162
- const { sendSpy } = setupExtensions();
163
-
164
- const Store = signalStore(
165
- { providedIn: 'root' },
166
- withState({ name: 'Product', price: 10.5 }),
167
- withDevtools('flight'),
168
- );
169
-
170
- const store = TestBed.inject(Store);
171
- renameDevtoolsName(store, 'flights');
172
- TestBed.flushEffects();
173
-
174
- expect(sendSpy).toHaveBeenCalledWith(
175
- { type: 'Store Update' },
176
- { flights: { name: 'Product', price: 10.5 } },
177
- );
178
- });
179
-
180
- it('should throw on rename if name already exists', () => {
181
- setupExtensions();
182
- const Store1 = signalStore(
183
- { providedIn: 'root' },
184
- withState({ name: 'Product', price: 10.5 }),
185
- withDevtools('shop'),
186
- );
187
-
188
- const Store2 = signalStore(
189
- { providedIn: 'root' },
190
- withState({ name: 'Product', price: 10.5 }),
191
- withDevtools('mall'),
192
- );
193
- TestBed.inject(Store1);
194
- const store = TestBed.inject(Store2);
195
- TestBed.flushEffects();
196
-
197
- expect(() => renameDevtoolsName(store, 'shop')).toThrow(
198
- 'NgRx Toolkit/DevTools: cannot rename from mall to shop. shop is already assigned to another SignalStore instance.',
199
- );
200
- });
201
-
202
- it('should throw if applied to a SignalStore without DevTools', () => {
203
- setupExtensions();
204
- const Store = signalStore(
205
- { providedIn: 'root' },
206
- withState({ name: 'Product', price: 10.5 }),
207
- );
208
-
209
- const store = TestBed.inject(Store);
210
-
211
- expect(() => renameDevtoolsName(store, 'shop')).toThrow(
212
- "Devtools extensions haven't been added to this store.",
213
- );
214
- });
215
- });
216
- });
@@ -1,25 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { DevtoolsSyncer } from '../internal/devtools-syncer.service';
3
- import { provideDevtoolsConfig } from '../provide-devtools-config';
4
- import { setupExtensions } from './helpers.spec';
5
-
6
- describe('provideDevtoolsConfig', () => {
7
- it('DevtoolsSyncer should use the default configuration if none is provided', () => {
8
- const { connectSpy } = setupExtensions();
9
- TestBed.inject(DevtoolsSyncer);
10
- expect(connectSpy).toHaveBeenCalledWith({
11
- name: 'NgRx SignalStore',
12
- });
13
- });
14
-
15
- it('DevtoolsSyncer should use the configuration provided', () => {
16
- const { connectSpy } = setupExtensions();
17
- TestBed.configureTestingModule({
18
- providers: [provideDevtoolsConfig({ name: 'test' })],
19
- });
20
- TestBed.inject(DevtoolsSyncer);
21
- expect(connectSpy).toHaveBeenCalledWith({
22
- name: 'test',
23
- });
24
- });
25
- });
@@ -1,19 +0,0 @@
1
- import { computed } from '@angular/core';
2
- import { patchState, signalStore, withState } from '@ngrx/signals';
3
- import { withDevtools } from '../with-devtools';
4
-
5
- it('should compile when signalStore is extended from', () => {
6
- class CounterStore extends signalStore(
7
- { protectedState: false },
8
- withState({ count: 0 }),
9
- withDevtools('counter-store'),
10
- ) {
11
- readonly myReadonlyProp = 42;
12
-
13
- readonly doubleCount = computed(() => this.count() * 2);
14
-
15
- increment(): void {
16
- patchState(this, { count: this.count() + 1 });
17
- }
18
- }
19
- });
@@ -1,29 +0,0 @@
1
- import { signalStore, withMethods } from '@ngrx/signals';
2
- import { setAllEntities, withEntities } from '@ngrx/signals/entities';
3
- import { setLoaded, withCallState } from '../../with-call-state';
4
- import { updateState } from '../update-state';
5
-
6
- describe('updateState', () => {
7
- it('should work with multiple updaters', () => {
8
- interface Item {
9
- id: string;
10
- name: string;
11
- }
12
-
13
- signalStore(
14
- withEntities<Item>(),
15
- withCallState({ collection: 'items' }),
16
- withMethods((store) => ({
17
- loadItems() {
18
- // This should not cause a type error
19
- updateState(
20
- store,
21
- 'Items loaded successfully',
22
- setAllEntities([] as Item[]),
23
- setLoaded('items'),
24
- );
25
- },
26
- })),
27
- );
28
- });
29
- });
@@ -1,5 +0,0 @@
1
- describe('Devtools', () => {
2
- it.todo('should group multiple patchStates (glitch-free) in one action');
3
- it.todo('should allow time-travel (revert state via devtools');
4
- it.todo('should clear actionNames automatically onDestroy');
5
- });