@aws-amplify/datastore 5.0.1-api-v6-models.c1977f8.0 → 5.0.1-api-v6-models.891fe0d.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 (70) hide show
  1. package/lib/authModeStrategies/defaultAuthStrategy.js +1 -1
  2. package/lib/authModeStrategies/multiAuthStrategy.js +29 -105
  3. package/lib/datastore/datastore.js +887 -1370
  4. package/lib/index.js +1 -1
  5. package/lib/predicates/index.js +53 -102
  6. package/lib/predicates/next.js +310 -557
  7. package/lib/predicates/sort.js +24 -27
  8. package/lib/ssr/index.js +1 -1
  9. package/lib/storage/adapter/AsyncStorageAdapter.js +115 -449
  10. package/lib/storage/adapter/AsyncStorageDatabase.js +215 -480
  11. package/lib/storage/adapter/InMemoryStore.js +27 -101
  12. package/lib/storage/adapter/InMemoryStore.native.js +1 -1
  13. package/lib/storage/adapter/IndexedDBAdapter.js +441 -1002
  14. package/lib/storage/adapter/StorageAdapterBase.js +177 -396
  15. package/lib/storage/adapter/getDefaultAdapter/index.js +5 -6
  16. package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -2
  17. package/lib/storage/relationship.js +174 -260
  18. package/lib/storage/storage.js +244 -507
  19. package/lib/sync/datastoreConnectivity.js +29 -84
  20. package/lib/sync/datastoreReachability/index.js +1 -1
  21. package/lib/sync/datastoreReachability/index.native.js +2 -2
  22. package/lib/sync/index.js +512 -885
  23. package/lib/sync/merger.js +30 -133
  24. package/lib/sync/outbox.js +147 -302
  25. package/lib/sync/processors/errorMaps.js +30 -80
  26. package/lib/sync/processors/mutation.js +331 -579
  27. package/lib/sync/processors/subscription.js +268 -428
  28. package/lib/sync/processors/sync.js +276 -464
  29. package/lib/sync/utils.js +248 -393
  30. package/lib/tsconfig.tsbuildinfo +1 -1
  31. package/lib/types.js +16 -58
  32. package/lib/util.js +335 -575
  33. package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -1
  34. package/lib-esm/authModeStrategies/multiAuthStrategy.js +27 -103
  35. package/lib-esm/datastore/datastore.js +874 -1359
  36. package/lib-esm/index.js +6 -6
  37. package/lib-esm/predicates/index.js +54 -104
  38. package/lib-esm/predicates/next.js +306 -555
  39. package/lib-esm/predicates/sort.js +24 -27
  40. package/lib-esm/ssr/index.js +1 -1
  41. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -446
  42. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -477
  43. package/lib-esm/storage/adapter/InMemoryStore.js +27 -102
  44. package/lib-esm/storage/adapter/IndexedDBAdapter.js +436 -997
  45. package/lib-esm/storage/adapter/StorageAdapterBase.js +172 -392
  46. package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -3
  47. package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -1
  48. package/lib-esm/storage/relationship.js +173 -260
  49. package/lib-esm/storage/storage.js +236 -499
  50. package/lib-esm/sync/datastoreConnectivity.js +26 -82
  51. package/lib-esm/sync/datastoreReachability/index.js +1 -1
  52. package/lib-esm/sync/datastoreReachability/index.native.js +1 -1
  53. package/lib-esm/sync/index.js +498 -872
  54. package/lib-esm/sync/merger.js +28 -131
  55. package/lib-esm/sync/outbox.js +143 -298
  56. package/lib-esm/sync/processors/errorMaps.js +32 -82
  57. package/lib-esm/sync/processors/mutation.js +324 -572
  58. package/lib-esm/sync/processors/subscription.js +258 -418
  59. package/lib-esm/sync/processors/sync.js +269 -457
  60. package/lib-esm/sync/utils.js +245 -390
  61. package/lib-esm/tsconfig.tsbuildinfo +1 -1
  62. package/lib-esm/types.js +16 -59
  63. package/lib-esm/util.js +335 -577
  64. package/package.json +12 -12
  65. package/src/datastore/datastore.ts +4 -3
  66. package/src/storage/adapter/getDefaultAdapter/index.ts +1 -3
  67. package/src/sync/processors/mutation.ts +1 -1
  68. package/src/sync/processors/sync.ts +1 -1
  69. package/src/sync/utils.ts +1 -1
  70. package/src/util.ts +44 -6
