@jsenv/core 24.2.2 → 24.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 (156) hide show
  1. package/dist/browser_runtime/browser_runtime-fbd309a1.js +5137 -0
  2. package/dist/browser_runtime/browser_runtime-fbd309a1.js.map +1064 -0
  3. package/dist/{jsenv_browser_system.js → browser_system/browser_system-29eda202.js} +12 -12
  4. package/dist/{jsenv_browser_system.js.map → browser_system/browser_system-29eda202.js.map} +64 -64
  5. package/dist/build_manifest.js +12 -0
  6. package/dist/compile_proxy/assets/s.js-749702e8.map +242 -0
  7. package/dist/compile_proxy/compile_proxy-405777e6.html +2074 -0
  8. package/dist/compile_proxy/compile_proxy.html__inline__20-39c0801c.js.map +385 -0
  9. package/dist/{jsenv_event_source_client.js → event_source_client/event_source_client-9f14c8b9.js} +39 -21
  10. package/dist/event_source_client/event_source_client-9f14c8b9.js.map +127 -0
  11. package/dist/redirector/assets/s.js-749702e8.map +242 -0
  12. package/dist/redirector/redirector-237cd168.html +2118 -0
  13. package/dist/redirector/redirector.html__inline__15-33acb0b9.js.map +390 -0
  14. package/dist/toolbar/assets/compilation.css-209d68b4.map +12 -0
  15. package/dist/toolbar/assets/eventsource.css-38cd0a36.map +12 -0
  16. package/dist/toolbar/assets/execution.css-0ebe522f.map +12 -0
  17. package/dist/toolbar/assets/focus.css-3f9c156d.map +12 -0
  18. package/dist/toolbar/assets/light-theme.css-78b19a80.map +12 -0
  19. package/dist/toolbar/assets/overflow-menu.css-d9688a1c.map +12 -0
  20. package/dist/toolbar/assets/s.js-749702e8.map +242 -0
  21. package/dist/toolbar/assets/settings.css-2b81b245.map +12 -0
  22. package/dist/toolbar/assets/toolbar.main.css-846920e9.map +28 -0
  23. package/dist/toolbar/assets/tooltip.css-03395ee6.map +12 -0
  24. package/dist/toolbar/toolbar-29e91dcd.html +4779 -0
  25. package/dist/toolbar/toolbar.main-53e1ab2b.js.map +795 -0
  26. package/dist/toolbar_injector/assets/jsenv-logo-188b9ca6.svg +95 -0
  27. package/dist/{jsenv_toolbar_injector.js → toolbar_injector/toolbar_injector-0af91b43.js} +87 -65
  28. package/dist/toolbar_injector/toolbar_injector-0af91b43.js.map +294 -0
  29. package/main.js +0 -1
  30. package/package.json +2 -1
  31. package/readme.md +10 -7
  32. package/src/buildProject.js +6 -2
  33. package/src/dev_server.js +22 -130
  34. package/src/execute.js +7 -10
  35. package/src/executeTestPlan.js +7 -1
  36. package/src/importUsingChildProcess.js +1 -1
  37. package/src/internal/{runtime/detectBrowser/detectBrowser.js → browser_detection/browser_detection.js} +0 -0
  38. package/src/internal/{runtime/detectBrowser → browser_detection}/detectAndroid.js +0 -0
  39. package/src/internal/{runtime/detectBrowser → browser_detection}/detectChrome.js +0 -0
  40. package/src/internal/{runtime/detectBrowser → browser_detection}/detectEdge.js +0 -0
  41. package/src/internal/{runtime/detectBrowser → browser_detection}/detectElectron.js +0 -0
  42. package/src/internal/{runtime/detectBrowser → browser_detection}/detectFirefox.js +0 -0
  43. package/src/internal/{runtime/detectBrowser → browser_detection}/detectIOS.js +0 -0
  44. package/src/internal/{runtime/detectBrowser → browser_detection}/detectInternetExplorer.js +0 -0
  45. package/src/internal/{runtime/detectBrowser → browser_detection}/detectOpera.js +0 -0
  46. package/src/internal/{runtime/detectBrowser → browser_detection}/detectSafari.js +0 -0
  47. package/src/internal/{runtime/detectBrowser → browser_detection}/util.js +0 -0
  48. package/src/internal/{runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js → browser_feature_detection/browser_feature_detection.js} +116 -81
  49. package/src/internal/browser_feature_detection/compile_proxy.html +27 -0
  50. package/src/internal/browser_launcher/browser_runtime_report.js +75 -0
  51. package/src/internal/{browser-launcher → browser_launcher}/executeHtmlFile.js +13 -16
  52. package/src/internal/browser_launcher/from_playwright.js +314 -0
  53. package/src/internal/{browser-launcher → browser_launcher}/trackPageToNotify.js +0 -0
  54. package/src/internal/{browser-launcher/jsenv-browser-system.js → browser_runtime/browser_runtime.js} +4 -4
  55. package/src/internal/{runtime/createBrowserRuntime/createBrowserSystem.js → browser_runtime/browser_system.js} +3 -2
  56. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/createBrowserRuntime.js +7 -5
  57. package/src/internal/{browser-launcher → browser_runtime}/displayErrorInDocument.js +0 -0
  58. package/src/internal/{browser-launcher → browser_runtime}/displayErrorNotification.js +2 -4
  59. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/evalSource.js +2 -0
  60. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/makeNamespaceTransferable.js +0 -0
  61. package/src/internal/{browser-utils → browser_utils}/fetch-browser.js +2 -0
  62. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingFetch.js +3 -0
  63. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingScript.js +2 -0
  64. package/src/internal/{browser-utils → browser_utils}/fetchJson.js +0 -0
  65. package/src/internal/{browser-utils → browser_utils}/fetchUsingXHR.js +4 -4
  66. package/src/internal/building/buildUsingRollup.js +4 -0
  67. package/src/internal/building/createJsenvRollupPlugin.js +19 -9
  68. package/src/internal/building/css/applyPostCss.js +19 -8
  69. package/src/internal/building/css/moveCssUrls.js +44 -0
  70. package/src/internal/building/css/parseCssRessource.js +67 -17
  71. package/src/internal/building/css/parseCssUrls.js +29 -23
  72. package/src/internal/building/css/postcss_plugin_url_visitor.js +11 -20
  73. package/src/internal/building/css/replaceCssUrls.js +38 -19
  74. package/src/internal/building/css_module.js +6 -10
  75. package/src/internal/building/html/parseHtmlRessource.js +37 -11
  76. package/src/internal/building/parseRessource.js +3 -0
  77. package/src/internal/building/ressource_builder.js +12 -3
  78. package/src/internal/compiling/babel_plugin_import_assertions.js +1 -2
  79. package/src/internal/compiling/html_source_file_service.js +23 -21
  80. package/src/internal/compiling/jsenvCompilerForHtml.js +15 -22
  81. package/src/internal/compiling/startCompileServer.js +37 -32
  82. package/src/internal/dev_server/event_source_client/event_source_connection.js +28 -19
  83. package/src/internal/dev_server/exploring/exploring.html +7 -2
  84. package/src/internal/dev_server/exploring/fetchExploringJson.js +4 -9
  85. package/src/internal/dev_server/redirector/redirector.html +37 -2
  86. package/src/internal/dev_server/toolbar/compilation/toolbar.compilation.js +4 -7
  87. package/src/internal/dev_server/toolbar/eventsource/toolbar.eventsource.js +2 -2
  88. package/src/internal/dev_server/toolbar/notification/toolbar.notification.js +75 -44
  89. package/src/internal/dev_server/toolbar/toolbar.html +31 -5
  90. package/src/internal/dev_server/toolbar/toolbar.injector.js +55 -36
  91. package/src/internal/dev_server/toolbar/toolbar.main.js +45 -31
  92. package/src/internal/dev_server/toolbar/util/fetching.js +1 -1
  93. package/src/internal/executing/executeConcurrently.js +15 -11
  94. package/src/internal/executing/executePlan.js +3 -2
  95. package/src/internal/generateGroupMap/one_runtime_compat.js +1 -1
  96. package/src/internal/generateGroupMap/runtime_compat_composition.js +1 -1
  97. package/src/internal/generateGroupMap/runtime_support.js +1 -1
  98. package/src/internal/jsenvInternalFiles.js +0 -26
  99. package/src/internal/jsenv_builds.js +19 -0
  100. package/src/internal/{runtime/node-feature-detect/feature-detect-dynamic-import.mjs → node_feature_detection/feature_detect_dynamic_import.mjs} +0 -0
  101. package/src/internal/{runtime/node-feature-detect/feature-detect-top-level-await.mjs → node_feature_detection/feature_detect_top_level_await.mjs} +0 -0
  102. package/src/internal/{runtime/node-feature-detect → node_feature_detection}/nodeSupportsDynamicImport.js +0 -0
  103. package/src/internal/node_feature_detection/nodeSupportsTopLevelAwait.js +16 -0
  104. package/src/internal/{runtime/createNodeRuntime/scanNodeRuntimeFeatures.js → node_feature_detection/node_feature_detection.js} +12 -13
  105. package/src/internal/{node-launcher → node_launcher}/createChildProcessOptions.js +0 -0
  106. package/src/internal/{node-launcher → node_launcher}/createControllableNodeProcess.js +9 -14
  107. package/src/internal/{node-launcher → node_launcher}/kill_process_tree.js +0 -0
  108. package/src/internal/node_launcher/node_runtime_report.js +71 -0
  109. package/src/internal/{node-launcher → node_launcher}/processOptions.js +0 -0
  110. package/src/internal/{runtime/detectNode → node_runtime}/detectNode.js +0 -0
  111. package/src/internal/{runtime/createNodeRuntime → node_runtime}/evalSource.js +1 -1
  112. package/src/internal/{runtime/createNodeRuntime → node_runtime}/fetchSource.js +1 -1
  113. package/src/internal/{node-launcher → node_runtime}/nodeControllableFile.mjs +14 -11
  114. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithDynamicImport.js → node_runtime/node_execution_dynamic_import.js} +34 -6
  115. package/src/internal/node_runtime/node_execution_performance.js +67 -0
  116. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithSystemJs.js → node_runtime/node_execution_systemjs.js} +38 -24
  117. package/src/internal/{runtime/createNodeRuntime/createNodeSystem.js → node_runtime/node_system.js} +4 -4
  118. package/src/internal/runtime/computeCompileIdFromGroupId.js +1 -0
  119. package/src/internal/runtime/resolveGroup.js +1 -1
  120. package/src/internal/runtime/resolveRuntimeGroup.js +2 -2
  121. package/src/internal/{semantic-versioning → semantic_versioning}/findHighestVersion.js +0 -0
  122. package/src/internal/{semantic-versioning → semantic_versioning}/findLowestVersion.js +0 -0
  123. package/src/internal/{semantic-versioning → semantic_versioning}/index.js +0 -0
  124. package/src/internal/{semantic-versioning → semantic_versioning}/valueToVersion.js +0 -0
  125. package/src/internal/{semantic-versioning → semantic_versioning}/versionCompare.js +0 -0
  126. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsAbove.js +0 -0
  127. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsBelow.js +0 -0
  128. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsEqual.js +0 -0
  129. package/src/launchBrowser.js +33 -492
  130. package/src/launchNode.js +36 -7
  131. package/src/requireUsingChildProcess.js +1 -1
  132. package/dist/jsenv_compile_proxy.js +0 -1339
  133. package/dist/jsenv_compile_proxy.js.map +0 -378
  134. package/dist/jsenv_event_source_client.js.map +0 -126
  135. package/dist/jsenv_exploring_index.js +0 -1092
  136. package/dist/jsenv_exploring_index.js.map +0 -353
  137. package/dist/jsenv_exploring_redirector.js +0 -1386
  138. package/dist/jsenv_exploring_redirector.js.map +0 -384
  139. package/dist/jsenv_redirector.js +0 -1388
  140. package/dist/jsenv_redirector.js.map +0 -384
  141. package/dist/jsenv_toolbar.js +0 -2880
  142. package/dist/jsenv_toolbar.js.map +0 -771
  143. package/dist/jsenv_toolbar_injector.js.map +0 -301
  144. package/src/internal/browser-launcher/createSharing.js +0 -70
  145. package/src/internal/browser-launcher/jsenv_compile_proxy.html +0 -13
  146. package/src/internal/browser-launcher/jsenv_compile_proxy.js +0 -5
  147. package/src/internal/dev_server/event_source_client/event_source_client_file_info.js +0 -17
  148. package/src/internal/dev_server/exploring/exploring_file_info.js +0 -21
  149. package/src/internal/dev_server/redirector/redirector.js +0 -30
  150. package/src/internal/dev_server/redirector/redirector_file_info.js +0 -24
  151. package/src/internal/dev_server/toolbar/backtolist/toolbar.backtolist.js +0 -33
  152. package/src/internal/dev_server/toolbar/toolbar_file_info.js +0 -37
  153. package/src/internal/node-launcher/node-js-file.js +0 -110
  154. package/src/internal/runtime/createNodeRuntime/createNodeRuntime.js +0 -32
  155. package/src/internal/runtime/node-feature-detect/nodeSupportsTopLevelAwait.js +0 -18
  156. package/src/nodeRuntime.js +0 -5
