@aws-amplify/datastore 3.14.1-unstable.3 → 3.14.1

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 (111) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/aws-amplify-datastore.js +2798 -1458
  3. package/dist/aws-amplify-datastore.js.map +1 -1
  4. package/dist/aws-amplify-datastore.min.js +10 -10
  5. package/dist/aws-amplify-datastore.min.js.map +1 -1
  6. package/lib/authModeStrategies/multiAuthStrategy.js +11 -0
  7. package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
  8. package/lib/datastore/datastore.js +524 -323
  9. package/lib/datastore/datastore.js.map +1 -1
  10. package/lib/storage/adapter/IndexedDBAdapter.js +76 -25
  11. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  12. package/lib/storage/storage.js +2 -2
  13. package/lib/storage/storage.js.map +1 -1
  14. package/lib/sync/datastoreConnectivity.js +45 -0
  15. package/lib/sync/datastoreConnectivity.js.map +1 -1
  16. package/lib/sync/index.js +518 -395
  17. package/lib/sync/index.js.map +1 -1
  18. package/lib/sync/merger.js +6 -0
  19. package/lib/sync/merger.js.map +1 -1
  20. package/lib/sync/outbox.js +66 -62
  21. package/lib/sync/outbox.js.map +1 -1
  22. package/lib/sync/processors/mutation.js +207 -165
  23. package/lib/sync/processors/mutation.js.map +1 -1
  24. package/lib/sync/processors/subscription.js +210 -175
  25. package/lib/sync/processors/subscription.js.map +1 -1
  26. package/lib/sync/processors/sync.js +95 -72
  27. package/lib/sync/processors/sync.js.map +1 -1
  28. package/lib/sync/utils.js +1 -3
  29. package/lib/sync/utils.js.map +1 -1
  30. package/lib/util.js +89 -0
  31. package/lib/util.js.map +1 -1
  32. package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +11 -0
  33. package/lib-esm/authModeStrategies/multiAuthStrategy.js +11 -0
  34. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
  35. package/lib-esm/datastore/datastore.d.ts +95 -2
  36. package/lib-esm/datastore/datastore.js +524 -323
  37. package/lib-esm/datastore/datastore.js.map +1 -1
  38. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +21 -0
  39. package/lib-esm/storage/adapter/IndexedDBAdapter.js +77 -26
  40. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  41. package/lib-esm/storage/storage.js +2 -2
  42. package/lib-esm/storage/storage.js.map +1 -1
  43. package/lib-esm/sync/datastoreConnectivity.d.ts +1 -0
  44. package/lib-esm/sync/datastoreConnectivity.js +45 -0
  45. package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
  46. package/lib-esm/sync/index.d.ts +9 -1
  47. package/lib-esm/sync/index.js +519 -396
  48. package/lib-esm/sync/index.js.map +1 -1
  49. package/lib-esm/sync/merger.d.ts +6 -0
  50. package/lib-esm/sync/merger.js +6 -0
  51. package/lib-esm/sync/merger.js.map +1 -1
  52. package/lib-esm/sync/outbox.js +66 -62
  53. package/lib-esm/sync/outbox.js.map +1 -1
  54. package/lib-esm/sync/processors/mutation.d.ts +2 -0
  55. package/lib-esm/sync/processors/mutation.js +208 -166
  56. package/lib-esm/sync/processors/mutation.js.map +1 -1
  57. package/lib-esm/sync/processors/subscription.d.ts +2 -0
  58. package/lib-esm/sync/processors/subscription.js +211 -176
  59. package/lib-esm/sync/processors/subscription.js.map +1 -1
  60. package/lib-esm/sync/processors/sync.d.ts +2 -0
  61. package/lib-esm/sync/processors/sync.js +96 -73
  62. package/lib-esm/sync/processors/sync.js.map +1 -1
  63. package/lib-esm/sync/utils.js +1 -3
  64. package/lib-esm/sync/utils.js.map +1 -1
  65. package/lib-esm/util.d.ts +11 -0
  66. package/lib-esm/util.js +89 -0
  67. package/lib-esm/util.js.map +1 -1
  68. package/package.json +7 -7
  69. package/src/authModeStrategies/multiAuthStrategy.ts +11 -0
  70. package/src/datastore/datastore.ts +572 -366
  71. package/src/storage/adapter/IndexedDBAdapter.ts +50 -9
  72. package/src/storage/storage.ts +2 -2
  73. package/src/sync/datastoreConnectivity.ts +6 -0
  74. package/src/sync/index.ts +492 -400
  75. package/src/sync/merger.ts +6 -0
  76. package/src/sync/outbox.ts +1 -1
  77. package/src/sync/processors/mutation.ts +139 -104
  78. package/src/sync/processors/subscription.ts +287 -250
  79. package/src/sync/processors/sync.ts +88 -60
  80. package/src/sync/utils.ts +1 -3
  81. package/src/util.ts +92 -2
  82. package/lib/authModeStrategies/defaultAuthStrategy.d.ts +0 -2
  83. package/lib/authModeStrategies/index.d.ts +0 -2
  84. package/lib/authModeStrategies/multiAuthStrategy.d.ts +0 -2
  85. package/lib/datastore/datastore.d.ts +0 -63
  86. package/lib/index.d.ts +0 -15
  87. package/lib/predicates/index.d.ts +0 -16
  88. package/lib/predicates/sort.d.ts +0 -8
  89. package/lib/ssr/index.d.ts +0 -3
  90. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +0 -41
  91. package/lib/storage/adapter/AsyncStorageDatabase.d.ts +0 -39
  92. package/lib/storage/adapter/InMemoryStore.d.ts +0 -11
  93. package/lib/storage/adapter/InMemoryStore.native.d.ts +0 -1
  94. package/lib/storage/adapter/IndexedDBAdapter.d.ts +0 -38
  95. package/lib/storage/adapter/getDefaultAdapter/index.d.ts +0 -3
  96. package/lib/storage/adapter/getDefaultAdapter/index.native.d.ts +0 -3
  97. package/lib/storage/adapter/index.d.ts +0 -9
  98. package/lib/storage/storage.d.ts +0 -49
  99. package/lib/sync/datastoreConnectivity.d.ts +0 -15
  100. package/lib/sync/datastoreReachability/index.d.ts +0 -3
  101. package/lib/sync/datastoreReachability/index.native.d.ts +0 -3
  102. package/lib/sync/index.d.ts +0 -81
  103. package/lib/sync/merger.d.ts +0 -11
  104. package/lib/sync/outbox.d.ts +0 -27
  105. package/lib/sync/processors/errorMaps.d.ts +0 -17
  106. package/lib/sync/processors/mutation.d.ts +0 -56
  107. package/lib/sync/processors/subscription.d.ts +0 -31
  108. package/lib/sync/processors/sync.d.ts +0 -26
  109. package/lib/sync/utils.d.ts +0 -42
  110. package/lib/types.d.ts +0 -501
  111. package/lib/util.d.ts +0 -145
