@jsenv/core 25.4.7 → 25.6.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 (60) hide show
  1. package/dist/browser_runtime/asset-manifest.json +2 -2
  2. package/dist/browser_runtime/browser_runtime_c81cd9af.js +5300 -0
  3. package/dist/browser_runtime/browser_runtime_c81cd9af.js.map +1089 -0
  4. package/dist/build_manifest.js +6 -6
  5. package/dist/compile_proxy/asset-manifest.json +2 -2
  6. package/dist/compile_proxy/{compile_proxy.html__inline__20_f4285042.js.map → compile_proxy.html__inline__20_c05fdc30.js.map} +2 -2
  7. package/dist/compile_proxy/{compile_proxy_ab528227.html → compile_proxy_93ec4247.html} +7 -4
  8. package/dist/event_source_client/asset-manifest.json +2 -2
  9. package/dist/event_source_client/event_source_client_69f48287.js +354 -0
  10. package/dist/event_source_client/{event_source_client_80644aee.js.map → event_source_client_69f48287.js.map} +2 -2
  11. package/dist/redirector/asset-manifest.json +2 -2
  12. package/dist/redirector/{redirector.html__inline__12_404b8295.js.map → redirector.html__inline__12_20421b23.js.map} +2 -2
  13. package/dist/redirector/{redirector_6df2620a.html → redirector_ddc79416.html} +7 -4
  14. package/dist/toolbar/asset-manifest.json +5 -5
  15. package/dist/toolbar/assets/{compilation.css_e37c747b.map → compilation.css_7421bd55.map} +3 -3
  16. package/dist/toolbar/assets/settings.css_942b5a9e.map +12 -0
  17. package/dist/toolbar/assets/{toolbar.main.css_269d7ce2.map → toolbar.main.css_b7d8bec1.map} +4 -4
  18. package/dist/toolbar/{toolbar.main_2c56a4e0.js.map → toolbar.main_7d7783d3.js.map} +2 -2
  19. package/dist/toolbar/{toolbar_17abd09a.html → toolbar_d6045dd0.html} +17 -11
  20. package/dist/toolbar_injector/asset-manifest.json +2 -2
  21. package/dist/toolbar_injector/toolbar_injector_c8c214dd.js +977 -0
  22. package/dist/toolbar_injector/{toolbar_injector_0f93509c.js.map → toolbar_injector_c8c214dd.js.map} +4 -4
  23. package/helpers/babel/asyncIterator/asyncIterator.js +61 -8
  24. package/helpers/babel/createClass/createClass.js +12 -12
  25. package/helpers/babel/inherits/inherits.js +10 -6
  26. package/helpers/babel/jsx/jsx.js +27 -22
  27. package/helpers/babel/objectSpread2/objectSpread2.js +22 -14
  28. package/helpers/babel/readme.md +3 -8
  29. package/helpers/babel/wrapRegExp/wrapRegExp.js +29 -29
  30. package/package.json +36 -36
  31. package/readme.md +21 -18
  32. package/src/buildProject.js +12 -20
  33. package/src/dev_server.js +6 -4
  34. package/src/executeTestPlan.js +20 -19
  35. package/src/internal/building/buildUsingRollup.js +5 -20
  36. package/src/internal/building/build_logs.js +33 -37
  37. package/src/internal/building/build_stats.js +2 -1
  38. package/src/internal/building/es_to_system.js +34 -0
  39. package/src/internal/building/import_references.js +0 -1
  40. package/src/internal/building/rollup_plugin_jsenv.js +146 -43
  41. package/src/internal/compiling/createCompiledFileService.js +0 -4
  42. package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -3
  43. package/src/internal/compiling/jsenv_directory/compile_context.js +1 -10
  44. package/src/internal/compiling/jsenv_directory/compile_profile.js +1 -2
  45. package/src/internal/compiling/startCompileServer.js +0 -14
  46. package/src/internal/dev_server/toolbar/compilation/compilation.css +3 -2
  47. package/src/internal/dev_server/toolbar/settings/settings.css +1 -2
  48. package/src/internal/dev_server/toolbar/toolbar.html +8 -4
  49. package/src/internal/executing/coverage/reportToCoverage.js +1 -0
  50. package/src/internal/executing/coverage_utils/v8_coverage_from_directory.js +2 -1
  51. package/src/internal/executing/executePlan.js +450 -60
  52. package/src/internal/jsenvCoreDirectoryUrl.js +7 -18
  53. package/src/internal/runtime/s.js +3 -2
  54. package/src/internal/runtime_support/runtime_support.js +1 -1
  55. package/dist/browser_runtime/browser_runtime_0e3396a1.js +0 -5298
  56. package/dist/browser_runtime/browser_runtime_0e3396a1.js.map +0 -1089
  57. package/dist/event_source_client/event_source_client_80644aee.js +0 -356
  58. package/dist/toolbar/assets/settings.css_61548139.map +0 -12
  59. package/dist/toolbar_injector/toolbar_injector_0f93509c.js +0 -976
  60. package/src/internal/executing/executeConcurrently.js +0 -440
