Skip to content

Commit 6256b3f

Browse files
committed
feat(with-storage-sync): enhance storage sync with local and indexedDB support
1 parent 6be5040 commit 6256b3f

File tree

8 files changed

+49
-54
lines changed

8 files changed

+49
-54
lines changed
Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
1-
import { patchState, signalStore, withHooks, withMethods } from '@ngrx/signals';
1+
import { patchState, signalStore, withMethods } from '@ngrx/signals';
22
import {
3-
withEntities,
4-
setEntity,
53
removeEntity,
4+
setEntity,
65
updateEntity,
6+
withEntities,
77
} from '@ngrx/signals/entities';
8-
import { inject } from '@angular/core';
9-
import { Todo, TodoService, AddTodo } from '../shared/todo.service';
8+
import { AddTodo, Todo } from '../shared/todo.service';
9+
import {
10+
withIndexeddb,
11+
withStorageSync,
12+
} from '@angular-architects/ngrx-toolkit';
1013

1114
export const SyncedTodoStore = signalStore(
1215
{ providedIn: 'root' },
1316
withEntities<Todo>(),
14-
// todo
15-
// withStorageSync({
16-
// storageType: 'indexedDB',
17-
// dbName: 'todos',
18-
// storeName: 'todos',
19-
// }),
17+
withStorageSync(
18+
{
19+
key: 'todos-indexeddb',
20+
},
21+
withIndexeddb()
22+
),
2023
withMethods((store) => {
2124
let currentId = 0;
2225
return {
@@ -36,11 +39,11 @@ export const SyncedTodoStore = signalStore(
3639
);
3740
},
3841
};
39-
}),
40-
withHooks({
41-
onInit(store, todoService = inject(TodoService)) {
42-
const todos = todoService.getData();
43-
todos.forEach((todo) => store.add(todo));
44-
},
4542
})
43+
//withHooks({
44+
// onInit(store, todoService = inject(TodoService)) {
45+
// const todos = todoService.getData();
46+
// todos.forEach((todo) => store.add(todo));
47+
// },
48+
//})
4649
);

apps/demo/src/app/todo-indexeddb-sync/todo-indexeddb-sync.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Todo } from '../shared/todo.service';
1111
imports: [MatCheckboxModule, MatIconModule, MatTableModule],
1212
templateUrl: './todo-indexeddb-sync.component.html',
1313
styleUrl: './todo-indexeddb-sync.component.scss',
14+
standalone: true,
1415
})
1516
export class TodoIndexeddbSyncComponent {
1617
todoStore = inject(SyncedTodoStore);
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
import { patchState, signalStore, withMethods } from '@ngrx/signals';
1+
import { patchState, signalStore, withHooks, withMethods } from '@ngrx/signals';
22
import {
3-
withEntities,
4-
setEntity,
53
removeEntity,
4+
setEntity,
65
updateEntity,
6+
withEntities,
77
} from '@ngrx/signals/entities';
88
import { withStorageSync } from '@angular-architects/ngrx-toolkit';
9-
import { Todo, AddTodo } from '../shared/todo.service';
9+
import { AddTodo, Todo, TodoService } from '../shared/todo.service';
10+
import { inject } from '@angular/core';
1011

1112
export const SyncedTodoStore = signalStore(
1213
{ providedIn: 'root' },
1314
withEntities<Todo>(),
14-
withStorageSync({
15-
key: 'todos',
16-
}),
1715
withMethods((store) => {
1816
let currentId = 0;
1917
return {
@@ -33,11 +31,14 @@ export const SyncedTodoStore = signalStore(
3331
);
3432
},
3533
};
34+
}),
35+
withHooks({
36+
onInit(store, todoService = inject(TodoService)) {
37+
const todos = todoService.getData();
38+
todos.forEach((todo) => store.add(todo));
39+
},
40+
}),
41+
withStorageSync({
42+
key: 'todos',
3643
})
37-
//withHooks({
38-
// onInit(store, todoService = inject(TodoService)) {
39-
// const todos = todoService.getData();
40-
// todos.forEach((todo) => store.add(todo));
41-
// },
42-
//})
4344
);
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
import { IndexedDBService } from '../internal/indexeddb.service';
2-
import { StorageServiceFactory } from '../internal/storage.service';
32

