@jsenv/core 27.3.2 → 27.4.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.
Files changed (38) hide show
  1. package/README.md +16 -4
  2. package/dist/controllable_child_process.mjs +1 -0
  3. package/dist/controllable_worker_thread.mjs +1 -0
  4. package/dist/js/event_source_client.js +45 -24
  5. package/dist/js/execute_using_dynamic_import.js +5 -3
  6. package/dist/js/html_supervisor_installer.js +368 -139
  7. package/dist/main.js +668 -471
  8. package/package.json +5 -6
  9. package/src/build/build.js +6 -4
  10. package/src/build/graph_utils.js +14 -11
  11. package/src/execute/run.js +29 -28
  12. package/src/execute/runtimes/browsers/from_playwright.js +90 -92
  13. package/src/execute/runtimes/node/execute_using_dynamic_import.js +8 -2
  14. package/src/execute/runtimes/node/node_child_process.js +2 -0
  15. package/src/execute/runtimes/node/node_worker_thread.js +11 -6
  16. package/src/helpers/event_source/event_source.js +38 -17
  17. package/src/omega/errors.js +41 -9
  18. package/src/omega/kitchen.js +35 -19
  19. package/src/omega/omega_server.js +54 -1
  20. package/src/omega/server/file_service.js +30 -3
  21. package/src/omega/url_graph/url_graph_report.js +2 -4
  22. package/src/omega/url_graph.js +29 -16
  23. package/src/plugins/autoreload/dev_sse/client/event_source_client.js +8 -8
  24. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +160 -172
  25. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +0 -4
  26. package/src/plugins/bundling/js_module/bundle_js_module.js +0 -1
  27. package/src/plugins/html_supervisor/client/error_in_document.js +268 -121
  28. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +47 -5
  29. package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +37 -12
  30. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +1 -2
  31. package/src/plugins/plugins.js +0 -2
  32. package/src/plugins/url_analysis/js/js_urls.js +0 -9
  33. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +3 -1
  34. package/src/test/coverage/report_to_coverage.js +16 -11
  35. package/src/test/execute_plan.js +3 -2
  36. package/src/test/execute_test_plan.js +3 -1
  37. package/src/test/logs_file_execution.js +60 -27
  38. package/src/test/logs_file_execution.test.mjs +41 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "27.3.2",
3
+ "version": "27.4.0",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -43,7 +43,6 @@
43
43
  "eslint": "npx eslint . --ext=.js,.mjs,.cjs,.html",
44
44
  "dev": "node --conditions=development ./scripts/dev/dev.mjs",
45
45
  "test": "node --conditions=development ./scripts/test/test.mjs",
46
- "test:coverage": "cross-env NODE_V8_COVERAGE=.coverage/node npm run test -- --coverage",
47
46
  "test:workspace": "npm run test --workspaces --if-present -- --workspace",
48
47
  "build": "node --conditions=development ./scripts/build/build.mjs",
49
48
  "workspace:versions": "node ./scripts/publish/workspace_versions.mjs",
@@ -68,16 +67,16 @@
68
67
  "@jsenv/abort": "4.2.3",
69
68
  "@jsenv/ast": "1.1.2",
70
69
  "@jsenv/babel-plugins": "1.0.6",
71
- "@jsenv/filesystem": "4.1.0",
70
+ "@jsenv/filesystem": "4.1.1",
72
71
  "@jsenv/importmap": "1.2.1",
73
72
  "@jsenv/integrity": "0.0.1",
74
73
  "@jsenv/log": "3.1.0",
75
74
  "@jsenv/node-esm-resolution": "0.1.0",
76
75
  "@jsenv/server": "12.8.0",
77
- "@jsenv/sourcemap": "1.0.1",
76
+ "@jsenv/sourcemap": "1.0.2",
78
77
  "@jsenv/uneval": "1.6.0",
79
78
  "@jsenv/url-meta": "7.0.0",
80
- "@jsenv/urls": "1.2.6",
79
+ "@jsenv/urls": "1.2.7",
81
80
  "@jsenv/utils": "2.0.1",
82
81
  "acorn-import-assertions": "1.8.0",
83
82
  "cuid": "2.1.8",
@@ -86,6 +85,7 @@
86
85
  "istanbul-lib-instrument": "5.2.0",