@@ -0,0 +1,16 @@
1
+ import { memoize } from "@jsenv/filesystem"
2
+
3
+ const FEATURE_DETECT_DYNAMIC_IMPORT_FILE_URL = new URL(
4
+ "./feature_detect_top_level_await.mjs",
5
+ import.meta.url,
6
+ ).href
7
+
8
+ export const nodeSupportsTopLevelAwait = memoize(async () => {
9
+ try {
10
+ const namespace = await import(FEATURE_DETECT_DYNAMIC_IMPORT_FILE_URL)
11
+ const supported = namespace.default === 42
12
+ return supported
13
+ } catch (e) {
14
+ return false
15
+ }
16
+ })
@@ -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
  }
@@ -0,0 +1,71 @@
1
+ import { scanNodeRuntimeFeatures } from "@jsenv/core/src/internal/node_feature_detection/node_feature_detection.js"
2
+
3
+ export const getNodeRuntimeReport = async ({
4
+ runtime,
5
+ compileServerId,
6
+ compileServerOrigin,
7
+ outDirectoryRelativeUrl,
8
+ coverageHandledFromOutside,
9
+ }) => {
10
+ const cache = cacheFromParams({
11
+ runtime,
12
+ compileServerId,
13
+ compileServerOrigin,
14
+ outDirectoryRelativeUrl,
15
+ coverageHandledFromOutside,
16
+ })
17
+ const entry = cache.read()
18
+ if (entry) {
19
+ return entry
20
+ }
21
+ const nodeRuntimeFeaturesReport = await scanNodeRuntimeFeatures({
22
+ compileServerOrigin,
23
+ outDirectoryRelativeUrl,
24
+ coverageHandledFromOutside,
25
+ })
26
+ cache.write(nodeRuntimeFeaturesReport)
27
+ return nodeRuntimeFeaturesReport
28
+ }
29
+
30
+ let currentCacheParams
31
+ let currentCacheValue
32
+ const cacheFromParams = ({
33
+ compileServerId,
34
+ compileServerOrigin,
35
+ outDirectoryRelativeUrl,
36
+ coverageHandledFromOutside,
37
+ }) => {
38
+ const params = {
39
+ compileServerId,
40
+ compileServerOrigin,
41
+ outDirectoryRelativeUrl,
42
+ coverageHandledFromOutside,
43
+ }
44
+
45
+ if (!currentCacheParams) {
46
+ currentCacheParams = params
47
+ return {
48
+ read: () => null,
49
+ write: (value) => {
50
+ currentCacheValue = value
51
+ },
52
+ }
53
+ }
54
+
55
+ if (JSON.stringify(currentCacheParams) !== JSON.stringify(params)) {
56
+ return {
57
+ read: () => null,
58
+ write: (value) => {
59
+ currentCacheParams = params
60
+ currentCacheValue = value
61
+ },
62
+ }
63
+ }
64
+
65
+ return {
66
+ read: () => currentCacheValue,
67
+ write: (value) => {
68
+ currentCacheValue = value
69
+ },
70
+ }
71
+ }
@@ -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) => {