@aws-amplify/datastore 4.7.6-api-v6-models.b3abc9b.0 → 5.0.0

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 (187) hide show
  1. package/README.md +4 -0
  2. package/lib/authModeStrategies/defaultAuthStrategy.js +3 -2
  3. package/lib/authModeStrategies/index.js +3 -3
  4. package/lib/authModeStrategies/multiAuthStrategy.js +38 -53
  5. package/lib/datastore/datastore.d.ts +4 -5
  6. package/lib/datastore/datastore.js +929 -1284
  7. package/lib/index.d.ts +1 -1
  8. package/lib/index.js +26 -13
  9. package/lib/predicates/index.js +54 -69
  10. package/lib/predicates/next.d.ts +2 -2
  11. package/lib/predicates/next.js +313 -462
  12. package/lib/predicates/sort.js +24 -28
  13. package/lib/ssr/index.js +2 -2
  14. package/lib/storage/adapter/AsyncStorageAdapter.js +120 -342
  15. package/lib/storage/adapter/AsyncStorageDatabase.js +217 -421
  16. package/lib/storage/adapter/InMemoryStore.js +28 -51
  17. package/lib/storage/adapter/InMemoryStore.native.js +5 -3
  18. package/lib/storage/adapter/IndexedDBAdapter.js +466 -871
  19. package/lib/storage/adapter/StorageAdapterBase.js +180 -330
  20. package/lib/storage/adapter/getDefaultAdapter/index.js +8 -10
  21. package/lib/storage/adapter/getDefaultAdapter/index.native.js +5 -4
  22. package/lib/storage/adapter/index.js +0 -1
  23. package/lib/storage/relationship.js +177 -253
  24. package/lib/storage/storage.d.ts +4 -4
  25. package/lib/storage/storage.js +255 -433
  26. package/lib/sync/datastoreConnectivity.d.ts +2 -2
  27. package/lib/sync/datastoreConnectivity.js +29 -39
  28. package/lib/sync/datastoreReachability/index.d.ts +1 -3
  29. package/lib/sync/datastoreReachability/index.js +3 -3
  30. package/lib/sync/datastoreReachability/index.native.d.ts +1 -3
  31. package/lib/sync/datastoreReachability/index.native.js +4 -5
  32. package/lib/sync/index.d.ts +2 -2
  33. package/lib/sync/index.js +522 -827
  34. package/lib/sync/merger.js +31 -63
  35. package/lib/sync/outbox.js +148 -232
  36. package/lib/sync/processors/errorMaps.d.ts +1 -1
  37. package/lib/sync/processors/errorMaps.js +30 -47
  38. package/lib/sync/processors/mutation.d.ts +2 -2
  39. package/lib/sync/processors/mutation.js +343 -502
  40. package/lib/sync/processors/subscription.d.ts +5 -2
  41. package/lib/sync/processors/subscription.js +283 -437
  42. package/lib/sync/processors/sync.d.ts +2 -2
  43. package/lib/sync/processors/sync.js +279 -404
  44. package/lib/sync/utils.d.ts +5 -4
  45. package/lib/sync/utils.js +267 -320
  46. package/lib/tsconfig.tsbuildinfo +1 -0
  47. package/lib/types.d.ts +138 -140
  48. package/lib/types.js +17 -24
  49. package/lib/util.d.ts +9 -17
  50. package/lib/util.js +387 -511
  51. package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -2
  52. package/lib-esm/authModeStrategies/index.js +0 -1
  53. package/lib-esm/authModeStrategies/multiAuthStrategy.js +35 -52
  54. package/lib-esm/datastore/datastore.d.ts +4 -5
  55. package/lib-esm/datastore/datastore.js +888 -1247
  56. package/lib-esm/index.d.ts +1 -1
  57. package/lib-esm/index.js +6 -7
  58. package/lib-esm/predicates/index.js +53 -70
  59. package/lib-esm/predicates/next.d.ts +2 -2
  60. package/lib-esm/predicates/next.js +306 -459
  61. package/lib-esm/predicates/sort.js +23 -28
  62. package/lib-esm/ssr/index.js +1 -2
  63. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -338
  64. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -416
  65. package/lib-esm/storage/adapter/InMemoryStore.js +27 -52
  66. package/lib-esm/storage/adapter/InMemoryStore.native.js +0 -1
  67. package/lib-esm/storage/adapter/IndexedDBAdapter.js +438 -866
  68. package/lib-esm/storage/adapter/StorageAdapterBase.js +173 -325
  69. package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -6
  70. package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -2
  71. package/lib-esm/storage/adapter/index.js +1 -1
  72. package/lib-esm/storage/relationship.js +173 -251
  73. package/lib-esm/storage/storage.d.ts +4 -4
  74. package/lib-esm/storage/storage.js +242 -424
  75. package/lib-esm/sync/datastoreConnectivity.d.ts +2 -2
  76. package/lib-esm/sync/datastoreConnectivity.js +28 -39
  77. package/lib-esm/sync/datastoreReachability/index.d.ts +1 -3
  78. package/lib-esm/sync/datastoreReachability/index.js +2 -3
  79. package/lib-esm/sync/datastoreReachability/index.native.d.ts +1 -3
  80. package/lib-esm/sync/datastoreReachability/index.native.js +3 -4
  81. package/lib-esm/sync/index.d.ts +2 -2
  82. package/lib-esm/sync/index.js +502 -812
  83. package/lib-esm/sync/merger.js +28 -61
  84. package/lib-esm/sync/outbox.js +143 -228
  85. package/lib-esm/sync/processors/errorMaps.d.ts +1 -1
  86. package/lib-esm/sync/processors/errorMaps.js +32 -50
  87. package/lib-esm/sync/processors/mutation.d.ts +2 -2
  88. package/lib-esm/sync/processors/mutation.js +329 -490
  89. package/lib-esm/sync/processors/subscription.d.ts +5 -2
  90. package/lib-esm/sync/processors/subscription.js +266 -421
  91. package/lib-esm/sync/processors/sync.d.ts +2 -2
  92. package/lib-esm/sync/processors/sync.js +271 -397
  93. package/lib-esm/sync/utils.d.ts +5 -4
  94. package/lib-esm/sync/utils.js +252 -307
  95. package/lib-esm/tsconfig.tsbuildinfo +1 -0
  96. package/lib-esm/types.d.ts +138 -140
  97. package/lib-esm/types.js +16 -25
  98. package/lib-esm/util.d.ts +9 -17
  99. package/lib-esm/util.js +335 -497
  100. package/package.json +31 -26
  101. package/src/authModeStrategies/multiAuthStrategy.ts +15 -12
  102. package/src/datastore/datastore.ts +36 -35
  103. package/src/predicates/sort.ts +3 -1
  104. package/src/storage/adapter/InMemoryStore.ts +1 -1
  105. package/src/storage/adapter/IndexedDBAdapter.ts +2 -2
  106. package/src/storage/adapter/StorageAdapterBase.ts +2 -2
  107. package/src/storage/adapter/getDefaultAdapter/index.ts +1 -4
  108. package/src/storage/storage.ts +29 -24
  109. package/src/sync/datastoreConnectivity.ts +6 -6
  110. package/src/sync/datastoreReachability/index.native.ts +5 -3
  111. package/src/sync/datastoreReachability/index.ts +1 -1
  112. package/src/sync/index.ts +79 -89
  113. package/src/sync/processors/errorMaps.ts +7 -7
  114. package/src/sync/processors/mutation.ts +19 -13
  115. package/src/sync/processors/subscription.ts +221 -295
  116. package/src/sync/processors/sync.ts +11 -8
  117. package/src/sync/utils.ts +30 -15
  118. package/src/types.ts +4 -8
  119. package/src/util.ts +46 -9
  120. package/lib/.tsbuildinfo +0 -3
  121. package/lib/authModeStrategies/defaultAuthStrategy.js.map +0 -1
  122. package/lib/authModeStrategies/index.js.map +0 -1
  123. package/lib/authModeStrategies/multiAuthStrategy.js.map +0 -1
  124. package/lib/datastore/datastore.js.map +0 -1
  125. package/lib/index.js.map +0 -1
  126. package/lib/predicates/index.js.map +0 -1
  127. package/lib/predicates/next.js.map +0 -1
  128. package/lib/predicates/sort.js.map +0 -1
  129. package/lib/ssr/index.js.map +0 -1
  130. package/lib/storage/adapter/AsyncStorageAdapter.js.map +0 -1
  131. package/lib/storage/adapter/AsyncStorageDatabase.js.map +0 -1
  132. package/lib/storage/adapter/InMemoryStore.js.map +0 -1
  133. package/lib/storage/adapter/InMemoryStore.native.js.map +0 -1
  134. package/lib/storage/adapter/IndexedDBAdapter.js.map +0 -1
  135. package/lib/storage/adapter/StorageAdapterBase.js.map +0 -1
  136. package/lib/storage/adapter/getDefaultAdapter/index.js.map +0 -1
  137. package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
  138. package/lib/storage/adapter/index.js.map +0 -1
  139. package/lib/storage/relationship.js.map +0 -1
  140. package/lib/storage/storage.js.map +0 -1
  141. package/lib/sync/datastoreConnectivity.js.map +0 -1
  142. package/lib/sync/datastoreReachability/index.js.map +0 -1
  143. package/lib/sync/datastoreReachability/index.native.js.map +0 -1
  144. package/lib/sync/index.js.map +0 -1
  145. package/lib/sync/merger.js.map +0 -1
  146. package/lib/sync/outbox.js.map +0 -1
  147. package/lib/sync/processors/errorMaps.js.map +0 -1
  148. package/lib/sync/processors/mutation.js.map +0 -1
  149. package/lib/sync/processors/subscription.js.map +0 -1
  150. package/lib/sync/processors/sync.js.map +0 -1
  151. package/lib/sync/utils.js.map +0 -1
  152. package/lib/types.js.map +0 -1
  153. package/lib/util.js.map +0 -1
  154. package/lib-esm/.tsbuildinfo +0 -3
  155. package/lib-esm/authModeStrategies/defaultAuthStrategy.js.map +0 -1
  156. package/lib-esm/authModeStrategies/index.js.map +0 -1
  157. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +0 -1
  158. package/lib-esm/datastore/datastore.js.map +0 -1
  159. package/lib-esm/index.js.map +0 -1
  160. package/lib-esm/predicates/index.js.map +0 -1
  161. package/lib-esm/predicates/next.js.map +0 -1
  162. package/lib-esm/predicates/sort.js.map +0 -1
  163. package/lib-esm/ssr/index.js.map +0 -1
  164. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +0 -1
  165. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +0 -1
  166. package/lib-esm/storage/adapter/InMemoryStore.js.map +0 -1
  167. package/lib-esm/storage/adapter/InMemoryStore.native.js.map +0 -1
  168. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +0 -1
  169. package/lib-esm/storage/adapter/StorageAdapterBase.js.map +0 -1
  170. package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +0 -1
  171. package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
  172. package/lib-esm/storage/adapter/index.js.map +0 -1
  173. package/lib-esm/storage/relationship.js.map +0 -1
  174. package/lib-esm/storage/storage.js.map +0 -1
  175. package/lib-esm/sync/datastoreConnectivity.js.map +0 -1
  176. package/lib-esm/sync/datastoreReachability/index.js.map +0 -1
  177. package/lib-esm/sync/datastoreReachability/index.native.js.map +0 -1
  178. package/lib-esm/sync/index.js.map +0 -1
  179. package/lib-esm/sync/merger.js.map +0 -1
  180. package/lib-esm/sync/outbox.js.map +0 -1
  181. package/lib-esm/sync/processors/errorMaps.js.map +0 -1
  182. package/lib-esm/sync/processors/mutation.js.map +0 -1
  183. package/lib-esm/sync/processors/subscription.js.map +0 -1
  184. package/lib-esm/sync/processors/sync.js.map +0 -1
  185. package/lib-esm/sync/utils.js.map +0 -1
  186. package/lib-esm/types.js.map +0 -1
  187. package/lib-esm/util.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var tslib_1 = require("tslib");
