@aws-amplify/datastore 3.7.3-webpack5.5 → 3.7.4-custom-pk.80

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.
Files changed (137) hide show
  1. package/CHANGELOG.md +153 -15
  2. package/README.md +154 -0
  3. package/dist/aws-amplify-datastore.js +4638 -2685
  4. package/dist/aws-amplify-datastore.js.map +1 -1
  5. package/dist/aws-amplify-datastore.min.js +25 -95
  6. package/dist/aws-amplify-datastore.min.js.map +1 -1
  7. package/lib/authModeStrategies/multiAuthStrategy.d.ts +2 -2
  8. package/lib/authModeStrategies/multiAuthStrategy.js +32 -26
  9. package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
  10. package/lib/datastore/datastore.d.ts +17 -16
  11. package/lib/datastore/datastore.js +249 -78
  12. package/lib/datastore/datastore.js.map +1 -1
  13. package/lib/index.d.ts +3 -19
  14. package/lib/predicates/index.d.ts +3 -2
  15. package/lib/predicates/index.js +12 -2
  16. package/lib/predicates/index.js.map +1 -1
  17. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
  18. package/lib/storage/adapter/AsyncStorageAdapter.js +140 -66
  19. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  20. package/lib/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
  21. package/lib/storage/adapter/AsyncStorageDatabase.js +57 -27
  22. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  23. package/lib/storage/adapter/InMemoryStore.js +2 -2
  24. package/lib/storage/adapter/InMemoryStore.js.map +1 -1
  25. package/lib/storage/adapter/IndexedDBAdapter.d.ts +7 -2
  26. package/lib/storage/adapter/IndexedDBAdapter.js +454 -252
  27. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  28. package/lib/storage/adapter/index.d.ts +1 -1
  29. package/lib/storage/storage.d.ts +3 -3
  30. package/lib/storage/storage.js +106 -28
  31. package/lib/storage/storage.js.map +1 -1
  32. package/lib/sync/index.d.ts +23 -7
  33. package/lib/sync/index.js +18 -17
  34. package/lib/sync/index.js.map +1 -1
  35. package/lib/sync/merger.d.ts +3 -3
  36. package/lib/sync/merger.js +8 -6
  37. package/lib/sync/merger.js.map +1 -1
  38. package/lib/sync/outbox.d.ts +2 -2
  39. package/lib/sync/outbox.js +12 -9
  40. package/lib/sync/outbox.js.map +1 -1
  41. package/lib/sync/processors/errorMaps.d.ts +17 -0
  42. package/lib/sync/processors/errorMaps.js +125 -0
  43. package/lib/sync/processors/errorMaps.js.map +1 -0
  44. package/lib/sync/processors/mutation.d.ts +22 -4
  45. package/lib/sync/processors/mutation.js +119 -51
  46. package/lib/sync/processors/mutation.js.map +1 -1
  47. package/lib/sync/processors/subscription.d.ts +4 -2
  48. package/lib/sync/processors/subscription.js +76 -41
  49. package/lib/sync/processors/subscription.js.map +1 -1
  50. package/lib/sync/processors/sync.d.ts +4 -2
  51. package/lib/sync/processors/sync.js +62 -27
  52. package/lib/sync/processors/sync.js.map +1 -1
  53. package/lib/sync/utils.d.ts +3 -2
  54. package/lib/sync/utils.js +58 -7
  55. package/lib/sync/utils.js.map +1 -1
  56. package/lib/types.d.ts +90 -34
  57. package/lib/types.js +31 -2
  58. package/lib/types.js.map +1 -1
  59. package/lib/util.d.ts +44 -33
  60. package/lib/util.js +210 -57
  61. package/lib/util.js.map +1 -1
  62. package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +2 -2
  63. package/lib-esm/authModeStrategies/multiAuthStrategy.js +32 -26
  64. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
  65. package/lib-esm/datastore/datastore.d.ts +17 -16
  66. package/lib-esm/datastore/datastore.js +251 -80
  67. package/lib-esm/datastore/datastore.js.map +1 -1
  68. package/lib-esm/index.d.ts +3 -19
  69. package/lib-esm/predicates/index.d.ts +3 -2
  70. package/lib-esm/predicates/index.js +13 -3
  71. package/lib-esm/predicates/index.js.map +1 -1
  72. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
  73. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +140 -66
  74. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  75. package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
  76. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +57 -27
  77. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  78. package/lib-esm/storage/adapter/InMemoryStore.js +2 -2
  79. package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
  80. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +7 -2
  81. package/lib-esm/storage/adapter/IndexedDBAdapter.js +454 -252
  82. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  83. package/lib-esm/storage/adapter/index.d.ts +1 -1
  84. package/lib-esm/storage/storage.d.ts +3 -3
  85. package/lib-esm/storage/storage.js +106 -28
  86. package/lib-esm/storage/storage.js.map +1 -1
  87. package/lib-esm/sync/index.d.ts +23 -7
  88. package/lib-esm/sync/index.js +20 -19
  89. package/lib-esm/sync/index.js.map +1 -1
  90. package/lib-esm/sync/merger.d.ts +3 -3
  91. package/lib-esm/sync/merger.js +8 -6
  92. package/lib-esm/sync/merger.js.map +1 -1
  93. package/lib-esm/sync/outbox.d.ts +2 -2
  94. package/lib-esm/sync/outbox.js +13 -10
  95. package/lib-esm/sync/outbox.js.map +1 -1
  96. package/lib-esm/sync/processors/errorMaps.d.ts +17 -0
  97. package/lib-esm/sync/processors/errorMaps.js +119 -0
  98. package/lib-esm/sync/processors/errorMaps.js.map +1 -0
  99. package/lib-esm/sync/processors/mutation.d.ts +22 -4
  100. package/lib-esm/sync/processors/mutation.js +122 -54
  101. package/lib-esm/sync/processors/mutation.js.map +1 -1
  102. package/lib-esm/sync/processors/subscription.d.ts +4 -2
  103. package/lib-esm/sync/processors/subscription.js +77 -42
  104. package/lib-esm/sync/processors/subscription.js.map +1 -1
  105. package/lib-esm/sync/processors/sync.d.ts +4 -2
  106. package/lib-esm/sync/processors/sync.js +62 -27
  107. package/lib-esm/sync/processors/sync.js.map +1 -1
  108. package/lib-esm/sync/utils.d.ts +3 -2
  109. package/lib-esm/sync/utils.js +58 -8
  110. package/lib-esm/sync/utils.js.map +1 -1
  111. package/lib-esm/types.d.ts +90 -34
  112. package/lib-esm/types.js +29 -3
  113. package/lib-esm/types.js.map +1 -1
  114. package/lib-esm/util.d.ts +44 -33
  115. package/lib-esm/util.js +199 -54
  116. package/lib-esm/util.js.map +1 -1
  117. package/package.json +10 -9
  118. package/src/authModeStrategies/multiAuthStrategy.ts +24 -21
  119. package/src/datastore/datastore.ts +395 -143
  120. package/src/predicates/index.ts +32 -10
  121. package/src/storage/adapter/AsyncStorageAdapter.ts +161 -61
  122. package/src/storage/adapter/AsyncStorageDatabase.ts +62 -25
  123. package/src/storage/adapter/InMemoryStore.ts +2 -2
  124. package/src/storage/adapter/IndexedDBAdapter.ts +345 -101
  125. package/src/storage/adapter/index.ts +1 -1
  126. package/src/storage/storage.ts +85 -24
  127. package/src/sync/index.ts +74 -58
  128. package/src/sync/merger.ts +16 -4
  129. package/src/sync/outbox.ts +22 -8
  130. package/src/sync/processors/errorMaps.ts +93 -0
  131. package/src/sync/processors/mutation.ts +143 -84
  132. package/src/sync/processors/subscription.ts +67 -36
  133. package/src/sync/processors/sync.ts +37 -12
  134. package/src/sync/utils.ts +67 -16
  135. package/src/types.ts +252 -50
  136. package/src/util.ts +241 -42
  137. package/ssr/package.json +1 -1
