@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.
Files changed (111) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/aws-amplify-datastore.js +2798 -1458
  3. package/dist/aws-amplify-datastore.js.map +1 -1
  4. package/dist/aws-amplify-datastore.min.js +10 -10
  5. package/dist/aws-amplify-datastore.min.js.map +1 -1
  6. package/lib/authModeStrategies/multiAuthStrategy.js +11 -0
  7. package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
  8. package/lib/datastore/datastore.js +524 -323
  9. package/lib/datastore/datastore.js.map +1 -1
  10. package/lib/storage/adapter/IndexedDBAdapter.js +76 -25
  11. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  12. package/lib/storage/storage.js +2 -2
  13. package/lib/storage/storage.js.map +1 -1
  14. package/lib/sync/datastoreConnectivity.js +45 -0
  15. package/lib/sync/datastoreConnectivity.js.map +1 -1
  16. package/lib/sync/index.js +518 -395
  17. package/lib/sync/index.js.map +1 -1
  18. package/lib/sync/merger.js +6 -0
  19. package/lib/sync/merger.js.map +1 -1
  20. package/lib/sync/outbox.js +66 -62
  21. package/lib/sync/outbox.js.map +1 -1
  22. package/lib/sync/processors/mutation.js +207 -165
  23. package/lib/sync/processors/mutation.js.map +1 -1
  24. package/lib/sync/processors/subscription.js +210 -175
  25. package/lib/sync/processors/subscription.js.map +1 -1
  26. package/lib/sync/processors/sync.js +95 -72
  27. package/lib/sync/processors/sync.js.map +1 -1
  28. package/lib/sync/utils.js +1 -3
  29. package/lib/sync/utils.js.map +1 -1
  30. package/lib/util.js +89 -0
  31. package/lib/util.js.map +1 -1
  32. package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +11 -0
  33. package/lib-esm/authModeStrategies/multiAuthStrategy.js +11 -0
  34. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
  35. package/lib-esm/datastore/datastore.d.ts +95 -2
  36. package/lib-esm/datastore/datastore.js +524 -323
  37. package/lib-esm/datastore/datastore.js.map +1 -1
  38. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +21 -0
  39. package/lib-esm/storage/adapter/IndexedDBAdapter.js +77 -26
  40. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  41. package/lib-esm/storage/storage.js +2 -2
  42. package/lib-esm/storage/storage.js.map +1 -1
  43. package/lib-esm/sync/datastoreConnectivity.d.ts +1 -0
  44. package/lib-esm/sync/datastoreConnectivity.js +45 -0
  45. package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
  46. package/lib-esm/sync/index.d.ts +9 -1
  47. package/lib-esm/sync/index.js +519 -396
  48. package/lib-esm/sync/index.js.map +1 -1
  49. package/lib-esm/sync/merger.d.ts +6 -0
  50. package/lib-esm/sync/merger.js +6 -0
  51. package/lib-esm/sync/merger.js.map +1 -1
  52. package/lib-esm/sync/outbox.js +66 -62
  53. package/lib-esm/sync/outbox.js.map +1 -1
  54. package/lib-esm/sync/processors/mutation.d.ts +2 -0
  55. package/lib-esm/sync/processors/mutation.js +208 -166
  56. package/lib-esm/sync/processors/mutation.js.map +1 -1
  57. package/lib-esm/sync/processors/subscription.d.ts +2 -0
  58. package/lib-esm/sync/processors/subscription.js +211 -176
  59. package/lib-esm/sync/processors/subscription.js.map +1 -1
  60. package/lib-esm/sync/processors/sync.d.ts +2 -0
  61. package/lib-esm/sync/processors/sync.js +96 -73
  62. package/lib-esm/sync/processors/sync.js.map +1 -1
  63. package/lib-esm/sync/utils.js +1 -3
  64. package/lib-esm/sync/utils.js.map +1 -1
  65. package/lib-esm/util.d.ts +11 -0
  66. package/lib-esm/util.js +89 -0
  67. package/lib-esm/util.js.map +1 -1
  68. package/package.json +7 -7
  69. package/src/authModeStrategies/multiAuthStrategy.ts +11 -0
  70. package/src/datastore/datastore.ts +572 -366
  71. package/src/storage/adapter/IndexedDBAdapter.ts +50 -9
  72. package/src/storage/storage.ts +2 -2
  73. package/src/sync/datastoreConnectivity.ts +6 -0
  74. package/src/sync/index.ts +492 -400
  75. package/src/sync/merger.ts +6 -0
  76. package/src/sync/outbox.ts +1 -1
  77. package/src/sync/processors/mutation.ts +139 -104
  78. package/src/sync/processors/subscription.ts +287 -250
  79. package/src/sync/processors/sync.ts +88 -60
  80. package/src/sync/utils.ts +1 -3
  81. package/src/util.ts +92 -2
  82. package/lib/authModeStrategies/defaultAuthStrategy.d.ts +0 -2
  83. package/lib/authModeStrategies/index.d.ts +0 -2
  84. package/lib/authModeStrategies/multiAuthStrategy.d.ts +0 -2
  85. package/lib/datastore/datastore.d.ts +0 -63
  86. package/lib/index.d.ts +0 -15
  87. package/lib/predicates/index.d.ts +0 -16
  88. package/lib/predicates/sort.d.ts +0 -8
  89. package/lib/ssr/index.d.ts +0 -3
  90. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +0 -41
  91. package/lib/storage/adapter/AsyncStorageDatabase.d.ts +0 -39
  92. package/lib/storage/adapter/InMemoryStore.d.ts +0 -11
  93. package/lib/storage/adapter/InMemoryStore.native.d.ts +0 -1
  94. package/lib/storage/adapter/IndexedDBAdapter.d.ts +0 -38
  95. package/lib/storage/adapter/getDefaultAdapter/index.d.ts +0 -3
  96. package/lib/storage/adapter/getDefaultAdapter/index.native.d.ts +0 -3
  97. package/lib/storage/adapter/index.d.ts +0 -9
  98. package/lib/storage/storage.d.ts +0 -49
  99. package/lib/sync/datastoreConnectivity.d.ts +0 -15
  100. package/lib/sync/datastoreReachability/index.d.ts +0 -3
  101. package/lib/sync/datastoreReachability/index.native.d.ts +0 -3
  102. package/lib/sync/index.d.ts +0 -81
  103. package/lib/sync/merger.d.ts +0 -11
  104. package/lib/sync/outbox.d.ts +0 -27
  105. package/lib/sync/processors/errorMaps.d.ts +0 -17
  106. package/lib/sync/processors/mutation.d.ts +0 -56
  107. package/lib/sync/processors/subscription.d.ts +0 -31
  108. package/lib/sync/processors/sync.d.ts +0 -26
  109. package/lib/sync/utils.d.ts +0 -42
  110. package/lib/types.d.ts +0 -501
  111. package/lib/util.d.ts +0 -145