@@ -1,317 +1,164 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __rest = (this && this.__rest) || function (s, e) {
50
- var t = {};
51
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
52
- t[p] = s[p];
53
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
54
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
55
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
56
- t[p[i]] = s[p[i]];
57
- }
58
- return t;
59
- };
60
- var __read = (this && this.__read) || function (o, n) {
61
- var m = typeof Symbol === "function" && o[Symbol.iterator];
62
- if (!m) return o;
63
- var i = m.call(o), r, ar = [], e;
64
- try {
65
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
66
- }
67
- catch (error) { e = { error: error }; }
68
- finally {
69
- try {
70
- if (r && !r.done && (m = i["return"])) m.call(i);
71
- }
72
- finally { if (e) throw e.error; }
73
- }
74
- return ar;
75
- };
76
2
  Object.defineProperty(exports, "__esModule", { value: true });
77
3
  exports.MutationEventOutbox = void 0;
78
- var predicates_1 = require("../predicates");
79
- var types_1 = require("../types");
80
- var util_1 = require("../util");
81
- var utils_1 = require("./utils");
4
+ const predicates_1 = require("../predicates");
5
+ const types_1 = require("../types");
6
+ const util_1 = require("../util");
7
+ const utils_1 = require("./utils");
82
8
  // TODO: Persist deleted ids
83
9
  // https://github.com/aws-amplify/amplify-js/blob/datastore-docs/packages/datastore/docs/sync-engine.md#outbox
84
- var MutationEventOutbox = /** @class */ (function () {
85
- function MutationEventOutbox(schema, MutationEvent, modelInstanceCreator, ownSymbol) {
10
+ class MutationEventOutbox {
11
+ constructor(schema, MutationEvent, modelInstanceCreator, ownSymbol) {
86
12
  this.schema = schema;
87
13
  this.MutationEvent = MutationEvent;
88
14
  this.modelInstanceCreator = modelInstanceCreator;
89
15
  this.ownSymbol = ownSymbol;
90
16
  }
91
- MutationEventOutbox.prototype.enqueue = function (storage, mutationEvent) {
92
- return __awaiter(this, void 0, void 0, function () {
93
- var _this = this;
94
- return __generator(this, function (_a) {
95
- switch (_a.label) {
96
- case 0: return [4 /*yield*/, storage.runExclusive(function (s) { return __awaiter(_this, void 0, void 0, function () {
97
- var mutationEventModelDefinition, predicate, _a, first, incomingMutationType, merged_1, incomingConditionJSON, incomingCondition, merged;
98
- return __generator(this, function (_b) {
99
- switch (_b.label) {
100
- case 0:
101
- mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models['MutationEvent'];
102
- predicate = predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
103
- and: [
104
- { modelId: { eq: mutationEvent.modelId } },
105
- { id: { ne: this.inProgressMutationEventId } },
106
- ],
107
- });
108
- return [4 /*yield*/, s.query(this.MutationEvent, predicate)];
109
- case 1:
110
- _a = __read.apply(void 0, [_b.sent(), 1]), first = _a[0];
111
- if (!(first === undefined)) return [3 /*break*/, 3];
112
- return [4 /*yield*/, s.save(mutationEvent, undefined, this.ownSymbol)];
113
- case 2:
114
- _b.sent();
115
- return [2 /*return*/];
116
- case 3:
117
- incomingMutationType = mutationEvent.operation;
118
- if (!(first.operation === utils_1.TransformerMutationType.CREATE)) return [3 /*break*/, 8];
119
- if (!(incomingMutationType === utils_1.TransformerMutationType.DELETE)) return [3 /*break*/, 5];
120
- return [4 /*yield*/, s.delete(this.MutationEvent, predicate)];
121
- case 4:
122
- _b.sent();
123
- return [3 /*break*/, 7];
124
- case 5:
125
- merged_1 = this.mergeUserFields(first, mutationEvent);
126
- return [4 /*yield*/, s.save(this.MutationEvent.copyOf(first, function (draft) {
127
- draft.data = merged_1.data;
128
- }), undefined, this.ownSymbol)];
129
- case 6:
130
- _b.sent();
131
- _b.label = 7;
132
- case 7: return [3 /*break*/, 12];
133
- case 8:
134
- incomingConditionJSON = mutationEvent.condition;
135
- incomingCondition = JSON.parse(incomingConditionJSON);
136
- merged = void 0;
137
- if (!(Object.keys(incomingCondition).length === 0)) return [3 /*break*/, 10];
138
- merged = this.mergeUserFields(first, mutationEvent);
139
- // delete all for model
140
- return [4 /*yield*/, s.delete(this.MutationEvent, predicate)];
141
- case 9:
142
- // delete all for model
143
- _b.sent();
144
- _b.label = 10;
145
- case 10:
146
- merged = merged || mutationEvent;
147
- // Enqueue new one
148
- return [4 /*yield*/, s.save(merged, undefined, this.ownSymbol)];
149
- case 11:
150
- // Enqueue new one
151
- _b.sent();
152
- _b.label = 12;
153
- case 12: return [2 /*return*/];
154
- }
155
- });
156
- }); })];
157
- case 1:
158
- _a.sent();
159
- return [2 /*return*/];
160
- }
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
+ ],
161
27
  });
162
- });
163
- };
164
- MutationEventOutbox.prototype.dequeue = function (storage, record, recordOp) {
165
- return __awaiter(this, void 0, void 0, function () {
166
- var head;
167
- return __generator(this, function (_a) {
168
- switch (_a.label) {
169
- case 0: return [4 /*yield*/, this.peek(storage)];
170
- case 1:
171
- head = _a.sent();
172
- if (!record) return [3 /*break*/, 3];
173
- return [4 /*yield*/, this.syncOutboxVersionsOnDequeue(storage, record, head, recordOp)];
174
- case 2:
175
- _a.sent();
176
- _a.label = 3;
177
- case 3: return [4 /*yield*/, storage.delete(head)];
178
- case 4:
179
- _a.sent();
180
- this.inProgressMutationEventId = undefined;
181
- 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);
182
40
  }
183
- });
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
+ }
184
65
  });
