@jsenv/core 24.2.2 → 24.3.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.
Files changed (150) hide show
  1. package/{license → LICENSE} +0 -0
  2. package/dist/browser_runtime/browser_runtime-fbd309a1.js +5137 -0
  3. package/dist/browser_runtime/browser_runtime-fbd309a1.js.map +1064 -0
  4. package/dist/{jsenv_browser_system.js → browser_system/browser_system-29eda202.js} +12 -12
  5. package/dist/{jsenv_browser_system.js.map → browser_system/browser_system-29eda202.js.map} +64 -64
  6. package/dist/build_manifest.js +12 -0
  7. package/dist/compile_proxy/assets/s.js-749702e8.map +242 -0
  8. package/dist/compile_proxy/compile_proxy-405777e6.html +2074 -0
  9. package/dist/compile_proxy/compile_proxy.html__inline__20-39c0801c.js.map +385 -0
  10. package/dist/{jsenv_event_source_client.js → event_source_client/event_source_client-9f14c8b9.js} +39 -21
  11. package/dist/event_source_client/event_source_client-9f14c8b9.js.map +127 -0
  12. package/dist/redirector/assets/s.js-749702e8.map +242 -0
  13. package/dist/redirector/redirector-237cd168.html +2118 -0
  14. package/dist/redirector/redirector.html__inline__15-33acb0b9.js.map +390 -0
  15. package/dist/toolbar/assets/compilation.css-209d68b4.map +12 -0
  16. package/dist/toolbar/assets/eventsource.css-38cd0a36.map +12 -0
  17. package/dist/toolbar/assets/execution.css-0ebe522f.map +12 -0
  18. package/dist/toolbar/assets/focus.css-3f9c156d.map +12 -0
  19. package/dist/toolbar/assets/light-theme.css-78b19a80.map +12 -0
  20. package/dist/toolbar/assets/overflow-menu.css-d9688a1c.map +12 -0
  21. package/dist/toolbar/assets/s.js-749702e8.map +242 -0
  22. package/dist/toolbar/assets/settings.css-2b81b245.map +12 -0
  23. package/dist/toolbar/assets/toolbar.main.css-846920e9.map +28 -0
  24. package/dist/toolbar/assets/tooltip.css-03395ee6.map +12 -0
  25. package/dist/toolbar/toolbar-d3d98c2e.html +4778 -0
  26. package/dist/toolbar/toolbar.main-cab36c15.js.map +795 -0
  27. package/dist/toolbar_injector/assets/jsenv-logo-188b9ca6.svg +95 -0
  28. package/dist/{jsenv_toolbar_injector.js → toolbar_injector/toolbar_injector-01f71ce3.js} +85 -65
  29. package/dist/toolbar_injector/toolbar_injector-01f71ce3.js.map +294 -0
  30. package/main.js +0 -1
  31. package/package.json +4 -2
  32. package/readme.md +10 -7
  33. package/src/buildProject.js +6 -2
  34. package/src/dev_server.js +22 -130
  35. package/src/importUsingChildProcess.js +1 -1
  36. package/src/internal/{runtime/detectBrowser/detectBrowser.js → browser_detection/browser_detection.js} +0 -0
  37. package/src/internal/{runtime/detectBrowser → browser_detection}/detectAndroid.js +0 -0
  38. package/src/internal/{runtime/detectBrowser → browser_detection}/detectChrome.js +0 -0
  39. package/src/internal/{runtime/detectBrowser → browser_detection}/detectEdge.js +0 -0
  40. package/src/internal/{runtime/detectBrowser → browser_detection}/detectElectron.js +0 -0
  41. package/src/internal/{runtime/detectBrowser → browser_detection}/detectFirefox.js +0 -0
  42. package/src/internal/{runtime/detectBrowser → browser_detection}/detectIOS.js +0 -0
  43. package/src/internal/{runtime/detectBrowser → browser_detection}/detectInternetExplorer.js +0 -0
  44. package/src/internal/{runtime/detectBrowser → browser_detection}/detectOpera.js +0 -0
  45. package/src/internal/{runtime/detectBrowser → browser_detection}/detectSafari.js +0 -0
  46. package/src/internal/{runtime/detectBrowser → browser_detection}/util.js +0 -0
  47. package/src/internal/{runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js → browser_feature_detection/browser_feature_detection.js} +116 -81
  48. package/src/internal/browser_feature_detection/compile_proxy.html +27 -0
  49. package/src/internal/{browser-launcher → browser_launcher}/createSharing.js +0 -0
  50. package/src/internal/{browser-launcher → browser_launcher}/executeHtmlFile.js +7 -4
  51. package/src/internal/{browser-launcher → browser_launcher}/trackPageToNotify.js +0 -0
  52. package/src/internal/{browser-launcher/jsenv-browser-system.js → browser_runtime/browser_runtime.js} +4 -4
  53. package/src/internal/{runtime/createBrowserRuntime/createBrowserSystem.js → browser_runtime/browser_system.js} +3 -2
  54. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/createBrowserRuntime.js +7 -5
  55. package/src/internal/{browser-launcher → browser_runtime}/displayErrorInDocument.js +0 -0
  56. package/src/internal/{browser-launcher → browser_runtime}/displayErrorNotification.js +2 -4
  57. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/evalSource.js +2 -0
  58. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/makeNamespaceTransferable.js +0 -0
  59. package/src/internal/{browser-utils → browser_utils}/fetch-browser.js +2 -0
  60. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingFetch.js +3 -0
  61. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingScript.js +2 -0
  62. package/src/internal/{browser-utils → browser_utils}/fetchJson.js +0 -0
  63. package/src/internal/{browser-utils → browser_utils}/fetchUsingXHR.js +4 -4
  64. package/src/internal/building/buildUsingRollup.js +4 -0
  65. package/src/internal/building/createJsenvRollupPlugin.js +19 -9
  66. package/src/internal/building/css/applyPostCss.js +19 -8
  67. package/src/internal/building/css/moveCssUrls.js +44 -0
  68. package/src/internal/building/css/parseCssRessource.js +67 -17
  69. package/src/internal/building/css/parseCssUrls.js +29 -23
  70. package/src/internal/building/css/postcss_plugin_url_visitor.js +11 -20
  71. package/src/internal/building/css/replaceCssUrls.js +38 -19
  72. package/src/internal/building/css_module.js +6 -10
  73. package/src/internal/building/html/parseHtmlRessource.js +37 -11
  74. package/src/internal/building/parseRessource.js +3 -0
  75. package/src/internal/building/ressource_builder.js +12 -3
  76. package/src/internal/compiling/babel_plugin_import_assertions.js +1 -2
  77. package/src/internal/compiling/html_source_file_service.js +23 -21
  78. package/src/internal/compiling/jsenvCompilerForHtml.js +15 -22
  79. package/src/internal/compiling/startCompileServer.js +34 -32
  80. package/src/internal/dev_server/event_source_client/event_source_connection.js +28 -19
  81. package/src/internal/dev_server/exploring/exploring.html +7 -2
  82. package/src/internal/dev_server/exploring/fetchExploringJson.js +4 -9
  83. package/src/internal/dev_server/redirector/redirector.html +37 -2
  84. package/src/internal/dev_server/toolbar/compilation/toolbar.compilation.js +4 -7
  85. package/src/internal/dev_server/toolbar/eventsource/toolbar.eventsource.js +2 -2
  86. package/src/internal/dev_server/toolbar/notification/toolbar.notification.js +75 -44
  87. package/src/internal/dev_server/toolbar/toolbar.html +31 -5
  88. package/src/internal/dev_server/toolbar/toolbar.injector.js +53 -36
  89. package/src/internal/dev_server/toolbar/toolbar.main.js +44 -31
  90. package/src/internal/dev_server/toolbar/util/fetching.js +1 -1
  91. package/src/internal/generateGroupMap/one_runtime_compat.js +1 -1
  92. package/src/internal/generateGroupMap/runtime_compat_composition.js +1 -1
  93. package/src/internal/generateGroupMap/runtime_support.js +1 -1
  94. package/src/internal/jsenvInternalFiles.js +0 -26
  95. package/src/internal/jsenv_builds.js +19 -0
  96. package/src/internal/{runtime/node-feature-detect/feature-detect-dynamic-import.mjs → node_feature_detection/feature_detect_dynamic_import.mjs} +0 -0
  97. package/src/internal/{runtime/node-feature-detect/feature-detect-top-level-await.mjs → node_feature_detection/feature_detect_top_level_await.mjs} +0 -0
  98. package/src/internal/{runtime/node-feature-detect → node_feature_detection}/nodeSupportsDynamicImport.js +0 -0
  99. package/src/internal/node_feature_detection/nodeSupportsTopLevelAwait.js +16 -0
  100. package/src/internal/{runtime/createNodeRuntime/scanNodeRuntimeFeatures.js → node_feature_detection/node_feature_detection.js} +12 -13
  101. package/src/internal/{node-launcher → node_launcher}/createChildProcessOptions.js +0 -0
  102. package/src/internal/{node-launcher → node_launcher}/createControllableNodeProcess.js +9 -14
  103. package/src/internal/{node-launcher → node_launcher}/kill_process_tree.js +0 -0
  104. package/src/internal/{node-launcher → node_launcher}/processOptions.js +0 -0
  105. package/src/internal/{runtime/detectNode → node_runtime}/detectNode.js +0 -0
  106. package/src/internal/{runtime/createNodeRuntime → node_runtime}/evalSource.js +1 -1
  107. package/src/internal/{runtime/createNodeRuntime → node_runtime}/fetchSource.js +1 -1
  108. package/src/internal/{node-launcher → node_runtime}/nodeControllableFile.mjs +14 -11
  109. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithDynamicImport.js → node_runtime/node_execution_dynamic_import.js} +34 -6
  110. package/src/internal/node_runtime/node_execution_performance.js +67 -0
  111. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithSystemJs.js → node_runtime/node_execution_systemjs.js} +38 -24
  112. package/src/internal/{runtime/createNodeRuntime/createNodeSystem.js → node_runtime/node_system.js} +4 -4
  113. package/src/internal/runtime/computeCompileIdFromGroupId.js +1 -0
  114. package/src/internal/runtime/resolveGroup.js +1 -1
  115. package/src/internal/runtime/resolveRuntimeGroup.js +2 -2
  116. package/src/internal/{semantic-versioning → semantic_versioning}/findHighestVersion.js +0 -0
  117. package/src/internal/{semantic-versioning → semantic_versioning}/findLowestVersion.js +0 -0
  118. package/src/internal/{semantic-versioning → semantic_versioning}/index.js +0 -0
  119. package/src/internal/{semantic-versioning → semantic_versioning}/valueToVersion.js +0 -0
  120. package/src/internal/{semantic-versioning → semantic_versioning}/versionCompare.js +0 -0
  121. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsAbove.js +0 -0
  122. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsBelow.js +0 -0
  123. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsEqual.js +0 -0
  124. package/src/launchBrowser.js +3 -3
  125. package/src/launchNode.js +33 -7
  126. package/src/requireUsingChildProcess.js +1 -1
  127. package/dist/jsenv_compile_proxy.js +0 -1339
  128. package/dist/jsenv_compile_proxy.js.map +0 -378
  129. package/dist/jsenv_event_source_client.js.map +0 -126
  130. package/dist/jsenv_exploring_index.js +0 -1092
  131. package/dist/jsenv_exploring_index.js.map +0 -353
  132. package/dist/jsenv_exploring_redirector.js +0 -1386
  133. package/dist/jsenv_exploring_redirector.js.map +0 -384
  134. package/dist/jsenv_redirector.js +0 -1388
  135. package/dist/jsenv_redirector.js.map +0 -384
  136. package/dist/jsenv_toolbar.js +0 -2880
  137. package/dist/jsenv_toolbar.js.map +0 -771
  138. package/dist/jsenv_toolbar_injector.js.map +0 -301
  139. package/src/internal/browser-launcher/jsenv_compile_proxy.html +0 -13
  140. package/src/internal/browser-launcher/jsenv_compile_proxy.js +0 -5
  141. package/src/internal/dev_server/event_source_client/event_source_client_file_info.js +0 -17
  142. package/src/internal/dev_server/exploring/exploring_file_info.js +0 -21
  143. package/src/internal/dev_server/redirector/redirector.js +0 -30
  144. package/src/internal/dev_server/redirector/redirector_file_info.js +0 -24
  145. package/src/internal/dev_server/toolbar/backtolist/toolbar.backtolist.js +0 -33
  146. package/src/internal/dev_server/toolbar/toolbar_file_info.js +0 -37
  147. package/src/internal/node-launcher/node-js-file.js +0 -110
  148. package/src/internal/runtime/createNodeRuntime/createNodeRuntime.js +0 -32
  149. package/src/internal/runtime/node-feature-detect/nodeSupportsTopLevelAwait.js +0 -18
  150. package/src/nodeRuntime.js +0 -5
