@aws-amplify/datastore 3.12.11 → 3.12.13-unstable.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 (106) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/aws-amplify-datastore.js +1853 -964
  3. package/dist/aws-amplify-datastore.js.map +1 -1
  4. package/dist/aws-amplify-datastore.min.js +7 -7
  5. package/dist/aws-amplify-datastore.min.js.map +1 -1
  6. package/lib/datastore/datastore.d.ts +13 -16
  7. package/lib/datastore/datastore.js +130 -63
  8. package/lib/datastore/datastore.js.map +1 -1
  9. package/lib/index.d.ts +3 -19
  10. package/lib/predicates/index.d.ts +3 -2
  11. package/lib/predicates/index.js +12 -2
  12. package/lib/predicates/index.js.map +1 -1
  13. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +4 -3
  14. package/lib/storage/adapter/AsyncStorageAdapter.js +354 -203
  15. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  16. package/lib/storage/adapter/AsyncStorageDatabase.d.ts +14 -4
  17. package/lib/storage/adapter/AsyncStorageDatabase.js +65 -28
  18. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  19. package/lib/storage/adapter/IndexedDBAdapter.d.ts +5 -4
  20. package/lib/storage/adapter/IndexedDBAdapter.js +389 -267
  21. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  22. package/lib/storage/adapter/index.d.ts +1 -1
  23. package/lib/storage/storage.d.ts +1 -1
  24. package/lib/storage/storage.js +92 -27
  25. package/lib/storage/storage.js.map +1 -1
  26. package/lib/sync/index.d.ts +21 -4
  27. package/lib/sync/index.js +13 -11
  28. package/lib/sync/index.js.map +1 -1
  29. package/lib/sync/merger.d.ts +3 -3
  30. package/lib/sync/merger.js +7 -6
  31. package/lib/sync/merger.js.map +1 -1
  32. package/lib/sync/outbox.d.ts +2 -2
  33. package/lib/sync/outbox.js +11 -9
  34. package/lib/sync/outbox.js.map +1 -1
  35. package/lib/sync/processors/mutation.js +60 -42
  36. package/lib/sync/processors/mutation.js.map +1 -1
  37. package/lib/sync/processors/subscription.js.map +1 -1
  38. package/lib/sync/processors/sync.js.map +1 -1
  39. package/lib/sync/utils.d.ts +3 -2
  40. package/lib/sync/utils.js +61 -8
  41. package/lib/sync/utils.js.map +1 -1
  42. package/lib/types.d.ts +64 -25
  43. package/lib/types.js +10 -1
  44. package/lib/types.js.map +1 -1
  45. package/lib/util.d.ts +56 -24
  46. package/lib/util.js +334 -170
  47. package/lib/util.js.map +1 -1
  48. package/lib-esm/datastore/datastore.d.ts +13 -16
  49. package/lib-esm/datastore/datastore.js +132 -65
  50. package/lib-esm/datastore/datastore.js.map +1 -1
  51. package/lib-esm/index.d.ts +3 -19
  52. package/lib-esm/predicates/index.d.ts +3 -2
  53. package/lib-esm/predicates/index.js +13 -3
  54. package/lib-esm/predicates/index.js.map +1 -1
  55. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +4 -3
  56. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +355 -204
  57. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  58. package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +14 -4
  59. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +66 -29
  60. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  61. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +5 -4
  62. package/lib-esm/storage/adapter/IndexedDBAdapter.js +390 -268
  63. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  64. package/lib-esm/storage/adapter/index.d.ts +1 -1
  65. package/lib-esm/storage/storage.d.ts +1 -1
  66. package/lib-esm/storage/storage.js +92 -27
  67. package/lib-esm/storage/storage.js.map +1 -1
  68. package/lib-esm/sync/index.d.ts +21 -4
  69. package/lib-esm/sync/index.js +15 -13
  70. package/lib-esm/sync/index.js.map +1 -1
  71. package/lib-esm/sync/merger.d.ts +3 -3
  72. package/lib-esm/sync/merger.js +7 -6
  73. package/lib-esm/sync/merger.js.map +1 -1
  74. package/lib-esm/sync/outbox.d.ts +2 -2
  75. package/lib-esm/sync/outbox.js +12 -10
  76. package/lib-esm/sync/outbox.js.map +1 -1
  77. package/lib-esm/sync/processors/mutation.js +61 -43
  78. package/lib-esm/sync/processors/mutation.js.map +1 -1
  79. package/lib-esm/sync/processors/subscription.js.map +1 -1
  80. package/lib-esm/sync/processors/sync.js.map +1 -1
  81. package/lib-esm/sync/utils.d.ts +3 -2
  82. package/lib-esm/sync/utils.js +62 -10
  83. package/lib-esm/sync/utils.js.map +1 -1
  84. package/lib-esm/types.d.ts +64 -25
  85. package/lib-esm/types.js +9 -2
  86. package/lib-esm/types.js.map +1 -1
  87. package/lib-esm/util.d.ts +56 -24
  88. package/lib-esm/util.js +334 -170
  89. package/lib-esm/util.js.map +1 -1
  90. package/package.json +7 -7
  91. package/src/datastore/datastore.ts +253 -113
  92. package/src/predicates/index.ts +32 -10
  93. package/src/storage/adapter/AsyncStorageAdapter.ts +309 -93
  94. package/src/storage/adapter/AsyncStorageDatabase.ts +74 -26
  95. package/src/storage/adapter/IndexedDBAdapter.ts +319 -136
  96. package/src/storage/adapter/index.ts +1 -1
  97. package/src/storage/storage.ts +68 -21
  98. package/src/sync/index.ts +41 -26
  99. package/src/sync/merger.ts +14 -4
  100. package/src/sync/outbox.ts +21 -8
  101. package/src/sync/processors/mutation.ts +49 -45
  102. package/src/sync/processors/subscription.ts +0 -1
  103. package/src/sync/processors/sync.ts +1 -3
  104. package/src/sync/utils.ts +69 -12
  105. package/src/types.ts +181 -29
  106. package/src/util.ts +415 -176
