@aws-amplify/datastore 3.14.5-unstable.4 → 3.14.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/build.js +5 -0
- package/dist/aws-amplify-datastore.js +92853 -0
- package/dist/aws-amplify-datastore.js.map +1 -0
- package/dist/aws-amplify-datastore.min.js +65 -0
- package/dist/aws-amplify-datastore.min.js.map +1 -0
- package/index.js +7 -0
- package/lib/authModeStrategies/multiAuthStrategy.js +64 -6
- package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib/datastore/datastore.js +297 -703
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/index.js +4 -6
- package/lib/index.js.map +1 -1
- package/lib/predicates/index.js +6 -127
- package/lib/predicates/index.js.map +1 -1
- package/lib/predicates/sort.js +4 -10
- package/lib/predicates/sort.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js +381 -138
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.js +98 -37
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.js +67 -16
- package/lib/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.native.js +4 -2
- package/lib/storage/adapter/InMemoryStore.native.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.js +420 -272
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/adapter/getDefaultAdapter/index.js +5 -3
- package/lib/storage/adapter/getDefaultAdapter/index.js.map +1 -1
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +4 -2
- package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +1 -1
- package/lib/storage/storage.js +143 -72
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/datastoreConnectivity.js +55 -6
- package/lib/sync/datastoreConnectivity.js.map +1 -1
- package/lib/sync/datastoreReachability/index.native.js +4 -2
- package/lib/sync/datastoreReachability/index.native.js.map +1 -1
- package/lib/sync/index.js +124 -49
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.js +74 -8
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.js +97 -24
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/errorMaps.js +35 -5
- package/lib/sync/processors/errorMaps.js.map +1 -1
- package/lib/sync/processors/mutation.js +131 -47
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.js +102 -29
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.js +102 -26
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.js +103 -40
- package/lib/sync/utils.js.map +1 -1
- package/lib/types.js +39 -9
- package/lib/types.js.map +1 -1
- package/lib/util.js +188 -192
- package/lib/util.js.map +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +57 -2
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +8 -59
- package/lib-esm/datastore/datastore.js +234 -642
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/index.d.ts +2 -3
- package/lib-esm/index.js +1 -2
- package/lib-esm/index.js.map +1 -1
- package/lib-esm/predicates/index.d.ts +2 -16
- package/lib-esm/predicates/index.js +7 -128
- package/lib-esm/predicates/index.js.map +1 -1
- package/lib-esm/predicates/sort.js +4 -10
- package/lib-esm/predicates/sort.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +1 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +349 -109
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +68 -7
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.d.ts +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.js +52 -1
- package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +2 -4
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +368 -227
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +1 -1
- package/lib-esm/storage/storage.d.ts +6 -7
- package/lib-esm/storage/storage.js +101 -33
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/datastoreConnectivity.js +47 -1
- package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
- package/lib-esm/sync/index.js +76 -4
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.js +67 -1
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.js +74 -1
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/errorMaps.js +32 -2
- package/lib-esm/sync/processors/errorMaps.js.map +1 -1
- package/lib-esm/sync/processors/mutation.js +93 -12
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.js +69 -6
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.js +75 -2
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.d.ts +1 -1
- package/lib-esm/sync/utils.js +95 -32
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/types.d.ts +10 -63
- package/lib-esm/types.js +38 -7
- package/lib-esm/types.js.map +1 -1
- package/lib-esm/util.d.ts +6 -39
- package/lib-esm/util.js +171 -171
- package/lib-esm/util.js.map +1 -1
- package/package.json +14 -21
- package/src/authModeStrategies/multiAuthStrategy.ts +2 -2
- package/src/datastore/datastore.ts +206 -699
- package/src/index.ts +0 -4
- package/src/predicates/index.ts +17 -143
- package/src/predicates/sort.ts +2 -8
- package/src/storage/adapter/AsyncStorageAdapter.ts +178 -56
- package/src/storage/adapter/AsyncStorageDatabase.ts +15 -16
- package/src/storage/adapter/InMemoryStore.ts +2 -5
- package/src/storage/adapter/IndexedDBAdapter.ts +191 -166
- package/src/storage/adapter/getDefaultAdapter/index.ts +2 -2
- package/src/storage/storage.ts +37 -56
- package/src/sync/datastoreConnectivity.ts +4 -4
- package/src/sync/index.ts +28 -22
- package/src/sync/merger.ts +1 -1
- package/src/sync/outbox.ts +6 -6
- package/src/sync/processors/errorMaps.ts +1 -1
- package/src/sync/processors/mutation.ts +19 -23
- package/src/sync/processors/subscription.ts +16 -20
- package/src/sync/processors/sync.ts +17 -17
- package/src/sync/utils.ts +48 -42
- package/src/types.ts +16 -128
- package/src/util.ts +150 -108
- package/webpack.config.dev.js +6 -0
- package/lib/authModeStrategies/defaultAuthStrategy.d.ts +0 -2
- package/lib/authModeStrategies/index.d.ts +0 -2
- package/lib/authModeStrategies/multiAuthStrategy.d.ts +0 -13
- package/lib/datastore/datastore.d.ts +0 -207
- package/lib/index.d.ts +0 -16
- package/lib/predicates/index.d.ts +0 -30
- package/lib/predicates/next.d.ts +0 -301
- package/lib/predicates/next.js +0 -816
- package/lib/predicates/next.js.map +0 -1
- package/lib/predicates/sort.d.ts +0 -8
- package/lib/ssr/index.d.ts +0 -3
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +0 -42
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +0 -39
- package/lib/storage/adapter/InMemoryStore.d.ts +0 -11
- package/lib/storage/adapter/InMemoryStore.native.d.ts +0 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +0 -61
- package/lib/storage/adapter/getDefaultAdapter/index.d.ts +0 -3
- package/lib/storage/adapter/getDefaultAdapter/index.native.d.ts +0 -3
- package/lib/storage/adapter/index.d.ts +0 -9
- package/lib/storage/relationship.d.ts +0 -140
- package/lib/storage/relationship.js +0 -335
- package/lib/storage/relationship.js.map +0 -1
- package/lib/storage/storage.d.ts +0 -50
- package/lib/sync/datastoreConnectivity.d.ts +0 -16
- package/lib/sync/datastoreReachability/index.d.ts +0 -3
- package/lib/sync/datastoreReachability/index.native.d.ts +0 -3
- package/lib/sync/index.d.ts +0 -89
- package/lib/sync/merger.d.ts +0 -17
- package/lib/sync/outbox.d.ts +0 -27
- package/lib/sync/processors/errorMaps.d.ts +0 -17
- package/lib/sync/processors/mutation.d.ts +0 -58
- package/lib/sync/processors/subscription.d.ts +0 -33
- package/lib/sync/processors/sync.d.ts +0 -28
- package/lib/sync/utils.d.ts +0 -42
- package/lib/types.d.ts +0 -554
- package/lib/util.d.ts +0 -189
- package/lib-esm/predicates/next.d.ts +0 -301
- package/lib-esm/predicates/next.js +0 -812
- package/lib-esm/predicates/next.js.map +0 -1
- package/lib-esm/storage/relationship.d.ts +0 -140
- package/lib-esm/storage/relationship.js +0 -333
- package/lib-esm/storage/relationship.js.map +0 -1
- package/src/predicates/next.ts +0 -967
- package/src/storage/relationship.ts +0 -272
package/src/storage/storage.ts
CHANGED
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
STORAGE,
|
|
26
26
|
validatePredicate,
|
|
27
27
|
valuesEqual,
|
|
28
|
-
NAMESPACES,
|
|
29
28
|
} from '../util';
|
|
30
29
|
import { getIdentifierValue } from '../sync/utils';
|
|
31
30
|
import { Adapter } from './adapter';
|
|
@@ -41,7 +40,7 @@ export type Storage = InstanceType<typeof StorageClass>;
|
|
|
41
40
|
|
|
42
41
|
const logger = new Logger('DataStore');
|
|
43
42
|
class StorageClass implements StorageFacade {
|
|
44
|
-
private initialized: Promise<void
|
|
43
|
+
private initialized: Promise<void>;
|
|
45
44
|
private readonly pushStream: {
|
|
46
45
|
observable: Observable<StorageSubscriptionMessage<PersistentModel>>;
|
|
47
46
|
} & Required<
|
|
@@ -52,7 +51,7 @@ class StorageClass implements StorageFacade {
|
|
|
52
51
|
private readonly schema: InternalSchema,
|
|
53
52
|
private readonly namespaceResolver: NamespaceResolver,
|
|
54
53
|
private readonly getModelConstructorByModelName: (
|
|
55
|
-
namsespaceName:
|
|
54
|
+
namsespaceName: string,
|
|
56
55
|
modelName: string
|
|
57
56
|
) => PersistentModelConstructor<any>,
|
|
58
57
|
private readonly modelInstanceCreator: ModelInstanceCreator,
|
|
@@ -60,7 +59,7 @@ class StorageClass implements StorageFacade {
|
|
|
60
59
|
private readonly sessionId?: string
|
|
61
60
|
) {
|
|
62
61
|
this.adapter = this.adapter || getDefaultAdapter();
|
|
63
|
-
this.pushStream = new PushStream()
|
|
62
|
+
this.pushStream = new PushStream();
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
static getNamespace() {
|
|
@@ -90,13 +89,15 @@ class StorageClass implements StorageFacade {
|
|
|
90
89
|
reject = rej;
|
|
91
90
|
});
|
|
92
91
|
|
|
93
|
-
this.adapter
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
this.adapter
|
|
93
|
+
.setUp(
|
|
94
|
+
this.schema,
|
|
95
|
+
this.namespaceResolver,
|
|
96
|
+
this.modelInstanceCreator,
|
|
97
|
+
this.getModelConstructorByModelName,
|
|
98
|
+
this.sessionId
|
|
99
|
+
)
|
|
100
|
+
.then(resolve, reject);
|
|
100
101
|
|
|
101
102
|
await this.initialized;
|
|
102
103
|
}
|
|
@@ -108,9 +109,6 @@ class StorageClass implements StorageFacade {
|
|
|
108
109
|
patchesTuple?: [Patch[], PersistentModel]
|
|
109
110
|
): Promise<[T, OpType.INSERT | OpType.UPDATE][]> {
|
|
110
111
|
await this.init();
|
|
111
|
-
if (!this.adapter) {
|
|
112
|
-
throw new Error('Storage adapter is missing');
|
|
113
|
-
}
|
|
114
112
|
|
|
115
113
|
const result = await this.adapter.save(model, condition);
|
|
116
114
|
|
|
@@ -154,14 +152,11 @@ class StorageClass implements StorageFacade {
|
|
|
154
152
|
.constructor as PersistentModelConstructor<T>;
|
|
155
153
|
|
|
156
154
|
this.pushStream.next({
|
|
157
|
-
model: modelConstructor
|
|
155
|
+
model: modelConstructor,
|
|
158
156
|
opType,
|
|
159
157
|
element,
|
|
160
158
|
mutator,
|
|
161
|
-
condition:
|
|
162
|
-
(condition &&
|
|
163
|
-
ModelPredicateCreator.getPredicates(condition, false)) ||
|
|
164
|
-
null,
|
|
159
|
+
condition: ModelPredicateCreator.getPredicates(condition, false),
|
|
165
160
|
savedElement,
|
|
166
161
|
});
|
|
167
162
|
});
|
|
@@ -185,12 +180,9 @@ class StorageClass implements StorageFacade {
|
|
|
185
180
|
mutator?: Symbol
|
|
186
181
|
): Promise<[T[], T[]]> {
|
|
187
182
|
await this.init();
|
|
188
|
-
if (!this.adapter) {
|
|
189
|
-
throw new Error('Storage adapter is missing');
|
|
190
|
-
}
|
|
191
183
|
|
|
184
|
+
let deleted: T[];
|
|
192
185
|
let models: T[];
|
|
193
|
-
let deleted: T[] | undefined;
|
|
194
186
|
|
|
195
187
|
[models, deleted] = await this.adapter.delete(
|
|
196
188
|
modelOrModelConstructor,
|
|
@@ -224,21 +216,21 @@ class StorageClass implements StorageFacade {
|
|
|
224
216
|
const modelConstructor = (Object.getPrototypeOf(model) as Object)
|
|
225
217
|
.constructor as PersistentModelConstructor<T>;
|
|
226
218
|
|
|
227
|
-
let theCondition: PredicatesGroup<any
|
|
219
|
+
let theCondition: PredicatesGroup<any>;
|
|
228
220
|
|
|
229
221
|
if (!isModelConstructor(modelOrModelConstructor)) {
|
|
230
222
|
const modelId = getIdentifierValue(modelDefinition, model);
|
|
231
223
|
theCondition = modelIds.has(modelId)
|
|
232
|
-
? ModelPredicateCreator.getPredicates(condition
|
|
224
|
+
? ModelPredicateCreator.getPredicates(condition, false)
|
|
233
225
|
: undefined;
|
|
234
226
|
}
|
|
235
227
|
|
|
236
228
|
this.pushStream.next({
|
|
237
|
-
model: modelConstructor
|
|
229
|
+
model: modelConstructor,
|
|
238
230
|
opType: OpType.DELETE,
|
|
239
231
|
element: model,
|
|
240
232
|
mutator,
|
|
241
|
-
condition: theCondition
|
|
233
|
+
condition: theCondition,
|
|
242
234
|
});
|
|
243
235
|
});
|
|
244
236
|
|
|
@@ -251,9 +243,6 @@ class StorageClass implements StorageFacade {
|
|
|
251
243
|
pagination?: PaginationInput<T>
|
|
252
244
|
): Promise<T[]> {
|
|
253
245
|
await this.init();
|
|
254
|
-
if (!this.adapter) {
|
|
255
|
-
throw new Error('Storage adapter is missing');
|
|
256
|
-
}
|
|
257
246
|
|
|
258
247
|
return await this.adapter.query(modelConstructor, predicate, pagination);
|
|
259
248
|
}
|
|
@@ -261,24 +250,22 @@ class StorageClass implements StorageFacade {
|
|
|
261
250
|
async queryOne<T extends PersistentModel>(
|
|
262
251
|
modelConstructor: PersistentModelConstructor<T>,
|
|
263
252
|
firstOrLast: QueryOne = QueryOne.FIRST
|
|
264
|
-
): Promise<T
|
|
253
|
+
): Promise<T> {
|
|
265
254
|
await this.init();
|
|
266
|
-
if (!this.adapter) {
|
|
267
|
-
throw new Error('Storage adapter is missing');
|
|
268
|
-
}
|
|
269
255
|
|
|
270
|
-
|
|
256
|
+
const record = await this.adapter.queryOne(modelConstructor, firstOrLast);
|
|
257
|
+
return record;
|
|
271
258
|
}
|
|
272
259
|
|
|
273
260
|
observe<T extends PersistentModel>(
|
|
274
|
-
modelConstructor?: PersistentModelConstructor<T
|
|
275
|
-
predicate?: ModelPredicate<T
|
|
261
|
+
modelConstructor?: PersistentModelConstructor<T>,
|
|
262
|
+
predicate?: ModelPredicate<T>,
|
|
276
263
|
skipOwn?: Symbol
|
|
277
264
|
): Observable<SubscriptionMessage<T>> {
|
|
278
265
|
const listenToAll = !modelConstructor;
|
|
279
266
|
const { predicates, type } =
|
|
280
|
-
|
|
281
|
-
|
|
267
|
+
ModelPredicateCreator.getPredicates(predicate, false) || {};
|
|
268
|
+
const hasPredicate = !!predicates;
|
|
282
269
|
|
|
283
270
|
let result = this.pushStream.observable
|
|
284
271
|
.filter(({ mutator }) => {
|
|
@@ -294,7 +281,7 @@ class StorageClass implements StorageFacade {
|
|
|
294
281
|
return false;
|
|
295
282
|
}
|
|
296
283
|
|
|
297
|
-
if (
|
|
284
|
+
if (hasPredicate) {
|
|
298
285
|
return validatePredicate(element, type, predicates);
|
|
299
286
|
}
|
|
300
287
|
|
|
@@ -307,9 +294,6 @@ class StorageClass implements StorageFacade {
|
|
|
307
294
|
|
|
308
295
|
async clear(completeObservable = true) {
|
|
309
296
|
this.initialized = undefined;
|
|
310
|
-
if (!this.adapter) {
|
|
311
|
-
throw new Error('Storage adapter is missing');
|
|
312
|
-
}
|
|
313
297
|
|
|
314
298
|
await this.adapter.clear();
|
|
315
299
|
|
|
@@ -324,9 +308,6 @@ class StorageClass implements StorageFacade {
|
|
|
324
308
|
mutator?: Symbol
|
|
325
309
|
): Promise<[T, OpType][]> {
|
|
326
310
|
await this.init();
|
|
327
|
-
if (!this.adapter) {
|
|
328
|
-
throw new Error('Storage adapter is missing');
|
|
329
|
-
}
|
|
330
311
|
|
|
331
312
|
const result = await this.adapter.batchSave(modelConstructor, items);
|
|
332
313
|
|
|
@@ -336,7 +317,7 @@ class StorageClass implements StorageFacade {
|
|
|
336
317
|
opType,
|
|
337
318
|
element,
|
|
338
319
|
mutator,
|
|
339
|
-
condition:
|
|
320
|
+
condition: undefined,
|
|
340
321
|
});
|
|
341
322
|
});
|
|
342
323
|
|
|
@@ -354,7 +335,7 @@ class StorageClass implements StorageFacade {
|
|
|
354
335
|
return null;
|
|
355
336
|
}
|
|
356
337
|
|
|
357
|
-
const [patches, source] = patchesTuple
|
|
338
|
+
const [patches, source] = patchesTuple;
|
|
358
339
|
const updatedElement = {};
|
|
359
340
|
// extract array of updated fields from patches
|
|
360
341
|
const updatedFields = <string[]>(
|
|
@@ -368,7 +349,7 @@ class StorageClass implements StorageFacade {
|
|
|
368
349
|
const { fields } =
|
|
369
350
|
this.schema.namespaces[namespace].models[modelConstructor.name];
|
|
370
351
|
const { primaryKey, compositeKeys = [] } =
|
|
371
|
-
this.schema.namespaces[namespace].keys
|
|
352
|
+
this.schema.namespaces[namespace].keys[modelConstructor.name];
|
|
372
353
|
|
|
373
354
|
// set original values for these fields
|
|
374
355
|
updatedFields.forEach((field: string) => {
|
|
@@ -459,7 +440,7 @@ class ExclusiveStorage implements StorageFacade {
|
|
|
459
440
|
schema: InternalSchema,
|
|
460
441
|
namespaceResolver: NamespaceResolver,
|
|
461
442
|
getModelConstructorByModelName: (
|
|
462
|
-
namsespaceName:
|
|
443
|
+
namsespaceName: string,
|
|
463
444
|
modelName: string
|
|
464
445
|
) => PersistentModelConstructor<any>,
|
|
465
446
|
modelInstanceCreator: ModelInstanceCreator,
|
|
@@ -510,11 +491,11 @@ class ExclusiveStorage implements StorageFacade {
|
|
|
510
491
|
if (isModelConstructor(modelOrModelConstructor)) {
|
|
511
492
|
const modelConstructor = modelOrModelConstructor;
|
|
512
493
|
|
|
513
|
-
return storage.delete(modelConstructor
|
|
494
|
+
return storage.delete(modelConstructor, condition, mutator);
|
|
514
495
|
} else {
|
|
515
496
|
const model = modelOrModelConstructor;
|
|
516
497
|
|
|
517
|
-
return storage.delete(model
|
|
498
|
+
return storage.delete(model, condition, mutator);
|
|
518
499
|
}
|
|
519
500
|
});
|
|
520
501
|
}
|
|
@@ -532,8 +513,8 @@ class ExclusiveStorage implements StorageFacade {
|
|
|
532
513
|
async queryOne<T extends PersistentModel>(
|
|
533
514
|
modelConstructor: PersistentModelConstructor<T>,
|
|
534
515
|
firstOrLast: QueryOne = QueryOne.FIRST
|
|
535
|
-
): Promise<T
|
|
536
|
-
return this.runExclusive<T
|
|
516
|
+
): Promise<T> {
|
|
517
|
+
return this.runExclusive<T>(storage =>
|
|
537
518
|
storage.queryOne<T>(modelConstructor, firstOrLast)
|
|
538
519
|
);
|
|
539
520
|
}
|
|
@@ -543,8 +524,8 @@ class ExclusiveStorage implements StorageFacade {
|
|
|
543
524
|
}
|
|
544
525
|
|
|
545
526
|
observe<T extends PersistentModel>(
|
|
546
|
-
modelConstructor?: PersistentModelConstructor<T
|
|
547
|
-
predicate?: ModelPredicate<T
|
|
527
|
+
modelConstructor?: PersistentModelConstructor<T>,
|
|
528
|
+
predicate?: ModelPredicate<T>,
|
|
548
529
|
skipOwn?: Symbol
|
|
549
530
|
): Observable<SubscriptionMessage<T>> {
|
|
550
531
|
return this.storage.observe(modelConstructor, predicate, skipOwn);
|
|
@@ -13,9 +13,9 @@ type ConnectionStatus = {
|
|
|
13
13
|
|
|
14
14
|
export default class DataStoreConnectivity {
|
|
15
15
|
private connectionStatus: ConnectionStatus;
|
|
16
|
-
private observer
|
|
17
|
-
private subscription
|
|
18
|
-
private timeout
|
|
16
|
+
private observer: ZenObservable.SubscriptionObserver<ConnectionStatus>;
|
|
17
|
+
private subscription: ZenObservable.Subscription;
|
|
18
|
+
private timeout: ReturnType<typeof setTimeout>;
|
|
19
19
|
constructor() {
|
|
20
20
|
this.connectionStatus = {
|
|
21
21
|
online: false,
|
|
@@ -26,7 +26,7 @@ export default class DataStoreConnectivity {
|
|
|
26
26
|
if (this.observer) {
|
|
27
27
|
throw new Error('Subscriber already exists');
|
|
28
28
|
}
|
|
29
|
-
return new Observable(
|
|
29
|
+
return new Observable(observer => {
|
|
30
30
|
this.observer = observer;
|
|
31
31
|
// Will be used to forward socket connection changes, enhancing Reachability
|
|
32
32
|
|
package/src/sync/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
// tslint:disable:no-duplicate-imports
|
|
33
33
|
import type { __modelMeta__ } from '../types';
|
|
34
34
|
|
|
35
|
-
import { getNow, SYNC, USER } from '../util';
|
|
35
|
+
import { exhaustiveCheck, getNow, SYNC, USER } from '../util';
|
|
36
36
|
import DataStoreConnectivity from './datastoreConnectivity';
|
|
37
37
|
import { ModelMerger } from './merger';
|
|
38
38
|
import { MutationEventOutbox } from './outbox';
|
|
@@ -122,7 +122,7 @@ export class SyncEngine {
|
|
|
122
122
|
public getModelSyncedStatus(
|
|
123
123
|
modelConstructor: PersistentModelConstructor<any>
|
|
124
124
|
): boolean {
|
|
125
|
-
return this.modelSyncedStatus.get(modelConstructor)
|
|
125
|
+
return this.modelSyncedStatus.get(modelConstructor);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
constructor(
|
|
@@ -235,8 +235,14 @@ export class SyncEngine {
|
|
|
235
235
|
);
|
|
236
236
|
} else {
|
|
237
237
|
//#region GraphQL Subscriptions
|
|
238
|
-
[
|
|
239
|
-
|
|
238
|
+
[
|
|
239
|
+
// const ctlObservable: Observable<CONTROL_MSG>
|
|
240
|
+
ctlSubsObservable,
|
|
241
|
+
// const dataObservable: Observable<[TransformerMutationType, SchemaModel, Readonly<{
|
|
242
|
+
// id: string;
|
|
243
|
+
// } & Record<string, any>>]>
|
|
244
|
+
dataSubsObservable,
|
|
245
|
+
] = this.subscriptionsProcessor.start();
|
|
240
246
|
|
|
241
247
|
try {
|
|
242
248
|
await new Promise((resolve, reject) => {
|
|
@@ -356,7 +362,7 @@ export class SyncEngine {
|
|
|
356
362
|
// TODO: extract to function
|
|
357
363
|
if (!isNode) {
|
|
358
364
|
subscriptions.push(
|
|
359
|
-
dataSubsObservable
|
|
365
|
+
dataSubsObservable.subscribe(
|
|
360
366
|
([_transformerMutationType, modelDefinition, item]) =>
|
|
361
367
|
this.runningProcesses.add(async () => {
|
|
362
368
|
const modelConstructor = this.userModelClasses[
|
|
@@ -415,11 +421,11 @@ export class SyncEngine {
|
|
|
415
421
|
] as PersistentModelConstructor<MutationEvent>;
|
|
416
422
|
const modelDefinition = this.getModelDefinition(model);
|
|
417
423
|
const graphQLCondition = predicateToGraphQLCondition(
|
|
418
|
-
condition
|
|
424
|
+
condition,
|
|
419
425
|
modelDefinition
|
|
420
426
|
);
|
|
421
427
|
const mutationEvent = createMutationInstanceFromModelOperation(
|
|
422
|
-
namespace.relationships
|
|
428
|
+
namespace.relationships,
|
|
423
429
|
this.getModelDefinition(model),
|
|
424
430
|
opType,
|
|
425
431
|
model,
|
|
@@ -494,7 +500,7 @@ export class SyncEngine {
|
|
|
494
500
|
fullSyncInterval,
|
|
495
501
|
lastSyncPredicate,
|
|
496
502
|
}) => {
|
|
497
|
-
const nextFullSync = lastFullSync
|
|
503
|
+
const nextFullSync = lastFullSync + fullSyncInterval;
|
|
498
504
|
const syncFrom =
|
|
499
505
|
!lastFullSync || nextFullSync < currentTimeStamp
|
|
500
506
|
? 0 // perform full sync if expired
|
|
@@ -502,7 +508,7 @@ export class SyncEngine {
|
|
|
502
508
|
|
|
503
509
|
return [
|
|
504
510
|
this.schema.namespaces[namespace].models[model],
|
|
505
|
-
[namespace, syncFrom
|
|
511
|
+
[namespace, syncFrom],
|
|
506
512
|
];
|
|
507
513
|
}
|
|
508
514
|
)
|
|
@@ -625,7 +631,7 @@ export class SyncEngine {
|
|
|
625
631
|
))
|
|
626
632
|
);
|
|
627
633
|
|
|
628
|
-
const counts = count.get(modelConstructor)
|
|
634
|
+
const counts = count.get(modelConstructor);
|
|
629
635
|
|
|
630
636
|
opTypeCount.forEach(([, opType]) => {
|
|
631
637
|
switch (opType) {
|
|
@@ -639,7 +645,7 @@ export class SyncEngine {
|
|
|
639
645
|
counts.deleted++;
|
|
640
646
|
break;
|
|
641
647
|
default:
|
|
642
|
-
|
|
648
|
+
exhaustiveCheck(opType);
|
|
643
649
|
}
|
|
644
650
|
});
|
|
645
651
|
});
|
|
@@ -659,10 +665,10 @@ export class SyncEngine {
|
|
|
659
665
|
|
|
660
666
|
newestFullSyncStartedAt =
|
|
661
667
|
newestFullSyncStartedAt === undefined
|
|
662
|
-
? lastFullSync
|
|
668
|
+
? lastFullSync
|
|
663
669
|
: Math.max(
|
|
664
670
|
newestFullSyncStartedAt,
|
|
665
|
-
isFullSync ? startedAt : lastFullSync
|
|
671
|
+
isFullSync ? startedAt : lastFullSync
|
|
666
672
|
);
|
|
667
673
|
|
|
668
674
|
modelMetadata = (
|
|
@@ -722,9 +728,9 @@ export class SyncEngine {
|
|
|
722
728
|
});
|
|
723
729
|
|
|
724
730
|
const msNextFullSync =
|
|
725
|
-
newestFullSyncStartedAt
|
|
726
|
-
theInterval
|
|
727
|
-
(newestStartedAt
|
|
731
|
+
newestFullSyncStartedAt +
|
|
732
|
+
theInterval -
|
|
733
|
+
(newestStartedAt + duration);
|
|
728
734
|
|
|
729
735
|
logger.debug(
|
|
730
736
|
`Next fullSync in ${msNextFullSync / 1000} seconds. (${new Date(
|
|
@@ -837,7 +843,7 @@ export class SyncEngine {
|
|
|
837
843
|
const promises = models.map(async ([namespace, model]) => {
|
|
838
844
|
const modelMetadata = await this.getModelMetadata(namespace, model.name);
|
|
839
845
|
const syncPredicate = ModelPredicateCreator.getPredicates(
|
|
840
|
-
this.syncPredicates.get(model)
|
|
846
|
+
this.syncPredicates.get(model),
|
|
841
847
|
false
|
|
842
848
|
);
|
|
843
849
|
const lastSyncPredicate = syncPredicate
|
|
@@ -849,9 +855,9 @@ export class SyncEngine {
|
|
|
849
855
|
this.modelInstanceCreator(ModelMetadataConstructor, {
|
|
850
856
|
model: model.name,
|
|
851
857
|
namespace,
|
|
852
|
-
lastSync: null
|
|
858
|
+
lastSync: null,
|
|
853
859
|
fullSyncInterval,
|
|
854
|
-
lastFullSync: null
|
|
860
|
+
lastFullSync: null,
|
|
855
861
|
lastSyncPredicate,
|
|
856
862
|
}),
|
|
857
863
|
undefined,
|
|
@@ -869,9 +875,9 @@ export class SyncEngine {
|
|
|
869
875
|
// perform a base sync if the syncPredicate changed in between calls to DataStore.start
|
|
870
876
|
// ensures that the local store contains all the data specified by the syncExpression
|
|
871
877
|
if (syncPredicateUpdated) {
|
|
872
|
-
draft.lastSync = null
|
|
873
|
-
draft.lastFullSync = null
|
|
874
|
-
|
|
878
|
+
draft.lastSync = null;
|
|
879
|
+
draft.lastFullSync = null;
|
|
880
|
+
draft.lastSyncPredicate = lastSyncPredicate;
|
|
875
881
|
}
|
|
876
882
|
})
|
|
877
883
|
);
|
package/src/sync/merger.ts
CHANGED
package/src/sync/outbox.ts
CHANGED
|
@@ -19,7 +19,7 @@ import { getIdentifierValue, TransformerMutationType } from './utils';
|
|
|
19
19
|
// TODO: Persist deleted ids
|
|
20
20
|
// https://github.com/aws-amplify/amplify-js/blob/datastore-docs/packages/datastore/docs/sync-engine.md#outbox
|
|
21
21
|
class MutationEventOutbox {
|
|
22
|
-
private inProgressMutationEventId
|
|
22
|
+
private inProgressMutationEventId: string;
|
|
23
23
|
|
|
24
24
|
constructor(
|
|
25
25
|
private readonly schema: InternalSchema,
|
|
@@ -88,7 +88,7 @@ class MutationEventOutbox {
|
|
|
88
88
|
await s.delete(this.MutationEvent, predicate);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
merged = merged
|
|
91
|
+
merged = merged || mutationEvent;
|
|
92
92
|
|
|
93
93
|
// Enqueue new one
|
|
94
94
|
await s.save(merged, undefined, this.ownSymbol);
|
|
@@ -104,11 +104,11 @@ class MutationEventOutbox {
|
|
|
104
104
|
const head = await this.peek(storage);
|
|
105
105
|
|
|
106
106
|
if (record) {
|
|
107
|
-
await this.syncOutboxVersionsOnDequeue(storage, record, head, recordOp
|
|
107
|
+
await this.syncOutboxVersionsOnDequeue(storage, record, head, recordOp);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
await storage.delete(head);
|
|
111
|
-
this.inProgressMutationEventId = undefined
|
|
111
|
+
this.inProgressMutationEventId = undefined;
|
|
112
112
|
|
|
113
113
|
return head;
|
|
114
114
|
}
|
|
@@ -121,9 +121,9 @@ class MutationEventOutbox {
|
|
|
121
121
|
public async peek(storage: StorageFacade): Promise<MutationEvent> {
|
|
122
122
|
const head = await storage.queryOne(this.MutationEvent, QueryOne.FIRST);
|
|
123
123
|
|
|
124
|
-
this.inProgressMutationEventId = head ? head.id : undefined
|
|
124
|
+
this.inProgressMutationEventId = head ? head.id : undefined;
|
|
125
125
|
|
|
126
|
-
return head
|
|
126
|
+
return head;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
public async getForModel<T extends PersistentModel>(
|
|
@@ -85,7 +85,7 @@ export function mapErrorToType(errorMap: ErrorMap, error: Error): ErrorType {
|
|
|
85
85
|
const errorTypes = [...Object.keys(errorMap)] as ErrorType[];
|
|
86
86
|
for (const errorType of errorTypes) {
|
|
87
87
|
const matcher = errorMap[errorType];
|
|
88
|
-
if (matcher
|
|
88
|
+
if (matcher(error)) {
|
|
89
89
|
return errorType;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import API, { GraphQLResult, GRAPHQL_AUTH_MODE } from '@aws-amplify/api';
|
|
2
2
|
import {
|
|
3
3
|
ConsoleLogger as Logger,
|
|
4
4
|
jitteredBackoff,
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
AmplifyContext,
|
|
30
30
|
} from '../../types';
|
|
31
31
|
import {
|
|
32
|
+
exhaustiveCheck,
|
|
32
33
|
extractTargetNamesFromSrc,
|
|
33
34
|
USER,
|
|
34
35
|
USER_AGENT_SUFFIX_DATASTORE,
|
|
@@ -56,7 +57,7 @@ type MutationProcessorEvent = {
|
|
|
56
57
|
};
|
|
57
58
|
|
|
58
59
|
class MutationProcessor {
|
|
59
|
-
private observer
|
|
60
|
+
private observer: ZenObservable.Observer<MutationProcessorEvent>;
|
|
60
61
|
private readonly typeQuery = new WeakMap<
|
|
61
62
|
SchemaModel,
|
|
62
63
|
[TransformerMutationType, string, string][]
|
|
@@ -117,8 +118,6 @@ class MutationProcessor {
|
|
|
117
118
|
}
|
|
118
119
|
|
|
119
120
|
public start(): Observable<MutationProcessorEvent> {
|
|
120
|
-
this.runningProcesses = new BackgroundProcessManager();
|
|
121
|
-
|
|
122
121
|
const observable = new Observable<MutationProcessorEvent>(observer => {
|
|
123
122
|
this.observer = observer;
|
|
124
123
|
|
|
@@ -167,10 +166,9 @@ class MutationProcessor {
|
|
|
167
166
|
const modelConstructor = this.userClasses[
|
|
168
167
|
model
|
|
169
168
|
] as PersistentModelConstructor<MutationEvent>;
|
|
170
|
-
let result: GraphQLResult<Record<string, PersistentModel
|
|
171
|
-
|
|
172
|
-
let
|
|
173
|
-
let modelDefinition: SchemaModel = undefined!;
|
|
169
|
+
let result: GraphQLResult<Record<string, PersistentModel>>;
|
|
170
|
+
let opName: string;
|
|
171
|
+
let modelDefinition: SchemaModel;
|
|
174
172
|
|
|
175
173
|
try {
|
|
176
174
|
const modelAuthModes = await getModelAuthModes({
|
|
@@ -195,7 +193,7 @@ class MutationProcessor {
|
|
|
195
193
|
operation,
|
|
196
194
|
data,
|
|
197
195
|
condition,
|
|
198
|
-
modelConstructor
|
|
196
|
+
modelConstructor,
|
|
199
197
|
this.MutationEvent,
|
|
200
198
|
head,
|
|
201
199
|
operationAuthModes[authModeAttempts],
|
|
@@ -246,7 +244,7 @@ class MutationProcessor {
|
|
|
246
244
|
continue;
|
|
247
245
|
}
|
|
248
246
|
|
|
249
|
-
const record = result.data
|
|
247
|
+
const record = result.data[opName];
|
|
250
248
|
let hasMore = false;
|
|
251
249
|
|
|
252
250
|
await this.storage.runExclusive(async storage => {
|
|
@@ -256,7 +254,7 @@ class MutationProcessor {
|
|
|
256
254
|
hasMore = (await this.outbox.peek(storage)) !== undefined;
|
|
257
255
|
});
|
|
258
256
|
|
|
259
|
-
this.observer.next
|
|
257
|
+
this.observer.next({
|
|
260
258
|
operation,
|
|
261
259
|
modelDefinition,
|
|
262
260
|
model: record,
|
|
@@ -324,8 +322,9 @@ class MutationProcessor {
|
|
|
324
322
|
await this.amplifyContext.API.graphql(tryWith)
|
|
325
323
|
);
|
|
326
324
|
|
|
327
|
-
|
|
328
|
-
//
|
|
325
|
+
|
|
326
|
+
// `as any` because TypeScript doesn't seem to like passing tuples
|
|
327
|
+
// through generic params???
|
|
329
328
|
return [result, opName, modelDefinition] as any;
|
|
330
329
|
} catch (err) {
|
|
331
330
|
if (err.errors && err.errors.length > 0) {
|
|
@@ -356,7 +355,7 @@ class MutationProcessor {
|
|
|
356
355
|
retryWith = DISCARD;
|
|
357
356
|
} else {
|
|
358
357
|
try {
|
|
359
|
-
retryWith = await this.conflictHandler
|
|
358
|
+
retryWith = await this.conflictHandler({
|
|
360
359
|
modelConstructor,
|
|
361
360
|
localModel: this.modelInstanceCreator(
|
|
362
361
|
modelConstructor,
|
|
@@ -409,7 +408,7 @@ class MutationProcessor {
|
|
|
409
408
|
// convert retry with to tryWith
|
|
410
409
|
const updatedMutation =
|
|
411
410
|
createMutationInstanceFromModelOperation(
|
|
412
|
-
namespace.relationships
|
|
411
|
+
namespace.relationships,
|
|
413
412
|
modelDefinition,
|
|
414
413
|
opType,
|
|
415
414
|
modelConstructor,
|
|
@@ -437,7 +436,7 @@ class MutationProcessor {
|
|
|
437
436
|
cause: error,
|
|
438
437
|
remoteModel: error.data
|
|
439
438
|
? this.modelInstanceCreator(modelConstructor, error.data)
|
|
440
|
-
: null
|
|
439
|
+
: null,
|
|
441
440
|
});
|
|
442
441
|
} catch (err) {
|
|
443
442
|
logger.warn('Mutation error handler failed with:', err);
|
|
@@ -482,13 +481,13 @@ class MutationProcessor {
|
|
|
482
481
|
condition: string
|
|
483
482
|
): [string, Record<string, any>, GraphQLCondition, string, SchemaModel] {
|
|
484
483
|
const modelDefinition = this.schema.namespaces[namespaceName].models[model];
|
|
485
|
-
const { primaryKey } = this.schema.namespaces[namespaceName].keys
|
|
484
|
+
const { primaryKey } = this.schema.namespaces[namespaceName].keys[model];
|
|
486
485
|
|
|
487
486
|
const queriesTuples = this.typeQuery.get(modelDefinition);
|
|
488
487
|
|
|
489
|
-
const [, opName, query] = queriesTuples
|
|
488
|
+
const [, opName, query] = queriesTuples.find(
|
|
490
489
|
([transformerMutationType]) => transformerMutationType === operation
|
|
491
|
-
)
|
|
490
|
+
);
|
|
492
491
|
|
|
493
492
|
const { _version, ...parsedData } = <ModelInstanceMetadata>JSON.parse(data);
|
|
494
493
|
|
|
@@ -581,11 +580,8 @@ class MutationProcessor {
|
|
|
581
580
|
case TransformerMutationType.GET: // Intentionally blank
|
|
582
581
|
break;
|
|
583
582
|
default:
|
|
584
|
-
|
|
583
|
+
exhaustiveCheck(operation);
|
|
585
584
|
}
|
|
586
|
-
|
|
587
|
-
// because it makes TS happy ...
|
|
588
|
-
return undefined!;
|
|
589
585
|
}
|
|
590
586
|
|
|
591
587
|
public pause() {
|