@jsenv/test 3.1.0 → 3.2.1

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.
@@ -809,6 +809,9 @@ const createException = (reason, { rootDirectoryUrl } = {}) => {
809
809
 
810
810
  const stackFramesNonNative = [];
811
811
  for (const stackFrame of stackFrames) {
812
+ if (!stackFrame.url) {
813
+ continue;
814
+ }
812
815
  if (stackFrame.url.startsWith("node:")) {
813
816
  stackFrame.native = "node";
814
817
  continue;
@@ -907,9 +910,7 @@ const getErrorName = (value) => {
907
910
 
908
911
  const getPropertiesFromEvalOrigin = (origin) => {
909
912
  // Most eval() calls are in this format
910
- const topLevelEvalMatch = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(
911
- origin,
912
- );
913
+ const topLevelEvalMatch = /^eval at [^(]+ \(.+:\d+:\d+\)$/.exec(origin);
913
914
  if (topLevelEvalMatch) {
914
915
  const source = topLevelEvalMatch[2];
915
916
  const line = Number(topLevelEvalMatch[3]);
@@ -921,7 +922,7 @@ const getPropertiesFromEvalOrigin = (origin) => {
921
922
  };
922
923
  }
923
924
  // Parse nested eval() calls using recursion
924
- const nestedEvalMatch = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
925
+ const nestedEvalMatch = /^eval at [^(]+ \(.+\)$/.exec(origin);
925
926
  if (nestedEvalMatch) {
926
927
  return getPropertiesFromEvalOrigin(nestedEvalMatch[2]);
927
928
  }
@@ -1,6 +1,6 @@
1
1
  import os, { cpus, release, totalmem, availableParallelism, freemem } from "node:os";
2
2
  import process$1, { cpuUsage, memoryUsage } from "node:process";
3
- import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, unlinkSync, readdirSync, rmdirSync, readFileSync, existsSync } from "node:fs";
3
+ import { readdir, chmod, stat, lstat, chmodSync, statSync, lstatSync, promises, readFile as readFile$1, readFileSync, writeFileSync as writeFileSync$1, mkdirSync, unlink, openSync, closeSync, rmdir, unlinkSync, readdirSync, rmdirSync, existsSync } from "node:fs";
4
4
  import { takeCoverage } from "node:v8";
5
5
  import stripAnsi from "strip-ansi";
6
6
  import { URL_META, createException } from "./js/exception.js";
@@ -2486,6 +2486,9 @@ const readFile = async (value, { as = "buffer" } = {}) => {
2486
2486
  const writeFileSync = (destination, content = "") => {
2487
2487
  const destinationUrl = assertAndNormalizeFileUrl(destination);
2488
2488
  const destinationUrlObject = new URL(destinationUrl);
2489
+ if (content && content instanceof URL) {
2490
+ content = readFileSync(content);
2491
+ }
2489
2492
  try {
2490
2493
  writeFileSync$1(destinationUrlObject, content);
2491
2494
  } catch (error) {
@@ -4295,7 +4298,7 @@ const stringifyUrlSite = ({ url, line, column }) => {
4295
4298
  };
4296
4299
 
4297
4300
  const replaceUrls$1 = (source, replace) => {
4298
- return source.replace(/(?:https?|ftp|file):\/\/\S+/gm, (match) => {
4301
+ return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
4299
4302
  let replacement = "";
4300
4303
  const lastChar = match[match.length - 1];
4301
4304
 
@@ -4702,7 +4705,7 @@ const formatErrorForTerminal = (
4702
4705
  // debugger
4703
4706
  // })
4704
4707
  const replaceUrls = (source, replace) => {
4705
- return source.replace(/(?:https?|ftp|file):\/\/\S+/gm, (match) => {
4708
+ return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
4706
4709
  let replacement = "";
4707
4710
  const lastChar = match[match.length - 1];
4708
4711
 
@@ -6133,6 +6136,7 @@ To fix this warning:
6133
6136
  runtime,
6134
6137
  runtimeParams,
6135
6138
  allocatedMs = defaultMsAllocatedPerExecution,
6139
+ uses,
6136
6140
  } = stepConfig;
6137
6141
  const params = {
6138
6142
  measureMemoryUsage: true,
@@ -6140,6 +6144,7 @@ To fix this warning:
6140
6144
  collectPerformance: false,
6141
6145
  collectConsole: true,
6142
6146
  allocatedMs,
6147
+ uses,
6143
6148
  runtime,
6144
6149
  runtimeParams: {
6145
6150
  rootDirectoryUrl,
@@ -6169,6 +6174,7 @@ To fix this warning:
6169
6174
  }
6170
6175
 
6171
6176
  const execution = {
6177
+ name: `${relativeUrl}/${groupName}`,
6172
6178
  counters,
6173
6179
  countersInOrder,
6174
6180
  index,
@@ -6321,7 +6327,13 @@ To fix this warning:
6321
6327
 
6322
6328
  const executionRemainingSet = new Set(executionPlanifiedSet);
6323
6329
  const executionExecutingSet = new Set();
6330
+ const usedTagSet = new Set();
6324
6331
  const start = async (execution) => {
6332
+ if (execution.params.uses) {
6333
+ for (const tagThatWillBeUsed of execution.params.uses) {
6334
+ usedTagSet.add(tagThatWillBeUsed);
6335
+ }
6336
+ }
6325
6337
  execution.fileExecutionCount = Object.keys(
6326
6338
  testPlanResult.results[execution.fileRelativeUrl],
6327
6339
  ).length;
@@ -6341,7 +6353,6 @@ To fix this warning:
6341
6353
  afterEachCallbackSet.add(callback);
6342
6354
  }
6343
6355
  }
6344
-
6345
6356
  for (const beforeEachInOrderCallback of beforeEachInOrderCallbackSet) {
6346
6357
  const returnValue = beforeEachInOrderCallback(
6347
6358
  execution,
@@ -6374,7 +6385,6 @@ To fix this warning:
6374
6385
  process.exitCode = 1;
6375
6386
  }
6376
6387
  }
6377
-
6378
6388
  for (const afterEachCallback of afterEachCallbackSet) {
6379
6389
  afterEachCallback(execution, testPlanResult);
6380
6390
  }
@@ -6384,7 +6394,11 @@ To fix this warning:
6384
6394
  afterEachInOrderCallback(execution, testPlanResult);
6385
6395
  }
6386
6396
  });
6387
-
6397
+ if (execution.params.uses) {
6398
+ for (const tagNoLongerInUse of execution.params.uses) {
6399
+ usedTagSet.delete(tagNoLongerInUse);
6400
+ }
6401
+ }
6388
6402
  if (testPlanResult.failed && failFast && counters.remaining) {
6389
6403
  logger.info(`"failFast" enabled -> cancel remaining executions`);
6390
6404
  failFastAbortController.abort();
@@ -6392,23 +6406,16 @@ To fix this warning:
6392
6406
  }
6393
6407
  };
6394
6408
  const startAsMuchAsPossible = async () => {
6409
+ operation.throwIfAborted();
6395
6410
  const promises = [];
6396
- // eslint-disable-next-line no-constant-condition
6397
- while (true) {
6398
- operation.throwIfAborted();
6399
- if (executionRemainingSet.size === 0) {
6400
- break;
6401
- }
6411
+ for (const executionCandidate of executionRemainingSet) {
6402
6412
  if (executionExecutingSet.size >= parallel.max) {
6403
6413
  break;
6404
6414
  }
6405
-
6406
- if (
6415
+ if (executionExecutingSet.size > 0) {
6407
6416
  // starting execution in parallel is limited by
6408
6417
  // cpu and memory only when trying to parallelize
6409
6418
  // if nothing is executing these limitations don't apply
6410
- executionExecutingSet.size > 0
6411
- ) {
6412
6419
  if (processMemoryUsageMonitoring.measure() > parallel.maxMemory) {
6413
6420
  // retry after Xms in case memory usage decreases
6414
6421
  const promise = (async () => {
@@ -6418,7 +6425,6 @@ To fix this warning:
6418
6425
  promises.push(promise);
6419
6426
  break;
6420
6427
  }
6421
-
6422
6428
  if (processCpuUsageMonitoring.measure() > parallel.maxCpu) {
6423
6429
  // retry after Xms in case cpu usage decreases
6424
6430
  const promise = (async () => {
@@ -6428,27 +6434,29 @@ To fix this warning:
6428
6434
  promises.push(promise);
6429
6435
  break;
6430
6436
  }
6437
+ if (executionCandidate.params.uses) {
6438
+ const nonAvailableTag = executionCandidate.params.uses.find(
6439
+ (tagToUse) => usedTagSet.has(tagToUse),
6440
+ );
6441
+ if (nonAvailableTag) {
6442
+ logger.debug(
6443
+ `"${nonAvailableTag}" is not available, ${executionCandidate.name} will wait until it is released by a previous execution`,
6444
+ );
6445
+ continue;
6446
+ }
6447
+ }
6431
6448
  }
6432
-
6433
- let execution;
6434
- for (const executionCandidate of executionRemainingSet) {
6435
- // TODO: this is where we'll check if it can be executed
6436
- // according to upcoming "using" execution param
6437
- execution = executionCandidate;
6438
- break;
6439
- }
6440
- if (execution) {
6441
- const promise = (async () => {
6442
- await start(execution);
6443
- await startAsMuchAsPossible();
6444
- })();
6445
- promises.push(promise);
6446
- }
6449
+ const promise = (async () => {
6450
+ await start(executionCandidate);
6451
+ await startAsMuchAsPossible();
6452
+ })();
6453
+ promises.push(promise);
6447
6454
  }
6448
- if (promises.length) {
6449
- await Promise.all(promises);
6450
- promises.length = 0;
6455
+ if (promises.length === 0) {
6456
+ return;
6451
6457
  }
6458
+ await Promise.all(promises);
6459
+ promises.length = 0;
6452
6460
  };
6453
6461
 
6454
6462
  reporters = reporters.flat(Infinity);
@@ -9186,4 +9194,75 @@ const execute = async ({
9186
9194
  }
9187
9195
  };
9188
9196
 
9189
- export { chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, nodeChildProcess, nodeWorkerThread, reportAsJunitXml, reportCoverageAsHtml, reportCoverageAsJson, reportCoverageInConsole, reporterList, webkit, webkitIsolatedTab };
9197
+ const inlineRuntime = (fn) => {
9198
+ return {
9199
+ type: "inline",
9200
+ name: "inline",
9201
+ version: "1",
9202
+ run: async ({
9203
+ signal = new AbortController().signal,
9204
+ onRuntimeStarted,
9205
+ onRuntimeStopped,
9206
+ }) => {
9207
+ const actionOperation = Abort.startOperation();
9208
+ actionOperation.addAbortSignal(signal);
9209
+ const result = {
9210
+ status: "executing",
9211
+ errors: [],
9212
+ namespace: null,
9213
+ timings: {},
9214
+ memoryUsage: null,
9215
+ performance: null,
9216
+ };
9217
+ try {
9218
+ let executionInternalErrorCallback;
9219
+ let executionCompletedCallback;
9220
+ const winnerPromise = new Promise((resolve) => {
9221
+ raceCallbacks(
9222
+ {
9223
+ aborted: (cb) => {
9224
+ return actionOperation.addAbortCallback(cb);
9225
+ },
9226
+ execution_internal_error: (cb) => {
9227
+ executionInternalErrorCallback = cb;
9228
+ },
9229
+ execution_completed: (cb) => {
9230
+ executionCompletedCallback = cb;
9231
+ },
9232
+ },
9233
+ resolve,
9234
+ );
9235
+ });
9236
+ try {
9237
+ onRuntimeStarted();
9238
+ const value = await fn();
9239
+ executionCompletedCallback(value);
9240
+ } catch (e) {
9241
+ executionInternalErrorCallback(e);
9242
+ }
9243
+ const raceHandlers = {
9244
+ aborted: () => {
9245
+ result.status = "aborted";
9246
+ },
9247
+ execution_internal_error: (e) => {
9248
+ result.status = "failed";
9249
+ result.errors.push(e);
9250
+ },
9251
+ execution_completed: (value) => {
9252
+ result.status = "completed";
9253
+ result.errors = [];
9254
+ result.namespace = value;
9255
+ },
9256
+ };
9257
+ const winner = await winnerPromise;
9258
+ raceHandlers[winner.name](winner.data);
9259
+ } finally {
9260
+ onRuntimeStopped();
9261
+ await actionOperation.end();
9262
+ return result;
9263
+ }
9264
+ },
9265
+ };
9266
+ };
9267
+
9268
+ export { chromium, chromiumIsolatedTab, execute, executeTestPlan, firefox, firefoxIsolatedTab, inlineRuntime, nodeChildProcess, nodeWorkerThread, reportAsJunitXml, reportCoverageAsHtml, reportCoverageAsJson, reportCoverageInConsole, reporterList, webkit, webkitIsolatedTab };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/test",
3
- "version": "3.1.0",
3
+ "version": "3.2.1",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -38,11 +38,11 @@
38
38
  "dependencies": {
39
39
  "@c88/v8-coverage": "0.1.1",
40
40
  "@jsenv/abort": "4.3.0",
41
- "@jsenv/ast": "6.1.0",
41
+ "@jsenv/ast": "6.1.1",
42
42
  "@jsenv/filesystem": "4.7.2",
43
- "@jsenv/github-check-run": "0.1.16",
43
+ "@jsenv/github-check-run": "0.1.17",
44
44
  "@jsenv/humanize": "1.1.3",
45
- "@jsenv/plugin-supervisor": "1.4.12",
45
+ "@jsenv/plugin-supervisor": "1.4.13",
46
46
  "@jsenv/url-meta": "8.4.2",
47
47
  "@jsenv/urls": "2.2.7",
48
48
  "@jsenv/utils": "2.1.1",
@@ -110,6 +110,9 @@ export const createException = (reason, { rootDirectoryUrl } = {}) => {
110
110
 
111
111
  const stackFramesNonNative = [];
112
112
  for (const stackFrame of stackFrames) {
113
+ if (!stackFrame.url) {
114
+ continue;
115
+ }
113
116
  if (stackFrame.url.startsWith("node:")) {
114
117
  stackFrame.native = "node";
115
118
  continue;
@@ -208,9 +211,7 @@ const getErrorName = (value) => {
208
211
 
209
212
  const getPropertiesFromEvalOrigin = (origin) => {
210
213
  // Most eval() calls are in this format
211
- const topLevelEvalMatch = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(
212
- origin,
213
- );
214
+ const topLevelEvalMatch = /^eval at [^(]+ \(.+:\d+:\d+\)$/.exec(origin);
214
215
  if (topLevelEvalMatch) {
215
216
  const source = topLevelEvalMatch[2];
216
217
  const line = Number(topLevelEvalMatch[3]);
@@ -222,7 +223,7 @@ const getPropertiesFromEvalOrigin = (origin) => {
222
223
  };
223
224
  }
224
225
  // Parse nested eval() calls using recursion
225
- const nestedEvalMatch = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
226
+ const nestedEvalMatch = /^eval at [^(]+ \(.+\)$/.exec(origin);
226
227
  if (nestedEvalMatch) {
227
228
  return getPropertiesFromEvalOrigin(nestedEvalMatch[2]);
228
229
  }
@@ -619,6 +619,7 @@ To fix this warning:
619
619
  runtime,
620
620
  runtimeParams,
621
621
  allocatedMs = defaultMsAllocatedPerExecution,
622
+ uses,
622
623
  } = stepConfig;
623
624
  const params = {
624
625
  measureMemoryUsage: true,
@@ -626,6 +627,7 @@ To fix this warning:
626
627
  collectPerformance: false,
627
628
  collectConsole: true,
628
629
  allocatedMs,
630
+ uses,
629
631
  runtime,
630
632
  runtimeParams: {
631
633
  rootDirectoryUrl,
@@ -655,6 +657,7 @@ To fix this warning:
655
657
  }
656
658
 
657
659
  const execution = {
660
+ name: `${relativeUrl}/${groupName}`,
658
661
  counters,
659
662
  countersInOrder,
660
663
  index,
@@ -807,7 +810,13 @@ To fix this warning:
807
810
 
808
811
  const executionRemainingSet = new Set(executionPlanifiedSet);
809
812
  const executionExecutingSet = new Set();
813
+ const usedTagSet = new Set();
810
814
  const start = async (execution) => {
815
+ if (execution.params.uses) {
816
+ for (const tagThatWillBeUsed of execution.params.uses) {
817
+ usedTagSet.add(tagThatWillBeUsed);
818
+ }
819
+ }
811
820
  execution.fileExecutionCount = Object.keys(
812
821
  testPlanResult.results[execution.fileRelativeUrl],
813
822
  ).length;
@@ -827,7 +836,6 @@ To fix this warning:
827
836
  afterEachCallbackSet.add(callback);
828
837
  }
829
838
  }
830
-
831
839
  for (const beforeEachInOrderCallback of beforeEachInOrderCallbackSet) {
832
840
  const returnValue = beforeEachInOrderCallback(
833
841
  execution,
@@ -860,7 +868,6 @@ To fix this warning:
860
868
  process.exitCode = 1;
861
869
  }
862
870
  }
863
-
864
871
  for (const afterEachCallback of afterEachCallbackSet) {
865
872
  afterEachCallback(execution, testPlanResult);
866
873
  }
@@ -870,7 +877,11 @@ To fix this warning:
870
877
  afterEachInOrderCallback(execution, testPlanResult);
871
878
  }
872
879
  });
873
-
880
+ if (execution.params.uses) {
881
+ for (const tagNoLongerInUse of execution.params.uses) {
882
+ usedTagSet.delete(tagNoLongerInUse);
883
+ }
884
+ }
874
885
  if (testPlanResult.failed && failFast && counters.remaining) {
875
886
  logger.info(`"failFast" enabled -> cancel remaining executions`);
876
887
  failFastAbortController.abort();
@@ -878,23 +889,16 @@ To fix this warning:
878
889
  }
879
890
  };
880
891
  const startAsMuchAsPossible = async () => {
892
+ operation.throwIfAborted();
881
893
  const promises = [];
882
- // eslint-disable-next-line no-constant-condition
883
- while (true) {
884
- operation.throwIfAborted();
885
- if (executionRemainingSet.size === 0) {
886
- break;
887
- }
894
+ for (const executionCandidate of executionRemainingSet) {
888
895
  if (executionExecutingSet.size >= parallel.max) {
889
896
  break;
890
897
  }
891
-
892
- if (
898
+ if (executionExecutingSet.size > 0) {
893
899
  // starting execution in parallel is limited by
894
900
  // cpu and memory only when trying to parallelize
895
901
  // if nothing is executing these limitations don't apply
896
- executionExecutingSet.size > 0
897
- ) {
898
902
  if (processMemoryUsageMonitoring.measure() > parallel.maxMemory) {
899
903
  // retry after Xms in case memory usage decreases
900
904
  const promise = (async () => {
@@ -904,7 +908,6 @@ To fix this warning:
904
908
  promises.push(promise);
905
909
  break;
906
910
  }
907
-
908
911
  if (processCpuUsageMonitoring.measure() > parallel.maxCpu) {
909
912
  // retry after Xms in case cpu usage decreases
910
913
  const promise = (async () => {
@@ -914,27 +917,29 @@ To fix this warning:
914
917
  promises.push(promise);
915
918
  break;
916
919
  }
920
+ if (executionCandidate.params.uses) {
921
+ const nonAvailableTag = executionCandidate.params.uses.find(
922
+ (tagToUse) => usedTagSet.has(tagToUse),
923
+ );
924
+ if (nonAvailableTag) {
925
+ logger.debug(
926
+ `"${nonAvailableTag}" is not available, ${executionCandidate.name} will wait until it is released by a previous execution`,
927
+ );
928
+ continue;
929
+ }
930
+ }
917
931
  }
918
-
919
- let execution;
920
- for (const executionCandidate of executionRemainingSet) {
921
- // TODO: this is where we'll check if it can be executed
922
- // according to upcoming "using" execution param
923
- execution = executionCandidate;
924
- break;
925
- }
926
- if (execution) {
927
- const promise = (async () => {
928
- await start(execution);
929
- await startAsMuchAsPossible();
930
- })();
931
- promises.push(promise);
932
- }
932
+ const promise = (async () => {
933
+ await start(executionCandidate);
934
+ await startAsMuchAsPossible();
935
+ })();
936
+ promises.push(promise);
933
937
  }
934
- if (promises.length) {
935
- await Promise.all(promises);
936
- promises.length = 0;
938
+ if (promises.length === 0) {
939
+ return;
937
940
  }
941
+ await Promise.all(promises);
942
+ promises.length = 0;
938
943
  };
939
944
 
940
945
  reporters = reporters.flat(Infinity);
@@ -142,7 +142,7 @@ export const formatErrorForTerminal = (
142
142
  // debugger
143
143
  // })
144
144
  const replaceUrls = (source, replace) => {
145
- return source.replace(/(?:https?|ftp|file):\/\/\S+/gm, (match) => {
145
+ return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
146
146
  let replacement = "";
147
147
  const lastChar = match[match.length - 1];
148
148
 
@@ -85,7 +85,7 @@ const stringifyUrlSite = ({ url, line, column }) => {
85
85
  };
86
86
 
87
87
  const replaceUrls = (source, replace) => {
88
- return source.replace(/(?:https?|ftp|file):\/\/\S+/gm, (match) => {
88
+ return source.replace(/(?:https?|ftp|file):\/\/\S+/g, (match) => {
89
89
  let replacement = "";
90
90
  const lastChar = match[match.length - 1];
91
91
 
package/src/main.js CHANGED
@@ -16,3 +16,7 @@ export { reporterList } from "./execution/reporters/reporter_list.js";
16
16
  export { reportAsJunitXml } from "./execution/junit_xml_file/report_as_junit_xml.js";
17
17
  // advanced
18
18
  export { execute } from "./execution/execute.js";
19
+
20
+ // internals
21
+ // help for internal self unit test
22
+ export { inlineRuntime } from "./runtime_inline/runtime_inline.js";
@@ -0,0 +1,72 @@
1
+ import { Abort, raceCallbacks } from "@jsenv/abort";
2
+
3
+ export const inlineRuntime = (fn) => {
4
+ return {
5
+ type: "inline",
6
+ name: "inline",
7
+ version: "1",
8
+ run: async ({
9
+ signal = new AbortController().signal,
10
+ onRuntimeStarted,
11
+ onRuntimeStopped,
12
+ }) => {
13
+ const actionOperation = Abort.startOperation();
14
+ actionOperation.addAbortSignal(signal);
15
+ const result = {
16
+ status: "executing",
17
+ errors: [],
18
+ namespace: null,
19
+ timings: {},
20
+ memoryUsage: null,
21
+ performance: null,
22
+ };
23
+ try {
24
+ let executionInternalErrorCallback;
25
+ let executionCompletedCallback;
26
+ const winnerPromise = new Promise((resolve) => {
27
+ raceCallbacks(
28
+ {
29
+ aborted: (cb) => {
30
+ return actionOperation.addAbortCallback(cb);
31
+ },
32
+ execution_internal_error: (cb) => {
33
+ executionInternalErrorCallback = cb;
34
+ },
35
+ execution_completed: (cb) => {
36
+ executionCompletedCallback = cb;
37
+ },
38
+ },
39
+ resolve,
40
+ );
41
+ });
42
+ try {
43
+ onRuntimeStarted();
44
+ const value = await fn();
45
+ executionCompletedCallback(value);
46
+ } catch (e) {
47
+ executionInternalErrorCallback(e);
48
+ }
49
+ const raceHandlers = {
50
+ aborted: () => {
51
+ result.status = "aborted";
52
+ },
53
+ execution_internal_error: (e) => {
54
+ result.status = "failed";
55
+ result.errors.push(e);
56
+ },
57
+ execution_completed: (value) => {
58
+ result.status = "completed";
59
+ result.errors = [];
60
+ result.namespace = value;
61
+ },
62
+ };
63
+ const winner = await winnerPromise;
64
+ raceHandlers[winner.name](winner.data);
65
+ } finally {
66
+ onRuntimeStopped();
67
+ await actionOperation.end();
68
+ return result;
69
+ }
70
+ },
71
+ };
72
+ };