@devrev/ts-adaas 1.12.3-beta.6 → 1.12.3-beta.7

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 (50) hide show
  1. package/dist/common/constants.d.ts +1 -0
  2. package/dist/common/constants.d.ts.map +1 -1
  3. package/dist/common/constants.js +2 -1
  4. package/dist/common/worker-memory.d.ts +59 -0
  5. package/dist/common/worker-memory.d.ts.map +1 -0
  6. package/dist/common/worker-memory.js +177 -0
  7. package/dist/tests/oom-handling/extraction.d.ts +11 -0
  8. package/dist/tests/oom-handling/extraction.d.ts.map +1 -0
  9. package/dist/tests/oom-handling/extraction.js +29 -0
  10. package/dist/tests/oom-handling/jest.setup.d.ts +7 -0
  11. package/dist/tests/oom-handling/jest.setup.d.ts.map +1 -0
  12. package/dist/tests/oom-handling/jest.setup.js +26 -0
  13. package/dist/tests/oom-handling/oom-after-emit-worker.d.ts +2 -0
  14. package/dist/tests/oom-handling/oom-after-emit-worker.d.ts.map +1 -0
  15. package/dist/tests/oom-handling/oom-after-emit-worker.js +35 -0
  16. package/dist/tests/oom-handling/oom-attachments-worker.d.ts +2 -0
  17. package/dist/tests/oom-handling/oom-attachments-worker.d.ts.map +1 -0
  18. package/dist/tests/oom-handling/oom-attachments-worker.js +29 -0
  19. package/dist/tests/oom-handling/oom-external-sync-units-worker.d.ts +2 -0
  20. package/dist/tests/oom-handling/oom-external-sync-units-worker.d.ts.map +1 -0
  21. package/dist/tests/oom-handling/oom-external-sync-units-worker.js +29 -0
  22. package/dist/tests/oom-handling/oom-gradual-worker.d.ts +2 -0
  23. package/dist/tests/oom-handling/oom-gradual-worker.d.ts.map +1 -0
  24. package/dist/tests/oom-handling/oom-gradual-worker.js +47 -0
  25. package/dist/tests/oom-handling/oom-handling.test.d.ts +2 -0
  26. package/dist/tests/oom-handling/oom-handling.test.d.ts.map +1 -0
  27. package/dist/tests/oom-handling/oom-handling.test.js +407 -0
  28. package/dist/tests/oom-handling/oom-metadata-worker.d.ts +2 -0
  29. package/dist/tests/oom-handling/oom-metadata-worker.d.ts.map +1 -0
  30. package/dist/tests/oom-handling/oom-metadata-worker.js +29 -0
  31. package/dist/tests/oom-handling/oom-worker.d.ts +2 -0
  32. package/dist/tests/oom-handling/oom-worker.d.ts.map +1 -0
  33. package/dist/tests/oom-handling/oom-worker.js +55 -0
  34. package/dist/tests/oom-handling/worker-memory.test.d.ts +2 -0
  35. package/dist/tests/oom-handling/worker-memory.test.d.ts.map +1 -0
  36. package/dist/tests/oom-handling/worker-memory.test.js +306 -0
  37. package/dist/types/common.d.ts +3 -0
  38. package/dist/types/common.d.ts.map +1 -1
  39. package/dist/types/workers.d.ts +58 -0
  40. package/dist/types/workers.d.ts.map +1 -1
  41. package/dist/uploader/uploader.d.ts.map +1 -1
  42. package/dist/uploader/uploader.js +13 -5
  43. package/dist/workers/create-worker.d.ts +20 -2
  44. package/dist/workers/create-worker.d.ts.map +1 -1
  45. package/dist/workers/create-worker.js +38 -3
  46. package/dist/workers/create-worker.test.js +113 -14
  47. package/dist/workers/spawn.d.ts +10 -1
  48. package/dist/workers/spawn.d.ts.map +1 -1
  49. package/dist/workers/spawn.js +77 -3
  50. package/package.json +2 -1
