@jsenv/core 27.0.0-alpha.11 → 27.0.0-alpha.14

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 (125) hide show
  1. package/main.js +4 -0
  2. package/package.json +17 -14
  3. package/readme.md +4 -12
  4. package/src/build/build.js +451 -388
  5. package/src/build/build_urls_generator.js +23 -20
  6. package/src/build/graph_utils.js +31 -0
  7. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +31 -14
  8. package/src/build/inject_service_worker_urls.js +66 -12
  9. package/src/build/resync_ressource_hints.js +83 -0
  10. package/src/build/start_build_server.js +193 -0
  11. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  12. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  13. package/src/dev/start_dev_server.js +16 -22
  14. package/src/execute/execute.js +19 -6
  15. package/src/execute/run.js +17 -54
  16. package/src/execute/runtimes/browsers/from_playwright.js +167 -146
  17. package/src/execute/runtimes/node/node_process.js +281 -37
  18. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  19. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +30 -7
  20. package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +14 -16
  21. package/src/omega/errors.js +51 -58
  22. package/src/omega/fetched_content_compliance.js +24 -0
  23. package/src/omega/kitchen.js +403 -283
  24. package/src/omega/server/file_service.js +9 -11
  25. package/src/omega/url_graph/url_graph_load.js +13 -7
  26. package/src/omega/url_graph/url_graph_report.js +7 -5
  27. package/src/omega/url_graph.js +22 -10
  28. package/src/omega/web_workers.js +42 -0
  29. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  30. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  31. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  32. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  33. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +41 -0
  34. package/src/{dev/plugins/autoreload/jsenv_plugin_autoreload.js → plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js} +25 -166
  35. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
  36. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  37. package/src/plugins/bundling/css/bundle_css.js +17 -0
  38. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  39. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +100 -75
  40. package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
  41. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +48 -41
  42. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  43. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +7 -4
  44. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  45. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  46. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
  47. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
  48. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  49. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  50. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +38 -46
  51. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  52. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  53. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  54. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  55. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +98 -0
  56. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +26 -8
  57. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  58. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  59. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
  60. package/src/{omega/core_plugins → plugins}/inject_globals/jsenv_plugin_inject_globals.js +5 -7
  61. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  62. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  63. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
  64. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  65. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  66. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +263 -0
  67. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  68. package/src/plugins/minification/css/minify_css.js +9 -0
  69. package/src/plugins/minification/html/minify_html.js +15 -0
  70. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  71. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  72. package/src/plugins/minification/json/minify_json.js +8 -0
  73. package/src/{omega/core_plugins → plugins}/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +15 -15
  74. package/src/{omega → plugins}/plugin_controller.js +18 -10
  75. package/src/plugins/plugins.js +73 -0
  76. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  77. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  78. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  79. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  80. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +191 -0
  81. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +156 -0
  82. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_top_level_await.js +37 -0
  83. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +133 -0
  84. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  85. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  86. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  87. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +3 -21
  88. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  89. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +29 -27
  90. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +0 -0
  91. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  92. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  93. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  94. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  95. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  96. package/src/{omega/core_plugins → plugins/transpilation}/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -0
  97. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +243 -0
  98. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +40 -0
  99. package/src/plugins/url_references/css/css_urls.js +49 -0
  100. package/src/plugins/url_references/html/html_urls.js +273 -0
  101. package/src/plugins/url_references/js/js_urls.js +170 -0
  102. package/src/plugins/url_references/jsenv_plugin_url_references.js +18 -0
  103. package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
  104. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  105. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +8 -8
  106. package/src/test/execute_plan.js +23 -11
  107. package/src/test/execute_test_plan.js +9 -6
  108. package/src/test/logs_file_execution.js +8 -7
  109. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  110. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  111. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  112. package/src/execute/runtimes/node/controlled_process.js +0 -316
  113. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  114. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  115. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  116. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  117. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  118. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -207
  119. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  120. package/src/omega/core_plugins.js +0 -42
  121. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  122. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  123. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  124. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  125. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -1,43 +1,32 @@
1
- import { isFileSystemPath, urlToRelativeUrl } from "@jsenv/filesystem"
1
+ import { isFileSystemPath } from "@jsenv/filesystem"
2
+ import { createDetailedMessage } from "@jsenv/logger"
2
3
 
