From d76a1b71f8567601ca6a65618976c2d4be5cf90b Mon Sep 17 00:00:00 2001 From: Paul Kilmurray Date: Thu, 6 Jun 2024 01:14:40 +0100 Subject: [PATCH] add fastDB for sync --- package.json | 2 +- src/collection-replication-state.ts | 26 ++++++++++++++++---------- src/manager.ts | 16 +++++++++++++++- src/provider.tsx | 6 ++++-- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 5bb1128..47a4b6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@wcpos/query", - "version": "1.5.5", + "version": "1.5.6", "description": "Query and Replication for WooCommerce POS", "author": "kilbot ", "license": "MIT", diff --git a/src/collection-replication-state.ts b/src/collection-replication-state.ts index 7188d54..1fcd186 100644 --- a/src/collection-replication-state.ts +++ b/src/collection-replication-state.ts @@ -39,6 +39,7 @@ export interface QueryHooks { interface CollectionReplicationConfig { collection: Collection; + syncCollection: any; httpClient: any; hooks?: any; endpoint: string; @@ -49,6 +50,7 @@ export class CollectionReplicationState extends Subscribab private hooks: CollectionReplicationConfig['hooks']; public readonly endpoint: string; public readonly collection: T; + public readonly syncCollection: any; public readonly storeDB: StoreDatabase; public readonly httpClient: any; private errorSubject: Subject; @@ -88,6 +90,7 @@ export class CollectionReplicationState extends Subscribab */ constructor({ collection, + syncCollection, httpClient, hooks, endpoint, @@ -95,6 +98,7 @@ export class CollectionReplicationState extends Subscribab }: CollectionReplicationConfig) { super(); this.collection = collection; + this.syncCollection = syncCollection; this.storeDB = collection.database; this.httpClient = httpClient; this.hooks = hooks || {}; @@ -118,12 +122,10 @@ export class CollectionReplicationState extends Subscribab * Subscribe to remote and local collections to calculate the total number of documents */ private setupDocumentCount() { - const remoteCount$ = this.storeDB.collections.sync - .find({ selector: { endpoint: this.endpoint } }) - .$.pipe( - map((docs) => docs?.length || 0), - distinctUntilChanged() - ); + const remoteCount$ = this.syncCollection.find({ selector: { endpoint: this.endpoint } }).$.pipe( + map((docs) => docs?.length || 0), + distinctUntilChanged() + ); const newLocalCount$ = this.collection.find({ selector: { id: { $eq: null } } }).$.pipe( map((docs) => docs?.length || 0), @@ -183,6 +185,11 @@ export class CollectionReplicationState extends Subscribab } } + /** + * @TODO - split audit into fullAudit and recentChanges + */ + async fullAudit() {} + /** * */ @@ -241,16 +248,15 @@ export class CollectionReplicationState extends Subscribab * - it's tempting to just bulk delete and insert, but it causes doc totals to flash in the UI */ const data = response.data.map((doc) => ({ ...doc, endpoint: this.endpoint })); - const syncCollection = this.storeDB.collections.sync; const ids = await this.getStoredRemoteIDs(); const orphanedIds = ids.filter((id) => !data.map((doc) => doc.id).includes(id)); if (orphanedIds.length > 0) { log.warn('removing remote', orphanedIds, 'from', this.collection.name); - await syncCollection + await this.syncCollection .find({ selector: { endpoint: this.endpoint, id: { $in: orphanedIds } } }) .remove(); } - const { error } = await this.storeDB.collections.sync.bulkUpsert(data); + const { error } = await this.syncCollection.bulkUpsert(data); if (error.length > 0) { log.error('Error saving remote state for ' + this.endpoint, error); @@ -294,7 +300,7 @@ export class CollectionReplicationState extends Subscribab * */ async getStoredRemoteDocs() { - return this.storeDB.collections.sync.find({ selector: { endpoint: this.endpoint } }).exec(); + return this.syncCollection.find({ selector: { endpoint: this.endpoint } }).exec(); } /** diff --git a/src/manager.ts b/src/manager.ts index bfa2f77..f1f6d2d 100644 --- a/src/manager.ts +++ b/src/manager.ts @@ -62,6 +62,7 @@ export class Manager extends SubscribableBase { private constructor( private localDB: TDatabase, + private fastLocalDB, private httpClient, private locale: string ) { @@ -94,6 +95,7 @@ export class Manager extends SubscribableBase { public static getInstance( localDB: TDatabase, + fastLocalDB, httpClient, locale: string ) { @@ -101,6 +103,7 @@ export class Manager extends SubscribableBase { if ( Manager.instance && Manager.instance.localDB === localDB && + Manager.instance.fastLocalDB === fastLocalDB && // Manager.instance.httpClient === httpClient && // @TODO - look into this Manager.instance.locale === locale ) { @@ -113,7 +116,7 @@ export class Manager extends SubscribableBase { } // Create a new instance - Manager.instance = new Manager(localDB, httpClient, locale); + Manager.instance = new Manager(localDB, fastLocalDB, httpClient, locale); return Manager.instance as Manager; } @@ -207,6 +210,15 @@ export class Manager extends SubscribableBase { return this.localDB[collectionName]; } + getSyncCollection(collectionName: string) { + if (!this.fastLocalDB[collectionName]) { + this.subjects.error.next( + new Error(`Sync collection with name: ${collectionName} not found.`) + ); + } + return this.fastLocalDB[collectionName]; + } + getQuery(queryKeys: (string | number | object)[]) { const key = this.stringify(queryKeys); const query = this.queryStates.get(key); @@ -298,10 +310,12 @@ export class Manager extends SubscribableBase { */ registerCollectionReplication({ collection, endpoint }) { const replicationState = this.replicationStates.get(endpoint); + const syncCollection = this.getSyncCollection(collection.name); if (!replicationState || !(replicationState instanceof CollectionReplicationState)) { const collectionReplication = new CollectionReplicationState({ httpClient: this.httpClient, collection, + syncCollection, endpoint, errorSubject: this.subjects.error, }); diff --git a/src/provider.tsx b/src/provider.tsx index 9e03256..317b6b2 100644 --- a/src/provider.tsx +++ b/src/provider.tsx @@ -8,6 +8,7 @@ const QueryContext = React.createContext | undefined>(undefi interface QueryProviderProps { localDB: T; + fastLocalDB: any; http: any; // Replace 'any' with the actual type of your HTTP client locale: string; children: React.ReactNode; @@ -18,13 +19,14 @@ interface QueryProviderProps { */ export const QueryProvider = ({ localDB, + fastLocalDB, http, children, locale, }: QueryProviderProps) => { const manager = React.useMemo(() => { - return Manager.getInstance(localDB, http, locale); - }, [localDB, http, locale]); + return Manager.getInstance(localDB, fastLocalDB, http, locale); + }, [localDB, fastLocalDB, http, locale]); return {children}; };