diff --git a/projects/ngrx-extension/src/lib/with-indexdb-sync/with-indexdb-sync.ts b/projects/ngrx-extension/src/lib/with-indexdb-sync/with-indexdb-sync.ts index e656272c..cf44036f 100644 --- a/projects/ngrx-extension/src/lib/with-indexdb-sync/with-indexdb-sync.ts +++ b/projects/ngrx-extension/src/lib/with-indexdb-sync/with-indexdb-sync.ts @@ -1,5 +1,6 @@ import { type TNodeItem, + readDfs, writeDfs, } from '@/projects/ngrx-extension/src/lib/helpers/graph'; import { effect } from '@angular/core'; @@ -13,18 +14,24 @@ import { rxMethod } from '@ngrx/signals/rxjs-interop'; import Dexie from 'dexie'; import { pipe, tap } from 'rxjs'; -export type IndexDBModel = { +export type IndexDBModel< + Table extends string, + ObjectState extends Partial<{ [key in Table]: unknown }>, +> = { dbName: string; version?: number; sync?: boolean; - prefix?: string; nodes: TNodeItem[]; writeCallback: Partial<{ [key in Table]: ({ db, key, targetState, - }: { db: Dexie; key: string; targetState: unknown }) => Promise; + }: { + db: Dexie; + key: string; + targetState: ObjectState[key]; + }) => Promise; }>; stores: { [key in Table]: string }; }; @@ -42,15 +49,17 @@ export const baseWriteCallback = async ( await db.table(key).put(targetState); }; -export function withIndexDBSync
({ +export function withIndexDBSync< + Table extends string, + ObjectState extends Partial<{ [key in Table]: unknown }>, +>({ dbName, version = 1, sync = true, nodes = [], - prefix = '', writeCallback, stores, -}: IndexDBModel
) { +}: IndexDBModel) { const db = new Dexie(dbName); db.version(version).stores(stores); @@ -65,11 +74,11 @@ export function withIndexDBSync
({ writeDfs( currentState, nodes, - prefix, + '', async (key, _fullKeyPath, objectState) => { - const targetState = (objectState as Record)[ - key - ]; + const targetState: ObjectState[Table] = ( + objectState as Record + )[key]; if (Object.hasOwn(writeCallback, key)) { // fixme key type check @@ -86,13 +95,19 @@ export function withIndexDBSync
({ readFromStorage: rxMethod( pipe( tap(() => { - db.table('users').toArray(); + readDfs(nodes, '', async (fullKeyPath) => { + const data = await db.table(fullKeyPath).toArray(); + + console.log('data', data); + }); }), ), ), })), withHooks({ onInit: (store) => { + store.readFromStorage({}); + if (sync) { effect(() => ((_) => { diff --git a/src/app/pages/with-indexdb-sync/with-indexdb-sync.component.ts b/src/app/pages/with-indexdb-sync/with-indexdb-sync.component.ts index 400e8b76..e212855f 100644 --- a/src/app/pages/with-indexdb-sync/with-indexdb-sync.component.ts +++ b/src/app/pages/with-indexdb-sync/with-indexdb-sync.component.ts @@ -1,34 +1,70 @@ import { withIndexDBSync } from '@/projects/ngrx-extension/src/lib/with-indexdb-sync/with-indexdb-sync'; import { Component, inject } from '@angular/core'; -import { signalStore, withState } from '@ngrx/signals'; +import { faker } from '@faker-js/faker'; +import { patchState, signalStore, withMethods, withState } from '@ngrx/signals'; const UserSignalStore = signalStore( withState<{ - users: { name: string; age: number }[]; + users: { id: number; name: string; age: number }[]; tasks: { title: string; subTitle: string }; }>({ users: [ { + id: 1, name: 'mzkmnk', age: 14, }, + { + id: 2, + name: 'mnk', + age: 21, + }, ], tasks: { title: 'task1', subTitle: 'subtask1', }, }), - withIndexDBSync<'users' | 'tasks'>({ + withIndexDBSync< + 'users' | 'tasks', + { + users: { id: number; name: string; age: number }[]; + tasks: { title: string; subTitle: string }; + } + >({ dbName: 'withIndexDBSync', nodes: ['users', 'tasks'], - writeCallback: { - users: async ({ db, key, targetState }) => {}, - }, stores: { - users: '++id', + users: 'id', tasks: '++id, title, subTitle', }, + writeCallback: { + users: async ({ db, key, targetState }) => { + db.table(key).bulkPut(targetState); + }, + tasks: async ({ db, key, targetState }) => { + db.table(key).put(targetState); + }, + }, }), + + withMethods((store) => ({ + editUser(idx: number) { + patchState(store, (state) => ({ + ...state, + users: state.users.map((user) => { + if (user.id === idx) { + return { + name: faker.person.firstName(), + age: 10, + id: idx, + }; + } + return user; + }), + })); + }, + })), ); @Component({ @@ -36,9 +72,11 @@ const UserSignalStore = signalStore( providers: [UserSignalStore], template: `
- @for (user of userSignalStore.users();track user){ + @for (user of userSignalStore.users();track user.id){

username:{{ user.name }}

userId:{{ user.age }}

+ + }
`,