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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +4 -0
  2. package/lib/authModeStrategies/defaultAuthStrategy.js +3 -2
  3. package/lib/authModeStrategies/index.js +3 -3
  4. package/lib/authModeStrategies/multiAuthStrategy.js +38 -53
  5. package/lib/datastore/datastore.d.ts +4 -5
  6. package/lib/datastore/datastore.js +929 -1284
  7. package/lib/index.d.ts +1 -1
  8. package/lib/index.js +26 -13
  9. package/lib/predicates/index.js +54 -69
  10. package/lib/predicates/next.d.ts +2 -2
  11. package/lib/predicates/next.js +313 -462
  12. package/lib/predicates/sort.js +24 -28
  13. package/lib/ssr/index.js +2 -2
  14. package/lib/storage/adapter/AsyncStorageAdapter.js +120 -342
  15. package/lib/storage/adapter/AsyncStorageDatabase.js +217 -421
  16. package/lib/storage/adapter/InMemoryStore.js +28 -51
  17. package/lib/storage/adapter/InMemoryStore.native.js +5 -3
  18. package/lib/storage/adapter/IndexedDBAdapter.js +466 -871
  19. package/lib/storage/adapter/StorageAdapterBase.js +180 -330
  20. package/lib/storage/adapter/getDefaultAdapter/index.js +8 -10
  21. package/lib/storage/adapter/getDefaultAdapter/index.native.js +5 -4
  22. package/lib/storage/adapter/index.js +0 -1
  23. package/lib/storage/relationship.js +177 -253
  24. package/lib/storage/storage.d.ts +4 -4
  25. package/lib/storage/storage.js +255 -433
  26. package/lib/sync/datastoreConnectivity.d.ts +2 -2
  27. package/lib/sync/datastoreConnectivity.js +29 -39
  28. package/lib/sync/datastoreReachability/index.d.ts +1 -3
  29. package/lib/sync/datastoreReachability/index.js +3 -3
  30. package/lib/sync/datastoreReachability/index.native.d.ts +1 -3
  31. package/lib/sync/datastoreReachability/index.native.js +4 -5
  32. package/lib/sync/index.d.ts +2 -2
  33. package/lib/sync/index.js +522 -827
  34. package/lib/sync/merger.js +31 -63
  35. package/lib/sync/outbox.js +148 -232
  36. package/lib/sync/processors/errorMaps.d.ts +1 -1
  37. package/lib/sync/processors/errorMaps.js +30 -47
  38. package/lib/sync/processors/mutation.d.ts +2 -2
  39. package/lib/sync/processors/mutation.js +343 -502
  40. package/lib/sync/processors/subscription.d.ts +5 -2
  41. package/lib/sync/processors/subscription.js +283 -437
  42. package/lib/sync/processors/sync.d.ts +2 -2
  43. package/lib/sync/processors/sync.js +279 -404
  44. package/lib/sync/utils.d.ts +5 -4
  45. package/lib/sync/utils.js +267 -320
  46. package/lib/tsconfig.tsbuildinfo +1 -0
  47. package/lib/types.d.ts +138 -140
  48. package/lib/types.js +17 -24
  49. package/lib/util.d.ts +9 -17
  50. package/lib/util.js +387 -511
  51. package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -2
  52. package/lib-esm/authModeStrategies/index.js +0 -1
  53. package/lib-esm/authModeStrategies/multiAuthStrategy.js +35 -52
  54. package/lib-esm/datastore/datastore.d.ts +4 -5
  55. package/lib-esm/datastore/datastore.js +888 -1247
  56. package/lib-esm/index.d.ts +1 -1
  57. package/lib-esm/index.js +6 -7
  58. package/lib-esm/predicates/index.js +53 -70
  59. package/lib-esm/predicates/next.d.ts +2 -2
  60. package/lib-esm/predicates/next.js +306 -459
  61. package/lib-esm/predicates/sort.js +23 -28
  62. package/lib-esm/ssr/index.js +1 -2
  63. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -338
  64. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -416
  65. package/lib-esm/storage/adapter/InMemoryStore.js +27 -52
  66. package/lib-esm/storage/adapter/InMemoryStore.native.js +0 -1
  67. package/lib-esm/storage/adapter/IndexedDBAdapter.js +438 -866
  68. package/lib-esm/storage/adapter/StorageAdapterBase.js +173 -325
  69. package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -6
  70. package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -2
  71. package/lib-esm/storage/adapter/index.js +1 -1
  72. package/lib-esm/storage/relationship.js +173 -251
  73. package/lib-esm/storage/storage.d.ts +4 -4
  74. package/lib-esm/storage/storage.js +242 -424
  75. package/lib-esm/sync/datastoreConnectivity.d.ts +2 -2
  76. package/lib-esm/sync/datastoreConnectivity.js +28 -39
  77. package/lib-esm/sync/datastoreReachability/index.d.ts +1 -3
  78. package/lib-esm/sync/datastoreReachability/index.js +2 -3
  79. package/lib-esm/sync/datastoreReachability/index.native.d.ts +1 -3
  80. package/lib-esm/sync/datastoreReachability/index.native.js +3 -4
  81. package/lib-esm/sync/index.d.ts +2 -2
  82. package/lib-esm/sync/index.js +502 -812
  83. package/lib-esm/sync/merger.js +28 -61
  84. package/lib-esm/sync/outbox.js +143 -228
  85. package/lib-esm/sync/processors/errorMaps.d.ts +1 -1
  86. package/lib-esm/sync/processors/errorMaps.js +32 -50
  87. package/lib-esm/sync/processors/mutation.d.ts +2 -2
  88. package/lib-esm/sync/processors/mutation.js +329 -490
  89. package/lib-esm/sync/processors/subscription.d.ts +5 -2
  90. package/lib-esm/sync/processors/subscription.js +266 -421
  91. package/lib-esm/sync/processors/sync.d.ts +2 -2
  92. package/lib-esm/sync/processors/sync.js +271 -397
  93. package/lib-esm/sync/utils.d.ts +5 -4
  94. package/lib-esm/sync/utils.js +252 -307
  95. package/lib-esm/tsconfig.tsbuildinfo +1 -0
  96. package/lib-esm/types.d.ts +138 -140
  97. package/lib-esm/types.js +16 -25
  98. package/lib-esm/util.d.ts +9 -17
  99. package/lib-esm/util.js +335 -497
  100. package/package.json +31 -26
  101. package/src/authModeStrategies/multiAuthStrategy.ts +15 -12
  102. package/src/datastore/datastore.ts +36 -35
  103. package/src/predicates/sort.ts +3 -1
  104. package/src/storage/adapter/InMemoryStore.ts +1 -1
  105. package/src/storage/adapter/IndexedDBAdapter.ts +2 -2
  106. package/src/storage/adapter/StorageAdapterBase.ts +2 -2
  107. package/src/storage/adapter/getDefaultAdapter/index.ts +1 -4
  108. package/src/storage/storage.ts +29 -24
  109. package/src/sync/datastoreConnectivity.ts +6 -6
  110. package/src/sync/datastoreReachability/index.native.ts +5 -3
  111. package/src/sync/datastoreReachability/index.ts +1 -1
  112. package/src/sync/index.ts +79 -89
  113. package/src/sync/processors/errorMaps.ts +7 -7
  114. package/src/sync/processors/mutation.ts +19 -13
  115. package/src/sync/processors/subscription.ts +221 -295
  116. package/src/sync/processors/sync.ts +11 -8
  117. package/src/sync/utils.ts +30 -15
  118. package/src/types.ts +4 -8
  119. package/src/util.ts +46 -9
  120. package/lib/.tsbuildinfo +0 -3
  121. package/lib/authModeStrategies/defaultAuthStrategy.js.map +0 -1
  122. package/lib/authModeStrategies/index.js.map +0 -1
  123. package/lib/authModeStrategies/multiAuthStrategy.js.map +0 -1
  124. package/lib/datastore/datastore.js.map +0 -1
  125. package/lib/index.js.map +0 -1
  126. package/lib/predicates/index.js.map +0 -1
  127. package/lib/predicates/next.js.map +0 -1
  128. package/lib/predicates/sort.js.map +0 -1
  129. package/lib/ssr/index.js.map +0 -1
  130. package/lib/storage/adapter/AsyncStorageAdapter.js.map +0 -1
  131. package/lib/storage/adapter/AsyncStorageDatabase.js.map +0 -1
  132. package/lib/storage/adapter/InMemoryStore.js.map +0 -1
  133. package/lib/storage/adapter/InMemoryStore.native.js.map +0 -1
  134. package/lib/storage/adapter/IndexedDBAdapter.js.map +0 -1
  135. package/lib/storage/adapter/StorageAdapterBase.js.map +0 -1
  136. package/lib/storage/adapter/getDefaultAdapter/index.js.map +0 -1
  137. package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
  138. package/lib/storage/adapter/index.js.map +0 -1
  139. package/lib/storage/relationship.js.map +0 -1
  140. package/lib/storage/storage.js.map +0 -1
  141. package/lib/sync/datastoreConnectivity.js.map +0 -1
  142. package/lib/sync/datastoreReachability/index.js.map +0 -1
  143. package/lib/sync/datastoreReachability/index.native.js.map +0 -1
  144. package/lib/sync/index.js.map +0 -1
  145. package/lib/sync/merger.js.map +0 -1
  146. package/lib/sync/outbox.js.map +0 -1
  147. package/lib/sync/processors/errorMaps.js.map +0 -1
  148. package/lib/sync/processors/mutation.js.map +0 -1
  149. package/lib/sync/processors/subscription.js.map +0 -1
  150. package/lib/sync/processors/sync.js.map +0 -1
  151. package/lib/sync/utils.js.map +0 -1
  152. package/lib/types.js.map +0 -1
  153. package/lib/util.js.map +0 -1
  154. package/lib-esm/.tsbuildinfo +0 -3
  155. package/lib-esm/authModeStrategies/defaultAuthStrategy.js.map +0 -1
  156. package/lib-esm/authModeStrategies/index.js.map +0 -1
  157. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +0 -1
  158. package/lib-esm/datastore/datastore.js.map +0 -1
  159. package/lib-esm/index.js.map +0 -1
  160. package/lib-esm/predicates/index.js.map +0 -1
  161. package/lib-esm/predicates/next.js.map +0 -1
  162. package/lib-esm/predicates/sort.js.map +0 -1
  163. package/lib-esm/ssr/index.js.map +0 -1
  164. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +0 -1
  165. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +0 -1
  166. package/lib-esm/storage/adapter/InMemoryStore.js.map +0 -1
  167. package/lib-esm/storage/adapter/InMemoryStore.native.js.map +0 -1
  168. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +0 -1
  169. package/lib-esm/storage/adapter/StorageAdapterBase.js.map +0 -1
  170. package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +0 -1
  171. package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
  172. package/lib-esm/storage/adapter/index.js.map +0 -1
  173. package/lib-esm/storage/relationship.js.map +0 -1
  174. package/lib-esm/storage/storage.js.map +0 -1
  175. package/lib-esm/sync/datastoreConnectivity.js.map +0 -1
  176. package/lib-esm/sync/datastoreReachability/index.js.map +0 -1
  177. package/lib-esm/sync/datastoreReachability/index.native.js.map +0 -1
  178. package/lib-esm/sync/index.js.map +0 -1
  179. package/lib-esm/sync/merger.js.map +0 -1
  180. package/lib-esm/sync/outbox.js.map +0 -1
  181. package/lib-esm/sync/processors/errorMaps.js.map +0 -1
  182. package/lib-esm/sync/processors/mutation.js.map +0 -1
  183. package/lib-esm/sync/processors/subscription.js.map +0 -1
  184. package/lib-esm/sync/processors/sync.js.map +0 -1
  185. package/lib-esm/sync/utils.js.map +0 -1
  186. package/lib-esm/types.js.map +0 -1
  187. package/lib-esm/util.js.map +0 -1
