Skip to content

Commit

Permalink
Lay groundwork for GraphQL sync
Browse files Browse the repository at this point in the history
  • Loading branch information
kand198 committed Aug 31, 2022
1 parent cf89510 commit ae666ad
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 20 deletions.
7 changes: 6 additions & 1 deletion apps/backend/src/app/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ export class UserService {
limit: number
): Promise<UserEntity[]> {
let query: SelectQueryBuilder<UserEntity>;
if (minUpdatedAt === undefined || lastId === undefined) {
if (
minUpdatedAt === undefined ||
lastId === undefined ||
minUpdatedAt?.getTime() === 0 ||
lastId === ''
) {
query = this.usersRepository.createQueryBuilder('user');
} else {
query = this.usersRepository
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/app/hooks/usePatients/usePatients.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
27 changes: 14 additions & 13 deletions apps/frontend/src/database/database-constructor.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { RxDatabase } from 'rxdb';

class DatabaseConstructor {
private _db: RxDatabase | null;
private _databaseConstructor: () => Promise<RxDatabase>;
constructor(databaseConstructor: () => Promise<RxDatabase>) {
this._databaseConstructor = databaseConstructor;
this._db = null;
this.get = async (): Promise<RxDatabase> => {
if (!this._db) {
this._db = await this._databaseConstructor();
}
return this._db;
};
private _blocked = false;
private _db: RxDatabase | null = null;
private _dbInitializer: () => Promise<RxDatabase>;

public async get(): Promise<RxDatabase | null> {
if (!this._db && !this._blocked) {
this._blocked = true;
this._db = await this._dbInitializer();
this._blocked = false;
}
return Promise.resolve(this._db);
}
get(): Promise<RxDatabase> | null {
return null;

constructor(dbInitializer: () => Promise<RxDatabase>) {
this._dbInitializer = dbInitializer;
}
}

Expand Down
53 changes: 49 additions & 4 deletions apps/frontend/src/database/patient-database.ts
Original file line number Diff line number Diff line change
@@ -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<any>) => {
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(),
Expand All @@ -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
);

0 comments on commit ae666ad

Please sign in to comment.