diff --git a/apps/backend/src/app/users/users.service.ts b/apps/backend/src/app/users/users.service.ts index 0e138014..91aa8edf 100644 --- a/apps/backend/src/app/users/users.service.ts +++ b/apps/backend/src/app/users/users.service.ts @@ -16,7 +16,12 @@ export class UserService { limit: number ): Promise { let query: SelectQueryBuilder; - if (minUpdatedAt === undefined || lastId === undefined) { + if ( + minUpdatedAt === undefined || + lastId === undefined || + minUpdatedAt?.getTime() === 0 || + lastId === '' + ) { query = this.usersRepository.createQueryBuilder('user'); } else { query = this.usersRepository diff --git a/apps/frontend/src/app/hooks/usePatients/usePatients.tsx b/apps/frontend/src/app/hooks/usePatients/usePatients.tsx index 8f2d3ea3..20054009 100644 --- a/apps/frontend/src/app/hooks/usePatients/usePatients.tsx +++ b/apps/frontend/src/app/hooks/usePatients/usePatients.tsx @@ -39,8 +39,8 @@ export const usePatients = () => { useEffect(() => { patientDatabase .get() - ?.then((db: RxDatabase) => { - setPatientsDb(db); + ?.then((db: RxDatabase | null) => { + db && setPatientsDb(db); }) .catch((error: Error) => { console.log(error); diff --git a/apps/frontend/src/database/database-constructor.ts b/apps/frontend/src/database/database-constructor.ts index 2cd9e8c4..8b7b476a 100644 --- a/apps/frontend/src/database/database-constructor.ts +++ b/apps/frontend/src/database/database-constructor.ts @@ -1,20 +1,21 @@ import { RxDatabase } from 'rxdb'; class DatabaseConstructor { - private _db: RxDatabase | null; - private _databaseConstructor: () => Promise; - constructor(databaseConstructor: () => Promise) { - this._databaseConstructor = databaseConstructor; - this._db = null; - this.get = async (): Promise => { - if (!this._db) { - this._db = await this._databaseConstructor(); - } - return this._db; - }; + private _blocked = false; + private _db: RxDatabase | null = null; + private _dbInitializer: () => Promise; + + public async get(): Promise { + if (!this._db && !this._blocked) { + this._blocked = true; + this._db = await this._dbInitializer(); + this._blocked = false; + } + return Promise.resolve(this._db); } - get(): Promise | null { - return null; + + constructor(dbInitializer: () => Promise) { + this._dbInitializer = dbInitializer; } } diff --git a/apps/frontend/src/database/patient-database.ts b/apps/frontend/src/database/patient-database.ts index 097cb421..d0ee7f6f 100644 --- a/apps/frontend/src/database/patient-database.ts +++ b/apps/frontend/src/database/patient-database.ts @@ -1,17 +1,49 @@ -import { addRxPlugin, createRxDatabase } from 'rxdb'; +import { addRxPlugin, createRxDatabase, RxDocument } from 'rxdb'; import { getRxStorageDexie } from 'rxdb/plugins/dexie'; import patientSchema from './patient-schema'; import { RxDBUpdatePlugin } from 'rxdb/plugins/update'; import DatabaseConstructor from './database-constructor'; -addRxPlugin(RxDBUpdatePlugin); +import { RxDBReplicationGraphQLPlugin } from 'rxdb/plugins/replication-graphql'; + +const addPlugins = async () => { + addRxPlugin(RxDBReplicationGraphQLPlugin); + addRxPlugin(RxDBUpdatePlugin); -const initializePatientDatabase = async () => { if (process.env['NODE_ENV'] !== 'production') { await import('rxdb/plugins/dev-mode').then((module) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any addRxPlugin((module as any).RxDBDevModePlugin); }); } +}; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const pullQueryBuilder = async (doc: RxDocument) => { + if (!doc) { + doc = { + id: '', + updatedAt: 0, + }; + } + + const query = `{ + userReplicationFeed(lastId: "${doc.id}", minUpdatedAt: ${doc.updatedAt}, limit: 5) { + id, + firstName, + lastName, + updatedAt, + deletedAt, + } + }`; + + return { + query, + variables: {}, + }; +}; + +const initializePatientDatabase = async () => { + await addPlugins(); const db = await createRxDatabase({ name: 'patientdb', storage: getRxStorageDexie(), @@ -21,9 +53,22 @@ const initializePatientDatabase = async () => { schema: patientSchema, }, }); + const replicationState = db.collections['patients'].syncGraphQL({ + url: 'http://localhost:3333/graphql', // url to the GraphQL endpoint + pull: { + queryBuilder: pullQueryBuilder, // the queryBuilder from above + batchSize: 5, + }, + deletedFlag: 'deletedAt', // the flag which indicates if a pulled document is deleted + live: true, // if this is true, rxdb will watch for ongoing changes and sync them, when false, a one-time-replication will be done + }); + replicationState.received$.subscribe((response) => + console.log('response from graphql', response) + ); + replicationState.run(); return db; }; -export const patientDatabase: DatabaseConstructor = new DatabaseConstructor( +export const patientDatabase = new DatabaseConstructor( initializePatientDatabase );