@@ -1,12 +1,10 @@
1
1
  import Observable from 'zen-observable-ts';
2
2
  import { PredicateAll } from '../predicates';
3
- import { ConflictHandler, DataStoreConfig, ModelInit, ModelInstanceMetadata, NonModelTypeConstructor, ProducerPaginationInput, PersistentModel, PersistentModelConstructor, ProducerModelPredicate, Schema, SubscriptionMessage, DataStoreSnapshot, TypeConstructorMap, ErrorHandler, ObserveQueryOptions } from '../types';
3
+ import { ConflictHandler, DataStoreConfig, NonModelTypeConstructor, ProducerPaginationInput, PersistentModel, PersistentModelConstructor, ProducerModelPredicate, Schema, SubscriptionMessage, DataStoreSnapshot, TypeConstructorMap, ErrorHandler, ObserveQueryOptions, PersistentModelMetaData, IdentifierFieldOrIdentifierObject } from '../types';
4
4
  export declare let syncClasses: TypeConstructorMap;
5
- declare const initSchema: (userSchema: Schema) => Record<string, NonModelTypeConstructor<any> | PersistentModelConstructor<any, {
6
- readOnlyFields: "createdAt" | "updatedAt";
7
- }>>;
5
+ declare const initSchema: (userSchema: Schema) => Record<string, PersistentModelConstructor<any> | NonModelTypeConstructor<unknown>>;
8
6
  export declare type ModelInstanceCreator = typeof modelInstanceCreator;
9
- declare function modelInstanceCreator<T extends PersistentModel = PersistentModel>(modelConstructor: PersistentModelConstructor<T>, init: ModelInit<T> & Partial<ModelInstanceMetadata>): T;
7
+ declare function modelInstanceCreator<T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, init: Partial<T>): T;
10
8
  declare class DataStore {
11
9
  private Auth;
12
10
  private API;
@@ -16,12 +14,12 @@ declare class DataStore {
16
14
  private conflictHandler;
17
15
  private errorHandler;
18
16
  private fullSyncInterval;
19
- private initialized;
17
+ private initialized?;
20
18
  private initReject;
21
19
  private initResolve;
22
20
  private maxRecordsToSync;
23
- private storage;
24
- private sync;
21
+ private storage?;
22
+ private sync?;
25
23
  private syncPageSize;
26
24
  private syncExpressions;
27
25
  private syncPredicates;
@@ -31,30 +29,29 @@ declare class DataStore {
31
29
  getModuleName(): string;
32
30
  start: () => Promise<void>;
33
31
  query: {
34
- <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, id: string): Promise<T | undefined>;
32
+ <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, identifier: IdentifierFieldOrIdentifierObject<T, PersistentModelMetaData<T>>): Promise<T | undefined>;
35
33
  <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, criteria?: ProducerModelPredicate<T> | typeof PredicateAll, paginationProducer?: ProducerPaginationInput<T>): Promise<T[]>;
36
34
  };
