@devrev/ts-adaas 0.0.3 → 1.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 (110) hide show
  1. package/README.md +182 -116
  2. package/dist/common/constants.d.ts +10 -0
  3. package/dist/common/constants.js +27 -0
  4. package/dist/common/control-protocol.d.ts +7 -0
  5. package/dist/common/control-protocol.js +41 -0
  6. package/dist/common/helpers.d.ts +4 -0
  7. package/dist/common/helpers.js +38 -0
  8. package/dist/common/install-initial-domain-mapping.d.ts +3 -0
  9. package/dist/common/install-initial-domain-mapping.js +87 -0
  10. package/dist/{src → deprecated}/adapter/index.d.ts +10 -7
  11. package/dist/{src → deprecated}/adapter/index.js +13 -10
  12. package/dist/{src → deprecated}/common/helpers.d.ts +1 -2
  13. package/dist/deprecated/common/helpers.js +47 -0
  14. package/dist/deprecated/demo-extractor/index.d.ts +17 -0
  15. package/dist/{src → deprecated}/demo-extractor/index.js +28 -22
  16. package/dist/{src → deprecated}/uploader/index.d.ts +1 -1
  17. package/dist/{src → deprecated}/uploader/index.js +3 -1
  18. package/dist/{src/http → http}/client.d.ts +2 -1
  19. package/dist/index.d.ts +10 -0
  20. package/dist/{src/index.js → index.js} +11 -3
  21. package/dist/logger/logger.d.ts +14 -0
  22. package/dist/logger/logger.interfaces.d.ts +14 -0
  23. package/dist/logger/logger.interfaces.js +9 -0
  24. package/dist/logger/logger.js +91 -0
  25. package/dist/logger/logger.test.js +49 -0
  26. package/dist/repo/repo.d.ts +14 -0
  27. package/dist/repo/repo.interfaces.d.ts +43 -0
  28. package/dist/repo/repo.interfaces.js +2 -0
  29. package/dist/repo/repo.js +68 -0
  30. package/dist/repo/repo.test.js +74 -0
  31. package/dist/state/state.d.ts +24 -0
  32. package/dist/state/state.interfaces.d.ts +24 -0
  33. package/dist/state/state.interfaces.js +2 -0
  34. package/dist/state/state.js +115 -0
  35. package/dist/tests/test-helpers.d.ts +9 -0
  36. package/dist/tests/test-helpers.interfaces.d.ts +11 -0
  37. package/dist/tests/test-helpers.interfaces.js +2 -0
  38. package/dist/tests/test-helpers.js +88 -0
  39. package/dist/tests/test-worker.js +16 -0
  40. package/dist/types/common.d.ts +39 -0
  41. package/dist/{src/types → types}/common.js +4 -0
  42. package/dist/{src/types → types}/extraction.d.ts +56 -12
  43. package/dist/{src/types → types}/extraction.js +12 -29
  44. package/dist/types/index.d.ts +5 -0
  45. package/dist/types/index.js +11 -0
  46. package/dist/types/workers.d.ts +142 -0
  47. package/dist/types/workers.js +23 -0
  48. package/dist/uploader/uploader.d.ts +38 -0
  49. package/dist/uploader/uploader.interfaces.d.ts +63 -0
  50. package/dist/uploader/uploader.interfaces.js +2 -0
  51. package/dist/uploader/uploader.js +351 -0
  52. package/dist/{tests → uploader}/uploader.test.js +7 -5
  53. package/dist/workers/create-worker.d.ts +4 -0
  54. package/dist/workers/create-worker.js +30 -0
  55. package/dist/workers/create-worker.test.js +25 -0
  56. package/dist/workers/default-workers/attachments-deletion.d.ts +1 -0
  57. package/dist/workers/default-workers/attachments-deletion.js +13 -0
  58. package/dist/workers/default-workers/attachments-extraction.d.ts +1 -0
  59. package/dist/workers/default-workers/attachments-extraction.js +49 -0
  60. package/dist/workers/default-workers/data-deletion.d.ts +1 -0
  61. package/dist/workers/default-workers/data-deletion.js +15 -0
  62. package/dist/workers/default-workers/data-extraction.d.ts +1 -0
  63. package/dist/workers/default-workers/data-extraction.js +101 -0
  64. package/dist/workers/default-workers/external-sync-units-extraction.d.ts +1 -0
  65. package/dist/workers/default-workers/external-sync-units-extraction.js +27 -0
  66. package/dist/workers/default-workers/metadata-extraction.d.ts +1 -0
  67. package/dist/workers/default-workers/metadata-extraction.js +26 -0
  68. package/dist/workers/dummy-extractor/data-normalization.d.ts +4 -0
  69. package/dist/workers/dummy-extractor/data-normalization.js +41 -0
  70. package/dist/workers/dummy-extractor/external_domain_metadata.json +58 -0
  71. package/dist/workers/process-task.d.ts +2 -0
  72. package/dist/workers/process-task.js +44 -0
  73. package/dist/workers/spawn.d.ts +25 -0
  74. package/dist/workers/spawn.js +163 -0
  75. package/dist/workers/worker-adapter.d.ts +48 -0
  76. package/dist/workers/worker-adapter.js +138 -0
  77. package/dist/workers/worker.d.ts +1 -0
  78. package/dist/workers/worker.js +6 -0
  79. package/package.json +9 -5
  80. package/dist/src/common/constants.d.ts +0 -2
  81. package/dist/src/common/constants.js +0 -10
  82. package/dist/src/common/helpers.js +0 -59
  83. package/dist/src/common/install-initial-domain-mapping.d.ts +0 -3
  84. package/dist/src/common/install-initial-domain-mapping.js +0 -60
  85. package/dist/src/demo-extractor/index.d.ts +0 -11
  86. package/dist/src/index.d.ts +0 -6
  87. package/dist/src/logging/index.d.ts +0 -18
  88. package/dist/src/logging/index.js +0 -39
  89. package/dist/src/state/index.d.ts +0 -23
  90. package/dist/src/state/index.js +0 -111
  91. package/dist/src/types/common.d.ts +0 -37
  92. package/dist/src/types/index.d.ts +0 -2
  93. package/dist/src/types/index.js +0 -18
  94. package/dist/tests/adapter.helpers.test.js +0 -60
  95. package/dist/tests/adapter.test.js +0 -123
  96. package/dist/tests/demo-extractor.test.js +0 -61
  97. package/dist/tests/state.test.js +0 -101
  98. /package/dist/{src → deprecated}/demo-extractor/external_domain_metadata.json +0 -0
  99. /package/dist/{src/http → http}/client.js +0 -0
  100. /package/dist/{src/http → http}/constants.d.ts +0 -0
  101. /package/dist/{src/http → http}/constants.js +0 -0
  102. /package/dist/{src/http → http}/index.d.ts +0 -0
  103. /package/dist/{src/http → http}/index.js +0 -0
  104. /package/dist/{src/http → http}/types.d.ts +0 -0
  105. /package/dist/{src/http → http}/types.js +0 -0
  106. /package/dist/{tests/adapter.helpers.test.d.ts → logger/logger.test.d.ts} +0 -0
  107. /package/dist/{tests/adapter.test.d.ts → repo/repo.test.d.ts} +0 -0
  108. /package/dist/tests/{demo-extractor.test.d.ts → test-worker.d.ts} +0 -0
  109. /package/dist/{tests → uploader}/uploader.test.d.ts +0 -0
  110. /package/dist/{tests/state.test.d.ts → workers/create-worker.test.d.ts} +0 -0
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createWorker = createWorker;
4
+ const node_worker_threads_1 = require("node:worker_threads");
5
+ const workers_1 = require("../types/workers");
6
+ const logger_1 = require("../logger/logger");
7
+ async function createWorker(workerData) {
8
+ return new Promise((resolve, reject) => {
9
+ if (node_worker_threads_1.isMainThread) {
10
+ const logger = new logger_1.Logger(workerData.event);
11
+ const workerFile = __dirname + '/worker.js';
12
+ const worker = new node_worker_threads_1.Worker(workerFile, {
13
+ workerData,
14
+ });
15
+ worker.on(workers_1.WorkerEvent.WorkerError, (error) => {
16
+ logger.error('Worker error', error);
17
+ reject(error);
18
+ });
19
+ worker.on(workers_1.WorkerEvent.WorkerOnline, () => {
20
+ resolve(worker);
21
+ logger.info('Worker is online. Started processing the task with event type: ' +
22
+ workerData.event.payload.event_type +
23
+ '.');
24
+ });
25
+ }
26
+ else {
27
+ reject(new Error('Worker threads can not start more worker threads.'));
28
+ }
29
+ });
30
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const worker_threads_1 = require("worker_threads");
4
+ const test_helpers_1 = require("../tests/test-helpers");
5
+ const extraction_1 = require("../types/extraction");
6
+ const create_worker_1 = require("./create-worker");
7
+ describe('createWorker function', () => {
8
+ it('should return a Worker instance when a valid worker script is found', async () => {
9
+ const workerPath = __dirname + '../tests/dummy-worker.ts';
10
+ const worker = worker_threads_1.isMainThread
11
+ ? await (0, create_worker_1.createWorker)({
12
+ event: (0, test_helpers_1.createEvent)({
13
+ eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
14
+ }),
15
+ initialState: {},
16
+ workerPath,
17
+ })
18
+ : null;
19
+ expect(worker).not.toBeNull();
20
+ expect(worker).toBeInstanceOf(worker_threads_1.Worker);
21
+ if (worker) {
22
+ await worker.terminate();
23
+ }
24
+ });
25
+ });
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../../index");
4
+ (0, index_1.processTask)({
5
+ task: async ({ adapter }) => {
6
+ await adapter.emit(index_1.ExtractorEventType.ExtractionAttachmentsDeleteDone);
7
+ },
8
+ onTimeout: async ({ adapter }) => {
9
+ await adapter.emit(index_1.ExtractorEventType.ExtractionAttachmentsDeleteError, {
10
+ error: { message: 'Failed to delete attachments. Lambda timeout.' },
11
+ });
12
+ },
13
+ });
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../../index");
4
+ const uploader_1 = require("../../uploader/uploader");
5
+ const repos = [
6
+ {
7
+ itemType: 'ssor_attachment',
8
+ },
9
+ ];
10
+ (0, index_1.processTask)({
11
+ task: async ({ adapter }) => {
12
+ var _a, _b, _c, _d, _e;
13
+ if (!((_a = adapter.state.toDevRev) === null || _a === void 0 ? void 0 : _a.attachmentsMetadata.artifactIds) ||
14
+ adapter.state.toDevRev.attachmentsMetadata.artifactIds.length === 0) {
15
+ console.log('No attachments to extract, skipping.');
16
+ await adapter.emit(index_1.ExtractorEventType.ExtractionAttachmentsDone);
17
+ return;
18
+ }
19
+ adapter.initializeRepos(repos);
20
+ const uploader = new uploader_1.Uploader({
21
+ event: adapter.event,
22
+ options: adapter.options,
23
+ });
24
+ for (const attachmentsMetadataArtifactId of (_b = adapter.state.toDevRev) === null || _b === void 0 ? void 0 : _b.attachmentsMetadata.artifactIds) {
25
+ const { ssorAttachments, error } = await uploader.streamAttachments({
26
+ attachmentsMetadataArtifactId,
27
+ });
28
+ if (error || !ssorAttachments) {
29
+ await adapter.emit(index_1.ExtractorEventType.ExtractionAttachmentsError, {
30
+ error,
31
+ });
32
+ return;
33
+ }
34
+ await ((_c = adapter.getRepo('ssor_attachment')) === null || _c === void 0 ? void 0 : _c.push(ssorAttachments));
35
+ (_d = adapter.state.toDevRev) === null || _d === void 0 ? void 0 : _d.attachmentsMetadata.artifactIds.shift();
36
+ adapter.state.toDevRev.attachmentsMetadata.lastProcessed = 0;
37
+ if (((_e = adapter.state.toDevRev) === null || _e === void 0 ? void 0 : _e.attachmentsMetadata.artifactIds.length) === 0) {
38
+ break;
39
+ }
40
+ }
41
+ await adapter.emit(index_1.ExtractorEventType.ExtractionAttachmentsDone);
42
+ },
43
+ onTimeout: async ({ adapter }) => {
44
+ await adapter.postState();
45
+ await adapter.emit(index_1.ExtractorEventType.ExtractionAttachmentsProgress, {
46
+ progress: 50,
47
+ });
48
+ },
49
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../../index");
4
+ (0, index_1.processTask)({
5
+ task: async ({ adapter }) => {
6
+ await adapter.emit(index_1.ExtractorEventType.ExtractionDataDeleteDone);
7
+ },
8
+ onTimeout: async ({ adapter }) => {
9
+ await adapter.emit(index_1.ExtractorEventType.ExtractionDataDeleteError, {
10
+ error: {
11
+ message: 'Failed to delete data. Lambda timeout.',
12
+ },
13
+ });
14
+ },
15
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../../index");
4
+ const data_normalization_1 = require("../dummy-extractor/data-normalization");
5
+ // Dummy data that originally would be fetched from an external source
6
+ const issues = [
7
+ {
8
+ id: 'issue-1',
9
+ created_date: '1999-12-25T01:00:03+01:00',
10
+ modified_date: '1999-12-25T01:00:03+01:00',
11
+ body: '<p>This is issue 1</p>',
12
+ creator: 'user-1',
13
+ owner: 'user-1',
14
+ title: 'Issue 1',
15
+ },
16
+ {
17
+ id: 'issue-2',
18
+ created_date: '1999-12-27T15:31:34+01:00',
19
+ modified_date: '2002-04-09T01:55:31+02:00',
20
+ body: '<p>This is issue 2</p>',
21
+ creator: 'user-2',
22
+ owner: 'user-2',
23
+ title: 'Issue 2',
24
+ },
25
+ ];
26
+ const users = [
27
+ {
28
+ id: 'user-1',
29
+ created_date: '1999-12-25T01:00:03+01:00',
30
+ modified_date: '1999-12-25T01:00:03+01:00',
31
+ data: {
32
+ email: 'johndoe@test.com',
33
+ name: 'John Doe',
34
+ },
35
+ },
36
+ {
37
+ id: 'user-2',
38
+ created_date: '1999-12-27T15:31:34+01:00',
39
+ modified_date: '2002-04-09T01:55:31+02:00',
40
+ data: {
41
+ email: 'janedoe@test.com',
42
+ name: 'Jane Doe',
43
+ },
44
+ },
45
+ ];
46
+ const attachments = [
47
+ {
48
+ url: 'https://app.dev.devrev-eng.ai/favicon.ico',
49
+ id: 'attachment-1',
50
+ file_name: 'dummy.jpg',
51
+ author_id: 'user-1',
52
+ parent_id: 'issue-1',
53
+ },
54
+ {
55
+ url: 'https://app.dev.devrev-eng.ai/favicon.ico',
56
+ id: 'attachment-2',
57
+ file_name: 'dummy.ico',
58
+ author_id: 'user-2',
59
+ parent_id: 'issue-2',
60
+ },
61
+ ];
62
+ const repos = [
63
+ {
64
+ itemType: 'issues',
65
+ normalize: data_normalization_1.normalizeIssue,
66
+ },
67
+ {
68
+ itemType: 'users',
69
+ normalize: data_normalization_1.normalizeUser,
70
+ },
71
+ {
72
+ itemType: 'attachments',
73
+ normalize: data_normalization_1.normalizeAttachment,
74
+ },
75
+ ];
76
+ (0, index_1.processTask)({
77
+ task: async ({ adapter }) => {
78
+ var _a, _b, _c;
79
+ console.log('Logging something from worker thread', {});
80
+ adapter.initializeRepos(repos);
81
+ if (adapter.event.payload.event_type === index_1.EventType.ExtractionDataStart) {
82
+ await ((_a = adapter.getRepo('issues')) === null || _a === void 0 ? void 0 : _a.push(issues));
83
+ await adapter.emit(index_1.ExtractorEventType.ExtractionDataProgress, {
84
+ progress: 50,
85
+ });
86
+ }
87
+ else {
88
+ await ((_b = adapter.getRepo('users')) === null || _b === void 0 ? void 0 : _b.push(users));
89
+ await ((_c = adapter.getRepo('attachments')) === null || _c === void 0 ? void 0 : _c.push(attachments));
90
+ await adapter.emit(index_1.ExtractorEventType.ExtractionDataDone, {
91
+ progress: 100,
92
+ });
93
+ }
94
+ },
95
+ onTimeout: async ({ adapter }) => {
96
+ await adapter.postState();
97
+ await adapter.emit(index_1.ExtractorEventType.ExtractionDataProgress, {
98
+ progress: 50,
99
+ });
100
+ },
101
+ });
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../../index");
4
+ // Dummy data that originally would be fetched from an external source
5
+ const externalSyncUnits = [
6
+ {
7
+ id: 'devrev',
8
+ name: 'devrev',
9
+ description: 'Demo external sync unit',
10
+ item_count: 2,
11
+ item_type: 'issues',
12
+ },
13
+ ];
14
+ (0, index_1.processTask)({
15
+ task: async ({ adapter }) => {
16
+ await adapter.emit(index_1.ExtractorEventType.ExtractionExternalSyncUnitsDone, {
17
+ external_sync_units: externalSyncUnits,
18
+ });
19
+ },
20
+ onTimeout: async ({ adapter }) => {
21
+ await adapter.emit(index_1.ExtractorEventType.ExtractionExternalSyncUnitsError, {
22
+ error: {
23
+ message: 'Failed to extract external sync units. Lambda timeout.',
24
+ },
25
+ });
26
+ },
27
+ });
@@ -0,0 +1,26 @@
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
+ const index_1 = require("../../index");
7
+ const external_domain_metadata_json_1 = __importDefault(require("../dummy-extractor/external_domain_metadata.json"));
8
+ const repos = [
9
+ {
10
+ itemType: 'external_domain_metadata',
11
+ },
12
+ ];
13
+ (0, index_1.processTask)({
14
+ task: async ({ adapter }) => {
15
+ var _a;
16
+ adapter.initializeRepos(repos);
17
+ await ((_a = adapter
18
+ .getRepo('external_domain_metadata')) === null || _a === void 0 ? void 0 : _a.push([external_domain_metadata_json_1.default]));
19
+ await adapter.emit(index_1.ExtractorEventType.ExtractionMetadataDone);
20
+ },
21
+ onTimeout: async ({ adapter }) => {
22
+ await adapter.emit(index_1.ExtractorEventType.ExtractionMetadataError, {
23
+ error: { message: 'Failed to extract metadata. Lambda timeout.' },
24
+ });
25
+ },
26
+ });
@@ -0,0 +1,4 @@
1
+ import { NormalizedItem, NormalizedAttachment } from '../../index';
2
+ export declare function normalizeIssue(item: any): NormalizedItem;
3
+ export declare function normalizeUser(item: any): NormalizedItem;
4
+ export declare function normalizeAttachment(item: any): NormalizedAttachment;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeIssue = normalizeIssue;
4
+ exports.normalizeUser = normalizeUser;
5
+ exports.normalizeAttachment = normalizeAttachment;
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ function normalizeIssue(item) {
8
+ return {
9
+ id: item.id,
10
+ created_date: item.created_date,
11
+ modified_date: item.modified_date,
12
+ data: {
13
+ body: item.body,
14
+ creator: item.creator,
15
+ owner: item.owner,
16
+ title: item.title,
17
+ },
18
+ };
19
+ }
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ function normalizeUser(item) {
22
+ return {
23
+ id: item.id,
24
+ created_date: item.created_date,
25
+ modified_date: item.modified_date,
26
+ data: {
27
+ email: item.email,
28
+ name: item.name,
29
+ },
30
+ };
31
+ }
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ function normalizeAttachment(item) {
34
+ return {
35
+ url: item.url,
36
+ id: item.id,
37
+ file_name: item.file_name,
38
+ author_id: item.author_id,
39
+ parent_id: item.parent_id,
40
+ };
41
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "record_types": {
3
+ "issues": {
4
+ "name": "Issues",
5
+ "fields": {
6
+ "title": {
7
+ "is_required": true,
8
+ "type": "text",
9
+ "name": "Title",
10
+ "text": {
11
+ "min_length": 1
12
+ }
13
+ },
14
+ "body": {
15
+ "type": "rich_text",
16
+ "name": "body",
17
+ "is_required": true
18
+ },
19
+ "owner": {
20
+ "is_required": true,
21
+ "type": "reference",
22
+ "reference": {
23
+ "refers_to": {
24
+ "#record:users": {}
25
+ }
26
+ }
27
+ },
28
+ "creator": {
29
+ "is_required": true,
30
+ "type": "reference",
31
+ "reference": {
32
+ "refers_to": {
33
+ "#record:users": {}
34
+ }
35
+ }
36
+ }
37
+ }
38
+ },
39
+ "users": {
40
+ "name": "Users",
41
+ "fields": {
42
+ "name": {
43
+ "is_required": true,
44
+ "type": "text",
45
+ "name": "Name",
46
+ "text": {
47
+ "min_length": 1
48
+ }
49
+ },
50
+ "email": {
51
+ "type": "text",
52
+ "name": "Email",
53
+ "is_required": true
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,2 @@
1
+ import { ProcessTaskInterface } from '../types/workers';
2
+ export declare function processTask<ConnectorState>({ task, onTimeout, }: ProcessTaskInterface<ConnectorState>): void;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processTask = processTask;
4
+ const node_worker_threads_1 = require("node:worker_threads");
5
+ const state_1 = require("../state/state");
6
+ const worker_adapter_1 = require("./worker-adapter");
7
+ const workers_1 = require("../types/workers");
8
+ const logger_1 = require("../logger/logger");
9
+ function processTask({ task, onTimeout, }) {
10
+ if (!node_worker_threads_1.isMainThread) {
11
+ (async () => {
12
+ const event = node_worker_threads_1.workerData.event;
13
+ const initialState = node_worker_threads_1.workerData.initialState;
14
+ const options = node_worker_threads_1.workerData.options;
15
+ console = new logger_1.Logger(event);
16
+ const adapterState = await (0, state_1.createAdapterState)({
17
+ event,
18
+ initialState,
19
+ options,
20
+ });
21
+ if (node_worker_threads_1.parentPort && node_worker_threads_1.workerData.event) {
22
+ const adapter = new worker_adapter_1.WorkerAdapter({
23
+ event,
24
+ adapterState,
25
+ parentPort: node_worker_threads_1.parentPort,
26
+ options,
27
+ });
28
+ node_worker_threads_1.parentPort.on(workers_1.WorkerEvent.WorkerMessage, async (message) => {
29
+ if (message.subject === workers_1.WorkerMessageSubject.WorkerMessageExit) {
30
+ adapter.handleTimeout();
31
+ await onTimeout({ adapter });
32
+ process.exit(0);
33
+ }
34
+ });
35
+ await task({ adapter });
36
+ const message = {
37
+ subject: workers_1.WorkerMessageSubject.WorkerMessageDone,
38
+ };
39
+ node_worker_threads_1.parentPort.postMessage(message);
40
+ process.exit(0);
41
+ }
42
+ })();
43
+ }
44
+ }
@@ -0,0 +1,25 @@
1
+ import { SpawnFactoryInterface, SpawnInterface } from '../types/workers';
2
+ /**
3
+ * Creates a new instance of Spawn class.
4
+ * Spawn class is responsible for spawning a new worker thread and managing the lifecycle of the worker.
5
+ * The class provides utilities to emit control events to the platform and exit the worker gracefully.
6
+ * In case of lambda timeout, the class emits a lambda timeout event to the platform.
7
+ * @param {SpawnFactoryInterface} options - The options to create a new instance of Spawn class
8
+ * @param {AirdropEvent} event - The event object received from the platform
9
+ * @param {object} initialState - The initial state of the adapter
10
+ * @param {string} workerPath - The path to the worker file
11
+ * @returns {Promise<Spawn>} - A new instance of Spawn class
12
+ */
13
+ export declare function spawn<ConnectorState>({ event, initialState, workerPath, options, }: SpawnFactoryInterface<ConnectorState>): Promise<boolean | PromiseLike<boolean>>;
14
+ export declare class Spawn {
15
+ private event;
16
+ private hasWorkerEmitted;
17
+ private defaultLambdaTimeout;
18
+ private lambdaTimeout;
19
+ private worker;
20
+ private resolve;
21
+ private timer;
22
+ private logger;
23
+ constructor({ event, worker, options, resolve }: SpawnInterface);
24
+ private exitFromMainThread;
25
+ }
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Spawn = void 0;
4
+ exports.spawn = spawn;
5
+ const extraction_1 = require("../types/extraction");
6
+ const control_protocol_1 = require("../common/control-protocol");
7
+ const helpers_1 = require("../common/helpers");
8
+ const logger_1 = require("../logger/logger");
9
+ const constants_1 = require("../common/constants");
10
+ const workers_1 = require("../types/workers");
11
+ const create_worker_1 = require("./create-worker");
12
+ function getWorkerPath({ event, connectorWorkerPath, }) {
13
+ const logger = new logger_1.Logger(event);
14
+ if (!constants_1.ALLOWED_EVENT_TYPES.includes(event.payload.event_type)) {
15
+ return null;
16
+ }
17
+ if (connectorWorkerPath)
18
+ return connectorWorkerPath;
19
+ let path = null;
20
+ switch (event.payload.event_type) {
21
+ case extraction_1.EventType.ExtractionExternalSyncUnitsStart:
22
+ path = __dirname + '/default-workers/external-sync-units-extraction';
23
+ break;
24
+ case extraction_1.EventType.ExtractionMetadataStart:
25
+ path = __dirname + '/default-workers/metadata-extraction';
26
+ break;
27
+ case extraction_1.EventType.ExtractionDataStart:
28
+ case extraction_1.EventType.ExtractionDataContinue:
29
+ path = __dirname + '/default-workers/data-extraction';
30
+ break;
31
+ case extraction_1.EventType.ExtractionAttachmentsStart:
32
+ case extraction_1.EventType.ExtractionAttachmentsContinue:
33
+ path = __dirname + '/default-workers/attachments-extraction';
34
+ break;
35
+ case extraction_1.EventType.ExtractionDataDelete:
36
+ path = __dirname + '/default-workers/data-deletion.js';
37
+ break;
38
+ case extraction_1.EventType.ExtractionAttachmentsDelete:
39
+ path = __dirname + '/default-workers/attachments-deletion';
40
+ break;
41
+ default:
42
+ logger.error('Worker script not found for event type: ' +
43
+ event.payload.event_type +
44
+ '.');
45
+ path = null;
46
+ }
47
+ return path;
48
+ }
49
+ /**
50
+ * Creates a new instance of Spawn class.
51
+ * Spawn class is responsible for spawning a new worker thread and managing the lifecycle of the worker.
52
+ * The class provides utilities to emit control events to the platform and exit the worker gracefully.
53
+ * In case of lambda timeout, the class emits a lambda timeout event to the platform.
54
+ * @param {SpawnFactoryInterface} options - The options to create a new instance of Spawn class
55
+ * @param {AirdropEvent} event - The event object received from the platform
56
+ * @param {object} initialState - The initial state of the adapter
57
+ * @param {string} workerPath - The path to the worker file
58
+ * @returns {Promise<Spawn>} - A new instance of Spawn class
59
+ */
60
+ async function spawn({ event, initialState, workerPath, options, }) {
61
+ const logger = new logger_1.Logger(event);
62
+ const script = getWorkerPath({
63
+ event,
64
+ connectorWorkerPath: workerPath,
65
+ });
66
+ if (script) {
67
+ try {
68
+ const worker = await (0, create_worker_1.createWorker)({
69
+ event,
70
+ initialState,
71
+ workerPath: script,
72
+ options,
73
+ });
74
+ return new Promise((resolve) => {
75
+ new Spawn({
76
+ event,
77
+ worker,
78
+ options: options || null,
79
+ resolve,
80
+ });
81
+ });
82
+ }
83
+ catch (error) {
84
+ logger.error('Worker error while processing task.', error);
85
+ return false;
86
+ }
87
+ }
88
+ else {
89
+ throw new Error('Worker script not found.');
90
+ }
91
+ }
92
+ class Spawn {
93
+ constructor({ event, worker, options, resolve }) {
94
+ this.defaultLambdaTimeout = 10 * 60 * 1000; // 10 minutes in milliseconds
95
+ this.hasWorkerEmitted = false;
96
+ this.event = event;
97
+ this.lambdaTimeout = (options === null || options === void 0 ? void 0 : options.timeout)
98
+ ? Math.min(options.timeout, this.defaultLambdaTimeout)
99
+ : this.defaultLambdaTimeout;
100
+ this.resolve = resolve;
101
+ this.timer = setTimeout(async () => {
102
+ this.logger.log('Lambda timeout reached. Exiting.');
103
+ if (this.worker) {
104
+ this.worker.postMessage({
105
+ subject: workers_1.WorkerMessageSubject.WorkerMessageExit,
106
+ });
107
+ }
108
+ else {
109
+ await this.exitFromMainThread();
110
+ }
111
+ }, this.lambdaTimeout);
112
+ this.logger = new logger_1.Logger(event);
113
+ this.worker = worker;
114
+ worker.on(workers_1.WorkerEvent.WorkerExit, async (code) => {
115
+ this.logger.info('Worker exited with exit code: ' + code + '.');
116
+ if (this.timer) {
117
+ clearTimeout(this.timer);
118
+ await this.exitFromMainThread();
119
+ }
120
+ });
121
+ worker.on(workers_1.WorkerEvent.WorkerMessage, async (message) => {
122
+ if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageEmitted) {
123
+ this.logger.info('Worker has emitted message to ADaaS.');
124
+ this.hasWorkerEmitted = true;
125
+ }
126
+ if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageDone) {
127
+ this.logger.info('Worker has completed work.');
128
+ clearTimeout(this.timer);
129
+ await this.exitFromMainThread();
130
+ }
131
+ });
132
+ worker.on(workers_1.WorkerEvent.WorkerMessage, (message) => {
133
+ var _a, _b;
134
+ if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageLog) {
135
+ const args = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.args;
136
+ const level = (_b = message.payload) === null || _b === void 0 ? void 0 : _b.level;
137
+ this.logger.logFn(args, level);
138
+ }
139
+ });
140
+ }
141
+ async exitFromMainThread() {
142
+ if (this.hasWorkerEmitted) {
143
+ return;
144
+ }
145
+ const timeoutEventType = (0, helpers_1.getErrorExtractorEventType)(this.event.payload.event_type);
146
+ if (timeoutEventType !== null) {
147
+ const { eventType } = timeoutEventType;
148
+ await (0, control_protocol_1.emit)({
149
+ eventType,
150
+ event: this.event,
151
+ data: {
152
+ error: {
153
+ message: 'Worker has not emitted anything. Exited.',
154
+ },
155
+ },
156
+ }).then(() => {
157
+ this.logger.error('Worker has not emitted anything. Exited.');
158
+ this.resolve(true);
159
+ });
160
+ }
161
+ }
162
+ }
163
+ exports.Spawn = Spawn;