4
- var types_1 = require("../types");
5
- var utils_1 = require("./utils");
3
+ exports.ModelMerger = void 0;
4
+ const types_1 = require("../types");
5
+ const utils_1 = require("./utils");
6
6
  // https://github.com/aws-amplify/amplify-js/blob/datastore-docs/packages/datastore/docs/sync-engine.md#merger
7
- var ModelMerger = /** @class */ (function () {
8
- function ModelMerger(outbox, ownSymbol) {
7
+ class ModelMerger {
8
+ constructor(outbox, ownSymbol) {
9
9
  this.outbox = outbox;
10
10
  this.ownSymbol = ownSymbol;
11
11
  }
@@ -15,62 +15,30 @@ var ModelMerger = /** @class */ (function () {
15
15
  * @param model The model from an outbox mutation.
16
16
  * @returns The type of operation (INSERT/UPDATE/DELETE)
17
17
  */
18
- ModelMerger.prototype.merge = function (storage, model, modelDefinition) {
19
- return tslib_1.__awaiter(this, void 0, void 0, function () {
20
- var result, mutationsForModel, isDelete;
21
- var _a, _b;
22
- return tslib_1.__generator(this, function (_c) {
23
- switch (_c.label) {
24
- case 0: return [4 /*yield*/, this.outbox.getForModel(storage, model, modelDefinition)];
25
- case 1:
26
- mutationsForModel = _c.sent();
27
- isDelete = model._deleted;
28
- if (!(mutationsForModel.length === 0)) return [3 /*break*/, 5];
29
- if (!isDelete) return [3 /*break*/, 3];
30
- result = types_1.OpType.DELETE;
31
- return [4 /*yield*/, storage.delete(model, undefined, this.ownSymbol)];
32
- case 2:
33
- _c.sent();
34
- return [3 /*break*/, 5];
35
- case 3: return [4 /*yield*/, storage.save(model, undefined, this.ownSymbol)];
36
- case 4:
37
- _a = tslib_1.__read.apply(void 0, [_c.sent(), 1]), _b = tslib_1.__read(_a[0], 2), result = _b[1];
38
- _c.label = 5;
39
- case 5: return [2 /*return*/, result];
40
- }
41
- });
42
- });
43
- };
44
- ModelMerger.prototype.mergePage = function (storage, modelConstructor, items, modelDefinition) {
45
- return tslib_1.__awaiter(this, void 0, void 0, function () {
46
- var itemsMap, items_1, items_1_1, item, modelId, page;
47
- var e_1, _a;
48
- return tslib_1.__generator(this, function (_b) {
49
- switch (_b.label) {
50
- case 0:
51
- itemsMap = new Map();
52
- try {
53
- for (items_1 = tslib_1.__values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
54
- item = items_1_1.value;
55
- modelId = utils_1.getIdentifierValue(modelDefinition, item);
56
- itemsMap.set(modelId, item);
57
- }
58
- }
59
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
60
- finally {
61
- try {
62
- if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
63
- }
64
- finally { if (e_1) throw e_1.error; }
65
- }
66
- page = tslib_1.__spread(itemsMap.values());
67
- return [4 /*yield*/, storage.batchSave(modelConstructor, page, this.ownSymbol)];
68
- case 1: return [2 /*return*/, _b.sent()];
69
- }
70
- });
71
- });
72
- };
73
- return ModelMerger;
74
- }());
18
+ async merge(storage, model, modelDefinition) {
19
+ let result;
20
+ const mutationsForModel = await this.outbox.getForModel(storage, model, modelDefinition);
21
+ const isDelete = model._deleted;
22
+ if (mutationsForModel.length === 0) {
23
+ if (isDelete) {
24
+ result = types_1.OpType.DELETE;
25
+ await storage.delete(model, undefined, this.ownSymbol);
26
+ }
27
+ else {
28
+ [[, result]] = await storage.save(model, undefined, this.ownSymbol);
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+ async mergePage(storage, modelConstructor, items, modelDefinition) {
34
+ const itemsMap = new Map();
35
+ for (const item of items) {
36
+ // merge items by model id. Latest record for a given id remains.
37
+ const modelId = (0, utils_1.getIdentifierValue)(modelDefinition, item);
38
+ itemsMap.set(modelId, item);
39
+ }
40
+ const page = [...itemsMap.values()];
41
+ return await storage.batchSave(modelConstructor, page, this.ownSymbol);
42
+ }
43
+ }
75
44
  exports.ModelMerger = ModelMerger;
76
- //# sourceMappingURL=merger.js.map
@@ -1,245 +1,164 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var tslib_1 = require("tslib");
4
- var predicates_1 = require("../predicates");
5
- var types_1 = require("../types");
6
- var util_1 = require("../util");
7
- var utils_1 = require("./utils");
3
+ exports.MutationEventOutbox = void 0;
4
+ const predicates_1 = require("../predicates");
5
+ const types_1 = require("../types");
6
+ const util_1 = require("../util");
7
+ const utils_1 = require("./utils");
8
8
  // TODO: Persist deleted ids
9
9
  // https://github.com/aws-amplify/amplify-js/blob/datastore-docs/packages/datastore/docs/sync-engine.md#outbox
10
- var MutationEventOutbox = /** @class */ (function () {
11
- function MutationEventOutbox(schema, MutationEvent, modelInstanceCreator, ownSymbol) {
10
+ class MutationEventOutbox {
11
+ constructor(schema, MutationEvent, modelInstanceCreator, ownSymbol) {
12
12
  this.schema = schema;
13
13
  this.MutationEvent = MutationEvent;
14
14
  this.modelInstanceCreator = modelInstanceCreator;
15
15
  this.ownSymbol = ownSymbol;
16
16
  }
17
- MutationEventOutbox.prototype.enqueue = function (storage, mutationEvent) {
18
- return tslib_1.__awaiter(this, void 0, void 0, function () {
19
- var _this = this;
20
- return tslib_1.__generator(this, function (_a) {
21
- switch (_a.label) {
22
- case 0: return [4 /*yield*/, storage.runExclusive(function (s) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
23
- var mutationEventModelDefinition, predicate, _a, first, incomingMutationType, merged_1, incomingConditionJSON, incomingCondition, merged;
24
- return tslib_1.__generator(this, function (_b) {
25
- switch (_b.label) {
26
- case 0:
27
- mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models['MutationEvent'];
28
- predicate = predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
29
- and: [
30
- { modelId: { eq: mutationEvent.modelId } },
31
- { id: { ne: this.inProgressMutationEventId } },
32
- ],
33
- });
34
- return [4 /*yield*/, s.query(this.MutationEvent, predicate)];
35
- case 1:
36
- _a = tslib_1.__read.apply(void 0, [_b.sent(), 1]), first = _a[0];
37
- if (!(first === undefined)) return [3 /*break*/, 3];
38
- return [4 /*yield*/, s.save(mutationEvent, undefined, this.ownSymbol)];
39
- case 2:
40
- _b.sent();
41
- return [2 /*return*/];
42
- case 3:
43
- incomingMutationType = mutationEvent.operation;
44
- if (!(first.operation === utils_1.TransformerMutationType.CREATE)) return [3 /*break*/, 8];
45
- if (!(incomingMutationType === utils_1.TransformerMutationType.DELETE)) return [3 /*break*/, 5];
46
- return [4 /*yield*/, s.delete(this.MutationEvent, predicate)];
47
- case 4:
48
- _b.sent();
49
- return [3 /*break*/, 7];
50
- case 5:
51
- merged_1 = this.mergeUserFields(first, mutationEvent);
52
- return [4 /*yield*/, s.save(this.MutationEvent.copyOf(first, function (draft) {
53
- draft.data = merged_1.data;
54
- }), undefined, this.ownSymbol)];
55
- case 6:
56
- _b.sent();
57
- _b.label = 7;
58
- case 7: return [3 /*break*/, 12];
59
- case 8:
60
- incomingConditionJSON = mutationEvent.condition;
61
- incomingCondition = JSON.parse(incomingConditionJSON);
62
- merged = void 0;
63
- if (!(Object.keys(incomingCondition).length === 0)) return [3 /*break*/, 10];
64
- merged = this.mergeUserFields(first, mutationEvent);
65
- // delete all for model
66
- return [4 /*yield*/, s.delete(this.MutationEvent, predicate)];
67
- case 9:
68
- // delete all for model
69
- _b.sent();
70
- _b.label = 10;
71
- case 10:
72
- merged = merged || mutationEvent;
73
- // Enqueue new one
74
- return [4 /*yield*/, s.save(merged, undefined, this.ownSymbol)];
75
- case 11:
76
- // Enqueue new one
77
- _b.sent();
78
- _b.label = 12;
79
- case 12: return [2 /*return*/];
80
- }
81
- });
82
- }); })];
83
- case 1:
84
- _a.sent();
85
- return [2 /*return*/];
86
- }
17
+ async enqueue(storage, mutationEvent) {
18
+ await storage.runExclusive(async (s) => {
19
+ const mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models['MutationEvent'];
20
+ // `id` is the key for the record in the mutationEvent;
21
+ // `modelId` is the key for the actual record that was mutated
22
+ const predicate = predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
23
+ and: [
24
+ { modelId: { eq: mutationEvent.modelId } },
25
+ { id: { ne: this.inProgressMutationEventId } },
26
+ ],
87
27
  });
88
- });
89
- };
90
- MutationEventOutbox.prototype.dequeue = function (storage, record, recordOp) {
91
- return tslib_1.__awaiter(this, void 0, void 0, function () {
92
- var head;
93
- return tslib_1.__generator(this, function (_a) {
94
- switch (_a.label) {
95
- case 0: return [4 /*yield*/, this.peek(storage)];
96
- case 1:
97
- head = _a.sent();
98
- if (!record) return [3 /*break*/, 3];
99
- return [4 /*yield*/, this.syncOutboxVersionsOnDequeue(storage, record, head, recordOp)];
100
- case 2:
101
- _a.sent();
102
- _a.label = 3;
103
- case 3: return [4 /*yield*/, storage.delete(head)];
104
- case 4:
105
- _a.sent();
106
- this.inProgressMutationEventId = undefined;
107
- return [2 /*return*/, head];
28
+ // Check if there are any other records with same id
29
+ const [first] = await s.query(this.MutationEvent, predicate);
30
+ // No other record with same modelId, so enqueue
31
+ if (first === undefined) {
32
+ await s.save(mutationEvent, undefined, this.ownSymbol);
33
+ return;
34
+ }
35
+ // There was an enqueued mutation for the modelId, so continue
36
+ const { operation: incomingMutationType } = mutationEvent;
37
+ if (first.operation === utils_1.TransformerMutationType.CREATE) {
38
+ if (incomingMutationType === utils_1.TransformerMutationType.DELETE) {
39
+ await s.delete(this.MutationEvent, predicate);
108
40
  }
109
- });
41
+ else {
42
+ // first gets updated with the incoming mutation's data, condition intentionally skipped
43
+ // we need to merge the fields for a create and update mutation to prevent
44
+ // data loss, since update mutations only include changed fields
45
+ const merged = this.mergeUserFields(first, mutationEvent);
46
+ await s.save(this.MutationEvent.copyOf(first, draft => {
47
+ draft.data = merged.data;
48
+ }), undefined, this.ownSymbol);
49
+ }
50
+ }
51
+ else {
52
+ const { condition: incomingConditionJSON } = mutationEvent;
53
+ const incomingCondition = JSON.parse(incomingConditionJSON);
54
+ let merged;
55
+ // If no condition
56
+ if (Object.keys(incomingCondition).length === 0) {
57
+ merged = this.mergeUserFields(first, mutationEvent);
58
+ // delete all for model
59
+ await s.delete(this.MutationEvent, predicate);
60
+ }
61
+ merged = merged || mutationEvent;
62
+ // Enqueue new one
63
+ await s.save(merged, undefined, this.ownSymbol);
64
+ }
110
65
  });
111
- };
66
+ }
67
+ async dequeue(storage, record, recordOp) {
68
+ const head = await this.peek(storage);
69
+ if (record) {
70
+ await this.syncOutboxVersionsOnDequeue(storage, record, head, recordOp);
71
+ }
72
+ await storage.delete(head);
73
+ this.inProgressMutationEventId = undefined;
74
+ return head;
75
+ }
112
76
  /**
113
77
  * Doing a peek() implies that the mutation goes "inProgress"
114
78
  *
115
79
  * @param storage
116
80
  */
117
- MutationEventOutbox.prototype.peek = function (storage) {
118
- return tslib_1.__awaiter(this, void 0, void 0, function () {
119
- var head;
120
- return tslib_1.__generator(this, function (_a) {
121
- switch (_a.label) {
122
- case 0: return [4 /*yield*/, storage.queryOne(this.MutationEvent, types_1.QueryOne.FIRST)];
123
- case 1:
124
- head = _a.sent();
125
- this.inProgressMutationEventId = head ? head.id : undefined;
126
- return [2 /*return*/, head];
127
- }
128
- });
129
- });
130
- };
131
- MutationEventOutbox.prototype.getForModel = function (storage, model, userModelDefinition) {
132
- return tslib_1.__awaiter(this, void 0, void 0, function () {
133
- var mutationEventModelDefinition, modelId, mutationEvents;
134
- return tslib_1.__generator(this, function (_a) {
135
- switch (_a.label) {
136
- case 0:
137
- mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models.MutationEvent;
138
- modelId = utils_1.getIdentifierValue(userModelDefinition, model);
139
- return [4 /*yield*/, storage.query(this.MutationEvent, predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
140
- and: { modelId: { eq: modelId } },
141
- }))];
142
- case 1:
143
- mutationEvents = _a.sent();
144
- return [2 /*return*/, mutationEvents];
145
- }
146
- });
147
- });
148
- };
149
- MutationEventOutbox.prototype.getModelIds = function (storage) {
150
- return tslib_1.__awaiter(this, void 0, void 0, function () {
151
- var mutationEvents, result;
152
- return tslib_1.__generator(this, function (_a) {
153
- switch (_a.label) {
154
- case 0: return [4 /*yield*/, storage.query(this.MutationEvent)];
155
- case 1:
156
- mutationEvents = _a.sent();
157
- result = new Set();
158
- mutationEvents.forEach(function (_a) {
159
- var modelId = _a.modelId;
160
- return result.add(modelId);
161
- });
162
- return [2 /*return*/, result];
163
- }
164
- });
165
- });
166
- };
81
+ async peek(storage) {
82
+ const head = await storage.queryOne(this.MutationEvent, types_1.QueryOne.FIRST);
83
+ this.inProgressMutationEventId = head ? head.id : undefined;
84
+ return head;
85
+ }
86
+ async getForModel(storage, model, userModelDefinition) {
87
+ const mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models.MutationEvent;
88
+ const modelId = (0, utils_1.getIdentifierValue)(userModelDefinition, model);
89
+ const mutationEvents = await storage.query(this.MutationEvent, predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
90
+ and: { modelId: { eq: modelId } },
91
+ }));
92
+ return mutationEvents;
93
+ }
94
+ async getModelIds(storage) {
95
+ const mutationEvents = await storage.query(this.MutationEvent);
96
+ const result = new Set();
97
+ mutationEvents.forEach(({ modelId }) => result.add(modelId));
98
+ return result;
99
+ }
167
100
  // applies _version from the AppSync mutation response to other items
168
101
  // in the mutation queue with the same id
169
102
  // see https://github.com/aws-amplify/amplify-js/pull/7354 for more details
170
- MutationEventOutbox.prototype.syncOutboxVersionsOnDequeue = function (storage, record, head, recordOp) {
171
- return tslib_1.__awaiter(this, void 0, void 0, function () {
172
- var _version, _lastChangedAt, _deleted, _incomingData, incomingData, data, __version, __lastChangedAt, __deleted, _outgoingData, outgoingData, mutationEventModelDefinition, userModelDefinition, recordId, predicate, outdatedMutations, reconciledMutations;
173
- var _this = this;
174
- return tslib_1.__generator(this, function (_a) {
175
- switch (_a.label) {
176
- case 0:
177
- if (head.operation !== recordOp) {
178
- return [2 /*return*/];
179
- }
180
- _version = record._version, _lastChangedAt = record._lastChangedAt, _deleted = record._deleted, _incomingData = tslib_1.__rest(record, ["_version", "_lastChangedAt", "_deleted"]);
181
- incomingData = this.removeTimestampFields(head.model, _incomingData);
182
- data = JSON.parse(head.data);
183
- if (!data) {
184
- return [2 /*return*/];
185
- }
186
- __version = data._version, __lastChangedAt = data._lastChangedAt, __deleted = data._deleted, _outgoingData = tslib_1.__rest(data, ["_version", "_lastChangedAt", "_deleted"]);
187
- outgoingData = this.removeTimestampFields(head.model, _outgoingData);
188
- // Don't sync the version when the data in the response does not match the data
189
- // in the request, i.e., when there's a handled conflict
190
- //
191
- // NOTE: `incomingData` contains all the fields in the record, and `outgoingData`
192
- // only contains updated fields, resulting in an error when doing a comparison
193
- // of two equal mutations. Fix this, or mitigate otherwise.
194
- if (!util_1.valuesEqual(incomingData, outgoingData, true)) {
195
- return [2 /*return*/];
196
- }
197
- mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models['MutationEvent'];
198
- userModelDefinition = this.schema.namespaces['user'].models[head.model];
199
- recordId = utils_1.getIdentifierValue(userModelDefinition, record);
200
- predicate = predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
201
- and: [
202
- { modelId: { eq: recordId } },
203
- { id: { ne: this.inProgressMutationEventId } },
204
- ],
205
- });
206
- return [4 /*yield*/, storage.query(this.MutationEvent, predicate)];
207
- case 1:
208
- outdatedMutations = _a.sent();
209
- if (!outdatedMutations.length) {
210
- return [2 /*return*/];
211
- }
212
- reconciledMutations = outdatedMutations.map(function (m) {
213
- var oldData = JSON.parse(m.data);
214
- var newData = tslib_1.__assign(tslib_1.__assign({}, oldData), { _version: _version, _lastChangedAt: _lastChangedAt });
215
- return _this.MutationEvent.copyOf(m, function (draft) {
216
- draft.data = JSON.stringify(newData);
217
- });
218
- });
219
- return [4 /*yield*/, storage.delete(this.MutationEvent, predicate)];
220
- case 2:
221
- _a.sent();
222
- return [4 /*yield*/, Promise.all(reconciledMutations.map(function (m) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
223
- switch (_a.label) {
224
- case 0: return [4 /*yield*/, storage.save(m, undefined, this.ownSymbol)];
225
- case 1: return [2 /*return*/, _a.sent()];
226
- }
227
- }); }); }))];
228
- case 3:
229
- _a.sent();
230
- return [2 /*return*/];
231
- }
103
+ async syncOutboxVersionsOnDequeue(storage, record, head, recordOp) {
104
+ if (head.operation !== recordOp) {
105
+ return;
106
+ }
107
+ const { _version, _lastChangedAt, _deleted, ..._incomingData } = record;
108
+ const incomingData = this.removeTimestampFields(head.model, _incomingData);
109
+ const data = JSON.parse(head.data);
110
+ if (!data) {
111
+ return;
112
+ }
113
+ const { _version: __version, _lastChangedAt: __lastChangedAt, _deleted: __deleted, ..._outgoingData } = data;
114
+ const outgoingData = this.removeTimestampFields(head.model, _outgoingData);
115
+ // Don't sync the version when the data in the response does not match the data
116
+ // in the request, i.e., when there's a handled conflict
117
+ //
118
+ // NOTE: `incomingData` contains all the fields in the record, and `outgoingData`
119
+ // only contains updated fields, resulting in an error when doing a comparison
120
+ // of two equal mutations. Fix this, or mitigate otherwise.
121
+ if (!(0, util_1.valuesEqual)(incomingData, outgoingData, true)) {
122
+ return;
123
+ }
124
+ const mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models['MutationEvent'];
125
+ const userModelDefinition = this.schema.namespaces['user'].models[head.model];
126
+ const recordId = (0, utils_1.getIdentifierValue)(userModelDefinition, record);
127
+ const predicate = predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
128
+ and: [
129
+ { modelId: { eq: recordId } },
130
+ { id: { ne: this.inProgressMutationEventId } },
131
+ ],
132
+ });
133
+ const outdatedMutations = await storage.query(this.MutationEvent, predicate);
134
+ if (!outdatedMutations.length) {
135
+ return;
136
+ }
137
+ const reconciledMutations = outdatedMutations.map(m => {
138
+ const oldData = JSON.parse(m.data);
139
+ const newData = { ...oldData, _version, _lastChangedAt };
140
+ return this.MutationEvent.copyOf(m, draft => {
141
+ draft.data = JSON.stringify(newData);
232
142
  });
233
143
  });
234
- };
235
- MutationEventOutbox.prototype.mergeUserFields = function (previous, current) {
236
- var _a = JSON.parse(previous.data), _version = _a._version, _lastChangedAt = _a._lastChangedAt, _deleted = _a._deleted, previousData = tslib_1.__rest(_a, ["_version", "_lastChangedAt", "_deleted"]);
237
- var _b = JSON.parse(current.data), __version = _b._version, __lastChangedAt = _b._lastChangedAt, __deleted = _b._deleted, currentData = tslib_1.__rest(_b, ["_version", "_lastChangedAt", "_deleted"]);
238
- var data = JSON.stringify(tslib_1.__assign(tslib_1.__assign({ _version: _version,
239
- _lastChangedAt: _lastChangedAt,
240
- _deleted: _deleted }, previousData), currentData));
241
- return this.modelInstanceCreator(this.MutationEvent, tslib_1.__assign(tslib_1.__assign({}, current), { data: data }));
242
- };
144
+ await storage.delete(this.MutationEvent, predicate);
145
+ await Promise.all(reconciledMutations.map(async (m) => await storage.save(m, undefined, this.ownSymbol)));
146
+ }
147
+ mergeUserFields(previous, current) {
148
+ const { _version, _lastChangedAt, _deleted, ...previousData } = JSON.parse(previous.data);
149
+ const { _version: __version, _lastChangedAt: __lastChangedAt, _deleted: __deleted, ...currentData } = JSON.parse(current.data);
150
+ const data = JSON.stringify({
151
+ _version,
152
+ _lastChangedAt,
153
+ _deleted,
154
+ ...previousData,
155
+ ...currentData,
156
+ });
157
+ return this.modelInstanceCreator(this.MutationEvent, {
158
+ ...current,
159
+ data,
160
+ });
161
+ }
243
162
  /*
244
163
  if a model is using custom timestamp fields
245
164
  the custom field names will be stored in the model attributes
@@ -257,14 +176,13 @@ var MutationEventOutbox = /** @class */ (function () {
257
176
  }
258
177
  ]
