@angular-architects/ngrx-toolkit 19.4.0 → 19.4.2

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 (128) 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 +2108 -0
  4. package/fesm2022/angular-architects-ngrx-toolkit.mjs.map +1 -0
  5. package/{src/index.ts → index.d.ts} +5 -32
  6. package/lib/assertions/assertions.d.ts +2 -0
  7. package/{src/lib/devtools/features/with-disabled-name-indicies.ts → lib/devtools/features/with-disabled-name-indicies.d.ts} +1 -5
  8. package/{src/lib/devtools/features/with-glitch-tracking.ts → lib/devtools/features/with-glitch-tracking.d.ts} +1 -6
  9. package/{src/lib/devtools/features/with-mapper.ts → lib/devtools/features/with-mapper.d.ts} +1 -7
  10. package/lib/devtools/internal/current-action-names.d.ts +1 -0
  11. package/lib/devtools/internal/default-tracker.d.ts +13 -0
  12. package/lib/devtools/internal/devtools-feature.d.ts +24 -0
  13. package/lib/devtools/internal/devtools-syncer.service.d.ts +39 -0
  14. package/lib/devtools/internal/glitch-tracker.service.d.ts +18 -0
  15. package/lib/devtools/internal/models.d.ts +24 -0
  16. package/{src/lib/devtools/provide-devtools-config.ts → lib/devtools/provide-devtools-config.d.ts} +4 -16
  17. package/lib/devtools/rename-devtools-name.d.ts +7 -0
  18. package/lib/devtools/update-state.d.ts +15 -0
  19. package/{src/lib/devtools/with-dev-tools-stub.ts → lib/devtools/with-dev-tools-stub.d.ts} +1 -2
  20. package/lib/devtools/with-devtools.d.ts +24 -0
  21. package/lib/flattening-operator.d.ts +14 -0
  22. package/lib/immutable-state/deep-freeze.d.ts +11 -0
  23. package/lib/immutable-state/is-dev-mode.d.ts +1 -0
  24. package/lib/immutable-state/with-immutable-state.d.ts +60 -0
  25. package/lib/mutation/http-mutation.d.ts +86 -0
  26. package/lib/mutation/mutation.d.ts +20 -0
  27. package/lib/mutation/rx-mutation.d.ts +76 -0
  28. package/{src/lib/shared/signal-store-models.ts → lib/shared/signal-store-models.d.ts} +4 -8
  29. package/lib/shared/throw-if-null.d.ts +1 -0
  30. package/lib/storage-sync/features/with-indexed-db.d.ts +2 -0
  31. package/lib/storage-sync/features/with-local-storage.d.ts +3 -0
  32. package/lib/storage-sync/internal/indexeddb.service.d.ts +29 -0
  33. package/lib/storage-sync/internal/local-storage.service.d.ts +8 -0
  34. package/lib/storage-sync/internal/models.d.ts +45 -0
  35. package/lib/storage-sync/internal/session-storage.service.d.ts +8 -0
  36. package/lib/storage-sync/with-storage-sync.d.ts +45 -0
  37. package/lib/with-call-state.d.ts +58 -0
  38. package/{src/lib/with-conditional.ts → lib/with-conditional.d.ts} +7 -31
  39. package/lib/with-data-service.d.ts +109 -0
  40. package/{src/lib/with-feature-factory.ts → lib/with-feature-factory.d.ts} +4 -32
  41. package/lib/with-mutations.d.ts +51 -0
  42. package/lib/with-pagination.d.ts +98 -0
  43. package/lib/with-redux.d.ts +147 -0
  44. package/lib/with-reset.d.ts +29 -0
  45. package/lib/with-undo-redo.d.ts +31 -0
  46. package/package.json +21 -4
  47. package/redux-connector/index.d.ts +2 -0
  48. package/redux-connector/src/lib/create-redux.d.ts +13 -0
  49. package/redux-connector/src/lib/model.d.ts +40 -0
  50. package/redux-connector/src/lib/rxjs-interop/redux-method.d.ts +14 -0
  51. package/redux-connector/src/lib/signal-redux-store.d.ts +11 -0
  52. package/redux-connector/src/lib/util.d.ts +5 -0
  53. package/eslint.config.cjs +0 -43
  54. package/jest.config.ts +0 -22
  55. package/ng-package.json +0 -7
  56. package/project.json +0 -37
  57. package/redux-connector/docs/README.md +0 -131
  58. package/redux-connector/index.ts +0 -6
  59. package/redux-connector/ng-package.json +0 -5
  60. package/redux-connector/src/lib/create-redux.ts +0 -102
  61. package/redux-connector/src/lib/model.ts +0 -89
  62. package/redux-connector/src/lib/rxjs-interop/redux-method.ts +0 -66
  63. package/redux-connector/src/lib/signal-redux-store.ts +0 -59
  64. package/redux-connector/src/lib/util.ts +0 -22
  65. package/src/lib/assertions/assertions.ts +0 -9
  66. package/src/lib/devtools/internal/current-action-names.ts +0 -1
  67. package/src/lib/devtools/internal/default-tracker.ts +0 -60
  68. package/src/lib/devtools/internal/devtools-feature.ts +0 -37
  69. package/src/lib/devtools/internal/devtools-syncer.service.ts +0 -202
  70. package/src/lib/devtools/internal/glitch-tracker.service.ts +0 -61
  71. package/src/lib/devtools/internal/models.ts +0 -29
  72. package/src/lib/devtools/rename-devtools-name.ts +0 -21
  73. package/src/lib/devtools/tests/action-name.spec.ts +0 -48
  74. package/src/lib/devtools/tests/basic.spec.ts +0 -111
  75. package/src/lib/devtools/tests/connecting.spec.ts +0 -37
  76. package/src/lib/devtools/tests/helpers.spec.ts +0 -43
  77. package/src/lib/devtools/tests/naming.spec.ts +0 -216
  78. package/src/lib/devtools/tests/provide-devtools-config.spec.ts +0 -25
  79. package/src/lib/devtools/tests/types.spec.ts +0 -19
  80. package/src/lib/devtools/tests/update-state.spec.ts +0 -29
  81. package/src/lib/devtools/tests/with-devtools.spec.ts +0 -5
  82. package/src/lib/devtools/tests/with-glitch-tracking.spec.ts +0 -272
  83. package/src/lib/devtools/tests/with-mapper.spec.ts +0 -69
  84. package/src/lib/devtools/update-state.ts +0 -38
  85. package/src/lib/devtools/with-devtools.ts +0 -81
  86. package/src/lib/flattening-operator.ts +0 -42
  87. package/src/lib/immutable-state/deep-freeze.ts +0 -43
  88. package/src/lib/immutable-state/is-dev-mode.ts +0 -6
  89. package/src/lib/immutable-state/tests/with-immutable-state.spec.ts +0 -260
  90. package/src/lib/immutable-state/with-immutable-state.ts +0 -115
  91. package/src/lib/mutation/http-mutation.spec.ts +0 -473
  92. package/src/lib/mutation/http-mutation.ts +0 -172
  93. package/src/lib/mutation/mutation.ts +0 -26
  94. package/src/lib/mutation/rx-mutation.spec.ts +0 -594
  95. package/src/lib/mutation/rx-mutation.ts +0 -208
  96. package/src/lib/shared/prettify.ts +0 -3
  97. package/src/lib/shared/throw-if-null.ts +0 -7
  98. package/src/lib/storage-sync/features/with-indexed-db.ts +0 -81
  99. package/src/lib/storage-sync/features/with-local-storage.ts +0 -58
  100. package/src/lib/storage-sync/internal/indexeddb.service.ts +0 -124
  101. package/src/lib/storage-sync/internal/local-storage.service.ts +0 -19
  102. package/src/lib/storage-sync/internal/models.ts +0 -62
  103. package/src/lib/storage-sync/internal/session-storage.service.ts +0 -18
  104. package/src/lib/storage-sync/tests/indexeddb.service.spec.ts +0 -99
  105. package/src/lib/storage-sync/tests/with-storage-async.spec.ts +0 -308
  106. package/src/lib/storage-sync/tests/with-storage-sync.spec.ts +0 -268
  107. package/src/lib/storage-sync/with-storage-sync.ts +0 -233
  108. package/src/lib/with-call-state.spec.ts +0 -42
  109. package/src/lib/with-call-state.ts +0 -195
  110. package/src/lib/with-conditional.spec.ts +0 -125
  111. package/src/lib/with-data-service.spec.ts +0 -564
  112. package/src/lib/with-data-service.ts +0 -433
  113. package/src/lib/with-feature-factory.spec.ts +0 -69
  114. package/src/lib/with-mutations.spec.ts +0 -537
  115. package/src/lib/with-mutations.ts +0 -146
  116. package/src/lib/with-pagination.spec.ts +0 -90
  117. package/src/lib/with-pagination.ts +0 -353
  118. package/src/lib/with-redux.spec.ts +0 -258
  119. package/src/lib/with-redux.ts +0 -387
  120. package/src/lib/with-reset.spec.ts +0 -112
  121. package/src/lib/with-reset.ts +0 -62
  122. package/src/lib/with-undo-redo.spec.ts +0 -287
  123. package/src/lib/with-undo-redo.ts +0 -199
  124. package/src/test-setup.ts +0 -8
  125. package/tsconfig.json +0 -29
  126. package/tsconfig.lib.json +0 -17
  127. package/tsconfig.lib.prod.json +0 -9
  128. package/tsconfig.spec.json +0 -17