185
- };
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
+ }
186
76
  /**
187
77
  * Doing a peek() implies that the mutation goes "inProgress"
188
78
  *
189
79
  * @param storage
190
80
  */
191
- MutationEventOutbox.prototype.peek = function (storage) {
192
- return __awaiter(this, void 0, void 0, function () {
193
- var head;
194
- return __generator(this, function (_a) {
195
- switch (_a.label) {
196
- case 0: return [4 /*yield*/, storage.queryOne(this.MutationEvent, types_1.QueryOne.FIRST)];
197
- case 1:
198
- head = _a.sent();
199
- this.inProgressMutationEventId = head ? head.id : undefined;
200
- return [2 /*return*/, head];
201
- }
202
- });
203
- });
204
- };
205
- MutationEventOutbox.prototype.getForModel = function (storage, model, userModelDefinition) {
206
- return __awaiter(this, void 0, void 0, function () {
207
- var mutationEventModelDefinition, modelId, mutationEvents;
208
- return __generator(this, function (_a) {
209
- switch (_a.label) {
210
- case 0:
211
- mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models.MutationEvent;
212
- modelId = (0, utils_1.getIdentifierValue)(userModelDefinition, model);
213
- return [4 /*yield*/, storage.query(this.MutationEvent, predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
214
- and: { modelId: { eq: modelId } },
215
- }))];
216
- case 1:
217
- mutationEvents = _a.sent();
218
- return [2 /*return*/, mutationEvents];
219
- }
220
- });
221
- });
222
- };
223
- MutationEventOutbox.prototype.getModelIds = function (storage) {
224
- return __awaiter(this, void 0, void 0, function () {
225
- var mutationEvents, result;
226
- return __generator(this, function (_a) {
227
- switch (_a.label) {
228
- case 0: return [4 /*yield*/, storage.query(this.MutationEvent)];
229
- case 1:
230
- mutationEvents = _a.sent();
231
- result = new Set();
232
- mutationEvents.forEach(function (_a) {
233
- var modelId = _a.modelId;
234
- return result.add(modelId);
235
- });
236
- return [2 /*return*/, result];
237
- }
238
- });
239
- });
240
- };
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
+ }
241
100
  // applies _version from the AppSync mutation response to other items