4-
export const withIndexeddb: () => StorageServiceFactory = () => {
5-
return () => IndexedDBService;
6-
};
3+
export const withIndexeddb = () => IndexedDBService;
Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { StorageServiceFactory } from '../internal/storage.service';
21
import { LocalStorageService } from '../internal/local-storage.service';
32

4-
export const withLocalStorage: () => StorageServiceFactory = () => {
5-
return () => LocalStorageService;
6-
};
3+
export const withLocalStorage = () => LocalStorageService;
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { StorageServiceFactory } from '../internal/storage.service';
21
import { SessionStorageService } from '../internal/session-storage.service';
32

4-
export const withSessionStorage: () => StorageServiceFactory = () => {
3+
export const withSessionStorage = () => {
54
return () => SessionStorageService;
65
};

libs/ngrx-toolkit/src/lib/storage-sync/internal/storage.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ export interface StorageService {
66
setItem(key: string, data: string): Promise<void>;
77
}
88

9-
export type StorageServiceFactory = () => Type<StorageService>;
9+
export type StorageServiceFactory = Type<StorageService>;

libs/ngrx-toolkit/src/lib/with-storage-sync.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
import { isPlatformServer } from '@angular/common';
22
import {
3-
PLATFORM_ID,
43
effect,
5-
inject,
64
EnvironmentInjector,
5+
inject,
6+
PLATFORM_ID,
77
runInInjectionContext,
88
} from '@angular/core';
99
import {
10-
SignalStoreFeature,
10+
EmptyFeatureResult,
1111
getState,
1212
patchState,
1313
signalStoreFeature,
14+
SignalStoreFeature,
15+
SignalStoreFeatureResult,
1416
withHooks,
1517
withMethods,
16-
SignalStoreFeatureResult,
17-
EmptyFeatureResult,
1818
} from '@ngrx/signals';
19-
import { withIndexeddb } from './storage-sync/features/with-indexeddb';
2019
import { StorageServiceFactory } from './storage-sync/internal/storage.service';
20+
import { withLocalStorage } from './storage-sync/features/with-local-storage';
2121

2222
const NOOP = () => Promise.resolve();
2323

@@ -98,15 +98,14 @@ export function withStorageSync<
9898
Input extends SignalStoreFeatureResult
9999
>(
100100
configOrKey: SyncConfig<Input['state']> | string,
101-
StorageServiceClass: StorageServiceFactory = withIndexeddb()
101+
StorageServiceClass: StorageServiceFactory = withLocalStorage()
102102
): SignalStoreFeature<Input, WithStorageSyncFeatureResult> {
103103
const {
104104
key,
105105
autoSync = true,
106106
select = (state: State) => state,
107107
parse = JSON.parse,
108108
stringify = JSON.stringify,
109-
storage: storageFactory = () => localStorage,
110109
} = typeof configOrKey === 'string' ? { key: configOrKey } : configOrKey;
111110

112111
return signalStoreFeature(
@@ -123,20 +122,18 @@ export function withStorageSync<
123122
return StorageSyncStub;
124123
}
125124

126-
const storage = storageFactory();
127-
128125
return {
129126
/**
130127
* Removes the item stored in storage.
131128
*/
132129
async clearStorage(): Promise<void> {
133-
storage.removeItem(key);
130+
await storageService.clear(key);
134131
},
135132
/**
136133
* Reads item from storage and patches the state.
137134
*/
138135
async readFromStorage(): Promise<void> {
139-
const stateString = storage.getItem(key);
136+
const stateString = await storageService.getItem(key);
140137
if (stateString) {
141138
patchState(store, parse(stateString));
142139
}
@@ -146,7 +143,7 @@ export function withStorageSync<
146143
*/
147144
async writeToStorage(): Promise<void> {
148145
const slicedState = select(getState(store) as State);
149-
storage.setItem(key, stringify(slicedState));
146+
await storageService.setItem(key, stringify(slicedState));
150147
},
151148
};
152149
}

0 commit comments

Comments
 (0)