@devrev/airsync-sdk 2.0.0-beta.0 → 2.0.0-beta.2

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 (157) hide show
  1. package/README.md +0 -4
  2. package/dist/airsync-sdk.d.ts +1802 -0
  3. package/dist/attachments-streaming/attachments-streaming-pool.d.ts +7 -0
  4. package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
  5. package/dist/attachments-streaming/attachments-streaming-pool.js +44 -4
  6. package/dist/attachments-streaming/attachments-streaming-pool.test.js +259 -10
  7. package/dist/common/constants.d.ts +16 -5
  8. package/dist/common/constants.d.ts.map +1 -1
  9. package/dist/common/constants.js +20 -6
  10. package/dist/common/control-protocol.d.ts +2 -2
  11. package/dist/common/control-protocol.d.ts.map +1 -1
  12. package/dist/common/control-protocol.js +1 -5
  13. package/dist/common/helpers.d.ts +8 -0
  14. package/dist/common/helpers.d.ts.map +1 -1
  15. package/dist/common/helpers.js +15 -0
  16. package/dist/common/install-initial-domain-mapping.d.ts +2 -2
  17. package/dist/common/install-initial-domain-mapping.test.js +7 -3
  18. package/dist/common/test-utils.d.ts +19 -0
  19. package/dist/common/test-utils.d.ts.map +1 -0
  20. package/dist/common/test-utils.js +101 -0
  21. package/dist/common/time-value-resolver.d.ts +47 -0
  22. package/dist/common/time-value-resolver.d.ts.map +1 -0
  23. package/dist/common/time-value-resolver.js +141 -0
  24. package/dist/common/time-value-resolver.test.d.ts +2 -0
  25. package/dist/common/time-value-resolver.test.d.ts.map +1 -0
  26. package/dist/common/time-value-resolver.test.js +268 -0
  27. package/dist/http/axios-client-internal.d.ts.map +1 -1
  28. package/dist/http/axios-client-internal.js +7 -0
  29. package/dist/http/axios-client-internal.test.js +27 -6
  30. package/dist/http/axios-client.d.ts.map +1 -1
  31. package/dist/http/axios-client.js +6 -3
  32. package/dist/http/index.d.ts +0 -1
  33. package/dist/http/index.d.ts.map +1 -1
  34. package/dist/http/index.js +0 -1
  35. package/dist/index.d.ts +9 -8
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +12 -10
  38. package/dist/logger/logger.d.ts +1 -17
  39. package/dist/logger/logger.d.ts.map +1 -1
  40. package/dist/logger/logger.interfaces.d.ts +2 -2
  41. package/dist/logger/logger.js +35 -27
  42. package/dist/logger/logger.test.js +66 -19
  43. package/dist/mappers/mappers.interface.d.ts +5 -5
  44. package/dist/mappers/mappers.interface.js +3 -3
  45. package/dist/mappers/mappers.test.js +8 -10
  46. package/dist/mock-server/mock-server.d.ts +47 -0
  47. package/dist/mock-server/mock-server.d.ts.map +1 -0
  48. package/dist/mock-server/mock-server.interfaces.d.ts +73 -0
  49. package/dist/mock-server/mock-server.interfaces.d.ts.map +1 -0
  50. package/dist/mock-server/mock-server.interfaces.js +4 -0
  51. package/dist/mock-server/mock-server.js +278 -0
  52. package/dist/multithreading/create-worker.test.js +36 -17
  53. package/dist/multithreading/process-task.d.ts.map +1 -1
  54. package/dist/multithreading/process-task.js +46 -44
  55. package/dist/multithreading/process-task.test.d.ts +2 -0
  56. package/dist/multithreading/process-task.test.d.ts.map +1 -0
  57. package/dist/multithreading/process-task.test.js +146 -0
  58. package/dist/multithreading/spawn/spawn.d.ts +4 -3
  59. package/dist/multithreading/spawn/spawn.d.ts.map +1 -1
  60. package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -1
  61. package/dist/multithreading/spawn/spawn.helpers.js +6 -14
  62. package/dist/multithreading/spawn/spawn.helpers.test.js +8 -8
  63. package/dist/multithreading/spawn/spawn.js +41 -31
  64. package/dist/multithreading/spawn/spawn.test.d.ts +2 -0
  65. package/dist/multithreading/spawn/spawn.test.d.ts.map +1 -0
  66. package/dist/multithreading/spawn/spawn.test.js +232 -0
  67. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.js +49 -1
  68. package/dist/multithreading/worker-adapter/worker-adapter.d.ts +11 -5
  69. package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +1 -1
  70. package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts +2 -0
  71. package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts.map +1 -0
  72. package/dist/multithreading/worker-adapter/worker-adapter.emit.test.js +390 -0
  73. package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts +2 -0
  74. package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts.map +1 -0
  75. package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.js +799 -0
  76. package/dist/multithreading/worker-adapter/worker-adapter.js +233 -134
  77. package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts +2 -0
  78. package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts.map +1 -0
  79. package/dist/multithreading/worker-adapter/worker-adapter.loading.test.js +596 -0
  80. package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts +2 -0
  81. package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts.map +1 -0
  82. package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.js +71 -0
  83. package/dist/repo/repo.d.ts.map +1 -1
  84. package/dist/repo/repo.interfaces.d.ts +4 -2
  85. package/dist/repo/repo.interfaces.d.ts.map +1 -1
  86. package/dist/repo/repo.js +4 -3
  87. package/dist/repo/repo.test.js +60 -7
  88. package/dist/state/state.d.ts +7 -1
  89. package/dist/state/state.d.ts.map +1 -1
  90. package/dist/state/state.extract-window.test.d.ts +2 -0
  91. package/dist/state/state.extract-window.test.d.ts.map +1 -0
  92. package/dist/state/state.extract-window.test.js +163 -0
  93. package/dist/state/state.interfaces.d.ts +25 -8
  94. package/dist/state/state.interfaces.d.ts.map +1 -1
  95. package/dist/state/state.interfaces.js +4 -2
  96. package/dist/state/state.js +111 -12
  97. package/dist/state/state.pending-boundaries.test.d.ts +2 -0
  98. package/dist/state/state.pending-boundaries.test.d.ts.map +1 -0
  99. package/dist/state/state.pending-boundaries.test.js +189 -0
  100. package/dist/state/state.post-state.test.d.ts +2 -0
  101. package/dist/state/state.post-state.test.d.ts.map +1 -0
  102. package/dist/state/state.post-state.test.js +77 -0
  103. package/dist/state/state.test.js +117 -73
  104. package/dist/state/state.time-value-resolution.test.d.ts +2 -0
  105. package/dist/state/state.time-value-resolution.test.d.ts.map +1 -0
  106. package/dist/state/state.time-value-resolution.test.js +175 -0
  107. package/dist/tsdoc-metadata.json +11 -0
  108. package/dist/types/common.d.ts +0 -25
  109. package/dist/types/common.d.ts.map +1 -1
  110. package/dist/types/common.js +1 -11
  111. package/dist/types/external-domain-metadata.d.ts +338 -0
  112. package/dist/types/external-domain-metadata.d.ts.map +1 -0
  113. package/dist/types/extraction.d.ts +89 -218
  114. package/dist/types/extraction.d.ts.map +1 -1
  115. package/dist/types/extraction.js +56 -124
  116. package/dist/types/extraction.test.js +69 -43
  117. package/dist/types/index.d.ts +4 -2
  118. package/dist/types/index.d.ts.map +1 -1
  119. package/dist/types/index.js +6 -3
  120. package/dist/types/loading.d.ts +4 -24
  121. package/dist/types/loading.d.ts.map +1 -1
  122. package/dist/types/loading.js +1 -22
  123. package/dist/types/workers.d.ts +31 -14
  124. package/dist/types/workers.d.ts.map +1 -1
  125. package/dist/types/workers.js +1 -0
  126. package/dist/uploader/uploader.d.ts +1 -0
  127. package/dist/uploader/uploader.d.ts.map +1 -1
  128. package/dist/uploader/uploader.helpers.test.js +0 -11
  129. package/dist/uploader/uploader.interfaces.d.ts +3 -3
  130. package/dist/uploader/uploader.js +53 -20
  131. package/dist/uploader/uploader.test.js +22 -10
  132. package/package.json +12 -11
  133. package/dist/common/event-type-translation.d.ts +0 -24
  134. package/dist/common/event-type-translation.d.ts.map +0 -1
  135. package/dist/common/event-type-translation.js +0 -117
  136. package/dist/deprecated/adapter/index.d.ts +0 -62
  137. package/dist/deprecated/adapter/index.d.ts.map +0 -1
  138. package/dist/deprecated/adapter/index.js +0 -151
  139. package/dist/deprecated/common/helpers.d.ts +0 -7
  140. package/dist/deprecated/common/helpers.d.ts.map +0 -1
  141. package/dist/deprecated/common/helpers.js +0 -47
  142. package/dist/deprecated/demo-extractor/external_domain_metadata.json +0 -38
  143. package/dist/deprecated/demo-extractor/index.d.ts +0 -18
  144. package/dist/deprecated/demo-extractor/index.d.ts.map +0 -1
  145. package/dist/deprecated/demo-extractor/index.js +0 -161
  146. package/dist/deprecated/http/client.d.ts +0 -22
  147. package/dist/deprecated/http/client.d.ts.map +0 -1
  148. package/dist/deprecated/http/client.js +0 -161
  149. package/dist/deprecated/uploader/index.d.ts +0 -35
  150. package/dist/deprecated/uploader/index.d.ts.map +0 -1
  151. package/dist/deprecated/uploader/index.js +0 -161
  152. package/dist/http/types.d.ts +0 -17
  153. package/dist/http/types.d.ts.map +0 -1
  154. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +0 -2
  155. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +0 -1
  156. package/dist/multithreading/worker-adapter/worker-adapter.test.js +0 -483
  157. /package/dist/{http/types.js → types/external-domain-metadata.js} +0 -0
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const extraction_1 = require("../types/extraction");
4
+ const workers_1 = require("../types/workers");
5
+ // These tests cover logic that is NOT exercised by the end-to-end integration
6
+ // tests under src/tests/timeout-handling/:
7
+ // - translation of legacy wire event types into the new enum (mutates event in place)
8
+ // - the hasWorkerEmitted guard that prevents onTimeout from firing after a
9
+ // successful emit (integration tests only exercise the positive case)
10
+ // - the error branch that posts WorkerMessageFailed and exits(1)
11
+ // - the WorkerMessage handler's guard that only flips isTimeout on
12
+ // WorkerMessageExit (integration tests can't cleanly target non-Exit messages)
13
+ //
14
+ // Tests for the happy path, timeout-signal-reaches-worker behavior, and main-thread
15
+ // early return were removed — they either duplicate what the integration suite
16
+ // already exercises or assert mocked behavior with little signal.
17
+ const mockParentPortPostMessage = jest.fn();
18
+ const mockParentPortOn = jest.fn();
19
+ let mockIsMainThread = false;
20
+ jest.mock('node:worker_threads', () => ({
21
+ get isMainThread() {
22
+ return mockIsMainThread;
23
+ },
24
+ get parentPort() {
25
+ return {
26
+ postMessage: mockParentPortPostMessage,
27
+ on: mockParentPortOn,
28
+ };
29
+ },
30
+ get workerData() {
31
+ var _a;
32
+ return (_a = global.__workerData__) !== null && _a !== void 0 ? _a : {};
33
+ },
34
+ }));
35
+ jest.mock('../logger/logger', () => ({
36
+ Logger: jest.fn().mockImplementation(() => ({
37
+ log: jest.fn(),
38
+ warn: jest.fn(),
39
+ error: jest.fn(),
40
+ info: jest.fn(),
41
+ logFn: jest.fn(),
42
+ })),
43
+ serializeError: jest.fn((e) => String(e)),
44
+ }));
45
+ jest.mock('../logger/logger.context', () => ({
46
+ runWithSdkLogContext: jest.fn((fn) => fn()),
47
+ runWithUserLogContext: jest.fn((fn) => fn()),
48
+ }));
49
+ jest.mock('../state/state', () => ({
50
+ createAdapterState: jest.fn(),
51
+ }));
52
+ jest.mock('./worker-adapter/worker-adapter', () => ({
53
+ WorkerAdapter: jest.fn().mockImplementation(() => ({
54
+ isTimeout: false,
55
+ hasWorkerEmitted: false,
56
+ })),
57
+ }));
58
+ const process_task_1 = require("./process-task");
59
+ const state_1 = require("../state/state");
60
+ const worker_adapter_1 = require("./worker-adapter/worker-adapter");
61
+ const test_utils_1 = require("../common/test-utils");
62
+ function setWorkerData(data) {
63
+ global.__workerData__ = data;
64
+ }
65
+ function makeEvent(eventType = extraction_1.EventType.StartExtractingData) {
66
+ return (0, test_utils_1.createMockEvent)('http://localhost:0', {
67
+ payload: { event_type: eventType },
68
+ });
69
+ }
70
+ // Flush the microtask queue enough to let the async IIFE inside processTask run.
71
+ const flush = async () => new Promise((r) => setTimeout(r, 0));
72
+ describe(process_task_1.processTask.name, () => {
73
+ let processExitSpy;
74
+ beforeEach(() => {
75
+ jest.clearAllMocks();
76
+ mockIsMainThread = false;
77
+ processExitSpy = jest
78
+ .spyOn(process, 'exit')
79
+ .mockImplementation((() => { }));
80
+ state_1.createAdapterState.mockResolvedValue({});
81
+ });
82
+ afterEach(() => {
83
+ processExitSpy.mockRestore();
84
+ });
85
+ it('should NOT call onTimeout when the worker already emitted before timeout check', async () => {
86
+ // Arrange
87
+ const event = makeEvent();
88
+ setWorkerData({ event, initialState: {}, options: {} });
89
+ // Both flags true: a timeout arrived but the worker had already emitted —
90
+ // onTimeout must be skipped. This is the guard the integration suite cannot
91
+ // target cleanly because it requires a precise race between emit and timeout.
92
+ const mockAdapter = { isTimeout: true, hasWorkerEmitted: true };
93
+ worker_adapter_1.WorkerAdapter.mockImplementation(() => mockAdapter);
94
+ const task = jest.fn().mockResolvedValue(undefined);
95
+ const onTimeout = jest.fn().mockResolvedValue(undefined);
96
+ // Act
97
+ (0, process_task_1.processTask)({ task, onTimeout });
98
+ await flush();
99
+ // Assert
100
+ expect(onTimeout).not.toHaveBeenCalled();
101
+ expect(processExitSpy).toHaveBeenCalledWith(0);
102
+ });
103
+ it('should NOT flip adapter.isTimeout when a non-Exit WorkerMessage arrives', async () => {
104
+ // Arrange
105
+ const event = makeEvent();
106
+ setWorkerData({ event, initialState: {}, options: {} });
107
+ const mockAdapter = { isTimeout: false, hasWorkerEmitted: false };
108
+ worker_adapter_1.WorkerAdapter.mockImplementation(() => mockAdapter);
109
+ const task = jest.fn().mockResolvedValue(undefined);
110
+ const onTimeout = jest.fn().mockResolvedValue(undefined);
111
+ // Act
112
+ (0, process_task_1.processTask)({ task, onTimeout });
113
+ await flush();
114
+ // Grab the handler registered for WorkerMessage events and invoke it with
115
+ // subjects that must NOT flip isTimeout (log messages, unknown subjects).
116
+ const messageHandlerCall = mockParentPortOn.mock.calls.find(([eventName]) => eventName === workers_1.WorkerEvent.WorkerMessage);
117
+ expect(messageHandlerCall).toBeDefined();
118
+ const handler = messageHandlerCall[1];
119
+ handler({ subject: workers_1.WorkerMessageSubject.WorkerMessageLog });
120
+ handler({ subject: 'NONSENSE_SUBJECT' });
121
+ // Assert
122
+ expect(mockAdapter.isTimeout).toBe(false);
123
+ });
124
+ it('should post WorkerMessageFailed with the error message and exit(1) when task throws', async () => {
125
+ // Arrange
126
+ const event = makeEvent();
127
+ setWorkerData({ event, initialState: {}, options: {} });
128
+ const mockAdapter = { isTimeout: false, hasWorkerEmitted: false };
129
+ worker_adapter_1.WorkerAdapter.mockImplementation(() => mockAdapter);
130
+ const taskError = new Error('task boom');
131
+ const task = jest.fn().mockRejectedValue(taskError);
132
+ const onTimeout = jest.fn().mockResolvedValue(undefined);
133
+ // Act
134
+ (0, process_task_1.processTask)({ task, onTimeout });
135
+ await flush();
136
+ // Assert
137
+ expect(mockParentPortPostMessage).toHaveBeenCalledWith(expect.objectContaining({
138
+ subject: workers_1.WorkerMessageSubject.WorkerMessageFailed,
139
+ payload: expect.objectContaining({
140
+ message: expect.stringContaining('task boom'),
141
+ }),
142
+ }));
143
+ expect(processExitSpy).toHaveBeenCalledWith(1);
144
+ expect(onTimeout).not.toHaveBeenCalled();
145
+ });
146
+ });
@@ -5,16 +5,16 @@ import { SpawnFactoryInterface, SpawnInterface } from '../../types/workers';
5
5
  * The class provides utilities to emit control events to the platform and exit the worker gracefully.
