@aws-amplify/datastore 3.7.3 → 3.7.4-custom-pk.79

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 +144 -17
  2. package/README.md +154 -0
  3. package/dist/aws-amplify-datastore.js +3344 -1405
  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 +250 -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 +460 -253
  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 +54 -7
  55. package/lib/sync/utils.js.map +1 -1
  56. package/lib/types.d.ts +85 -33
  57. package/lib/types.js +31 -2
  58. package/lib/types.js.map +1 -1
  59. package/lib/util.d.ts +43 -33
  60. package/lib/util.js +161 -21
  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 +252 -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 +460 -253
  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 +54 -8
  110. package/lib-esm/sync/utils.js.map +1 -1
  111. package/lib-esm/types.d.ts +85 -33
  112. package/lib-esm/types.js +29 -3
  113. package/lib-esm/types.js.map +1 -1
  114. package/lib-esm/util.d.ts +43 -33
  115. package/lib-esm/util.js +151 -18
  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 +396 -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 +355 -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 +63 -15
  135. package/src/types.ts +242 -49
  136. package/src/util.ts +212 -35
  137. package/ssr/package.json +1 -1
@@ -92,7 +92,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
92
92
  return (mod && mod.__esModule) ? mod : { "default": mod };
93
93
  };
94
94
  Object.defineProperty(exports, "__esModule", { value: true });
95
+ var api_1 = __importDefault(require("@aws-amplify/api"));
95
96
  var core_1 = require("@aws-amplify/core");
97
+ var auth_1 = require("@aws-amplify/auth");
98
+ var cache_1 = __importDefault(require("@aws-amplify/cache"));
96
99
  var immer_1 = require("immer");
97
100
  var uuid_1 = require("uuid");
98
101
  var zen_observable_ts_1 = __importDefault(require("zen-observable-ts"));
@@ -205,6 +208,18 @@ var initSchema = function (userSchema) {
205
208
  return userClasses;
206
209
  };
207
210
  exports.initSchema = initSchema;