@@ -7,7 +7,7 @@ const create_worker_1 = require("./create-worker");
7
7
  describe(create_worker_1.createWorker.name, () => {
8
8
  it('should create a Worker instance when valid parameters are provided', async () => {
9
9
  const workerPath = __dirname + '../tests/dummy-worker.ts';
10
- const worker = worker_threads_1.isMainThread
10
+ const result = worker_threads_1.isMainThread
11
11
  ? await (0, create_worker_1.createWorker)({
12
12
  event: (0, test_helpers_1.createEvent)({
13
13
  eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
@@ -16,10 +16,12 @@ describe(create_worker_1.createWorker.name, () => {
16
16
  workerPath,
17
17
  })
18
18
  : null;
19
- expect(worker).not.toBeNull();
20
- expect(worker).toBeInstanceOf(worker_threads_1.Worker);
21
- if (worker) {
22
- await worker.terminate();
19
+ expect(result).not.toBeNull();
20
+ expect(result === null || result === void 0 ? void 0 : result.worker).toBeInstanceOf(worker_threads_1.Worker);
21
+ expect(result === null || result === void 0 ? void 0 : result.memoryConfig).toBeDefined();
22
+ expect(result === null || result === void 0 ? void 0 : result.resourceLimits).toBeDefined();
23
+ if (result) {
24
+ await result.worker.terminate();
23
25
  }
24
26
  });
25
27
  it('should throw error when not in main thread', async () => {
@@ -41,15 +43,15 @@ describe(create_worker_1.createWorker.name, () => {
41
43
  it('[edge] should handle worker creation with minimal valid data', async () => {
42
44
  const workerPath = __dirname + '../tests/dummy-worker.ts';
43
45
  if (worker_threads_1.isMainThread) {
44
- const worker = await (0, create_worker_1.createWorker)({
46
+ const result = await (0, create_worker_1.createWorker)({
45
47
  event: (0, test_helpers_1.createEvent)({
46
48
  eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
47
49
  }),
48
50
  initialState: {},
49
51
  workerPath,
50
52
  });
51
- expect(worker).toBeInstanceOf(worker_threads_1.Worker);
52
- await worker.terminate();
53
+ expect(result.worker).toBeInstanceOf(worker_threads_1.Worker);
54
+ await result.worker.terminate();
53
55
  }
54
56
  });
55
57
  it('[edge] should handle worker creation with complex initial state', async () => {
@@ -61,29 +63,126 @@ describe(create_worker_1.createWorker.name, () => {
61
63
  },
62
64
  };
63
65
  if (worker_threads_1.isMainThread) {
64
- const worker = await (0, create_worker_1.createWorker)({
66
+ const result = await (0, create_worker_1.createWorker)({
65
67
  event: (0, test_helpers_1.createEvent)({
66
68
  eventType: extraction_1.EventType.ExtractionDataStart,
67
69
  }),
68
70
  initialState: complexState,
69
71
  workerPath,
70
72
  });
71
- expect(worker).toBeInstanceOf(worker_threads_1.Worker);
72
- await worker.terminate();
73
+ expect(result.worker).toBeInstanceOf(worker_threads_1.Worker);
74
+ await result.worker.terminate();
73
75
  }
74
76
  });
75
77
  it('[edge] should handle different event types', async () => {
76
78
  const workerPath = __dirname + '../tests/dummy-worker.ts';
77
79
  if (worker_threads_1.isMainThread) {
78
- const worker = await (0, create_worker_1.createWorker)({
80
+ const result = await (0, create_worker_1.createWorker)({
79
81
  event: (0, test_helpers_1.createEvent)({
80
82
  eventType: extraction_1.EventType.ExtractionMetadataStart,
81
83
  }),
82
84
  initialState: {},
83
85
  workerPath,
84
86
  });
85
- expect(worker).toBeInstanceOf(worker_threads_1.Worker);
86
- await worker.terminate();
87
+ expect(result.worker).toBeInstanceOf(worker_threads_1.Worker);
88
+ await result.worker.terminate();
89
+ }
90
+ });
91
+ it('should include memory configuration in result', async () => {
92
+ const workerPath = __dirname + '../tests/dummy-worker.ts';
93
+ if (worker_threads_1.isMainThread) {
94
+ const result = await (0, create_worker_1.createWorker)({
95
+ event: (0, test_helpers_1.createEvent)({
96
+ eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
97
+ }),
98
+ initialState: {},
99
+ workerPath,
100
+ });
101
+ expect(result.memoryConfig).toHaveProperty('maxOldGenerationSizeMb');
102
+ expect(result.memoryConfig).toHaveProperty('totalAvailableMemoryMb');
103
+ expect(result.memoryConfig).toHaveProperty('isLambda');
104
+ expect(result.memoryConfig).toHaveProperty('isLocalDevelopment');
105
+ expect(result.resourceLimits).toHaveProperty('maxOldGenerationSizeMb');
106
+ await result.worker.terminate();
107
+ }
108
+ });
109
+ it('should apply testMemoryLimitMb override when provided', async () => {
110
+ const workerPath = __dirname + '../tests/dummy-worker.ts';
111
+ const testMemoryLimit = 64;
112
+ if (worker_threads_1.isMainThread) {
113
+ const result = await (0, create_worker_1.createWorker)({
114
+ event: (0, test_helpers_1.createEvent)({
115
+ eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
116
+ }),
117
+ initialState: {},
118
+ workerPath,
119
+ options: {
120
+ testMemoryLimitMb: testMemoryLimit,
121
+ },
122
+ });
123
+ expect(result.resourceLimits.maxOldGenerationSizeMb).toBe(testMemoryLimit);
124
+ await result.worker.terminate();
125
+ }
126
+ });
127
+ it('should create worker without memory limits when enableMemoryLimits is false', async () => {
128
+ const workerPath = __dirname + '../tests/dummy-worker.ts';
129
+ if (worker_threads_1.isMainThread) {
130
+ const result = await (0, create_worker_1.createWorker)({
131
+ event: (0, test_helpers_1.createEvent)({
132
+ eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
133
+ }),
134
+ initialState: {},
135
+ workerPath,
136
+ options: {
137
+ enableMemoryLimits: false,
138
+ },
139
+ });
140
+ // Worker should still be created successfully
141
+ expect(result.worker).toBeInstanceOf(worker_threads_1.Worker);
142
+ // Memory config should still be calculated (for logging purposes)
143
+ expect(result.memoryConfig).toBeDefined();
144
+ expect(result.resourceLimits).toBeDefined();
145
+ await result.worker.terminate();
146
+ }
147
+ });
148
+ it('should set isLocalDevelopment in memory config when option is provided', async () => {
149
+ const workerPath = __dirname + '../tests/dummy-worker.ts';
150
+ if (worker_threads_1.isMainThread) {
151
+ const result = await (0, create_worker_1.createWorker)({
152
+ event: (0, test_helpers_1.createEvent)({
153
+ eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
154
+ }),
155
+ initialState: {},
156
+ workerPath,
157
+ options: {
158
+ isLocalDevelopment: true,
159
+ },
160
+ });
161
+ expect(result.memoryConfig.isLocalDevelopment).toBe(true);
162
+ await result.worker.terminate();
163
+ }
164
+ });
165
+ it('[edge] should handle all extraction event types', async () => {
166
+ const workerPath = __dirname + '../tests/dummy-worker.ts';
167
+ const eventTypes = [
168
+ extraction_1.EventType.ExtractionExternalSyncUnitsStart,
169
+ extraction_1.EventType.ExtractionMetadataStart,
170
+ extraction_1.EventType.ExtractionDataStart,
171
+ extraction_1.EventType.ExtractionDataContinue,
172
+ extraction_1.EventType.ExtractionAttachmentsStart,
173
+ extraction_1.EventType.ExtractionAttachmentsContinue,
174
+ ];
175
+ if (worker_threads_1.isMainThread) {
176
+ for (const eventType of eventTypes) {
177
+ const result = await (0, create_worker_1.createWorker)({
178
+ event: (0, test_helpers_1.createEvent)({ eventType }),
179
+ initialState: {},
180
+ workerPath,
181
+ });
182
+ expect(result.worker).toBeInstanceOf(worker_threads_1.Worker);
183
+ expect(result.memoryConfig).toBeDefined();
184
+ await result.worker.terminate();
185
+ }
87
186
  }
88
187
  });
89
188
  });
@@ -22,8 +22,17 @@ export declare class Spawn {
22
22
  private resolve;
23
23
  private originalConsole;
24
24
  private logger;
25
- constructor({ event, worker, options, resolve, originalConsole, }: SpawnInterface);
25
+ private memoryConfig?;
26
+ private resourceLimits?;
27
+ private isOOMExit;
28
+ constructor({ event, worker, options, resolve, originalConsole, memoryConfig, resourceLimits, }: SpawnInterface);
26
29
  private clearTimeouts;
27
30
  private exitFromMainThread;
31
+ /**
32
+ * Handles worker exit due to OOM (Out-Of-Memory) error.
33
+ * Emits an error event with detailed OOM information.
34
+ * @param exitCode - The exit code from the worker
35
+ */
36
+ private handleOOMExit;
28
37
  }
29
38
  //# sourceMappingURL=spawn.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/workers/spawn.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,kBAAkB,CAAC;AAmC1B;;;;;;;;;;GAUG;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,CAuGvD;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;IAgGjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAiCjC"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/workers/spawn.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,qBAAqB,EACrB,cAAc,EAKf,MAAM,kBAAkB,CAAC;AAmC1B;;;;;;;;;;GAUG;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,CA0GvD;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;IACvB,OAAO,CAAC,YAAY,CAAC,CAAqB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAuB;IAC9C,OAAO,CAAC,SAAS,CAAkB;gBAEvB,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,EACf,YAAY,EACZ,cAAc,GACf,EAAE,cAAc;IAwHjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;IAkChC;;;;OAIG;YACW,aAAa;CAyD5B"}
@@ -10,6 +10,7 @@ const helpers_1 = require("yargs/helpers");
10
10
  const control_protocol_1 = require("../common/control-protocol");
11
11
  const event_type_translation_1 = require("../common/event-type-translation");
12
12
  const helpers_2 = require("../common/helpers");
13
+ const worker_memory_1 = require("../common/worker-memory");
13
14
  const logger_1 = require("../logger/logger");
14
15
  const extraction_1 = require("../types/extraction");
15
16
  const workers_1 = require("../types/workers");
@@ -86,7 +87,7 @@ async function spawn({ event, initialState, workerPath, initialDomainMapping, op
86
87
  }
87
88
  if (script) {
88
89
  try {
89
- const worker = await (0, create_worker_1.createWorker)({
90
+ const { worker, memoryConfig, resourceLimits } = await (0, create_worker_1.createWorker)({
90
91
  event,
91
92
  initialState,
92
93
  workerPath: script,
@@ -100,6 +101,8 @@ async function spawn({ event, initialState, workerPath, initialDomainMapping, op
100
101
  options,
101
102
  resolve,
102
103
  originalConsole,
104
+ memoryConfig,
105
+ resourceLimits,
103
106
  });
104
107
  });
105
108
  }
@@ -136,8 +139,9 @@ async function spawn({ event, initialState, workerPath, initialDomainMapping, op
136
139
  }
137
140
  }
138
141
  class Spawn {
139
- constructor({ event, worker, options, resolve, originalConsole, }) {
142
+ constructor({ event, worker, options, resolve, originalConsole, memoryConfig, resourceLimits, }) {
140
143
  this.defaultLambdaTimeout = constants_1.DEFAULT_LAMBDA_TIMEOUT;
144
+ this.isOOMExit = false;
141
145
  this.originalConsole = originalConsole || console;
142
146
  this.logger = console;
143
147
  this.alreadyEmitted = false;
@@ -146,6 +150,8 @@ class Spawn {
146
150
  ? Math.min(options.timeout, this.defaultLambdaTimeout)
147
151
  : this.defaultLambdaTimeout;
148
152
  this.resolve = resolve;
153
+ this.memoryConfig = memoryConfig;
154
+ this.resourceLimits = resourceLimits;
149
155
  // If soft timeout is reached, send a message to the worker to gracefully exit.
150
156
  this.softTimeoutTimer = setTimeout(() => void (async () => {
151
157
  console.log('SOFT TIMEOUT: Sending a message to the worker to gracefully exit.');
@@ -170,12 +176,33 @@ class Spawn {
170
176
  await this.exitFromMainThread();
171
177
  }
172
178
  })(), this.lambdaTimeout * constants_1.HARD_TIMEOUT_MULTIPLIER);
179
+ // Listen for worker errors to detect OOM
180
+ // Node.js worker threads emit ERR_WORKER_OUT_OF_MEMORY error code when OOM occurs
181
+ // @see https://nodejs.org/api/errors.html#err_worker_out_of_memory
182
+ worker.on(workers_1.WorkerEvent.WorkerError, (error) => {
183
+ if ((0, worker_memory_1.isOOMError)(error)) {
184
+ this.isOOMExit = true;
185
+ console.error('OOM ERROR DETECTED: Worker ran out of memory.', {
186
+ errorCode: error.code,
187
+ errorMessage: error === null || error === void 0 ? void 0 : error.message,
188
+ memoryConfig: this.memoryConfig,
189
+ resourceLimits: this.resourceLimits,
190
+ });
191
+ }
192
+ });
173
193
  // If worker exits with process.exit(code), clear the timeouts and exit from
174
194
  // main thread.
175
195
  worker.on(workers_1.WorkerEvent.WorkerExit, (code) => void (async () => {
176
196
  console.info('Worker exited with exit code: ' + code + '.');
177
197
  this.clearTimeouts();
178
- await this.exitFromMainThread();
198
+ // Check if this was an OOM exit (non-zero exit code and OOM error detected)
199
+ // Exit code 134 is common for OOM (SIGABRT), but we also check the error message
200
+ if (code !== 0 && this.isOOMExit) {
201
+ await this.handleOOMExit(code);
202
+ }
203
+ else {
204
+ await this.exitFromMainThread();
205
+ }
179
206
  })());
180
207
  worker.on(workers_1.WorkerEvent.WorkerMessage, (message) => {
181
208
  var _a, _b;
@@ -248,5 +275,52 @@ class Spawn {
248
275
  console.error('Error while emitting event.', (0, logger_1.serializeError)(error));
249
276
  }
250
277
  }
278
+ /**
279
+ * Handles worker exit due to OOM (Out-Of-Memory) error.
280
+ * Emits an error event with detailed OOM information.
281
+ * @param exitCode - The exit code from the worker
282
+ */
283
+ async handleOOMExit(exitCode) {
284
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
285
+ this.clearTimeouts();
286
+ // eslint-disable-next-line no-global-assign
287
+ console = this.originalConsole;
288
+ if (this.alreadyEmitted) {
289
+ this.resolve();
290
+ return;
291
+ }
292
+ this.alreadyEmitted = true;
293
+ const { eventType } = (0, helpers_2.getTimeoutErrorEventType)(this.event.payload.event_type);
294
+ // Build OOM error info
295
+ const oomErrorInfo = {
296
+ type: 'OOM_ERROR',
297
+ message: `Worker thread ran out of memory and was terminated. ` +
298
+ `Memory limit: ${(_b = (_a = this.resourceLimits) === null || _a === void 0 ? void 0 : _a.maxOldGenerationSizeMb) !== null && _b !== void 0 ? _b : 'unknown'}MB, ` +
299
+ `Total available: ${(_e = (_d = (_c = this.memoryConfig) === null || _c === void 0 ? void 0 : _c.totalAvailableMemoryMb) === null || _d === void 0 ? void 0 : _d.toFixed(0)) !== null && _e !== void 0 ? _e : 'unknown'}MB.`,
300
+ memoryLimitMb: (_g = (_f = this.resourceLimits) === null || _f === void 0 ? void 0 : _f.maxOldGenerationSizeMb) !== null && _g !== void 0 ? _g : 0,
301
+ totalAvailableMemoryMb: (_j = (_h = this.memoryConfig) === null || _h === void 0 ? void 0 : _h.totalAvailableMemoryMb) !== null && _j !== void 0 ? _j : 0,
302
+ isLambda: (_l = (_k = this.memoryConfig) === null || _k === void 0 ? void 0 : _k.isLambda) !== null && _l !== void 0 ? _l : false,
303
+ isLocalDevelopment: (_o = (_m = this.memoryConfig) === null || _m === void 0 ? void 0 : _m.isLocalDevelopment) !== null && _o !== void 0 ? _o : false,
304
+ exitCode,
305
+ eventType: this.event.payload.event_type,
306
+ };
307
+ console.error('OOM Error Details:', oomErrorInfo);
308
+ try {
309
+ await (0, control_protocol_1.emit)({
310
+ eventType,
311
+ event: this.event,
312
+ data: {
313
+ error: {
314
+ message: oomErrorInfo.message,
315
+ oom_error_info: oomErrorInfo,
316
+ },
317
+ },
318
+ });
319
+ this.resolve();
320
+ }
321
+ catch (error) {
322
+ console.error('Error while emitting OOM error event.', (0, logger_1.serializeError)(error));
323
+ }
324
+ }
251
325
  }
252
326
  exports.Spawn = Spawn;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrev/ts-adaas",
3
- "version": "1.12.3-beta.6",
3
+ "version": "1.12.3-beta.7",
4
4
  "description": "Typescript library containing the ADaaS(AirDrop as a Service) control protocol.",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",
@@ -12,6 +12,7 @@
12
12
  "lint": "eslint .",
13
13
  "lint:fix": "eslint . --fix",
14
14
  "test": "jest --forceExit --coverage --runInBand --selectProjects default --",
15
+ "test:oom": "node --max-old-space-size=4096 ./node_modules/.bin/jest --forceExit --runInBand --selectProjects oom-tests --logHeapUsage --",
15
16
  "test:backwards-compatibility": "jest --forceExit --runInBand --selectProjects backwards-compatibility --"
16
17
  },
17
18
  "repository": {