6
6
  * In case of lambda timeout, the class emits a lambda timeout event to the platform.
7
7
  * @param {SpawnFactoryInterface} options - The options to create a new instance of Spawn class
8
- * @param {AirdropEvent} options.event - The event object received from the platform
8
+ * @param {AirSyncEvent} options.event - The event object received from the platform
9
9
  * @param {object} options.initialState - The initial state of the adapter
10
- * @param {string} [options.workerPath] Remove getWorkerPath function and use baseWorkerPath: __dirname instead of workerPath
11
10
  * @param {string} [options.baseWorkerPath] - The base path for the worker files, usually `__dirname`
12
11
  * @returns {Promise<Spawn>} - A new instance of Spawn class
13
12
  */
14
- export declare function spawn<ConnectorState>({ event, initialState, workerPath, initialDomainMapping, options, baseWorkerPath, }: SpawnFactoryInterface<ConnectorState>): Promise<void>;
13
+ export declare function spawn<ConnectorState>({ event, initialState, initialDomainMapping, options, baseWorkerPath, }: SpawnFactoryInterface<ConnectorState>): Promise<void>;
15
14
  export declare class Spawn {
16
15
  private event;
17
16
  private alreadyEmitted;
17
+ private softTimeoutSent;
18
18
  private defaultLambdaTimeout;
19
19
  private lambdaTimeout;
20
20
  private softTimeoutTimer;
@@ -23,6 +23,7 @@ export declare class Spawn {
23
23
  private resolve;
24
24
  private originalConsole;
25
25
  private logger;
26
+ private workerFailedMessage;
26
27
  constructor({ event, worker, options, resolve, originalConsole, }: SpawnInterface);
27
28
  private clearTimeouts;
28
29
  private exitFromMainThread;
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,qBAAqB,CAAC;AA+C7B;;;;;;;;;;;GAWG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,cAAc,GACf,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,MAAM,CAAS;gBACX,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,GAChB,EAAE,cAAc;IAiGjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAiCjC"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,qBAAqB,CAAC;AA+C7B;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,oBAAoB,EACpB,OAAO,EACP,cAAc,GACf,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyEvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,mBAAmB,CAAqB;gBACpC,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,GAChB,EAAE,cAAc;IAiHjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAoCjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.helpers.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG;IAC9D,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;CACjD,CAmFA;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS;;;;EA2BxD"}
1
+ {"version":3,"file":"spawn.helpers.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG;IAC9D,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;CACjD,CA2EA;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS;;;;EA2BxD"}
@@ -11,43 +11,35 @@ const loading_1 = require("../../types/loading");
11
11
  */
12
12
  function getTimeoutErrorEventType(eventType) {
13
13
  switch (eventType) {
14
- // Metadata extraction (handles both old and new enum members)
14
+ // Metadata extraction
15
15
  case extraction_1.EventType.StartExtractingMetadata:
16
- case extraction_1.EventType.ExtractionMetadataStart:
17
16
  return {
18
17
  eventType: extraction_1.ExtractorEventType.MetadataExtractionError,
19
18
  };
20
- // Data extraction (handles both old and new enum members)
19
+ // Data extraction
21
20
  case extraction_1.EventType.StartExtractingData:
22
21
  case extraction_1.EventType.ContinueExtractingData:
23
- case extraction_1.EventType.ExtractionDataStart:
24
- case extraction_1.EventType.ExtractionDataContinue:
25
22
  return {
26
23
  eventType: extraction_1.ExtractorEventType.DataExtractionError,
27
24
  };
28
- // Data deletion (handles both old and new enum members)
25
+ // Data deletion
29
26
  case extraction_1.EventType.StartDeletingExtractorState:
30
- case extraction_1.EventType.ExtractionDataDelete:
31
27
  return {
32
28
  eventType: extraction_1.ExtractorEventType.ExtractorStateDeletionError,
33
29
  };
34
- // Attachments extraction (handles both old and new enum members)
30
+ // Attachments extraction
35
31
  case extraction_1.EventType.StartExtractingAttachments:
36
32
  case extraction_1.EventType.ContinueExtractingAttachments:
37
- case extraction_1.EventType.ExtractionAttachmentsStart:
38
- case extraction_1.EventType.ExtractionAttachmentsContinue:
39
33
  return {
40
34
  eventType: extraction_1.ExtractorEventType.AttachmentExtractionError,
41
35
  };
42
- // Attachments deletion (handles both old and new enum members)
36
+ // Attachments deletion
43
37
  case extraction_1.EventType.StartDeletingExtractorAttachmentsState:
44
- case extraction_1.EventType.ExtractionAttachmentsDelete:
45
38
  return {
46
39
  eventType: extraction_1.ExtractorEventType.ExtractorAttachmentsStateDeletionError,
47
40
  };
48
- // External sync units (handles both old and new enum members)
41
+ // External sync units
49
42
  case extraction_1.EventType.StartExtractingExternalSyncUnits:
50
- case extraction_1.EventType.ExtractionExternalSyncUnitsStart:
51
43
  return {
52
44
  eventType: extraction_1.ExtractorEventType.ExternalSyncUnitExtractionError,
53
45
  };
@@ -15,7 +15,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
15
15
  });
16
16
  it('should return MetadataExtractionError for deprecated ExtractionMetadataStart', () => {
17
17
  // Arrange
18
- const eventType = extraction_1.EventType.ExtractionMetadataStart;
18
+ const eventType = extraction_1.EventType.StartExtractingMetadata;
19
19
  // Act
20
20
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
21
21
  // Assert
@@ -41,7 +41,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
41
41
  });
42
42
  it('should return DataExtractionError for deprecated ExtractionDataStart', () => {
43
43
  // Arrange
44
- const eventType = extraction_1.EventType.ExtractionDataStart;
44
+ const eventType = extraction_1.EventType.StartExtractingData;
45
45
  // Act
46
46
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
47
47
  // Assert
@@ -49,7 +49,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
49
49
  });
50
50
  it('should return DataExtractionError for deprecated ExtractionDataContinue', () => {
51
51
  // Arrange
52
- const eventType = extraction_1.EventType.ExtractionDataContinue;
52
+ const eventType = extraction_1.EventType.ContinueExtractingData;
53
53
  // Act
54
54
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
55
55
  // Assert
@@ -67,7 +67,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
67
67
  });
68
68
  it('should return ExtractorStateDeletionError for deprecated ExtractionDataDelete', () => {
69
69
  // Arrange
70
- const eventType = extraction_1.EventType.ExtractionDataDelete;
70
+ const eventType = extraction_1.EventType.StartDeletingExtractorState;
71
71
  // Act
72
72
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
73
73
  // Assert
@@ -93,7 +93,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
93
93
  });
94
94
  it('should return AttachmentExtractionError for deprecated ExtractionAttachmentsStart', () => {
95
95
  // Arrange
96
- const eventType = extraction_1.EventType.ExtractionAttachmentsStart;
96
+ const eventType = extraction_1.EventType.StartExtractingAttachments;
97
97
  // Act
98
98
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
99
99
  // Assert
@@ -101,7 +101,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
101
101
  });
102
102
  it('should return AttachmentExtractionError for deprecated ExtractionAttachmentsContinue', () => {
103
103
  // Arrange
104
- const eventType = extraction_1.EventType.ExtractionAttachmentsContinue;
104
+ const eventType = extraction_1.EventType.ContinueExtractingAttachments;
105
105
  // Act
106
106
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
107
107
  // Assert
@@ -119,7 +119,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
119
119
  });
120
120
  it('should return ExtractorAttachmentsStateDeletionError for deprecated ExtractionAttachmentsDelete', () => {
121
121
  // Arrange
122
- const eventType = extraction_1.EventType.ExtractionAttachmentsDelete;
122
+ const eventType = extraction_1.EventType.StartDeletingExtractorAttachmentsState;
123
123
  // Act
124
124
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
125
125
  // Assert
@@ -137,7 +137,7 @@ describe(spawn_helpers_1.getTimeoutErrorEventType.name, () => {
137
137
  });
138
138
  it('should return ExternalSyncUnitExtractionError for deprecated ExtractionExternalSyncUnitsStart', () => {
139
139
  // Arrange
140
- const eventType = extraction_1.EventType.ExtractionExternalSyncUnitsStart;
140
+ const eventType = extraction_1.EventType.StartExtractingExternalSyncUnits;
141
141
  // Act
142
142
  const result = (0, spawn_helpers_1.getTimeoutErrorEventType)(eventType);
143
143
  // Assert
@@ -8,7 +8,6 @@ exports.spawn = spawn;
8
8
  const yargs_1 = __importDefault(require("yargs"));
9
9
  const helpers_1 = require("yargs/helpers");
10
10
  const control_protocol_1 = require("../../common/control-protocol");
11
- const event_type_translation_1 = require("../../common/event-type-translation");
12
11
  const helpers_2 = require("../../common/helpers");
13
12
  const logger_1 = require("../../logger/logger");
14
13
  const extraction_1 = require("../../types/extraction");
@@ -50,42 +49,30 @@ function getWorkerPath({ event, workerBasePath, }) {
50
49
  * The class provides utilities to emit control events to the platform and exit the worker gracefully.
51
50
  * In case of lambda timeout, the class emits a lambda timeout event to the platform.
52
51
  * @param {SpawnFactoryInterface} options - The options to create a new instance of Spawn class
53
- * @param {AirdropEvent} options.event - The event object received from the platform
52
+ * @param {AirSyncEvent} options.event - The event object received from the platform
54
53
  * @param {object} options.initialState - The initial state of the adapter
55
- * @param {string} [options.workerPath] Remove getWorkerPath function and use baseWorkerPath: __dirname instead of workerPath
56
54
  * @param {string} [options.baseWorkerPath] - The base path for the worker files, usually `__dirname`
57
55
  * @returns {Promise<Spawn>} - A new instance of Spawn class
58
56
  */
59
- async function spawn({ event, initialState, workerPath, initialDomainMapping, options, baseWorkerPath, }) {
60
- // Translate incoming event type for backwards compatibility. This allows the
61
- // SDK to accept both old and new event type formats. Then update the event with the translated event type.
62
- const originalEventType = event.payload.event_type;
63
- const translatedEventType = (0, event_type_translation_1.translateIncomingEventType)(event.payload.event_type);
64
- event.payload.event_type = translatedEventType;
57
+ async function spawn({ event, initialState, initialDomainMapping, options, baseWorkerPath, }) {
65
58
  // Read the command line arguments to check if the local flag is passed.
66
59
  const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv)).argv;
67
- if (argv._.includes('local')) {
60
+ if (argv._.includes('local') || argv.local) {
68
61
  options = Object.assign(Object.assign({}, (options || {})), { isLocalDevelopment: true });
69
62
  }
70
63
  const originalConsole = console;
71
64
  // eslint-disable-next-line no-global-assign
72
65
  console = new logger_1.Logger({ event, options });
73
- if (translatedEventType !== originalEventType) {
74
- console.log(`Event type translated from ${originalEventType} to ${translatedEventType}.`);
75
- }
76
66
  if (options === null || options === void 0 ? void 0 : options.isLocalDevelopment) {
77
67
  console.log('Snap-in is running in local development mode.');
78
68
  }
69
+ const eventType = event.payload.event_type;
79
70
  let script = null;
80
- if (workerPath != null) {
81
- script = workerPath;
82
- }
83
- else if (baseWorkerPath != null &&
71
+ if (baseWorkerPath != null &&
84
72
  (options === null || options === void 0 ? void 0 : options.workerPathOverrides) != null &&
85
- options.workerPathOverrides[translatedEventType] != null) {
73
+ options.workerPathOverrides[eventType] != null) {
86
74
  script =
87
- baseWorkerPath +
88
- options.workerPathOverrides[translatedEventType];
75
+ baseWorkerPath + options.workerPathOverrides[eventType];
89
76
  }
90
77
  else {
91
78
  script = getWorkerPath({
@@ -137,6 +124,7 @@ class Spawn {
137
124
  this.originalConsole = originalConsole || console;
138
125
  this.logger = console;
139
126
  this.alreadyEmitted = false;
127
+ this.softTimeoutSent = false;
140
128
  this.event = event;
141
129
  this.lambdaTimeout = (options === null || options === void 0 ? void 0 : options.timeout)
142
130
  ? Math.min(options.timeout, this.defaultLambdaTimeout)
@@ -145,6 +133,7 @@ class Spawn {
145
133
  // If soft timeout is reached, send a message to the worker to gracefully exit.
146
134
  this.softTimeoutTimer = setTimeout(() => void (async () => {
147
135
  console.log('SOFT TIMEOUT: Sending a message to the worker to gracefully exit.');
136
+ this.softTimeoutSent = true;
148
137
  if (worker) {
149
138
  worker.postMessage({
150
139
  subject: workers_1.WorkerMessageSubject.WorkerMessageExit,
@@ -167,28 +156,45 @@ class Spawn {
167
156
  }
168
157
  })(), this.lambdaTimeout * constants_1.HARD_TIMEOUT_MULTIPLIER);
169
158
  // If worker exits with process.exit(code), clear the timeouts and exit from
170
- // main thread.
171
- worker.on(workers_1.WorkerEvent.WorkerExit, (code) => void (async () => {
172
- console.info('Worker exited with exit code: ' + code + '.');
173
- this.clearTimeouts();
174
- await this.exitFromMainThread();
175
- })());
159
+ // main thread. When a soft timeout was sent, we use setImmediate to defer
160
+ // processing so that any pending WorkerMessage events (e.g.
161
+ // WorkerMessageEmitted from onTimeout) already queued in the event loop are
162
+ // handled first, preventing a race condition where exitFromMainThread sees
163
+ // alreadyEmitted=false and emits an error even though the worker
164
+ // successfully emitted an event.
165
+ worker.on(workers_1.WorkerEvent.WorkerExit, (code) => {
166
+ const handler = async () => {
167
+ console.info('Worker exited with exit code: ' + code + '.');
168
+ this.clearTimeouts();
169
+ await this.exitFromMainThread();
170
+ };
171
+ if (this.softTimeoutSent) {
172
+ void setImmediate(() => void handler());
173
+ }
174
+ else {
175
+ void handler();
176
+ }
177
+ });
176
178
  worker.on(workers_1.WorkerEvent.WorkerMessage, (message) => {
177
- var _a, _b, _c, _d;
179
+ var _a, _b, _c, _d, _e;
178
180
  // Since logs from the worker thread are handled differently in snap-in
179
181
  // platform, we need to catch the log messages from worker thread and log
180
182
  // them in main thread.
181
183
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageLog) {
182
184
  const stringifiedArgs = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.stringifiedArgs;
183
185
  const level = (_b = message.payload) === null || _b === void 0 ? void 0 : _b.level;
184
- const isSdkLog = (_d = (_c = message.payload) === null || _c === void 0 ? void 0 : _c.isSdkLog) !== null && _d !== void 0 ? _d : false;
186
+ const isSdkLog = (_d = (_c = message.payload) === null || _c === void 0 ? void 0 : _c.isSdkLog) !== null && _d !== void 0 ? _d : true;
185
187
  this.logger.logFn(stringifiedArgs, level, isSdkLog);
186
188
  }
187
189
  // If worker sends a message that it has emitted an event, then set alreadyEmitted to true.
188
190
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageEmitted) {
189
- console.info('Worker has emitted message to ADaaS.');
191
+ console.info('Worker has emitted message to the AirSync platform.');
190
192
  this.alreadyEmitted = true;
191
193
  }
194
+ // If worker sends a failure message before exiting, capture it for use in the error event.
195
+ if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageFailed) {
196
+ this.workerFailedMessage = (_e = message.payload) === null || _e === void 0 ? void 0 : _e.message;
197
+ }
192
198
  });
193
199
  // Log memory usage every 30 seconds
194
200
  this.memoryMonitoringInterval = setInterval(() => {
@@ -235,15 +241,19 @@ class Spawn {
235
241
  event: this.event,
236
242
  data: {
237
243
  error: {
238
- message: 'Worker exited the process without emitting an event. Check other logs for more information.',
244
+ message: `Worker exited without emitting event. ${this.workerFailedMessage
245
+ ? `Error: ${this.workerFailedMessage}`
246
+ : 'Check the logs for more information.'}`,
239
247
  },
240
248
  },
241
249
  });
242
- this.resolve();
243
250
  }
244
251
  catch (error) {
245
252
  console.error('Error while emitting event.', (0, logger_1.serializeError)(error));
246
253
  }
254
+ finally {
255
+ this.resolve();
256
+ }
247
257
  }
248
258
  }
249
259
  exports.Spawn = Spawn;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=spawn.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.test.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.test.ts"],"names":[],"mappings":""}