@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.
- package/README.md +4 -0
- package/lib/authModeStrategies/defaultAuthStrategy.js +3 -2
- package/lib/authModeStrategies/index.js +3 -3
- package/lib/authModeStrategies/multiAuthStrategy.js +38 -53
- package/lib/datastore/datastore.d.ts +4 -5
- package/lib/datastore/datastore.js +929 -1284
- package/lib/index.d.ts +1 -1
- package/lib/index.js +26 -13
- package/lib/predicates/index.js +54 -69
- package/lib/predicates/next.d.ts +2 -2
- package/lib/predicates/next.js +313 -462
- package/lib/predicates/sort.js +24 -28
- package/lib/ssr/index.js +2 -2
- package/lib/storage/adapter/AsyncStorageAdapter.js +120 -342
- package/lib/storage/adapter/AsyncStorageDatabase.js +217 -421
- package/lib/storage/adapter/InMemoryStore.js +28 -51
- package/lib/storage/adapter/InMemoryStore.native.js +5 -3
- package/lib/storage/adapter/IndexedDBAdapter.js +466 -871
- package/lib/storage/adapter/StorageAdapterBase.js +180 -330
- package/lib/storage/adapter/getDefaultAdapter/index.js +8 -10
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +5 -4
- package/lib/storage/adapter/index.js +0 -1
- package/lib/storage/relationship.js +177 -253
- package/lib/storage/storage.d.ts +4 -4
- package/lib/storage/storage.js +255 -433
- package/lib/sync/datastoreConnectivity.d.ts +2 -2
- package/lib/sync/datastoreConnectivity.js +29 -39
- package/lib/sync/datastoreReachability/index.d.ts +1 -3
- package/lib/sync/datastoreReachability/index.js +3 -3
- package/lib/sync/datastoreReachability/index.native.d.ts +1 -3
- package/lib/sync/datastoreReachability/index.native.js +4 -5
- package/lib/sync/index.d.ts +2 -2
- package/lib/sync/index.js +522 -827
- package/lib/sync/merger.js +31 -63
- package/lib/sync/outbox.js +148 -232
- package/lib/sync/processors/errorMaps.d.ts +1 -1
- package/lib/sync/processors/errorMaps.js +30 -47
- package/lib/sync/processors/mutation.d.ts +2 -2
- package/lib/sync/processors/mutation.js +343 -502
- package/lib/sync/processors/subscription.d.ts +5 -2
- package/lib/sync/processors/subscription.js +283 -437
- package/lib/sync/processors/sync.d.ts +2 -2
- package/lib/sync/processors/sync.js +279 -404
- package/lib/sync/utils.d.ts +5 -4
- package/lib/sync/utils.js +267 -320
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types.d.ts +138 -140
- package/lib/types.js +17 -24
- package/lib/util.d.ts +9 -17
- package/lib/util.js +387 -511
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -2
- package/lib-esm/authModeStrategies/index.js +0 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +35 -52
- package/lib-esm/datastore/datastore.d.ts +4 -5
- package/lib-esm/datastore/datastore.js +888 -1247
- package/lib-esm/index.d.ts +1 -1
- package/lib-esm/index.js +6 -7
- package/lib-esm/predicates/index.js +53 -70
- package/lib-esm/predicates/next.d.ts +2 -2
- package/lib-esm/predicates/next.js +306 -459
- package/lib-esm/predicates/sort.js +23 -28
- package/lib-esm/ssr/index.js +1 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -338
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -416
- package/lib-esm/storage/adapter/InMemoryStore.js +27 -52
- package/lib-esm/storage/adapter/InMemoryStore.native.js +0 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +438 -866
- package/lib-esm/storage/adapter/StorageAdapterBase.js +173 -325
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -6
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -2
- package/lib-esm/storage/adapter/index.js +1 -1
- package/lib-esm/storage/relationship.js +173 -251
- package/lib-esm/storage/storage.d.ts +4 -4
- package/lib-esm/storage/storage.js +242 -424
- package/lib-esm/sync/datastoreConnectivity.d.ts +2 -2
- package/lib-esm/sync/datastoreConnectivity.js +28 -39
- package/lib-esm/sync/datastoreReachability/index.d.ts +1 -3
- package/lib-esm/sync/datastoreReachability/index.js +2 -3
- package/lib-esm/sync/datastoreReachability/index.native.d.ts +1 -3
- package/lib-esm/sync/datastoreReachability/index.native.js +3 -4
- package/lib-esm/sync/index.d.ts +2 -2
- package/lib-esm/sync/index.js +502 -812
- package/lib-esm/sync/merger.js +28 -61
- package/lib-esm/sync/outbox.js +143 -228
- package/lib-esm/sync/processors/errorMaps.d.ts +1 -1
- package/lib-esm/sync/processors/errorMaps.js +32 -50
- package/lib-esm/sync/processors/mutation.d.ts +2 -2
- package/lib-esm/sync/processors/mutation.js +329 -490
- package/lib-esm/sync/processors/subscription.d.ts +5 -2
- package/lib-esm/sync/processors/subscription.js +266 -421
- package/lib-esm/sync/processors/sync.d.ts +2 -2
- package/lib-esm/sync/processors/sync.js +271 -397
- package/lib-esm/sync/utils.d.ts +5 -4
- package/lib-esm/sync/utils.js +252 -307
- package/lib-esm/tsconfig.tsbuildinfo +1 -0
- package/lib-esm/types.d.ts +138 -140
- package/lib-esm/types.js +16 -25
- package/lib-esm/util.d.ts +9 -17
- package/lib-esm/util.js +335 -497
- package/package.json +31 -26
- package/src/authModeStrategies/multiAuthStrategy.ts +15 -12
- package/src/datastore/datastore.ts +36 -35
- package/src/predicates/sort.ts +3 -1
- package/src/storage/adapter/InMemoryStore.ts +1 -1
- package/src/storage/adapter/IndexedDBAdapter.ts +2 -2
- package/src/storage/adapter/StorageAdapterBase.ts +2 -2
- package/src/storage/adapter/getDefaultAdapter/index.ts +1 -4
- package/src/storage/storage.ts +29 -24
- package/src/sync/datastoreConnectivity.ts +6 -6
- package/src/sync/datastoreReachability/index.native.ts +5 -3
- package/src/sync/datastoreReachability/index.ts +1 -1
- package/src/sync/index.ts +79 -89
- package/src/sync/processors/errorMaps.ts +7 -7
- package/src/sync/processors/mutation.ts +19 -13
- package/src/sync/processors/subscription.ts +221 -295
- package/src/sync/processors/sync.ts +11 -8
- package/src/sync/utils.ts +30 -15
- package/src/types.ts +4 -8
- package/src/util.ts +46 -9
- package/lib/.tsbuildinfo +0 -3
- package/lib/authModeStrategies/defaultAuthStrategy.js.map +0 -1
- package/lib/authModeStrategies/index.js.map +0 -1
- package/lib/authModeStrategies/multiAuthStrategy.js.map +0 -1
- package/lib/datastore/datastore.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/predicates/index.js.map +0 -1
- package/lib/predicates/next.js.map +0 -1
- package/lib/predicates/sort.js.map +0 -1
- package/lib/ssr/index.js.map +0 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +0 -1
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +0 -1
- package/lib/storage/adapter/InMemoryStore.js.map +0 -1
- package/lib/storage/adapter/InMemoryStore.native.js.map +0 -1
- package/lib/storage/adapter/IndexedDBAdapter.js.map +0 -1
- package/lib/storage/adapter/StorageAdapterBase.js.map +0 -1
- package/lib/storage/adapter/getDefaultAdapter/index.js.map +0 -1
- package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
- package/lib/storage/adapter/index.js.map +0 -1
- package/lib/storage/relationship.js.map +0 -1
- package/lib/storage/storage.js.map +0 -1
- package/lib/sync/datastoreConnectivity.js.map +0 -1
- package/lib/sync/datastoreReachability/index.js.map +0 -1
- package/lib/sync/datastoreReachability/index.native.js.map +0 -1
- package/lib/sync/index.js.map +0 -1
- package/lib/sync/merger.js.map +0 -1
- package/lib/sync/outbox.js.map +0 -1
- package/lib/sync/processors/errorMaps.js.map +0 -1
- package/lib/sync/processors/mutation.js.map +0 -1
- package/lib/sync/processors/subscription.js.map +0 -1
- package/lib/sync/processors/sync.js.map +0 -1
- package/lib/sync/utils.js.map +0 -1
- package/lib/types.js.map +0 -1
- package/lib/util.js.map +0 -1
- package/lib-esm/.tsbuildinfo +0 -3
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js.map +0 -1
- package/lib-esm/authModeStrategies/index.js.map +0 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +0 -1
- package/lib-esm/datastore/datastore.js.map +0 -1
- package/lib-esm/index.js.map +0 -1
- package/lib-esm/predicates/index.js.map +0 -1
- package/lib-esm/predicates/next.js.map +0 -1
- package/lib-esm/predicates/sort.js.map +0 -1
- package/lib-esm/ssr/index.js.map +0 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +0 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +0 -1
- package/lib-esm/storage/adapter/InMemoryStore.js.map +0 -1
- package/lib-esm/storage/adapter/InMemoryStore.native.js.map +0 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +0 -1
- package/lib-esm/storage/adapter/StorageAdapterBase.js.map +0 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +0 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
- package/lib-esm/storage/adapter/index.js.map +0 -1
- package/lib-esm/storage/relationship.js.map +0 -1
- package/lib-esm/storage/storage.js.map +0 -1
- package/lib-esm/sync/datastoreConnectivity.js.map +0 -1
- package/lib-esm/sync/datastoreReachability/index.js.map +0 -1
- package/lib-esm/sync/datastoreReachability/index.native.js.map +0 -1
- package/lib-esm/sync/index.js.map +0 -1
- package/lib-esm/sync/merger.js.map +0 -1
- package/lib-esm/sync/outbox.js.map +0 -1
- package/lib-esm/sync/processors/errorMaps.js.map +0 -1
- package/lib-esm/sync/processors/mutation.js.map +0 -1
- package/lib-esm/sync/processors/subscription.js.map +0 -1
- package/lib-esm/sync/processors/sync.js.map +0 -1
- package/lib-esm/sync/utils.js.map +0 -1
- package/lib-esm/types.js.map +0 -1
- package/lib-esm/util.js.map +0 -1
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
exports.MutationProcessor = exports.safeJitteredBackoff = void 0;
|
|
4
|
+
const internals_1 = require("@aws-amplify/api/internals");
|
|
5
|
+
const utils_1 = require("@aws-amplify/core/internals/utils");
|
|
6
|
+
const rxjs_1 = require("rxjs");
|
|
7
|
+
const types_1 = require("../../types");
|
|
8
|
+
const util_1 = require("../../util");
|
|
9
|
+
const utils_2 = require("../utils");
|
|
10
|
+
const errorMaps_1 = require("./errorMaps");
|
|
11
|
+
const core_1 = require("@aws-amplify/core");
|
|
12
|
+
const MAX_ATTEMPTS = 10;
|
|
13
|
+
const logger = new core_1.ConsoleLogger('DataStore');
|
|
14
|
+
class MutationProcessor {
|
|
15
|
+
constructor(schema, storage, userClasses, outbox, modelInstanceCreator, MutationEvent, amplifyConfig = {}, authModeStrategy, errorHandler, conflictHandler, amplifyContext) {
|
|
16
16
|
this.schema = schema;
|
|
17
17
|
this.storage = storage;
|
|
18
18
|
this.userClasses = userClasses;
|
|
@@ -26,548 +26,388 @@ var MutationProcessor = /** @class */ (function () {
|
|
|
26
26
|
this.amplifyContext = amplifyContext;
|
|
27
27
|
this.typeQuery = new WeakMap();
|
|
28
28
|
this.processing = false;
|
|
29
|
-
this.runningProcesses = new
|
|
29
|
+
this.runningProcesses = new utils_1.BackgroundProcessManager();
|
|
30
30
|
this.amplifyContext.InternalAPI =
|
|
31
31
|
this.amplifyContext.InternalAPI || internals_1.InternalAPI;
|
|
32
32
|
this.generateQueries();
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Object.values(this.schema.namespaces).forEach(function (namespace) {
|
|
34
|
+
generateQueries() {
|
|
35
|
+
Object.values(this.schema.namespaces).forEach(namespace => {
|
|
37
36
|
Object.values(namespace.models)
|
|
38
|
-
.filter(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.
|
|
43
|
-
|
|
44
|
-
var _b = tslib_1.__read(utils_1.buildGraphQLOperation(namespace, model, 'UPDATE'), 1), updateMutation = _b[0];
|
|
45
|
-
var _c = tslib_1.__read(utils_1.buildGraphQLOperation(namespace, model, 'DELETE'), 1), deleteMutation = _c[0];
|
|
46
|
-
_this.typeQuery.set(model, [
|
|
37
|
+
.filter(({ syncable }) => syncable)
|
|
38
|
+
.forEach(model => {
|
|
39
|
+
const [createMutation] = (0, utils_2.buildGraphQLOperation)(namespace, model, 'CREATE');
|
|
40
|
+
const [updateMutation] = (0, utils_2.buildGraphQLOperation)(namespace, model, 'UPDATE');
|
|
41
|
+
const [deleteMutation] = (0, utils_2.buildGraphQLOperation)(namespace, model, 'DELETE');
|
|
42
|
+
this.typeQuery.set(model, [
|
|
47
43
|
createMutation,
|
|
48
44
|
updateMutation,
|
|
49
45
|
deleteMutation,
|
|
50
46
|
]);
|
|
51
47
|
});
|
|
52
48
|
});
|
|
53
|
-
}
|
|
54
|
-
|
|
49
|
+
}
|
|
50
|
+
isReady() {
|
|
55
51
|
return this.observer !== undefined;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
_this.observer = observer;
|
|
52
|
+
}
|
|
53
|
+
start() {
|
|
54
|
+
this.runningProcesses = new utils_1.BackgroundProcessManager();
|
|
55
|
+
const observable = new rxjs_1.Observable(observer => {
|
|
56
|
+
this.observer = observer;
|
|
62
57
|
try {
|
|
63
|
-
|
|
58
|
+
this.resume();
|
|
64
59
|
}
|
|
65
60
|
catch (error) {
|
|
66
61
|
logger.error('mutations processor start error', error);
|
|
67
62
|
throw error;
|
|
68
63
|
}
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
this.pause();
|
|
74
|
-
return [2 /*return*/];
|
|
75
|
-
});
|
|
76
|
-
}); });
|
|
77
|
-
});
|
|
78
|
-
return observable;
|
|
79
|
-
};
|
|
80
|
-
MutationProcessor.prototype.stop = function () {
|
|
81
|
-
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
82
|
-
return tslib_1.__generator(this, function (_a) {
|
|
83
|
-
switch (_a.label) {
|
|
84
|
-
case 0:
|
|
85
|
-
this.removeObserver();
|
|
86
|
-
return [4 /*yield*/, this.runningProcesses.close()];
|
|
87
|
-
case 1:
|
|
88
|
-
_a.sent();
|
|
89
|
-
return [4 /*yield*/, this.runningProcesses.open()];
|
|
90
|
-
case 2:
|
|
91
|
-
_a.sent();
|
|
92
|
-
return [2 /*return*/];
|
|
93
|
-
}
|
|
64
|
+
return this.runningProcesses.addCleaner(async () => {
|
|
65
|
+
// The observer has unsubscribed and/or `stop()` has been called.
|
|
66
|
+
this.removeObserver();
|
|
67
|
+
this.pause();
|
|
94
68
|
});
|
|
95
69
|
});
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
70
|
+
return observable;
|
|
71
|
+
}
|
|
72
|
+
async stop() {
|
|
73
|
+
this.removeObserver();
|
|
74
|
+
await this.runningProcesses.close();
|
|
75
|
+
await this.runningProcesses.open();
|
|
76
|
+
}
|
|
77
|
+
removeObserver() {
|
|
78
|
+
this.observer?.complete?.();
|
|
100
79
|
this.observer = undefined;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
var head, namespaceName, _loop_1, this_1, _a;
|
|
110
|
-
var _this = this;
|
|
111
|
-
var _b, _c;
|
|
112
|
-
return tslib_1.__generator(this, function (_d) {
|
|
113
|
-
switch (_d.label) {
|
|
114
|
-
case 0:
|
|
115
|
-
if (this.processing ||
|
|
116
|
-
!this.isReady() ||
|
|
117
|
-
!this.runningProcesses.isOpen) {
|
|
118
|
-
return [2 /*return*/];
|
|
119
|
-
}
|
|
120
|
-
this.processing = true;
|
|
121
|
-
namespaceName = util_1.USER;
|
|
122
|
-
_loop_1 = function () {
|
|
123
|
-
var model, operation, data, condition, modelConstructor, result, opName, modelDefinition, modelAuthModes, operationAuthModes_1, authModeAttempts_1, authModeRetry_1, error_1, record, hasMore;
|
|
124
|
-
var _a;
|
|
125
|
-
return tslib_1.__generator(this, function (_b) {
|
|
126
|
-
switch (_b.label) {
|
|
127
|
-
case 0:
|
|
128
|
-
model = head.model, operation = head.operation, data = head.data, condition = head.condition;
|
|
129
|
-
modelConstructor = this_1.userClasses[model];
|
|
130
|
-
result = undefined;
|
|
131
|
-
opName = undefined;
|
|
132
|
-
modelDefinition = undefined;
|
|
133
|
-
_b.label = 1;
|
|
134
|
-
case 1:
|
|
135
|
-
_b.trys.push([1, 4, , 5]);
|
|
136
|
-
return [4 /*yield*/, utils_1.getModelAuthModes({
|
|
137
|
-
authModeStrategy: this_1.authModeStrategy,
|
|
138
|
-
defaultAuthMode: this_1.amplifyConfig.aws_appsync_authenticationType,
|
|
139
|
-
modelName: model,
|
|
140
|
-
schema: this_1.schema,
|
|
141
|
-
})];
|
|
142
|
-
case 2:
|
|
143
|
-
modelAuthModes = _b.sent();
|
|
144
|
-
operationAuthModes_1 = modelAuthModes[operation.toUpperCase()];
|
|
145
|
-
authModeAttempts_1 = 0;
|
|
146
|
-
authModeRetry_1 = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
147
|
-
var response, error_2, e_1;
|
|
148
|
-
return tslib_1.__generator(this, function (_a) {
|
|
149
|
-
switch (_a.label) {
|
|
150
|
-
case 0:
|
|
151
|
-
_a.trys.push([0, 2, , 9]);
|
|
152
|
-
logger.debug("Attempting mutation with authMode: " + operationAuthModes_1[authModeAttempts_1]);
|
|
153
|
-
return [4 /*yield*/, this.jitteredRetry(namespaceName, model, operation, data, condition, modelConstructor, this.MutationEvent, head, operationAuthModes_1[authModeAttempts_1], onTerminate)];
|
|
154
|
-
case 1:
|
|
155
|
-
response = _a.sent();
|
|
156
|
-
logger.debug("Mutation sent successfully with authMode: " + operationAuthModes_1[authModeAttempts_1]);
|
|
157
|
-
return [2 /*return*/, response];
|
|
158
|
-
case 2:
|
|
159
|
-
error_2 = _a.sent();
|
|
160
|
-
authModeAttempts_1++;
|
|
161
|
-
if (!(authModeAttempts_1 >= operationAuthModes_1.length)) return [3 /*break*/, 7];
|
|
162
|
-
logger.debug("Mutation failed with authMode: " + operationAuthModes_1[authModeAttempts_1 - 1]);
|
|
163
|
-
_a.label = 3;
|
|
164
|
-
case 3:
|
|
165
|
-
_a.trys.push([3, 5, , 6]);
|
|
166
|
-
return [4 /*yield*/, this.errorHandler({
|
|
167
|
-
recoverySuggestion: 'Ensure app code is up to date, auth directives exist and are correct on each model, and that server-side data has not been invalidated by a schema change. If the problem persists, search for or create an issue: https://github.com/aws-amplify/amplify-js/issues',
|
|
168
|
-
localModel: null,
|
|
169
|
-
message: error_2.message,
|
|
170
|
-
model: modelConstructor.name,
|
|
171
|
-
operation: opName,
|
|
172
|
-
errorType: errorMaps_1.getMutationErrorType(error_2),
|
|
173
|
-
process: types_1.ProcessName.sync,
|
|
174
|
-
remoteModel: null,
|
|
175
|
-
cause: error_2,
|
|
176
|
-
})];
|
|
177
|
-
case 4:
|
|
178
|
-
_a.sent();
|
|
179
|
-
return [3 /*break*/, 6];
|
|
180
|
-
case 5:
|
|
181
|
-
e_1 = _a.sent();
|
|
182
|
-
logger.error('Mutation error handler failed with:', e_1);
|
|
183
|
-
return [3 /*break*/, 6];
|
|
184
|
-
case 6: throw error_2;
|
|
185
|
-
case 7:
|
|
186
|
-
logger.debug("Mutation failed with authMode: " + operationAuthModes_1[authModeAttempts_1 - 1] + ". Retrying with authMode: " + operationAuthModes_1[authModeAttempts_1]);
|
|
187
|
-
return [4 /*yield*/, authModeRetry_1()];
|
|
188
|
-
case 8: return [2 /*return*/, _a.sent()];
|
|
189
|
-
case 9: return [2 /*return*/];
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
}); };
|
|
193
|
-
return [4 /*yield*/, authModeRetry_1()];
|
|
194
|
-
case 3:
|
|
195
|
-
_a = tslib_1.__read.apply(void 0, [_b.sent(), 3]), result = _a[0], opName = _a[1], modelDefinition = _a[2];
|
|
196
|
-
return [3 /*break*/, 5];
|
|
197
|
-
case 4:
|
|
198
|
-
error_1 = _b.sent();
|
|
199
|
-
if (error_1.message === 'Offline' ||
|
|
200
|
-
error_1.message === 'RetryMutation') {
|
|
201
|
-
return [2 /*return*/, "continue"];
|
|
202
|
-
}
|
|
203
|
-
return [3 /*break*/, 5];
|
|
204
|
-
case 5:
|
|
205
|
-
if (!(result === undefined)) return [3 /*break*/, 7];
|
|
206
|
-
logger.debug('done retrying');
|
|
207
|
-
return [4 /*yield*/, this_1.storage.runExclusive(function (storage) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
208
|
-
return tslib_1.__generator(this, function (_a) {
|
|
209
|
-
switch (_a.label) {
|
|
210
|
-
case 0: return [4 /*yield*/, this.outbox.dequeue(storage)];
|
|
211
|
-
case 1:
|
|
212
|
-
_a.sent();
|
|
213
|
-
return [2 /*return*/];
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
}); })];
|
|
217
|
-
case 6:
|
|
218
|
-
_b.sent();
|
|
219
|
-
return [2 /*return*/, "continue"];
|
|
220
|
-
case 7:
|
|
221
|
-
record = result.data[opName];
|
|
222
|
-
hasMore = false;
|
|
223
|
-
return [4 /*yield*/, this_1.storage.runExclusive(function (storage) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
224
|
-
return tslib_1.__generator(this, function (_a) {
|
|
225
|
-
switch (_a.label) {
|
|
226
|
-
case 0:
|
|
227
|
-
// using runExclusive to prevent possible race condition
|
|
228
|
-
// when another record gets enqueued between dequeue and peek
|
|
229
|
-
return [4 /*yield*/, this.outbox.dequeue(storage, record, operation)];
|
|
230
|
-
case 1:
|
|
231
|
-
// using runExclusive to prevent possible race condition
|
|
232
|
-
// when another record gets enqueued between dequeue and peek
|
|
233
|
-
_a.sent();
|
|
234
|
-
return [4 /*yield*/, this.outbox.peek(storage)];
|
|
235
|
-
case 2:
|
|
236
|
-
hasMore = (_a.sent()) !== undefined;
|
|
237
|
-
return [2 /*return*/];
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
}); })];
|
|
241
|
-
case 8:
|
|
242
|
-
_b.sent();
|
|
243
|
-
(_c = (_b = this_1.observer) === null || _b === void 0 ? void 0 : _b.next) === null || _c === void 0 ? void 0 : _c.call(_b, {
|
|
244
|
-
operation: operation,
|
|
245
|
-
modelDefinition: modelDefinition,
|
|
246
|
-
model: record,
|
|
247
|
-
hasMore: hasMore,
|
|
248
|
-
});
|
|
249
|
-
return [2 /*return*/];
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
};
|
|
253
|
-
this_1 = this;
|
|
254
|
-
_d.label = 1;
|
|
255
|
-
case 1:
|
|
256
|
-
_a = this.processing &&
|
|
257
|
-
this.runningProcesses.isOpen;
|
|
258
|
-
if (!_a) return [3 /*break*/, 3];
|
|
259
|
-
return [4 /*yield*/, this.outbox.peek(this.storage)];
|
|
260
|
-
case 2:
|
|
261
|
-
_a = (head = _d.sent()) !== undefined;
|
|
262
|
-
_d.label = 3;
|
|
263
|
-
case 3:
|
|
264
|
-
if (!_a) return [3 /*break*/, 5];
|
|
265
|
-
return [5 /*yield**/, _loop_1()];
|
|
266
|
-
case 4:
|
|
267
|
-
_d.sent();
|
|
268
|
-
return [3 /*break*/, 1];
|
|
269
|
-
case 5:
|
|
270
|
-
// pauses itself
|
|
271
|
-
this.pause();
|
|
272
|
-
return [2 /*return*/];
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
}); }, 'mutation resume loop'))];
|
|
276
|
-
case 1:
|
|
277
|
-
_a.sent();
|
|
278
|
-
return [2 /*return*/];
|
|
80
|
+
}
|
|
81
|
+
async resume() {
|
|
82
|
+
if (this.runningProcesses.isOpen) {
|
|
83
|
+
await this.runningProcesses.add(async (onTerminate) => {
|
|
84
|
+
if (this.processing ||
|
|
85
|
+
!this.isReady() ||
|
|
86
|
+
!this.runningProcesses.isOpen) {
|
|
87
|
+
return;
|
|
279
88
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
) {
|
|
330
|
-
if (!this.processing) {
|
|
331
|
-
throw new core_1.NonRetryableError('Offline');
|
|
332
|
-
}
|
|
333
|
-
// TODO: Check errors on different env (react-native or other browsers)
|
|
334
|
-
throw new Error('Network Error');
|
|
335
|
-
}
|
|
336
|
-
if (!(error.errorType === 'ConflictUnhandled')) return [3 /*break*/, 13];
|
|
337
|
-
// TODO: add on ConflictConditionalCheck error query last from server
|
|
338
|
-
attempt++;
|
|
339
|
-
retryWith = void 0;
|
|
340
|
-
if (!(attempt > MAX_ATTEMPTS)) return [3 /*break*/, 5];
|
|
341
|
-
retryWith = types_1.DISCARD;
|
|
342
|
-
return [3 /*break*/, 8];
|
|
343
|
-
case 5:
|
|
344
|
-
_h.trys.push([5, 7, , 8]);
|
|
345
|
-
return [4 /*yield*/, this.conflictHandler({
|
|
346
|
-
modelConstructor: modelConstructor,
|
|
347
|
-
localModel: this.modelInstanceCreator(modelConstructor, variables.input),
|
|
348
|
-
remoteModel: this.modelInstanceCreator(modelConstructor, error.data),
|
|
349
|
-
operation: opType,
|
|
350
|
-
attempts: attempt,
|
|
351
|
-
})];
|
|
352
|
-
case 6:
|
|
353
|
-
retryWith = _h.sent();
|
|
354
|
-
return [3 /*break*/, 8];
|
|
355
|
-
case 7:
|
|
356
|
-
err_2 = _h.sent();
|
|
357
|
-
logger.warn('conflict trycatch', err_2);
|
|
358
|
-
return [3 /*break*/, 17];
|
|
359
|
-
case 8:
|
|
360
|
-
if (!(retryWith === types_1.DISCARD)) return [3 /*break*/, 11];
|
|
361
|
-
_e = tslib_1.__read(utils_1.buildGraphQLOperation(this.schema.namespaces[namespaceName], modelDefinition, 'GET'), 1), _f = tslib_1.__read(_e[0], 3), opName_1 = _f[1], query_1 = _f[2];
|
|
362
|
-
return [4 /*yield*/, utils_1.getTokenForCustomAuth(authMode, this.amplifyConfig)];
|
|
363
|
-
case 9:
|
|
364
|
-
authToken_1 = _h.sent();
|
|
365
|
-
return [4 /*yield*/, this.amplifyContext.InternalAPI.graphql({
|
|
366
|
-
query: query_1,
|
|
367
|
-
variables: { id: variables.input.id },
|
|
368
|
-
authMode: authMode,
|
|
369
|
-
authToken: authToken_1,
|
|
370
|
-
}, undefined, customUserAgentDetails)];
|
|
371
|
-
case 10:
|
|
372
|
-
serverData = _h.sent();
|
|
373
|
-
// onTerminate cancel graphql()
|
|
374
|
-
return [2 /*return*/, [serverData, opName_1, modelDefinition]];
|
|
375
|
-
case 11:
|
|
376
|
-
namespace = this.schema.namespaces[namespaceName];
|
|
377
|
-
updatedMutation = utils_1.createMutationInstanceFromModelOperation(namespace.relationships, modelDefinition, opType, modelConstructor, retryWith, graphQLCondition, MutationEvent, this.modelInstanceCreator, mutationEvent.id);
|
|
378
|
-
return [4 /*yield*/, this.storage.save(updatedMutation)];
|
|
379
|
-
case 12:
|
|
380
|
-
_h.sent();
|
|
381
|
-
throw new core_1.NonRetryableError('RetryMutation');
|
|
382
|
-
case 13:
|
|
383
|
-
try {
|
|
384
|
-
this.errorHandler({
|
|
385
|
-
recoverySuggestion: 'Ensure app code is up to date, auth directives exist and are correct on each model, and that server-side data has not been invalidated by a schema change. If the problem persists, search for or create an issue: https://github.com/aws-amplify/amplify-js/issues',
|
|
386
|
-
localModel: variables.input,
|
|
387
|
-
message: error.message,
|
|
388
|
-
operation: operation,
|
|
389
|
-
errorType: errorMaps_1.getMutationErrorType(error),
|
|
390
|
-
errorInfo: error.errorInfo,
|
|
391
|
-
process: types_1.ProcessName.mutate,
|
|
392
|
-
cause: error,
|
|
393
|
-
remoteModel: error.data
|
|
394
|
-
? this.modelInstanceCreator(modelConstructor, error.data)
|
|
395
|
-
: null,
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
catch (err) {
|
|
399
|
-
logger.warn('Mutation error handler failed with:', err);
|
|
400
|
-
}
|
|
401
|
-
finally {
|
|
402
|
-
// Return empty tuple, dequeues the mutation
|
|
403
|
-
return [2 /*return*/, error.data
|
|
404
|
-
? [
|
|
405
|
-
{ data: (_g = {}, _g[opName] = error.data, _g) },
|
|
406
|
-
opName,
|
|
407
|
-
modelDefinition,
|
|
408
|
-
]
|
|
409
|
-
: []];
|
|
410
|
-
}
|
|
411
|
-
_h.label = 14;
|
|
412
|
-
case 14: return [3 /*break*/, 16];
|
|
413
|
-
case 15:
|
|
414
|
-
// Catch-all for client-side errors that don't come back in the `GraphQLError` format.
|
|
415
|
-
// These errors should not be retried.
|
|
416
|
-
throw new core_1.NonRetryableError(err_1);
|
|
417
|
-
case 16: return [3 /*break*/, 17];
|
|
418
|
-
case 17:
|
|
419
|
-
if (tryWith) return [3 /*break*/, 2];
|
|
420
|
-
_h.label = 18;
|
|
421
|
-
case 18: return [2 /*return*/];
|
|
89
|
+
this.processing = true;
|
|
90
|
+
let head;
|
|
91
|
+
const namespaceName = util_1.USER;
|
|
92
|
+
// start to drain outbox
|
|
93
|
+
while (this.processing &&
|
|
94
|
+
this.runningProcesses.isOpen &&
|
|
95
|
+
(head = await this.outbox.peek(this.storage)) !== undefined) {
|
|
96
|
+
const { model, operation, data, condition } = head;
|
|
97
|
+
const modelConstructor = this.userClasses[model];
|
|
98
|
+
let result = undefined;
|
|
99
|
+
let opName = undefined;
|
|
100
|
+
let modelDefinition = undefined;
|
|
101
|
+
try {
|
|
102
|
+
const modelAuthModes = await (0, utils_2.getModelAuthModes)({
|
|
103
|
+
authModeStrategy: this.authModeStrategy,
|
|
104
|
+
defaultAuthMode: this.amplifyConfig.aws_appsync_authenticationType,
|
|
105
|
+
modelName: model,
|
|
106
|
+
schema: this.schema,
|
|
107
|
+
});
|
|
108
|
+
const operationAuthModes = modelAuthModes[operation.toUpperCase()];
|
|
109
|
+
let authModeAttempts = 0;
|
|
110
|
+
const authModeRetry = async () => {
|
|
111
|
+
try {
|
|
112
|
+
logger.debug(`Attempting mutation with authMode: ${operationAuthModes[authModeAttempts]}`);
|
|
113
|
+
const response = await this.jitteredRetry(namespaceName, model, operation, data, condition, modelConstructor, this.MutationEvent, head, operationAuthModes[authModeAttempts], onTerminate);
|
|
114
|
+
logger.debug(`Mutation sent successfully with authMode: ${operationAuthModes[authModeAttempts]}`);
|
|
115
|
+
return response;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
authModeAttempts++;
|
|
119
|
+
if (authModeAttempts >= operationAuthModes.length) {
|
|
120
|
+
logger.debug(`Mutation failed with authMode: ${operationAuthModes[authModeAttempts - 1]}`);
|
|
121
|
+
try {
|
|
122
|
+
await this.errorHandler({
|
|
123
|
+
recoverySuggestion: 'Ensure app code is up to date, auth directives exist and are correct on each model, and that server-side data has not been invalidated by a schema change. If the problem persists, search for or create an issue: https://github.com/aws-amplify/amplify-js/issues',
|
|
124
|
+
localModel: null,
|
|
125
|
+
message: error.message,
|
|
126
|
+
model: modelConstructor.name,
|
|
127
|
+
operation: opName,
|
|
128
|
+
errorType: (0, errorMaps_1.getMutationErrorType)(error),
|
|
129
|
+
process: types_1.ProcessName.sync,
|
|
130
|
+
remoteModel: null,
|
|
131
|
+
cause: error,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
logger.error('Mutation error handler failed with:', e);
|
|
136
|
+
}
|
|
137
|
+
throw error;
|
|
422
138
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
var pkField = primaryKey_1_1.value;
|
|
457
|
-
deleteInput[pkField] = parsedData[pkField];
|
|
139
|
+
logger.debug(`Mutation failed with authMode: ${operationAuthModes[authModeAttempts - 1]}. Retrying with authMode: ${operationAuthModes[authModeAttempts]}`);
|
|
140
|
+
return await authModeRetry();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
[result, opName, modelDefinition] = await authModeRetry();
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
if (error.message === 'Offline' ||
|
|
147
|
+
error.message === 'RetryMutation') {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (result === undefined) {
|
|
152
|
+
logger.debug('done retrying');
|
|
153
|
+
await this.storage.runExclusive(async (storage) => {
|
|
154
|
+
await this.outbox.dequeue(storage);
|
|
155
|
+
});
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const record = result.data[opName];
|
|
159
|
+
let hasMore = false;
|
|
160
|
+
await this.storage.runExclusive(async (storage) => {
|
|
161
|
+
// using runExclusive to prevent possible race condition
|
|
162
|
+
// when another record gets enqueued between dequeue and peek
|
|
163
|
+
await this.outbox.dequeue(storage, record, operation);
|
|
164
|
+
hasMore = (await this.outbox.peek(storage)) !== undefined;
|
|
165
|
+
});
|
|
166
|
+
this.observer?.next?.({
|
|
167
|
+
operation,
|
|
168
|
+
modelDefinition,
|
|
169
|
+
model: record,
|
|
170
|
+
hasMore,
|
|
171
|
+
});
|
|
458
172
|
}
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
173
|
+
// pauses itself
|
|
174
|
+
this.pause();
|
|
175
|
+
}, 'mutation resume loop');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async jitteredRetry(namespaceName, model, operation, data, condition, modelConstructor, MutationEvent, mutationEvent, authMode, onTerminate) {
|
|
179
|
+
return await (0, utils_1.retry)(async (model, operation, data, condition, modelConstructor, MutationEvent, mutationEvent) => {
|
|
180
|
+
const [query, variables, graphQLCondition, opName, modelDefinition] = this.createQueryVariables(namespaceName, model, operation, data, condition);
|
|
181
|
+
const authToken = await (0, utils_2.getTokenForCustomAuth)(authMode, this.amplifyConfig);
|
|
182
|
+
const tryWith = {
|
|
183
|
+
query,
|
|
184
|
+
variables,
|
|
185
|
+
authMode,
|
|
186
|
+
authToken,
|
|
187
|
+
};
|
|
188
|
+
let attempt = 0;
|
|
189
|
+
const opType = this.opTypeFromTransformerOperation(operation);
|
|
190
|
+
const customUserAgentDetails = {
|
|
191
|
+
category: utils_1.Category.DataStore,
|
|
192
|
+
action: utils_1.DataStoreAction.GraphQl,
|
|
193
|
+
};
|
|
194
|
+
do {
|
|
462
195
|
try {
|
|
463
|
-
|
|
196
|
+
const result = (await this.amplifyContext.InternalAPI.graphql(tryWith, undefined, customUserAgentDetails));
|
|
197
|
+
// Use `as any` because TypeScript doesn't seem to like passing tuples
|
|
198
|
+
// through generic params.
|
|
199
|
+
return [result, opName, modelDefinition];
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (err.errors && err.errors.length > 0) {
|
|
203
|
+
const [error] = err.errors;
|
|
204
|
+
const { originalError: { code = null } = {} } = error;
|
|
205
|
+
if (error.errorType === 'Unauthorized') {
|
|
206
|
+
throw new utils_1.NonRetryableError('Unauthorized');
|
|
207
|
+
}
|
|
208
|
+
if (error.message === 'Network Error' ||
|
|
209
|
+
code === 'ECONNABORTED' // refers to axios timeout error caused by device's bad network condition
|
|
210
|
+
) {
|
|
211
|
+
if (!this.processing) {
|
|
212
|
+
throw new utils_1.NonRetryableError('Offline');
|
|
213
|
+
}
|
|
214
|
+
// TODO: Check errors on different env (react-native or other browsers)
|
|
215
|
+
throw new Error('Network Error');
|
|
216
|
+
}
|
|
217
|
+
if (error.errorType === 'ConflictUnhandled') {
|
|
218
|
+
// TODO: add on ConflictConditionalCheck error query last from server
|
|
219
|
+
attempt++;
|
|
220
|
+
let retryWith;
|
|
221
|
+
if (attempt > MAX_ATTEMPTS) {
|
|
222
|
+
retryWith = types_1.DISCARD;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
try {
|
|
226
|
+
retryWith = await this.conflictHandler({
|
|
227
|
+
modelConstructor,
|
|
228
|
+
localModel: this.modelInstanceCreator(modelConstructor, variables.input),
|
|
229
|
+
remoteModel: this.modelInstanceCreator(modelConstructor, error.data),
|
|
230
|
+
operation: opType,
|
|
231
|
+
attempts: attempt,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
logger.warn('conflict trycatch', err);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (retryWith === types_1.DISCARD) {
|
|
240
|
+
// Query latest from server and notify merger
|
|
241
|
+
const [[, opName, query]] = (0, utils_2.buildGraphQLOperation)(this.schema.namespaces[namespaceName], modelDefinition, 'GET');
|
|
242
|
+
const authToken = await (0, utils_2.getTokenForCustomAuth)(authMode, this.amplifyConfig);
|
|
243
|
+
const serverData = await this.amplifyContext.InternalAPI.graphql({
|
|
244
|
+
query,
|
|
245
|
+
variables: { id: variables.input.id },
|
|
246
|
+
authMode,
|
|
247
|
+
authToken,
|
|
248
|
+
}, undefined, customUserAgentDetails);
|
|
249
|
+
// onTerminate cancel graphql()
|
|
250
|
+
return [serverData, opName, modelDefinition];
|
|
251
|
+
}
|
|
252
|
+
const namespace = this.schema.namespaces[namespaceName];
|
|
253
|
+
// convert retry with to tryWith
|
|
254
|
+
const updatedMutation = (0, utils_2.createMutationInstanceFromModelOperation)(namespace.relationships, modelDefinition, opType, modelConstructor, retryWith, graphQLCondition, MutationEvent, this.modelInstanceCreator, mutationEvent.id);
|
|
255
|
+
await this.storage.save(updatedMutation);
|
|
256
|
+
throw new utils_1.NonRetryableError('RetryMutation');
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
try {
|
|
260
|
+
this.errorHandler({
|
|
261
|
+
recoverySuggestion: 'Ensure app code is up to date, auth directives exist and are correct on each model, and that server-side data has not been invalidated by a schema change. If the problem persists, search for or create an issue: https://github.com/aws-amplify/amplify-js/issues',
|
|
262
|
+
localModel: variables.input,
|
|
263
|
+
message: error.message,
|
|
264
|
+
operation,
|
|
265
|
+
errorType: (0, errorMaps_1.getMutationErrorType)(error),
|
|
266
|
+
errorInfo: error.errorInfo,
|
|
267
|
+
process: types_1.ProcessName.mutate,
|
|
268
|
+
cause: error,
|
|
269
|
+
remoteModel: error.data
|
|
270
|
+
? this.modelInstanceCreator(modelConstructor, error.data)
|
|
271
|
+
: null,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
logger.warn('Mutation error handler failed with:', err);
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
// Return empty tuple, dequeues the mutation
|
|
279
|
+
return error.data
|
|
280
|
+
? [
|
|
281
|
+
{ data: { [opName]: error.data } },
|
|
282
|
+
opName,
|
|
283
|
+
modelDefinition,
|
|
284
|
+
]
|
|
285
|
+
: [];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
// Catch-all for client-side errors that don't come back in the `GraphQLError` format.
|
|
291
|
+
// These errors should not be retried.
|
|
292
|
+
throw new utils_1.NonRetryableError(err);
|
|
293
|
+
}
|
|
464
294
|
}
|
|
465
|
-
|
|
295
|
+
} while (tryWith);
|
|
296
|
+
}, [
|
|
297
|
+
model,
|
|
298
|
+
operation,
|
|
299
|
+
data,
|
|
300
|
+
condition,
|
|
301
|
+
modelConstructor,
|
|
302
|
+
MutationEvent,
|
|
303
|
+
mutationEvent,
|
|
304
|
+
], exports.safeJitteredBackoff, onTerminate);
|
|
305
|
+
}
|
|
306
|
+
createQueryVariables(namespaceName, model, operation, data, condition) {
|
|
307
|
+
const modelDefinition = this.schema.namespaces[namespaceName].models[model];
|
|
308
|
+
const { primaryKey } = this.schema.namespaces[namespaceName].keys[model];
|
|
309
|
+
const auth = modelDefinition.attributes?.find(a => a.type === 'auth');
|
|
310
|
+
const ownerFields = auth?.properties?.rules
|
|
311
|
+
.map(rule => rule.ownerField)
|
|
312
|
+
.filter(f => f) || ['owner'];
|
|
313
|
+
const queriesTuples = this.typeQuery.get(modelDefinition);
|
|
314
|
+
const [, opName, query] = queriesTuples.find(([transformerMutationType]) => transformerMutationType === operation);
|
|
315
|
+
const { _version, ...parsedData } = JSON.parse(data);
|
|
316
|
+
// include all the fields that comprise a custom PK if one is specified
|
|
317
|
+
const deleteInput = {};
|
|
318
|
+
if (primaryKey && primaryKey.length) {
|
|
319
|
+
for (const pkField of primaryKey) {
|
|
320
|
+
deleteInput[pkField] = parsedData[pkField];
|
|
466
321
|
}
|
|
467
322
|
}
|
|
468
323
|
else {
|
|
469
324
|
deleteInput[util_1.ID] = parsedData.id;
|
|
470
325
|
}
|
|
471
|
-
|
|
472
|
-
if (operation ===
|
|
326
|
+
let mutationInput;
|
|
327
|
+
if (operation === utils_2.TransformerMutationType.DELETE) {
|
|
473
328
|
// For DELETE mutations, only the key(s) are included in the input
|
|
474
329
|
mutationInput = deleteInput;
|
|
475
330
|
}
|
|
476
331
|
else {
|
|
477
332
|
// Otherwise, we construct the mutation input with the following logic
|
|
478
333
|
mutationInput = {};
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
//
|
|
492
|
-
if (types_1.
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
// instead of including the connected model itself, we add its key(s) to the mutation input
|
|
500
|
-
for (var targetNames_1 = (e_4 = void 0, tslib_1.__values(targetNames)), targetNames_1_1 = targetNames_1.next(); !targetNames_1_1.done; targetNames_1_1 = targetNames_1.next()) {
|
|
501
|
-
var targetName = targetNames_1_1.value;
|
|
502
|
-
mutationInput[targetName] = parsedData[targetName];
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
506
|
-
finally {
|
|
507
|
-
try {
|
|
508
|
-
if (targetNames_1_1 && !targetNames_1_1.done && (_c = targetNames_1.return)) _c.call(targetNames_1);
|
|
509
|
-
}
|
|
510
|
-
finally { if (e_4) throw e_4.error; }
|
|
511
|
-
}
|
|
334
|
+
const modelFields = Object.values(modelDefinition.fields);
|
|
335
|
+
for (const { name, type, association, isReadOnly } of modelFields) {
|
|
336
|
+
// omit readonly fields. cloud storage doesn't need them and won't take them!
|
|
337
|
+
if (isReadOnly) {
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
// omit owner fields if it's `null`. cloud storage doesn't allow it.
|
|
341
|
+
if (ownerFields.includes(name) && parsedData[name] === null) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
// model fields should be stripped out from the input
|
|
345
|
+
if ((0, types_1.isModelFieldType)(type)) {
|
|
346
|
+
// except for belongs to relations - we need to replace them with the correct foreign key(s)
|
|
347
|
+
if ((0, types_1.isTargetNameAssociation)(association) &&
|
|
348
|
+
association.connectionType === 'BELONGS_TO') {
|
|
349
|
+
const targetNames = (0, util_1.extractTargetNamesFromSrc)(association);
|
|
350
|
+
if (targetNames) {
|
|
351
|
+
// instead of including the connected model itself, we add its key(s) to the mutation input
|
|
352
|
+
for (const targetName of targetNames) {
|
|
353
|
+
mutationInput[targetName] = parsedData[targetName];
|
|
512
354
|
}
|
|
513
355
|
}
|
|
514
|
-
continue;
|
|
515
356
|
}
|
|
516
|
-
|
|
517
|
-
if (operation === utils_1.TransformerMutationType.UPDATE) {
|
|
518
|
-
if (!parsedData.hasOwnProperty(name_1)) {
|
|
519
|
-
// for update mutations - strip out a field if it's unchanged
|
|
520
|
-
continue;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
// all other fields are added to the input object
|
|
524
|
-
mutationInput[name_1] = parsedData[name_1];
|
|
357
|
+
continue;
|
|
525
358
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
359
|
+
// scalar fields / non-model types
|
|
360
|
+
if (operation === utils_2.TransformerMutationType.UPDATE) {
|
|
361
|
+
if (!parsedData.hasOwnProperty(name)) {
|
|
362
|
+
// for update mutations - strip out a field if it's unchanged
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
531
365
|
}
|
|
532
|
-
|
|
366
|
+
// all other fields are added to the input object
|
|
367
|
+
mutationInput[name] = parsedData[name];
|
|
533
368
|
}
|
|
534
369
|
}
|
|
535
370
|
// Build mutation variables input object
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
371
|
+
const input = {
|
|
372
|
+
...mutationInput,
|
|
373
|
+
_version,
|
|
374
|
+
};
|
|
375
|
+
const graphQLCondition = JSON.parse(condition);
|
|
376
|
+
const variables = {
|
|
377
|
+
input,
|
|
378
|
+
...(operation === utils_2.TransformerMutationType.CREATE
|
|
379
|
+
? {}
|
|
380
|
+
: {
|
|
381
|
+
condition: Object.keys(graphQLCondition).length > 0
|
|
382
|
+
? graphQLCondition
|
|
383
|
+
: null,
|
|
384
|
+
}),
|
|
385
|
+
};
|
|
545
386
|
return [query, variables, graphQLCondition, opName, modelDefinition];
|
|
546
|
-
}
|
|
547
|
-
|
|
387
|
+
}
|
|
388
|
+
opTypeFromTransformerOperation(operation) {
|
|
548
389
|
switch (operation) {
|
|
549
|
-
case
|
|
390
|
+
case utils_2.TransformerMutationType.CREATE:
|
|
550
391
|
return types_1.OpType.INSERT;
|
|
551
|
-
case
|
|
392
|
+
case utils_2.TransformerMutationType.DELETE:
|
|
552
393
|
return types_1.OpType.DELETE;
|
|
553
|
-
case
|
|
394
|
+
case utils_2.TransformerMutationType.UPDATE:
|
|
554
395
|
return types_1.OpType.UPDATE;
|
|
555
|
-
case
|
|
396
|
+
case utils_2.TransformerMutationType.GET: // Intentionally blank
|
|
556
397
|
break;
|
|
557
398
|
default:
|
|
558
|
-
throw new Error(
|
|
399
|
+
throw new Error(`Invalid operation ${operation}`);
|
|
559
400
|
}
|
|
560
401
|
// because it makes TS happy ...
|
|
561
402
|
return undefined;
|
|
562
|
-
}
|
|
563
|
-
|
|
403
|
+
}
|
|
404
|
+
pause() {
|
|
564
405
|
this.processing = false;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
}());
|
|
406
|
+
}
|
|
407
|
+
}
|
|
568
408
|
exports.MutationProcessor = MutationProcessor;
|
|
569
|
-
|
|
570
|
-
|
|
409
|
+
const MAX_RETRY_DELAY_MS = 5 * 60 * 1000;
|
|
410
|
+
const originalJitteredBackoff = (0, utils_1.jitteredBackoff)(MAX_RETRY_DELAY_MS);
|
|
571
411
|
/**
|
|
572
412
|
* @private
|
|
573
413
|
* Internal use of Amplify only.
|
|
@@ -583,12 +423,13 @@ var originalJitteredBackoff = core_1.jitteredBackoff(MAX_RETRY_DELAY_MS);
|
|
|
583
423
|
* @param error tested to see if `.message` is 'Network Error'
|
|
584
424
|
* @returns number | false :
|
|
585
425
|
*/
|
|
586
|
-
|
|
587
|
-
|
|
426
|
+
const safeJitteredBackoff = (attempt, _args, error) => {
|
|
427
|
+
const attemptResult = originalJitteredBackoff(attempt);
|
|
588
428
|
// If this is the last attempt and it is a network error, we retry indefinitively every 5 minutes
|
|
589
|
-
if (attemptResult === false &&
|
|
429
|
+
if (attemptResult === false &&
|
|
430
|
+
(error || {}).message === 'Network Error') {
|
|
590
431
|
return MAX_RETRY_DELAY_MS;
|
|
591
432
|
}
|
|
592
433
|
return attemptResult;
|
|
593
434
|
};
|
|
594
|
-
|
|
435
|
+
exports.safeJitteredBackoff = safeJitteredBackoff;
|