@@ -1,13 +1,14 @@
1
- import { detectNode } from "../detectNode/detectNode.js"
2
- import { resolveGroup } from "../resolveGroup.js"
3
- import { computeCompileIdFromGroupId } from "../computeCompileIdFromGroupId.js"
4
- import { nodeSupportsDynamicImport } from "../node-feature-detect/nodeSupportsDynamicImport.js"
5
- import { nodeSupportsTopLevelAwait } from "../node-feature-detect/nodeSupportsTopLevelAwait.js"
6
- import { fetchSource } from "./fetchSource.js"
1
+ import { resolveGroup } from "@jsenv/core/src/internal/runtime/resolveGroup.js"
2
+ import { detectNode } from "@jsenv/core/src/internal/node_runtime/detectNode.js"
3
+ import { computeCompileIdFromGroupId } from "@jsenv/core/src/internal/runtime/computeCompileIdFromGroupId.js"
4
+ import { nodeSupportsDynamicImport } from "@jsenv/core/src/internal/node_feature_detection/nodeSupportsDynamicImport.js"
5
+ import { nodeSupportsTopLevelAwait } from "@jsenv/core/src/internal/node_feature_detection/nodeSupportsTopLevelAwait.js"
6
+ import { fetchSource } from "@jsenv/core/src/internal/node_runtime/fetchSource.js"
7
7
 
