@jsenv/core 34.2.2 → 35.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.
- package/README.md +1 -1
- package/dist/html/explorer.html +5 -4
- package/dist/{jsenv.js → jsenv_core.js} +840 -3914
- package/package.json +7 -21
- package/src/build/build.js +34 -16
- package/src/build/version_mappings_injection.js +20 -27
- package/src/dev/file_service.js +9 -9
- package/src/dev/start_dev_server.js +3 -3
- package/src/dev/user_agent.js +1 -1
- package/src/kitchen/kitchen.js +5 -3
- package/src/main.js +0 -23
- package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +2 -2
- package/src/plugins/importmap/jsenv_plugin_importmap.js +6 -2
- package/src/plugins/{inline/jsenv_plugin_html_inline_content.js → inline_content_analysis/jsenv_plugin_html_inline_content_analysis.js} +12 -6
- package/src/plugins/{inline/jsenv_plugin_inline.js → inline_content_analysis/jsenv_plugin_inline_content_analysis.js} +8 -10
- package/src/plugins/{inline/jsenv_plugin_js_inline_content.js → inline_content_analysis/jsenv_plugin_js_inline_content_analysis.js} +4 -2
- package/src/plugins/inlining/jsenv_plugin_inlining.js +22 -0
- package/src/plugins/{inline/jsenv_plugin_inline_query_param.js → inlining/jsenv_plugin_inlining_as_data_url.js} +16 -9
- package/src/plugins/inlining/jsenv_plugin_inlining_into_html.js +149 -0
- package/src/plugins/plugins.js +5 -2
- package/src/plugins/ribbon/jsenv_plugin_ribbon.js +11 -10
- package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +2 -2
- package/src/plugins/supervisor/html_supervisor_injection.js +23 -25
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +1 -1
- package/src/plugins/transpilation/babel/require_babel_plugin.js +1 -1
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +20 -5
- package/src/plugins/transpilation/js_module_fallback/convert_js_module_to_js_classic.js +1 -1
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +2 -2
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +3 -3
- package/src/plugins/url_analysis/html/html_urls.js +1 -1
- package/dist/controllable_child_process.mjs +0 -129
- package/dist/controllable_worker_thread.mjs +0 -91
- package/dist/js/execute_using_dynamic_import.js +0 -850
- package/dist/js/v8_coverage.js +0 -508
- package/src/execute/execute.js +0 -109
- package/src/execute/run.js +0 -161
- package/src/execute/runtimes/browsers/chromium.js +0 -10
- package/src/execute/runtimes/browsers/firefox.js +0 -9
- package/src/execute/runtimes/browsers/from_playwright.js +0 -574
- package/src/execute/runtimes/browsers/middleware_istanbul.js +0 -65
- package/src/execute/runtimes/browsers/middleware_js_supervisor.js +0 -100
- package/src/execute/runtimes/browsers/webkit.js +0 -26
- package/src/execute/runtimes/node/child_exec_options.js +0 -166
- package/src/execute/runtimes/node/controllable_child_process.mjs +0 -135
- package/src/execute/runtimes/node/controllable_worker_thread.mjs +0 -103
- package/src/execute/runtimes/node/exec_options.js +0 -44
- package/src/execute/runtimes/node/execute_using_dynamic_import.js +0 -55
- package/src/execute/runtimes/node/exit_codes.js +0 -9
- package/src/execute/runtimes/node/kill_process_tree.js +0 -76
- package/src/execute/runtimes/node/node_child_process.js +0 -348
- package/src/execute/runtimes/node/node_execution_performance.js +0 -67
- package/src/execute/runtimes/node/node_worker_thread.js +0 -282
- package/src/execute/runtimes/node/profiler_v8_coverage.js +0 -56
- package/src/execute/runtimes/readme.md +0 -13
- package/src/execute/web_server_param.js +0 -74
- package/src/test/coverage/babel_plugin_instrument.js +0 -48
- package/src/test/coverage/coverage_reporter_html_directory.js +0 -32
- package/src/test/coverage/coverage_reporter_json_file.js +0 -17
- package/src/test/coverage/coverage_reporter_text_log.js +0 -19
- package/src/test/coverage/empty_coverage_factory.js +0 -52
- package/src/test/coverage/file_by_file_coverage.js +0 -25
- package/src/test/coverage/istanbul_coverage_composition.js +0 -28
- package/src/test/coverage/istanbul_coverage_map_from_coverage.js +0 -16
- package/src/test/coverage/list_files_not_covered.js +0 -15
- package/src/test/coverage/missing_coverage.js +0 -41
- package/src/test/coverage/report_to_coverage.js +0 -198
- package/src/test/coverage/v8_and_istanbul.js +0 -37
- package/src/test/coverage/v8_coverage.js +0 -26
- package/src/test/coverage/v8_coverage_composition.js +0 -24
- package/src/test/coverage/v8_coverage_node_directory.js +0 -85
- package/src/test/coverage/v8_coverage_to_istanbul.js +0 -99
- package/src/test/execute_steps.js +0 -425
- package/src/test/execute_test_plan.js +0 -372
- package/src/test/execution_colors.js +0 -10
- package/src/test/execution_steps.js +0 -65
- package/src/test/gc.js +0 -9
- package/src/test/logs_file_execution.js +0 -427
- package/src/test/logs_file_execution.test.mjs +0 -41
- package/src/test/readme.md +0 -3
- /package/src/{basic_fetch.js → helpers/basic_fetch.js} +0 -0
- /package/src/{lookup_package_directory.js → helpers/lookup_package_directory.js} +0 -0
- /package/src/{ping_server.js → helpers/ping_server.js} +0 -0
- /package/src/{require_from_jsenv.js → helpers/require_from_jsenv.js} +0 -0
- /package/src/{watch_source_files.js → helpers/watch_source_files.js} +0 -0
- /package/src/{web_url_converter.js → helpers/web_url_converter.js} +0 -0
- /package/src/plugins/{inline → inline_content_analysis}/client/inline_content.js +0 -0
- /package/src/plugins/{inline → inline_content_analysis}/jsenv_plugin_data_urls.js +0 -0
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
import { existsSync } from "node:fs"
|
|
2
|
-
import { memoryUsage } from "node:process"
|
|
3
|
-
import { takeCoverage } from "node:v8"
|
|
4
|
-
import stripAnsi from "strip-ansi"
|
|
5
|
-
|
|
6
|
-
import { urlToFileSystemPath } from "@jsenv/urls"
|
|
7
|
-
import { createLog, startSpinner } from "@jsenv/log"
|
|
8
|
-
import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
|
|
9
|
-
import { ensureEmptyDirectory, writeFileSync } from "@jsenv/filesystem"
|
|
10
|
-
|
|
11
|
-
import { reportToCoverage } from "./coverage/report_to_coverage.js"
|
|
12
|
-
import { run } from "@jsenv/core/src/execute/run.js"
|
|
13
|
-
|
|
14
|
-
import { ensureGlobalGc } from "./gc.js"
|
|
15
|
-
import { createExecutionLog, createSummaryLog } from "./logs_file_execution.js"
|
|
16
|
-
|
|
17
|
-
export const executeSteps = async (
|
|
18
|
-
executionSteps,
|
|
19
|
-
{
|
|
20
|
-
signal,
|
|
21
|
-
handleSIGINT,
|
|
22
|
-
logger,
|
|
23
|
-
logRefresh,
|
|
24
|
-
logRuntime,
|
|
25
|
-
logEachDuration,
|
|
26
|
-
logSummary,
|
|
27
|
-
logTimeUsage,
|
|
28
|
-
logMemoryHeapUsage,
|
|
29
|
-
logFileRelativeUrl,
|
|
30
|
-
completedExecutionLogMerging,
|
|
31
|
-
completedExecutionLogAbbreviation,
|
|
32
|
-
rootDirectoryUrl,
|
|
33
|
-
webServer,
|
|
34
|
-
|
|
35
|
-
keepRunning,
|
|
36
|
-
defaultMsAllocatedPerExecution,
|
|
37
|
-
maxExecutionsInParallel,
|
|
38
|
-
failFast,
|
|
39
|
-
gcBetweenExecutions,
|
|
40
|
-
cooldownBetweenExecutions,
|
|
41
|
-
|
|
42
|
-
coverageEnabled,
|
|
43
|
-
coverageConfig,
|
|
44
|
-
coverageIncludeMissing,
|
|
45
|
-
coverageMethodForBrowsers,
|
|
46
|
-
coverageMethodForNodeJs,
|
|
47
|
-
coverageV8ConflictWarning,
|
|
48
|
-
coverageTempDirectoryUrl,
|
|
49
|
-
|
|
50
|
-
beforeExecutionCallback = () => {},
|
|
51
|
-
afterExecutionCallback = () => {},
|
|
52
|
-
} = {},
|
|
53
|
-
) => {
|
|
54
|
-
const executePlanReturnValue = {}
|
|
55
|
-
const report = {}
|
|
56
|
-
const callbacks = []
|
|
57
|
-
const stopAfterAllSignal = { notify: () => {} }
|
|
58
|
-
|
|
59
|
-
const multipleExecutionsOperation = Abort.startOperation()
|
|
60
|
-
multipleExecutionsOperation.addAbortSignal(signal)
|
|
61
|
-
if (handleSIGINT) {
|
|
62
|
-
multipleExecutionsOperation.addAbortSource((abort) => {
|
|
63
|
-
return raceProcessTeardownEvents(
|
|
64
|
-
{
|
|
65
|
-
SIGINT: true,
|
|
66
|
-
},
|
|
67
|
-
() => {
|
|
68
|
-
logger.debug(`SIGINT abort`)
|
|
69
|
-
abort()
|
|
70
|
-
},
|
|
71
|
-
)
|
|
72
|
-
})
|
|
73
|
-
}
|
|
74
|
-
const failFastAbortController = new AbortController()
|
|
75
|
-
if (failFast) {
|
|
76
|
-
multipleExecutionsOperation.addAbortSignal(failFastAbortController.signal)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
if (gcBetweenExecutions) {
|
|
81
|
-
ensureGlobalGc()
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (coverageEnabled) {
|
|
85
|
-
// when runned multiple times, we don't want to keep previous files in this directory
|
|
86
|
-
await ensureEmptyDirectory(coverageTempDirectoryUrl)
|
|
87
|
-
callbacks.push(async () => {
|
|
88
|
-
if (multipleExecutionsOperation.signal.aborted) {
|
|
89
|
-
// don't try to do the coverage stuff
|
|
90
|
-
return
|
|
91
|
-
}
|
|
92
|
-
try {
|
|
93
|
-
if (coverageMethodForNodeJs === "NODE_V8_COVERAGE") {
|
|
94
|
-
takeCoverage()
|
|
95
|
-
// conceptually we don't need coverage anymore so it would be
|
|
96
|
-
// good to call v8.stopCoverage()
|
|
97
|
-
// but it logs a strange message about "result is not an object"
|
|
98
|
-
}
|
|
99
|
-
const planCoverage = await reportToCoverage(report, {
|
|
100
|
-
signal: multipleExecutionsOperation.signal,
|
|
101
|
-
logger,
|
|
102
|
-
rootDirectoryUrl,
|
|
103
|
-
coverageConfig,
|
|
104
|
-
coverageIncludeMissing,
|
|
105
|
-
coverageMethodForBrowsers,
|
|
106
|
-
coverageV8ConflictWarning,
|
|
107
|
-
})
|
|
108
|
-
executePlanReturnValue.planCoverage = planCoverage
|
|
109
|
-
} catch (e) {
|
|
110
|
-
if (Abort.isAbortError(e)) {
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
throw e
|
|
114
|
-
}
|
|
115
|
-
})
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
let runtimeParams = {
|
|
119
|
-
rootDirectoryUrl,
|
|
120
|
-
webServer,
|
|
121
|
-
|
|
122
|
-
coverageEnabled,
|
|
123
|
-
coverageConfig,
|
|
124
|
-
coverageMethodForBrowsers,
|
|
125
|
-
coverageMethodForNodeJs,
|
|
126
|
-
stopAfterAllSignal,
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (completedExecutionLogMerging && !process.stdout.isTTY) {
|
|
130
|
-
completedExecutionLogMerging = false
|
|
131
|
-
logger.debug(
|
|
132
|
-
`Force completedExecutionLogMerging to false because process.stdout.isTTY is false`,
|
|
133
|
-
)
|
|
134
|
-
}
|
|
135
|
-
const debugLogsEnabled = logger.levels.debug
|
|
136
|
-
const executionLogsEnabled = logger.levels.info
|
|
137
|
-
const executionSpinner =
|
|
138
|
-
logRefresh &&
|
|
139
|
-
!debugLogsEnabled &&
|
|
140
|
-
executionLogsEnabled &&
|
|
141
|
-
process.stdout.isTTY &&
|
|
142
|
-
// if there is an error during execution npm will mess up the output
|
|
143
|
-
// (happens when npm runs several command in a workspace)
|
|
144
|
-
// so we enable spinner only when !process.exitCode (no error so far)
|
|
145
|
-
process.exitCode !== 1
|
|
146
|
-
|
|
147
|
-
const startMs = Date.now()
|
|
148
|
-
let rawOutput = ""
|
|
149
|
-
let executionLog = createLog({ newLine: "" })
|
|
150
|
-
const counters = {
|
|
151
|
-
total: executionSteps.length,
|
|
152
|
-
aborted: 0,
|
|
153
|
-
timedout: 0,
|
|
154
|
-
failed: 0,
|
|
155
|
-
completed: 0,
|
|
156
|
-
done: 0,
|
|
157
|
-
}
|
|
158
|
-
await executeInParallel({
|
|
159
|
-
multipleExecutionsOperation,
|
|
160
|
-
maxExecutionsInParallel,
|
|
161
|
-
cooldownBetweenExecutions,
|
|
162
|
-
executionSteps,
|
|
163
|
-
start: async (paramsFromStep) => {
|
|
164
|
-
const executionIndex = executionSteps.indexOf(paramsFromStep)
|
|
165
|
-
const { executionName, fileRelativeUrl, runtime } = paramsFromStep
|
|
166
|
-
const runtimeType = runtime.type
|
|
167
|
-
const runtimeName = runtime.name
|
|
168
|
-
const runtimeVersion = runtime.version
|
|
169
|
-
const executionParams = {
|
|
170
|
-
measurePerformance: false,
|
|
171
|
-
collectPerformance: false,
|
|
172
|
-
collectConsole: true,
|
|
173
|
-
allocatedMs: defaultMsAllocatedPerExecution,
|
|
174
|
-
...paramsFromStep,
|
|
175
|
-
runtimeParams: {
|
|
176
|
-
fileRelativeUrl,
|
|
177
|
-
...paramsFromStep.runtimeParams,
|
|
178
|
-
},
|
|
179
|
-
}
|
|
180
|
-
const beforeExecutionInfo = {
|
|
181
|
-
fileRelativeUrl,
|
|
182
|
-
runtimeType,
|
|
183
|
-
runtimeName,
|
|
184
|
-
runtimeVersion,
|
|
185
|
-
executionIndex,
|
|
186
|
-
executionParams,
|
|
187
|
-
startMs: Date.now(),
|
|
188
|
-
executionResult: {
|
|
189
|
-
status: "executing",
|
|
190
|
-
},
|
|
191
|
-
}
|
|
192
|
-
let spinner
|
|
193
|
-
if (executionSpinner) {
|
|
194
|
-
spinner = startSpinner({
|
|
195
|
-
log: executionLog,
|
|
196
|
-
render: () => {
|
|
197
|
-
return createExecutionLog(beforeExecutionInfo, {
|
|
198
|
-
counters,
|
|
199
|
-
logRuntime,
|
|
200
|
-
logEachDuration,
|
|
201
|
-
...(logTimeUsage
|
|
202
|
-
? {
|
|
203
|
-
timeEllapsed: Date.now() - startMs,
|
|
204
|
-
}
|
|
205
|
-
: {}),
|
|
206
|
-
...(logMemoryHeapUsage
|
|
207
|
-
? { memoryHeap: memoryUsage().heapUsed }
|
|
208
|
-
: {}),
|
|
209
|
-
})
|
|
210
|
-
},
|
|
211
|
-
})
|
|
212
|
-
}
|
|
213
|
-
beforeExecutionCallback(beforeExecutionInfo)
|
|
214
|
-
|
|
215
|
-
const fileUrl = `${rootDirectoryUrl}${fileRelativeUrl}`
|
|
216
|
-
let executionResult
|
|
217
|
-
if (existsSync(new URL(fileUrl))) {
|
|
218
|
-
executionResult = await run({
|
|
219
|
-
signal: multipleExecutionsOperation.signal,
|
|
220
|
-
logger,
|
|
221
|
-
allocatedMs:
|
|
222
|
-
typeof executionParams.allocatedMs === "function"
|
|
223
|
-
? executionParams.allocatedMs(beforeExecutionInfo)
|
|
224
|
-
: executionParams.allocatedMs,
|
|
225
|
-
keepRunning,
|
|
226
|
-
mirrorConsole: false, // file are executed in parallel, log would be a mess to read
|
|
227
|
-
collectConsole: executionParams.collectConsole,
|
|
228
|
-
coverageEnabled,
|
|
229
|
-
coverageTempDirectoryUrl,
|
|
230
|
-
runtime: executionParams.runtime,
|
|
231
|
-
runtimeParams: {
|
|
232
|
-
...runtimeParams,
|
|
233
|
-
...executionParams.runtimeParams,
|
|
234
|
-
},
|
|
235
|
-
})
|
|
236
|
-
} else {
|
|
237
|
-
executionResult = {
|
|
238
|
-
status: "failed",
|
|
239
|
-
errors: [
|
|
240
|
-
new Error(
|
|
241
|
-
`No file at ${fileRelativeUrl} for execution "${executionName}"`,
|
|
242
|
-
),
|
|
243
|
-
],
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
counters.done++
|
|
247
|
-
const fileReport = report[fileRelativeUrl]
|
|
248
|
-
if (fileReport) {
|
|
249
|
-
fileReport[executionName] = executionResult
|
|
250
|
-
} else {
|
|
251
|
-
report[fileRelativeUrl] = {
|
|
252
|
-
[executionName]: executionResult,
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
const afterExecutionInfo = {
|
|
257
|
-
...beforeExecutionInfo,
|
|
258
|
-
runtimeVersion: runtime.version,
|
|
259
|
-
endMs: Date.now(),
|
|
260
|
-
executionResult,
|
|
261
|
-
}
|
|
262
|
-
afterExecutionCallback(afterExecutionInfo)
|
|
263
|
-
|
|
264
|
-
if (executionResult.status === "aborted") {
|
|
265
|
-
counters.aborted++
|
|
266
|
-
} else if (executionResult.status === "timedout") {
|
|
267
|
-
counters.timedout++
|
|
268
|
-
} else if (executionResult.status === "failed") {
|
|
269
|
-
counters.failed++
|
|
270
|
-
} else if (executionResult.status === "completed") {
|
|
271
|
-
counters.completed++
|
|
272
|
-
}
|
|
273
|
-
if (gcBetweenExecutions) {
|
|
274
|
-
global.gc()
|
|
275
|
-
}
|
|
276
|
-
if (executionLogsEnabled) {
|
|
277
|
-
const log = createExecutionLog(afterExecutionInfo, {
|
|
278
|
-
completedExecutionLogAbbreviation,
|
|
279
|
-
counters,
|
|
280
|
-
logRuntime,
|
|
281
|
-
logEachDuration,
|
|
282
|
-
...(logTimeUsage
|
|
283
|
-
? {
|
|
284
|
-
timeEllapsed: Date.now() - startMs,
|
|
285
|
-
}
|
|
286
|
-
: {}),
|
|
287
|
-
...(logMemoryHeapUsage
|
|
288
|
-
? { memoryHeap: memoryUsage().heapUsed }
|
|
289
|
-
: {}),
|
|
290
|
-
})
|
|
291
|
-
// replace spinner with this execution result
|
|
292
|
-
if (spinner) spinner.stop()
|
|
293
|
-
executionLog.write(log)
|
|
294
|
-
rawOutput += stripAnsi(log)
|
|
295
|
-
|
|
296
|
-
const canOverwriteLog = canOverwriteLogGetter({
|
|
297
|
-
completedExecutionLogMerging,
|
|
298
|
-
executionResult,
|
|
299
|
-
})
|
|
300
|
-
if (canOverwriteLog) {
|
|
301
|
-
// nothing to do, we reuse the current executionLog object
|
|
302
|
-
} else {
|
|
303
|
-
executionLog.destroy()
|
|
304
|
-
executionLog = createLog({ newLine: "" })
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
const isLastExecutionLog = executionIndex === executionSteps.length - 1
|
|
308
|
-
const cancelRemaining =
|
|
309
|
-
failFast &&
|
|
310
|
-
executionResult.status !== "completed" &&
|
|
311
|
-
counters.done < counters.total
|
|
312
|
-
if (isLastExecutionLog && logger.levels.info) {
|
|
313
|
-
executionLog.write("\n")
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (cancelRemaining) {
|
|
317
|
-
logger.info(`"failFast" enabled -> cancel remaining executions`)
|
|
318
|
-
failFastAbortController.abort()
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
})
|
|
322
|
-
if (!keepRunning) {
|
|
323
|
-
logger.debug("stopAfterAllSignal.notify()")
|
|
324
|
-
await stopAfterAllSignal.notify()
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
counters.cancelled = counters.total - counters.done
|
|
328
|
-
const summary = {
|
|
329
|
-
counters,
|
|
330
|
-
// when execution is aborted, the remaining executions are "cancelled"
|
|
331
|
-
duration: Date.now() - startMs,
|
|
332
|
-
}
|
|
333
|
-
if (logSummary) {
|
|
334
|
-
const summaryLog = createSummaryLog(summary)
|
|
335
|
-
rawOutput += stripAnsi(summaryLog)
|
|
336
|
-
logger.info(summaryLog)
|
|
337
|
-
}
|
|
338
|
-
if (summary.counters.total !== summary.counters.completed) {
|
|
339
|
-
const logFileUrl = new URL(logFileRelativeUrl, rootDirectoryUrl).href
|
|
340
|
-
writeFileSync(logFileUrl, rawOutput)
|
|
341
|
-
logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`)
|
|
342
|
-
}
|
|
343
|
-
executePlanReturnValue.aborted = multipleExecutionsOperation.signal.aborted
|
|
344
|
-
executePlanReturnValue.planSummary = summary
|
|
345
|
-
executePlanReturnValue.planReport = report
|
|
346
|
-
await callbacks.reduce(async (previous, callback) => {
|
|
347
|
-
await previous
|
|
348
|
-
await callback()
|
|
349
|
-
}, Promise.resolve())
|
|
350
|
-
return executePlanReturnValue
|
|
351
|
-
} finally {
|
|
352
|
-
await multipleExecutionsOperation.end()
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
const canOverwriteLogGetter = ({
|
|
357
|
-
completedExecutionLogMerging,
|
|
358
|
-
executionResult,
|
|
359
|
-
}) => {
|
|
360
|
-
if (!completedExecutionLogMerging) {
|
|
361
|
-
return false
|
|
362
|
-
}
|
|
363
|
-
if (executionResult.status === "aborted") {
|
|
364
|
-
return true
|
|
365
|
-
}
|
|
366
|
-
if (executionResult.status !== "completed") {
|
|
367
|
-
return false
|
|
368
|
-
}
|
|
369
|
-
const { consoleCalls = [] } = executionResult
|
|
370
|
-
if (consoleCalls.length > 0) {
|
|
371
|
-
return false
|
|
372
|
-
}
|
|
373
|
-
return true
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const executeInParallel = async ({
|
|
377
|
-
multipleExecutionsOperation,
|
|
378
|
-
maxExecutionsInParallel,
|
|
379
|
-
cooldownBetweenExecutions,
|
|
380
|
-
executionSteps,
|
|
381
|
-
start,
|
|
382
|
-
}) => {
|
|
383
|
-
const executionResults = []
|
|
384
|
-
let progressionIndex = 0
|
|
385
|
-
let remainingExecutionCount = executionSteps.length
|
|
386
|
-
|
|
387
|
-
const nextChunk = async () => {
|
|
388
|
-
if (multipleExecutionsOperation.signal.aborted) {
|
|
389
|
-
return
|
|
390
|
-
}
|
|
391
|
-
const outputPromiseArray = []
|
|
392
|
-
while (
|
|
393
|
-
remainingExecutionCount > 0 &&
|
|
394
|
-
outputPromiseArray.length < maxExecutionsInParallel
|
|
395
|
-
) {
|
|
396
|
-
remainingExecutionCount--
|
|
397
|
-
const outputPromise = executeOne(progressionIndex)
|
|
398
|
-
progressionIndex++
|
|
399
|
-
outputPromiseArray.push(outputPromise)
|
|
400
|
-
}
|
|
401
|
-
if (outputPromiseArray.length) {
|
|
402
|
-
await Promise.all(outputPromiseArray)
|
|
403
|
-
if (remainingExecutionCount > 0) {
|
|
404
|
-
await nextChunk()
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const executeOne = async (index) => {
|
|
410
|
-
const input = executionSteps[index]
|
|
411
|
-
const output = await start(input)
|
|
412
|
-
if (!multipleExecutionsOperation.signal.aborted) {
|
|
413
|
-
executionResults[index] = output
|
|
414
|
-
}
|
|
415
|
-
if (cooldownBetweenExecutions) {
|
|
416
|
-
await new Promise((resolve) =>
|
|
417
|
-
setTimeout(resolve, cooldownBetweenExecutions),
|
|
418
|
-
)
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
await nextChunk()
|
|
423
|
-
|
|
424
|
-
return executionResults
|
|
425
|
-
}
|