@@ -87,7 +87,10 @@ var __spread = (this && this.__spread) || function () {
87
87
  for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
88
88
  return ar;
89
89
  };
90
+ import API from '@aws-amplify/api';
90
91
  import { Amplify, ConsoleLogger as Logger, Hub, JS } from '@aws-amplify/core';
92
+ import { Auth } from '@aws-amplify/auth';
93
+ import Cache from '@aws-amplify/cache';
91
94
  import { immerable, produce, setAutoFreeze, enablePatches, } from 'immer';
92
95
  import { v4 as uuid4 } from 'uuid';
93
96
  import Observable from 'zen-observable-ts';
@@ -95,8 +98,8 @@ import { defaultAuthStrategy, multiAuthStrategy } from '../authModeStrategies';
95
98
  import { isPredicatesAll, ModelPredicateCreator, ModelSortPredicateCreator, } from '../predicates';
96
99
  import { ExclusiveStorage as Storage } from '../storage/storage';
97
100
  import { ControlMessage, SyncEngine } from '../sync';
98
- import { GraphQLScalarType, isGraphQLScalarType, AuthModeStrategyType, isNonModelFieldType, isModelFieldType, } from '../types';
99
- import { DATASTORE, establishRelationAndKeys, exhaustiveCheck, isModelConstructor, monotonicUlidFactory, STORAGE, SYNC, USER, isNullOrUndefined, registerNonModelClass, sortCompareFunction, DeferredCallbackResolver, } from '../util';
101
+ import { GraphQLScalarType, isGraphQLScalarType, AuthModeStrategyType, isNonModelFieldType, isModelFieldType, __modelMeta__, isIdentifierObject, } from '../types';
102
+ import { DATASTORE, establishRelationAndKeys, exhaustiveCheck, isModelConstructor, monotonicUlidFactory, STORAGE, SYNC, USER, isNullOrUndefined, registerNonModelClass, sortCompareFunction, DeferredCallbackResolver, extractPrimaryKeyFieldNames, isIdManaged, isIdOptionallyManaged, validatePredicate, mergePatches, } from '../util';
100
103
  setAutoFreeze(true);
101
104
  enablePatches();
102
105
  var logger = new Logger('DataStore');
@@ -201,6 +204,18 @@ var initSchema = function (userSchema) {
201
204
  });
202
205
  return userClasses;
203
206
  };