37
- save: <T extends Readonly<{
38
- id: string;
39
- } & Record<string, any>>>(model: T, condition?: ProducerModelPredicate<T>) => Promise<T>;
35
+ save: <T extends Readonly<Record<string, any>>>(model: T, condition?: ProducerModelPredicate<T>) => Promise<T>;
40
36
  setConflictHandler: (config: DataStoreConfig) => ConflictHandler;
41
37
  setErrorHandler: (config: DataStoreConfig) => ErrorHandler;
42
38
  delete: {
43
- <T extends PersistentModel>(model: T, condition?: ProducerModelPredicate<T>): Promise<T>;
44
- <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, id: string): Promise<T[]>;
39
+ <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, identifier: IdentifierFieldOrIdentifierObject<T, PersistentModelMetaData<T>>): Promise<T[]>;
45
40
  <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, condition: ProducerModelPredicate<T> | typeof PredicateAll): Promise<T[]>;
41
+ <T extends PersistentModel>(model: T, condition?: ProducerModelPredicate<T>): Promise<T>;
46
42
  };
47
43
  observe: {
48
44
  (): Observable<SubscriptionMessage<PersistentModel>>;
45
+ <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, identifier: string): Observable<SubscriptionMessage<T>>;
46
+ <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, criteria?: ProducerModelPredicate<T> | typeof PredicateAll): Observable<SubscriptionMessage<T>>;
49
47
  <T extends PersistentModel>(model: T): Observable<SubscriptionMessage<T>>;
50
- <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, criteria?: string | ProducerModelPredicate<T>): Observable<SubscriptionMessage<T>>;
51
48
  };
52
49
  observeQuery: {
53
50
  <T extends PersistentModel>(modelConstructor: PersistentModelConstructor<T>, criteria?: ProducerModelPredicate<T> | typeof PredicateAll, paginationProducer?: ObserveQueryOptions<T>): Observable<DataStoreSnapshot<T>>;
54
51
  };
55
52
  configure: (config?: DataStoreConfig) => void;
56
53
  clear: () => Promise<void>;
57
- stop: () => Promise<void>;
54
+ stop: (this: DataStore) => Promise<void>;
58
55
  private processPagination;
59
56
  private processSyncExpressions;
60
57
  private createFromCondition;
@@ -105,6 +105,7 @@ var storage_1 = require("../storage/storage");
105
105
  var sync_1 = require("../sync");
106
106
  var types_1 = require("../types");
107
107
  var util_1 = require("../util");
108
+ var utils_1 = require("../sync/utils");
108
109
  immer_1.setAutoFreeze(true);
109
110
  immer_1.enablePatches();
110
111
  var logger = new core_1.ConsoleLogger('DataStore');
