@jsenv/core 25.4.5 → 25.6.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.
- package/dist/browser_runtime/asset-manifest.json +2 -2
- package/dist/browser_runtime/browser_runtime_27a156f1.js +5297 -0
- package/dist/browser_runtime/browser_runtime_27a156f1.js.map +1089 -0
- package/dist/build_manifest.js +6 -6
- package/dist/compile_proxy/asset-manifest.json +1 -1
- package/dist/compile_proxy/{compile_proxy_ab528227.html → compile_proxy_f2f16cc6.html} +3 -2
- package/dist/event_source_client/asset-manifest.json +2 -2
- package/dist/event_source_client/event_source_client_69f48287.js +354 -0
- package/dist/event_source_client/{event_source_client_80644aee.js.map → event_source_client_69f48287.js.map} +2 -2
- package/dist/redirector/asset-manifest.json +1 -1
- package/dist/redirector/{redirector_6df2620a.html → redirector_eef2bb25.html} +3 -2
- package/dist/toolbar/asset-manifest.json +5 -5
- package/dist/toolbar/assets/{compilation.css_e37c747b.map → compilation.css_7421bd55.map} +3 -3
- package/dist/toolbar/assets/settings.css_942b5a9e.map +12 -0
- package/dist/toolbar/assets/{toolbar.main.css_269d7ce2.map → toolbar.main.css_b7d8bec1.map} +4 -4
- package/dist/toolbar/{toolbar.main_279b3a68.js.map → toolbar.main_2c56a4e0.js.map} +24 -12
- package/dist/toolbar/{toolbar_0a91ca3b.html → toolbar_7447de59.html} +100 -65
- package/dist/toolbar_injector/asset-manifest.json +2 -2
- package/dist/toolbar_injector/toolbar_injector_524c2404.js +974 -0
- package/dist/toolbar_injector/{toolbar_injector_34f6ad8e.js.map → toolbar_injector_524c2404.js.map} +3 -3
- package/package.json +6 -3
- package/readme.md +20 -17
- package/src/buildProject.js +12 -20
- package/src/executeTestPlan.js +20 -19
- package/src/internal/building/buildUsingRollup.js +5 -20
- package/src/internal/building/build_logs.js +33 -37
- package/src/internal/building/build_stats.js +2 -1
- package/src/internal/building/es_to_system.js +34 -0
- package/src/internal/building/import_references.js +0 -1
- package/src/internal/building/rollup_plugin_jsenv.js +146 -43
- package/src/internal/compiling/createCompiledFileService.js +0 -4
- package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -3
- package/src/internal/compiling/jsenv_directory/compile_context.js +1 -10
- package/src/internal/compiling/jsenv_directory/compile_profile.js +1 -2
- package/src/internal/compiling/jsenv_directory/jsenv_directory.js +1 -1
- package/src/internal/compiling/startCompileServer.js +0 -14
- package/src/internal/dev_server/toolbar/compilation/compilation.css +3 -2
- package/src/internal/dev_server/toolbar/compilation/toolbar.compilation.js +19 -19
- package/src/internal/dev_server/toolbar/notification/toolbar.notification.js +66 -37
- package/src/internal/dev_server/toolbar/settings/settings.css +1 -2
- package/src/internal/dev_server/toolbar/toolbar.html +9 -5
- package/src/internal/dev_server/toolbar/toolbar.main.js +5 -3
- package/src/internal/dev_server/toolbar/util/iframe_to_parent_href.js +10 -0
- package/src/internal/executing/coverage/reportToCoverage.js +1 -0
- package/src/internal/executing/coverage_utils/v8_coverage_from_directory.js +2 -1
- package/src/internal/executing/executePlan.js +450 -60
- package/src/internal/runtime/s.js +3 -2
- package/src/internal/runtime_support/runtime_support.js +1 -1
- package/dist/browser_runtime/browser_runtime_0e3396a1.js +0 -5298
- package/dist/browser_runtime/browser_runtime_0e3396a1.js.map +0 -1089
- package/dist/event_source_client/event_source_client_80644aee.js +0 -356
- package/dist/toolbar/assets/settings.css_61548139.map +0 -12
- package/dist/toolbar_injector/toolbar_injector_34f6ad8e.js +0 -976
- package/src/internal/executing/executeConcurrently.js +0 -440
|
@@ -1,11 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { existsSync } from "node:fs"
|
|
2
|
+
import { memoryUsage } from "node:process"
|
|
3
|
+
import wrapAnsi from "wrap-ansi"
|
|
4
|
+
import stripAnsi from "strip-ansi"
|
|
5
|
+
import cuid from "cuid"
|
|
6
|
+
import { createDetailedMessage, loggerToLevels } from "@jsenv/logger"
|
|
7
|
+
import { createLog, startSpinner } from "@jsenv/log"
|
|
8
|
+
import {
|
|
9
|
+
Abort,
|
|
10
|
+
raceProcessTeardownEvents,
|
|
11
|
+
createCallbackListNotifiedOnce,
|
|
12
|
+
} from "@jsenv/abort"
|
|
13
|
+
import {
|
|
14
|
+
urlToFileSystemPath,
|
|
15
|
+
resolveUrl,
|
|
16
|
+
writeDirectory,
|
|
17
|
+
ensureEmptyDirectory,
|
|
18
|
+
normalizeStructuredMetaMap,
|
|
19
|
+
urlToMeta,
|
|
20
|
+
writeFile,
|
|
21
|
+
} from "@jsenv/filesystem"
|
|
3
22
|
|
|
4
|
-
import { mergeRuntimeSupport } from "@jsenv/core/src/internal/runtime_support/runtime_support.js"
|
|
5
23
|
import { startCompileServer } from "../compiling/startCompileServer.js"
|
|
6
24
|
import { babelPluginInstrument } from "./coverage/babel_plugin_instrument.js"
|
|
7
25
|
import { generateExecutionSteps } from "./generateExecutionSteps.js"
|
|
8
|
-
|
|
26
|
+
|
|
27
|
+
import { launchAndExecute } from "../executing/launchAndExecute.js"
|
|
28
|
+
import { reportToCoverage } from "./coverage/reportToCoverage.js"
|
|
29
|
+
import { formatExecuting, formatExecutionResult } from "./executionLogs.js"
|
|
30
|
+
import { createSummaryLog } from "./createSummaryLog.js"
|
|
31
|
+
import { ensureGlobalGc } from "./gc.js"
|
|
9
32
|
|
|
10
33
|
export const executePlan = async (
|
|
11
34
|
plan,
|
|
@@ -26,11 +49,13 @@ export const executePlan = async (
|
|
|
26
49
|
|
|
27
50
|
logSummary,
|
|
28
51
|
logMemoryHeapUsage,
|
|
52
|
+
logFileRelativeUrl,
|
|
29
53
|
completedExecutionLogMerging,
|
|
30
54
|
completedExecutionLogAbbreviation,
|
|
31
55
|
|
|
32
56
|
defaultMsAllocatedPerExecution,
|
|
33
57
|
maxExecutionsInParallel,
|
|
58
|
+
failFast,
|
|
34
59
|
gcBetweenExecutions,
|
|
35
60
|
stopAfterExecute,
|
|
36
61
|
cooldownBetweenExecutions,
|
|
@@ -56,6 +81,9 @@ export const executePlan = async (
|
|
|
56
81
|
serviceWorkers,
|
|
57
82
|
importMapInWebWorkers,
|
|
58
83
|
customCompilers,
|
|
84
|
+
|
|
85
|
+
beforeExecutionCallback = () => {},
|
|
86
|
+
afterExecutionCallback = () => {},
|
|
59
87
|
} = {},
|
|
60
88
|
) => {
|
|
61
89
|
if (coverage) {
|
|
@@ -67,27 +95,22 @@ export const executePlan = async (
|
|
|
67
95
|
],
|
|
68
96
|
}
|
|
69
97
|
}
|
|
70
|
-
|
|
71
|
-
const runtimeSupport = {}
|
|
98
|
+
const runtimes = {}
|
|
72
99
|
Object.keys(plan).forEach((filePattern) => {
|
|
73
100
|
const filePlan = plan[filePattern]
|
|
74
101
|
Object.keys(filePlan).forEach((executionName) => {
|
|
75
102
|
const executionConfig = filePlan[executionName]
|
|
76
103
|
const { runtime } = executionConfig
|
|
77
104
|
if (runtime) {
|
|
78
|
-
|
|
79
|
-
[runtime.name]: runtime.version,
|
|
80
|
-
})
|
|
105
|
+
runtimes[runtime.name] = runtime.version
|
|
81
106
|
}
|
|
82
107
|
})
|
|
83
108
|
})
|
|
84
|
-
|
|
85
109
|
logger.debug(
|
|
86
110
|
createDetailedMessage(`Prepare executing plan`, {
|
|
87
|
-
|
|
111
|
+
runtimes: JSON.stringify(runtimes, null, " "),
|
|
88
112
|
}),
|
|
89
113
|
)
|
|
90
|
-
|
|
91
114
|
const multipleExecutionsOperation = Abort.startOperation()
|
|
92
115
|
multipleExecutionsOperation.addAbortSignal(signal)
|
|
93
116
|
if (handleSIGINT) {
|
|
@@ -103,6 +126,10 @@ export const executePlan = async (
|
|
|
103
126
|
)
|
|
104
127
|
})
|
|
105
128
|
}
|
|
129
|
+
const failFastAbortController = new AbortController()
|
|
130
|
+
if (failFast) {
|
|
131
|
+
multipleExecutionsOperation.addAbortSignal(failFastAbortController.signal)
|
|
132
|
+
}
|
|
106
133
|
|
|
107
134
|
try {
|
|
108
135
|
const compileServer = await startCompileServer({
|
|
@@ -131,74 +158,303 @@ export const executePlan = async (
|
|
|
131
158
|
serviceWorkers,
|
|
132
159
|
importMapInWebWorkers,
|
|
133
160
|
customCompilers,
|
|
134
|
-
runtimeSupport,
|
|
135
161
|
})
|
|
136
|
-
|
|
162
|
+
babelPluginMap = compileServer.babelPluginMap
|
|
137
163
|
multipleExecutionsOperation.addEndCallback(async () => {
|
|
138
164
|
await compileServer.stop()
|
|
139
165
|
})
|
|
140
|
-
|
|
141
166
|
logger.debug(`Generate executions`)
|
|
167
|
+
const executionSteps = await getExecutionAsSteps({
|
|
168
|
+
plan,
|
|
169
|
+
compileServer,
|
|
170
|
+
multipleExecutionsOperation,
|
|
171
|
+
projectDirectoryUrl,
|
|
172
|
+
})
|
|
173
|
+
logger.debug(`${executionSteps.length} executions planned`)
|
|
142
174
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
...plan,
|
|
148
|
-
[compileServer.jsenvDirectoryRelativeUrl]: null,
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
signal: multipleExecutionsOperation.signal,
|
|
152
|
-
projectDirectoryUrl,
|
|
153
|
-
},
|
|
175
|
+
if (completedExecutionLogMerging && !process.stdout.isTTY) {
|
|
176
|
+
completedExecutionLogMerging = false
|
|
177
|
+
logger.debug(
|
|
178
|
+
`Force completedExecutionLogMerging to false because process.stdout.isTTY is false`,
|
|
154
179
|
)
|
|
155
|
-
} catch (e) {
|
|
156
|
-
if (Abort.isAbortError(e)) {
|
|
157
|
-
return {
|
|
158
|
-
aborted: true,
|
|
159
|
-
planSummary: {},
|
|
160
|
-
planReport: {},
|
|
161
|
-
planCoverage: null,
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
throw e
|
|
165
180
|
}
|
|
166
|
-
|
|
181
|
+
const executionLogsEnabled = loggerToLevels(logger).info
|
|
182
|
+
const executionSpinner = executionLogsEnabled && process.stdout.isTTY
|
|
167
183
|
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
184
|
+
const startMs = Date.now()
|
|
185
|
+
const report = {}
|
|
186
|
+
const executionCount = executionSteps.length
|
|
187
|
+
let rawOutput = ""
|
|
188
|
+
|
|
189
|
+
let transformReturnValue = (value) => value
|
|
172
190
|
|
|
191
|
+
if (gcBetweenExecutions) {
|
|
192
|
+
ensureGlobalGc()
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const coverageTempDirectoryUrl = resolveUrl(
|
|
196
|
+
coverageTempDirectoryRelativeUrl,
|
|
173
197
|
projectDirectoryUrl,
|
|
174
|
-
|
|
198
|
+
)
|
|
199
|
+
const structuredMetaMapForCover = normalizeStructuredMetaMap(
|
|
200
|
+
{
|
|
201
|
+
cover: coverageConfig,
|
|
202
|
+
},
|
|
203
|
+
projectDirectoryUrl,
|
|
204
|
+
)
|
|
205
|
+
const coverageIgnorePredicate = (url) => {
|
|
206
|
+
return !urlToMeta({
|
|
207
|
+
url: resolveUrl(url, projectDirectoryUrl),
|
|
208
|
+
structuredMetaMap: structuredMetaMapForCover,
|
|
209
|
+
}).cover
|
|
210
|
+
}
|
|
175
211
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
212
|
+
if (coverage) {
|
|
213
|
+
// in case runned multiple times, we don't want to keep writing lot of files in this directory
|
|
214
|
+
if (!process.env.NODE_V8_COVERAGE) {
|
|
215
|
+
await ensureEmptyDirectory(coverageTempDirectoryUrl)
|
|
216
|
+
}
|
|
217
|
+
if (runtimes.node) {
|
|
218
|
+
// v8 coverage is written in a directoy and auto propagate to subprocesses
|
|
219
|
+
// through process.env.NODE_V8_COVERAGE.
|
|
220
|
+
if (!coverageForceIstanbul && !process.env.NODE_V8_COVERAGE) {
|
|
221
|
+
const v8CoverageDirectory = resolveUrl(
|
|
222
|
+
`./node_v8/${cuid()}`,
|
|
223
|
+
coverageTempDirectoryUrl,
|
|
224
|
+
)
|
|
225
|
+
await writeDirectory(v8CoverageDirectory, { allowUseless: true })
|
|
226
|
+
process.env.NODE_V8_COVERAGE =
|
|
227
|
+
urlToFileSystemPath(v8CoverageDirectory)
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
transformReturnValue = async (value) => {
|
|
232
|
+
if (multipleExecutionsOperation.signal.aborted) {
|
|
233
|
+
// don't try to do the coverage stuff
|
|
234
|
+
return value
|
|
235
|
+
}
|
|
179
236
|
|
|
180
|
-
|
|
237
|
+
try {
|
|
238
|
+
value.coverage = await reportToCoverage(value.report, {
|
|
239
|
+
signal: multipleExecutionsOperation.signal,
|
|
240
|
+
logger,
|
|
241
|
+
projectDirectoryUrl,
|
|
242
|
+
babelPluginMap,
|
|
243
|
+
coverageConfig,
|
|
244
|
+
coverageIncludeMissing,
|
|
245
|
+
coverageForceIstanbul,
|
|
246
|
+
coverageIgnorePredicate,
|
|
247
|
+
coverageV8ConflictWarning,
|
|
248
|
+
})
|
|
249
|
+
} catch (e) {
|
|
250
|
+
if (Abort.isAbortError(e)) {
|
|
251
|
+
return value
|
|
252
|
+
}
|
|
253
|
+
throw e
|
|
254
|
+
}
|
|
255
|
+
return value
|
|
256
|
+
}
|
|
257
|
+
}
|
|
181
258
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
259
|
+
logger.info("")
|
|
260
|
+
let executionLog = createLog({ newLine: "" })
|
|
261
|
+
let abortedCount = 0
|
|
262
|
+
let timedoutCount = 0
|
|
263
|
+
let erroredCount = 0
|
|
264
|
+
let completedCount = 0
|
|
265
|
+
const stopAfterAllExecutionCallbackList = createCallbackListNotifiedOnce()
|
|
186
266
|
|
|
187
|
-
|
|
267
|
+
let executionDoneCount = 0
|
|
268
|
+
await executeInParallel({
|
|
269
|
+
multipleExecutionsOperation,
|
|
188
270
|
maxExecutionsInParallel,
|
|
189
|
-
stopAfterExecute,
|
|
190
|
-
gcBetweenExecutions,
|
|
191
271
|
cooldownBetweenExecutions,
|
|
272
|
+
executionSteps,
|
|
273
|
+
start: async (paramsFromStep) => {
|
|
274
|
+
const executionIndex = executionSteps.indexOf(paramsFromStep)
|
|
275
|
+
const { executionName, fileRelativeUrl, runtime } = paramsFromStep
|
|
276
|
+
const runtimeName = runtime.name
|
|
277
|
+
const runtimeVersion = runtime.version
|
|
192
278
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
279
|
+
const executionParams = {
|
|
280
|
+
// the params below can be overriden by executionDefaultParams
|
|
281
|
+
measurePerformance: false,
|
|
282
|
+
collectPerformance: false,
|
|
283
|
+
captureConsole: true,
|
|
284
|
+
stopAfterExecute,
|
|
285
|
+
stopAfterExecuteReason: "execution-done",
|
|
286
|
+
allocatedMs: defaultMsAllocatedPerExecution,
|
|
287
|
+
...paramsFromStep,
|
|
288
|
+
runtime,
|
|
289
|
+
// mirrorConsole: false because file will be executed in parallel
|
|
290
|
+
// so log would be a mess to read
|
|
291
|
+
mirrorConsole: false,
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const beforeExecutionInfo = {
|
|
295
|
+
fileRelativeUrl,
|
|
296
|
+
runtimeName,
|
|
297
|
+
runtimeVersion,
|
|
298
|
+
executionIndex,
|
|
299
|
+
executionParams,
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
let spinner
|
|
303
|
+
if (executionSpinner) {
|
|
304
|
+
spinner = startSpinner({
|
|
305
|
+
log: executionLog,
|
|
306
|
+
text: formatExecuting(beforeExecutionInfo, {
|
|
307
|
+
executionCount,
|
|
308
|
+
abortedCount,
|
|
309
|
+
timedoutCount,
|
|
310
|
+
erroredCount,
|
|
311
|
+
completedCount,
|
|
312
|
+
...(logMemoryHeapUsage
|
|
313
|
+
? { memoryHeap: memoryUsage().heapUsed }
|
|
314
|
+
: {}),
|
|
315
|
+
}),
|
|
316
|
+
})
|
|
317
|
+
}
|
|
318
|
+
beforeExecutionCallback(beforeExecutionInfo)
|
|
319
|
+
|
|
320
|
+
const filePath = urlToFileSystemPath(
|
|
321
|
+
`${projectDirectoryUrl}${fileRelativeUrl}`,
|
|
322
|
+
)
|
|
323
|
+
let executionResult
|
|
324
|
+
if (existsSync(filePath)) {
|
|
325
|
+
executionResult = await launchAndExecute({
|
|
326
|
+
signal: multipleExecutionsOperation.signal,
|
|
327
|
+
launchAndExecuteLogLevel,
|
|
328
|
+
|
|
329
|
+
...executionParams,
|
|
330
|
+
collectCoverage: coverage,
|
|
331
|
+
coverageTempDirectoryUrl,
|
|
332
|
+
runtimeParams: {
|
|
333
|
+
projectDirectoryUrl,
|
|
334
|
+
compileServerOrigin: compileServer.origin,
|
|
335
|
+
compileServerId: compileServer.id,
|
|
336
|
+
jsenvDirectoryRelativeUrl:
|
|
337
|
+
compileServer.jsenvDirectoryRelativeUrl,
|
|
338
|
+
|
|
339
|
+
collectCoverage: coverage,
|
|
340
|
+
coverageIgnorePredicate,
|
|
341
|
+
coverageForceIstanbul,
|
|
342
|
+
stopAfterAllExecutionCallbackList,
|
|
343
|
+
...executionParams.runtimeParams,
|
|
344
|
+
},
|
|
345
|
+
executeParams: {
|
|
346
|
+
fileRelativeUrl,
|
|
347
|
+
...executionParams.executeParams,
|
|
348
|
+
},
|
|
349
|
+
coverageV8ConflictWarning,
|
|
350
|
+
})
|
|
351
|
+
} else {
|
|
352
|
+
executionResult = {
|
|
353
|
+
status: "errored",
|
|
354
|
+
error: new Error(
|
|
355
|
+
`No file at ${fileRelativeUrl} for execution "${executionName}"`,
|
|
356
|
+
),
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
executionDoneCount++
|
|
360
|
+
if (fileRelativeUrl in report === false) {
|
|
361
|
+
report[fileRelativeUrl] = {}
|
|
362
|
+
}
|
|
363
|
+
report[fileRelativeUrl][executionName] = executionResult
|
|
364
|
+
const afterExecutionInfo = {
|
|
365
|
+
...beforeExecutionInfo,
|
|
366
|
+
endMs: Date.now(),
|
|
367
|
+
executionResult,
|
|
368
|
+
}
|
|
369
|
+
afterExecutionCallback(afterExecutionInfo)
|
|
370
|
+
|
|
371
|
+
if (executionResult.status === "aborted") {
|
|
372
|
+
abortedCount++
|
|
373
|
+
} else if (executionResult.status === "timedout") {
|
|
374
|
+
timedoutCount++
|
|
375
|
+
} else if (executionResult.status === "errored") {
|
|
376
|
+
erroredCount++
|
|
377
|
+
} else if (executionResult.status === "completed") {
|
|
378
|
+
completedCount++
|
|
379
|
+
}
|
|
380
|
+
if (gcBetweenExecutions) {
|
|
381
|
+
global.gc()
|
|
382
|
+
}
|
|
383
|
+
if (executionLogsEnabled) {
|
|
384
|
+
let log = formatExecutionResult(afterExecutionInfo, {
|
|
385
|
+
completedExecutionLogAbbreviation,
|
|
386
|
+
executionCount,
|
|
387
|
+
abortedCount,
|
|
388
|
+
timedoutCount,
|
|
389
|
+
erroredCount,
|
|
390
|
+
completedCount,
|
|
391
|
+
...(logMemoryHeapUsage
|
|
392
|
+
? { memoryHeap: memoryUsage().heapUsed }
|
|
393
|
+
: {}),
|
|
394
|
+
})
|
|
395
|
+
log = `${log}
|
|
396
|
+
|
|
397
|
+
`
|
|
398
|
+
const { columns = 80 } = process.stdout
|
|
399
|
+
log = wrapAnsi(log, columns, {
|
|
400
|
+
trim: false,
|
|
401
|
+
hard: true,
|
|
402
|
+
wordWrap: false,
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
// replace spinner with this execution result
|
|
406
|
+
if (spinner) spinner.stop()
|
|
407
|
+
executionLog.write(log)
|
|
408
|
+
rawOutput += stripAnsi(log)
|
|
409
|
+
|
|
410
|
+
const canOverwriteLog = canOverwriteLogGetter({
|
|
411
|
+
completedExecutionLogMerging,
|
|
412
|
+
executionResult,
|
|
413
|
+
})
|
|
414
|
+
if (canOverwriteLog) {
|
|
415
|
+
// nothing to do, we reuse the current executionLog object
|
|
416
|
+
} else {
|
|
417
|
+
executionLog.destroy()
|
|
418
|
+
executionLog = createLog({ newLine: "" })
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if (
|
|
422
|
+
failFast &&
|
|
423
|
+
executionResult.status !== "completed" &&
|
|
424
|
+
executionDoneCount < executionCount
|
|
425
|
+
) {
|
|
426
|
+
logger.info(`"failFast" enabled -> cancel remaining executions`)
|
|
427
|
+
failFastAbortController.abort()
|
|
428
|
+
}
|
|
429
|
+
},
|
|
200
430
|
})
|
|
201
431
|
|
|
432
|
+
if (stopAfterExecute) {
|
|
433
|
+
stopAfterAllExecutionCallbackList.notify()
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const summaryCounts = reportToSummary(report)
|
|
437
|
+
const summary = {
|
|
438
|
+
executionCount,
|
|
439
|
+
...summaryCounts,
|
|
440
|
+
// when execution is aborted, the remaining executions are "cancelled"
|
|
441
|
+
cancelledCount: executionCount - executionDoneCount,
|
|
442
|
+
duration: Date.now() - startMs,
|
|
443
|
+
}
|
|
444
|
+
if (logSummary) {
|
|
445
|
+
const summaryLog = createSummaryLog(summary)
|
|
446
|
+
rawOutput += stripAnsi(summaryLog)
|
|
447
|
+
logger.info(summaryLog)
|
|
448
|
+
}
|
|
449
|
+
if (summary.executionCount !== summary.completedCount) {
|
|
450
|
+
const logFileUrl = new URL(logFileRelativeUrl, projectDirectoryUrl)
|
|
451
|
+
writeFile(logFileUrl, rawOutput)
|
|
452
|
+
logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`)
|
|
453
|
+
}
|
|
454
|
+
const result = await transformReturnValue({
|
|
455
|
+
summary,
|
|
456
|
+
report,
|
|
457
|
+
})
|
|
202
458
|
return {
|
|
203
459
|
aborted: multipleExecutionsOperation.signal.aborted,
|
|
204
460
|
planSummary: result.summary,
|
|
@@ -209,3 +465,137 @@ export const executePlan = async (
|
|
|
209
465
|
await multipleExecutionsOperation.end()
|
|
210
466
|
}
|
|
211
467
|
}
|
|
468
|
+
|
|
469
|
+
const getExecutionAsSteps = async ({
|
|
470
|
+
plan,
|
|
471
|
+
compileServer,
|
|
472
|
+
multipleExecutionsOperation,
|
|
473
|
+
projectDirectoryUrl,
|
|
474
|
+
}) => {
|
|
475
|
+
try {
|
|
476
|
+
const executionSteps = await generateExecutionSteps(
|
|
477
|
+
{
|
|
478
|
+
...plan,
|
|
479
|
+
[compileServer.jsenvDirectoryRelativeUrl]: null,
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
signal: multipleExecutionsOperation.signal,
|
|
483
|
+
projectDirectoryUrl,
|
|
484
|
+
},
|
|
485
|
+
)
|
|
486
|
+
return executionSteps
|
|
487
|
+
} catch (e) {
|
|
488
|
+
if (Abort.isAbortError(e)) {
|
|
489
|
+
return {
|
|
490
|
+
aborted: true,
|
|
491
|
+
planSummary: {},
|
|
492
|
+
planReport: {},
|
|
493
|
+
planCoverage: null,
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
throw e
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const canOverwriteLogGetter = ({
|
|
501
|
+
completedExecutionLogMerging,
|
|
502
|
+
executionResult,
|
|
503
|
+
}) => {
|
|
504
|
+
if (!completedExecutionLogMerging) {
|
|
505
|
+
return false
|
|
506
|
+
}
|
|
507
|
+
if (executionResult.status === "aborted") {
|
|
508
|
+
return true
|
|
509
|
+
}
|
|
510
|
+
if (executionResult.status !== "completed") {
|
|
511
|
+
return false
|
|
512
|
+
}
|
|
513
|
+
const { consoleCalls = [] } = executionResult
|
|
514
|
+
if (consoleCalls.length > 0) {
|
|
515
|
+
return false
|
|
516
|
+
}
|
|
517
|
+
return true
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const executeInParallel = async ({
|
|
521
|
+
multipleExecutionsOperation,
|
|
522
|
+
maxExecutionsInParallel,
|
|
523
|
+
cooldownBetweenExecutions,
|
|
524
|
+
executionSteps,
|
|
525
|
+
start,
|
|
526
|
+
}) => {
|
|
527
|
+
const executionResults = []
|
|
528
|
+
let progressionIndex = 0
|
|
529
|
+
let remainingExecutionCount = executionSteps.length
|
|
530
|
+
|
|
531
|
+
const nextChunk = async () => {
|
|
532
|
+
if (multipleExecutionsOperation.signal.aborted) {
|
|
533
|
+
return
|
|
534
|
+
}
|
|
535
|
+
const outputPromiseArray = []
|
|
536
|
+
while (
|
|
537
|
+
remainingExecutionCount > 0 &&
|
|
538
|
+
outputPromiseArray.length < maxExecutionsInParallel
|
|
539
|
+
) {
|
|
540
|
+
remainingExecutionCount--
|
|
541
|
+
const outputPromise = executeOne(progressionIndex)
|
|
542
|
+
progressionIndex++
|
|
543
|
+
outputPromiseArray.push(outputPromise)
|
|
544
|
+
}
|
|
545
|
+
if (outputPromiseArray.length) {
|
|
546
|
+
await Promise.all(outputPromiseArray)
|
|
547
|
+
if (remainingExecutionCount > 0) {
|
|
548
|
+
await nextChunk()
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const executeOne = async (index) => {
|
|
554
|
+
const input = executionSteps[index]
|
|
555
|
+
const output = await start(input)
|
|
556
|
+
if (!multipleExecutionsOperation.signal.aborted) {
|
|
557
|
+
executionResults[index] = output
|
|
558
|
+
}
|
|
559
|
+
if (cooldownBetweenExecutions) {
|
|
560
|
+
await new Promise((resolve) =>
|
|
561
|
+
setTimeout(resolve, cooldownBetweenExecutions),
|
|
562
|
+
)
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
await nextChunk()
|
|
567
|
+
|
|
568
|
+
return executionResults
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const reportToSummary = (report) => {
|
|
572
|
+
const fileNames = Object.keys(report)
|
|
573
|
+
const countResultMatching = (predicate) => {
|
|
574
|
+
return fileNames.reduce((previous, fileName) => {
|
|
575
|
+
const fileExecutionResult = report[fileName]
|
|
576
|
+
|
|
577
|
+
return (
|
|
578
|
+
previous +
|
|
579
|
+
Object.keys(fileExecutionResult).filter((executionName) => {
|
|
580
|
+
const fileExecutionResultForRuntime =
|
|
581
|
+
fileExecutionResult[executionName]
|
|
582
|
+
return predicate(fileExecutionResultForRuntime)
|
|
583
|
+
}).length
|
|
584
|
+
)
|
|
585
|
+
}, 0)
|
|
586
|
+
}
|
|
587
|
+
const abortedCount = countResultMatching(({ status }) => status === "aborted")
|
|
588
|
+
const timedoutCount = countResultMatching(
|
|
589
|
+
({ status }) => status === "timedout",
|
|
590
|
+
)
|
|
591
|
+
const erroredCount = countResultMatching(({ status }) => status === "errored")
|
|
592
|
+
const completedCount = countResultMatching(
|
|
593
|
+
({ status }) => status === "completed",
|
|
594
|
+
)
|
|
595
|
+
return {
|
|
596
|
+
abortedCount,
|
|
597
|
+
timedoutCount,
|
|
598
|
+
erroredCount,
|
|
599
|
+
completedCount,
|
|
600
|
+
}
|
|
601
|
+
}
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
var loader = this;
|
|
226
226
|
return Promise.resolve(loader.prepareImport())
|
|
227
227
|
.then(function() {
|
|
228
|
-
return loader.resolve(id, parentUrl);
|
|
228
|
+
return loader.resolve(String(id), parentUrl);
|
|
229
229
|
})
|
|
230
230
|
.then(function (id) {
|
|
231
231
|
var load = getOrCreateLoad(loader, id);
|
|
@@ -813,12 +813,13 @@
|
|
|
813
813
|
System.register = function(deps, declare) {
|
|
814
814
|
System.register = register;
|
|
815
815
|
System.registerRegistry[self.location.href] = [deps, declare];
|
|
816
|
-
System.import(self.location.href).then(() => {
|
|
816
|
+
return System.import(self.location.href).then((result) => {
|
|
817
817
|
self.removeEventListener('message', messageCallback)
|
|
818
818
|
messageEvents.forEach((messageEvent) => {
|
|
819
819
|
self.dispatchEvent(messageEvent)
|
|
820
820
|
})
|
|
821
821
|
messageEvents = null
|
|
822
|
+
return result
|
|
822
823
|
})
|
|
823
824
|
}
|
|
824
825
|
}
|
|
@@ -56,7 +56,7 @@ const normalizeRuntimeVersion = (version) => {
|
|
|
56
56
|
return version
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
const mergeRuntimeSupport = (runtimeSupport, childRuntimeSupport) => {
|
|
60
60
|
Object.keys(childRuntimeSupport).forEach((runtimeName) => {
|
|
61
61
|
const childRuntimeVersion = normalizeRuntimeVersion(
|
|
62
62
|
childRuntimeSupport[runtimeName],
|