@@ -1,20 +1,19 @@
1
- import { __awaiter, __generator, __read, __values } from "tslib";
2
1
  import { InternalAPI } from '@aws-amplify/api/internals';
3
- import Observable from 'zen-observable-ts';
2
+ import { Observable } from 'rxjs';
4
3
  import { ProcessName, } from '../../types';
5
4
  import { buildGraphQLOperation, getModelAuthModes, getClientSideAuthError, getForbiddenError, predicateToGraphQLFilter, getTokenForCustomAuth, } from '../utils';
6
- import { jitteredExponentialRetry, Category, ConsoleLogger as Logger, DataStoreAction, Hub, NonRetryableError, BackgroundProcessManager, } from '@aws-amplify/core';
5
+ import { jitteredExponentialRetry, Category, DataStoreAction, NonRetryableError, BackgroundProcessManager, } from '@aws-amplify/core/internals/utils';
6
+ import { ConsoleLogger, Hub } from '@aws-amplify/core';
7
7
  import { ModelPredicateCreator } from '../../predicates';
8
8
  import { getSyncErrorType } from './errorMaps';
9
- var opResultDefaults = {
9
+ const opResultDefaults = {
10
10
  items: [],
11
11
  nextToken: null,
12
12
  startedAt: null,
13
13
  };
14
- var logger = new Logger('DataStore');
15
- var SyncProcessor = /** @class */ (function () {
16
- function SyncProcessor(schema, syncPredicates, amplifyConfig, authModeStrategy, errorHandler, amplifyContext) {
17
- if (amplifyConfig === void 0) { amplifyConfig = {}; }
14
+ const logger = new ConsoleLogger('DataStore');
15
+ class SyncProcessor {
16
+ constructor(schema, syncPredicates, amplifyConfig = {}, authModeStrategy, errorHandler, amplifyContext) {
18
17
  this.schema = schema;
19
18
  this.syncPredicates = syncPredicates;
20
19
  this.amplifyConfig = amplifyConfig;
@@ -26,417 +25,292 @@ var SyncProcessor = /** @class */ (function () {
26
25
  amplifyContext.InternalAPI = amplifyContext.InternalAPI || InternalAPI;
27
26
  this.generateQueries();
28
27
  }
29
- SyncProcessor.prototype.generateQueries = function () {
30
- var _this = this;
31
- Object.values(this.schema.namespaces).forEach(function (namespace) {
28
+ generateQueries() {
29
+ Object.values(this.schema.namespaces).forEach(namespace => {
32
30
  Object.values(namespace.models)
33
- .filter(function (_a) {
34
- var syncable = _a.syncable;
35
- return syncable;
36
- })
37
- .forEach(function (model) {
38
- var _a = __read(buildGraphQLOperation(namespace, model, 'LIST'), 1), _b = __read(_a[0]), opNameQuery = _b.slice(1);
39
- _this.typeQuery.set(model, opNameQuery);
31
+ .filter(({ syncable }) => syncable)
32
+ .forEach(model => {
33
+ const [[, ...opNameQuery]] = buildGraphQLOperation(namespace, model, 'LIST');
34
+ this.typeQuery.set(model, opNameQuery);
40
35
  });
41
36
  });
42
- };
43
- SyncProcessor.prototype.graphqlFilterFromPredicate = function (model) {
37
+ }
38
+ graphqlFilterFromPredicate(model) {
44
39
  if (!this.syncPredicates) {
45
40
  return null;
46
41
  }
47
- var predicatesGroup = ModelPredicateCreator.getPredicates(this.syncPredicates.get(model), false);
42
+ const predicatesGroup = ModelPredicateCreator.getPredicates(this.syncPredicates.get(model), false);
48
43
  if (!predicatesGroup) {
49
44
  return null;
50
45
  }
51
46
  return predicateToGraphQLFilter(predicatesGroup);
52
- };
53
- SyncProcessor.prototype.retrievePage = function (modelDefinition, lastSync, nextToken, limit, filter, onTerminate) {
54
- if (limit === void 0) { limit = null; }
55
- return __awaiter(this, void 0, void 0, function () {
56
- var _a, opName, query, variables, modelAuthModes, readAuthModes, authModeAttempts, authModeRetry, data, _b, _c, opResult, items, newNextToken, startedAt;
57
- var _this = this;
58
- return __generator(this, function (_d) {
59
- switch (_d.label) {
60
- case 0:
61
- _a = __read(this.typeQuery.get(modelDefinition), 2), opName = _a[0], query = _a[1];
62
- variables = {
63
- limit: limit,
64
- nextToken: nextToken,
65
- lastSync: lastSync,
66
- filter: filter,
47
+ }
48
+ async retrievePage(modelDefinition, lastSync, nextToken, limit = null, filter, onTerminate) {
49
+ const [opName, query] = this.typeQuery.get(modelDefinition);
50
+ const variables = {
51
+ limit,
52
+ nextToken,
53
+ lastSync,
54
+ filter,
55
+ };
56
+ const modelAuthModes = await getModelAuthModes({
57
+ authModeStrategy: this.authModeStrategy,
58
+ defaultAuthMode: this.amplifyConfig.aws_appsync_authenticationType,
59
+ modelName: modelDefinition.name,
60
+ schema: this.schema,
61
+ });
62
+ // sync only needs the READ auth mode(s)
63
+ const readAuthModes = modelAuthModes.READ;
64
+ let authModeAttempts = 0;
65
+ const authModeRetry = async () => {
66
+ if (!this.runningProcesses.isOpen) {
67
+ throw new Error('sync.retreievePage termination was requested. Exiting.');
68
+ }
69
+ try {
70
+ logger.debug(`Attempting sync with authMode: ${readAuthModes[authModeAttempts]}`);
71
+ const response = await this.jitteredRetry({
72
+ query,
73
+ variables,
74
+ opName,
75
+ modelDefinition,
76
+ authMode: readAuthModes[authModeAttempts],
77
+ onTerminate,
78
+ });
79
+ logger.debug(`Sync successful with authMode: ${readAuthModes[authModeAttempts]}`);
80
+ return response;
81
+ }
82
+ catch (error) {
83
+ authModeAttempts++;
84
+ if (authModeAttempts >= readAuthModes.length) {
85
+ const authMode = readAuthModes[authModeAttempts - 1];
86
+ logger.debug(`Sync failed with authMode: ${authMode}`, error);
87
+ if (getClientSideAuthError(error) || getForbiddenError(error)) {
88
+ // return empty list of data so DataStore will continue to sync other models
89
+ logger.warn(`User is unauthorized to query ${opName} with auth mode ${authMode}. No data could be returned.`);
90
+ return {
91
+ data: {
92
+ [opName]: opResultDefaults,
93
+ },
67
94
  };
68
- return [4 /*yield*/, getModelAuthModes({
69
- authModeStrategy: this.authModeStrategy,
70
- defaultAuthMode: this.amplifyConfig.aws_appsync_authenticationType,
71
- modelName: modelDefinition.name,
72
- schema: this.schema,
73
- })];
74
- case 1:
75
- modelAuthModes = _d.sent();
76
- readAuthModes = modelAuthModes.READ;
77
- authModeAttempts = 0;
78
- authModeRetry = function () { return __awaiter(_this, void 0, void 0, function () {
79
- var response, error_1, authMode;
80
- var _a;
81
- return __generator(this, function (_b) {
82
- switch (_b.label) {
83
- case 0:
84
- if (!this.runningProcesses.isOpen) {
85
- throw new Error('sync.retreievePage termination was requested. Exiting.');
86
- }
87
- _b.label = 1;
88
- case 1:
89
- _b.trys.push([1, 3, , 5]);
90
- logger.debug("Attempting sync with authMode: " + readAuthModes[authModeAttempts]);
91
- return [4 /*yield*/, this.jitteredRetry({
92
- query: query,
93
- variables: variables,
94
- opName: opName,
95
- modelDefinition: modelDefinition,
96
- authMode: readAuthModes[authModeAttempts],
97
- onTerminate: onTerminate,
98
- })];
99
- case 2:
100
- response = _b.sent();
101
- logger.debug("Sync successful with authMode: " + readAuthModes[authModeAttempts]);
102
- return [2 /*return*/, response];
103
- case 3:
104
- error_1 = _b.sent();
105
- authModeAttempts++;
106
- if (authModeAttempts >= readAuthModes.length) {
107
- authMode = readAuthModes[authModeAttempts - 1];
108
- logger.debug("Sync failed with authMode: " + authMode, error_1);
109
- if (getClientSideAuthError(error_1) || getForbiddenError(error_1)) {
110
- // return empty list of data so DataStore will continue to sync other models
111
- logger.warn("User is unauthorized to query " + opName + " with auth mode " + authMode + ". No data could be returned.");
112
- return [2 /*return*/, {
113
- data: (_a = {},
114
- _a[opName] = opResultDefaults,
115
- _a),
116
- }];
117
- }
118
- throw error_1;
119
- }
120
- logger.debug("Sync failed with authMode: " + readAuthModes[authModeAttempts - 1] + ". Retrying with authMode: " + readAuthModes[authModeAttempts]);
121
- return [4 /*yield*/, authModeRetry()];
122
- case 4: return [2 /*return*/, _b.sent()];
123
- case 5: return [2 /*return*/];
124
- }
125
- });
126
- }); };
127
- return [4 /*yield*/, authModeRetry()];
128
- case 2:
129
- data = (_d.sent()).data;
130
- _b = data, _c = opName, opResult = _b[_c];
131
- items = opResult.items, newNextToken = opResult.nextToken, startedAt = opResult.startedAt;
132
- return [2 /*return*/, {
133
- nextToken: newNextToken,
134
- startedAt: startedAt,
135
- items: items,
136
- }];
95
+ }
96
+ throw error;
137
97
  }
138
- });
139
- });
140
- };
141
- SyncProcessor.prototype.jitteredRetry = function (_a) {
142
- var query = _a.query, variables = _a.variables, opName = _a.opName, modelDefinition = _a.modelDefinition, authMode = _a.authMode, onTerminate = _a.onTerminate;
143
- return __awaiter(this, void 0, void 0, function () {
144
- var _this = this;
145
- return __generator(this, function (_b) {
146
- switch (_b.label) {
147
- case 0: return [4 /*yield*/, jitteredExponentialRetry(function (query, variables) { return __awaiter(_this, void 0, void 0, function () {
148
- var authToken, customUserAgentDetails, error_2, clientOrForbiddenErrorMessage, hasItems, unauthorized, otherErrors, result;
149
- var _this = this;
150
- var _a, _b, _c, _d;
151
- return __generator(this, function (_e) {
152
- switch (_e.label) {
153
- case 0:
154
- _e.trys.push([0, 3, , 6]);
155
- return [4 /*yield*/, getTokenForCustomAuth(authMode, this.amplifyConfig)];
156
- case 1:
157
- authToken = _e.sent();
158
- customUserAgentDetails = {
159
- category: Category.DataStore,
160
- action: DataStoreAction.GraphQl,
161
- };
162
- return [4 /*yield*/, this.amplifyContext.InternalAPI.graphql({
163
- query: query,
164
- variables: variables,
165
- authMode: authMode,
166
- authToken: authToken,
167
- }, undefined, customUserAgentDetails)];
168
- case 2: return [2 /*return*/, _e.sent()];
169
- case 3:
170
- error_2 = _e.sent();
171
- clientOrForbiddenErrorMessage = getClientSideAuthError(error_2) || getForbiddenError(error_2);
172
- if (clientOrForbiddenErrorMessage) {
173
- logger.error('Sync processor retry error:', error_2);
174
- throw new NonRetryableError(clientOrForbiddenErrorMessage);
175
- }
176
- hasItems = Boolean((_b = (_a = error_2 === null || error_2 === void 0 ? void 0 : error_2.data) === null || _a === void 0 ? void 0 : _a[opName]) === null || _b === void 0 ? void 0 : _b.items);
177
- unauthorized = (error_2 === null || error_2 === void 0 ? void 0 : error_2.errors) &&
178
- error_2.errors.some(function (err) { return err.errorType === 'Unauthorized'; });
179
- otherErrors = (error_2 === null || error_2 === void 0 ? void 0 : error_2.errors) &&
180
- error_2.errors.filter(function (err) { return err.errorType !== 'Unauthorized'; });
181
- result = error_2;
182
- if (hasItems) {
183
- result.data[opName].items = result.data[opName].items.filter(function (item) { return item !== null; });
184
- }
185
- if (!(hasItems && (otherErrors === null || otherErrors === void 0 ? void 0 : otherErrors.length))) return [3 /*break*/, 5];
186
- return [4 /*yield*/, Promise.all(otherErrors.map(function (err) { return __awaiter(_this, void 0, void 0, function () {
187
- var e_1;
188
- return __generator(this, function (_a) {
189
- switch (_a.label) {
190
- case 0:
191
- _a.trys.push([0, 2, , 3]);
192
- return [4 /*yield*/, this.errorHandler({
193
- 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',
194
- localModel: null,
195
- message: err.message,
196
- model: modelDefinition.name,
197
- operation: opName,
198
- errorType: getSyncErrorType(err),
199
- process: ProcessName.sync,
200
- remoteModel: null,
201
- cause: err,
202
- })];
203
- case 1:
204
- _a.sent();
205
- return [3 /*break*/, 3];
206
- case 2:
207
- e_1 = _a.sent();
208
- logger.error('Sync error handler failed with:', e_1);
209
- return [3 /*break*/, 3];
210
- case 3: return [2 /*return*/];
211
- }
212
- });
213
- }); }))];
214
- case 4:
215
- _e.sent();
216
- Hub.dispatch('datastore', {
217
- event: 'nonApplicableDataReceived',
218
- data: {
219
- errors: otherErrors,
220
- modelName: modelDefinition.name,
221
- },
222
- });
223
- _e.label = 5;
224
- case 5:
225
- /**
226
- * Handle $util.unauthorized() in resolver request mapper, which responses with something
227
- * like this:
228
- *
229
- * ```
230
- * {
231
- * data: { syncYourModel: null },
232
- * errors: [
233
- * {
234
- * path: ['syncLegacyJSONComments'],
235
- * data: null,
236
- * errorType: 'Unauthorized',
237
- * errorInfo: null,
238
- * locations: [{ line: 2, column: 3, sourceName: null }],
239
- * message:
240
- * 'Not Authorized to access syncYourModel on type Query',
241
- * },
242
- * ],
243
- * }
244
- * ```
245
- *
246
- * The correct handling for this is to signal that we've encountered a non-retryable error,
247
- * since the server has responded with an auth error and *NO DATA* at this point.
248
- */
249
- if (unauthorized) {
250
- this.errorHandler({
251
- 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',
252
- localModel: null,
253
- message: error_2.message,
254
- model: modelDefinition.name,
255
- operation: opName,
256
- errorType: getSyncErrorType(error_2.errors[0]),
257
- process: ProcessName.sync,
258
- remoteModel: null,
259
- cause: error_2,
260
- });
261
- throw new NonRetryableError(error_2);
262
- }
263
- if ((_d = (_c = result.data) === null || _c === void 0 ? void 0 : _c[opName].items) === null || _d === void 0 ? void 0 : _d.length) {
264
- return [2 /*return*/, result];
265
- }
266
- throw error_2;
267
- case 6: return [2 /*return*/];
268
- }
98
+ logger.debug(`Sync failed with authMode: ${readAuthModes[authModeAttempts - 1]}. Retrying with authMode: ${readAuthModes[authModeAttempts]}`);
99
+ return await authModeRetry();
100
+ }
101
+ };
102
+ const { data } = await authModeRetry();
103
+ const { [opName]: opResult } = data;
104
+ const { items, nextToken: newNextToken, startedAt } = opResult;
105
+ return {
106
+ nextToken: newNextToken,
107
+ startedAt,
108
+ items,
109
+ };
110
+ }
111
+ async jitteredRetry({ query, variables, opName, modelDefinition, authMode, onTerminate, }) {
112
+ return await jitteredExponentialRetry(async (query, variables) => {
113
+ try {
114
+ const authToken = await getTokenForCustomAuth(authMode, this.amplifyConfig);
115
+ const customUserAgentDetails = {
116
+ category: Category.DataStore,
117
+ action: DataStoreAction.GraphQl,
118
+ };
119
+ return await this.amplifyContext.InternalAPI.graphql({
120
+ query,
121
+ variables,
122
+ authMode,
123
+ authToken,
124
+ }, undefined, customUserAgentDetails);
125
+ // TODO: onTerminate.then(() => API.cancel(...))
126
+ }
127
+ catch (error) {
128
+ // Catch client-side (GraphQLAuthError) & 401/403 errors here so that we don't continue to retry
129
+ const clientOrForbiddenErrorMessage = getClientSideAuthError(error) || getForbiddenError(error);
130
+ if (clientOrForbiddenErrorMessage) {
131
+ logger.error('Sync processor retry error:', error);
132
+ throw new NonRetryableError(clientOrForbiddenErrorMessage);
133
+ }
134
+ const hasItems = Boolean(error?.data?.[opName]?.items);
135
+ const unauthorized = error?.errors &&
136
+ error.errors.some(err => err.errorType === 'Unauthorized');
137
+ const otherErrors = error?.errors &&
138
+ error.errors.filter(err => err.errorType !== 'Unauthorized');
139
+ const result = error;
140
+ if (hasItems) {
141
+ result.data[opName].items = result.data[opName].items.filter(item => item !== null);
142
+ }
143
+ if (hasItems && otherErrors?.length) {
144
+ await Promise.all(otherErrors.map(async (err) => {
145
+ try {
146
+ await this.errorHandler({
147
+ 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',
148
+ localModel: null,
149
+ message: err.message,
150
+ model: modelDefinition.name,
151
+ operation: opName,
152
+ errorType: getSyncErrorType(err),
153
+ process: ProcessName.sync,
154
+ remoteModel: null,
155
+ cause: err,
269
156
  });
270
- }); }, [query, variables], undefined, onTerminate)];
271
- case 1: return [2 /*return*/, _b.sent()];
157
+ }
158
+ catch (e) {
159
+ logger.error('Sync error handler failed with:', e);
160
+ }
161
+ }));
162
+ Hub.dispatch('datastore', {
163
+ event: 'nonApplicableDataReceived',
164
+ data: {
165
+ errors: otherErrors,
166
+ modelName: modelDefinition.name,
167
+ },
168
+ });
272
169
  }
273
- });
274
- });
275
- };
276
- SyncProcessor.prototype.start = function (typesLastSync) {
277
- var _this = this;
278
- var _a = this.amplifyConfig, maxRecordsToSync = _a.maxRecordsToSync, syncPageSize = _a.syncPageSize;
279
- var parentPromises = new Map();
280
- var observable = new Observable(function (observer) {
281
- var sortedTypesLastSyncs = Object.values(_this.schema.namespaces).reduce(function (map, namespace) {
282
- var e_2, _a;
283
- try {
284
- for (var _b = __values(Array.from(namespace.modelTopologicalOrdering.keys())), _c = _b.next(); !_c.done; _c = _b.next()) {
285
- var modelName = _c.value;
286
- var typeLastSync = typesLastSync.get(namespace.models[modelName]);
287
- map.set(namespace.models[modelName], typeLastSync);
288
- }
170
+ /**
171
+ * Handle $util.unauthorized() in resolver request mapper, which responses with something
172
+ * like this:
173
+ *
174
+ * ```
175
+ * {
176
+ * data: { syncYourModel: null },
177
+ * errors: [
178
+ * {
179
+ * path: ['syncLegacyJSONComments'],
180
+ * data: null,
181
+ * errorType: 'Unauthorized',
182
+ * errorInfo: null,
183
+ * locations: [{ line: 2, column: 3, sourceName: null }],
184
+ * message:
185
+ * 'Not Authorized to access syncYourModel on type Query',
186
+ * },
187
+ * ],
188
+ * }
189
+ * ```
190
+ *
191
+ * The correct handling for this is to signal that we've encountered a non-retryable error,
192
+ * since the server has responded with an auth error and *NO DATA* at this point.
193
+ */
194
+ if (unauthorized) {
195
+ this.errorHandler({
196
+ 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',
197
+ localModel: null,
198
+ message: error.message,
199
+ model: modelDefinition.name,
200
+ operation: opName,
201
+ errorType: getSyncErrorType(error.errors[0]),
202
+ process: ProcessName.sync,
203
+ remoteModel: null,
204
+ cause: error,
205
+ });
206
+ throw new NonRetryableError(error);
289
207
  }
290
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
291
- finally {
292
- try {
293
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
294
- }
295
- finally { if (e_2) throw e_2.error; }
208
+ if (result.data?.[opName]?.items?.length) {
209
+ return result;
210
+ }
211
+ throw error;
212
+ }
213
+ }, [query, variables], undefined, onTerminate);
214
+ }
215
+ start(typesLastSync) {
216
+ const { maxRecordsToSync, syncPageSize } = this.amplifyConfig;
217
+ const parentPromises = new Map();
218
+ const observable = new Observable(observer => {
219
+ const sortedTypesLastSyncs = Object.values(this.schema.namespaces).reduce((map, namespace) => {
220
+ for (const modelName of Array.from(namespace.modelTopologicalOrdering.keys())) {
221
+ const typeLastSync = typesLastSync.get(namespace.models[modelName]);
222
+ map.set(namespace.models[modelName], typeLastSync);
296
223
  }
297
224
  return map;
298
225
  }, new Map());
299
- var allModelsReady = Array.from(sortedTypesLastSyncs.entries())
300
- .filter(function (_a) {
301
- var _b = __read(_a, 1), syncable = _b[0].syncable;
302
- return syncable;
303
- })
304
- .map(function (_a) {
305
- var _b = __read(_a, 2), modelDefinition = _b[0], _c = __read(_b[1], 2), namespace = _c[0], lastSync = _c[1];
306
- return _this.runningProcesses.isOpen &&
307
- _this.runningProcesses.add(function (onTerminate) { return __awaiter(_this, void 0, void 0, function () {
308
- var done, nextToken, startedAt, items, recordsReceived, filter, parents, promises, promise;
309
- var _this = this;
310
- return __generator(this, function (_a) {
311
- switch (_a.label) {
312
- case 0:
313
- done = false;
314
- nextToken = null;
315
- startedAt = null;
316
- items = null;
317
- recordsReceived = 0;
318
- filter = this.graphqlFilterFromPredicate(modelDefinition);
319
- parents = this.schema.namespaces[namespace].modelTopologicalOrdering.get(modelDefinition.name);
320
- promises = parents.map(function (parent) {
321
- return parentPromises.get(namespace + "_" + parent);
226
+ const allModelsReady = Array.from(sortedTypesLastSyncs.entries())
227
+ .filter(([{ syncable }]) => syncable)
228
+ .map(([modelDefinition, [namespace, lastSync]]) => this.runningProcesses.isOpen &&
229
+ this.runningProcesses.add(async (onTerminate) => {
230
+ let done = false;
231
+ let nextToken = null;
232
+ let startedAt = null;
233
+ let items = null;
234
+ let recordsReceived = 0;
235
+ const filter = this.graphqlFilterFromPredicate(modelDefinition);
236
+ const parents = this.schema.namespaces[namespace].modelTopologicalOrdering.get(modelDefinition.name);
237
+ const promises = parents.map(parent => parentPromises.get(`${namespace}_${parent}`));
238
+ const promise = new Promise(async (res) => {
239
+ await Promise.all(promises);
240
+ do {
241
+ /**
242
+ * If `runningProcesses` is not open, it means that the sync processor has been
243
+ * stopped (for example by calling `DataStore.clear()` upstream) and has not yet
244
+ * finished terminating and/or waiting for its background processes to complete.
245
+ */
246
+ if (!this.runningProcesses.isOpen) {
247
+ logger.debug(`Sync processor has been stopped, terminating sync for ${modelDefinition.name}`);
248
+ return res();
249
+ }
250
+ const limit = Math.min(maxRecordsToSync - recordsReceived, syncPageSize);
251
+ /**
252
+ * It's possible that `retrievePage` will fail.
253
+ * If it does fail, continue merging the rest of the data,
254
+ * and invoke the error handler for non-applicable data.
255
+ */
256
+ try {
257
+ ({ items, nextToken, startedAt } = await this.retrievePage(modelDefinition, lastSync, nextToken, limit, filter, onTerminate));
258
+ }
259
+ catch (error) {
260
+ try {
261
+ await this.errorHandler({
262
+ 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',
263
+ localModel: null,
264
+ message: error.message,
265
+ model: modelDefinition.name,
266
+ operation: null,
267
+ errorType: getSyncErrorType(error),
268
+ process: ProcessName.sync,
269
+ remoteModel: null,
270
+ cause: error,
322
271
  });
323
- promise = new Promise(function (res) { return __awaiter(_this, void 0, void 0, function () {
324
- var limit, error_3, e_3;
325
- var _a;
326
- return __generator(this, function (_b) {
327
- switch (_b.label) {
328
- case 0: return [4 /*yield*/, Promise.all(promises)];
329
- case 1:
330
- _b.sent();
331
- _b.label = 2;
332
- case 2:
333
- /**
334
- * If `runningProcesses` is not open, it means that the sync processor has been
335
- * stopped (for example by calling `DataStore.clear()` upstream) and has not yet
336
- * finished terminating and/or waiting for its background processes to complete.
337
- */
338
- if (!this.runningProcesses.isOpen) {
339
- logger.debug("Sync processor has been stopped, terminating sync for " + modelDefinition.name);
340
- return [2 /*return*/, res()];
341
- }
342
- limit = Math.min(maxRecordsToSync - recordsReceived, syncPageSize);
343
- _b.label = 3;
344
- case 3:
345
- _b.trys.push([3, 5, , 10]);
346
- return [4 /*yield*/, this.retrievePage(modelDefinition, lastSync, nextToken, limit, filter, onTerminate)];
347
- case 4:
348
- (_a = _b.sent(), items = _a.items, nextToken = _a.nextToken, startedAt = _a.startedAt);
349
- return [3 /*break*/, 10];
350
- case 5:
351
- error_3 = _b.sent();
352
- _b.label = 6;
353
- case 6:
354
- _b.trys.push([6, 8, , 9]);
355
- return [4 /*yield*/, this.errorHandler({
356
- 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',
357
- localModel: null,
358
- message: error_3.message,
359
- model: modelDefinition.name,
360
- operation: null,
361
- errorType: getSyncErrorType(error_3),
362
- process: ProcessName.sync,
363
- remoteModel: null,
364
- cause: error_3,
365
- })];
366
- case 7:
367
- _b.sent();
368
- return [3 /*break*/, 9];
369
- case 8:
370
- e_3 = _b.sent();
371
- logger.error('Sync error handler failed with:', e_3);
372
- return [3 /*break*/, 9];
373
- case 9:
374
- /**
375
- * If there's an error, this model fails, but the rest of the sync should
376
- * continue. To facilitate this, we explicitly mark this model as `done`
377
- * with no items and allow the loop to continue organically. This ensures
378
- * all callbacks (subscription messages) happen as normal, so anything
379
- * waiting on them knows the model is as done as it can be.
380
- */
381
- done = true;
382
- items = [];
383
- return [3 /*break*/, 10];
384
- case 10:
385
- recordsReceived += items.length;
386
- done =
387
- nextToken === null || recordsReceived >= maxRecordsToSync;
388
- observer.next({
389
- namespace: namespace,
390
- modelDefinition: modelDefinition,
391
- items: items,
392
- done: done,
393
- startedAt: startedAt,
394
- isFullSync: !lastSync,
395
- });
396
- _b.label = 11;
397
- case 11:
398
- if (!done) return [3 /*break*/, 2];
399
- _b.label = 12;
400
- case 12:
401
- res();
402
- return [2 /*return*/];
403
- }
404
- });
405
- }); });
406
- parentPromises.set(namespace + "_" + modelDefinition.name, promise);
407
- return [4 /*yield*/, promise];
408
- case 1:
409
- _a.sent();
410
- return [2 /*return*/];
272
+ }
273
+ catch (e) {
274
+ logger.error('Sync error handler failed with:', e);
275
+ }
276
+ /**
277
+ * If there's an error, this model fails, but the rest of the sync should
278
+ * continue. To facilitate this, we explicitly mark this model as `done`
279
+ * with no items and allow the loop to continue organically. This ensures
280
+ * all callbacks (subscription messages) happen as normal, so anything
281
+ * waiting on them knows the model is as done as it can be.
282
+ */
283
+ done = true;
284
+ items = [];
411
285
  }
412
- });
413
- }); }, "adding model " + modelDefinition.name);
414
- });
415
- Promise.all(allModelsReady).then(function () {
286
+ recordsReceived += items.length;
287
+ done =
288
+ nextToken === null || recordsReceived >= maxRecordsToSync;
289
+ observer.next({
290
+ namespace,
291
+ modelDefinition,
292
+ items,
293
+ done,
294
+ startedAt,
295
+ isFullSync: !lastSync,
296
+ });
297
+ } while (!done);
298
+ res();
299
+ });
300
+ parentPromises.set(`${namespace}_${modelDefinition.name}`, promise);
301
+ await promise;
302
+ }, `adding model ${modelDefinition.name}`));
303
+ Promise.all(allModelsReady).then(() => {
416
304
  observer.complete();
417
305
  });
418
306
  });
419
307
  return observable;
420
- };
421
- SyncProcessor.prototype.stop = function () {
422
- return __awaiter(this, void 0, void 0, function () {
423
- return __generator(this, function (_a) {
424
- switch (_a.label) {
425
- case 0:
426
- logger.debug('stopping sync processor');
427
- return [4 /*yield*/, this.runningProcesses.close()];
428
- case 1:
429
- _a.sent();
430
- return [4 /*yield*/, this.runningProcesses.open()];
431
- case 2:
432
- _a.sent();
433
- logger.debug('sync processor stopped');
434
- return [2 /*return*/];
435
- }
436
- });
437
- });
438
- };
439
- return SyncProcessor;
440
- }());
308
+ }
309
+ async stop() {
310
+ logger.debug('stopping sync processor');
311
+ await this.runningProcesses.close();
312
+ await this.runningProcesses.open();
313
+ logger.debug('sync processor stopped');
314
+ }
315
+ }
441
316
  export { SyncProcessor };
442
- //# sourceMappingURL=sync.js.map