3
4
  import { applyRollupPlugins } from "@jsenv/utils/js_ast/apply_rollup_plugins.js"
4
5
  import { sourcemapConverter } from "@jsenv/utils/sourcemap/sourcemap_converter.js"
5
6
  import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
6
7
 
7
- export const jsenvPluginBundleJsModule = () => {
8
- return {
9
- name: "jsenv:bundle_js_module",
10
- appliesDuring: {
11
- build: true,
12
- },
13
- bundle: {
14
- js_module: async (
15
- jsModuleUrlInfos,
16
- {
17
- signal,
18
- logger,
19
- rootDirectoryUrl,
20
- buildDirectoryUrl,
21
- urlGraph,
22
- runtimeSupport,
23
- sourcemaps,
24
- },
25
- ) => {
26
- const { jsModuleBundleUrlInfos } = await buildWithRollup({
27
- signal,
28
- logger,
29
- rootDirectoryUrl,
30
- buildDirectoryUrl,
31
- urlGraph,
32
- jsModuleUrlInfos,
8
+ export const bundleJsModule = async ({ jsModuleUrlInfos, context }) => {
9
+ const {
10
+ signal,
11
+ logger,
12
+ rootDirectoryUrl,
13
+ buildDirectoryUrl,
14
+ urlGraph,
15
+ runtimeCompat,
16
+ sourcemaps,
17
+ } = context
18
+ const { jsModuleBundleUrlInfos } = await buildWithRollup({
19
+ signal,
20
+ logger,
21
+ rootDirectoryUrl,
22
+ buildDirectoryUrl,
23
+ urlGraph,
24
+ jsModuleUrlInfos,
33
25
 
34
- runtimeSupport,
35
- sourcemaps,
36
- })
37
- return jsModuleBundleUrlInfos
38
- },
39
- },
40
- }
26
+ runtimeCompat,
27
+ sourcemaps,
28
+ })
29
+ return jsModuleBundleUrlInfos
41
30
  }
42
31
 
43
32
  export const buildWithRollup = async ({
@@ -48,36 +37,46 @@ export const buildWithRollup = async ({
48
37
  urlGraph,
49
38
  jsModuleUrlInfos,
50
39
 
51
- runtimeSupport,
40
+ runtimeCompat,
52
41
  sourcemaps,
53
42
  }) => {
54
43
  const resultRef = { current: null }
55
- await applyRollupPlugins({
56
- rollupPlugins: [
57
- rollupPluginJsenv({
58
- signal,
59
- logger,
60
- rootDirectoryUrl,
61
- buildDirectoryUrl,
62
- urlGraph,
63
- jsModuleUrlInfos,
44
+ try {
45
+ await applyRollupPlugins({
46
+ rollupPlugins: [
47
+ rollupPluginJsenv({
48
+ signal,
49
+ logger,
50
+ rootDirectoryUrl,
51
+ buildDirectoryUrl,
52
+ urlGraph,
53
+ jsModuleUrlInfos,
64
54
 
65
- runtimeSupport,
66
- sourcemaps,
67
- resultRef,
68
- }),
69
- ],
70
- inputOptions: {
71
- input: [],
72
- onwarn: (warning) => {
73
- if (warning.code === "CIRCULAR_DEPENDENCY") {
74
- return
75
- }
76
- logger.warn(String(warning))
55
+ runtimeCompat,
56
+ sourcemaps,
57
+ resultRef,
58
+ }),
59
+ ],
60
+ inputOptions: {
61
+ input: [],
62
+ onwarn: (warning) => {
63
+ if (warning.code === "CIRCULAR_DEPENDENCY") {
64
+ return
65
+ }
66
+ logger.warn(String(warning))
67
+ },
77
68
  },
78
- },
79
- })
80
- return resultRef.current
69
+ })
70
+ return resultRef.current
71
+ } catch (e) {
72
+ if (e.code === "MISSING_EXPORT") {
73
+ const detailedMessage = createDetailedMessage(e.message, {
74
+ frame: e.frame,
75
+ })
76
+ throw new Error(detailedMessage, { cause: e })
77
+ }
78
+ throw e
79
+ }
81
80
  }
82
81
 
83
82
  const rollupPluginJsenv = ({
@@ -119,6 +118,7 @@ const rollupPluginJsenv = ({
119
118
  implicitlyLoadedAfterOneOf: previousNonEntryPointModuleId
120
119
  ? [previousNonEntryPointModuleId]
121
120
  : null,
121
+ preserveSignature: "allow-extension",
122
122
  })
123
123
  previousNonEntryPointModuleId = id
124
124
  })
@@ -135,8 +135,12 @@ const rollupPluginJsenv = ({
135
135
  // buildRelativeUrl: rollupFileInfo.fileName,
136
136
  data: {
137
137
  generatedBy: "rollup",
138
+ usesImport:
139
+ rollupFileInfo.imports.length > 0 ||
140
+ rollupFileInfo.dynamicImports.length > 0,
141
+ usesExport: rollupFileInfo.exports.length > 0,
138
142
  },
139
- contentType: "application/javascript",
143
+ contentType: "text/javascript",
140
144
  content: rollupFileInfo.code,
141
145
  sourcemap: rollupFileInfo.map,
142
146
  }
@@ -144,7 +148,7 @@ const rollupPluginJsenv = ({
144
148
  if (rollupFileInfo.facadeModuleId) {
145
149
  url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
146
150
  } else {
147
- url = new URL(rollupFileInfo.fileName, rootDirectoryUrl).href
151
+ url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
148
152
  }
149
153
  jsModuleBundleUrlInfos[url] = jsModuleBundleUrlInfo
150
154
  }
@@ -167,19 +171,12 @@ const rollupPluginJsenv = ({
167
171
  return `[name].js`
168
172
  },
169
173
  chunkFileNames: (chunkInfo) => {
170
- // preserves relative path parts:
171
- // the goal is to maintain the original relative path (relative to the root directory)
172
- // so that later in the build process, when resolving these urls, we are able to
173
- // re-resolve the specifier againt the original parent url and find the original url
174
- if (chunkInfo.facadeModuleId) {
175
- const fileUrl = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
176
- const relativePath = urlToRelativeUrl(fileUrl, rootDirectoryUrl)
177
- return relativePath
178
- }
179
- // chunk generated dynamically by rollup to share code.
180
- // we prefix with "__rollup__/" to avoid potential conflict of filename
181
- // between this one and a file with the same name existing in the root directory
182
- return `__rollup__/${chunkInfo.name}.js`
174
+ const insideJs = willBeInsideJsDirectory({
175
+ chunkInfo,
176
+ fileUrlConverter,
177
+ jsModuleUrlInfos,
178
+ })
179
+ return insideJs ? `js/${chunkInfo.name}.js` : `${chunkInfo.name}.js`
183
180
  },
184
181
  // https://rollupjs.org/guide/en/#outputpaths
185
182
  // paths: (id) => {
@@ -197,7 +194,7 @@ const rollupPluginJsenv = ({
197
194
  urlImporters[url] = importer
198
195
  }
199
196
  if (!url.startsWith("file:")) {
200
- return { url, external: true }
197
+ return { id: url, external: true }
201
198
  }
202
199
  const filePath = fileUrlConverter.asFilePath(url)
203
200
  return filePath
@@ -225,3 +222,31 @@ const rollupPluginJsenv = ({
225
222
  },
226
223
  }
227
224
  }
225
+
226
+ const willBeInsideJsDirectory = ({
227
+ chunkInfo,
228
+ fileUrlConverter,
229
+ jsModuleUrlInfos,
230
+ }) => {
231
+ // if the chunk is generated dynamically by rollup
232
+ // for an entry point jsenv will put that file inside js/ directory
233
+ // if it's generated dynamically for a file already in js/ directory
234
+ // both will be inside the js/ directory
235
+ if (!chunkInfo.facadeModuleId) {
236
+ // generated by rollup
237
+ return true
238
+ }
239
+ const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
240
+ const jsModuleUrlInfo = jsModuleUrlInfos.find(
241
+ (jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
242
+ )
243
+ if (!jsModuleUrlInfo) {
244
+ // generated by rollup
245
+ return true
246
+ }
247
+ if (!jsModuleUrlInfo.data.isEntryPoint) {
248
+ // not an entry point, jsenv will put it inside js/ directory
249
+ return true
250
+ }
251
+ return false
252
+ }
@@ -0,0 +1,51 @@
1
+ import { bundleCss } from "./css/bundle_css.js"
2
+ import { bundleJsClassicWorkers } from "./js_classic_workers/bundle_js_classic_workers.js"
3
+ import { bundleJsModule } from "./js_module/bundle_js_module.js"
4
+
5
+ export const jsenvPluginBundling = (bundling) => {
6
+ if (typeof bundling === "boolean") {
7
+ bundling = {
8
+ css: bundling,
9
+ js_classic_workers: bundling,
10
+ js_module: bundling,
11
+ }
12
+ } else if (typeof bundling !== "object") {
13
+ throw new Error(`bundling must be a boolean or an object, got ${bundling}`)
14
+ }
15
+ Object.keys(bundling).forEach((key) => {
16
+ if (bundling[key] === true) bundling[key] = {}
17
+ })
18
+
19
+ return {
20
+ name: "jsenv:bundling",
21
+ appliesDuring: {
22
+ build: true,
23
+ },
24
+ bundle: {
25
+ css: bundling.css
26
+ ? (cssUrlInfos, context) =>
27
+ bundleCss({
28
+ cssUrlInfos,
29
+ context,
30
+ options: bundling.css,
31
+ })
32
+ : undefined,
33
+ js_classic: bundling.js_classic
34
+ ? (jsClassicUrlInfos, context) =>
35
+ bundleJsClassicWorkers({
36
+ jsClassicUrlInfos,
37
+ context,
38
+ options: bundling.js_classic_workers,
39
+ })
40
+ : undefined,
41
+ js_module: bundling.js_module
42
+ ? (jsModuleUrlInfos, context) =>
43
+ bundleJsModule({
44
+ jsModuleUrlInfos,
45
+ context,
46
+ options: bundling.js_module,
47
+ })
48
+ : undefined,
49
+ },
50
+ }
51
+ }
@@ -11,50 +11,57 @@ import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
11
11
  import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
12
12
 
13
13
  export const jsenvPluginCommonJsGlobals = () => {
14
+ const transformCommonJsGlobals = async (urlInfo, { scenario }) => {
15
+ const isJsModule = urlInfo.type === "js_module"
16
+
17
+ const replaceMap = {
18
+ "process.env.NODE_ENV": `("${
19
+ scenario === "dev" || scenario === "test" ? "dev" : "prod"
20
+ }")`,
21
+ "global": "globalThis",
22
+ "__filename": isJsModule
23
+ ? `import.meta.url.slice('file:///'.length)`
24
+ : `document.currentScript.src`,
25
+ "__dirname": isJsModule
26
+ ? `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`
27
+ : `new URL('./', document.currentScript.src).href`,
28
+ }
29
+ const { metadata } = await applyBabelPlugins({
30
+ babelPlugins: [
31
+ [
32
+ babelPluginMetadataExpressionPaths,
33
+ {
34
+ replaceMap,
35
+ allowConflictingReplacements: true,
36
+ },
37
+ ],
38
+ ],
39
+ urlInfo,
40
+ })
41
+ const { expressionPaths } = metadata
42
+ const keys = Object.keys(expressionPaths)
43
+ if (keys.length === 0) {
44
+ return null
45
+ }
46
+ const magicSource = createMagicSource(urlInfo.content)
47
+ keys.forEach((key) => {
48
+ expressionPaths[key].forEach((path) => {
49
+ magicSource.replace({
50
+ start: path.node.start,
51
+ end: path.node.end,
52
+ replacement: replaceMap[key],
53
+ })
54
+ })
55
+ })
56
+ return magicSource.toContentAndSourcemap()
57
+ }
58
+
14
59
  return {
15
60
  name: "jsenv:commonjs_globals",
16
61
  appliesDuring: "*",
17
- transform: {
18
- js_module: async ({ url, generatedUrl, content }, { scenario }) => {
19
- const replaceMap = {
20
- "process.env.NODE_ENV": `("${
21
- scenario === "dev" || scenario === "test" ? "dev" : "prod"
22
- }")`,
23
- "global": "globalThis",
24
- "__filename": `import.meta.url.slice('file:///'.length)`,
25
- "__dirname": `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`,
26
- }
27
- const { metadata } = await applyBabelPlugins({
28
- babelPlugins: [
29
- [
30
- babelPluginMetadataExpressionPaths,
31
- {
32
- replaceMap,
33
- allowConflictingReplacements: true,
34
- },
35
- ],
36
- ],
37
- url,
38
- generatedUrl,
39
- content,
40
- })
41
- const { expressionPaths } = metadata
42
- const keys = Object.keys(expressionPaths)
43
- if (keys.length === 0) {
44
- return null
45
- }
46
- const magicSource = createMagicSource(content)
47
- keys.forEach((key) => {
48
- expressionPaths[key].forEach((path) => {
49
- magicSource.replace({
50
- start: path.node.start,
51
- end: path.node.end,
52
- replacement: replaceMap[key],
53
- })
54
- })
55
- })
56
- return magicSource.toContentAndSourcemap()
57
- },
62
+ transformUrlContent: {
63
+ js_classic: transformCommonJsGlobals,
64
+ js_module: transformCommonJsGlobals,
58
65
  },
59
66
  }
60
67
  }
@@ -0,0 +1,66 @@
1
+ import { readFileSync } from "node:fs"
2
+ import { urlIsInsideOf, urlToRelativeUrl } from "@jsenv/filesystem"
3
+
4
+ import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
5
+
6
+ export const jsenvPluginFileUrls = () => {
7
+ return [jsenvPluginResolveAbsoluteFileUrls(), jsenvPluginFetchFileUrls()]
8
+ }
9
+
10
+ const jsenvPluginResolveAbsoluteFileUrls = () => {
11
+ return {
12
+ name: "jsenv:resolve_absolute_file_urls",
13
+ appliesDuring: {
14
+ // during dev and test it's a browser running the code
15
+ // so absolute file urls needs to be relativized
16
+ dev: true,
17
+ test: true,
18
+ // during build it's fine to use file:// urls
19
+ build: false,
20
+ },
21
+ resolveUrl: (reference) => {
22
+ if (!reference.specifier.startsWith("/@fs/")) {
23
+ return null
24
+ }
25
+ const fsRootRelativeUrl = reference.specifier.slice("/@fs/".length)
26
+ return `file:///${fsRootRelativeUrl}`
27
+ },
28
+ formatUrl: (reference, context) => {
29
+ if (!reference.generatedUrl.startsWith("file:")) {
30
+ return null
31
+ }
32
+ if (urlIsInsideOf(reference.generatedUrl, context.rootDirectoryUrl)) {
33
+ return `/${urlToRelativeUrl(
34
+ reference.generatedUrl,
35
+ context.rootDirectoryUrl,
36
+ )}`
37
+ }
38
+ return `/@fs/${reference.generatedUrl.slice("file:///".length)}`
39
+ },
40
+ }
41
+ }
42
+
43
+ const jsenvPluginFetchFileUrls = () => {
44
+ return {
45
+ name: "jsenv:fetch_file_urls",
46
+ appliesDuring: "*",
47
+ fetchUrlContent: (urlInfo) => {
48
+ if (!urlInfo.url.startsWith("file:")) {
49
+ return null
50
+ }
51
+ const urlObject = new URL(urlInfo.url)
52
+ const fileBuffer = readFileSync(urlObject)
53
+ const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url)
54
+ if (CONTENT_TYPE.isTextual(contentType)) {
55
+ return {
56
+ contentType,
57
+ content: String(fileBuffer),
58
+ }
59
+ }
60
+ return {
61
+ contentType,
62
+ content: fileBuffer,
63
+ }
64
+ },
65
+ }
66
+ }
@@ -13,12 +13,12 @@ export const jsenvPluginFileSystemMagic = ({
13
13
  return {
14
14
  name: "jsenv:filesystem_magic",
15
15
  appliesDuring: "*",
16
- normalize: ({ parentUrl, url }) => {
16
+ normalizeUrl: (reference) => {
17
17
  // http, https, data, about, etc
18
- if (!url.startsWith("file:")) {
18
+ if (!reference.url.startsWith("file:")) {
19
19
  return null
20
20
  }
21
- const urlObject = new URL(url)
21
+ const urlObject = new URL(reference.url)
22
22
  const { search, hash } = urlObject
23
23
  urlObject.search = ""
24
24
  urlObject.hash = ""
@@ -26,7 +26,10 @@ export const jsenvPluginFileSystemMagic = ({
26
26
  urlObject.href,
27
27
  {
28
28
  magicDirectoryIndex,
29
- magicExtensions: getExtensionsToTry(magicExtensions, parentUrl),
29
+ magicExtensions: getExtensionsToTry(
30
+ magicExtensions,
31
+ reference.parentUrl,
32
+ ),
30
33
  },
31
34
  )
32
35
  if (!filesystemResolution.found) {
@@ -89,7 +89,6 @@ export const installHtmlSupervisor = ({ logs, measurePerf }) => {
89
89
  onExecutionSettled(src, executionResult)
90
90
  if (logs) {
91
91
  console.log(`${type} load ended`)
92
-
93
92
  console.groupEnd()
94
93
  }
95
94
  },
@@ -120,7 +119,9 @@ export const installHtmlSupervisor = ({ logs, measurePerf }) => {
120
119
  console.error(error)
121
120
  }
122
121
  }
123
- console.groupEnd()
122
+ if (logs) {
123
+ console.groupEnd()
124
+ }
124
125
  },
125
126
  )
126
127
  }
@@ -2,27 +2,21 @@
2
2
  * Things happening here
3
3
  * - html supervisor module injection
4
4
  * - scripts are wrapped to be supervised
5
- *
6
- * TODO:
7
- * - if ressource is referenced by ressource hint we should do sthing?
8
- * I think so when we inject ?js_classic
9
5
  */
10
6
 
11
- import { injectQueryParams } from "@jsenv/utils/urls/url_utils.js"
12
7
  import {
13
8
  parseHtmlString,
14
9
  stringifyHtmlAst,
15
10
  visitHtmlAst,
16
11
  getHtmlNodeAttributeByName,
17
12
  removeHtmlNodeAttributeByName,
18
- setHtmlNodeText,
19
- assignHtmlNodeAttributes,
20
13
  parseScriptNode,
21
14
  injectScriptAsEarlyAsPossible,
22
15
  createHtmlNode,
23
16
  htmlNodePosition,
24
- removeHtmlNodeText,
25
17
  getHtmlNodeTextNode,
18
+ removeHtmlNodeText,
19
+ setHtmlNodeGeneratedText,
26
20
  } from "@jsenv/utils/html_ast/html_ast.js"
27
21
  import { generateInlineContentUrl } from "@jsenv/utils/urls/inline_content_url_generator.js"
28
22
 
@@ -45,7 +39,7 @@ export const jsenvPluginHtmlSupervisor = ({
45
39
  dev: true,
46
40
  test: true,
47
41
  },
48
- transform: {
42
+ transformUrlContent: {
49
43
  html: ({ url, content }, { referenceUtils }) => {
50
44
  const htmlAst = parseHtmlString(content)
51
45
  const scriptsToSupervise = []
@@ -64,27 +58,22 @@ export const jsenvPluginHtmlSupervisor = ({
64
58
  lineEnd,
65
59
  columnEnd,
66
60
  })
67
- if (scriptCategory === "classic") {
68
- inlineScriptUrl = injectQueryParams(inlineScriptUrl, {
69
- js_classic: "",
70
- })
71
- }
72
61
  const [inlineScriptReference] = referenceUtils.foundInline({
73
62
  type: "script_src",
63
+ expectedType: { classic: "js_classic", module: "js_module" }[
64
+ scriptCategory
65
+ ],
74
66
  line: line - 1,
75
67
  column,
76
- isOriginal,
68
+ isOriginalPosition: isOriginal,
77
69
  specifier: inlineScriptUrl,
78
- contentType: "application/javascript",
70
+ contentType: "text/javascript",
79
71
  content: textNode.value,
80
72
  })
81
- assignHtmlNodeAttributes(node, {
82
- "src": inlineScriptReference.generatedSpecifier,
83
- "src-generated-from-inline-content": "",
84
- })
85
73
  removeHtmlNodeText(node)
86
74
  scriptsToSupervise.push({
87
75
  node,
76
+ isInline: true,
88
77
  type: scriptCategory,
89
78
  src: inlineScriptReference.generatedSpecifier,
90
79
  })
@@ -105,6 +94,7 @@ export const jsenvPluginHtmlSupervisor = ({
105
94
  const crossorigin = crossoriginAttribute
106
95
  ? crossoriginAttribute.value
107
96
  : undefined
97
+ removeHtmlNodeAttributeByName(node, "src")
108
98
  scriptsToSupervise.push({
109
99
  node,
110
100
  type: scriptCategory,
@@ -151,6 +141,7 @@ export const jsenvPluginHtmlSupervisor = ({
151
141
  }
152
142
  const [htmlSupervisorInstallerFileReference] = referenceUtils.inject({
153
143
  type: "js_import_export",
144
+ expectedType: "js_module",
154
145
  specifier: htmlSupervisorInstallerFileUrl,
155
146
  })
156
147
  injectScriptAsEarlyAsPossible(
@@ -159,25 +150,24 @@ export const jsenvPluginHtmlSupervisor = ({
159
150
  "tagName": "script",
160
151
  "type": "module",
161
152
  "textContent": `
162
- import { installHtmlSupervisor } from ${
163
- htmlSupervisorInstallerFileReference.generatedSpecifier
164
- }
165
- installHtmlSupervisor(${JSON.stringify(
166
- {
167
- logs,
168
- measurePerf,
169
- },
170
- null,
171
- " ",
172
- )})`,
153
+ import { installHtmlSupervisor } from ${
154
+ htmlSupervisorInstallerFileReference.generatedSpecifier
155
+ }
156
+ installHtmlSupervisor(${JSON.stringify(
157
+ {
158
+ logs,
159
+ measurePerf,
160
+ },
161
+ null,
162
+ " ",
163
+ )})`,
173
164
  "injected-by": "jsenv:html_supervisor",
174
165
  }),
175
166
  )
176
167
  const [htmlSupervisorSetupFileReference] = referenceUtils.inject({
177
168
  type: "script_src",
178
- specifier: injectQueryParams(htmlSupervisorSetupFileUrl, {
179
- js_classic: "",
180
- }),
169
+ expectedType: "js_classic",
170
+ specifier: htmlSupervisorSetupFileUrl,
181
171
  })
182
172
  injectScriptAsEarlyAsPossible(
183
173
  htmlAst,
@@ -188,14 +178,9 @@ installHtmlSupervisor(${JSON.stringify(
188
178
  }),
189
179
  )
190
180
  scriptsToSupervise.forEach(
191
- ({ node, type, src, integrity, crossorigin }) => {
192
- removeHtmlNodeAttributeByName(node, "src")
193
- assignHtmlNodeAttributes(node, {
194
- "content-src": src,
195
- })
196
- setHtmlNodeText(
197
- node,
198
- generateCodeToSuperviseScript({
181
+ ({ node, isInline, type, src, integrity, crossorigin }) => {
182
+ setHtmlNodeGeneratedText(node, {
183
+ generatedText: generateCodeToSuperviseScript({
199
184
  type,
200
185
  src,
201
186
  integrity,
@@ -203,7 +188,10 @@ installHtmlSupervisor(${JSON.stringify(
203
188
  htmlSupervisorInstallerSpecifier:
204
189
  htmlSupervisorInstallerFileReference.generatedSpecifier,
205
190
  }),
206
- )
191
+ generatedBy: "jsenv:html_supervisor",
192
+ generatedFromSrc: src,
193
+ generatedFromInlineContent: isInline,
194
+ })
207
195
  },
208
196
  )
209
197
  const htmlModified = stringifyHtmlAst(htmlAst)
@@ -226,8 +214,12 @@ const generateCodeToSuperviseScript = ({
226
214
  }) => {
227
215
  const paramsAsJson = JSON.stringify({ src, integrity, crossorigin })
228
216
  if (type === "module") {
229
- return `import { superviseScriptTypeModule } from ${htmlSupervisorInstallerSpecifier}
230
- superviseScriptTypeModule(${paramsAsJson})`
217
+ return `
218
+ import { superviseScriptTypeModule } from ${htmlSupervisorInstallerSpecifier}
219
+ superviseScriptTypeModule(${paramsAsJson})
220
+ `
231
221
  }
232
- return `window.__html_supervisor__.superviseScript(${paramsAsJson})`
222
+ return `
223
+ window.__html_supervisor__.superviseScript(${paramsAsJson})
224
+ `
233
225
  }