Skip to content

Commit

Permalink
feat(@aws-amplify/datastore): selective sync enhancements (aws-amplif…
Browse files Browse the repository at this point in the history
  • Loading branch information
iartemiev authored and CryogenicPlanet committed Jan 20, 2021
1 parent ed6914e commit 589d140
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 39 deletions.
41 changes: 11 additions & 30 deletions packages/datastore/src/datastore/datastore.ts
Expand Up @@ -551,7 +551,6 @@ class DataStore {
SchemaModel,
ModelPredicate<any>
> = new WeakMap<SchemaModel, ModelPredicate<any>>();
private syncModelsUpdated: Set<string> = new Set<string>();

getModuleName() {
return 'DataStore';
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<SchemaModel, ModelPredicate<any>>();
};

stop = async function stop() {
Expand Down Expand Up @@ -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
Expand All @@ -1123,34 +1126,9 @@ class DataStore {
)
);

this.compareSyncPredicates(syncPredicates);

return this.weakMapFromEntries(syncPredicates);
}

private compareSyncPredicates(
syncPredicates: [SchemaModel, ModelPredicate<any>][]
) {
this.syncModelsUpdated = new Set<string>();

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<PersistentModel>
Expand Down Expand Up @@ -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<SchemaModel, ModelPredicate<any>>());
}
Expand Down
37 changes: 28 additions & 9 deletions packages/datastore/src/sync/index.ts
Expand Up @@ -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 {
Expand Down Expand Up @@ -104,8 +105,7 @@ export class SyncEngine {
private readonly syncPageSize: number,
conflictHandler: ConflictHandler,
errorHandler: ErrorHandler,
private readonly syncPredicates: WeakMap<SchemaModel, ModelPredicate<any>>,
private readonly syncModelsUpdated: ReadonlySet<string>
private readonly syncPredicates: WeakMap<SchemaModel, ModelPredicate<any>>
) {
const MutationEvent = this.modelClasses[
'MutationEvent'
Expand Down Expand Up @@ -410,7 +410,14 @@ export class SyncEngine {
): Promise<Map<SchemaModel, [string, number]>> {
const modelLastSync: Map<SchemaModel, [string, number]> = 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
Expand Down Expand Up @@ -694,34 +701,45 @@ export class SyncEngine {
const ModelMetadata = this.modelClasses
.ModelMetadata as PersistentModelConstructor<ModelMetadata>;

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<
Expand All @@ -733,6 +751,7 @@ export class SyncEngine {
if (syncPredicateUpdated) {
draft.lastSync = null;
draft.lastFullSync = null;
draft.lastSyncPredicate = lastSyncPredicate;
}
})
);
Expand Down

0 comments on commit 589d140

Please sign in to comment.