@@ -88,9 +88,9 @@ var __spread = (this && this.__spread) || function () {
88
88
  return ar;
89
89
  };
90
90
  import API from '@aws-amplify/api';
91
- import { Amplify, ConsoleLogger as Logger, Hub, JS } from '@aws-amplify/core';
92
91
  import { Auth } from '@aws-amplify/auth';
93
92
  import Cache from '@aws-amplify/cache';
93
+ import { Amplify, ConsoleLogger as Logger, Hub, JS, BackgroundProcessManager, } from '@aws-amplify/core';
94
94
  import { immerable, produce, setAutoFreeze, enablePatches, } from 'immer';
95
95
  import { v4 as uuid4 } from 'uuid';
96
96
  import Observable from 'zen-observable-ts';
@@ -205,10 +205,14 @@ var initSchema = function (userSchema) {
205
205
  });
206
206
  return userClasses;
207
207
  };
208
- /* Checks if the schema has been initialized by initSchema().
208
+ /**
209
+ * Throws an exception if the schema has *not* been initialized
210
+ * by `initSchema()`.
209
211
  *
210
- * Call this function before accessing schema.
211
- * Currently this only needs to be called in start() and clear() because all other functions will call start first.
212
+ * **To be called before trying to access schema.**
213
+ *
214
+ * Currently this only needs to be called in `start()` and `clear()` because
215
+ * all other functions will call start first.
212
216
  */
213
217
  var checkSchemaInitialized = function () {
214
218
  if (schema === undefined) {
@@ -232,6 +236,11 @@ var createTypeClasses = function (namespace) {
232
236
  });
233
237
  return classes;
234
238
  };
239
+ /**
240
+ * Collection of instantiated models to allow storage of metadata apart from
241
+ * the model visible to the consuming app -- in case the app doesn't have
242
+ * metadata fields (_version, _deleted, etc.) exposed on the model itself.
243
+ */
235
244
  var instancesMetadata = new WeakSet();
236
245
  function modelInstanceCreator(modelConstructor, init) {
237
246
  instancesMetadata.add(init);
@@ -550,6 +559,18 @@ function getModelConstructorByModelName(namespaceName, modelName) {
550
559
  throw new Error(msg);
551
560
  }
552
561
  }