@@ -1,11 +1,34 @@
1
- import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
2
- import { createDetailedMessage } from "@jsenv/logger"
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
- import { executeConcurrently } from "./executeConcurrently.js"
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
- mergeRuntimeSupport(runtimeSupport, {
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
- runtimeSupport: JSON.stringify(runtimeSupport, null, " "),
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
- let executionSteps
144
- try {
145
- executionSteps = await generateExecutionSteps(
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
- logger.debug(`${executionSteps.length} executions planned`)
181
+ const executionLogsEnabled = loggerToLevels(logger).info
182
+ const executionSpinner = executionLogsEnabled && process.stdout.isTTY
167
183
 
168
- const result = await executeConcurrently(executionSteps, {
169
- multipleExecutionsOperation,
170
- logger,
171
- launchAndExecuteLogLevel,
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
- compileServer,
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
- // not sure we actually have to pass import params to executeConcurrently
177
- importResolutionMethod,
178
- importDefaultExtension,
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
- babelPluginMap: compileServer.babelPluginMap,
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
- logSummary,
183
- logMemoryHeapUsage,
184
- completedExecutionLogMerging,
185
- completedExecutionLogAbbreviation,
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
- defaultMsAllocatedPerExecution,
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
- coverage,
194
- coverageConfig,
195
- coverageIncludeMissing,
196
- coverageForceIstanbul,
197
- coverageV8ConflictWarning,
198
- coverageTempDirectoryRelativeUrl,
199
- runtimeSupport,
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
+ }
@@ -1,22 +1,11 @@
1
- /* global __filename */
2
-
3
- import { fileSystemPathToUrl, resolveUrl } from "@jsenv/filesystem"
4
-
5
- let jsenvCoreDirectoryUrl
6
- if (typeof __filename === "string") {
7
- jsenvCoreDirectoryUrl = resolveUrl(
8
- // get ride of dist/commonjs/main.js
9
- "../../",
10
- fileSystemPathToUrl(__filename),
11
- )
12
- } else {
13
- jsenvCoreDirectoryUrl = resolveUrl(
1
+ export const jsenvCoreDirectoryUrl = String(
2
+ new URL(
14
3
  // get ride of src/internal/jsenvCoreDirectoryUrl.js
15
4
  "../../",
16
5
  import.meta.url,
17
- )
18
- }
19
-
20
- export const jsenvDistDirectoryUrl = new URL("./dist/", jsenvCoreDirectoryUrl)
6
+ ),
7
+ )
21
8
 
22
- export { jsenvCoreDirectoryUrl }
9
+ export const jsenvDistDirectoryUrl = String(
10
+ new URL("./dist/", jsenvCoreDirectoryUrl),
11
+ )
@@ -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
- export const mergeRuntimeSupport = (runtimeSupport, childRuntimeSupport) => {
59
+ const mergeRuntimeSupport = (runtimeSupport, childRuntimeSupport) => {
60
60
  Object.keys(childRuntimeSupport).forEach((runtimeName) => {
61
61
  const childRuntimeVersion = normalizeRuntimeVersion(
62
62
  childRuntimeSupport[runtimeName],