242
101
  // in the mutation queue with the same id
243
102
  // see https://github.com/aws-amplify/amplify-js/pull/7354 for more details
244
- MutationEventOutbox.prototype.syncOutboxVersionsOnDequeue = function (storage, record, head, recordOp) {
245
- return __awaiter(this, void 0, void 0, function () {
246
- var _version, _lastChangedAt, _deleted, _incomingData, incomingData, data, __version, __lastChangedAt, __deleted, _outgoingData, outgoingData, mutationEventModelDefinition, userModelDefinition, recordId, predicate, outdatedMutations, reconciledMutations;
247
- var _this = this;
248
- return __generator(this, function (_a) {
249
- switch (_a.label) {
250
- case 0:
251
- if (head.operation !== recordOp) {
252
- return [2 /*return*/];
253
- }
254
- _version = record._version, _lastChangedAt = record._lastChangedAt, _deleted = record._deleted, _incomingData = __rest(record, ["_version", "_lastChangedAt", "_deleted"]);
255
- incomingData = this.removeTimestampFields(head.model, _incomingData);
256
- data = JSON.parse(head.data);
257
- if (!data) {
258
- return [2 /*return*/];
259
- }
260
- __version = data._version, __lastChangedAt = data._lastChangedAt, __deleted = data._deleted, _outgoingData = __rest(data, ["_version", "_lastChangedAt", "_deleted"]);
261
- outgoingData = this.removeTimestampFields(head.model, _outgoingData);
262
- // Don't sync the version when the data in the response does not match the data
263
- // in the request, i.e., when there's a handled conflict
264
- //
265
- // NOTE: `incomingData` contains all the fields in the record, and `outgoingData`
266
- // only contains updated fields, resulting in an error when doing a comparison
267
- // of two equal mutations. Fix this, or mitigate otherwise.
268
- if (!(0, util_1.valuesEqual)(incomingData, outgoingData, true)) {
269
- return [2 /*return*/];
270
- }
271
- mutationEventModelDefinition = this.schema.namespaces[util_1.SYNC].models['MutationEvent'];
272
- userModelDefinition = this.schema.namespaces['user'].models[head.model];
273
- recordId = (0, utils_1.getIdentifierValue)(userModelDefinition, record);
274
- predicate = predicates_1.ModelPredicateCreator.createFromAST(mutationEventModelDefinition, {
275
- and: [
276
- { modelId: { eq: recordId } },
277
- { id: { ne: this.inProgressMutationEventId } },
278
- ],
279
- });
280
- return [4 /*yield*/, storage.query(this.MutationEvent, predicate)];
281
- case 1:
282
- outdatedMutations = _a.sent();
283
- if (!outdatedMutations.length) {
284
- return [2 /*return*/];
285
- }
286
- reconciledMutations = outdatedMutations.map(function (m) {
287
- var oldData = JSON.parse(m.data);
288
- var newData = __assign(__assign({}, oldData), { _version: _version, _lastChangedAt: _lastChangedAt });
289
- return _this.MutationEvent.copyOf(m, function (draft) {
290
- draft.data = JSON.stringify(newData);
291
- });
292
- });
293
- return [4 /*yield*/, storage.delete(this.MutationEvent, predicate)];
294
- case 2:
295
- _a.sent();
296
- return [4 /*yield*/, Promise.all(reconciledMutations.map(function (m) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
297
- switch (_a.label) {
298
- case 0: return [4 /*yield*/, storage.save(m, undefined, this.ownSymbol)];
299
- case 1: return [2 /*return*/, _a.sent()];
300
- }
301
- }); }); }))];
302
- case 3:
303
- _a.sent();
304
- return [2 /*return*/];
305
- }
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);
306
142
  });
307
143
  });
