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