@@ -1,308 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { getState, patchState, signalStore, withState } from '@ngrx/signals';
3
- import 'fake-indexeddb/auto';
4
- import { withIndexedDB } from '../features/with-indexed-db';
5
- import { IndexedDBService } from '../internal/indexeddb.service';
6
- import { withStorageSync } from '../with-storage-sync';
7
-
8
- interface StateObject {
9
- foo: string;
10
- age: number;
11
- }
12
-
13
- const initialState: StateObject = {
14
- foo: 'bar',
15
- age: 18,
16
- };
17
- const key = 'FooBar';
18
-
19
- const waitForSyncStable = async (store: {
20
- whenSynced?: () => Promise<void>;
21
- }) => {
22
- if (store.whenSynced) {
23
- await store.whenSynced();
24
- }
25
- };
26
-
27
- describe('withStorageSync (async storage)', () => {
28
- beforeEach(() => {
29
- // make sure to start with a clean storage
30
- globalThis.indexedDB = new IDBFactory();
31
- });
32
-
33
- it('adds methods for storage access to the store', () => {
34
- TestBed.runInInjectionContext(() => {
35
- const Store = signalStore(withStorageSync({ key }, withIndexedDB()));
36
- const store = new Store();
37
-
38
- expect(Object.keys(store)).toEqual([
39
- 'isSynced',
40
- 'whenSynced',
41
- 'clearStorage',
42
- 'readFromStorage',
43
- 'writeToStorage',
44
- ]);
45
- });
46
- });
47
-
48
- it('offers manual sync using provided methods', async () => {
49
- TestBed.runInInjectionContext(async () => {
50
- // prefill storage
51
- const indexedDBService = TestBed.inject(IndexedDBService);
52
- await indexedDBService.setItem(
53
- key,
54
- JSON.stringify({
55
- foo: 'baz',
56
- age: 99,
57
- }),
58
- );
59
-
60
- const Store = signalStore(
61
- { protectedState: false },
62
- withStorageSync({ key, autoSync: false }, withIndexedDB()),
63
- );
64
- const store = TestBed.inject(Store);
65
- await waitForSyncStable(store);
66
-
67
- expect(getState(store)).toEqual({});
68
-
69
- await store.readFromStorage();
70
-
71
- expect(getState(store)).toEqual({
72
- foo: 'baz',
73
- age: 99,
74
- });
75
-
76
- patchState(store, { ...initialState });
77
- await waitForSyncStable(store);
78
-
79
- expect(await indexedDBService.getItem(key)).toEqual({
80
- foo: 'baz',
81
- age: 99,
82
- });
83
-
84
- await store.writeToStorage();
85
- expect(await indexedDBService.getItem(key)).toEqual({
86
- ...initialState,
87
- });
88
-
89
- await store.clearStorage();
90
- expect(await indexedDBService.getItem(key)).toEqual(null);
91
- });
92
- });
93
-
94
- describe('autoSync', () => {
95
- it('inits from storage and write to storage on changes when set to `true`', async () => {
96
- const indexedDBService = TestBed.inject(IndexedDBService);
97
- // prefill storage
98
- await indexedDBService.setItem(
99
- key,
100
- JSON.stringify({
101
- foo: 'baz',
102
- age: 99,
103
- } as StateObject),
104
- );
105
-
106
- const Store = signalStore(
107
- { providedIn: 'root', protectedState: false },
108
- withStorageSync(key, withIndexedDB()),
109
- );
110
-
111
- const store = TestBed.inject(Store);
112
- await waitForSyncStable(store);
113
- expect(getState(store)).toEqual({
114
- foo: 'baz',
115
- age: 99,
116
- });
117
-
118
- patchState(store, { ...initialState });
119
- await waitForSyncStable(store);
120
-
121
- expect(getState(store)).toEqual({
122
- ...initialState,
123
- });
124
-
125
- expect(await indexedDBService.getItem(key)).toEqual(
126
- JSON.stringify(initialState),
127
- );
128
- });
129
-
130
- it('does not init from storage and does write to storage on changes when set to `false`', async () => {
131
- const indexedDBService = TestBed.inject(IndexedDBService);
132
- await indexedDBService.setItem(
133
- key,
134
- JSON.stringify({
135
- foo: 'baz',
136
- age: 99,
137
- }),
138
- );
139
-
140
- const Store = signalStore(
141
- { providedIn: 'root', protectedState: false },
142
- withStorageSync({ key, autoSync: false }, withIndexedDB()),
143
- );
144
- const store = TestBed.inject(Store);
145
- expect(store.isSynced()).toBe(false);
146
- expect(getState(store)).toEqual({});
147
-
148
- patchState(store, { ...initialState });
149
- expect(store.isSynced()).toBe(false);
150
-
151
- const storeItem = JSON.parse(
152
- (await indexedDBService.getItem(key)) || '{}',
153
- );
154
- expect(storeItem).toEqual({
155
- foo: 'baz',
156
- age: 99,
157
- });
158
- });
159
- });
160
-
161
- describe('select', () => {
162
- it('syncs the whole state by default', async () => {
163
- const indexedDBService = TestBed.inject(IndexedDBService);
164
- const Store = signalStore(
165
- { providedIn: 'root', protectedState: false },
166
- withStorageSync(key, withIndexedDB()),
167
- );
168
- const store = TestBed.inject(Store);
169
- await waitForSyncStable(store);
170
-
171
- patchState(store, { ...initialState });
172
- await waitForSyncStable(store);
173
-
174
- expect(await indexedDBService.getItem(key)).toEqual(
175
- JSON.stringify(initialState),
176
- );
177
- });
178
-
179
- it('syncs selected slices when specified', async () => {
180
- const indexedDBService = TestBed.inject(IndexedDBService);
181
- const Store = signalStore(
182
- { providedIn: 'root', protectedState: false },
183
- withState(initialState),
184
- withStorageSync(
185
- { key, select: ({ foo }) => ({ foo }) },
186
- withIndexedDB(),
187
- ),
188
- );
189
- const store = TestBed.inject(Store);
190
- await waitForSyncStable(store);
191
-
192
- patchState(store, { foo: 'baz' });
193
- await waitForSyncStable(store);
194
-
195
- const storeItem = JSON.parse(
196
- (await indexedDBService.getItem(key)) || '{}',
197
- );
198
- expect(storeItem).toEqual({
199
- foo: 'baz',
200
- });
201
- });
202
- });
203
-
204
- describe('parse/stringify', () => {
205
- it('uses custom parsing/stringification when specified', async () => {
206
- const indexedDBService = TestBed.inject(IndexedDBService);
207
- const parse = (stateString: string) => {
208
- const [foo, age] = stateString.split('_');
209
- return {
210
- foo,
211
- age: +age,
212
- };
213
- };
214
-
215
- const Store = signalStore(
216
- { providedIn: 'root', protectedState: false },
217
- withState(initialState),
218
- withStorageSync(
219
- {
220
- key,
221
- parse,
222
- stringify: (state) => `${state.foo}_${state.age}`,
223
- },
224
- withIndexedDB(),
225
- ),
226
- );
227
-
228
- const store = TestBed.inject(Store);
229
- await waitForSyncStable(store);
230
- patchState(store, { foo: 'baz' });
231
- await waitForSyncStable(store);
232
-
233
- const storeItem = parse((await indexedDBService.getItem(key)) || '');
234
- expect(storeItem).toEqual({
235
- ...initialState,
236
- foo: 'baz',
237
- });
238
- });
239
- });
240
-
241
- describe('withStorageSync', () => {
242
- let warnings = [] as string[];
243
-
244
- jest.spyOn(console, 'warn').mockImplementation((...messages: string[]) => {
245
- warnings.push(...messages);
246
- });
247
-
248
- beforeEach(() => {
249
- warnings = [];
250
- });
251
-
252
- it('logs when writing happens before state is synchronized', async () => {
253
- const Store = signalStore(
254
- { providedIn: 'root', protectedState: false },
255
- withState({ name: 'Delta', age: 52 }),
256
- withStorageSync('flights', withIndexedDB()),
257
- );
258
- const store = TestBed.inject(Store);
259
-
260
- expect(warnings).toEqual([]);
261
- patchState(store, { name: 'Lufthansa', age: 27 });
262
- expect(warnings).toEqual([
263
- 'Writing to Store (flights) happened before the state was initially read from storage.',
264
- 'Please ensure that the store is not in syncing state via `store.whenSynced()` before writing to the state.',
265
- 'Alternatively, you can disable autoSync by passing `autoSync: false` in the config.',
266
- ]);
267
- });
268
-
269
- it('warns when reading happens during a write', async () => {
270
- console.log('starting test');
271
- const Store = signalStore(
272
- { providedIn: 'root', protectedState: false },
273
- withState({ name: 'Delta', age: 52 }),
274
- withStorageSync('flights', withIndexedDB()),
275
- );
276
-
277
- const store = TestBed.inject(Store);
278
- await waitForSyncStable(store);
279
- patchState(store, { name: 'Lufthansa', age: 27 });
280
- store.readFromStorage();
281
-
282
- expect(warnings).toEqual([
283
- 'Reading to Store (flights) happened during an ongoing synchronization process.',
284
- 'Please ensure that the store is not in syncing state via `store.whenSynced()`.',
285
- 'Alternatively, you can disable the autoSync by passing `autoSync: false` in the config.',
286
- ]);
287
- });
288
-
289
- it('warns when writing happens during a read', async () => {
290
- const Store = signalStore(
291
- { providedIn: 'root', protectedState: false },
292
- withState({ name: 'Delta', age: 52 }),
293
- withStorageSync('flights', withIndexedDB()),
294
- );
295
-
296
- const store = TestBed.inject(Store);
297
- await waitForSyncStable(store);
298
-
299
- store.readFromStorage();
300
- patchState(store, { name: 'Lufthansa', age: 27 });
301
- expect(warnings).toEqual([
302
- 'Writing to Store (flights) happened during an ongoing synchronization process.',
303
- 'Please ensure that the store is not in syncing state via `store.whenSynced()`.',
304
- 'Alternatively, you can disable the autoSync by passing `autoSync: false` in the config.',
305
- ]);
306
- });
307
- });
308
- });
@@ -1,268 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { getState, patchState, signalStore, withState } from '@ngrx/signals';
3
- import { withLocalStorage } from '../features/with-local-storage';
4
- import { withStorageSync } from '../with-storage-sync';
5
-
6
- interface StateObject {
7
- foo: string;
8
- age: number;
9
- }
10
-
11
- const initialState: StateObject = {
12
- foo: 'bar',
13
- age: 18,
14
- };
15
- const key = 'FooBar';
16
-
17
- describe('withStorageSync (sync storage)', () => {
18
- beforeEach(() => {
19
- // make sure to start with a clean storage
20
- localStorage.removeItem(key);
21
- });
22
-
23
- it('adds methods for storage access to the store', () => {
24
- TestBed.runInInjectionContext(() => {
25
- const Store = signalStore(withStorageSync({ key }));
26
- const store = new Store();
27
-
28
- expect(Object.keys(store)).toEqual([
29
- 'clearStorage',
30
- 'readFromStorage',
31
- 'writeToStorage',
32
- ]);
33
- });
34
- });
35
-
36
- it('offers manual sync using provided methods', () => {
37
- TestBed.runInInjectionContext(() => {
38
- // prefill storage
39
- localStorage.setItem(
40
- key,
41
- JSON.stringify({
42
- foo: 'baz',
43
- age: 99,
44
- } as StateObject),
45
- );
46
-
47
- const Store = signalStore(
48
- { protectedState: false },
49
- withStorageSync({ key, autoSync: false }),
50
- );
51
- const store = new Store();
52
- expect(getState(store)).toEqual({});
53
-
54
- store.readFromStorage();
55
- expect(getState(store)).toEqual({
56
- foo: 'baz',
57
- age: 99,
58
- });
59
-
60
- patchState(store, { ...initialState });
61
- TestBed.flushEffects();
62
-
63
- let storeItem = JSON.parse(localStorage.getItem(key) || '{}');
64
- expect(storeItem).toEqual({
65
- foo: 'baz',
66
- age: 99,
67
- });
68
-
69
- store.writeToStorage();
70
- storeItem = JSON.parse(localStorage.getItem(key) || '{}');
71
- expect(storeItem).toEqual({
72
- ...initialState,
73
- });
74
-
75
- store.clearStorage();
76
- storeItem = localStorage.getItem(key);
77
- expect(storeItem).toEqual(null);
78
- });
79
- });
80
-
81
- describe('autoSync', () => {
82
- it('inits from storage and write to storage on changes when set to `true`', () => {
83
- TestBed.runInInjectionContext(() => {
84
- // prefill storage
85
- localStorage.setItem(
86
- key,
87
- JSON.stringify({
88
- foo: 'baz',
89
- age: 99,
90
- } as StateObject),
91
- );
92
-
93
- const Store = signalStore(
94
- { protectedState: false },
95
- withStorageSync(key),
96
- );
97
- const store = new Store();
98
- expect(getState(store)).toEqual({
99
- foo: 'baz',
100
- age: 99,
101
- });
102
-
103
- patchState(store, { ...initialState });
104
- TestBed.flushEffects();
105
-
106
- expect(getState(store)).toEqual({
107
- ...initialState,
108
- });
109
- const storeItem = JSON.parse(localStorage.getItem(key) || '{}');
110
- expect(storeItem).toEqual({
111
- ...initialState,
112
- });
113
- });
114
- });
115
-
116
- it('does not init from storage and does write to storage on changes when set to `false`', () => {
117
- TestBed.runInInjectionContext(() => {
118
- // prefill storage
119
- localStorage.setItem(
120
- key,
121
- JSON.stringify({
122
- foo: 'baz',
123
- age: 99,
124
- } as StateObject),
125
- );
126
-
127
- const Store = signalStore(
128
- { protectedState: false },
129
- withStorageSync({ key, autoSync: false }),
130
- );
131
- const store = new Store();
132
- expect(getState(store)).toEqual({});
133
-
134
- patchState(store, { ...initialState });
135
- const storeItem = JSON.parse(localStorage.getItem(key) || '{}');
136
- expect(storeItem).toEqual({
137
- foo: 'baz',
138
- age: 99,
139
- });
140
- });
141
- });
142
- });
143
-
144
- describe('select', () => {
145
- it('syncs the whole state by default', () => {
146
- TestBed.runInInjectionContext(() => {
147
- const Store = signalStore(
148
- { protectedState: false },
149
- withStorageSync(key),
150
- );
151
- const store = new Store();
152
-
153
- patchState(store, { ...initialState });
154
- TestBed.flushEffects();
155
-
156
- const storeItem = JSON.parse(localStorage.getItem(key) || '{}');
157
- expect(storeItem).toEqual({
158
- ...initialState,
159
- });
160
- });
161
- });
162
-
163
- it('syncs selected slices when specified', () => {
164
- TestBed.runInInjectionContext(() => {
165
- const Store = signalStore(
166
- { protectedState: false },
167
- withState(initialState),
168
- withStorageSync({ key, select: ({ foo }) => ({ foo }) }),
169
- );
170
- const store = new Store();
171
-
172
- patchState(store, { foo: 'baz' });
173
- TestBed.flushEffects();
174
-
175
- const storeItem = JSON.parse(localStorage.getItem(key) || '{}');
176
- expect(storeItem).toEqual({
177
- foo: 'baz',
178
- });
179
- });
180
- });
181
- });
182
-
183
- describe('parse/stringify', () => {
184
- it('uses custom parsing/stringification when specified', () => {
185
- const parse = (stateString: string) => {
186
- const [foo, age] = stateString.split('_');
187
- return {
188
- foo,
189
- age: +age,
190
- };
191
- };
192
-
193
- TestBed.runInInjectionContext(() => {
194
- const Store = signalStore(
195
- { protectedState: false },
196
- withState(initialState),
197
- withStorageSync({
198
- key,
199
- parse,
200
- stringify: (state) => `${state.foo}_${state.age}`,
201
- }),
202
- );
203
- const store = new Store();
204
-
205
- patchState(store, { foo: 'baz' });
206
- TestBed.flushEffects();
207
-
208
- const storeItem = parse(localStorage.getItem(key) || '');
209
- expect(storeItem).toEqual({
210
- ...initialState,
211
- foo: 'baz',
212
- });
213
- });
214
- });
215
- });
216
-
217
- describe('storage factory', () => {
218
- it('should throw an error when both config and storage strategy are provided', () => {
219
- const signalStoreFactory = () =>
220
- signalStore(
221
- withStorageSync(
222
- { key: 'foo', storage: () => localStorage },
223
- withLocalStorage(),
224
- ),
225
- );
226
-
227
- expect(signalStoreFactory).toThrow(
228
- 'You can either pass a storage strategy or a config with storage, but not both.',
229
- );
230
- });
231
-
232
- it('uses specified storage', () => {
233
- TestBed.runInInjectionContext(() => {
234
- // prefill storage
235
- sessionStorage.setItem(
236
- key,
237
- JSON.stringify({
238
- foo: 'baz',
239
- age: 99,
240
- } as StateObject),
241
- );
242
-
243
- const Store = signalStore(
244
- { protectedState: false },
245
- withStorageSync({ key, storage: () => sessionStorage }),
246
- );
247
- const store = new Store();
248
- expect(getState(store)).toEqual({
249
- foo: 'baz',
250
- age: 99,
251
- });
252
-
253
- patchState(store, { ...initialState });
254
- TestBed.flushEffects();
255
-
256
- expect(getState(store)).toEqual({
257
- ...initialState,
258
- });
259
- const storeItem = JSON.parse(sessionStorage.getItem(key) || '{}');
260
- expect(storeItem).toEqual({
261
- ...initialState,
262
- });
263
-
264
- store.clearStorage();
265
- });
266
- });
267
- });
268
- });