308
- };
309
- MutationEventOutbox.prototype.mergeUserFields = function (previous, current) {
310
- var _a = JSON.parse(previous.data), _version = _a._version, _lastChangedAt = _a._lastChangedAt, _deleted = _a._deleted, previousData = __rest(_a, ["_version", "_lastChangedAt", "_deleted"]);
311
- var _b = JSON.parse(current.data), __version = _b._version, __lastChangedAt = _b._lastChangedAt, __deleted = _b._deleted, currentData = __rest(_b, ["_version", "_lastChangedAt", "_deleted"]);
312
- var data = JSON.stringify(__assign(__assign({ _version: _version, _lastChangedAt: _lastChangedAt, _deleted: _deleted }, previousData), currentData));
313
- return this.modelInstanceCreator(this.MutationEvent, __assign(__assign({}, current), { data: data }));
314
- };
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
+ }
315
162
  /*
316
163
  if a model is using custom timestamp fields
317
164
  the custom field names will be stored in the model attributes
@@ -329,14 +176,13 @@ var MutationEventOutbox = /** @class */ (function () {
329
176
  }
330
177
  ]
331
178
  */
332
- MutationEventOutbox.prototype.removeTimestampFields = function (model, record) {
333
- var _a, _b;
334
- var CREATED_AT_DEFAULT_KEY = 'createdAt';
335
- var UPDATED_AT_DEFAULT_KEY = 'updatedAt';
336
- var createdTimestampKey = CREATED_AT_DEFAULT_KEY;
337
- var updatedTimestampKey = UPDATED_AT_DEFAULT_KEY;
338
- 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'; });
339
- 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;
340
186
  if (timestampFieldsMap) {
341
187
  createdTimestampKey = timestampFieldsMap[CREATED_AT_DEFAULT_KEY];
342
188
  updatedTimestampKey = timestampFieldsMap[UPDATED_AT_DEFAULT_KEY];
@@ -344,7 +190,6 @@ var MutationEventOutbox = /** @class */ (function () {
344
190
  delete record[createdTimestampKey];
345
191
  delete record[updatedTimestampKey];
346
192
  return record;
347
- };
348
- return MutationEventOutbox;
349
- }());
193
+ }
194
+ }
350
195
  exports.MutationEventOutbox = MutationEventOutbox;
@@ -1,80 +1,40 @@
1
1
  "use strict";
2
- var __read = (this && this.__read) || function (o, n) {
3
- var m = typeof Symbol === "function" && o[Symbol.iterator];
4
- if (!m) return o;
5
- var i = m.call(o), r, ar = [], e;
6
- try {
7
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
8
- }
9
- catch (error) { e = { error: error }; }
10
- finally {
11
- try {
12
- if (r && !r.done && (m = i["return"])) m.call(i);
13
- }
14
- finally { if (e) throw e.error; }
15
- }
16
- return ar;
17
- };
18
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
19
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
20
- if (ar || !(i in from)) {
21
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
22
- ar[i] = from[i];
23
- }
24
- }
25
- return to.concat(ar || Array.prototype.slice.call(from));
26
- };
27
- var __values = (this && this.__values) || function(o) {
28
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
29
- if (m) return m.call(o);
30
- if (o && typeof o.length === "number") return {
31
- next: function () {
32
- if (o && i >= o.length) o = void 0;
33
- return { value: o && o[i++], done: !o };
34
- }
35
- };
36
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
37
- };
38
2
  Object.defineProperty(exports, "__esModule", { value: true });
39
3
  exports.mapErrorToType = exports.getSyncErrorType = exports.getSubscriptionErrorType = exports.getMutationErrorType = exports.syncErrorMap = exports.subscriptionErrorMap = exports.mutationErrorMap = void 0;