207
+ /* Checks if the schema has been initialized by initSchema().
208
+ *
209
+ * Call this function before accessing schema.
210
+ * Currently this only needs to be called in start() and clear() because all other functions will call start first.
211
+ */
212
+ var checkSchemaInitialized = function () {
213
+ if (schema === undefined) {
214
+ var message = 'Schema is not initialized. DataStore will not function as expected. This could happen if you have multiple versions of DataStore installed. Please see https://docs.amplify.aws/lib/troubleshooting/upgrading/q/platform/js/#check-for-duplicate-versions';
215
+ logger.error(message);
216
+ throw new Error(message);
217
+ }
218
+ };
204
219
  var createTypeClasses = function (namespace) {
205
220
  var classes = {};
206
221
  Object.entries(namespace.models).forEach(function (_a) {
@@ -329,21 +344,29 @@ var createModelClass = function (modelDefinition) {
329
344
  function Model(init) {
330
345
  var instance = produce(this, function (draft) {
331
346
  initializeInstance(init, modelDefinition, draft);
332
- var modelInstanceMetadata = instancesMetadata.has(init)
347
+ // model is initialized inside a DataStore component (e.g. by Sync Engine, Storage Engine, etc.)
348
+ var isInternallyInitialized = instancesMetadata.has(init);
349
+ var modelInstanceMetadata = isInternallyInitialized
333
350
  ? init
334
351
  : {};
335
- var _id = modelInstanceMetadata.id, _version = modelInstanceMetadata._version, _lastChangedAt = modelInstanceMetadata._lastChangedAt, _deleted = modelInstanceMetadata._deleted;
336
- // instancesIds are set by modelInstanceCreator, it is accessible only internally
337
- var isInternal = _id !== null && _id !== undefined;
338
- var id = isInternal
339
- ? _id
340
- : modelDefinition.syncable
341
- ? uuid4()
342
- : ulid();
343
- if (!isInternal) {
352
+ var _id = modelInstanceMetadata.id;
353
+ if (isIdManaged(modelDefinition)) {
354
+ var isInternalModel = _id !== null && _id !== undefined;
355
+ var id = isInternalModel
356
+ ? _id
357
+ : modelDefinition.syncable
358
+ ? uuid4()
359
+ : ulid();
360
+ draft.id = id;
361
+ }
362
+ else if (isIdOptionallyManaged(modelDefinition)) {
363
+ // only auto-populate if the id was not provided
364
+ draft.id = draft.id || uuid4();
365
+ }
366
+ if (!isInternallyInitialized) {
344
367
  checkReadOnlyPropertyOnCreate(draft, modelDefinition);
345
368
  }
346
- draft.id = id;
369
+ var _version = modelInstanceMetadata._version, _lastChangedAt = modelInstanceMetadata._lastChangedAt, _deleted = modelInstanceMetadata._deleted;
347
370
  if (modelDefinition.syncable) {
348
371
  draft._version = _version;
349
372
  draft._lastChangedAt = _lastChangedAt;
@@ -362,7 +385,10 @@ var createModelClass = function (modelDefinition) {
362
385
  var patches;
363
386
  var model = produce(source, function (draft) {
364
387
  fn(draft);
365
- draft.id = source.id;
388
+ var keyNames = extractPrimaryKeyFieldNames(modelDefinition);
389
+ // Keys are immutable
390
+ // @ts-ignore TODO: fix type
391
+ keyNames.forEach(function (key) { return (draft[key] = source[key]); });
366
392
  var modelValidator = validateModelFields(modelDefinition);
367
393
  Object.entries(draft).forEach(function (_a) {
368
394
  var _b = __read(_a, 2), k = _b[0], v = _b[1];
@@ -370,9 +396,18 @@ var createModelClass = function (modelDefinition) {
370
396
  modelValidator(k, parsedValue);
371
397
  });
372
398
  }, function (p) { return (patches = p); });
373
- if (patches.length) {
374
- modelPatchesMap.set(model, [patches, source]);
375
- checkReadOnlyPropertyOnUpdate(patches, modelDefinition);
399
+ var hasExistingPatches = modelPatchesMap.has(source);
400
+ if (patches.length || hasExistingPatches) {
401
+ if (hasExistingPatches) {
402
+ var _a = __read(modelPatchesMap.get(source), 2), existingPatches = _a[0], existingSource = _a[1];
403
+ var mergedPatches = mergePatches(existingSource, existingPatches, patches);
404
+ modelPatchesMap.set(model, [mergedPatches, existingSource]);
405
+ checkReadOnlyPropertyOnUpdate(mergedPatches, modelDefinition);
406
+ }
407
+ else {
408
+ modelPatchesMap.set(model, [patches, source]);
409
+ checkReadOnlyPropertyOnUpdate(patches, modelDefinition);
410
+ }
376
411
  }
377
412
  return model;
378
413
  };
@@ -486,7 +521,6 @@ function checkSchemaVersion(storage, version) {
486
521
  return __generator(this, function (_b) {
487
522
  switch (_b.label) {
488
523
  case 0: return [4 /*yield*/, s.query(Setting, ModelPredicateCreator.createFromExisting(modelDefinition, function (c) {
489
- // @ts-ignore Argument of type '"eq"' is not assignable to parameter of type 'never'.
490
524
  return c.key('eq', SETTING_SCHEMA_VERSION);
491
525
  }), { page: 0, limit: 1 })];
492
526
  case 1:
@@ -558,8 +592,18 @@ function getNamespace() {
558
592
  var DataStore = /** @class */ (function () {
559
593
  function DataStore() {
560
594
  var _this = this;
595
+ // reference to configured category instances. Used for preserving SSR context
596
+ this.Auth = Auth;
597
+ this.API = API;
598
+ this.Cache = Cache;
561
599
  this.amplifyConfig = {};
562
600
  this.syncPredicates = new WeakMap();
601
+ // object that gets passed to descendent classes. Allows us to pass these down by reference
602
+ this.amplifyContext = {
603
+ Auth: this.Auth,
604
+ API: this.API,
605
+ Cache: this.Cache,
606
+ };
563
607
  this.start = function () { return __awaiter(_this, void 0, void 0, function () {
564
608
  var aws_appsync_graphqlEndpoint, _a, fullSyncIntervalInMilliseconds;
565
609
  var _this = this;
@@ -582,6 +626,7 @@ var DataStore = /** @class */ (function () {
582
626
  return [4 /*yield*/, this.storage.init()];
583
627
  case 4:
584
628
  _b.sent();
629
+ checkSchemaInitialized();
585
630
  return [4 /*yield*/, checkSchemaVersion(this.storage, schema.version)];
586
631
  case 5:
587
632
  _b.sent();
@@ -592,7 +637,7 @@ var DataStore = /** @class */ (function () {
592
637
  return [4 /*yield*/, this.processSyncExpressions()];
593
638
  case 6:
594
639
  _a.syncPredicates = _b.sent();
595
- this.sync = new SyncEngine(schema, namespaceResolver, syncClasses, userClasses, this.storage, modelInstanceCreator, this.maxRecordsToSync, this.syncPageSize, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy);
640
+ this.sync = new SyncEngine(schema, namespaceResolver, syncClasses, userClasses, this.storage, modelInstanceCreator, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy, this.amplifyContext);
596
641
  fullSyncIntervalInMilliseconds = this.fullSyncInterval * 1000 * 60;
597
642
  syncSubscription = this.sync
598
643
  .start({ fullSyncInterval: fullSyncIntervalInMilliseconds })
@@ -631,8 +676,8 @@ var DataStore = /** @class */ (function () {
631
676
  }
632
677
  });
633
678
  }); };
634
- this.query = function (modelConstructor, idOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
635
- var msg, modelDefinition, predicate, pagination, result;
679
+ this.query = function (modelConstructor, identifierOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
680
+ var msg, modelDefinition, keyFields, predicate, pagination, result, isSingleFieldIdentifier, returnOne;
636
681
  return __generator(this, function (_a) {
637
682
  switch (_a.label) {
638
683
  case 0: return [4 /*yield*/, this.start()];
@@ -644,22 +689,27 @@ var DataStore = /** @class */ (function () {
644
689
  logger.error(msg, { modelConstructor: modelConstructor });
645
690
  throw new Error(msg);
646
691
  }
647
- if (typeof idOrCriteria === 'string') {
692
+ if (typeof identifierOrCriteria === 'string') {
648
693
  if (paginationProducer !== undefined) {
649
694
  logger.warn('Pagination is ignored when querying by id');
650
695
  }
651
696
  }
652
697
  modelDefinition = getModelDefinition(modelConstructor);
653
- if (isQueryOne(idOrCriteria)) {
654
- predicate = ModelPredicateCreator.createForId(modelDefinition, idOrCriteria);
698
+ keyFields = extractPrimaryKeyFieldNames(modelDefinition);
699
+ if (isQueryOne(identifierOrCriteria)) {
700
+ predicate = ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], identifierOrCriteria);
655
701
  }
656
702
  else {
657
- if (isPredicatesAll(idOrCriteria)) {
703
+ // Object is being queried using object literal syntax
704
+ if (isIdentifierObject(identifierOrCriteria, modelDefinition)) {
705
+ predicate = ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
706
+ }
707
+ else if (isPredicatesAll(identifierOrCriteria)) {
658
708
  // Predicates.ALL means "all records", so no predicate (undefined)
659
709
  predicate = undefined;
660
710
  }
661
711
  else {
662
- predicate = ModelPredicateCreator.createFromExisting(modelDefinition, idOrCriteria);
712
+ predicate = ModelPredicateCreator.createFromExisting(modelDefinition, identifierOrCriteria);
663
713
  }
664
714
  }
665
715
  pagination = this.processPagination(modelDefinition, paginationProducer);
@@ -672,7 +722,11 @@ var DataStore = /** @class */ (function () {
672
722
  return [4 /*yield*/, this.storage.query(modelConstructor, predicate, pagination)];
673
723
  case 2:
674
724
  result = _a.sent();
675
- return [2 /*return*/, isQueryOne(idOrCriteria) ? result[0] : result];
725
+ isSingleFieldIdentifier = keyFields.length === 1;
726
+ returnOne = isSingleFieldIdentifier &&
727
+ (isQueryOne(identifierOrCriteria) ||
728
+ isIdentifierObject(identifierOrCriteria, modelDefinition));
729
+ return [2 /*return*/, returnOne ? result[0] : result];
676
730
  }
677
731
  });
678
732
  }); };
@@ -701,7 +755,7 @@ var DataStore = /** @class */ (function () {
701
755
  case 0: return [4 /*yield*/, s.save(model, producedCondition, undefined, patchesTuple)];
702
756
  case 1:
703
757
  _a.sent();
704
- return [2 /*return*/, s.query(modelConstructor, ModelPredicateCreator.createForId(modelDefinition, model.id))];
758
+ return [2 /*return*/, s.query(modelConstructor, ModelPredicateCreator.createForPk(modelDefinition, model))];
705
759
  }
706
760
  });
707
761
  }); })];
@@ -737,13 +791,13 @@ var DataStore = /** @class */ (function () {
737
791
  }
738
792
  return _this.errorHandler || defaultErrorHandler;
739
793
  };
740
- this.delete = function (modelOrConstructor, idOrCriteria) { return __awaiter(_this, void 0, void 0, function () {
741
- var condition, msg, modelConstructor, msg, msg, _a, deleted, model, modelConstructor, msg, modelDefinition, idPredicate, msg, _b, _c, deleted;
742
- return __generator(this, function (_d) {
743
- switch (_d.label) {
794
+ this.delete = function (modelOrConstructor, identifierOrCriteria) { return __awaiter(_this, void 0, void 0, function () {
795
+ var condition, msg, modelConstructor, msg, modelDefinition, _a, keyField, msg, _b, deleted, model, modelConstructor, msg, modelDefinition, pkPredicate, msg, _c, _d, deleted;
796
+ return __generator(this, function (_e) {
797
+ switch (_e.label) {
744
798
  case 0: return [4 /*yield*/, this.start()];
745
799
  case 1:
746
- _d.sent();
800
+ _e.sent();
747
801
  if (!modelOrConstructor) {
748
802
  msg = 'Model or Model Constructor required';
749
803
  logger.error(msg, { modelOrConstructor: modelOrConstructor });
@@ -751,21 +805,28 @@ var DataStore = /** @class */ (function () {
751
805
  }
752
806
  if (!isValidModelConstructor(modelOrConstructor)) return [3 /*break*/, 3];
753
807
  modelConstructor = modelOrConstructor;
754
- if (!idOrCriteria) {
808
+ if (!identifierOrCriteria) {
755
809
  msg = 'Id to delete or criteria required. Do you want to delete all? Pass Predicates.ALL';
756
- logger.error(msg, { idOrCriteria: idOrCriteria });
810
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
757
811
  throw new Error(msg);
758
812
  }
759
- if (typeof idOrCriteria === 'string') {
760
- condition = ModelPredicateCreator.createForId(getModelDefinition(modelConstructor), idOrCriteria);
813
+ modelDefinition = getModelDefinition(modelConstructor);
814
+ if (typeof identifierOrCriteria === 'string') {
815
+ _a = __read(extractPrimaryKeyFieldNames(modelDefinition), 1), keyField = _a[0];
816
+ condition = ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyField, identifierOrCriteria);
761
817
  }
762
818
  else {
763
- condition = ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor),
764
- /**
765
- * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
766
- * The symbol is used only for typing purposes. e.g. see Predicates.ALL
767
- */
768
- idOrCriteria);
819
+ if (isIdentifierObject(identifierOrCriteria, modelDefinition)) {
820
+ condition = ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
821
+ }
822
+ else {
823
+ condition = ModelPredicateCreator.createFromExisting(modelDefinition,
824
+ /**
825
+ * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
826
+ * The symbol is used only for typing purposes. e.g. see Predicates.ALL
827
+ */
828
+ identifierOrCriteria);
829
+ }
769
830
  if (!condition || !ModelPredicateCreator.isValidPredicate(condition)) {
770
831
  msg = 'Criteria required. Do you want to delete all? Pass Predicates.ALL';
771
832
  logger.error(msg, { condition: condition });
@@ -774,7 +835,7 @@ var DataStore = /** @class */ (function () {
774
835
  }
775
836
  return [4 /*yield*/, this.storage.delete(modelConstructor, condition)];
776
837
  case 2:
777
- _a = __read.apply(void 0, [_d.sent(), 1]), deleted = _a[0];
838
+ _b = __read.apply(void 0, [_e.sent(), 1]), deleted = _b[0];
778
839
  return [2 /*return*/, deleted];
779
840
  case 3:
780
841
  model = modelOrConstructor;
@@ -786,26 +847,26 @@ var DataStore = /** @class */ (function () {
786
847
  throw new Error(msg);
787
848
  }
788
849
  modelDefinition = getModelDefinition(modelConstructor);
789
- idPredicate = ModelPredicateCreator.createForId(modelDefinition, model.id);
790
- if (idOrCriteria) {
791
- if (typeof idOrCriteria !== 'function') {
850
+ pkPredicate = ModelPredicateCreator.createForPk(modelDefinition, model);
851
+ if (identifierOrCriteria) {
852
+ if (typeof identifierOrCriteria !== 'function') {
792
853
  msg = 'Invalid criteria';
793
- logger.error(msg, { idOrCriteria: idOrCriteria });
854
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
794
855
  throw new Error(msg);
795
856
  }
796
- condition = idOrCriteria(idPredicate);
857
+ condition = identifierOrCriteria(pkPredicate);
797
858
  }
798
859
  else {
799
- condition = idPredicate;
860
+ condition = pkPredicate;
800
861
  }
801
862
  return [4 /*yield*/, this.storage.delete(model, condition)];
802
863
  case 4:
803
- _b = __read.apply(void 0, [_d.sent(), 1]), _c = __read(_b[0], 1), deleted = _c[0];
864
+ _c = __read.apply(void 0, [_e.sent(), 1]), _d = __read(_c[0], 1), deleted = _d[0];
804
865
  return [2 /*return*/, deleted];
805
866
  }
806
867
  });
807
868
  }); };
808
- this.observe = function (modelOrConstructor, idOrCriteria) {
869
+ this.observe = function (modelOrConstructor, identifierOrCriteria) {
809
870
  var predicate;
810
871
  var modelConstructor = modelOrConstructor && isValidModelConstructor(modelOrConstructor)
811
872
  ? modelOrConstructor
@@ -814,10 +875,10 @@ var DataStore = /** @class */ (function () {
814
875
  var model = modelOrConstructor;
815
876
  var modelConstructor_1 = model && Object.getPrototypeOf(model).constructor;
816
877
  if (isValidModelConstructor(modelConstructor_1)) {
817
- if (idOrCriteria) {
878
+ if (identifierOrCriteria) {
818
879
  logger.warn('idOrCriteria is ignored when using a model instance', {
819
880
  model: model,
820
- idOrCriteria: idOrCriteria,
881
+ identifierOrCriteria: identifierOrCriteria,
821
882
  });
822
883
  }
823
884
  return _this.observe(modelConstructor_1, model.id);
@@ -828,9 +889,9 @@ var DataStore = /** @class */ (function () {
828
889
  throw new Error(msg);
829
890
  }
830
891
  }
831
- if (idOrCriteria !== undefined && modelConstructor === undefined) {
892
+ if (identifierOrCriteria !== undefined && modelConstructor === undefined) {
832
893
  var msg = 'Cannot provide criteria without a modelConstructor';
833
- logger.error(msg, idOrCriteria);
894
+ logger.error(msg, identifierOrCriteria);
834
895
  throw new Error(msg);
835
896
  }
836
897
  if (modelConstructor && !isValidModelConstructor(modelConstructor)) {
@@ -838,29 +899,60 @@ var DataStore = /** @class */ (function () {
838
899
  logger.error(msg, { modelConstructor: modelConstructor });
839
900
  throw new Error(msg);
840
901
  }
841
- if (typeof idOrCriteria === 'string') {
842
- predicate = ModelPredicateCreator.createForId(getModelDefinition(modelConstructor), idOrCriteria);
902
+ if (typeof identifierOrCriteria === 'string') {
903
+ var modelDefinition = getModelDefinition(modelConstructor);
904
+ var _a = __read(extractPrimaryKeyFieldNames(modelDefinition), 1), keyField = _a[0];
905
+ predicate = ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyField, identifierOrCriteria);
843
906
  }
844
907
  else {
845
- predicate =
846
- modelConstructor &&
847
- ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor), idOrCriteria);
908
+ if (isPredicatesAll(identifierOrCriteria)) {
909
+ predicate = undefined;
910
+ }
911
+ else {
912
+ predicate =
913
+ modelConstructor &&
914
+ ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor), identifierOrCriteria);
915
+ }
848
916
  }
849
917
  return new Observable(function (observer) {
850
918
  var handle;
851
919
  (function () { return __awaiter(_this, void 0, void 0, function () {
920
+ var _this = this;
852
921
  return __generator(this, function (_a) {
853
922
  switch (_a.label) {
854
923
  case 0: return [4 /*yield*/, this.start()];
855
924
  case 1:
856
925
  _a.sent();
926
+ // Filter the events returned by Storage according to namespace,
927
+ // append original element data, and subscribe to the observable
857
928
  handle = this.storage
858
929
  .observe(modelConstructor, predicate)
859
930
  .filter(function (_a) {
860
931
  var model = _a.model;
861
932
  return namespaceResolver(model) === USER;
862
933
  })
863
- .subscribe(observer);
934
+ .subscribe({
935
+ next: function (item) { return __awaiter(_this, void 0, void 0, function () {
936
+ var message, freshElement;
937
+ return __generator(this, function (_a) {
938
+ switch (_a.label) {
939
+ case 0:
940
+ message = item;
941
+ if (!(item.opType !== 'DELETE')) return [3 /*break*/, 2];
942
+ return [4 /*yield*/, this.query(item.model, item.element.id)];
943
+ case 1:
944
+ freshElement = _a.sent();
945
+ message = __assign(__assign({}, message), { element: freshElement });
946
+ _a.label = 2;
947
+ case 2:
948
+ observer.next(message);
949
+ return [2 /*return*/];
950
+ }
951
+ });
952
+ }); },
953
+ error: function (err) { return observer.error(err); },
954
+ complete: function () { return observer.complete(); },
955
+ });
864
956
  return [2 /*return*/];
865
957
  }
866
958
  });
@@ -878,6 +970,17 @@ var DataStore = /** @class */ (function () {
878
970
  var itemsChanged = new Map();
879
971
  var deletedItemIds = [];
880
972
  var handle;
973
+ var predicate;
974
+ /**
975
+ * As the name suggests, this geneates a snapshot in the form of
976
+ * `{items: T[], isSynced: boolean}`
977
+ * and sends it to the observer.
978
+ *
979
+ * SIDE EFFECT: The underlying generation and emission methods may touch:
980
+ * `items`, `itemsChanged`, and `deletedItemIds`.
981
+ *
982
+ * Refer to `generateSnapshot` and `emitSnapshot` for more details.
983
+ */
881
984
  var generateAndEmitSnapshot = function () {
882
985
  var snapshot = generateSnapshot();
883
986
  emitSnapshot(snapshot);
@@ -891,6 +994,22 @@ var DataStore = /** @class */ (function () {
891
994
  });
892
995
  var sort = (options || {}).sort;
893
996
  var sortOptions = sort ? { sort: sort } : undefined;
997
+ var modelDefinition = getModelDefinition(model);
998
+ var keyFields = extractPrimaryKeyFieldNames(modelDefinition);
999
+ if (isQueryOne(criteria)) {
1000
+ predicate = ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], criteria);
1001
+ }
1002
+ else {
1003
+ if (isPredicatesAll(criteria)) {
1004
+ // Predicates.ALL means "all records", so no predicate (undefined)
1005
+ predicate = undefined;
1006
+ }
1007
+ else {
1008
+ predicate = ModelPredicateCreator.createFromExisting(modelDefinition, criteria);
1009
+ }
1010
+ }
1011
+ var _a = ModelPredicateCreator.getPredicates(predicate, false) || {}, predicates = _a.predicates, predicateGroupType = _a.type;
1012
+ var hasPredicate = !!predicates;
894
1013
  (function () { return __awaiter(_this, void 0, void 0, function () {
895
1014
  var err_1;
896
1015
  var _this = this;
@@ -904,12 +1023,28 @@ var DataStore = /** @class */ (function () {
904
1023
  (_a.sent()).forEach(function (item) {
905
1024
  return items.set(item.id, item);
906
1025
  });
907
- // observe the model and send a stream of updates (debounced)
908
- handle = this.observe(model,
909
- // @ts-ignore TODO: fix this TSlint error
910
- criteria).subscribe(function (_a) {
1026
+ // Observe the model and send a stream of updates (debounced).
1027
+ // We need to post-filter results instead of passing criteria through
1028
+ // to have visibility into items that move from in-set to out-of-set.
1029
+ // We need to explicitly remove those items from the existing snapshot.
1030
+ handle = this.observe(model).subscribe(function (_a) {
911
1031
  var element = _a.element, model = _a.model, opType = _a.opType;
912
1032
  var _b, _c;
1033
+ if (hasPredicate &&
1034
+ !validatePredicate(element, predicateGroupType, predicates)) {
1035
+ if (opType === 'UPDATE' &&
1036
+ (items.has(element.id) || itemsChanged.has(element.id))) {
1037
+ // tracking as a "deleted item" will include the item in
1038
+ // page limit calculations and ensure it is removed from the
1039
+ // final items collection, regardless of which collection(s)
1040
+ // it is currently in. (I mean, it could be in both, right!?)
1041
+ deletedItemIds.push(element.id);
1042
+ }
1043
+ else {
1044
+ // ignore updates for irrelevant/filtered items.
1045
+ return;
1046
+ }
1047
+ }
913
1048
  // Flag items which have been recently deleted
914
1049
  // NOTE: Merging of separate operations to the same model instance is handled upstream
915
1050
  // in the `mergePage` method within src/sync/merger.ts. The final state of a model instance
@@ -939,7 +1074,12 @@ var DataStore = /** @class */ (function () {
939
1074
  }
940
1075
  });
941
1076
  }); })();
942
- // TODO: abstract this function into a util file to be able to write better unit tests
1077
+ /**
1078
+ * Combines the `items`, `itemsChanged`, and `deletedItemIds` collections into
1079
+ * a snapshot in the form of `{ items: T[], isSynced: boolean}`.
1080
+ *
1081
+ * SIDE EFFECT: The shared `items` collection is recreated.
1082
+ */
943
1083
  var generateSnapshot = function () {
944
1084
  var _a, _b;
945
1085
  var isSynced = (_b = (_a = _this.sync) === null || _a === void 0 ? void 0 : _a.getModelSyncedStatus(model)) !== null && _b !== void 0 ? _b : false;
@@ -956,6 +1096,14 @@ var DataStore = /** @class */ (function () {
956
1096
  isSynced: isSynced,
957
1097
  };
958
1098
  };
1099
+ /**
1100
+ * Emits the list of items to the observer.
1101
+ *
1102
+ * SIDE EFFECT: `itemsChanged` and `deletedItemIds` are cleared to prepare
1103
+ * for the next snapshot.
1104
+ *
1105
+ * @param snapshot The generated items data to emit.
1106
+ */
959
1107
  var emitSnapshot = function (snapshot) {
960
1108
  // send the generated snapshot to the primary subscription
961
1109
  observer.next(snapshot);
@@ -963,6 +1111,12 @@ var DataStore = /** @class */ (function () {
963
1111
  itemsChanged.clear();
964
1112
  deletedItemIds = [];
965
1113
  };
1114
+ /**
1115
+ * Sorts an `Array` of `T` according to the sort instructions given in the
1116
+ * original `observeQuery()` call.
1117
+ *
1118
+ * @param itemsToSort A array of model type.
1119
+ */
966
1120
  var sortItems = function (itemsToSort) {
967
1121
  var modelDefinition = getModelDefinition(model);
968
1122
  var pagination = _this.processPagination(modelDefinition, options);
@@ -972,7 +1126,14 @@ var DataStore = /** @class */ (function () {
972
1126
  itemsToSort.sort(compareFn);
973
1127
  }
974
1128
  };
975
- // send one last snapshot when the model is fully synced
1129
+ /**
1130
+ * Force one last snapshot when the model is fully synced.
1131
+ *
1132
+ * This reduces latency for that last snapshot, which will otherwise
1133
+ * wait for the configured timeout.
1134
+ *
1135
+ * @param payload The payload from the Hub event.
1136
+ */
976
1137
  var hubCallback = function (_a) {
977
1138
  var payload = _a.payload;
978
1139
  var _b;
@@ -993,6 +1154,9 @@ var DataStore = /** @class */ (function () {
993
1154
  };
994
1155
  this.configure = function (config) {
995
1156
  if (config === void 0) { config = {}; }
1157
+ _this.amplifyContext.Auth = _this.Auth;
1158
+ _this.amplifyContext.API = _this.API;
1159
+ _this.amplifyContext.Cache = _this.Cache;
996
1160
  var configDataStore = config.DataStore, configAuthModeStrategyType = config.authModeStrategyType, configConflictHandler = config.conflictHandler, configErrorHandler = config.errorHandler, configMaxRecordsToSync = config.maxRecordsToSync, configSyncPageSize = config.syncPageSize, configFullSyncInterval = config.fullSyncInterval, configSyncExpressions = config.syncExpressions, configAuthProviders = config.authProviders, configStorageAdapter = config.storageAdapter, configFromAmplify = __rest(config, ["DataStore", "authModeStrategyType", "conflictHandler", "errorHandler", "maxRecordsToSync", "syncPageSize", "fullSyncInterval", "syncExpressions", "authProviders", "storageAdapter"]);
997
1161
  _this.amplifyConfig = __assign(__assign({}, configFromAmplify), _this.amplifyConfig);
998
1162
  _this.conflictHandler = _this.setConflictHandler(config);
@@ -1002,7 +1166,7 @@ var DataStore = /** @class */ (function () {
1002
1166
  AuthModeStrategyType.DEFAULT;
1003
1167
  switch (authModeStrategyType) {
1004
1168
  case AuthModeStrategyType.MULTI_AUTH:
1005
- _this.authModeStrategy = multiAuthStrategy;
1169
+ _this.authModeStrategy = multiAuthStrategy(_this.amplifyContext);
1006
1170
  break;
1007
1171
  case AuthModeStrategyType.DEFAULT:
1008
1172
  _this.authModeStrategy = defaultAuthStrategy;
@@ -1016,29 +1180,31 @@ var DataStore = /** @class */ (function () {
1016
1180
  (configDataStore && configDataStore.authProviders) || configAuthProviders;
1017
1181
  _this.syncExpressions =
1018
1182
  (configDataStore && configDataStore.syncExpressions) ||
1019
- _this.syncExpressions ||
1020
- configSyncExpressions;
1183
+ configSyncExpressions ||
1184
+ _this.syncExpressions;
1021
1185
  _this.maxRecordsToSync =
1022
1186
  (configDataStore && configDataStore.maxRecordsToSync) ||
1023
1187
  configMaxRecordsToSync ||
1188
+ _this.maxRecordsToSync ||
1024
1189
  10000;
1025
1190
  // store on config object, so that Sync, Subscription, and Mutation processors can have access
1026
1191
  _this.amplifyConfig.maxRecordsToSync = _this.maxRecordsToSync;
1027
1192
  _this.syncPageSize =
1028
1193
  (configDataStore && configDataStore.syncPageSize) ||
1029
1194
  configSyncPageSize ||
1195
+ _this.syncPageSize ||
1030
1196
  1000;
1031
1197
  // store on config object, so that Sync, Subscription, and Mutation processors can have access
1032
1198
  _this.amplifyConfig.syncPageSize = _this.syncPageSize;
1033
1199
  _this.fullSyncInterval =
1034
1200
  (configDataStore && configDataStore.fullSyncInterval) ||
1035
- _this.fullSyncInterval ||
1036
1201
  configFullSyncInterval ||
1202
+ _this.fullSyncInterval ||
1037
1203
  24 * 60; // 1 day
1038
1204
  _this.storageAdapter =
1039
1205
  (configDataStore && configDataStore.storageAdapter) ||
1040
- _this.storageAdapter ||
1041
1206
  configStorageAdapter ||
1207
+ _this.storageAdapter ||
1042
1208
  undefined;
1043
1209
  _this.sessionId = _this.retrieveSessionId();
1044
1210
  };
@@ -1047,14 +1213,20 @@ var DataStore = /** @class */ (function () {
1047
1213
  return __generator(this, function (_a) {
1048
1214
  switch (_a.label) {
1049
1215
  case 0:
1050
- if (this.storage === undefined) {
1051
- return [2 /*return*/];
1052
- }
1216
+ checkSchemaInitialized();
1217
+ if (!(this.storage === undefined)) return [3 /*break*/, 2];
1218
+ // connect to storage so that it can be cleared without fully starting DataStore
1219
+ this.storage = new Storage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
1220
+ return [4 /*yield*/, this.storage.init()];
1221
+ case 1:
1222
+ _a.sent();
1223
+ _a.label = 2;
1224
+ case 2:
1053
1225
  if (syncSubscription && !syncSubscription.closed) {
1054
1226
  syncSubscription.unsubscribe();
1055
1227
  }
1056
1228
  return [4 /*yield*/, this.storage.clear()];
1057
- case 1:
1229
+ case 3:
1058
1230
  _a.sent();
1059
1231
  if (this.sync) {
1060
1232
  this.sync.unsubscribeConnectivity();
@@ -1222,9 +1394,8 @@ var DataStore = /** @class */ (function () {
1222
1394
  return sessionId + "-" + appSyncId;
1223
1395
  }
1224
1396
  }
1225
- catch (_b) {
1226
- return undefined;
1227
- }
1397
+ catch (_b) { }
1398
+ return undefined;
1228
1399
  };
1229
1400
  return DataStore;
1230
1401
  }());