562
+ /**
563
+ * Queries the DataStore metadata tables to see if they are the expected
564
+ * version. If not, clobbers the whole DB. If so, leaves them alone.
565
+ * Otherwise, simply writes the schema version.
566
+ *
567
+ * SIDE EFFECT:
568
+ * 1. Creates a transaction
569
+ * 1. Updates data.
570
+ *
571
+ * @param storage Storage adapter containing the metadata.
572
+ * @param version The expected schema version.
573
+ */
553
574
  function checkSchemaVersion(storage, version) {
554
575
  return __awaiter(this, void 0, void 0, function () {
555
576
  var Setting, modelDefinition;
@@ -632,6 +653,14 @@ function getNamespace() {
632
653
  };
633
654
  return namespace;
634
655
  }
656
+ var DataStoreState;
657
+ (function (DataStoreState) {
658
+ DataStoreState["NotRunning"] = "Not Running";
659
+ DataStoreState["Starting"] = "Starting";
660
+ DataStoreState["Running"] = "Running";
661
+ DataStoreState["Stopping"] = "Stopping";
662
+ DataStoreState["Clearing"] = "Clearing";
663
+ })(DataStoreState || (DataStoreState = {}));
635
664
  var DataStore = /** @class */ (function () {
636
665
  function DataStore() {
637
666
  var _this = this;
@@ -647,168 +676,235 @@ var DataStore = /** @class */ (function () {
647
676
  API: this.API,
648
677
  Cache: this.Cache,
649
678
  };
679
+ /**
680
+ * **IMPORTANT!**
681
+ *
682
+ * Accumulator for background things that can **and MUST** be called when
683
+ * DataStore stops.
684
+ *
685
+ * These jobs **MUST** be *idempotent promises* that resolve ONLY
686
+ * once the intended jobs are completely finished and/or otherwise destroyed
687
+ * and cleaned up with ZERO outstanding:
688
+ *
689
+ * 1. side effects (e.g., state changes)
690
+ * 1. callbacks
691
+ * 1. subscriptions
692
+ * 1. calls to storage
693
+ * 1. *etc.*
694
+ *
695
+ * Methods that create pending promises, subscriptions, callbacks, or any
696
+ * type of side effect **MUST** be registered with the manager. And, a new
697
+ * manager must be created after each `exit()`.
698
+ *
699
+ * Failure to comply will put DataStore into a highly unpredictable state
700
+ * when it needs to stop or clear -- which occurs when restarting with new
701
+ * sync expressions, during testing, and potentially during app code
702
+ * recovery handling, etc..
703
+ *
704
+ * It is up to the discretion of each disposer whether to wait for job
705
+ * completion or to cancel operations and issue failures *as long as the
706
+ * disposer returns in a reasonable amount of time.*
707
+ *
708
+ * (Reasonable = *seconds*, not minutes.)
709
+ */
710
+ this.runningProcesses = new BackgroundProcessManager();
711
+ /**
712
+ * Indicates what state DataStore is in.
713
+ *
714
+ * Not [yet?] used for actual state management; but for messaging
715
+ * when errors occur, to help troubleshoot.
716
+ */
717
+ this.state = DataStoreState.NotRunning;
718
+ /**
719
+ * If not already done:
720
+ * 1. Attaches and initializes storage.
721
+ * 1. Loads the schema and records metadata.
722
+ * 1. If `this.amplifyConfig.aws_appsync_graphqlEndpoint` contains a URL,
723
+ * attaches a sync engine, starts it, and subscribes.
724
+ */
650
725
  this.start = function () { return __awaiter(_this, void 0, void 0, function () {
651
- var aws_appsync_graphqlEndpoint, _a, fullSyncIntervalInMilliseconds;
652
726
  var _this = this;
653
- return __generator(this, function (_b) {
654
- switch (_b.label) {
655
- case 0:
656
- if (!(this.initialized === undefined)) return [3 /*break*/, 1];
657
- logger.debug('Starting DataStore');
658
- this.initialized = new Promise(function (res, rej) {
659
- _this.initResolve = res;
660
- _this.initReject = rej;
661
- });
662
- return [3 /*break*/, 3];
663
- case 1: return [4 /*yield*/, this.initialized];
664
- case 2:
665
- _b.sent();
666
- return [2 /*return*/];
667
- case 3:
668
- this.storage = new Storage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
669
- return [4 /*yield*/, this.storage.init()];
670
- case 4:
671
- _b.sent();
672
- checkSchemaInitialized();
673
- return [4 /*yield*/, checkSchemaVersion(this.storage, schema.version)];
674
- case 5:
675
- _b.sent();
676
- aws_appsync_graphqlEndpoint = this.amplifyConfig.aws_appsync_graphqlEndpoint;
677
- if (!aws_appsync_graphqlEndpoint) return [3 /*break*/, 7];
678
- logger.debug('GraphQL endpoint available', aws_appsync_graphqlEndpoint);
679
- _a = this;
680
- return [4 /*yield*/, this.processSyncExpressions()];
681
- case 6:
682
- _a.syncPredicates = _b.sent();
683
- this.sync = new SyncEngine(schema, namespaceResolver, syncClasses, userClasses, this.storage, modelInstanceCreator, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy, this.amplifyContext);
684
- fullSyncIntervalInMilliseconds = this.fullSyncInterval * 1000 * 60;
685
- syncSubscription = this.sync
686
- .start({ fullSyncInterval: fullSyncIntervalInMilliseconds })
687
- .subscribe({
688
- next: function (_a) {
689
- var type = _a.type, data = _a.data;
690
- // In Node, we need to wait for queries to be synced to prevent returning empty arrays.
691
- // In the Browser, we can begin returning data once subscriptions are in place.
692
- var readyType = isNode
693
- ? ControlMessage.SYNC_ENGINE_SYNC_QUERIES_READY
694
- : ControlMessage.SYNC_ENGINE_STORAGE_SUBSCRIBED;
695
- if (type === readyType) {
696
- _this.initResolve();
697
- }
698
- Hub.dispatch('datastore', {
699
- event: type,
700
- data: data,
701
- });
702
- },
703
- error: function (err) {
704
- logger.warn('Sync error', err);
705
- _this.initReject();
706
- },
707
- });
708
- return [3 /*break*/, 8];
709
- case 7:
710
- logger.warn("Data won't be synchronized. No GraphQL endpoint configured. Did you forget `Amplify.configure(awsconfig)`?", {
711
- config: this.amplifyConfig,
727
+ return __generator(this, function (_a) {
728
+ return [2 /*return*/, this.runningProcesses
729
+ .add(function () { return __awaiter(_this, void 0, void 0, function () {
730
+ var aws_appsync_graphqlEndpoint, _a, fullSyncIntervalInMilliseconds;
731
+ var _this = this;
732
+ return __generator(this, function (_b) {
733
+ switch (_b.label) {
734
+ case 0:
735
+ this.state = DataStoreState.Starting;
736
+ if (!(this.initialized === undefined)) return [3 /*break*/, 1];
737
+ logger.debug('Starting DataStore');
738
+ this.initialized = new Promise(function (res, rej) {
739
+ _this.initResolve = res;
740
+ _this.initReject = rej;
741
+ });
742
+ return [3 /*break*/, 3];
743
+ case 1: return [4 /*yield*/, this.initialized];
744
+ case 2:
745
+ _b.sent();
746
+ return [2 /*return*/];
747
+ case 3:
748
+ this.storage = new Storage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
749
+ return [4 /*yield*/, this.storage.init()];
750
+ case 4:
751
+ _b.sent();
752
+ checkSchemaInitialized();
753
+ return [4 /*yield*/, checkSchemaVersion(this.storage, schema.version)];
754
+ case 5:
755
+ _b.sent();
756
+ aws_appsync_graphqlEndpoint = this.amplifyConfig.aws_appsync_graphqlEndpoint;
757
+ if (!aws_appsync_graphqlEndpoint) return [3 /*break*/, 7];
758
+ logger.debug('GraphQL endpoint available', aws_appsync_graphqlEndpoint);
759
+ _a = this;
760
+ return [4 /*yield*/, this.processSyncExpressions()];
761
+ case 6:
762
+ _a.syncPredicates = _b.sent();
763
+ this.sync = new SyncEngine(schema, namespaceResolver, syncClasses, userClasses, this.storage, modelInstanceCreator, this.conflictHandler, this.errorHandler, this.syncPredicates, this.amplifyConfig, this.authModeStrategy, this.amplifyContext, this.connectivityMonitor);
764
+ fullSyncIntervalInMilliseconds = this.fullSyncInterval * 1000 * 60;
765
+ syncSubscription = this.sync
766
+ .start({ fullSyncInterval: fullSyncIntervalInMilliseconds })
767
+ .subscribe({
768
+ next: function (_a) {
769
+ var type = _a.type, data = _a.data;
770
+ // In Node, we need to wait for queries to be synced to prevent returning empty arrays.
771
+ // In the Browser, we can begin returning data once subscriptions are in place.
772
+ var readyType = isNode
773
+ ? ControlMessage.SYNC_ENGINE_SYNC_QUERIES_READY
774
+ : ControlMessage.SYNC_ENGINE_STORAGE_SUBSCRIBED;
775
+ if (type === readyType) {
776
+ _this.initResolve();
777
+ }
778
+ Hub.dispatch('datastore', {
779
+ event: type,
780
+ data: data,
781
+ });
782
+ },
783
+ error: function (err) {
784
+ logger.warn('Sync error', err);
785
+ _this.initReject();
786
+ },
787
+ });
788
+ return [3 /*break*/, 8];
789
+ case 7:
790
+ logger.warn("Data won't be synchronized. No GraphQL endpoint configured. Did you forget `Amplify.configure(awsconfig)`?", {
791
+ config: this.amplifyConfig,
792
+ });
793
+ this.initResolve();
794
+ _b.label = 8;
795
+ case 8: return [4 /*yield*/, this.initialized];
796
+ case 9:
797
+ _b.sent();
798
+ this.state = DataStoreState.Running;
799
+ return [2 /*return*/];
800
+ }
712
801
  });
713
- this.initResolve();
714
- _b.label = 8;
715
- case 8: return [4 /*yield*/, this.initialized];
716
- case 9:
717
- _b.sent();
718
- return [2 /*return*/];
719
- }
802
+ }); }, 'datastore start')
803
+ .catch(this.handleAddProcError('DataStore.start()'))];
720
804
  });
721
805
  }); };
722
806
  this.query = function (modelConstructor, identifierOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
723
- var msg, modelDefinition, keyFields, predicate, msg, pagination, result, returnOne;
807
+ var _this = this;
724
808
  return __generator(this, function (_a) {
725
- switch (_a.label) {
726
- case 0: return [4 /*yield*/, this.start()];
727
- case 1:
728
- _a.sent();
729
- //#region Input validation
730
- if (!isValidModelConstructor(modelConstructor)) {
731
- msg = 'Constructor is not for a valid model';
732
- logger.error(msg, { modelConstructor: modelConstructor });
733
- throw new Error(msg);
734
- }
735
- if (typeof identifierOrCriteria === 'string') {
736
- if (paginationProducer !== undefined) {
737
- logger.warn('Pagination is ignored when querying by id');
738
- }
739
- }
740
- modelDefinition = getModelDefinition(modelConstructor);
741
- keyFields = extractPrimaryKeyFieldNames(modelDefinition);
742
- if (isQueryOne(identifierOrCriteria)) {
743
- if (keyFields.length > 1) {
744
- msg = errorMessages.queryByPkWithCompositeKeyPresent;
745
- logger.error(msg, { keyFields: keyFields });
746
- throw new Error(msg);
747
- }
748
- predicate = ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], identifierOrCriteria);
749
- }
750
- else {
751
- // Object is being queried using object literal syntax
752
- if (isIdentifierObject(identifierOrCriteria, modelDefinition)) {
753
- predicate = ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
754
- }
755
- else if (isPredicatesAll(identifierOrCriteria)) {
756
- // Predicates.ALL means "all records", so no predicate (undefined)
757
- predicate = undefined;
758
- }
759
- else {
760
- predicate = ModelPredicateCreator.createFromExisting(modelDefinition, identifierOrCriteria);
809
+ return [2 /*return*/, this.runningProcesses
810
+ .add(function () { return __awaiter(_this, void 0, void 0, function () {
811
+ var msg, modelDefinition, keyFields, predicate, msg, pagination, result, returnOne;
812
+ return __generator(this, function (_a) {
813
+ switch (_a.label) {
814
+ case 0: return [4 /*yield*/, this.start()];
815
+ case 1:
816
+ _a.sent();
817
+ //#region Input validation
818
+ if (!isValidModelConstructor(modelConstructor)) {
819
+ msg = 'Constructor is not for a valid model';
820
+ logger.error(msg, { modelConstructor: modelConstructor });
821
+ throw new Error(msg);
822
+ }
823
+ if (typeof identifierOrCriteria === 'string') {
824
+ if (paginationProducer !== undefined) {
825
+ logger.warn('Pagination is ignored when querying by id');
826
+ }
827
+ }
828
+ modelDefinition = getModelDefinition(modelConstructor);
829
+ keyFields = extractPrimaryKeyFieldNames(modelDefinition);
830
+ if (isQueryOne(identifierOrCriteria)) {
831
+ if (keyFields.length > 1) {
832
+ msg = errorMessages.queryByPkWithCompositeKeyPresent;
833
+ logger.error(msg, { keyFields: keyFields });
834
+ throw new Error(msg);
835
+ }
836
+ predicate = ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], identifierOrCriteria);
837
+ }
838
+ else {
839
+ // Object is being queried using object literal syntax
840
+ if (isIdentifierObject(identifierOrCriteria, modelDefinition)) {
841
+ predicate = ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
842
+ }
843
+ else if (isPredicatesAll(identifierOrCriteria)) {
844
+ // Predicates.ALL means "all records", so no predicate (undefined)
845
+ predicate = undefined;
846
+ }
847
+ else {
848
+ predicate = ModelPredicateCreator.createFromExisting(modelDefinition, identifierOrCriteria);
849
+ }
850
+ }
851
+ pagination = this.processPagination(modelDefinition, paginationProducer);
852
+ //#endregion
853
+ logger.debug('params ready', {
854
+ modelConstructor: modelConstructor,
855
+ predicate: ModelPredicateCreator.getPredicates(predicate, false),
856
+ pagination: __assign(__assign({}, pagination), { sort: ModelSortPredicateCreator.getPredicates(pagination && pagination.sort, false) }),
857
+ });
858
+ return [4 /*yield*/, this.storage.query(modelConstructor, predicate, pagination)];
859
+ case 2:
860
+ result = _a.sent();
861
+ returnOne = isQueryOne(identifierOrCriteria) ||
862
+ isIdentifierObject(identifierOrCriteria, modelDefinition);
863
+ return [2 /*return*/, returnOne ? result[0] : result];
761
864
  }
762
- }
763
- pagination = this.processPagination(modelDefinition, paginationProducer);
764
- //#endregion
765
- logger.debug('params ready', {
766
- modelConstructor: modelConstructor,
767
- predicate: ModelPredicateCreator.getPredicates(predicate, false),
768
- pagination: __assign(__assign({}, pagination), { sort: ModelSortPredicateCreator.getPredicates(pagination && pagination.sort, false) }),
769
865
  });
770
- return [4 /*yield*/, this.storage.query(modelConstructor, predicate, pagination)];
771
- case 2:
772
- result = _a.sent();
773
- returnOne = isQueryOne(identifierOrCriteria) ||
774
- isIdentifierObject(identifierOrCriteria, modelDefinition);
775
- return [2 /*return*/, returnOne ? result[0] : result];
776
- }
866
+ }); }, 'datastore query')
867
+ .catch(this.handleAddProcError('DataStore.query()'))];
777
868
  });
778
869
  }); };
779
870
  this.save = function (model, condition) { return __awaiter(_this, void 0, void 0, function () {
780
- var patchesTuple, modelConstructor, msg, modelDefinition, producedCondition, _a, savedModel;
781
871
  var _this = this;
782
- return __generator(this, function (_b) {
783
- switch (_b.label) {
784
- case 0: return [4 /*yield*/, this.start()];
785
- case 1:
786
- _b.sent();
787
- patchesTuple = modelPatchesMap.get(model);
788
- modelConstructor = model
789
- ? model.constructor
790
- : undefined;
791
- if (!isValidModelConstructor(modelConstructor)) {
792
- msg = 'Object is not an instance of a valid model';
793
- logger.error(msg, { model: model });
794
- throw new Error(msg);
795
- }
796
- modelDefinition = getModelDefinition(modelConstructor);
797
- producedCondition = ModelPredicateCreator.createFromExisting(modelDefinition, condition);
798
- return [4 /*yield*/, this.storage.runExclusive(function (s) { return __awaiter(_this, void 0, void 0, function () {
799
- return __generator(this, function (_a) {
800
- switch (_a.label) {
801
- case 0: return [4 /*yield*/, s.save(model, producedCondition, undefined, patchesTuple)];
802
- case 1:
803
- _a.sent();
804
- return [2 /*return*/, s.query(modelConstructor, ModelPredicateCreator.createForPk(modelDefinition, model))];
872
+ return __generator(this, function (_a) {
873
+ return [2 /*return*/, this.runningProcesses
874
+ .add(function () { return __awaiter(_this, void 0, void 0, function () {
875
+ var patchesTuple, modelConstructor, msg, modelDefinition, producedCondition, _a, savedModel;
876
+ var _this = this;
877
+ return __generator(this, function (_b) {
878
+ switch (_b.label) {
879
+ case 0: return [4 /*yield*/, this.start()];
880
+ case 1:
881
+ _b.sent();
882
+ patchesTuple = modelPatchesMap.get(model);
883
+ modelConstructor = model ? model.constructor : undefined;
884
+ if (!isValidModelConstructor(modelConstructor)) {
885
+ msg = 'Object is not an instance of a valid model';
886
+ logger.error(msg, { model: model });
887
+ throw new Error(msg);
805
888
  }
806
- });
807
- }); })];
808
- case 2:
809
- _a = __read.apply(void 0, [_b.sent(), 1]), savedModel = _a[0];
810
- return [2 /*return*/, savedModel];
811
- }
889
+ modelDefinition = getModelDefinition(modelConstructor);
890
+ producedCondition = ModelPredicateCreator.createFromExisting(modelDefinition, condition);
891
+ return [4 /*yield*/, this.storage.runExclusive(function (s) { return __awaiter(_this, void 0, void 0, function () {
892
+ return __generator(this, function (_a) {
893
+ switch (_a.label) {
894
+ case 0: return [4 /*yield*/, s.save(model, producedCondition, undefined, patchesTuple)];
895
+ case 1:
896
+ _a.sent();
897
+ return [2 /*return*/, s.query(modelConstructor, ModelPredicateCreator.createForPk(modelDefinition, model))];
898
+ }
899
+ });
900
+ }); })];
901
+ case 2:
902
+ _a = __read.apply(void 0, [_b.sent(), 1]), savedModel = _a[0];
903
+ return [2 /*return*/, savedModel];
904
+ }
905
+ });
906
+ }); }, 'datastore save')
907
+ .catch(this.handleAddProcError('DataStore.save()'))];
812
908
  });
813
909
  }); };
814
910
  this.setConflictHandler = function (config) {
@@ -838,83 +934,91 @@ var DataStore = /** @class */ (function () {
838
934
  return _this.errorHandler || defaultErrorHandler;
839
935
  };
840
936
  this.delete = function (modelOrConstructor, identifierOrCriteria) { return __awaiter(_this, void 0, void 0, function () {
841
- var condition, msg, modelConstructor, msg, modelDefinition, keyFields, msg, msg, _a, deleted, model, modelConstructor, msg, modelDefinition, pkPredicate, msg, _b, _c, deleted;
842
- return __generator(this, function (_d) {
843
- switch (_d.label) {
844
- case 0: return [4 /*yield*/, this.start()];
845
- case 1:
846
- _d.sent();
847
- if (!modelOrConstructor) {
848
- msg = 'Model or Model Constructor required';
849
- logger.error(msg, { modelOrConstructor: modelOrConstructor });
850
- throw new Error(msg);
851
- }
852
- if (!isValidModelConstructor(modelOrConstructor)) return [3 /*break*/, 3];
853
- modelConstructor = modelOrConstructor;
854
- if (!identifierOrCriteria) {
855
- msg = 'Id to delete or criteria required. Do you want to delete all? Pass Predicates.ALL';
856
- logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
857
- throw new Error(msg);
858
- }
859
- modelDefinition = getModelDefinition(modelConstructor);
860
- if (typeof identifierOrCriteria === 'string') {
861
- keyFields = extractPrimaryKeyFieldNames(modelDefinition);
862
- if (keyFields.length > 1) {
863
- msg = errorMessages.deleteByPkWithCompositeKeyPresent;
864
- logger.error(msg, { keyFields: keyFields });
865
- throw new Error(msg);
866
- }
867
- condition = ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyFields[0], identifierOrCriteria);
868
- }
869
- else {
870
- if (isIdentifierObject(identifierOrCriteria, modelDefinition)) {
871
- condition = ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
872
- }
873
- else {
874
- condition = ModelPredicateCreator.createFromExisting(modelDefinition,
875
- /**
876
- * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
877
- * The symbol is used only for typing purposes. e.g. see Predicates.ALL
878
- */
879
- identifierOrCriteria);
880
- }
881
- if (!condition || !ModelPredicateCreator.isValidPredicate(condition)) {
882
- msg = 'Criteria required. Do you want to delete all? Pass Predicates.ALL';
883
- logger.error(msg, { condition: condition });
884
- throw new Error(msg);
885
- }
886
- }
887
- return [4 /*yield*/, this.storage.delete(modelConstructor, condition)];
888
- case 2:
889
- _a = __read.apply(void 0, [_d.sent(), 1]), deleted = _a[0];
890
- return [2 /*return*/, deleted];
891
- case 3:
892
- model = modelOrConstructor;
893
- modelConstructor = Object.getPrototypeOf(model || {})
894
- .constructor;
895
- if (!isValidModelConstructor(modelConstructor)) {
896
- msg = 'Object is not an instance of a valid model';
897
- logger.error(msg, { model: model });
898
- throw new Error(msg);
899
- }
900
- modelDefinition = getModelDefinition(modelConstructor);
901
- pkPredicate = ModelPredicateCreator.createForPk(modelDefinition, model);
902
- if (identifierOrCriteria) {
903
- if (typeof identifierOrCriteria !== 'function') {
904
- msg = 'Invalid criteria';
905
- logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
906
- throw new Error(msg);
937
+ var _this = this;
938
+ return __generator(this, function (_a) {
939
+ return [2 /*return*/, this.runningProcesses
940
+ .add(function () { return __awaiter(_this, void 0, void 0, function () {
941
+ var condition, msg, modelConstructor, msg, modelDefinition, keyFields, msg, msg, _a, deleted, model, modelConstructor, msg, modelDefinition, pkPredicate, msg, _b, _c, deleted;
942
+ return __generator(this, function (_d) {
943
+ switch (_d.label) {
944
+ case 0: return [4 /*yield*/, this.start()];
945
+ case 1:
946
+ _d.sent();
947
+ if (!modelOrConstructor) {
948
+ msg = 'Model or Model Constructor required';
949
+ logger.error(msg, { modelOrConstructor: modelOrConstructor });
950
+ throw new Error(msg);
951
+ }
952
+ if (!isValidModelConstructor(modelOrConstructor)) return [3 /*break*/, 3];
953
+ modelConstructor = modelOrConstructor;
954
+ if (!identifierOrCriteria) {
955
+ msg = 'Id to delete or criteria required. Do you want to delete all? Pass Predicates.ALL';
956
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
957
+ throw new Error(msg);
958
+ }
959
+ modelDefinition = getModelDefinition(modelConstructor);
960
+ if (typeof identifierOrCriteria === 'string') {
961
+ keyFields = extractPrimaryKeyFieldNames(modelDefinition);
962
+ if (keyFields.length > 1) {
963
+ msg = errorMessages.deleteByPkWithCompositeKeyPresent;
964
+ logger.error(msg, { keyFields: keyFields });
965
+ throw new Error(msg);
966
+ }
967
+ condition = ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyFields[0], identifierOrCriteria);
968
+ }
969
+ else {
970
+ if (isIdentifierObject(identifierOrCriteria, modelDefinition)) {
971
+ condition = ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
972
+ }
973
+ else {
974
+ condition = ModelPredicateCreator.createFromExisting(modelDefinition,
975
+ /**
976
+ * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
977
+ * The symbol is used only for typing purposes. e.g. see Predicates.ALL
978
+ */
979
+ identifierOrCriteria);
980
+ }
981
+ if (!condition ||
982
+ !ModelPredicateCreator.isValidPredicate(condition)) {
983
+ msg = 'Criteria required. Do you want to delete all? Pass Predicates.ALL';
984
+ logger.error(msg, { condition: condition });
985
+ throw new Error(msg);
986
+ }
987
+ }
988
+ return [4 /*yield*/, this.storage.delete(modelConstructor, condition)];
989
+ case 2:
990
+ _a = __read.apply(void 0, [_d.sent(), 1]), deleted = _a[0];
991
+ return [2 /*return*/, deleted];
992
+ case 3:
993
+ model = modelOrConstructor;
994
+ modelConstructor = Object.getPrototypeOf(model || {})
995
+ .constructor;
996
+ if (!isValidModelConstructor(modelConstructor)) {
997
+ msg = 'Object is not an instance of a valid model';
998
+ logger.error(msg, { model: model });
999
+ throw new Error(msg);
1000
+ }
1001
+ modelDefinition = getModelDefinition(modelConstructor);
1002
+ pkPredicate = ModelPredicateCreator.createForPk(modelDefinition, model);
1003
+ if (identifierOrCriteria) {
1004
+ if (typeof identifierOrCriteria !== 'function') {
1005
+ msg = 'Invalid criteria';
1006
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
1007
+ throw new Error(msg);
1008
+ }
1009
+ condition = identifierOrCriteria(pkPredicate);
1010
+ }
1011
+ else {
1012
+ condition = pkPredicate;
1013
+ }
1014
+ return [4 /*yield*/, this.storage.delete(model, condition)];
1015
+ case 4:
1016
+ _b = __read.apply(void 0, [_d.sent(), 1]), _c = __read(_b[0], 1), deleted = _c[0];
1017
+ return [2 /*return*/, deleted];
907
1018
  }
908
- condition = identifierOrCriteria(pkPredicate);
909
- }
910
- else {
911
- condition = pkPredicate;
912
- }
913
- return [4 /*yield*/, this.storage.delete(model, condition)];
914
- case 4:
915
- _b = __read.apply(void 0, [_d.sent(), 1]), _c = __read(_b[0], 1), deleted = _c[0];
916
- return [2 /*return*/, deleted];
917
- }
1019
+ });
1020
+ }); }, 'datastore delete')
1021
+ .catch(this.handleAddProcError('DataStore.delete()'))];
918
1022
  });
919
1023
  }); };
920
1024
  this.observe = function (modelOrConstructor, identifierOrCriteria) {
@@ -975,7 +1079,8 @@ var DataStore = /** @class */ (function () {
975
1079
  }
976
1080
  return new Observable(function (observer) {
977
1081
  var handle;
978
- (function () { return __awaiter(_this, void 0, void 0, function () {
1082
+ _this.runningProcesses
1083
+ .add(function () { return __awaiter(_this, void 0, void 0, function () {
979
1084
  var _this = this;
980
1085
  return __generator(this, function (_a) {
981
1086
  switch (_a.label) {
@@ -991,39 +1096,52 @@ var DataStore = /** @class */ (function () {
991
1096
  return namespaceResolver(model) === USER;
992
1097
  })
993
1098
  .subscribe({
994
- next: function (item) { return __awaiter(_this, void 0, void 0, function () {
995
- var message, modelDefinition, keyFields, primaryKeysAndValues, freshElement;
996
- return __generator(this, function (_a) {
997
- switch (_a.label) {
998
- case 0:
999
- message = item;
1000
- if (!(item.opType !== 'DELETE')) return [3 /*break*/, 2];
1001
- modelDefinition = getModelDefinition(item.model);
1002
- keyFields = extractPrimaryKeyFieldNames(modelDefinition);
1003
- primaryKeysAndValues = extractPrimaryKeysAndValues(item.element, keyFields);
1004
- return [4 /*yield*/, this.query(item.model, primaryKeysAndValues)];
1005
- case 1:
1006
- freshElement = _a.sent();
1007
- message = __assign(__assign({}, message), { element: freshElement });
1008
- _a.label = 2;
1009
- case 2:
1010
- observer.next(message);
1011
- return [2 /*return*/];
1012
- }
1013
- });
1014
- }); },
1099
+ next: function (item) {
1100
+ return _this.runningProcesses.isOpen &&
1101
+ _this.runningProcesses.add(function () { return __awaiter(_this, void 0, void 0, function () {
1102
+ var message, modelDefinition, keyFields, primaryKeysAndValues, freshElement;
1103
+ return __generator(this, function (_a) {
1104
+ switch (_a.label) {
1105
+ case 0:
1106
+ message = item;
1107
+ if (!(item.opType !== 'DELETE')) return [3 /*break*/, 2];
1108
+ modelDefinition = getModelDefinition(item.model);
1109
+ keyFields = extractPrimaryKeyFieldNames(modelDefinition);
1110
+ primaryKeysAndValues = extractPrimaryKeysAndValues(item.element, keyFields);
1111
+ return [4 /*yield*/, this.query(item.model, primaryKeysAndValues)];
1112
+ case 1:
1113
+ freshElement = _a.sent();
1114
+ message = __assign(__assign({}, message), { element: freshElement });
1115
+ _a.label = 2;
1116
+ case 2:
1117
+ observer.next(message);
1118
+ return [2 /*return*/];
1119
+ }
1120
+ });
1121
+ }); }, 'datastore observe message handler');
1122
+ },
1015
1123
  error: function (err) { return observer.error(err); },
1016
1124
  complete: function () { return observer.complete(); },
1017
1125
  });
1018
1126
  return [2 /*return*/];
1019
1127
  }
1020
1128
  });
1021
- }); })();
1022
- return function () {
1023
- if (handle) {
1024
- handle.unsubscribe();
1025
- }
1026
- };
1129
+ }); }, 'datastore observe observable initialization')
1130
+ .catch(_this.handleAddProcError('DataStore.observe()'))
1131
+ .catch(function (error) {
1132
+ observer.error(error);
1133
+ });
1134
+ // better than no cleaner, but if the subscriber is handling the
1135
+ // complete() message async and not registering with the context,
1136
+ // this will still be problematic.
1137
+ return _this.runningProcesses.addCleaner(function () { return __awaiter(_this, void 0, void 0, function () {
1138
+ return __generator(this, function (_a) {
1139
+ if (handle) {
1140
+ handle.unsubscribe();
1141
+ }
1142
+ return [2 /*return*/];
1143
+ });
1144
+ }); }, 'DataStore.observe() cleanup');
1027
1145
  });
1028
1146
  };
1029
1147
  this.observeQuery = function (model, criteria, options) {
@@ -1072,7 +1190,8 @@ var DataStore = /** @class */ (function () {
1072
1190
  }
1073
1191
  var _a = ModelPredicateCreator.getPredicates(predicate, false) || {}, predicates = _a.predicates, predicateGroupType = _a.type;
1074
1192
  var hasPredicate = !!predicates;
1075
- (function () { return __awaiter(_this, void 0, void 0, function () {
1193
+ _this.runningProcesses
1194
+ .add(function () { return __awaiter(_this, void 0, void 0, function () {
1076
1195
  var err_1;
1077
1196
  var _this = this;
1078
1197
  return __generator(this, function (_a) {
@@ -1122,7 +1241,8 @@ var DataStore = /** @class */ (function () {
1122
1241
  itemsChanged.set(idOrPk, element);
1123
1242
  }
1124
1243
  var isSynced = (_c = (_b = _this.sync) === null || _b === void 0 ? void 0 : _b.getModelSyncedStatus(model)) !== null && _c !== void 0 ? _c : false;
1125
- var limit = itemsChanged.size - deletedItemIds.length >= _this.syncPageSize;
1244
+ var limit = itemsChanged.size - deletedItemIds.length >=
1245
+ _this.syncPageSize;
1126
1246
  if (limit || isSynced) {
1127
1247
  limitTimerRace.resolve();
1128
1248
  }
@@ -1139,7 +1259,11 @@ var DataStore = /** @class */ (function () {
1139
1259
  case 3: return [2 /*return*/];
1140
1260
  }
1141
1261
  });
1142
- }); })();
1262
+ }); }, 'datastore observequery startup')
1263
+ .catch(_this.handleAddProcError('DataStore.observeQuery()'))
1264
+ .catch(function (error) {
1265
+ observer.error(error);
1266
+ });
1143
1267
  /**
1144
1268
  * Combines the `items`, `itemsChanged`, and `deletedItemIds` collections into
1145
1269
  * a snapshot in the form of `{ items: T[], isSynced: boolean}`.
@@ -1175,7 +1299,8 @@ var DataStore = /** @class */ (function () {
1175
1299
  * @param snapshot The generated items data to emit.
1176
1300
  */
1177
1301
  var emitSnapshot = function (snapshot) {
1178
- // send the generated snapshot to the primary subscription
1302
+ // send the generated snapshot to the primary subscription.
1303
+ // NOTE: This observer's handler *could* be async ...
1179
1304
  observer.next(snapshot);
1180
1305
  // reset the changed items sets
1181
1306
  itemsChanged.clear();
@@ -1211,15 +1336,18 @@ var DataStore = /** @class */ (function () {
1211
1336
  if (event === ControlMessage.SYNC_ENGINE_MODEL_SYNCED &&
1212
1337
  ((_b = data === null || data === void 0 ? void 0 : data.model) === null || _b === void 0 ? void 0 : _b.name) === model.name) {
1213
1338
  generateAndEmitSnapshot();
1214
- Hub.remove('api', hubCallback);
1339
+ Hub.remove('datastore', hubCallback);
1215
1340
  }
1216
1341
  };
1217
1342
  Hub.listen('datastore', hubCallback);
1218
- return function () {
1219
- if (handle) {
1220
- handle.unsubscribe();
1221
- }
1222
- };
1343
+ return _this.runningProcesses.addCleaner(function () { return __awaiter(_this, void 0, void 0, function () {
1344
+ return __generator(this, function (_a) {
1345
+ if (handle) {
1346
+ handle.unsubscribe();
1347
+ }
1348
+ return [2 /*return*/];
1349
+ });
1350
+ }); }, 'datastore observequery cleaner');
1223
1351
  });
1224
1352
  };
1225
1353
  this.configure = function (config) {
@@ -1278,66 +1406,132 @@ var DataStore = /** @class */ (function () {
1278
1406
  undefined;
1279
1407
  _this.sessionId = _this.retrieveSessionId();
1280
1408
  };
1281
- this.clear = function clear() {
1282
- return __awaiter(this, void 0, void 0, function () {
1283
- return __generator(this, function (_a) {
1284
- switch (_a.label) {
1285
- case 0:
1286
- checkSchemaInitialized();
1287
- if (!(this.storage === undefined)) return [3 /*break*/, 2];
1288
- // connect to storage so that it can be cleared without fully starting DataStore
1289
- this.storage = new Storage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
1290
- return [4 /*yield*/, this.storage.init()];
1291
- case 1:
1292
- _a.sent();
1293
- _a.label = 2;
1294
- case 2:
1295
- if (syncSubscription && !syncSubscription.closed) {
1296
- syncSubscription.unsubscribe();
1297
- }
1298
- return [4 /*yield*/, this.storage.clear()];
1299
- case 3:
1300
- _a.sent();
1301
- if (this.sync) {
1302
- this.sync.unsubscribeConnectivity();
1303
- }
1304
- this.initialized = undefined; // Should re-initialize when start() is called.
1305
- this.storage = undefined;
1306
- this.sync = undefined;
1307
- this.syncPredicates = new WeakMap();
1308
- return [2 /*return*/];
1309
- }
1310
- });
1311
- });
1312
- };
1313
- this.stop = function stop() {
1314
- return __awaiter(this, void 0, void 0, function () {
1315
- return __generator(this, function (_a) {
1316
- switch (_a.label) {
1317
- case 0:
1318
- if (!(this.initialized !== undefined)) return [3 /*break*/, 2];
1319
- return [4 /*yield*/, this.start()];
1320
- case 1:
1321
- _a.sent();
1322
- _a.label = 2;
1323
- case 2:
1324
- if (syncSubscription && !syncSubscription.closed) {
1325
- syncSubscription.unsubscribe();
1326
- }
1327
- if (this.sync) {
1328
- this.sync.unsubscribeConnectivity();
1329
- }
1330
- this.initialized = undefined; // Should re-initialize when start() is called.
1331
- this.sync = undefined;
1332
- return [2 /*return*/];
1333
- }
1334
- });
1335
- });
1336
- };
1337
1409
  }
1338
1410
  DataStore.prototype.getModuleName = function () {
1339
1411
  return 'DataStore';
1340
1412
  };
1413
+ /**
1414
+ * Builds a function to capture `BackgroundManagerNotOpenError`'s to produce friendlier,
1415
+ * more instructive errors for customers.
1416
+ *
1417
+ * @param operation The name of the operation (usually a Datastore method) the customer
1418
+ * tried to call.
1419
+ */
1420
+ DataStore.prototype.handleAddProcError = function (operation) {
1421
+ var _this = this;
1422
+ /**
1423
+ * If the tested error is a `BackgroundManagerNotOpenError`, it will be captured
1424
+ * and replaced with a friendlier message that instructs the App Developer.
1425
+ *
1426
+ * @param err An error to test.
1427
+ */
1428
+ var handler = function (err) {
1429
+ if (err.message.startsWith('BackgroundManagerNotOpenError')) {
1430
+ throw new Error([
1431
+ "DataStoreStateError: Tried to execute `" + operation + "` while DataStore was \"" + _this.state + "\".",
1432
+ "This can only be done while DataStore is \"Started\" or \"Stopped\". To remedy:",
1433
+ 'Ensure all calls to `stop()` and `clear()` have completed first.',
1434
+ 'If this is not possible, retry the operation until it succeeds.',
1435
+ ].join('\n'));
1436
+ }
1437
+ else {
1438
+ throw err;
1439
+ }
1440
+ };
1441
+ return handler;
1442
+ };
1443
+ /**
1444
+ * Clears all data from storage and removes all data, schema info, other
1445
+ * initialization details, and then stops DataStore.
1446
+ *
1447
+ * That said, reinitialization is required after clearing. This can be done
1448
+ * by explicitiliy calling `start()` or any method that implicitly starts
1449
+ * DataStore, such as `query()`, `save()`, or `delete()`.
1450
+ */
1451
+ DataStore.prototype.clear = function () {
1452
+ return __awaiter(this, void 0, void 0, function () {
1453
+ return __generator(this, function (_a) {
1454
+ switch (_a.label) {
1455
+ case 0:
1456
+ checkSchemaInitialized();
1457
+ this.state = DataStoreState.Clearing;
1458
+ return [4 /*yield*/, this.runningProcesses.close()];
1459
+ case 1:
1460
+ _a.sent();
1461
+ if (!(this.storage === undefined)) return [3 /*break*/, 3];
1462
+ // connect to storage so that it can be cleared without fully starting DataStore
1463
+ this.storage = new Storage(schema, namespaceResolver, getModelConstructorByModelName, modelInstanceCreator, this.storageAdapter, this.sessionId);
1464
+ return [4 /*yield*/, this.storage.init()];
1465
+ case 2:
1466
+ _a.sent();
1467
+ _a.label = 3;
1468
+ case 3:
1469
+ if (syncSubscription && !syncSubscription.closed) {
1470
+ syncSubscription.unsubscribe();
1471
+ }
1472
+ if (!this.sync) return [3 /*break*/, 5];
1473
+ return [4 /*yield*/, this.sync.stop()];
1474
+ case 4:
1475
+ _a.sent();
1476
+ _a.label = 5;
1477
+ case 5: return [4 /*yield*/, this.storage.clear()];
1478
+ case 6:
1479
+ _a.sent();
1480
+ this.initialized = undefined; // Should re-initialize when start() is called.
1481
+ this.storage = undefined;
1482
+ this.sync = undefined;
1483
+ this.syncPredicates = new WeakMap();
1484
+ return [4 /*yield*/, this.runningProcesses.open()];
1485
+ case 7:
1486
+ _a.sent();
1487
+ this.state = DataStoreState.NotRunning;
1488
+ return [2 /*return*/];
1489
+ }
1490
+ });
1491
+ });
1492
+ };
1493
+ /**
1494
+ * Stops all DataStore sync activities.
1495
+ *
1496
+ * TODO: "Waits for graceful termination of
1497
+ * running queries and terminates subscriptions."
1498
+ */
1499
+ DataStore.prototype.stop = function () {
1500
+ return __awaiter(this, void 0, void 0, function () {
1501
+ return __generator(this, function (_a) {
1502
+ switch (_a.label) {
1503
+ case 0:
1504
+ this.state = DataStoreState.Stopping;
1505
+ return [4 /*yield*/, this.runningProcesses.close()];
1506
+ case 1:
1507
+ _a.sent();
1508
+ if (syncSubscription && !syncSubscription.closed) {
1509
+ syncSubscription.unsubscribe();
1510
+ }
1511
+ if (!this.sync) return [3 /*break*/, 3];
1512
+ return [4 /*yield*/, this.sync.stop()];
1513
+ case 2:
1514
+ _a.sent();
1515
+ _a.label = 3;
1516
+ case 3:
1517
+ this.initialized = undefined; // Should re-initialize when start() is called.
1518
+ this.sync = undefined;
1519
+ return [4 /*yield*/, this.runningProcesses.open()];
1520
+ case 4:
1521
+ _a.sent();
1522
+ this.state = DataStoreState.NotRunning;
1523
+ return [2 /*return*/];
1524
+ }
1525
+ });
1526
+ });
1527
+ };
1528
+ /**
1529
+ * Validates given pagination input from a query and creates a pagination
1530
+ * argument for use against the storage layer.
1531
+ *
1532
+ * @param modelDefinition
1533
+ * @param paginationProducer
1534
+ */
1341
1535
  DataStore.prototype.processPagination = function (modelDefinition, paginationProducer) {
1342
1536
  var sortPredicate;
1343
1537
  var _a = paginationProducer || {}, limit = _a.limit, page = _a.page, sort = _a.sort;
@@ -1372,6 +1566,10 @@ var DataStore = /** @class */ (function () {
1372
1566
  sort: sortPredicate,
1373
1567
  };
1374
1568
  };
1569
+ /**
1570
+ * Examines the configured `syncExpressions` and produces a WeakMap of
1571
+ * SchemaModel -> predicate to use during sync.
1572
+ */
1375
1573
  DataStore.prototype.processSyncExpressions = function () {
1376
1574
  return __awaiter(this, void 0, void 0, function () {
1377
1575
  var syncPredicates;
@@ -1453,7 +1651,10 @@ var DataStore = /** @class */ (function () {
1453
1651
  return map;
1454
1652
  }, new WeakMap());
1455
1653
  };
1456
- // database separation for Amplify Console. Not a public API
1654
+ /**
1655
+ * A session ID to allow CMS to open databases against multiple apps.
1656
+ * This session ID is only expected be set by AWS Amplify Studio.
1657
+ */
1457
1658
  DataStore.prototype.retrieveSessionId = function () {
1458
1659
  try {
1459
1660
  var sessionId = sessionStorage.getItem('datastoreSessionId');