40
- var utils_1 = require("../utils");
41
- var connectionTimeout = function (error) {
42
- return /^Connection failed: Connection Timeout/.test(error.message);
43
- };
44
- var serverError = function (error) { return (0, utils_1.resolveServiceErrorStatusCode)(error) >= 500; };
4
+ const utils_1 = require("../utils");
5
+ const connectionTimeout = error => /^Connection failed: Connection Timeout/.test(error.message);
6
+ const serverError = error => (0, utils_1.resolveServiceErrorStatusCode)(error) >= 500;
45
7
  exports.mutationErrorMap = {
46
- BadModel: function () { return false; },
47
- BadRecord: function (error) {
48
- var message = error.message;
8
+ BadModel: () => false,
9
+ BadRecord: error => {
10
+ const { message } = error;
49
11
  return (/^Cannot return \w+ for [\w-_]+ type/.test(message) ||
50
12
  /^Variable '.+' has coerced Null value for NonNull type/.test(message)); // newly required field, out of date client
51
13
  },
52
- ConfigError: function () { return false; },
53
- Transient: function (error) { return connectionTimeout(error) || serverError(error); },
54
- Unauthorized: function (error) {
55
- return error.message === 'Unauthorized' ||
56
- (0, utils_1.resolveServiceErrorStatusCode)(error) === 401;
57
- },
14
+ ConfigError: () => false,
15
+ Transient: error => connectionTimeout(error) || serverError(error),
16
+ Unauthorized: error => error.message === 'Unauthorized' ||
17
+ (0, utils_1.resolveServiceErrorStatusCode)(error) === 401,
58
18
  };
59
19
  exports.subscriptionErrorMap = {
60
- BadModel: function () { return false; },
61
- BadRecord: function () { return false; },
62
- ConfigError: function () { return false; },
63
- Transient: function (observableError) {
64
- var error = unwrapObservableError(observableError);
20
+ BadModel: () => false,
21
+ BadRecord: () => false,
22
+ ConfigError: () => false,
23
+ Transient: observableError => {
24
+ const error = unwrapObservableError(observableError);
65
25
  return connectionTimeout(error) || serverError(error);
66
26
  },
67
- Unauthorized: function (observableError) {
68
- var error = unwrapObservableError(observableError);
27
+ Unauthorized: observableError => {
28
+ const error = unwrapObservableError(observableError);
69
29
  return /Connection failed.+Unauthorized/.test(error.message);
70
30
  },
71
31
  };
72
32
  exports.syncErrorMap = {
73
- BadModel: function () { return false; },
74
- BadRecord: function (error) { return /^Cannot return \w+ for [\w-_]+ type/.test(error.message); },
75
- ConfigError: function () { return false; },
76
- Transient: function (error) { return connectionTimeout(error) || serverError(error); },
77
- Unauthorized: function (error) { return error.errorType === 'Unauthorized'; },
33
+ BadModel: () => false,
34
+ BadRecord: error => /^Cannot return \w+ for [\w-_]+ type/.test(error.message),
35
+ ConfigError: () => false,
36
+ Transient: error => connectionTimeout(error) || serverError(error),
37
+ Unauthorized: error => error.errorType === 'Unauthorized',
78
38
  };
79
39
  /**
80
40
  * Get the first error reason of an observable.
@@ -83,8 +43,9 @@ exports.syncErrorMap = {
83
43
  * @param observableError an error from ZenObservable subscribe error callback
84
44
  */
85
45
  function unwrapObservableError(observableError) {
86
- var _a;
87
- var _b = __read((_a = __read(observableError.errors, 0), observableError).errors, 1), error = _b[0];
46
+ const { errors: [error], } = ({
47
+ errors: [],
48
+ } = observableError);
88
49
  return error;
89
50
  }
90
51
  function getMutationErrorType(error) {
@@ -106,23 +67,12 @@ exports.getSyncErrorType = getSyncErrorType;
106
67
  * @param error The underying error to categorize.
107
68
  */
108
69
  function mapErrorToType(errorMap, error) {
109
- var e_1, _a;
110
- var errorTypes = __spreadArray([], __read(Object.keys(errorMap)), false);
111
- try {
112
- for (var errorTypes_1 = __values(errorTypes), errorTypes_1_1 = errorTypes_1.next(); !errorTypes_1_1.done; errorTypes_1_1 = errorTypes_1.next()) {
113
- var errorType = errorTypes_1_1.value;
114
- var matcher = errorMap[errorType];
115
- if (matcher === null || matcher === void 0 ? void 0 : matcher(error)) {
116
- return errorType;
117
- }
118
- }
119
- }
120
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
121
- finally {
122
- try {
123
- if (errorTypes_1_1 && !errorTypes_1_1.done && (_a = errorTypes_1.return)) _a.call(errorTypes_1);
70
+ const errorTypes = [...Object.keys(errorMap)];
71
+ for (const errorType of errorTypes) {
72
+ const matcher = errorMap[errorType];
73
+ if (matcher?.(error)) {
74
+ return errorType;
124
75
  }
125
- finally { if (e_1) throw e_1.error; }
126
76
  }
127
77
  return 'Unknown';
128
78
  }