211
+ /* Checks if the schema has been initialized by initSchema().
212
+ *
213
+ * Call this function before accessing schema.
214
+ * Currently this only needs to be called in start() and clear() because all other functions will call start first.
215
+ */
216
+ var checkSchemaInitialized = function () {
217
+ if (schema === undefined) {
218
+ 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';
219
+ logger.error(message);
220
+ throw new Error(message);
221
+ }
222
+ };
208
223
  var createTypeClasses = function (namespace) {
209
224
  var classes = {};
210
225
  Object.entries(namespace.models).forEach(function (_a) {
@@ -333,21 +348,29 @@ var createModelClass = function (modelDefinition) {
333
348
  function Model(init) {
334
349
  var instance = immer_1.produce(this, function (draft) {
335
350
  initializeInstance(init, modelDefinition, draft);
336
- var modelInstanceMetadata = instancesMetadata.has(init)
351
+ // model is initialized inside a DataStore component (e.g. by Sync Engine, Storage Engine, etc.)
352
+ var isInternallyInitialized = instancesMetadata.has(init);
353
+ var modelInstanceMetadata = isInternallyInitialized
337
354
  ? init
338
355
  : {};
339
- var _id = modelInstanceMetadata.id, _version = modelInstanceMetadata._version, _lastChangedAt = modelInstanceMetadata._lastChangedAt, _deleted = modelInstanceMetadata._deleted;
340
- // instancesIds are set by modelInstanceCreator, it is accessible only internally
341
- var isInternal = _id !== null && _id !== undefined;
342
- var id = isInternal
343
- ? _id
344
- : modelDefinition.syncable
345
- ? uuid_1.v4()
346
- : ulid();
347
- if (!isInternal) {
356
+ var _id = modelInstanceMetadata.id;
357
+ if (util_1.isIdManaged(modelDefinition)) {
358
+ var isInternalModel = _id !== null && _id !== undefined;
359
+ var id = isInternalModel
360
+ ? _id
361
+ : modelDefinition.syncable
362
+ ? uuid_1.v4()
363
+ : ulid();
364
+ draft.id = id;
365
+ }
366
+ else if (util_1.isIdOptionallyManaged(modelDefinition)) {
367
+ // only auto-populate if the id was not provided
368
+ draft.id = draft.id || uuid_1.v4();
369
+ }
370
+ if (!isInternallyInitialized) {
348
371
  checkReadOnlyPropertyOnCreate(draft, modelDefinition);
349
372
  }
350
- draft.id = id;
373
+ var _version = modelInstanceMetadata._version, _lastChangedAt = modelInstanceMetadata._lastChangedAt, _deleted = modelInstanceMetadata._deleted;
351
374
  if (modelDefinition.syncable) {
352
375
  draft._version = _version;
353
376
  draft._lastChangedAt = _lastChangedAt;
@@ -366,7 +389,11 @@ var createModelClass = function (modelDefinition) {
366
389
  var patches;
367
390
  var model = immer_1.produce(source, function (draft) {
368
391
  fn(draft);
369
- draft.id = source.id;
392
+ var keyNames = util_1.extractPrimaryKeyFieldNames(modelDefinition);
393
+ // Keys are immutable
394
+ // CPK TODO: Previous comment from Ivan:
395
+ // @ts-ignore TODO: fix type
396
+ keyNames.forEach(function (key) { return (draft[key] = source[key]); });
370
397
  var modelValidator = validateModelFields(modelDefinition);
371
398
  Object.entries(draft).forEach(function (_a) {
372
399
  var _b = __read(_a, 2), k = _b[0], v = _b[1];
@@ -374,9 +401,18 @@ var createModelClass = function (modelDefinition) {
374
401
  modelValidator(k, parsedValue);
375
402
  });
376
403
  }, function (p) { return (patches = p); });
377
- if (patches.length) {
378
- modelPatchesMap.set(model, [patches, source]);
379
- checkReadOnlyPropertyOnUpdate(patches, modelDefinition);
404
+ var hasExistingPatches = modelPatchesMap.has(source);
405
+ if (patches.length || hasExistingPatches) {
406
+ if (hasExistingPatches) {
407
+ var _a = __read(modelPatchesMap.get(source), 2), existingPatches = _a[0], existingSource = _a[1];
408
+ var mergedPatches = util_1.mergePatches(existingSource, existingPatches, patches);
409
+ modelPatchesMap.set(model, [mergedPatches, existingSource]);
410
+ checkReadOnlyPropertyOnUpdate(mergedPatches, modelDefinition);
411
+ }
412
+ else {
413
+ modelPatchesMap.set(model, [patches, source]);
414
+ checkReadOnlyPropertyOnUpdate(patches, modelDefinition);
415
+ }
380
416
  }
381
417
  return model;
382
418
  };
@@ -490,7 +526,6 @@ function checkSchemaVersion(storage, version) {
490
526
  return __generator(this, function (_b) {
491
527
  switch (_b.label) {
492
528
  case 0: return [4 /*yield*/, s.query(Setting, predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition, function (c) {
493
- // @ts-ignore Argument of type '"eq"' is not assignable to parameter of type 'never'.
494
529
  return c.key('eq', SETTING_SCHEMA_VERSION);
495
530
  }), { page: 0, limit: 1 })];
496
531
  case 1:
@@ -562,8 +597,18 @@ function getNamespace() {
562
597
  var DataStore = /** @class */ (function () {
563
598
  function DataStore() {
564
599
  var _this = this;
600
+ // reference to configured category instances. Used for preserving SSR context
601
+ this.Auth = auth_1.Auth;
602
+ this.API = api_1.default;
603
+ this.Cache = cache_1.default;
565
604
  this.amplifyConfig = {};
566
605
  this.syncPredicates = new WeakMap();
606
+ // object that gets passed to descendent classes. Allows us to pass these down by reference
607
+ this.amplifyContext = {
608
+ Auth: this.Auth,
609
+ API: this.API,
610
+ Cache: this.Cache,
611
+ };
567
612
  this.start = function () { return __awaiter(_this, void 0, void 0, function () {
568
613
  var aws_appsync_graphqlEndpoint, _a, fullSyncIntervalInMilliseconds;
569
614
  var _this = this;
@@ -586,6 +631,7 @@ var DataStore = /** @class */ (function () {
586
631
  return [4 /*yield*/, this.storage.init()];
587
632
  case 4:
588
633
  _b.sent();
634
+ checkSchemaInitialized();
589
635
  return [4 /*yield*/, checkSchemaVersion(this.storage, schema.version)];
590
636
  case 5:
591
637
  _b.sent();
@@ -596,7 +642,7 @@ var DataStore = /** @class */ (function () {
596
642
  return [4 /*yield*/, this.processSyncExpressions()];
597
643
  case 6:
598
644
  _a.syncPredicates = _b.sent();
599
- this.sync = new sync_1.SyncEngine(schema, namespaceResolver, exports.syncClasses, userClasses, this.storage, modelInstanceCreator, this.maxRecordsToSync, this.syncPageSize, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy);
645
+ this.sync = new sync_1.SyncEngine(schema, namespaceResolver, exports.syncClasses, userClasses, this.storage, modelInstanceCreator, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy, this.amplifyContext);
600
646
  fullSyncIntervalInMilliseconds = this.fullSyncInterval * 1000 * 60;
601
647
  syncSubscription = this.sync
602
648
  .start({ fullSyncInterval: fullSyncIntervalInMilliseconds })
@@ -635,8 +681,8 @@ var DataStore = /** @class */ (function () {
635
681
  }
636
682
  });
637
683
  }); };
638
- this.query = function (modelConstructor, idOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
639
- var msg, modelDefinition, predicate, pagination, result;
684
+ this.query = function (modelConstructor, identifierOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
685
+ var msg, modelDefinition, keyFields, predicate, pagination, result, isSingleFieldIdentifier, returnOne;
640
686
  return __generator(this, function (_a) {
641
687
  switch (_a.label) {
642
688
  case 0: return [4 /*yield*/, this.start()];
@@ -648,22 +694,27 @@ var DataStore = /** @class */ (function () {
648
694
  logger.error(msg, { modelConstructor: modelConstructor });
649
695
  throw new Error(msg);
650
696
  }
651
- if (typeof idOrCriteria === 'string') {
697
+ if (typeof identifierOrCriteria === 'string') {
652
698
  if (paginationProducer !== undefined) {
653
699
  logger.warn('Pagination is ignored when querying by id');
654
700
  }
655
701
  }
656
702
  modelDefinition = getModelDefinition(modelConstructor);
657
- if (isQueryOne(idOrCriteria)) {
658
- predicate = predicates_1.ModelPredicateCreator.createForId(modelDefinition, idOrCriteria);
703
+ keyFields = util_1.extractPrimaryKeyFieldNames(modelDefinition);
704
+ if (isQueryOne(identifierOrCriteria)) {
705
+ predicate = predicates_1.ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], identifierOrCriteria);
659
706
  }
660
707
  else {
661
- if (predicates_1.isPredicatesAll(idOrCriteria)) {
708
+ // Object is being queried using object literal syntax
709
+ if (types_1.isIdentifierObject(identifierOrCriteria, modelDefinition)) {
710
+ predicate = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
711
+ }
712
+ else if (predicates_1.isPredicatesAll(identifierOrCriteria)) {
662
713
  // Predicates.ALL means "all records", so no predicate (undefined)
663
714
  predicate = undefined;
664
715
  }
665
716
  else {
666
- predicate = predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition, idOrCriteria);
717
+ predicate = predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition, identifierOrCriteria);
667
718
  }
668
719
  }
669
720
  pagination = this.processPagination(modelDefinition, paginationProducer);
@@ -676,7 +727,11 @@ var DataStore = /** @class */ (function () {
676
727
  return [4 /*yield*/, this.storage.query(modelConstructor, predicate, pagination)];
677
728
  case 2:
678
729
  result = _a.sent();
679
- return [2 /*return*/, isQueryOne(idOrCriteria) ? result[0] : result];
730
+ isSingleFieldIdentifier = keyFields.length === 1;
731
+ returnOne = isSingleFieldIdentifier &&
732
+ (isQueryOne(identifierOrCriteria) ||
733
+ types_1.isIdentifierObject(identifierOrCriteria, modelDefinition));
734
+ return [2 /*return*/, returnOne ? result[0] : result];
680
735
  }
681
736
  });
682
737
  }); };
@@ -705,7 +760,7 @@ var DataStore = /** @class */ (function () {
705
760
  case 0: return [4 /*yield*/, s.save(model, producedCondition, undefined, patchesTuple)];
706
761
  case 1:
707
762
  _a.sent();
708
- return [2 /*return*/, s.query(modelConstructor, predicates_1.ModelPredicateCreator.createForId(modelDefinition, model.id))];
763
+ return [2 /*return*/, s.query(modelConstructor, predicates_1.ModelPredicateCreator.createForPk(modelDefinition, model))];
709
764
  }
710
765
  });
711
766
  }); })];
@@ -741,13 +796,13 @@ var DataStore = /** @class */ (function () {
741
796
  }
742
797
  return _this.errorHandler || defaultErrorHandler;
743
798
  };
744
- this.delete = function (modelOrConstructor, idOrCriteria) { return __awaiter(_this, void 0, void 0, function () {
745
- var condition, msg, modelConstructor, msg, msg, _a, deleted, model, modelConstructor, msg, modelDefinition, idPredicate, msg, _b, _c, deleted;
746
- return __generator(this, function (_d) {
747
- switch (_d.label) {
799
+ this.delete = function (modelOrConstructor, identifierOrCriteria) { return __awaiter(_this, void 0, void 0, function () {
800
+ var condition, msg, modelConstructor, msg, modelDefinition, _a, keyField, msg, _b, deleted, model, modelConstructor, msg, modelDefinition, pkPredicate, msg, _c, _d, deleted;
801
+ return __generator(this, function (_e) {
802
+ switch (_e.label) {
748
803
  case 0: return [4 /*yield*/, this.start()];
749
804
  case 1:
750
- _d.sent();
805
+ _e.sent();
751
806
  if (!modelOrConstructor) {
752
807
  msg = 'Model or Model Constructor required';
753
808
  logger.error(msg, { modelOrConstructor: modelOrConstructor });
@@ -755,21 +810,28 @@ var DataStore = /** @class */ (function () {
755
810
  }
756
811
  if (!isValidModelConstructor(modelOrConstructor)) return [3 /*break*/, 3];
757
812
  modelConstructor = modelOrConstructor;
758
- if (!idOrCriteria) {
813
+ if (!identifierOrCriteria) {
759
814
  msg = 'Id to delete or criteria required. Do you want to delete all? Pass Predicates.ALL';
760
- logger.error(msg, { idOrCriteria: idOrCriteria });
815
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
761
816
  throw new Error(msg);
762
817
  }
763
- if (typeof idOrCriteria === 'string') {
764
- condition = predicates_1.ModelPredicateCreator.createForId(getModelDefinition(modelConstructor), idOrCriteria);
818
+ modelDefinition = getModelDefinition(modelConstructor);
819
+ if (typeof identifierOrCriteria === 'string') {
820
+ _a = __read(util_1.extractPrimaryKeyFieldNames(modelDefinition), 1), keyField = _a[0];
821
+ condition = predicates_1.ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyField, identifierOrCriteria);
765
822
  }
766
823
  else {
767
- condition = predicates_1.ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor),
768
- /**
769
- * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
770
- * The symbol is used only for typing purposes. e.g. see Predicates.ALL
771
- */
772
- idOrCriteria);
824
+ if (types_1.isIdentifierObject(identifierOrCriteria, modelDefinition)) {
825
+ condition = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
826
+ }
827
+ else {
828
+ condition = predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition,
829
+ /**
830
+ * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
831
+ * The symbol is used only for typing purposes. e.g. see Predicates.ALL
832
+ */
833
+ identifierOrCriteria);
834
+ }
773
835
  if (!condition || !predicates_1.ModelPredicateCreator.isValidPredicate(condition)) {
774
836
  msg = 'Criteria required. Do you want to delete all? Pass Predicates.ALL';
775
837
  logger.error(msg, { condition: condition });
@@ -778,7 +840,7 @@ var DataStore = /** @class */ (function () {
778
840
  }
779
841
  return [4 /*yield*/, this.storage.delete(modelConstructor, condition)];
780
842
  case 2:
781
- _a = __read.apply(void 0, [_d.sent(), 1]), deleted = _a[0];
843
+ _b = __read.apply(void 0, [_e.sent(), 1]), deleted = _b[0];
782
844
  return [2 /*return*/, deleted];
783
845
  case 3:
784
846
  model = modelOrConstructor;
@@ -790,26 +852,26 @@ var DataStore = /** @class */ (function () {
790
852
  throw new Error(msg);
791
853
  }
792
854
  modelDefinition = getModelDefinition(modelConstructor);
793
- idPredicate = predicates_1.ModelPredicateCreator.createForId(modelDefinition, model.id);
794
- if (idOrCriteria) {
795
- if (typeof idOrCriteria !== 'function') {
855
+ pkPredicate = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, model);
856
+ if (identifierOrCriteria) {
857
+ if (typeof identifierOrCriteria !== 'function') {
796
858
  msg = 'Invalid criteria';
797
- logger.error(msg, { idOrCriteria: idOrCriteria });
859
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
798
860
  throw new Error(msg);
799
861
  }
800
- condition = idOrCriteria(idPredicate);
862
+ condition = identifierOrCriteria(pkPredicate);
801
863
  }
802
864
  else {
803
- condition = idPredicate;
865
+ condition = pkPredicate;
804
866
  }
805
867
  return [4 /*yield*/, this.storage.delete(model, condition)];
806
868
  case 4:
807
- _b = __read.apply(void 0, [_d.sent(), 1]), _c = __read(_b[0], 1), deleted = _c[0];
869
+ _c = __read.apply(void 0, [_e.sent(), 1]), _d = __read(_c[0], 1), deleted = _d[0];
808
870
  return [2 /*return*/, deleted];
809
871
  }
810
872
  });
811
873
  }); };
812
- this.observe = function (modelOrConstructor, idOrCriteria) {
874
+ this.observe = function (modelOrConstructor, identifierOrCriteria) {
813
875
  var predicate;
814
876
  var modelConstructor = modelOrConstructor && isValidModelConstructor(modelOrConstructor)
815
877
  ? modelOrConstructor
@@ -818,10 +880,10 @@ var DataStore = /** @class */ (function () {
818
880
  var model = modelOrConstructor;
819
881
  var modelConstructor_1 = model && Object.getPrototypeOf(model).constructor;
820
882
  if (isValidModelConstructor(modelConstructor_1)) {
821
- if (idOrCriteria) {
883
+ if (identifierOrCriteria) {
822
884
  logger.warn('idOrCriteria is ignored when using a model instance', {
823
885
  model: model,
824
- idOrCriteria: idOrCriteria,
886
+ identifierOrCriteria: identifierOrCriteria,
825
887
  });
826
888
  }
827
889
  return _this.observe(modelConstructor_1, model.id);
@@ -832,9 +894,9 @@ var DataStore = /** @class */ (function () {
832
894
  throw new Error(msg);
833
895
  }
834
896
  }
835
- if (idOrCriteria !== undefined && modelConstructor === undefined) {
897
+ if (identifierOrCriteria !== undefined && modelConstructor === undefined) {
836
898
  var msg = 'Cannot provide criteria without a modelConstructor';
837
- logger.error(msg, idOrCriteria);
899
+ logger.error(msg, identifierOrCriteria);
838
900
  throw new Error(msg);
839
901
  }
840
902
  if (modelConstructor && !isValidModelConstructor(modelConstructor)) {
@@ -842,29 +904,60 @@ var DataStore = /** @class */ (function () {
842
904
  logger.error(msg, { modelConstructor: modelConstructor });
843
905
  throw new Error(msg);
844
906
  }
845
- if (typeof idOrCriteria === 'string') {
846
- predicate = predicates_1.ModelPredicateCreator.createForId(getModelDefinition(modelConstructor), idOrCriteria);
907
+ if (typeof identifierOrCriteria === 'string') {
908
+ var modelDefinition = getModelDefinition(modelConstructor);
909
+ var _a = __read(util_1.extractPrimaryKeyFieldNames(modelDefinition), 1), keyField = _a[0];
910
+ predicate = predicates_1.ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyField, identifierOrCriteria);
847
911
  }
848
912
  else {
849
- predicate =
850
- modelConstructor &&
851
- predicates_1.ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor), idOrCriteria);
913
+ if (predicates_1.isPredicatesAll(identifierOrCriteria)) {
914
+ predicate = undefined;
915
+ }
916
+ else {
917
+ predicate =
918
+ modelConstructor &&
919
+ predicates_1.ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor), identifierOrCriteria);
920
+ }
852
921
  }
853
922
  return new zen_observable_ts_1.default(function (observer) {
854
923
  var handle;
855
924
  (function () { return __awaiter(_this, void 0, void 0, function () {
925
+ var _this = this;
856
926
  return __generator(this, function (_a) {
857
927
  switch (_a.label) {
858
928
  case 0: return [4 /*yield*/, this.start()];
859
929
  case 1:
860
930
  _a.sent();
931
+ // Filter the events returned by Storage according to namespace,
932
+ // append original element data, and subscribe to the observable
861
933
  handle = this.storage
862
934
  .observe(modelConstructor, predicate)
863
935
  .filter(function (_a) {
864
936
  var model = _a.model;
865
937
  return namespaceResolver(model) === util_1.USER;
866
938
  })
867
- .subscribe(observer);
939
+ .subscribe({
940
+ next: function (item) { return __awaiter(_this, void 0, void 0, function () {
941
+ var message, freshElement;
942
+ return __generator(this, function (_a) {
943
+ switch (_a.label) {
944
+ case 0:
945
+ message = item;
946
+ if (!(item.opType !== 'DELETE')) return [3 /*break*/, 2];
947
+ return [4 /*yield*/, this.query(item.model, item.element.id)];
948
+ case 1:
949
+ freshElement = _a.sent();
950
+ message = __assign(__assign({}, message), { element: freshElement });
951
+ _a.label = 2;
952
+ case 2:
953
+ observer.next(message);
954
+ return [2 /*return*/];
955
+ }
956
+ });
957
+ }); },
958
+ error: function (err) { return observer.error(err); },
959
+ complete: function () { return observer.complete(); },
960
+ });
868
961
  return [2 /*return*/];
869
962
  }
870
963
  });
@@ -882,6 +975,17 @@ var DataStore = /** @class */ (function () {
882
975
  var itemsChanged = new Map();
883
976
  var deletedItemIds = [];
884
977
  var handle;
978
+ var predicate;
979
+ /**
980
+ * As the name suggests, this geneates a snapshot in the form of
981
+ * `{items: T[], isSynced: boolean}`
982
+ * and sends it to the observer.
983
+ *
984
+ * SIDE EFFECT: The underlying generation and emission methods may touch:
985
+ * `items`, `itemsChanged`, and `deletedItemIds`.
986
+ *
987
+ * Refer to `generateSnapshot` and `emitSnapshot` for more details.
988
+ */
885
989
  var generateAndEmitSnapshot = function () {
886
990
  var snapshot = generateSnapshot();
887
991
  emitSnapshot(snapshot);
@@ -895,6 +999,22 @@ var DataStore = /** @class */ (function () {
895
999
  });
896
1000
  var sort = (options || {}).sort;
897
1001
  var sortOptions = sort ? { sort: sort } : undefined;
1002
+ var modelDefinition = getModelDefinition(model);
1003
+ var keyFields = util_1.extractPrimaryKeyFieldNames(modelDefinition);
1004
+ if (isQueryOne(criteria)) {
1005
+ predicate = predicates_1.ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], criteria);
1006
+ }
1007
+ else {
1008
+ if (predicates_1.isPredicatesAll(criteria)) {
1009
+ // Predicates.ALL means "all records", so no predicate (undefined)
1010
+ predicate = undefined;
1011
+ }
1012
+ else {
1013
+ predicate = predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition, criteria);
1014
+ }
1015
+ }
1016
+ var _a = predicates_1.ModelPredicateCreator.getPredicates(predicate, false) || {}, predicates = _a.predicates, predicateGroupType = _a.type;
1017
+ var hasPredicate = !!predicates;
898
1018
  (function () { return __awaiter(_this, void 0, void 0, function () {
899
1019
  var err_1;
900
1020
  var _this = this;
@@ -908,12 +1028,28 @@ var DataStore = /** @class */ (function () {
908
1028
  (_a.sent()).forEach(function (item) {
909
1029
  return items.set(item.id, item);
910
1030
  });
911
- // observe the model and send a stream of updates (debounced)
912
- handle = this.observe(model,
913
- // @ts-ignore TODO: fix this TSlint error
914
- criteria).subscribe(function (_a) {
1031
+ // Observe the model and send a stream of updates (debounced).
1032
+ // We need to post-filter results instead of passing criteria through
1033
+ // to have visibility into items that move from in-set to out-of-set.
1034
+ // We need to explicitly remove those items from the existing snapshot.
1035
+ handle = this.observe(model).subscribe(function (_a) {
915
1036
  var element = _a.element, model = _a.model, opType = _a.opType;
916
1037
  var _b, _c;
1038
+ if (hasPredicate &&
1039
+ !util_1.validatePredicate(element, predicateGroupType, predicates)) {
1040
+ if (opType === 'UPDATE' &&
1041
+ (items.has(element.id) || itemsChanged.has(element.id))) {
1042
+ // tracking as a "deleted item" will include the item in
1043
+ // page limit calculations and ensure it is removed from the
1044
+ // final items collection, regardless of which collection(s)
1045
+ // it is currently in. (I mean, it could be in both, right!?)
1046
+ deletedItemIds.push(element.id);
1047
+ }
1048
+ else {
1049
+ // ignore updates for irrelevant/filtered items.
1050
+ return;
1051
+ }
1052
+ }
917
1053
  // Flag items which have been recently deleted
918
1054
  // NOTE: Merging of separate operations to the same model instance is handled upstream
919
1055
  // in the `mergePage` method within src/sync/merger.ts. The final state of a model instance
@@ -943,7 +1079,12 @@ var DataStore = /** @class */ (function () {
943
1079
  }
944
1080
  });
945
1081
  }); })();
946
- // TODO: abstract this function into a util file to be able to write better unit tests
1082
+ /**
1083
+ * Combines the `items`, `itemsChanged`, and `deletedItemIds` collections into
1084
+ * a snapshot in the form of `{ items: T[], isSynced: boolean}`.
1085
+ *
1086
+ * SIDE EFFECT: The shared `items` collection is recreated.
1087
+ */
947
1088
  var generateSnapshot = function () {
948
1089
  var _a, _b;
949
1090
  var isSynced = (_b = (_a = _this.sync) === null || _a === void 0 ? void 0 : _a.getModelSyncedStatus(model)) !== null && _b !== void 0 ? _b : false;
@@ -960,6 +1101,14 @@ var DataStore = /** @class */ (function () {
960
1101
  isSynced: isSynced,
961
1102
  };
962
1103
  };
1104
+ /**
1105
+ * Emits the list of items to the observer.
1106
+ *
1107
+ * SIDE EFFECT: `itemsChanged` and `deletedItemIds` are cleared to prepare
1108
+ * for the next snapshot.
1109
+ *
1110
+ * @param snapshot The generated items data to emit.
1111
+ */
963
1112
  var emitSnapshot = function (snapshot) {
964
1113
  // send the generated snapshot to the primary subscription
965
1114
  observer.next(snapshot);
@@ -967,6 +1116,12 @@ var DataStore = /** @class */ (function () {
967
1116
  itemsChanged.clear();
968
1117
  deletedItemIds = [];
969
1118
  };
1119
+ /**
1120
+ * Sorts an `Array` of `T` according to the sort instructions given in the
1121
+ * original `observeQuery()` call.
1122
+ *
1123
+ * @param itemsToSort A array of model type.
1124
+ */
970
1125
  var sortItems = function (itemsToSort) {
971
1126
  var modelDefinition = getModelDefinition(model);
972
1127
  var pagination = _this.processPagination(modelDefinition, options);
@@ -976,7 +1131,14 @@ var DataStore = /** @class */ (function () {
976
1131
  itemsToSort.sort(compareFn);
977
1132
  }
978
1133
  };
979
- // send one last snapshot when the model is fully synced
1134
+ /**
1135
+ * Force one last snapshot when the model is fully synced.
1136
+ *
1137
+ * This reduces latency for that last snapshot, which will otherwise
1138
+ * wait for the configured timeout.
1139
+ *
1140
+ * @param payload The payload from the Hub event.
1141
+ */
980
1142
  var hubCallback = function (_a) {
981
1143
  var payload = _a.payload;
982
1144
  var _b;
@@ -997,6 +1159,9 @@ var DataStore = /** @class */ (function () {
997
1159
  };
998
1160
  this.configure = function (config) {
999
1161
  if (config === void 0) { config = {}; }
1162
+ _this.amplifyContext.Auth = _this.Auth;
1163
+ _this.amplifyContext.API = _this.API;
1164
+ _this.amplifyContext.Cache = _this.Cache;
1000
1165
  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"]);
1001
1166
  _this.amplifyConfig = __assign(__assign({}, configFromAmplify), _this.amplifyConfig);
1002
1167
  _this.conflictHandler = _this.setConflictHandler(config);
@@ -1006,7 +1171,7 @@ var DataStore = /** @class */ (function () {
1006
1171
  types_1.AuthModeStrategyType.DEFAULT;
1007
1172
  switch (authModeStrategyType) {
1008
1173
  case types_1.AuthModeStrategyType.MULTI_AUTH:
1009
- _this.authModeStrategy = authModeStrategies_1.multiAuthStrategy;
1174
+ _this.authModeStrategy = authModeStrategies_1.multiAuthStrategy(_this.amplifyContext);
1010
1175
  break;
1011
1176
  case types_1.AuthModeStrategyType.DEFAULT:
1012
1177
  _this.authModeStrategy = authModeStrategies_1.defaultAuthStrategy;
@@ -1020,29 +1185,31 @@ var DataStore = /** @class */ (function () {
1020
1185
  (configDataStore && configDataStore.authProviders) || configAuthProviders;
1021
1186
  _this.syncExpressions =
1022
1187
  (configDataStore && configDataStore.syncExpressions) ||
1023
- _this.syncExpressions ||
1024
- configSyncExpressions;
1188
+ configSyncExpressions ||
1189
+ _this.syncExpressions;
1025
1190
  _this.maxRecordsToSync =
1026
1191
  (configDataStore && configDataStore.maxRecordsToSync) ||
1027
1192
  configMaxRecordsToSync ||
1193
+ _this.maxRecordsToSync ||
1028
1194
  10000;
1029
1195
  // store on config object, so that Sync, Subscription, and Mutation processors can have access
1030
1196
  _this.amplifyConfig.maxRecordsToSync = _this.maxRecordsToSync;
1031
1197
  _this.syncPageSize =
1032
1198
  (configDataStore && configDataStore.syncPageSize) ||
1033
1199
  configSyncPageSize ||
1200
+ _this.syncPageSize ||
1034
1201
  1000;
1035
1202
  // store on config object, so that Sync, Subscription, and Mutation processors can have access
1036
1203
  _this.amplifyConfig.syncPageSize = _this.syncPageSize;
1037
1204
  _this.fullSyncInterval =
1038
1205
  (configDataStore && configDataStore.fullSyncInterval) ||
1039
- _this.fullSyncInterval ||
1040
1206
  configFullSyncInterval ||
1207
+ _this.fullSyncInterval ||
1041
1208
  24 * 60; // 1 day
1042
1209
  _this.storageAdapter =
1043
1210
  (configDataStore && configDataStore.storageAdapter) ||
1044
- _this.storageAdapter ||
1045
1211
  configStorageAdapter ||
1212
+ _this.storageAdapter ||
1046
1213
  undefined;
1047
1214
  _this.sessionId = _this.retrieveSessionId();
1048
1215
  };
@@ -1051,14 +1218,20 @@ var DataStore = /** @class */ (function () {
1051
1218
  return __generator(this, function (_a) {
1052
1219
  switch (_a.label) {
1053
1220
  case 0:
1054
- if (this.storage === undefined) {
1055
- return [2 /*return*/];
1056
- }
1221
+ checkSchemaInitialized();
1222
+ if (!(this.storage === undefined)) return [3 /*break*/, 2];
1223
+ // connect to storage so that it can be cleared without fully starting DataStore
1224
+ this.storage = new storage_1.ExclusiveStorage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
1225
+ return [4 /*yield*/, this.storage.init()];
1226
+ case 1:
1227
+ _a.sent();
1228
+ _a.label = 2;
1229
+ case 2:
1057
1230
  if (syncSubscription && !syncSubscription.closed) {
1058
1231
  syncSubscription.unsubscribe();
1059
1232
  }
1060
1233
  return [4 /*yield*/, this.storage.clear()];
1061
- case 1:
1234
+ case 3:
1062
1235
  _a.sent();
1063
1236
  if (this.sync) {
1064
1237
  this.sync.unsubscribeConnectivity();
@@ -1226,9 +1399,8 @@ var DataStore = /** @class */ (function () {
1226
1399
  return sessionId + "-" + appSyncId;
1227
1400
  }
1228
1401
  }
1229
- catch (_b) {
1230
- return undefined;
1231
- }
1402
+ catch (_b) { }
1403
+ return undefined;
1232
1404
  };
1233
1405
  return DataStore;
1234
1406
  }());