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