@aws-amplify/datastore 3.14.1-unstable.2 → 3.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/aws-amplify-datastore.js +2798 -1458
- package/dist/aws-amplify-datastore.js.map +1 -1
- package/dist/aws-amplify-datastore.min.js +10 -10
- package/dist/aws-amplify-datastore.min.js.map +1 -1
- package/lib/authModeStrategies/multiAuthStrategy.js +11 -0
- package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib/datastore/datastore.js +524 -323
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.js +76 -25
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/storage.js +2 -2
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/datastoreConnectivity.js +45 -0
- package/lib/sync/datastoreConnectivity.js.map +1 -1
- package/lib/sync/index.js +518 -395
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.js +6 -0
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.js +66 -62
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/mutation.js +207 -165
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.js +210 -175
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.js +95 -72
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.js +1 -3
- package/lib/sync/utils.js.map +1 -1
- package/lib/util.js +89 -0
- package/lib/util.js.map +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +11 -0
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +11 -0
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +95 -2
- package/lib-esm/datastore/datastore.js +524 -323
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +21 -0
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +77 -26
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/storage.js +2 -2
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/datastoreConnectivity.d.ts +1 -0
- package/lib-esm/sync/datastoreConnectivity.js +45 -0
- package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
- package/lib-esm/sync/index.d.ts +9 -1
- package/lib-esm/sync/index.js +519 -396
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.d.ts +6 -0
- package/lib-esm/sync/merger.js +6 -0
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.js +66 -62
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/mutation.d.ts +2 -0
- package/lib-esm/sync/processors/mutation.js +208 -166
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.d.ts +2 -0
- package/lib-esm/sync/processors/subscription.js +211 -176
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.d.ts +2 -0
- package/lib-esm/sync/processors/sync.js +96 -73
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.js +1 -3
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/util.d.ts +11 -0
- package/lib-esm/util.js +89 -0
- package/lib-esm/util.js.map +1 -1
- package/package.json +7 -7
- package/src/authModeStrategies/multiAuthStrategy.ts +11 -0
- package/src/datastore/datastore.ts +572 -366
- package/src/storage/adapter/IndexedDBAdapter.ts +50 -9
- package/src/storage/storage.ts +2 -2
- package/src/sync/datastoreConnectivity.ts +6 -0
- package/src/sync/index.ts +492 -400
- package/src/sync/merger.ts +6 -0
- package/src/sync/outbox.ts +1 -1
- package/src/sync/processors/mutation.ts +139 -104
- package/src/sync/processors/subscription.ts +287 -250
- package/src/sync/processors/sync.ts +88 -60
- package/src/sync/utils.ts +1 -3
- package/src/util.ts +92 -2
- package/lib/authModeStrategies/defaultAuthStrategy.d.ts +0 -2
- package/lib/authModeStrategies/index.d.ts +0 -2
- package/lib/authModeStrategies/multiAuthStrategy.d.ts +0 -2
- package/lib/datastore/datastore.d.ts +0 -63
- package/lib/index.d.ts +0 -15
- package/lib/predicates/index.d.ts +0 -16
- package/lib/predicates/sort.d.ts +0 -8
- package/lib/ssr/index.d.ts +0 -3
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +0 -41
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +0 -39
- package/lib/storage/adapter/InMemoryStore.d.ts +0 -11
- package/lib/storage/adapter/InMemoryStore.native.d.ts +0 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +0 -38
- package/lib/storage/adapter/getDefaultAdapter/index.d.ts +0 -3
- package/lib/storage/adapter/getDefaultAdapter/index.native.d.ts +0 -3
- package/lib/storage/adapter/index.d.ts +0 -9
- package/lib/storage/storage.d.ts +0 -49
- package/lib/sync/datastoreConnectivity.d.ts +0 -15
- package/lib/sync/datastoreReachability/index.d.ts +0 -3
- package/lib/sync/datastoreReachability/index.native.d.ts +0 -3
- package/lib/sync/index.d.ts +0 -81
- package/lib/sync/merger.d.ts +0 -11
- package/lib/sync/outbox.d.ts +0 -27
- package/lib/sync/processors/errorMaps.d.ts +0 -17
- package/lib/sync/processors/mutation.d.ts +0 -56
- package/lib/sync/processors/subscription.d.ts +0 -31
- package/lib/sync/processors/sync.d.ts +0 -26
- package/lib/sync/utils.d.ts +0 -42
- package/lib/types.d.ts +0 -501
- package/lib/util.d.ts +0 -145
package/src/sync/merger.ts
CHANGED
|
@@ -15,6 +15,12 @@ class ModelMerger {
|
|
|
15
15
|
private readonly ownSymbol: Symbol
|
|
16
16
|
) {}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param storage Storage adapter that contains the data.
|
|
21
|
+
* @param model The model from an outbox mutation.
|
|
22
|
+
* @returns The type of operation (INSERT/UPDATE/DELETE)
|
|
23
|
+
*/
|
|
18
24
|
public async merge<T extends ModelInstanceMetadata>(
|
|
19
25
|
storage: Storage,
|
|
20
26
|
model: T,
|
package/src/sync/outbox.ts
CHANGED
|
@@ -32,7 +32,7 @@ class MutationEventOutbox {
|
|
|
32
32
|
storage: Storage,
|
|
33
33
|
mutationEvent: MutationEvent
|
|
34
34
|
): Promise<void> {
|
|
35
|
-
storage.runExclusive(async s => {
|
|
35
|
+
await storage.runExclusive(async s => {
|
|
36
36
|
const mutationEventModelDefinition =
|
|
37
37
|
this.schema.namespaces[SYNC].models['MutationEvent'];
|
|
38
38
|
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
jitteredBackoff,
|
|
5
5
|
NonRetryableError,
|
|
6
6
|
retry,
|
|
7
|
+
BackgroundProcessManager,
|
|
7
8
|
} from '@aws-amplify/core';
|
|
8
9
|
import Observable, { ZenObservable } from 'zen-observable-ts';
|
|
9
10
|
import { MutationEvent } from '../';
|
|
@@ -63,6 +64,8 @@ class MutationProcessor {
|
|
|
63
64
|
>();
|
|
64
65
|
private processing: boolean = false;
|
|
65
66
|
|
|
67
|
+
private runningProcesses = new BackgroundProcessManager();
|
|
68
|
+
|
|
66
69
|
constructor(
|
|
67
70
|
private readonly schema: InternalSchema,
|
|
68
71
|
private readonly storage: Storage,
|
|
@@ -118,126 +121,150 @@ class MutationProcessor {
|
|
|
118
121
|
const observable = new Observable<MutationProcessorEvent>(observer => {
|
|
119
122
|
this.observer = observer;
|
|
120
123
|
|
|
121
|
-
|
|
124
|
+
try {
|
|
125
|
+
this.resume();
|
|
126
|
+
} catch (error) {
|
|
127
|
+
logger.error('mutations processor start error', error);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
122
130
|
|
|
123
|
-
return () => {
|
|
131
|
+
return this.runningProcesses.addCleaner(async () => {
|
|
124
132
|
this.pause();
|
|
125
|
-
};
|
|
133
|
+
});
|
|
126
134
|
});
|
|
127
135
|
|
|
128
136
|
return observable;
|
|
129
137
|
}
|
|
130
138
|
|
|
131
|
-
public async
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
139
|
+
public async stop() {
|
|
140
|
+
await this.runningProcesses.close();
|
|
141
|
+
await this.runningProcesses.open();
|
|
142
|
+
}
|
|
135
143
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const modelConstructor = this.userClasses[
|
|
147
|
-
model
|
|
148
|
-
] as PersistentModelConstructor<MutationEvent>;
|
|
149
|
-
let result: GraphQLResult<Record<string, PersistentModel>>;
|
|
150
|
-
let opName: string;
|
|
151
|
-
let modelDefinition: SchemaModel;
|
|
152
|
-
try {
|
|
153
|
-
const modelAuthModes = await getModelAuthModes({
|
|
154
|
-
authModeStrategy: this.authModeStrategy,
|
|
155
|
-
defaultAuthMode: this.amplifyConfig.aws_appsync_authenticationType,
|
|
156
|
-
modelName: model,
|
|
157
|
-
schema: this.schema,
|
|
158
|
-
});
|
|
144
|
+
public async resume(): Promise<void> {
|
|
145
|
+
await (this.runningProcesses.isOpen &&
|
|
146
|
+
this.runningProcesses.add(async onTerminate => {
|
|
147
|
+
if (
|
|
148
|
+
this.processing ||
|
|
149
|
+
!this.isReady() ||
|
|
150
|
+
!this.runningProcesses.isOpen
|
|
151
|
+
) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
159
154
|
|
|
160
|
-
|
|
155
|
+
this.processing = true;
|
|
156
|
+
let head: MutationEvent;
|
|
157
|
+
const namespaceName = USER;
|
|
158
|
+
|
|
159
|
+
// start to drain outbox
|
|
160
|
+
while (
|
|
161
|
+
this.processing &&
|
|
162
|
+
this.runningProcesses.isOpen &&
|
|
163
|
+
(head = await this.outbox.peek(this.storage)) !== undefined
|
|
164
|
+
) {
|
|
165
|
+
const { model, operation, data, condition } = head;
|
|
166
|
+
const modelConstructor = this.userClasses[
|
|
167
|
+
model
|
|
168
|
+
] as PersistentModelConstructor<MutationEvent>;
|
|
169
|
+
let result: GraphQLResult<Record<string, PersistentModel>>;
|
|
170
|
+
let opName: string;
|
|
171
|
+
let modelDefinition: SchemaModel;
|
|
161
172
|
|
|
162
|
-
let authModeAttempts = 0;
|
|
163
|
-
const authModeRetry = async () => {
|
|
164
173
|
try {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
174
|
+
const modelAuthModes = await getModelAuthModes({
|
|
175
|
+
authModeStrategy: this.authModeStrategy,
|
|
176
|
+
defaultAuthMode:
|
|
177
|
+
this.amplifyConfig.aws_appsync_authenticationType,
|
|
178
|
+
modelName: model,
|
|
179
|
+
schema: this.schema,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const operationAuthModes = modelAuthModes[operation.toUpperCase()];
|
|
183
|
+
|
|
184
|
+
let authModeAttempts = 0;
|
|
185
|
+
const authModeRetry = async () => {
|
|
186
|
+
try {
|
|
187
|
+
logger.debug(
|
|
188
|
+
`Attempting mutation with authMode: ${operationAuthModes[authModeAttempts]}`
|
|
189
|
+
);
|
|
190
|
+
const response = await this.jitteredRetry(
|
|
191
|
+
namespaceName,
|
|
192
|
+
model,
|
|
193
|
+
operation,
|
|
194
|
+
data,
|
|
195
|
+
condition,
|
|
196
|
+
modelConstructor,
|
|
197
|
+
this.MutationEvent,
|
|
198
|
+
head,
|
|
199
|
+
operationAuthModes[authModeAttempts],
|
|
200
|
+
onTerminate
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
logger.debug(
|
|
204
|
+
`Mutation sent successfully with authMode: ${operationAuthModes[authModeAttempts]}`
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
return response;
|
|
208
|
+
} catch (error) {
|
|
209
|
+
authModeAttempts++;
|
|
210
|
+
if (authModeAttempts >= operationAuthModes.length) {
|
|
211
|
+
logger.debug(
|
|
212
|
+
`Mutation failed with authMode: ${
|
|
213
|
+
operationAuthModes[authModeAttempts - 1]
|
|
214
|
+
}`
|
|
215
|
+
);
|
|
216
|
+
throw error;
|
|
217
|
+
}
|
|
218
|
+
logger.debug(
|
|
219
|
+
`Mutation failed with authMode: ${
|
|
220
|
+
operationAuthModes[authModeAttempts - 1]
|
|
221
|
+
}. Retrying with authMode: ${
|
|
222
|
+
operationAuthModes[authModeAttempts]
|
|
223
|
+
}`
|
|
224
|
+
);
|
|
225
|
+
return await authModeRetry();
|
|
226
|
+
}
|
|
227
|
+
};
|
|
183
228
|
|
|
184
|
-
|
|
229
|
+
[result, opName, modelDefinition] = await authModeRetry();
|
|
185
230
|
} catch (error) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}`
|
|
192
|
-
);
|
|
193
|
-
throw error;
|
|
231
|
+
if (
|
|
232
|
+
error.message === 'Offline' ||
|
|
233
|
+
error.message === 'RetryMutation'
|
|
234
|
+
) {
|
|
235
|
+
continue;
|
|
194
236
|
}
|
|
195
|
-
logger.debug(
|
|
196
|
-
`Mutation failed with authMode: ${
|
|
197
|
-
operationAuthModes[authModeAttempts - 1]
|
|
198
|
-
}. Retrying with authMode: ${
|
|
199
|
-
operationAuthModes[authModeAttempts]
|
|
200
|
-
}`
|
|
201
|
-
);
|
|
202
|
-
return await authModeRetry();
|
|
203
237
|
}
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
[result, opName, modelDefinition] = await authModeRetry();
|
|
207
|
-
} catch (error) {
|
|
208
|
-
if (error.message === 'Offline' || error.message === 'RetryMutation') {
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
238
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
239
|
+
if (result === undefined) {
|
|
240
|
+
logger.debug('done retrying');
|
|
241
|
+
await this.storage.runExclusive(async storage => {
|
|
242
|
+
await this.outbox.dequeue(storage);
|
|
243
|
+
});
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
220
246
|
|
|
221
|
-
|
|
222
|
-
|
|
247
|
+
const record = result.data[opName];
|
|
248
|
+
let hasMore = false;
|
|
223
249
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
250
|
+
await this.storage.runExclusive(async storage => {
|
|
251
|
+
// using runExclusive to prevent possible race condition
|
|
252
|
+
// when another record gets enqueued between dequeue and peek
|
|
253
|
+
await this.outbox.dequeue(storage, record, operation);
|
|
254
|
+
hasMore = (await this.outbox.peek(storage)) !== undefined;
|
|
255
|
+
});
|
|
230
256
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
257
|
+
this.observer.next({
|
|
258
|
+
operation,
|
|
259
|
+
modelDefinition,
|
|
260
|
+
model: record,
|
|
261
|
+
hasMore,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
238
264
|
|
|
239
|
-
|
|
240
|
-
|
|
265
|
+
// pauses itself
|
|
266
|
+
this.pause();
|
|
267
|
+
}, 'mutation resume loop'));
|
|
241
268
|
}
|
|
242
269
|
|
|
243
270
|
private async jitteredRetry(
|
|
@@ -249,7 +276,8 @@ class MutationProcessor {
|
|
|
249
276
|
modelConstructor: PersistentModelConstructor<PersistentModel>,
|
|
250
277
|
MutationEvent: PersistentModelConstructor<MutationEvent>,
|
|
251
278
|
mutationEvent: MutationEvent,
|
|
252
|
-
authMode: GRAPHQL_AUTH_MODE
|
|
279
|
+
authMode: GRAPHQL_AUTH_MODE,
|
|
280
|
+
onTerminate: Promise<void>
|
|
253
281
|
): Promise<
|
|
254
282
|
[GraphQLResult<Record<string, PersistentModel>>, string, SchemaModel]
|
|
255
283
|
> {
|
|
@@ -293,7 +321,11 @@ class MutationProcessor {
|
|
|
293
321
|
const result = <GraphQLResult<Record<string, PersistentModel>>>(
|
|
294
322
|
await this.amplifyContext.API.graphql(tryWith)
|
|
295
323
|
);
|
|
296
|
-
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
// `as any` because TypeScript doesn't seem to like passing tuples
|
|
327
|
+
// through generic params???
|
|
328
|
+
return [result, opName, modelDefinition] as any;
|
|
297
329
|
} catch (err) {
|
|
298
330
|
if (err.errors && err.errors.length > 0) {
|
|
299
331
|
const [error] = err.errors;
|
|
@@ -366,6 +398,8 @@ class MutationProcessor {
|
|
|
366
398
|
userAgentSuffix: USER_AGENT_SUFFIX_DATASTORE,
|
|
367
399
|
});
|
|
368
400
|
|
|
401
|
+
// onTerminate cancel graphql()
|
|
402
|
+
|
|
369
403
|
return [serverData, opName, modelDefinition];
|
|
370
404
|
}
|
|
371
405
|
|
|
@@ -390,7 +424,7 @@ class MutationProcessor {
|
|
|
390
424
|
throw new NonRetryableError('RetryMutation');
|
|
391
425
|
} else {
|
|
392
426
|
try {
|
|
393
|
-
|
|
427
|
+
this.errorHandler({
|
|
394
428
|
recoverySuggestion:
|
|
395
429
|
'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',
|
|
396
430
|
localModel: variables.input,
|
|
@@ -434,7 +468,8 @@ class MutationProcessor {
|
|
|
434
468
|
MutationEvent,
|
|
435
469
|
mutationEvent,
|
|
436
470
|
],
|
|
437
|
-
safeJitteredBackoff
|
|
471
|
+
safeJitteredBackoff,
|
|
472
|
+
onTerminate
|
|
438
473
|
);
|
|
439
474
|
}
|
|
440
475
|
|