forked from aws-amplify/amplify-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmerger.ts
73 lines (62 loc) · 1.92 KB
/
merger.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { Storage } from '../storage/storage';
import {
ModelInstanceMetadata,
OpType,
PersistentModelConstructor,
SchemaModel,
} from '../types';
import { MutationEventOutbox } from './outbox';
import { getIdentifierValue } from './utils';
// https://github.com/aws-amplify/amplify-js/blob/datastore-docs/packages/datastore/docs/sync-engine.md#merger
class ModelMerger {
constructor(
private readonly outbox: MutationEventOutbox,
private readonly ownSymbol: Symbol
) {}
/**
*
* @param storage Storage adapter that contains the data.
* @param model The model from an outbox mutation.
* @returns The type of operation (INSERT/UPDATE/DELETE)
*/
public async merge<T extends ModelInstanceMetadata>(
storage: Storage,
model: T,
modelDefinition: SchemaModel
): Promise<OpType> {
let result: OpType;
const mutationsForModel = await this.outbox.getForModel(
storage,
model,
modelDefinition
);
const isDelete = model._deleted;
if (mutationsForModel.length === 0) {
if (isDelete) {
result = OpType.DELETE;
await storage.delete(model, undefined, this.ownSymbol);
} else {
[[, result]] = await storage.save(model, undefined, this.ownSymbol);
}
}
return result!;
}
public async mergePage(
storage: Storage,
modelConstructor: PersistentModelConstructor<any>,
items: ModelInstanceMetadata[],
modelDefinition: SchemaModel
): Promise<[ModelInstanceMetadata, OpType][]> {
const itemsMap: Map<string, ModelInstanceMetadata> = new Map();
for (const item of items) {
// merge items by model id. Latest record for a given id remains.
const modelId = getIdentifierValue(modelDefinition, item);
itemsMap.set(modelId, item);
}
const page = [...itemsMap.values()];
return await storage.batchSave(modelConstructor, page, this.ownSymbol);
}
}
export { ModelMerger };