@@ -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,
@@ -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
- this.resume();
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 resume(): Promise<void> {
132
- if (this.processing || !this.isReady()) {
133
- return;
134
- }
139
+ public async stop() {
140
+ await this.runningProcesses.close();
141
+ await this.runningProcesses.open();
142
+ }
135
143
 
136
- this.processing = true;
137
- let head: MutationEvent;
138
- const namespaceName = USER;
139
-
140
- // start to drain outbox
141
- while (
142
- this.processing &&
143
- (head = await this.outbox.peek(this.storage)) !== undefined
144
- ) {
145
- const { model, operation, data, condition } = head;
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
- const operationAuthModes = modelAuthModes[operation.toUpperCase()];
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
- logger.debug(
166
- `Attempting mutation with authMode: ${operationAuthModes[authModeAttempts]}`
167
- );
168
- const response = await this.jitteredRetry(
169
- namespaceName,
170
- model,
171
- operation,
172
- data,
173
- condition,
174
- modelConstructor,
175
- this.MutationEvent,
176
- head,
177
- operationAuthModes[authModeAttempts]
178
- );
179
-
180
- logger.debug(
181
- `Mutation sent successfully with authMode: ${operationAuthModes[authModeAttempts]}`
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
- return response;
229
+ [result, opName, modelDefinition] = await authModeRetry();
185
230
  } catch (error) {
186
- authModeAttempts++;
187
- if (authModeAttempts >= operationAuthModes.length) {
188
- logger.debug(
189
- `Mutation failed with authMode: ${
190
- operationAuthModes[authModeAttempts - 1]
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
- if (result === undefined) {
214
- logger.debug('done retrying');
215
- await this.storage.runExclusive(async storage => {
216
- await this.outbox.dequeue(storage);
217
- });
218
- continue;
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
- const record = result.data[opName];
222
- let hasMore = false;
247
+ const record = result.data[opName];
248
+ let hasMore = false;
223
249
 
224
- await this.storage.runExclusive(async storage => {
225
- // using runExclusive to prevent possible race condition
226
- // when another record gets enqueued between dequeue and peek
227
- await this.outbox.dequeue(storage, record, operation);
228
- hasMore = (await this.outbox.peek(storage)) !== undefined;
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
- this.observer.next({
232
- operation,
233
- modelDefinition,
234
- model: record,
235
- hasMore,
236
- });
237
- }
257
+ this.observer.next({
258
+ operation,
259
+ modelDefinition,
260
+ model: record,
261
+ hasMore,
262
+ });
263
+ }
238
264
 
239
- // pauses itself
240
- this.pause();
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
- return [result, opName, modelDefinition];
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
- await this.errorHandler({
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