diff --git a/packages/datastore/src/datastore/datastore.ts b/packages/datastore/src/datastore/datastore.ts index c13c2002024..7e0712d138e 100644 --- a/packages/datastore/src/datastore/datastore.ts +++ b/packages/datastore/src/datastore/datastore.ts @@ -551,7 +551,6 @@ class DataStore { SchemaModel, ModelPredicate > = new WeakMap>(); - private syncModelsUpdated: Set = new Set(); getModuleName() { return 'DataStore'; @@ -599,8 +598,7 @@ class DataStore { this.syncPageSize, this.conflictHandler, this.errorHandler, - this.syncPredicates, - this.syncModelsUpdated + this.syncPredicates ); // tslint:disable-next-line:max-line-length @@ -1035,6 +1033,7 @@ class DataStore { this.initialized = undefined; // Should re-initialize when start() is called. this.storage = undefined; this.sync = undefined; + this.syncPredicates = new WeakMap>(); }; stop = async function stop() { @@ -1113,6 +1112,10 @@ class DataStore { // conditionProducer is either a predicate, e.g. (c) => c.field('eq', 1) // OR a function/promise that returns a predicate const condition = await this.unwrapPromise(conditionProducer); + if (isPredicatesAll(condition)) { + return [modelDefinition, null]; + } + const predicate = this.createFromCondition( modelDefinition, condition @@ -1123,34 +1126,9 @@ class DataStore { ) ); - this.compareSyncPredicates(syncPredicates); - return this.weakMapFromEntries(syncPredicates); } - private compareSyncPredicates( - syncPredicates: [SchemaModel, ModelPredicate][] - ) { - this.syncModelsUpdated = new Set(); - - syncPredicates.forEach(([modelDefinition, predicate]) => { - const previousPredicate = ModelPredicateCreator.getPredicates( - this.syncPredicates.get(modelDefinition), - false - ); - - const newPredicate = ModelPredicateCreator.getPredicates( - predicate, - false - ); - - const predicateChanged = - JSON.stringify(previousPredicate) !== JSON.stringify(newPredicate); - - predicateChanged && this.syncModelsUpdated.add(modelDefinition.name); - }); - } - private createFromCondition( modelDefinition: SchemaModel, condition: ProducerModelPredicate @@ -1188,12 +1166,15 @@ class DataStore { const { name } = modelDefinition; logger.warn( `You can only utilize one Sync Expression per model. - Subsequent sync expressions for the ${name} model will be ignored.` + Subsequent sync expressions for the ${name} model will be ignored.` ); return map; } - map.set(modelDefinition, predicate); + if (predicate) { + map.set(modelDefinition, predicate); + } + return map; }, new WeakMap>()); } diff --git a/packages/datastore/src/sync/index.ts b/packages/datastore/src/sync/index.ts index 9eef1cdebf7..772eaa02f42 100644 --- a/packages/datastore/src/sync/index.ts +++ b/packages/datastore/src/sync/index.ts @@ -69,6 +69,7 @@ declare class ModelMetadata { public readonly fullSyncInterval: number; public readonly lastSync?: number; public readonly lastFullSync?: number; + public readonly lastSyncPredicate?: null | string; } export enum ControlMessage { @@ -104,8 +105,7 @@ export class SyncEngine { private readonly syncPageSize: number, conflictHandler: ConflictHandler, errorHandler: ErrorHandler, - private readonly syncPredicates: WeakMap>, - private readonly syncModelsUpdated: ReadonlySet + private readonly syncPredicates: WeakMap> ) { const MutationEvent = this.modelClasses[ 'MutationEvent' @@ -410,7 +410,14 @@ export class SyncEngine { ): Promise> { const modelLastSync: Map = new Map( (await this.getModelsMetadata()).map( - ({ namespace, model, lastSync, lastFullSync, fullSyncInterval }) => { + ({ + namespace, + model, + lastSync, + lastFullSync, + fullSyncInterval, + lastSyncPredicate, + }) => { const nextFullSync = lastFullSync + fullSyncInterval; const syncFrom = !lastFullSync || nextFullSync < currentTimeStamp @@ -694,34 +701,45 @@ export class SyncEngine { const ModelMetadata = this.modelClasses .ModelMetadata as PersistentModelConstructor; - const models: [string, string][] = []; + const models: [string, SchemaModel][] = []; + let savedModel; Object.values(this.schema.namespaces).forEach(namespace => { Object.values(namespace.models) .filter(({ syncable }) => syncable) .forEach(model => { - models.push([namespace.name, model.name]); + models.push([namespace.name, model]); }); }); const promises = models.map(async ([namespace, model]) => { - const modelMetadata = await this.getModelMetadata(namespace, model); - let savedModel: ModelMetadata; + const modelMetadata = await this.getModelMetadata(namespace, model.name); + const syncPredicate = ModelPredicateCreator.getPredicates( + this.syncPredicates.get(model), + false + ); + const lastSyncPredicate = syncPredicate + ? JSON.stringify(syncPredicate) + : null; if (modelMetadata === undefined) { [[savedModel]] = await this.storage.save( this.modelInstanceCreator(ModelMetadata, { - model, + model: model.name, namespace, lastSync: null, fullSyncInterval, lastFullSync: null, + lastSyncPredicate, }), undefined, ownSymbol ); } else { - const syncPredicateUpdated = this.syncModelsUpdated.has(model); + const prevSyncPredicate = modelMetadata.lastSyncPredicate + ? JSON.stringify(modelMetadata.lastSyncPredicate) + : null; + const syncPredicateUpdated = prevSyncPredicate !== lastSyncPredicate; [[savedModel]] = await this.storage.save( (this.modelClasses.ModelMetadata as PersistentModelConstructor< @@ -733,6 +751,7 @@ export class SyncEngine { if (syncPredicateUpdated) { draft.lastSync = null; draft.lastFullSync = null; + draft.lastSyncPredicate = lastSyncPredicate; } }) );