259
178
  */
260
- MutationEventOutbox.prototype.removeTimestampFields = function (model, record) {
261
- var _a, _b;
262
- var CREATED_AT_DEFAULT_KEY = 'createdAt';
263
- var UPDATED_AT_DEFAULT_KEY = 'updatedAt';
264
- var createdTimestampKey = CREATED_AT_DEFAULT_KEY;
265
- var updatedTimestampKey = UPDATED_AT_DEFAULT_KEY;
266
- var modelAttributes = (_a = this.schema.namespaces[util_1.USER].models[model].attributes) === null || _a === void 0 ? void 0 : _a.find(function (attr) { return attr.type === 'model'; });
267
- var timestampFieldsMap = (_b = modelAttributes === null || modelAttributes === void 0 ? void 0 : modelAttributes.properties) === null || _b === void 0 ? void 0 : _b.timestamps;
179
+ removeTimestampFields(model, record) {
180
+ const CREATED_AT_DEFAULT_KEY = 'createdAt';
181
+ const UPDATED_AT_DEFAULT_KEY = 'updatedAt';
182
+ let createdTimestampKey = CREATED_AT_DEFAULT_KEY;
183
+ let updatedTimestampKey = UPDATED_AT_DEFAULT_KEY;
184
+ const modelAttributes = this.schema.namespaces[util_1.USER].models[model].attributes?.find(attr => attr.type === 'model');
185
+ const timestampFieldsMap = modelAttributes?.properties?.timestamps;
268
186
  if (timestampFieldsMap) {
269
187
  createdTimestampKey = timestampFieldsMap[CREATED_AT_DEFAULT_KEY];
270
188
  updatedTimestampKey = timestampFieldsMap[UPDATED_AT_DEFAULT_KEY];
@@ -272,8 +190,6 @@ var MutationEventOutbox = /** @class */ (function () {
272
190
  delete record[createdTimestampKey];
273
191
  delete record[updatedTimestampKey];
274
192
  return record;
275
- };
276
- return MutationEventOutbox;
277
- }());
193
+ }
194
+ }
278
195
  exports.MutationEventOutbox = MutationEventOutbox;
279
- //# sourceMappingURL=outbox.js.map
@@ -1,5 +1,5 @@
1
1
  import { ErrorType } from '../../types';
2
- export declare type ErrorMap = Partial<{
2
+ export type ErrorMap = Partial<{
3
3
  [key in ErrorType]: (error: Error) => boolean;
4
4
  }>;
5
5
  export declare const mutationErrorMap: ErrorMap;