8
8
  export const scanNodeRuntimeFeatures = async ({
9
9
  compileServerOrigin,
10
10
  outDirectoryRelativeUrl,
11
+ coverageHandledFromOutside = false,
11
12
  }) => {
12
13
  const outDirectoryServerUrl = `${compileServerOrigin}/${outDirectoryRelativeUrl}`
13
14
  const {
@@ -35,10 +36,7 @@ export const scanNodeRuntimeFeatures = async ({
35
36
  })
36
37
  const pluginRequiredNameArray = pluginRequiredNamesFromGroupInfo(groupInfo, {
37
38
  featuresReport,
38
- // https://nodejs.org/docs/latest-v15.x/api/cli.html#cli_node_v8_coverage_dir
39
- // instrumentation CAN be handed by process.env.NODE_V8_COVERAGE
40
- // "transform-instrument" becomes non mandatory
41
- coverageHandledFromOutside: process.env.NODE_V8_COVERAGE,
39
+ coverageHandledFromOutside,
42
40
  })
43
41
 
44
42
  const canAvoidCompilation =
@@ -102,9 +100,10 @@ const pluginRequiredNamesFromGroupInfo = (
102
100
  if (coverageHandledFromOutside) {
103
101
  markPluginAsSupported("transform-instrument")
104
102
  }
105
- // We assume import assertions and constructable stylesheet won't be used
106
- // in code executed in Node.js
107
- // so event they are conceptually required, they are ignored
103
+ // CSS import assertions and constructable stylesheet are not supported by Node.js
104
+ // but we assume they are not used for code executed in Node.js
105
+ // Without this check code executed on Node.js would always be compiled
106
+ // because import assertions and constructable stylesheet are enabled by default
108
107
  markPluginAsSupported("transform-import-assertions")
109
108
  markPluginAsSupported("new-stylesheet-as-jsenv-import")
110
109
 
@@ -1,11 +1,7 @@
1
1
  import { fork } from "node:child_process"
2
2
  import { uneval } from "@jsenv/uneval"
3
3
  import { createLogger, createDetailedMessage } from "@jsenv/logger"
4
- import {
5
- urlToFileSystemPath,
6
- resolveUrl,
7
- assertFilePresence,
8
- } from "@jsenv/filesystem"
4
+ import { urlToFileSystemPath, assertFilePresence } from "@jsenv/filesystem"
9
5
  import {
10
6
  Abort,
11
7
  raceCallbacks,
@@ -13,8 +9,7 @@ import {
13
9
  createCallbackListNotifiedOnce,
14
10
  } from "@jsenv/abort"
15
11
 
16
- import { nodeSupportsDynamicImport } from "../runtime/node-feature-detect/nodeSupportsDynamicImport.js"
17
- import { jsenvCoreDirectoryUrl } from "../jsenvCoreDirectoryUrl.js"
12
+ import { nodeSupportsDynamicImport } from "../node_feature_detection/nodeSupportsDynamicImport.js"
18
13
  import { createChildProcessOptions } from "./createChildProcessOptions.js"
19
14
  import {
20
15
  processOptionsFromExecArgv,
@@ -22,10 +17,10 @@ import {
22
17
  } from "./processOptions.js"
23
18
  import { killProcessTree } from "./kill_process_tree.js"
24
19
 
25
- const nodeControllableFileUrl = resolveUrl(
26
- "./src/internal/node-launcher/nodeControllableFile.mjs",
27
- jsenvCoreDirectoryUrl,
28
- )
20
+ const NODE_CONTROLLABLE_FILE_URL = new URL(
21
+ "../node_runtime/nodeControllableFile.mjs",
22
+ import.meta.url,
23
+ ).href
29
24
 
30
25
  // https://nodejs.org/api/process.html#process_signal_events
31
26
  const SIGINT_SIGNAL_NUMBER = 2
@@ -79,12 +74,12 @@ export const createControllableNodeProcess = async ({
79
74
  throw new TypeError(`env must be an object, got ${env}`)
80
75
  }
81
76
 
82
- await assertFilePresence(nodeControllableFileUrl)
77
+ await assertFilePresence(NODE_CONTROLLABLE_FILE_URL)
83
78
  const envForChildProcess = {
84
79
  ...(inheritProcessEnv ? process.env : {}),
85
80
  ...env,
86
81
  }
87
- const childProcess = fork(urlToFileSystemPath(nodeControllableFileUrl), {
82
+ const childProcess = fork(urlToFileSystemPath(NODE_CONTROLLABLE_FILE_URL), {
88
83
  execArgv,
89
84
  // silent: true
90
85
  stdio: ["pipe", "pipe", "pipe", "ipc"],
@@ -111,7 +106,7 @@ export const createControllableNodeProcess = async ({
111
106
  if (logProcessCommand) {
112
107
  console.log(
113
108
  `${process.argv[0]} ${execArgv.join(" ")} ${urlToFileSystemPath(
114
- nodeControllableFileUrl,
109
+ NODE_CONTROLLABLE_FILE_URL,
115
110
  )}`,
116
111
  )
117
112
  }
@@ -1,4 +1,4 @@
1
- import { Script } from "vm"
1
+ import { Script } from "node:vm"
2
2
 
3
3
  export const evalSource = (code, filePath) => {
4
4
  const script = new Script(code, { filename: filePath })
@@ -1,4 +1,4 @@
1
- import { fetchUrl } from "../../fetchUrl.js"
1
+ import { fetchUrl } from "../fetchUrl.js"
2
2
 
3
3
  export const fetchSource = (url, { executionId } = {}) => {
4
4
  return fetchUrl(url, {
@@ -1,19 +1,26 @@
1
1
  import v8 from "node:v8"
2
2
  import { uneval } from "@jsenv/uneval"
3
3
 
4
- import { jsenvNodeSystemFileInfo } from "@jsenv/core/src/internal/jsenvInternalFiles.js"
4
+ const NODE_EXECUTION_DYNAMIC_IMPORT_URL = new URL(
5
+ "./node_execution_dynamic_import.js",
6
+ import.meta.url,
7
+ ).href
8
+ const NODE_EXECUTION_SYSTEMJS_URL = new URL(
9
+ "./node_execution_systemjs.js",
10
+ import.meta.url,
11
+ ).href
5
12
 
6
13
  const ACTIONS_AVAILABLE = {
7
- "execute-using-dynamic-import-fallback-on-systemjs": async (
8
- executeParams,
9
- ) => {
10
- const { execute } = await import(jsenvNodeSystemFileInfo.url)
11
-
14
+ "execute-using-dynamic-import": async (executeParams) => {
15
+ const { execute } = await import(NODE_EXECUTION_DYNAMIC_IMPORT_URL)
16
+ return execute(executeParams)
17
+ },
18
+ "execute-using-systemjs": async (executeParams) => {
19
+ const { execute } = await import(NODE_EXECUTION_SYSTEMJS_URL)
12
20
  return execute(executeParams)
13
21
  },
14
22
  "execute-using-import": async ({ fileUrl }) => {
15
23
  const namespace = await import(fileUrl)
16
-
17
24
  const namespaceResolved = {}
18
25
  await Promise.all([
19
26
  ...Object.keys(namespace).map(async (key) => {
@@ -21,19 +28,15 @@ const ACTIONS_AVAILABLE = {
21
28
  namespaceResolved[key] = value
22
29
  }),
23
30
  ])
24
-
25
31
  return namespaceResolved
26
32
  },
27
33
  "execute-using-require": async ({ fileUrl }) => {
28
34
  const { createRequire } = await import("module")
29
35
  const { fileURLToPath } = await import("url")
30
-
31
36
  const filePath = fileURLToPath(fileUrl)
32
37
  const require = createRequire(fileUrl)
33
-
34
38
  // eslint-disable-next-line import/no-dynamic-require
35
39
  const namespace = require(filePath)
36
-
37
40
  const namespaceResolved = {}
38
41
  await Promise.all([
39
42
  ...Object.keys(namespace).map(async (key) => {
@@ -2,10 +2,33 @@ import { resolveUrl } from "@jsenv/filesystem"
2
2
 
3
3
  import { unevalException } from "@jsenv/core/src/internal/unevalException.js"
4
4
  import { measureAsyncFnPerf } from "@jsenv/core/src/internal/perf_node.js"
5
+ import { startObservingPerformances } from "./node_execution_performance.js"
5
6
 
6
- export const createNodeExecutionWithDynamicImport = ({
7
+ export const execute = async ({
7
8
  projectDirectoryUrl,
9
+ fileRelativeUrl,
10
+ // do not log in the console
11
+ // because error handling becomes responsability
12
+ // of node code launching node process
13
+ // it avoids seeing error in runtime logs during testing
14
+ errorExposureInConsole = false,
15
+ collectCoverage,
16
+ measurePerformance,
17
+ collectPerformance,
8
18
  }) => {
19
+ let finalizeExecutionResult = (result) => result
20
+
21
+ if (collectPerformance) {
22
+ const getPerformance = startObservingPerformances()
23
+ finalizeExecutionResult = async (executionResult) => {
24
+ const performance = await getPerformance()
25
+ return {
26
+ ...executionResult,
27
+ performance,
28
+ }
29
+ }
30
+ }
31
+
9
32
  const executeFile = async (
10
33
  specifier,
11
34
  { measurePerformance, errorExposureInConsole = false } = {},
@@ -13,7 +36,6 @@ export const createNodeExecutionWithDynamicImport = ({
13
36
  // we can't dynamically import from compileServerOrigin I guess
14
37
  // we have to use the filesystem
15
38
  const fileUrl = resolveUrl(specifier, projectDirectoryUrl)
16
-
17
39
  const importWithDynamicImport = async () => {
18
40
  try {
19
41
  const status = "completed"
@@ -33,14 +55,20 @@ export const createNodeExecutionWithDynamicImport = ({
33
55
  }
34
56
  }
35
57
  }
36
-
37
58
  if (measurePerformance) {
38
59
  return measureAsyncFnPerf(importWithDynamicImport, "jsenv_file_import")
39
60
  }
40
61
  return importWithDynamicImport()
41
62
  }
42
63
 
43
- return {
44
- executeFile,
45
- }
64
+ const executionResult = await executeFile(fileRelativeUrl, {
65
+ errorExposureInConsole,
66
+ measurePerformance,
67
+ collectCoverage,
68
+ })
69
+
70
+ return finalizeExecutionResult({
71
+ ...executionResult,
72
+ indirectCoverage: global.__indirectCoverage__,
73
+ })
46
74
  }
@@ -0,0 +1,67 @@
1
+ import { PerformanceObserver, performance } from "node:perf_hooks"
2
+
3
+ export const startObservingPerformances = () => {
4
+ const measureEntries = []
5
+ // https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html
6
+ const perfObserver = new PerformanceObserver(
7
+ (
8
+ // https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceobserverentrylist
9
+ list,
10
+ ) => {
11
+ const perfMeasureEntries = list.getEntriesByType("measure")
12
+ measureEntries.push(...perfMeasureEntries)
13
+ },
14
+ )
15
+ perfObserver.observe({
16
+ entryTypes: ["measure"],
17
+ })
18
+ return async () => {
19
+ // wait for node to call the performance observer
20
+ await new Promise((resolve) => {
21
+ setTimeout(resolve)
22
+ })
23
+ performance.clearMarks()
24
+ perfObserver.disconnect()
25
+ return {
26
+ ...readNodePerformance(),
27
+ measures: measuresFromMeasureEntries(measureEntries),
28
+ }
29
+ }
30
+ }
31
+
32
+ const readNodePerformance = () => {
33
+ const nodePerformance = {
34
+ nodeTiming: asPlainObject(performance.nodeTiming),
35
+ timeOrigin: performance.timeOrigin,
36
+ eventLoopUtilization: performance.eventLoopUtilization(),
37
+ }
38
+ return nodePerformance
39
+ }
40
+
41
+ // remove getters that cannot be stringified
42
+ const asPlainObject = (objectWithGetters) => {
43
+ const objectWithoutGetters = {}
44
+ Object.keys(objectWithGetters).forEach((key) => {
45
+ objectWithoutGetters[key] = objectWithGetters[key]
46
+ })
47
+ return objectWithoutGetters
48
+ }
49
+
50
+ const measuresFromMeasureEntries = (measureEntries) => {
51
+ const measures = {}
52
+ // Sort to ensure measures order is predictable
53
+ // It seems to be already predictable on Node 16+ but
54
+ // it's not the case on Node 14.
55
+ measureEntries.sort((a, b) => {
56
+ return a.startTime - b.startTime
57
+ })
58
+ measureEntries.forEach(
59
+ (
60
+ // https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceentry
61
+ perfMeasureEntry,
62
+ ) => {
63
+ measures[perfMeasureEntry.name] = perfMeasureEntry.duration
64
+ },
65
+ )
66
+ return measures
67
+ }
@@ -1,38 +1,48 @@
1
1
  import { resolveUrl } from "@jsenv/filesystem"
2
2
 
3
3
  import { measureAsyncFnPerf } from "@jsenv/core/src/internal/perf_node.js"
4
+ import { startObservingPerformances } from "./node_execution_performance.js"
4
5
  import { unevalException } from "@jsenv/core/src/internal/unevalException.js"
5
- import { memoize } from "../../memoize.js"
6
- import { installNodeErrorStackRemapping } from "../../error-stack-remapping/installNodeErrorStackRemapping.js"
7
- import { fetchSource } from "./fetchSource.js"
8
- import { createNodeSystem } from "./createNodeSystem.js"
9
6
 
10
- const memoizedCreateNodeSystem = memoize(createNodeSystem)
7
+ import { installNodeErrorStackRemapping } from "@jsenv/core/src/internal/error-stack-remapping/installNodeErrorStackRemapping.js"
8
+ import { fetchSource } from "@jsenv/core/src/internal/node_runtime/fetchSource.js"
9
+ import { createNodeSystem } from "@jsenv/core/src/internal/node_runtime/node_system.js"
11
10
 
12
- export const createNodeExecutionWithSystemJs = ({
11
+ export const execute = async ({
13
12
  projectDirectoryUrl,
14
13
  compileServerOrigin,
14
+ fileRelativeUrl,
15
15
  outDirectoryRelativeUrl,
16
16
  compileId,
17
17
  importDefaultExtension,
18
+ // do not log in the console
19
+ // because error handling becomes responsability
20
+ // of node code launching node process
21
+ // it avoids seeing error in runtime logs during testing
22
+ errorExposureInConsole = false,
23
+ collectCoverage,
24
+ measurePerformance,
25
+ collectPerformance,
18
26
  }) => {
27
+ let finalizeExecutionResult = (result) => result
28
+
29
+ if (collectPerformance) {
30
+ const getPerformance = startObservingPerformances()
31
+ finalizeExecutionResult = async (executionResult) => {
32
+ const performance = await getPerformance()
33
+ return {
34
+ ...executionResult,
35
+ performance,
36
+ }
37
+ }
38
+ }
39
+
19
40
  const { getErrorOriginalStackString } = installNodeErrorStackRemapping({
20
41
  projectDirectoryUrl,
21
42
  })
22
43
 
23
44
  const compileDirectoryRelativeUrl = `${outDirectoryRelativeUrl}${compileId}/`
24
45
 
25
- const importFile = async (specifier) => {
26
- const nodeSystem = await memoizedCreateNodeSystem({
27
- projectDirectoryUrl,
28
- compileServerOrigin,
29
- compileDirectoryRelativeUrl,
30
- fetchSource,
31
- importDefaultExtension,
32
- })
33
- return makePromiseKeepNodeProcessAlive(nodeSystem.import(specifier))
34
- }
35
-
36
46
  const errorTransformer = async (error) => {
37
47
  // code can throw something else than an error
38
48
  // in that case return it unchanged
@@ -52,7 +62,7 @@ export const createNodeExecutionWithSystemJs = ({
52
62
  `${compileServerOrigin}/${compileDirectoryRelativeUrl}`,
53
63
  )
54
64
 
55
- const nodeSystem = await memoizedCreateNodeSystem({
65
+ const nodeSystem = await createNodeSystem({
56
66
  projectDirectoryUrl,
57
67
  compileServerOrigin,
58
68
  compileDirectoryRelativeUrl,
@@ -88,18 +98,22 @@ export const createNodeExecutionWithSystemJs = ({
88
98
  }
89
99
  }
90
100
  }
91
-
92
101
  if (measurePerformance) {
93
102
  return measureAsyncFnPerf(importWithSystemJs, "jsenv_file_import")
94
103
  }
95
104
  return importWithSystemJs()
96
105
  }
97
106
 
98
- return {
99
- compileDirectoryRelativeUrl,
100
- importFile,
101
- executeFile,
102
- }
107
+ const executionResult = await executeFile(fileRelativeUrl, {
108
+ errorExposureInConsole,
109
+ measurePerformance,
110
+ collectCoverage,
111
+ })
112
+
113
+ return finalizeExecutionResult({
114
+ ...executionResult,
115
+ indirectCoverage: global.__indirectCoverage__,
116
+ })
103
117
  }
104
118
 
105
119
  const makePromiseKeepNodeProcessAlive = async (promise) => {
@@ -8,14 +8,14 @@ import { urlToFileSystemPath, resolveUrl } from "@jsenv/filesystem"
8
8
  import { isSpecifierForNodeCoreModule } from "@jsenv/importmap/src/isSpecifierForNodeCoreModule.js"
9
9
 
10
10
  import { createImportResolverForNode } from "@jsenv/core/src/internal/import-resolution/import-resolver-node.js"
11
- import { require } from "../../require.js"
12
- import "../s.js"
11
+ import { require } from "../require.js"
12
+ import "../runtime/s.js"
13
13
  import {
14
14
  fromFunctionReturningNamespace,
15
15
  getJavaScriptModuleResponseError,
16
16
  fromFunctionReturningRegisteredModule,
17
- } from "../module-registration.js"
18
- import { valueInstall } from "../valueInstall.js"
17
+ } from "../runtime/module-registration.js"
18
+ import { valueInstall } from "../runtime/valueInstall.js"
19
19
  import { evalSource } from "./evalSource.js"
20
20
 
21
21
  export const createNodeSystem = async ({
@@ -1,4 +1,5 @@
1
1
  import { createDetailedMessage } from "@jsenv/logger"
2
+
2
3
  import { COMPILE_ID_OTHERWISE } from "../CONSTANTS.js"
3
4
 
4
5
  export const computeCompileIdFromGroupId = ({ groupId, groupMap }) => {
@@ -1,4 +1,4 @@
1
- import { findHighestVersion } from "../semantic-versioning/index.js"
1
+ import { findHighestVersion } from "../semantic_versioning/index.js"
2
2
 
3
3
  export const resolveGroup = ({ name, version }, groupMap) => {
4
4
  return Object.keys(groupMap).find((compileIdCandidate) => {
@@ -1,6 +1,6 @@
1
1
  /* eslint-env browser, node */
2
- import { detectBrowser } from "./detectBrowser/detectBrowser.js"
3
- import { detectNode } from "./detectNode/detectNode.js"
2
+ import { detectBrowser } from "../browser_detection/browser_detection.js"
3
+ import { detectNode } from "../node_runtime/detectNode.js"
4
4
  import { resolveGroup } from "./resolveGroup.js"
5
5
 
6
6
  export const resolveRuntimeGroup = (groupMap) => {
@@ -11,9 +11,9 @@ import { memoize } from "@jsenv/filesystem"
11
11
 
12
12
  import { fetchUrl } from "./internal/fetchUrl.js"
13
13
  import { validateResponse } from "./internal/response_validation.js"
14
- import { trackPageToNotify } from "./internal/browser-launcher/trackPageToNotify.js"
15
- import { createSharing } from "./internal/browser-launcher/createSharing.js"
16
- import { executeHtmlFile } from "./internal/browser-launcher/executeHtmlFile.js"
14
+ import { trackPageToNotify } from "./internal/browser_launcher/trackPageToNotify.js"
15
+ import { createSharing } from "./internal/browser_launcher/createSharing.js"
16
+ import { executeHtmlFile } from "./internal/browser_launcher/executeHtmlFile.js"
17
17
  import {
18
18
  PLAYWRIGHT_CHROMIUM_VERSION,
19
19
  PLAYWRIGHT_FIREFOX_VERSION,
package/src/launchNode.js CHANGED
@@ -3,7 +3,8 @@ import { loggerToLogLevel } from "@jsenv/logger"
3
3
 
4
4
  import { jsenvCoreDirectoryUrl } from "@jsenv/core/src/internal/jsenvCoreDirectoryUrl.js"
5
5
  import { escapeRegexpSpecialCharacters } from "./internal/escapeRegexpSpecialCharacters.js"
6
- import { createControllableNodeProcess } from "./internal/node-launcher/createControllableNodeProcess.js"
6
+ import { createControllableNodeProcess } from "./internal/node_launcher/createControllableNodeProcess.js"
7
+ import { scanNodeRuntimeFeatures } from "./internal/node_feature_detection/node_feature_detection.js"
7
8
 
8
9
  export const nodeRuntime = {
9
10
  name: "node",
@@ -34,7 +35,7 @@ nodeRuntime.launch = async ({
34
35
  stdout,
35
36
  stderr,
36
37
  stopAfterExecute,
37
- canUseNativeModuleSystem,
38
+ forceSystemJs,
38
39
 
39
40
  remap = true,
40
41
  }) => {
@@ -103,7 +104,6 @@ nodeRuntime.launch = async ({
103
104
 
104
105
  fileRelativeUrl,
105
106
  executionId,
106
- canUseNativeModuleSystem,
107
107
  exitAfterAction: stopAfterExecute,
108
108
 
109
109
  measurePerformance,
@@ -114,11 +114,37 @@ nodeRuntime.launch = async ({
114
114
  remap,
115
115
  }
116
116
 
117
- let executionResult = await requestActionOnChildProcess({
118
- signal,
119
- actionType: "execute-using-dynamic-import-fallback-on-systemjs",
120
- actionParams: executeParams,
117
+ // the computation of runtime features can be cached
118
+ const nodeFeatures = await scanNodeRuntimeFeatures({
119
+ compileServerOrigin,
120
+ outDirectoryRelativeUrl,
121
+ // https://nodejs.org/docs/latest-v15.x/api/cli.html#cli_node_v8_coverage_dir
122
+ // instrumentation CAN be handed by process.env.NODE_V8_COVERAGE
123
+ // "transform-instrument" becomes non mandatory
124
+ coverageHandledFromOutside:
125
+ !coverageForceIstanbul && process.env.NODE_V8_COVERAGE,
121
126
  })
127
+ const { canAvoidCompilation, compileId, importDefaultExtension } =
128
+ nodeFeatures
129
+
130
+ let executionResult
131
+ if (canAvoidCompilation && !forceSystemJs) {
132
+ executionResult = await requestActionOnChildProcess({
133
+ signal,
134
+ actionType: "execute-using-dynamic-import",
135
+ actionParams: executeParams,
136
+ })
137
+ } else {
138
+ executionResult = await requestActionOnChildProcess({
139
+ signal,
140
+ actionType: "execute-using-systemjs",
141
+ actionParams: {
142
+ compileId,
143
+ importDefaultExtension,
144
+ ...executeParams,
145
+ },
146
+ })
147
+ }
122
148
 
123
149
  executionResult = transformExecutionResult(executionResult, {
124
150
  compileServerOrigin,
@@ -1,5 +1,5 @@
1
1
  import { launchAndExecute } from "./internal/executing/launchAndExecute.js"
2
- import { createControllableNodeProcess } from "./internal/node-launcher/createControllableNodeProcess.js"
2
+ import { createControllableNodeProcess } from "./internal/node_launcher/createControllableNodeProcess.js"
3
3
 
4
4
  export const requireUsingChildProcess = async (
5
5
  fileUrl,