87
86
  "istanbul-lib-report": "3.0.0",
88
87
  "istanbul-reports": "3.1.4",
88
+ "launch-editor": "2.4.0",
89
89
  "pidtree": "0.6.0",
90
90
  "rollup": "2.76.0",
91
91
  "string-width": "5.1.2",
@@ -103,7 +103,6 @@
103
103
  "@jsenv/https-local": "2.1.0",
104
104
  "@jsenv/package-workspace": "0.4.1",
105
105
  "@jsenv/performance-impact": "3.0.1",
106
- "cross-env": "7.0.3",
107
106
  "eslint": "8.19.0",
108
107
  "eslint-plugin-html": "6.2.0",
109
108
  "eslint-plugin-import": "2.26.0",
@@ -228,7 +228,9 @@ build ${entryPointKeys.length} entry points`)
228
228
  startLoading: (cookEntryFile) => {
229
229
  Object.keys(entryPoints).forEach((key) => {
230
230
  const [, entryUrlInfo] = cookEntryFile({
231
- trace: `"${key}" in entryPoints parameter`,
231
+ trace: {
232
+ message: `"${key}" in entryPoints parameter`,
233
+ },
232
234
  type: "entry_point",
233
235
  specifier: key,
234
236
  })
@@ -722,7 +724,7 @@ build ${entryPointKeys.length} entry points`)
722
724
  startLoading: (cookEntryFile) => {
723
725
  entryUrls.forEach((entryUrl) => {
724
726
  const [, postBuildEntryUrlInfo] = cookEntryFile({
725
- trace: `entryPoint`,
727
+ trace: { message: `entryPoint` },
726
728
  type: "entry_point",
727
729
  specifier: entryUrl,
728
730
  })
@@ -738,7 +740,7 @@ build ${entryPointKeys.length} entry points`)
738
740
 
739
741
  logger.debug(
740
742
  `graph urls pre-versioning:
741
- ${Object.keys(finalGraph.urlInfos).join("\n")}`,
743
+ ${Array.from(finalGraph.urlInfoMap.keys()).join("\n")}`,
742
744
  )
743
745
  if (versioning) {
744
746
  await applyUrlVersioning({
@@ -973,7 +975,7 @@ const applyUrlVersioning = async ({
973
975
  disabled: infoLogsAreDisabled,
974
976
  })
975
977
  try {
976
- const urlsSorted = sortByDependencies(finalGraph.urlInfos)
978
+ const urlsSorted = sortByDependencies(finalGraph.toObject())
977
979
  urlsSorted.forEach((url) => {
978
980
  if (url.startsWith("data:")) {
979
981
  return
@@ -1,20 +1,19 @@
1
1
  export const GRAPH = {
2
2
  map: (graph, callback) => {
3
- return Object.keys(graph.urlInfos).map((url) => {
4
- return callback(graph.urlInfos[url])
3
+ const array = []
4
+ graph.urlInfoMap.forEach((urlInfo) => {
5
+ array.push(callback(urlInfo))
5
6
  })
7
+ return array
6
8
  },
7
9
 
8
10
  forEach: (graph, callback) => {
9
- Object.keys(graph.urlInfos).forEach((url) => {
10
- callback(graph.urlInfos[url], url)
11
- })
11
+ graph.urlInfoMap.forEach(callback)
12
12
  },
13
13
 
14
14
  filter: (graph, callback) => {
15
15
  const urlInfos = []
16
- Object.keys(graph.urlInfos).forEach((url) => {
17
- const urlInfo = graph.urlInfos[url]
16
+ graph.urlInfoMap.forEach((urlInfo) => {
18
17
  if (callback(urlInfo)) {
19
18
  urlInfos.push(urlInfo)
20
19
  }
@@ -23,9 +22,13 @@ export const GRAPH = {
23
22
  },
24
23
 
25
24
  find: (graph, callback) => {
26
- const urlFound = Object.keys(graph.urlInfos).find((url) => {
27
- return callback(graph.urlInfos[url])
28
- })
29
- return graph.urlInfos[urlFound]
25
+ let found = null
26
+ for (const urlInfo of graph.urlInfoMap.values()) {
27
+ if (callback(urlInfo)) {
28
+ found = urlInfo
29
+ break
30
+ }
31
+ }
32
+ return found
30
33
  },
31
34
  }
@@ -1,6 +1,6 @@
1
1
  import cuid from "cuid"
2
2
  import { Abort, raceCallbacks } from "@jsenv/abort"
3
- import { writeFileSync } from "@jsenv/filesystem"
3
+ import { ensureParentDirectories } from "@jsenv/filesystem"
4
4
 
5
5
  export const run = async ({
6
6
  signal = new AbortController().signal,
@@ -16,7 +16,7 @@ export const run = async ({
16
16
  runtime,
17
17
  runtimeParams,
18
18
  }) => {
19
- let result = {}
19
+ const result = {}
20
20
  const callbacks = []
21
21
 
22
22
  const onConsoleRef = { current: () => {} }
@@ -39,17 +39,15 @@ export const run = async ({
39
39
  Abort.isAbortError(result.error) &&
40
40
  timeoutAbortSource.signal.aborted
41
41
  ) {
42
- result = {
43
- status: "timedout",
44
- }
42
+ result.status = "timedout"
43
+ delete result.error
45
44
  }
46
45
  })
47
46
  }
48
47
  callbacks.push(() => {
49
48
  if (result.status === "errored" && Abort.isAbortError(result.error)) {
50
- result = {
51
- status: "aborted",
52
- }
49
+ result.status = "aborted"
50
+ delete result.error
53
51
  }
54
52
  })
55
53
  const consoleCalls = []
@@ -71,6 +69,24 @@ export const run = async ({
71
69
  })
72
70
  }
73
71
 
72
+ // we do not keep coverage in memory, it can grow very big
73
+ // instead we store it on the filesystem
74
+ // and they can be read later at "coverageFileUrl"
75
+ let coverageFileUrl
76
+ if (coverageEnabled) {
77
+ coverageFileUrl = new URL(
78
+ `./${runtime.name}/${cuid()}.json`,
79
+ coverageTempDirectoryUrl,
80
+ ).href
81
+ await ensureParentDirectories(coverageFileUrl)
82
+ if (coverageEnabled) {
83
+ result.coverageFileUrl = coverageFileUrl
84
+ // written within the child_process/worker_thread or during runtime.run()
85
+ // for browsers
86
+ // (because it takes time to serialize and transfer the coverage object)
87
+ }
88
+ }
89
+
74
90
  const startMs = Date.now()
75
91
  callbacks.push(() => {
76
92
  result.duration = Date.now() - startMs
@@ -94,7 +110,9 @@ export const run = async ({
94
110
  signal: runOperation.signal,
95
111
  logger,
96
112
  ...runtimeParams,
113
+ collectConsole,
97
114
  collectPerformance,
115
+ coverageFileUrl,
98
116
  keepRunning,
99
117
  stopSignal,
100
118
  onConsole: (log) => onConsoleRef.current(log),
@@ -116,7 +134,7 @@ export const run = async ({
116
134
  runOperation.throwIfAborted()
117
135
  }
118
136
 
119
- const { status, namespace, error, performance, coverage } = winner.data
137
+ const { status, namespace, error, performance } = winner.data
120
138
  result.status = status
121
139
  if (status === "errored") {
122
140
  result.error = error
@@ -126,30 +144,13 @@ export const run = async ({
126
144
  if (collectPerformance) {
127
145
  result.performance = performance
128
146
  }
129
- if (coverageEnabled) {
130
- if (coverage) {
131
- // we do not keep coverage in memory, it can grow very big
132
- // instead we store it on the filesystem
133
- // and they can be read later at "coverageFileUrl"
134
- const coverageFileUrl = new URL(
135
- `./${runtime.name}/${cuid()}.json`,
136
- coverageTempDirectoryUrl,
137
- )
138
- writeFileSync(coverageFileUrl, JSON.stringify(coverage, null, " "))
139
- result.coverageFileUrl = coverageFileUrl.href
140
- } else {
141
- // will eventually log a warning in report_to_coverage.js
142
- }
143
- }
144
147
  callbacks.forEach((callback) => {
145
148
  callback()
146
149
  })
147
150
  return result
148
151
  } catch (e) {
149
- result = {
150
- status: "errored",
151
- error: e,
152
- }
152
+ result.status = "errored"
153
+ result.error = e
153
154
  callbacks.forEach((callback) => {
154
155
  callback()
155
156
  })
@@ -1,4 +1,5 @@
1
1
  import { Script } from "node:vm"
2
+ import { writeFileSync } from "node:fs"
2
3
 
3
4
  import { createDetailedMessage } from "@jsenv/log"
4
5
  import {
@@ -41,6 +42,7 @@ export const createRuntimeFromPlaywright = ({
41
42
  coverageEnabled = false,
42
43
  coverageConfig,
43
44
  coverageMethodForBrowsers,
45
+ coverageFileUrl,
44
46
 
45
47
  stopAfterAllSignal,
46
48
  stopSignal,
@@ -108,7 +110,8 @@ export const createRuntimeFromPlaywright = ({
108
110
  }
109
111
  }
110
112
 
111
- let resultTransformer = (result) => result
113
+ const result = {}
114
+ const callbacks = []
112
115
  if (coverageEnabled) {
113
116
  if (
114
117
  coveragePlaywrightAPIAvailable &&
@@ -117,93 +120,86 @@ export const createRuntimeFromPlaywright = ({
117
120
  await page.coverage.startJSCoverage({
118
121
  // reportAnonymousScripts: true,
119
122
  })
120
- resultTransformer = composeTransformer(
121
- resultTransformer,
122
- async (result) => {
123
- const v8CoveragesWithWebUrls = await page.coverage.stopJSCoverage()
124
- // we convert urls starting with http:// to file:// because we later
125
- // convert the url to filesystem path in istanbulCoverageFromV8Coverage function
126
- const v8CoveragesWithFsUrls = v8CoveragesWithWebUrls.map(
127
- (v8CoveragesWithWebUrl) => {
128
- const fsUrl = moveUrl({
129
- url: v8CoveragesWithWebUrl.url,
130
- from: `${server.origin}/`,
131
- to: rootDirectoryUrl,
132
- preferAbsolute: true,
133
- })
134
- return {
135
- ...v8CoveragesWithWebUrl,
136
- url: fsUrl,
137
- }
138
- },
139
- )
140
- const coverage = await filterV8Coverage(
141
- { result: v8CoveragesWithFsUrls },
142
- {
143
- rootDirectoryUrl,
144
- coverageConfig,
145
- },
146
- )
147
- return {
148
- ...result,
149
- coverage,
150
- }
151
- },
152
- )
123
+ callbacks.push(async () => {
124
+ const v8CoveragesWithWebUrls = await page.coverage.stopJSCoverage()
125
+ // we convert urls starting with http:// to file:// because we later
126
+ // convert the url to filesystem path in istanbulCoverageFromV8Coverage function
127
+ const v8CoveragesWithFsUrls = v8CoveragesWithWebUrls.map(
128
+ (v8CoveragesWithWebUrl) => {
129
+ const fsUrl = moveUrl({
130
+ url: v8CoveragesWithWebUrl.url,
131
+ from: `${server.origin}/`,
132
+ to: rootDirectoryUrl,
133
+ preferAbsolute: true,
134
+ })
135
+ return {
136
+ ...v8CoveragesWithWebUrl,
137
+ url: fsUrl,
138
+ }
139
+ },
140
+ )
141
+ const coverage = await filterV8Coverage(
142
+ { result: v8CoveragesWithFsUrls },
143
+ {
144
+ rootDirectoryUrl,
145
+ coverageConfig,
146
+ },
147
+ )
148
+ writeFileSync(
149
+ new URL(coverageFileUrl),
150
+ JSON.stringify(coverage, null, " "),
151
+ )
152
+ })
153
153
  } else {
154
- resultTransformer = composeTransformer(
155
- resultTransformer,
156
- async (result) => {
157
- const scriptExecutionResults = result.namespace
158
- if (scriptExecutionResults) {
159
- result.coverage = generateCoverageForPage(scriptExecutionResults)
160
- }
161
- return result
162
- },
163
- )
154
+ callbacks.push(() => {
155
+ const scriptExecutionResults = result.namespace
156
+ if (scriptExecutionResults) {
157
+ const coverage =
158
+ generateCoverageForPage(scriptExecutionResults) || {}
159
+ writeFileSync(
160
+ new URL(coverageFileUrl),
161
+ JSON.stringify(coverage, null, " "),
162
+ )
163
+ }
164
+ })
164
165
  }
165
166
  } else {
166
- resultTransformer = composeTransformer(resultTransformer, (result) => {
167
+ callbacks.push(() => {
167
168
  const scriptExecutionResults = result.namespace
168
169
  if (scriptExecutionResults) {
169
170
  Object.keys(scriptExecutionResults).forEach((fileRelativeUrl) => {
170
171
  delete scriptExecutionResults[fileRelativeUrl].coverage
171
172
  })
172
173
  }
173
- return result
174
174
  })
175
175
  }
176
176
 
177
177
  if (collectPerformance) {
178
- resultTransformer = composeTransformer(
179
- resultTransformer,
180
- async (result) => {
181
- const performance = await page.evaluate(
182
- /* eslint-disable no-undef */
183
- /* istanbul ignore next */
184
- () => {
185
- const { performance } = window
186
- if (!performance) {
187
- return null
188
- }
189
- const measures = {}
190
- const measurePerfEntries = performance.getEntriesByType("measure")
191
- measurePerfEntries.forEach((measurePerfEntry) => {
192
- measures[measurePerfEntry.name] = measurePerfEntry.duration
193
- })
194
- return {
195
- timeOrigin: performance.timeOrigin,
196
- timing: performance.timing.toJSON(),
197
- navigation: performance.navigation.toJSON(),
198
- measures,
199
- }
200
- },
201
- /* eslint-enable no-undef */
202
- )
203
- result.performance = performance
204
- return result
205
- },
206
- )
178
+ callbacks.push(async () => {
179
+ const performance = await page.evaluate(
180
+ /* eslint-disable no-undef */
181
+ /* istanbul ignore next */
182
+ () => {
183
+ const { performance } = window
184
+ if (!performance) {
185
+ return null
186
+ }
187
+ const measures = {}
188
+ const measurePerfEntries = performance.getEntriesByType("measure")
189
+ measurePerfEntries.forEach((measurePerfEntry) => {
190
+ measures[measurePerfEntry.name] = measurePerfEntry.duration
191
+ })
192
+ return {
193
+ timeOrigin: performance.timeOrigin,
194
+ timing: performance.timing.toJSON(),
195
+ navigation: performance.navigation.toJSON(),
196
+ measures,
197
+ }
198
+ },
199
+ /* eslint-enable no-undef */
200
+ )
201
+ result.performance = performance
202
+ })
207
203
  }
208
204
 
209
205
  const fileClientUrl = new URL(fileRelativeUrl, `${server.origin}/`).href
@@ -290,7 +286,7 @@ export const createRuntimeFromPlaywright = ({
290
286
  response: async (cb) => {
291
287
  try {
292
288
  await page.goto(fileClientUrl, { timeout: 0 })
293
- const result = await page.evaluate(
289
+ const returnValue = await page.evaluate(
294
290
  /* eslint-disable no-undef */
295
291
  /* istanbul ignore next */
296
292
  () => {
@@ -301,9 +297,9 @@ export const createRuntimeFromPlaywright = ({
301
297
  },
302
298
  /* eslint-enable no-undef */
303
299
  )
304
- const { status, scriptExecutionResults } = result
300
+ const { status, scriptExecutionResults } = returnValue
305
301
  if (status === "errored") {
306
- const { exceptionSource } = result
302
+ const { exceptionSource } = returnValue
307
303
  const error = evalException(exceptionSource, {
308
304
  rootDirectoryUrl,
309
305
  server,
@@ -353,16 +349,25 @@ export const createRuntimeFromPlaywright = ({
353
349
  }
354
350
  return winner.data
355
351
  }
356
- let result
357
352
 
358
353
  try {
359
- result = await getResult()
360
- result = await resultTransformer(result)
361
- } catch (e) {
362
- result = {
363
- status: "errored",
364
- error: e,
354
+ const { status, error, namespace, performance } = await getResult()
355
+ result.status = status
356
+ if (status === "errored") {
357
+ result.error = error
358
+ } else {
359
+ result.namespace = namespace
365
360
  }
361
+ if (collectPerformance) {
362
+ result.performance = performance
363
+ }
364
+ await callbacks.reduce(async (previous, callback) => {
365
+ await previous
366
+ await callback()
367
+ }, Promise.resolve())
368
+ } catch (e) {
369
+ result.status = "errored"
370
+ result.error = e
366
371
  }
367
372
  if (keepRunning) {
368
373
  stopSignal.notify = cleanup
@@ -478,13 +483,6 @@ const isTargetClosedError = (error) => {
478
483
  return false
479
484
  }
480
485
 
481
- const composeTransformer = (previousTransformer, transformer) => {
482
- return async (value) => {
483
- const transformedValue = await previousTransformer(value)
484
- return transformer(transformedValue)
485
- }
486
- }
487
-
488
486
  const extractTextFromConsoleMessage = (consoleMessage) => {
489
487
  return consoleMessage.text()
490
488
  // ensure we use a string so that istanbul won't try
@@ -1,3 +1,5 @@
1
+ import { writeFileSync } from "node:fs"
2
+
1
3
  import { startJsCoverage } from "./profiler_v8_coverage.js"
2
4
  import { startObservingPerformances } from "./node_execution_performance.js"
3
5
 
@@ -8,8 +10,9 @@ export const executeUsingDynamicImport = async ({
8
10
  coverageEnabled,
9
11
  coverageConfig,
10
12
  coverageMethodForNodeJs,
13
+ coverageFileUrl,
11
14
  }) => {
12
- let result = {}
15
+ const result = {}
13
16
  const afterImportCallbacks = []
14
17
  if (coverageEnabled && coverageMethodForNodeJs === "Profiler") {
15
18
  const { filterV8Coverage } = await import(
@@ -22,7 +25,10 @@ export const executeUsingDynamicImport = async ({
22
25
  rootDirectoryUrl,
23
26
  coverageConfig,
24
27
  })
25
- result.coverage = coverageLight
28
+ writeFileSync(
29
+ new URL(coverageFileUrl),
30
+ JSON.stringify(coverageLight, null, " "),
31
+ )
26
32
  })
27
33
  }
28
34
  if (collectPerformance) {
@@ -39,6 +39,7 @@ nodeChildProcess.run = async ({
39
39
  coverageEnabled = false,
40
40
  coverageConfig,
41
41
  coverageMethodForNodeJs,
42
+ coverageFileUrl,
42
43
  collectPerformance,
43
44
 
44
45
  env,
@@ -199,6 +200,7 @@ nodeChildProcess.run = async ({
199
200
  coverageEnabled,
200
201
  coverageConfig,
201
202
  coverageMethodForNodeJs,
203
+ coverageFileUrl,
202
204
  exitAfterAction: true,
203
205
  },
204
206
  },
@@ -35,10 +35,12 @@ nodeWorkerThread.run = async ({
35
35
  stopSignal,
36
36
  onConsole,
37
37
 
38
+ collectConsole = false,
39
+ collectPerformance,
40
+ coverageEnabled = false,
38
41
  coverageConfig,
39
42
  coverageMethodForNodeJs,
40
- coverageEnabled = false,
41
- collectPerformance,
43
+ coverageFileUrl,
42
44
 
43
45
  env,
44
46
  debugPort,
@@ -104,10 +106,12 @@ nodeWorkerThread.run = async ({
104
106
  const stop = memoize(async () => {
105
107
  // read all stdout before terminating
106
108
  // (no need for stderr because it's sync)
107
- while (workerThread.stdout.read() !== null) {}
108
- await new Promise((resolve) => {
109
- setTimeout(resolve)
110
- })
109
+ if (collectConsole) {
110
+ while (workerThread.stdout.read() !== null) {}
111
+ await new Promise((resolve) => {
112
+ setTimeout(resolve, 50)
113
+ })
114
+ }
111
115
  await workerThread.terminate()
112
116
  })
113
117
 
@@ -148,6 +152,7 @@ nodeWorkerThread.run = async ({
148
152
  coverageEnabled,
149
153
  coverageConfig,
150
154
  coverageMethodForNodeJs,
155
+ coverageFileUrl,
151
156
  exitAfterAction: true,
152
157
  },
153
158
  },