@devrev/airsync-sdk 2.0.0-beta.2 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/airsync-sdk.d.ts +414 -157
- package/dist/attachments-streaming/attachments-streaming-pool.d.ts +2 -1
- package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
- package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts +8 -2
- package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts.map +1 -1
- package/dist/attachments-streaming/attachments-streaming-pool.js +14 -14
- package/dist/attachments-streaming/attachments-streaming-pool.test.js +47 -23
- package/dist/common/time-value-resolver.d.ts +2 -2
- package/dist/common/time-value-resolver.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/multithreading/adapters/base-adapter.d.ts +56 -0
- package/dist/multithreading/adapters/base-adapter.d.ts.map +1 -0
- package/dist/multithreading/adapters/base-adapter.emit.test.d.ts +2 -0
- package/dist/multithreading/adapters/base-adapter.emit.test.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.emit.test.js → adapters/base-adapter.emit.test.js} +66 -53
- package/dist/multithreading/adapters/base-adapter.js +105 -0
- package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts +2 -0
- package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.artifacts.test.js → adapters/extraction-adapter.artifacts.test.js} +6 -6
- package/dist/multithreading/adapters/extraction-adapter.d.ts +58 -0
- package/dist/multithreading/adapters/extraction-adapter.d.ts.map +1 -0
- package/dist/multithreading/adapters/extraction-adapter.js +325 -0
- package/dist/multithreading/adapters/extraction-adapter.test.d.ts +2 -0
- package/dist/multithreading/adapters/extraction-adapter.test.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.extraction.test.js → adapters/extraction-adapter.test.js} +41 -51
- package/dist/multithreading/adapters/loading-adapter.d.ts +44 -0
- package/dist/multithreading/adapters/loading-adapter.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.helpers.d.ts → adapters/loading-adapter.helpers.d.ts} +1 -1
- package/dist/multithreading/adapters/loading-adapter.helpers.d.ts.map +1 -0
- package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts +2 -0
- package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.helpers.test.js → adapters/loading-adapter.helpers.test.js} +26 -26
- package/dist/multithreading/adapters/loading-adapter.js +461 -0
- package/dist/multithreading/adapters/loading-adapter.test.d.ts +2 -0
- package/dist/multithreading/adapters/loading-adapter.test.d.ts.map +1 -0
- package/dist/multithreading/{worker-adapter/worker-adapter.loading.test.js → adapters/loading-adapter.test.js} +19 -26
- package/dist/multithreading/adapters/serialization.test.d.ts +2 -0
- package/dist/multithreading/adapters/serialization.test.d.ts.map +1 -0
- package/dist/multithreading/process-task.d.ts +16 -1
- package/dist/multithreading/process-task.d.ts.map +1 -1
- package/dist/multithreading/process-task.js +97 -49
- package/dist/multithreading/process-task.test.js +15 -15
- package/dist/state/base-state.d.ts +75 -0
- package/dist/state/base-state.d.ts.map +1 -0
- package/dist/state/base-state.js +261 -0
- package/dist/state/extraction-state.d.ts +29 -0
- package/dist/state/extraction-state.d.ts.map +1 -0
- package/dist/state/extraction-state.js +122 -0
- package/dist/state/loading-state.d.ts +19 -0
- package/dist/state/loading-state.d.ts.map +1 -0
- package/dist/state/loading-state.js +40 -0
- package/dist/state/state.extract-window.test.js +7 -7
- package/dist/state/state.interfaces.d.ts +32 -25
- package/dist/state/state.interfaces.d.ts.map +1 -1
- package/dist/state/state.interfaces.js +15 -4
- package/dist/state/state.pending-boundaries.test.js +15 -15
- package/dist/state/state.post-state.test.js +9 -8
- package/dist/state/state.test.js +22 -19
- package/dist/state/state.time-value-resolution.test.js +8 -8
- package/dist/types/extraction.d.ts +3 -3
- package/dist/types/extraction.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/workers.d.ts +16 -15
- package/dist/types/workers.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.d.ts +0 -97
- package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.helpers.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.js +0 -846
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts.map +0 -1
- package/dist/state/state.d.ts +0 -36
- package/dist/state/state.d.ts.map +0 -1
- package/dist/state/state.js +0 -265
- /package/dist/multithreading/{worker-adapter/worker-adapter.helpers.js → adapters/loading-adapter.helpers.js} +0 -0
- /package/dist/multithreading/{worker-adapter/worker-adapter.serialization.test.js → adapters/serialization.test.js} +0 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LoadingAdapter = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const logger_1 = require("../../logger/logger");
|
|
9
|
+
const logger_context_1 = require("../../logger/logger.context");
|
|
10
|
+
const mappers_1 = require("../../mappers/mappers");
|
|
11
|
+
const mappers_interface_1 = require("../../mappers/mappers.interface");
|
|
12
|
+
const extraction_1 = require("../../types/extraction");
|
|
13
|
+
const loading_1 = require("../../types/loading");
|
|
14
|
+
const base_adapter_1 = require("./base-adapter");
|
|
15
|
+
const loading_adapter_helpers_1 = require("./loading-adapter.helpers");
|
|
16
|
+
/**
|
|
17
|
+
* LoadingAdapter is the adapter passed to loading tasks. It exposes the loading
|
|
18
|
+
* surface (item/attachment loading, mappers, loader reports).
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
class LoadingAdapter extends base_adapter_1.BaseAdapter {
|
|
23
|
+
constructor(params) {
|
|
24
|
+
super(params);
|
|
25
|
+
this.loaderReports = [];
|
|
26
|
+
this._processedFiles = [];
|
|
27
|
+
this._mappers = new mappers_1.Mappers({
|
|
28
|
+
event: params.event,
|
|
29
|
+
options: params.options,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
get reports() {
|
|
33
|
+
return this.loaderReports;
|
|
34
|
+
}
|
|
35
|
+
get processedFiles() {
|
|
36
|
+
return this._processedFiles;
|
|
37
|
+
}
|
|
38
|
+
get mappers() {
|
|
39
|
+
return this._mappers;
|
|
40
|
+
}
|
|
41
|
+
async beforeEmit() {
|
|
42
|
+
// Loading has no pre-emit work (no repos, no extraction boundaries).
|
|
43
|
+
}
|
|
44
|
+
buildEmitPayload(newEventType) {
|
|
45
|
+
const isLoaderEvent = Object.values(loading_1.LoaderEventType).includes(newEventType);
|
|
46
|
+
return isLoaderEvent
|
|
47
|
+
? {
|
|
48
|
+
reports: this.reports,
|
|
49
|
+
processed_files: this.processedFiles,
|
|
50
|
+
}
|
|
51
|
+
: {};
|
|
52
|
+
}
|
|
53
|
+
afterEmit() {
|
|
54
|
+
// Loading keeps its accumulated reports/processed files across emits.
|
|
55
|
+
}
|
|
56
|
+
async loadItemTypes({ itemTypesToLoad, }) {
|
|
57
|
+
return (0, logger_context_1.runWithSdkLogContext)(async () => {
|
|
58
|
+
var _a;
|
|
59
|
+
if (this.event.payload.event_type === extraction_1.EventType.StartLoadingData) {
|
|
60
|
+
const itemTypes = itemTypesToLoad.map((itemTypeToLoad) => itemTypeToLoad.itemType);
|
|
61
|
+
if (!itemTypes.length) {
|
|
62
|
+
console.warn('No item types to load, returning.');
|
|
63
|
+
return {
|
|
64
|
+
reports: this.reports,
|
|
65
|
+
processed_files: this.processedFiles,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const filesToLoad = await this.getLoaderBatches({
|
|
69
|
+
supportedItemTypes: itemTypes,
|
|
70
|
+
});
|
|
71
|
+
this.adapterState.sdkState.fromDevRev = {
|
|
72
|
+
filesToLoad,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (!this.adapterState.sdkState.fromDevRev ||
|
|
76
|
+
!this.adapterState.sdkState.fromDevRev.filesToLoad.length) {
|
|
77
|
+
console.warn('No files to load, returning.');
|
|
78
|
+
return {
|
|
79
|
+
reports: this.reports,
|
|
80
|
+
processed_files: this.processedFiles,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
console.log('Files to load in state', (_a = this.adapterState.sdkState.fromDevRev) === null || _a === void 0 ? void 0 : _a.filesToLoad);
|
|
84
|
+
try {
|
|
85
|
+
outerloop: for (const fileToLoad of this.adapterState.sdkState
|
|
86
|
+
.fromDevRev.filesToLoad) {
|
|
87
|
+
const itemTypeToLoad = itemTypesToLoad.find((itemTypeToLoad) => itemTypeToLoad.itemType === fileToLoad.itemType);
|
|
88
|
+
if (!itemTypeToLoad) {
|
|
89
|
+
console.error(`Item type to load not found for item type: ${fileToLoad.itemType}.`);
|
|
90
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingError, {
|
|
91
|
+
error: {
|
|
92
|
+
message: `Item type to load not found for item type: ${fileToLoad.itemType}.`,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
if (!fileToLoad.completed) {
|
|
98
|
+
const { response, error: transformerFileError } = await this.uploader.getJsonObjectByArtifactId({
|
|
99
|
+
artifactId: fileToLoad.id,
|
|
100
|
+
isGzipped: true,
|
|
101
|
+
});
|
|
102
|
+
if (transformerFileError) {
|
|
103
|
+
console.error(`Transformer file not found for artifact ID: ${fileToLoad.id}.`);
|
|
104
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingError, {
|
|
105
|
+
error: {
|
|
106
|
+
message: `Transformer file not found for artifact ID: ${fileToLoad.id}.`,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
break outerloop;
|
|
110
|
+
}
|
|
111
|
+
const transformerFile = response;
|
|
112
|
+
for (let i = fileToLoad.lineToProcess; i < fileToLoad.count; i++) {
|
|
113
|
+
if (this.isTimeout) {
|
|
114
|
+
console.log('Timeout detected during data loading. Emitting progress to allow continuation.');
|
|
115
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingProgress);
|
|
116
|
+
process.exit(0);
|
|
117
|
+
}
|
|
118
|
+
const { report, rateLimit } = await this.loadItem({
|
|
119
|
+
item: transformerFile[i],
|
|
120
|
+
itemTypeToLoad,
|
|
121
|
+
});
|
|
122
|
+
if (rateLimit === null || rateLimit === void 0 ? void 0 : rateLimit.delay) {
|
|
123
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingDelayed, {
|
|
124
|
+
delay: rateLimit.delay,
|
|
125
|
+
reports: this.reports,
|
|
126
|
+
processed_files: this.processedFiles,
|
|
127
|
+
});
|
|
128
|
+
break outerloop;
|
|
129
|
+
}
|
|
130
|
+
if (report) {
|
|
131
|
+
(0, loading_adapter_helpers_1.addReportToLoaderReport)({
|
|
132
|
+
loaderReports: this.loaderReports,
|
|
133
|
+
report,
|
|
134
|
+
});
|
|
135
|
+
fileToLoad.lineToProcess = fileToLoad.lineToProcess + 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
fileToLoad.completed = true;
|
|
139
|
+
this._processedFiles.push(fileToLoad.id);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
console.error('Error during data loading.', (0, logger_1.serializeError)(error));
|
|
145
|
+
await this.emit(loading_1.LoaderEventType.DataLoadingError, {
|
|
146
|
+
error: {
|
|
147
|
+
message: `Error during data loading. ${(0, logger_1.serializeError)(error)}`,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
reports: this.reports,
|
|
154
|
+
processed_files: this.processedFiles,
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async getLoaderBatches({ supportedItemTypes, }) {
|
|
159
|
+
return (0, logger_context_1.runWithSdkLogContext)(async () => {
|
|
160
|
+
var _a;
|
|
161
|
+
const statsFileArtifactId = (_a = this.event.payload.event_data) === null || _a === void 0 ? void 0 : _a.stats_file;
|
|
162
|
+
if (statsFileArtifactId) {
|
|
163
|
+
const { response, error: statsFileError } = await this.uploader.getJsonObjectByArtifactId({
|
|
164
|
+
artifactId: statsFileArtifactId,
|
|
165
|
+
});
|
|
166
|
+
const statsFile = response;
|
|
167
|
+
if (statsFileError || statsFile.length === 0) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
const filesToLoad = (0, loading_adapter_helpers_1.getFilesToLoad)({
|
|
171
|
+
supportedItemTypes,
|
|
172
|
+
statsFile,
|
|
173
|
+
});
|
|
174
|
+
return filesToLoad;
|
|
175
|
+
}
|
|
176
|
+
return [];
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
async loadAttachments({ create, }) {
|
|
180
|
+
return (0, logger_context_1.runWithSdkLogContext)(async () => {
|
|
181
|
+
var _a, _b;
|
|
182
|
+
if (this.event.payload.event_type === extraction_1.EventType.StartLoadingAttachments) {
|
|
183
|
+
this.adapterState.sdkState.fromDevRev = {
|
|
184
|
+
filesToLoad: await this.getLoaderBatches({
|
|
185
|
+
supportedItemTypes: ['attachment'],
|
|
186
|
+
}),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (!this.adapterState.sdkState.fromDevRev ||
|
|
190
|
+
((_a = this.adapterState.sdkState.fromDevRev) === null || _a === void 0 ? void 0 : _a.filesToLoad.length) === 0) {
|
|
191
|
+
console.log('No files to load, returning.');
|
|
192
|
+
return {
|
|
193
|
+
reports: this.reports,
|
|
194
|
+
processed_files: this.processedFiles,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const filesToLoad = (_b = this.adapterState.sdkState.fromDevRev) === null || _b === void 0 ? void 0 : _b.filesToLoad;
|
|
198
|
+
try {
|
|
199
|
+
outerloop: for (const fileToLoad of filesToLoad) {
|
|
200
|
+
if (!fileToLoad.completed) {
|
|
201
|
+
const { response, error: transformerFileError } = await this.uploader.getJsonObjectByArtifactId({
|
|
202
|
+
artifactId: fileToLoad.id,
|
|
203
|
+
isGzipped: true,
|
|
204
|
+
});
|
|
205
|
+
const transformerFile = response;
|
|
206
|
+
if (transformerFileError) {
|
|
207
|
+
console.error(`Transformer file not found for artifact ID: ${fileToLoad.id}.`);
|
|
208
|
+
await this.emit(loading_1.LoaderEventType.AttachmentLoadingError, {
|
|
209
|
+
error: {
|
|
210
|
+
message: `Transformer file not found for artifact ID: ${fileToLoad.id}.`,
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
break outerloop;
|
|
214
|
+
}
|
|
215
|
+
for (let i = fileToLoad.lineToProcess; i < fileToLoad.count; i++) {
|
|
216
|
+
if (this.isTimeout) {
|
|
217
|
+
console.log('Timeout detected during attachment loading. Emitting progress to allow continuation.');
|
|
218
|
+
await this.emit(loading_1.LoaderEventType.AttachmentLoadingProgress);
|
|
219
|
+
process.exit(0);
|
|
220
|
+
}
|
|
221
|
+
const { report, rateLimit } = await this.loadAttachment({
|
|
222
|
+
item: transformerFile[i],
|
|
223
|
+
create,
|
|
224
|
+
});
|
|
225
|
+
if (rateLimit === null || rateLimit === void 0 ? void 0 : rateLimit.delay) {
|
|
226
|
+
await this.emit(loading_1.LoaderEventType.AttachmentLoadingDelayed, {
|
|
227
|
+
delay: rateLimit.delay,
|
|
228
|
+
reports: this.reports,
|
|
229
|
+
processed_files: this.processedFiles,
|
|
230
|
+
});
|
|
231
|
+
break outerloop;
|
|
232
|
+
}
|
|
233
|
+
if (report) {
|
|
234
|
+
(0, loading_adapter_helpers_1.addReportToLoaderReport)({
|
|
235
|
+
loaderReports: this.loaderReports,
|
|
236
|
+
report,
|
|
237
|
+
});
|
|
238
|
+
fileToLoad.lineToProcess = fileToLoad.lineToProcess + 1;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
fileToLoad.completed = true;
|
|
242
|
+
this._processedFiles.push(fileToLoad.id);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
console.error('Error during attachment loading.', (0, logger_1.serializeError)(error));
|
|
248
|
+
await this.emit(loading_1.LoaderEventType.AttachmentLoadingError, {
|
|
249
|
+
error: {
|
|
250
|
+
message: `Error during attachment loading. ${(0, logger_1.serializeError)(error)}`,
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
reports: this.reports,
|
|
257
|
+
processed_files: this.processedFiles,
|
|
258
|
+
};
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
async loadItem({ item, itemTypeToLoad, }) {
|
|
262
|
+
return (0, logger_context_1.runWithSdkLogContext)(async () => {
|
|
263
|
+
var _a;
|
|
264
|
+
const devrevId = item.id.devrev;
|
|
265
|
+
try {
|
|
266
|
+
const syncMapperRecordResponse = await this._mappers.getByTargetId({
|
|
267
|
+
sync_unit: this.event.payload.event_context.sync_unit,
|
|
268
|
+
target: devrevId,
|
|
269
|
+
});
|
|
270
|
+
const syncMapperRecord = syncMapperRecordResponse.data;
|
|
271
|
+
if (!syncMapperRecord) {
|
|
272
|
+
console.warn('Failed to get sync mapper record from response.');
|
|
273
|
+
return {
|
|
274
|
+
error: {
|
|
275
|
+
message: 'Failed to get sync mapper record from response.',
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
// Update item in external system
|
|
280
|
+
const { id, modifiedDate, delay, error } = await (0, logger_context_1.runWithUserLogContext)(async () => {
|
|
281
|
+
return await itemTypeToLoad.update({
|
|
282
|
+
item,
|
|
283
|
+
mappers: this._mappers,
|
|
284
|
+
event: this.event,
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
if (id) {
|
|
288
|
+
try {
|
|
289
|
+
const syncMapperRecordUpdateResponse = await this._mappers.update(Object.assign(Object.assign({ id: syncMapperRecord.sync_mapper_record.id, sync_unit: this.event.payload.event_context.sync_unit, status: mappers_interface_1.SyncMapperRecordStatus.OPERATIONAL }, (modifiedDate && {
|
|
290
|
+
external_versions: {
|
|
291
|
+
add: [
|
|
292
|
+
{
|
|
293
|
+
modified_date: modifiedDate,
|
|
294
|
+
recipe_version: 0,
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
},
|
|
298
|
+
})), { external_ids: {
|
|
299
|
+
add: [id],
|
|
300
|
+
}, targets: {
|
|
301
|
+
add: [devrevId],
|
|
302
|
+
} }));
|
|
303
|
+
console.log('Successfully updated sync mapper record.', syncMapperRecordUpdateResponse.data);
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
console.warn('Failed to update sync mapper record.', (0, logger_1.serializeError)(error));
|
|
307
|
+
return {
|
|
308
|
+
error: {
|
|
309
|
+
message: 'Failed to update sync mapper record' + (0, logger_1.serializeError)(error),
|
|
310
|
+
},
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
report: {
|
|
315
|
+
item_type: itemTypeToLoad.itemType,
|
|
316
|
+
[loading_1.ActionType.UPDATED]: 1,
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
else if (delay) {
|
|
321
|
+
console.log(`Rate limited while updating item in external system, delaying for ${delay} seconds.`);
|
|
322
|
+
return {
|
|
323
|
+
rateLimit: {
|
|
324
|
+
delay,
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
console.warn('Failed to update item in external system', error);
|
|
330
|
+
return {
|
|
331
|
+
report: {
|
|
332
|
+
item_type: itemTypeToLoad.itemType,
|
|
333
|
+
[loading_1.ActionType.FAILED]: 1,
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
// TODO: Update mapper (optional)
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
341
|
+
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
|
|
342
|
+
// Create item in external system if mapper record not found
|
|
343
|
+
const { id, modifiedDate, delay, error } = await (0, logger_context_1.runWithUserLogContext)(async () => {
|
|
344
|
+
return await itemTypeToLoad.create({
|
|
345
|
+
item,
|
|
346
|
+
mappers: this._mappers,
|
|
347
|
+
event: this.event,
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
if (id) {
|
|
351
|
+
// Create mapper
|
|
352
|
+
try {
|
|
353
|
+
const syncMapperRecordCreateResponse = await this._mappers.create(Object.assign({ sync_unit: this.event.payload.event_context.sync_unit, status: mappers_interface_1.SyncMapperRecordStatus.OPERATIONAL, external_ids: [id], targets: [devrevId] }, (modifiedDate && {
|
|
354
|
+
external_versions: [
|
|
355
|
+
{
|
|
356
|
+
modified_date: modifiedDate,
|
|
357
|
+
recipe_version: 0,
|
|
358
|
+
},
|
|
359
|
+
],
|
|
360
|
+
})));
|
|
361
|
+
console.log('Successfully created sync mapper record.', syncMapperRecordCreateResponse.data);
|
|
362
|
+
return {
|
|
363
|
+
report: {
|
|
364
|
+
item_type: itemTypeToLoad.itemType,
|
|
365
|
+
[loading_1.ActionType.CREATED]: 1,
|
|
366
|
+
},
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
console.warn('Failed to create sync mapper record.', (0, logger_1.serializeError)(error));
|
|
371
|
+
return {
|
|
372
|
+
error: {
|
|
373
|
+
message: 'Failed to create sync mapper record. ' +
|
|
374
|
+
(0, logger_1.serializeError)(error),
|
|
375
|
+
},
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
else if (delay) {
|
|
380
|
+
return {
|
|
381
|
+
rateLimit: {
|
|
382
|
+
delay,
|
|
383
|
+
},
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
console.warn('Failed to create item in external system.', (0, logger_1.serializeError)(error));
|
|
388
|
+
return {
|
|
389
|
+
report: {
|
|
390
|
+
item_type: itemTypeToLoad.itemType,
|
|
391
|
+
[loading_1.ActionType.FAILED]: 1,
|
|
392
|
+
},
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
console.warn('Failed to get sync mapper record.', (0, logger_1.serializeError)(error));
|
|
398
|
+
return {
|
|
399
|
+
error: {
|
|
400
|
+
message: error.message,
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
console.warn('Failed to get sync mapper record.', (0, logger_1.serializeError)(error));
|
|
406
|
+
return {
|
|
407
|
+
error: {
|
|
408
|
+
message: 'Failed to get sync mapper record. ' + (0, logger_1.serializeError)(error),
|
|
409
|
+
},
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
async loadAttachment({ item, create, }) {
|
|
415
|
+
return (0, logger_context_1.runWithSdkLogContext)(async () => {
|
|
416
|
+
// Create item
|
|
417
|
+
const { id, delay, error } = await (0, logger_context_1.runWithUserLogContext)(async () => create({
|
|
418
|
+
item,
|
|
419
|
+
mappers: this._mappers,
|
|
420
|
+
event: this.event,
|
|
421
|
+
}));
|
|
422
|
+
if (delay) {
|
|
423
|
+
return {
|
|
424
|
+
rateLimit: {
|
|
425
|
+
delay,
|
|
426
|
+
},
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
else if (id) {
|
|
430
|
+
try {
|
|
431
|
+
const syncMapperRecordCreateResponse = await this._mappers.create({
|
|
432
|
+
sync_unit: this.event.payload.event_context.sync_unit,
|
|
433
|
+
external_ids: [id],
|
|
434
|
+
targets: [item.reference_id],
|
|
435
|
+
status: mappers_interface_1.SyncMapperRecordStatus.OPERATIONAL,
|
|
436
|
+
});
|
|
437
|
+
console.log('Successfully created sync mapper record.', syncMapperRecordCreateResponse.data);
|
|
438
|
+
}
|
|
439
|
+
catch (error) {
|
|
440
|
+
console.warn('Failed to create sync mapper record.', (0, logger_1.serializeError)(error));
|
|
441
|
+
}
|
|
442
|
+
return {
|
|
443
|
+
report: {
|
|
444
|
+
item_type: 'attachment',
|
|
445
|
+
[loading_1.ActionType.CREATED]: 1,
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
console.warn('Failed to create attachment in external system', error);
|
|
451
|
+
return {
|
|
452
|
+
report: {
|
|
453
|
+
item_type: 'attachment',
|
|
454
|
+
[loading_1.ActionType.FAILED]: 1,
|
|
455
|
+
},
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
exports.LoadingAdapter = LoadingAdapter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loading-adapter.test.d.ts","sourceRoot":"","sources":["../../../src/multithreading/adapters/loading-adapter.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const loading_state_1 = require("../../state/loading-state");
|
|
4
4
|
const jest_setup_1 = require("../../tests/jest.setup");
|
|
5
5
|
const test_utils_1 = require("../../common/test-utils");
|
|
6
6
|
const types_1 = require("../../types");
|
|
7
7
|
const loading_1 = require("../../types/loading");
|
|
8
|
-
const
|
|
8
|
+
const loading_adapter_1 = require("./loading-adapter");
|
|
9
9
|
jest.mock('../../common/control-protocol', () => ({
|
|
10
10
|
emit: jest.fn().mockResolvedValue({}),
|
|
11
11
|
}));
|
|
@@ -26,17 +26,10 @@ function makeAdapter(eventType) {
|
|
|
26
26
|
});
|
|
27
27
|
const initialState = {
|
|
28
28
|
attachments: { completed: false },
|
|
29
|
-
snapInVersionId: '',
|
|
30
|
-
toDevRev: {
|
|
31
|
-
attachmentsMetadata: {
|
|
32
|
-
artifactIds: [],
|
|
33
|
-
lastProcessed: 0,
|
|
34
|
-
lastProcessedAttachmentsIdsList: [],
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
29
|
};
|
|
38
|
-
const adapterState = new
|
|
39
|
-
|
|
30
|
+
const adapterState = new loading_state_1.LoadingState({ event, initialState });
|
|
31
|
+
adapterState.sdkState.snapInVersionId = '';
|
|
32
|
+
const adapter = new loading_adapter_1.LoadingAdapter({ event, adapterState });
|
|
40
33
|
return { adapter, event, adapterState };
|
|
41
34
|
}
|
|
42
35
|
function makeLoaderItem(devrevId = 'dev-1') {
|
|
@@ -48,7 +41,7 @@ function makeLoaderItem(devrevId = 'dev-1') {
|
|
|
48
41
|
};
|
|
49
42
|
}
|
|
50
43
|
function setupLoaderFile(adapter, items, itemType = 'tasks') {
|
|
51
|
-
adapter['adapterState'].
|
|
44
|
+
adapter['adapterState'].sdkState.fromDevRev = {
|
|
52
45
|
filesToLoad: [
|
|
53
46
|
{
|
|
54
47
|
id: 'artifact-1',
|
|
@@ -64,7 +57,7 @@ function setupLoaderFile(adapter, items, itemType = 'tasks') {
|
|
|
64
57
|
.fn()
|
|
65
58
|
.mockResolvedValue({ response: items });
|
|
66
59
|
}
|
|
67
|
-
describe(`${
|
|
60
|
+
describe(`${loading_adapter_1.LoadingAdapter.name}.loadItemTypes — timeout and unexpected errors`, () => {
|
|
68
61
|
let adapter;
|
|
69
62
|
let exitSpy;
|
|
70
63
|
let emitSpy;
|
|
@@ -125,7 +118,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadItemTypes — timeout and u
|
|
|
125
118
|
});
|
|
126
119
|
it('should emit DataLoadingError and exit(1) on unexpected error', async () => {
|
|
127
120
|
// Arrange
|
|
128
|
-
adapter['adapterState'].
|
|
121
|
+
adapter['adapterState'].sdkState.fromDevRev = {
|
|
129
122
|
filesToLoad: [
|
|
130
123
|
{
|
|
131
124
|
id: 'artifact-1',
|
|
@@ -154,7 +147,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadItemTypes — timeout and u
|
|
|
154
147
|
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
155
148
|
});
|
|
156
149
|
});
|
|
157
|
-
describe(`${
|
|
150
|
+
describe(`${loading_adapter_1.LoadingAdapter.name}.loadItemTypes — loadItem branch coverage via public API`, () => {
|
|
158
151
|
let adapter;
|
|
159
152
|
let emitSpy;
|
|
160
153
|
let exitSpy;
|
|
@@ -271,7 +264,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadItemTypes — loadItem bran
|
|
|
271
264
|
expect(reports).toBeDefined();
|
|
272
265
|
});
|
|
273
266
|
});
|
|
274
|
-
describe(`${
|
|
267
|
+
describe(`${loading_adapter_1.LoadingAdapter.name}.loadItemTypes — additional branches`, () => {
|
|
275
268
|
let adapter;
|
|
276
269
|
let emitSpy;
|
|
277
270
|
beforeEach(() => {
|
|
@@ -284,7 +277,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadItemTypes — additional br
|
|
|
284
277
|
});
|
|
285
278
|
it('should return immediately with empty reports when filesToLoad is empty', async () => {
|
|
286
279
|
// Arrange
|
|
287
|
-
adapter['adapterState'].
|
|
280
|
+
adapter['adapterState'].sdkState.fromDevRev = { filesToLoad: [] };
|
|
288
281
|
// Act
|
|
289
282
|
const result = await adapter.loadItemTypes({
|
|
290
283
|
itemTypesToLoad: [
|
|
@@ -297,7 +290,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadItemTypes — additional br
|
|
|
297
290
|
});
|
|
298
291
|
it('should emit DataLoadingError when a file references an item type not in itemTypesToLoad', async () => {
|
|
299
292
|
// Arrange
|
|
300
|
-
adapter['adapterState'].
|
|
293
|
+
adapter['adapterState'].sdkState.fromDevRev = {
|
|
301
294
|
filesToLoad: [
|
|
302
295
|
{
|
|
303
296
|
id: 'art-1',
|
|
@@ -326,12 +319,12 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadItemTypes — additional br
|
|
|
326
319
|
}));
|
|
327
320
|
});
|
|
328
321
|
});
|
|
329
|
-
describe(`${
|
|
322
|
+
describe(`${loading_adapter_1.LoadingAdapter.name}.loadAttachments — timeout, transformer errors, unexpected errors`, () => {
|
|
330
323
|
let adapter;
|
|
331
324
|
let exitSpy;
|
|
332
325
|
let emitSpy;
|
|
333
326
|
function setupFilesToLoad(a, items) {
|
|
334
|
-
a['adapterState'].
|
|
327
|
+
a['adapterState'].sdkState.fromDevRev = {
|
|
335
328
|
filesToLoad: [
|
|
336
329
|
{
|
|
337
330
|
id: 'artifact-1',
|
|
@@ -389,7 +382,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadAttachments — timeout, tr
|
|
|
389
382
|
});
|
|
390
383
|
it('should emit AttachmentLoadingError on transformer file error', async () => {
|
|
391
384
|
// Arrange
|
|
392
|
-
adapter['adapterState'].
|
|
385
|
+
adapter['adapterState'].sdkState.fromDevRev = {
|
|
393
386
|
filesToLoad: [
|
|
394
387
|
{
|
|
395
388
|
id: 'bad-artifact',
|
|
@@ -451,7 +444,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadAttachments — timeout, tr
|
|
|
451
444
|
expect(exitSpy).toHaveBeenCalledWith(1);
|
|
452
445
|
});
|
|
453
446
|
});
|
|
454
|
-
describe(`${
|
|
447
|
+
describe(`${loading_adapter_1.LoadingAdapter.name}.loadAttachments — additional branches`, () => {
|
|
455
448
|
let adapter;
|
|
456
449
|
let emitSpy;
|
|
457
450
|
beforeEach(() => {
|
|
@@ -464,7 +457,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadAttachments — additional
|
|
|
464
457
|
});
|
|
465
458
|
it('should return immediately with empty reports when fromDevRev is not set', async () => {
|
|
466
459
|
// Arrange
|
|
467
|
-
adapter['adapterState'].
|
|
460
|
+
adapter['adapterState'].sdkState.fromDevRev = undefined;
|
|
468
461
|
// Act
|
|
469
462
|
const result = await adapter.loadAttachments({ create: jest.fn() });
|
|
470
463
|
// Assert
|
|
@@ -473,7 +466,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadAttachments — additional
|
|
|
473
466
|
});
|
|
474
467
|
it('should emit AttachmentLoadingDelayed and stop the loop when the connector signals a rate-limit delay', async () => {
|
|
475
468
|
// Arrange
|
|
476
|
-
adapter['adapterState'].
|
|
469
|
+
adapter['adapterState'].sdkState.fromDevRev = {
|
|
477
470
|
filesToLoad: [
|
|
478
471
|
{
|
|
479
472
|
id: 'art-1',
|
|
@@ -515,7 +508,7 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.loadAttachments — additional
|
|
|
515
508
|
expect(emitSpy).toHaveBeenCalledWith(types_1.LoaderEventType.AttachmentLoadingDelayed, expect.objectContaining({ delay: 20 }));
|
|
516
509
|
});
|
|
517
510
|
});
|
|
518
|
-
describe(`${
|
|
511
|
+
describe(`${loading_adapter_1.LoadingAdapter.name}.loadAttachment`, () => {
|
|
519
512
|
let adapter;
|
|
520
513
|
beforeEach(() => {
|
|
521
514
|
jest.clearAllMocks();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.test.d.ts","sourceRoot":"","sources":["../../../src/multithreading/adapters/serialization.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,3 +1,18 @@
|
|
|
1
1
|
import { ProcessTaskInterface } from '../types/workers';
|
|
2
|
-
|
|
2
|
+
import { ExtractionAdapter } from './adapters/extraction-adapter';
|
|
3
|
+
import { LoadingAdapter } from './adapters/loading-adapter';
|
|
4
|
+
/**
|
|
5
|
+
* Entry point for an extraction worker. Builds an {@link ExtractionAdapter} and
|
|
6
|
+
* runs the provided task against it.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare function processExtractionTask<ConnectorState>({ task, onTimeout, }: ProcessTaskInterface<ExtractionAdapter<ConnectorState>>): void;
|
|
11
|
+
/**
|
|
12
|
+
* Entry point for a loading worker. Builds a {@link LoadingAdapter} and runs the
|
|
13
|
+
* provided task against it.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export declare function processLoadingTask<ConnectorState>({ task, onTimeout, }: ProcessTaskInterface<LoadingAdapter<ConnectorState>>): void;
|
|
3
18
|
//# sourceMappingURL=process-task.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-task.d.ts","sourceRoot":"","sources":["../../src/multithreading/process-task.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-task.d.ts","sourceRoot":"","sources":["../../src/multithreading/process-task.ts"],"names":[],"mappings":"AASA,OAAO,EACL,oBAAoB,EAGrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAgD5D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,EAAE,EACpD,IAAI,EACJ,SAAS,GACV,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,QA6BzD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,EACjD,IAAI,EACJ,SAAS,GACV,EAAE,oBAAoB,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,QA6BtD"}
|