@@ -248,6 +249,13 @@ var validateModelFields = function (modelDefinition) { return function (k, v) {
248
249
  (v === null || v === undefined)) {
249
250
  throw new Error("Field " + name_1 + " is required");
250
251
  }
252
+ if (types_1.isSchemaModelWithAttributes(modelDefinition) && !util_1.isIdManaged(modelDefinition)) {
253
+ var keys = util_1.extractPrimaryKeyFieldNames(modelDefinition);
254
+ if (keys.includes(k) && v === '') {
255
+ logger.error(util_1.errorMessages.idEmptyString, { k: k, value: v });
256
+ throw new Error(util_1.errorMessages.idEmptyString);
257
+ }
258
+ }
251
259
  if (types_1.isGraphQLScalarType(type)) {
252
260
  var jsType_1 = types_1.GraphQLScalarType.getJSType(type);
253
261
  var validateScalar_1 = types_1.GraphQLScalarType.getValidationFunction(type);
@@ -348,21 +356,29 @@ var createModelClass = function (modelDefinition) {
348
356
  function Model(init) {
349
357
  var instance = immer_1.produce(this, function (draft) {
350
358
  initializeInstance(init, modelDefinition, draft);
351
- var modelInstanceMetadata = instancesMetadata.has(init)
359
+ // model is initialized inside a DataStore component (e.g. by Sync Engine, Storage Engine, etc.)
360
+ var isInternallyInitialized = instancesMetadata.has(init);
361
+ var modelInstanceMetadata = isInternallyInitialized
352
362
  ? init
353
363
  : {};
354
- var _id = modelInstanceMetadata.id, _version = modelInstanceMetadata._version, _lastChangedAt = modelInstanceMetadata._lastChangedAt, _deleted = modelInstanceMetadata._deleted;
355
- // instancesIds are set by modelInstanceCreator, it is accessible only internally
356
- var isInternal = _id !== null && _id !== undefined;
357
- var id = isInternal
358
- ? _id
359
- : modelDefinition.syncable
360
- ? uuid_1.v4()
361
- : ulid();
362
- if (!isInternal) {
364
+ var _id = modelInstanceMetadata.id;
365
+ if (util_1.isIdManaged(modelDefinition)) {
366
+ var isInternalModel = _id !== null && _id !== undefined;
367
+ var id = isInternalModel
368
+ ? _id
369
+ : modelDefinition.syncable
370
+ ? uuid_1.v4()
371
+ : ulid();
372
+ draft.id = id;
373
+ }
374
+ else if (util_1.isIdOptionallyManaged(modelDefinition)) {
375
+ // only auto-populate if the id was not provided
376
+ draft.id = draft.id || uuid_1.v4();
377
+ }
378
+ if (!isInternallyInitialized) {
363
379
  checkReadOnlyPropertyOnCreate(draft, modelDefinition);
364
380
  }
365
- draft.id = id;
381
+ var _version = modelInstanceMetadata._version, _lastChangedAt = modelInstanceMetadata._lastChangedAt, _deleted = modelInstanceMetadata._deleted;
366
382
  if (modelDefinition.syncable) {
367
383
  draft._version = _version;
368
384
  draft._lastChangedAt = _lastChangedAt;
@@ -381,7 +397,9 @@ var createModelClass = function (modelDefinition) {
381
397
  var patches;
382
398
  var model = immer_1.produce(source, function (draft) {
383
399
  fn(draft);
384
- draft.id = source.id;
400
+ var keyNames = util_1.extractPrimaryKeyFieldNames(modelDefinition);
401
+ // Keys are immutable
402
+ keyNames.forEach(function (key) { return (draft[key] = source[key]); });
385
403
  var modelValidator = validateModelFields(modelDefinition);
386
404
  Object.entries(draft).forEach(function (_a) {
387
405
  var _b = __read(_a, 2), k = _b[0], v = _b[1];
@@ -514,7 +532,6 @@ function checkSchemaVersion(storage, version) {
514
532
  return __generator(this, function (_b) {
515
533
  switch (_b.label) {
516
534
  case 0: return [4 /*yield*/, s.query(Setting, predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition, function (c) {
517
- // @ts-ignore Argument of type '"eq"' is not assignable to parameter of type 'never'.
518
535
  return c.key('eq', SETTING_SCHEMA_VERSION);
519
536
  }), { page: 0, limit: 1 })];
520
537
  case 1:
@@ -670,8 +687,8 @@ var DataStore = /** @class */ (function () {
670
687
  }
671
688
  });
672
689
  }); };
673
- this.query = function (modelConstructor, idOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
674
- var msg, modelDefinition, predicate, pagination, result;
690
+ this.query = function (modelConstructor, identifierOrCriteria, paginationProducer) { return __awaiter(_this, void 0, void 0, function () {
691
+ var msg, modelDefinition, keyFields, predicate, msg, pagination, result, returnOne;
675
692
  return __generator(this, function (_a) {
676
693
  switch (_a.label) {
677
694
  case 0: return [4 /*yield*/, this.start()];
@@ -683,22 +700,32 @@ var DataStore = /** @class */ (function () {
683
700
  logger.error(msg, { modelConstructor: modelConstructor });
684
701
  throw new Error(msg);
685
702
  }
686
- if (typeof idOrCriteria === 'string') {
703
+ if (typeof identifierOrCriteria === 'string') {
687
704
  if (paginationProducer !== undefined) {
688
705
  logger.warn('Pagination is ignored when querying by id');
689
706
  }
690
707
  }
691
708
  modelDefinition = getModelDefinition(modelConstructor);
692
- if (isQueryOne(idOrCriteria)) {
693
- predicate = predicates_1.ModelPredicateCreator.createForId(modelDefinition, idOrCriteria);
709
+ keyFields = util_1.extractPrimaryKeyFieldNames(modelDefinition);
710
+ if (isQueryOne(identifierOrCriteria)) {
711
+ if (keyFields.length > 1) {
712
+ msg = util_1.errorMessages.queryByPkWithCompositeKeyPresent;
713
+ logger.error(msg, { keyFields: keyFields });
714
+ throw new Error(msg);
715
+ }
716
+ predicate = predicates_1.ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], identifierOrCriteria);
694
717
  }
695
718
  else {
696
- if (predicates_1.isPredicatesAll(idOrCriteria)) {
719
+ // Object is being queried using object literal syntax
720
+ if (types_1.isIdentifierObject(identifierOrCriteria, modelDefinition)) {
721
+ predicate = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
722
+ }
723
+ else if (predicates_1.isPredicatesAll(identifierOrCriteria)) {
697
724
  // Predicates.ALL means "all records", so no predicate (undefined)
698
725
  predicate = undefined;
699
726
  }
700
727
  else {
701
- predicate = predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition, idOrCriteria);
728
+ predicate = predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition, identifierOrCriteria);
702
729
  }
703
730
  }
704
731
  pagination = this.processPagination(modelDefinition, paginationProducer);
@@ -711,7 +738,9 @@ var DataStore = /** @class */ (function () {
711
738
  return [4 /*yield*/, this.storage.query(modelConstructor, predicate, pagination)];
712
739
  case 2:
713
740
  result = _a.sent();
714
- return [2 /*return*/, isQueryOne(idOrCriteria) ? result[0] : result];
741
+ returnOne = isQueryOne(identifierOrCriteria) ||
742
+ types_1.isIdentifierObject(identifierOrCriteria, modelDefinition);
743
+ return [2 /*return*/, returnOne ? result[0] : result];
715
744
  }
716
745
  });
717
746
  }); };
@@ -740,7 +769,7 @@ var DataStore = /** @class */ (function () {
740
769
  case 0: return [4 /*yield*/, s.save(model, producedCondition, undefined, patchesTuple)];
741
770
  case 1:
742
771
  _a.sent();
743
- return [2 /*return*/, s.query(modelConstructor, predicates_1.ModelPredicateCreator.createForId(modelDefinition, model.id))];
772
+ return [2 /*return*/, s.query(modelConstructor, predicates_1.ModelPredicateCreator.createForPk(modelDefinition, model))];
744
773
  }
745
774
  });
746
775
  }); })];
@@ -776,8 +805,8 @@ var DataStore = /** @class */ (function () {
776
805
  }
777
806
  return _this.errorHandler || defaultErrorHandler;
778
807
  };
779
- this.delete = function (modelOrConstructor, idOrCriteria) { return __awaiter(_this, void 0, void 0, function () {
780
- var condition, msg, modelConstructor, msg, msg, _a, deleted, model, modelConstructor, msg, modelDefinition, idPredicate, msg, _b, _c, deleted;
808
+ this.delete = function (modelOrConstructor, identifierOrCriteria) { return __awaiter(_this, void 0, void 0, function () {
809
+ var condition, msg, modelConstructor, msg, modelDefinition, keyFields, msg, msg, _a, deleted, model, modelConstructor, msg, modelDefinition, pkPredicate, msg, _b, _c, deleted;
781
810
  return __generator(this, function (_d) {
782
811
  switch (_d.label) {
783
812
  case 0: return [4 /*yield*/, this.start()];
@@ -790,21 +819,33 @@ var DataStore = /** @class */ (function () {
790
819
  }
791
820
  if (!isValidModelConstructor(modelOrConstructor)) return [3 /*break*/, 3];
792
821
  modelConstructor = modelOrConstructor;
793
- if (!idOrCriteria) {
822
+ if (!identifierOrCriteria) {
794
823
  msg = 'Id to delete or criteria required. Do you want to delete all? Pass Predicates.ALL';
795
- logger.error(msg, { idOrCriteria: idOrCriteria });
824
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
796
825
  throw new Error(msg);
797
826
  }
798
- if (typeof idOrCriteria === 'string') {
799
- condition = predicates_1.ModelPredicateCreator.createForId(getModelDefinition(modelConstructor), idOrCriteria);
827
+ modelDefinition = getModelDefinition(modelConstructor);
828
+ if (typeof identifierOrCriteria === 'string') {
829
+ keyFields = util_1.extractPrimaryKeyFieldNames(modelDefinition);
830
+ if (keyFields.length > 1) {
831
+ msg = util_1.errorMessages.deleteByPkWithCompositeKeyPresent;
832
+ logger.error(msg, { keyFields: keyFields });
833
+ throw new Error(msg);
834
+ }
835
+ condition = predicates_1.ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyFields[0], identifierOrCriteria);
800
836
  }
801
837
  else {
802
- condition = predicates_1.ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor),
803
- /**
804
- * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
805
- * The symbol is used only for typing purposes. e.g. see Predicates.ALL
806
- */
807
- idOrCriteria);
838
+ if (types_1.isIdentifierObject(identifierOrCriteria, modelDefinition)) {
839
+ condition = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, identifierOrCriteria);
840
+ }
841
+ else {
842
+ condition = predicates_1.ModelPredicateCreator.createFromExisting(modelDefinition,
843
+ /**
844
+ * idOrCriteria is always a ProducerModelPredicate<T>, never a symbol.
845
+ * The symbol is used only for typing purposes. e.g. see Predicates.ALL
846
+ */
847
+ identifierOrCriteria);
848
+ }
808
849
  if (!condition || !predicates_1.ModelPredicateCreator.isValidPredicate(condition)) {
809
850
  msg = 'Criteria required. Do you want to delete all? Pass Predicates.ALL';
810
851
  logger.error(msg, { condition: condition });
@@ -825,17 +866,17 @@ var DataStore = /** @class */ (function () {
825
866
  throw new Error(msg);
826
867
  }
827
868
  modelDefinition = getModelDefinition(modelConstructor);
828
- idPredicate = predicates_1.ModelPredicateCreator.createForId(modelDefinition, model.id);
829
- if (idOrCriteria) {
830
- if (typeof idOrCriteria !== 'function') {
869
+ pkPredicate = predicates_1.ModelPredicateCreator.createForPk(modelDefinition, model);
870
+ if (identifierOrCriteria) {
871
+ if (typeof identifierOrCriteria !== 'function') {
831
872
  msg = 'Invalid criteria';
832
- logger.error(msg, { idOrCriteria: idOrCriteria });
873
+ logger.error(msg, { identifierOrCriteria: identifierOrCriteria });
833
874
  throw new Error(msg);
834
875
  }
835
- condition = idOrCriteria(idPredicate);
876
+ condition = identifierOrCriteria(pkPredicate);
836
877
  }
837
878
  else {
838
- condition = idPredicate;
879
+ condition = pkPredicate;
839
880
  }
840
881
  return [4 /*yield*/, this.storage.delete(model, condition)];
841
882
  case 4:
@@ -844,7 +885,7 @@ var DataStore = /** @class */ (function () {
844
885
  }
845
886
  });
846
887
  }); };
847
- this.observe = function (modelOrConstructor, idOrCriteria) {
888
+ this.observe = function (modelOrConstructor, identifierOrCriteria) {
848
889
  var predicate;
849
890
  var modelConstructor = modelOrConstructor && isValidModelConstructor(modelOrConstructor)
850
891
  ? modelOrConstructor
@@ -853,10 +894,10 @@ var DataStore = /** @class */ (function () {
853
894
  var model = modelOrConstructor;
854
895
  var modelConstructor_1 = model && Object.getPrototypeOf(model).constructor;
855
896
  if (isValidModelConstructor(modelConstructor_1)) {
856
- if (idOrCriteria) {
897
+ if (identifierOrCriteria) {
857
898
  logger.warn('idOrCriteria is ignored when using a model instance', {
858
899
  model: model,
859
- idOrCriteria: idOrCriteria,
900
+ identifierOrCriteria: identifierOrCriteria,
860
901
  });
861
902
  }
862
903
  return _this.observe(modelConstructor_1, model.id);
@@ -867,9 +908,17 @@ var DataStore = /** @class */ (function () {
867
908
  throw new Error(msg);
868
909
  }
869
910
  }
870
- if (idOrCriteria !== undefined && modelConstructor === undefined) {
911
+ // observe should not accept object literal syntax
912
+ if (identifierOrCriteria &&
913
+ modelConstructor &&
914
+ types_1.isIdentifierObject(identifierOrCriteria, getModelDefinition(modelConstructor))) {
915
+ var msg = util_1.errorMessages.observeWithObjectLiteral;
916
+ logger.error(msg, { objectLiteral: identifierOrCriteria });
917
+ throw new Error(msg);
918
+ }
919
+ if (identifierOrCriteria !== undefined && modelConstructor === undefined) {
871
920
  var msg = 'Cannot provide criteria without a modelConstructor';
872
- logger.error(msg, idOrCriteria);
921
+ logger.error(msg, identifierOrCriteria);
873
922
  throw new Error(msg);
874
923
  }
875
924
  if (modelConstructor && !isValidModelConstructor(modelConstructor)) {
@@ -877,13 +926,20 @@ var DataStore = /** @class */ (function () {
877
926
  logger.error(msg, { modelConstructor: modelConstructor });
878
927
  throw new Error(msg);
879
928
  }
880
- if (typeof idOrCriteria === 'string') {
881
- predicate = predicates_1.ModelPredicateCreator.createForId(getModelDefinition(modelConstructor), idOrCriteria);
929
+ if (typeof identifierOrCriteria === 'string') {
930
+ var modelDefinition = getModelDefinition(modelConstructor);
931
+ var _a = __read(util_1.extractPrimaryKeyFieldNames(modelDefinition), 1), keyField = _a[0];
932
+ predicate = predicates_1.ModelPredicateCreator.createForSingleField(getModelDefinition(modelConstructor), keyField, identifierOrCriteria);
882
933
  }
883
934
  else {
884
- predicate =
885
- modelConstructor &&
886
- predicates_1.ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor), idOrCriteria);
935
+ if (predicates_1.isPredicatesAll(identifierOrCriteria)) {
936
+ predicate = undefined;
937
+ }
938
+ else {
939
+ predicate =
940
+ modelConstructor &&
941
+ predicates_1.ModelPredicateCreator.createFromExisting(getModelDefinition(modelConstructor), identifierOrCriteria);
942
+ }
887
943
  }
888
944
  return new zen_observable_ts_1.default(function (observer) {
889
945
  var handle;
@@ -904,13 +960,16 @@ var DataStore = /** @class */ (function () {
904
960
  })
905
961
  .subscribe({
906
962
  next: function (item) { return __awaiter(_this, void 0, void 0, function () {
907
- var message, freshElement;
963
+ var message, modelDefinition, keyFields, primaryKeysAndValues, freshElement;
908
964
  return __generator(this, function (_a) {
909
965
  switch (_a.label) {
910
966
  case 0:
911
967
  message = item;
912
968
  if (!(item.opType !== 'DELETE')) return [3 /*break*/, 2];
913
- return [4 /*yield*/, this.query(item.model, item.element.id)];
969
+ modelDefinition = getModelDefinition(item.model);
970
+ keyFields = util_1.extractPrimaryKeyFieldNames(modelDefinition);
971
+ primaryKeysAndValues = util_1.extractPrimaryKeysAndValues(item.element, keyFields);
972
+ return [4 /*yield*/, this.query(item.model, primaryKeysAndValues)];
914
973
  case 1:
915
974
  freshElement = _a.sent();
916
975
  message = __assign(__assign({}, message), { element: freshElement });
@@ -966,8 +1025,9 @@ var DataStore = /** @class */ (function () {
966
1025
  var sort = (options || {}).sort;
967
1026
  var sortOptions = sort ? { sort: sort } : undefined;
968
1027
  var modelDefinition = getModelDefinition(model);
1028
+ var keyFields = util_1.extractPrimaryKeyFieldNames(modelDefinition);
969
1029
  if (isQueryOne(criteria)) {
970
- predicate = predicates_1.ModelPredicateCreator.createForId(modelDefinition, criteria);
1030
+ predicate = predicates_1.ModelPredicateCreator.createForSingleField(modelDefinition, keyFields[0], criteria);
971
1031
  }
972
1032
  else {
973
1033
  if (predicates_1.isPredicatesAll(criteria)) {
@@ -991,7 +1051,9 @@ var DataStore = /** @class */ (function () {
991
1051
  case 1:
992
1052
  // first, query and return any locally-available records
993
1053
  (_a.sent()).forEach(function (item) {
994
- return items.set(item.id, item);
1054
+ var itemModelDefinition = getModelDefinition(model);
1055
+ var idOrPk = utils_1.getIdentifierValue(itemModelDefinition, item);
1056
+ items.set(idOrPk, item);
995
1057
  });
996
1058
  // Observe the model and send a stream of updates (debounced).
997
1059
  // We need to post-filter results instead of passing criteria through
@@ -1000,15 +1062,17 @@ var DataStore = /** @class */ (function () {
1000
1062
  handle = this.observe(model).subscribe(function (_a) {
1001
1063
  var element = _a.element, model = _a.model, opType = _a.opType;
1002
1064
  var _b, _c;
1065
+ var itemModelDefinition = getModelDefinition(model);
1066
+ var idOrPk = utils_1.getIdentifierValue(itemModelDefinition, element);
1003
1067
  if (hasPredicate &&
1004
1068
  !util_1.validatePredicate(element, predicateGroupType, predicates)) {
1005
1069
  if (opType === 'UPDATE' &&
1006
- (items.has(element.id) || itemsChanged.has(element.id))) {
1070
+ (items.has(idOrPk) || itemsChanged.has(idOrPk))) {
1007
1071
  // tracking as a "deleted item" will include the item in
1008
1072
  // page limit calculations and ensure it is removed from the
1009
1073
  // final items collection, regardless of which collection(s)
1010
1074
  // it is currently in. (I mean, it could be in both, right!?)
1011
- deletedItemIds.push(element.id);
1075
+ deletedItemIds.push(idOrPk);
1012
1076
  }
1013
1077
  else {
1014
1078
  // ignore updates for irrelevant/filtered items.
@@ -1020,10 +1084,10 @@ var DataStore = /** @class */ (function () {
1020
1084
  // in the `mergePage` method within src/sync/merger.ts. The final state of a model instance
1021
1085
  // depends on the LATEST record (for a given id).
1022
1086
  if (opType === 'DELETE') {
1023
- deletedItemIds.push(element.id);
1087
+ deletedItemIds.push(idOrPk);
1024
1088
  }
1025
1089
  else {
1026
- itemsChanged.set(element.id, element);
1090
+ itemsChanged.set(idOrPk, element);
1027
1091
  }
1028
1092
  var isSynced = (_c = (_b = _this.sync) === null || _b === void 0 ? void 0 : _b.getModelSyncedStatus(model)) !== null && _c !== void 0 ? _c : false;
1029
1093
  var limit = itemsChanged.size - deletedItemIds.length >= _this.syncPageSize;
@@ -1058,9 +1122,13 @@ var DataStore = /** @class */ (function () {
1058
1122
  sortItems(itemsArray);
1059
1123
  }
1060
1124
  items.clear();
1061
- itemsArray.forEach(function (item) { return items.set(item.id, item); });
1125
+ itemsArray.forEach(function (item) {
1126
+ var itemModelDefinition = getModelDefinition(model);
1127
+ var idOrPk = utils_1.getIdentifierValue(itemModelDefinition, item);
1128
+ items.set(idOrPk, item);
1129
+ });
1062
1130
  // remove deleted items from the final result set
1063
- deletedItemIds.forEach(function (id) { return items.delete(id); });
1131
+ deletedItemIds.forEach(function (idOrPk) { return items.delete(idOrPk); });
1064
1132
  return {
1065
1133
  items: Array.from(items.values()),
1066
1134
  isSynced: isSynced,
@@ -1364,9 +1432,8 @@ var DataStore = /** @class */ (function () {
1364
1432
  return sessionId + "-" + appSyncId;
1365
1433
  }
1366
1434
  }
1367
- catch (_b) {
1368
- return undefined;
1369
- }
1435
+ catch (_b) { }
1436
+ return undefined;
1370
1437
  };
1371
1438
  return DataStore;
1372
1439
  }());