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