@jsenv/core 27.0.0-alpha.4 → 27.0.0-alpha.40

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 (141) hide show
  1. package/dist/event_source_client.js +549 -0
  2. package/dist/event_source_client.js.map +188 -0
  3. package/dist/html_supervisor_installer.js +1145 -0
  4. package/dist/html_supervisor_installer.js.map +322 -0
  5. package/dist/html_supervisor_setup.js +92 -0
  6. package/dist/html_supervisor_setup.js.map +57 -0
  7. package/main.js +8 -1
  8. package/package.json +22 -21
  9. package/readme.md +4 -12
  10. package/src/build/build.js +731 -433
  11. package/src/build/build_urls_generator.js +55 -21
  12. package/src/build/graph_utils.js +31 -0
  13. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +33 -15
  14. package/src/build/inject_service_worker_urls.js +79 -0
  15. package/src/build/resync_ressource_hints.js +68 -0
  16. package/src/build/start_build_server.js +205 -0
  17. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  18. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  19. package/src/dev/start_dev_server.js +58 -26
  20. package/src/execute/execute.js +30 -4
  21. package/src/execute/run.js +19 -56
  22. package/src/execute/runtimes/browsers/from_playwright.js +201 -147
  23. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  24. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  25. package/src/execute/runtimes/node/node_process.js +280 -39
  26. package/src/jsenv_root_directory_url.js +1 -0
  27. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  28. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +66 -4
  29. package/src/omega/compat/runtime_compat.js +50 -0
  30. package/src/omega/errors.js +51 -58
  31. package/src/omega/fetched_content_compliance.js +24 -0
  32. package/src/omega/file_url_converter.js +8 -50
  33. package/src/omega/kitchen.js +414 -285
  34. package/src/omega/server/file_service.js +21 -22
  35. package/src/omega/url_graph/url_graph_load.js +14 -7
  36. package/src/omega/url_graph/url_graph_report.js +17 -15
  37. package/src/omega/url_graph/url_info_transformations.js +17 -5
  38. package/src/omega/url_graph.js +33 -10
  39. package/src/omega/web_workers.js +42 -0
  40. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  41. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  42. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  43. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  44. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +46 -0
  45. package/src/{dev/plugins/autoreload/jsenv_plugin_autoreload.js → plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js} +31 -172
  46. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +27 -0
  47. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  48. package/src/plugins/bundling/css/bundle_css.js +21 -0
  49. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  50. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +120 -79
  51. package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
  52. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  53. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  54. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +8 -5
  55. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  56. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  57. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
  58. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
  59. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  60. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  61. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +52 -55
  62. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  63. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  64. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  65. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  66. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +101 -0
  67. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  68. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  69. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  70. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
  71. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +67 -0
  72. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  73. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  74. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
  75. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  76. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  77. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +296 -0
  78. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  79. package/src/plugins/minification/css/minify_css.js +9 -0
  80. package/src/plugins/minification/html/minify_html.js +15 -0
  81. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  82. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  83. package/src/plugins/minification/json/minify_json.js +8 -0
  84. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +146 -0
  85. package/src/{omega → plugins}/plugin_controller.js +39 -11
  86. package/src/plugins/plugins.js +89 -0
  87. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  88. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  89. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  90. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  91. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +183 -0
  92. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +256 -0
  93. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +93 -0
  94. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  95. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  96. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  97. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +4 -22
  98. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  99. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +37 -21
  100. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  101. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  102. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  103. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  104. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  105. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  106. package/src/plugins/transpilation/fetch_original_url_info.js +30 -0
  107. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +200 -0
  108. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +70 -0
  109. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +44 -0
  110. package/src/plugins/url_references/css/css_urls.js +49 -0
  111. package/src/plugins/url_references/html/html_urls.js +273 -0
  112. package/src/plugins/url_references/js/js_urls.js +43 -0
  113. package/src/plugins/url_references/jsenv_plugin_imports_analysis.js +46 -0
  114. package/src/plugins/url_references/jsenv_plugin_url_analysis.js +18 -0
  115. package/src/plugins/url_references/jsenv_plugin_url_references.js +6 -0
  116. package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
  117. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  118. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +12 -15
  119. package/src/test/execute_plan.js +28 -11
  120. package/src/test/execute_test_plan.js +23 -8
  121. package/src/test/logs_file_execution.js +8 -7
  122. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  123. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  124. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  125. package/src/execute/runtimes/node/controlled_process.js +0 -316
  126. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  127. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  128. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  129. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  130. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  131. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  132. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  133. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  134. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  135. package/src/omega/core_plugins.js +0 -39
  136. package/src/omega/runtime_support/runtime_support.js +0 -20
  137. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  138. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  139. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  140. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  141. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -11,50 +11,63 @@ 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
+ if (
16
+ !urlInfo.content.includes("process.env.NODE_ENV") &&
17
+ !urlInfo.content.includes("__filename") &&
18
+ !urlInfo.content.includes("__dirname")
19
+ ) {
20
+ return null
21
+ }
22
+ const isJsModule = urlInfo.type === "js_module"
23
+ const replaceMap = {
24
+ "process.env.NODE_ENV": `("${
25
+ scenario === "dev" || scenario === "test" ? "dev" : "prod"
26
+ }")`,
27
+ "global": "globalThis",
28
+ "__filename": isJsModule
29
+ ? `import.meta.url.slice('file:///'.length)`
30
+ : `document.currentScript.src`,
31
+ "__dirname": isJsModule
32
+ ? `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`
33
+ : `new URL('./', document.currentScript.src).href`,
34
+ }
35
+ const { metadata } = await applyBabelPlugins({
36
+ babelPlugins: [
37
+ [
38
+ babelPluginMetadataExpressionPaths,
39
+ {
40
+ replaceMap,
41
+ allowConflictingReplacements: true,
42
+ },
43
+ ],
44
+ ],
45
+ urlInfo,
46
+ })
47
+ const { expressionPaths } = metadata
48
+ const keys = Object.keys(expressionPaths)
49
+ if (keys.length === 0) {
50
+ return null
51
+ }
52
+ const magicSource = createMagicSource(urlInfo.content)
53
+ keys.forEach((key) => {
54
+ expressionPaths[key].forEach((path) => {
55
+ magicSource.replace({
56
+ start: path.node.start,
57
+ end: path.node.end,
58
+ replacement: replaceMap[key],
59
+ })
60
+ })
61
+ })
62
+ return magicSource.toContentAndSourcemap()
63
+ }
64
+
14
65
  return {
15
66
  name: "jsenv:commonjs_globals",
16
67
  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
- },
68
+ transformUrlContent: {
69
+ js_classic: transformCommonJsGlobals,
70
+ js_module: transformCommonJsGlobals,
58
71
  },
59
72
  }
60
73
  }
@@ -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
+ }
@@ -6,19 +6,19 @@ import { urlToExtension } from "@jsenv/filesystem"
6
6
  import { applyFileSystemMagicResolution } from "@jsenv/node-esm-resolution"
7
7
 
8
8
  export const jsenvPluginFileSystemMagic = ({
9
- magicExtensions = ["inherit"],
9
+ magicExtensions = ["inherit", ".js"],
10
10
  magicDirectoryIndex = true,
11
11
  preservesSymlink = true,
12
12
  } = {}) => {
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,42 +2,41 @@
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"
7
+ import { urlIsInsideOf } from "@jsenv/filesystem"
8
+
12
9
  import {
13
10
  parseHtmlString,
14
11
  stringifyHtmlAst,
15
12
  visitHtmlAst,
16
13
  getHtmlNodeAttributeByName,
17
14
  removeHtmlNodeAttributeByName,
18
- setHtmlNodeText,
19
- assignHtmlNodeAttributes,
20
15
  parseScriptNode,
21
16
  injectScriptAsEarlyAsPossible,
22
17
  createHtmlNode,
23
18
  htmlNodePosition,
24
- removeHtmlNodeText,
25
19
  getHtmlNodeTextNode,
20
+ removeHtmlNodeText,
21
+ setHtmlNodeGeneratedText,
26
22
  } from "@jsenv/utils/html_ast/html_ast.js"
27
23
  import { generateInlineContentUrl } from "@jsenv/utils/urls/inline_content_url_generator.js"
24
+ import { jsenvRootDirectoryUrl } from "@jsenv/core/src/jsenv_root_directory_url.js"
28
25
 
29
26
  export const jsenvPluginHtmlSupervisor = ({
27
+ rootDirectoryUrl,
30
28
  logs = false,
31
29
  measurePerf = false,
32
- } = {}) => {
33
- const htmlSupervisorSetupFileUrl = new URL(
34
- "./client/html_supervisor_setup.js",
35
- import.meta.url,
36
- ).href
37
- const htmlSupervisorInstallerFileUrl = new URL(
38
- "./client/html_supervisor_installer.js",
39
- import.meta.url,
40
- ).href
30
+ }) => {
31
+ const preferSourceFiles =
32
+ rootDirectoryUrl === jsenvRootDirectoryUrl ||
33
+ urlIsInsideOf(rootDirectoryUrl, jsenvRootDirectoryUrl)
34
+ const htmlSupervisorSetupFileUrl = preferSourceFiles
35
+ ? new URL("./client/html_supervisor_setup.js", import.meta.url).href
36
+ : new URL("./dist/html_supervisor_setup.js", jsenvRootDirectoryUrl)
37
+ const htmlSupervisorInstallerFileUrl = preferSourceFiles
38
+ ? new URL("./client/html_supervisor_installer.js", import.meta.url).href
39
+ : new URL("./dist/html_supervisor_installer.js", jsenvRootDirectoryUrl)
41
40
 
42
41
  return {
43
42
  name: "jsenv:html_supervisor",
@@ -45,7 +44,7 @@ export const jsenvPluginHtmlSupervisor = ({
45
44
  dev: true,
46
45
  test: true,
47
46
  },
48
- transform: {
47
+ transformUrlContent: {
49
48
  html: ({ url, content }, { referenceUtils }) => {
50
49
  const htmlAst = parseHtmlString(content)
51
50
  const scriptsToSupervise = []
@@ -64,27 +63,22 @@ export const jsenvPluginHtmlSupervisor = ({
64
63
  lineEnd,
65
64
  columnEnd,
66
65
  })
67
- if (scriptCategory === "classic") {
68
- inlineScriptUrl = injectQueryParams(inlineScriptUrl, {
69
- js_classic: "",
70
- })
71
- }
72
66
  const [inlineScriptReference] = referenceUtils.foundInline({
73
67
  type: "script_src",
68
+ expectedType: { classic: "js_classic", module: "js_module" }[
69
+ scriptCategory
70
+ ],
74
71
  line: line - 1,
75
72
  column,
76
- isOriginal,
73
+ isOriginalPosition: isOriginal,
77
74
  specifier: inlineScriptUrl,
78
- contentType: "application/javascript",
75
+ contentType: "text/javascript",
79
76
  content: textNode.value,
80
77
  })
81
- assignHtmlNodeAttributes(node, {
82
- "src": inlineScriptReference.generatedSpecifier,
83
- "src-generated-from-inline-content": "",
84
- })
85
78
  removeHtmlNodeText(node)
86
79
  scriptsToSupervise.push({
87
80
  node,
81
+ isInline: true,
88
82
  type: scriptCategory,
89
83
  src: inlineScriptReference.generatedSpecifier,
90
84
  })
@@ -105,6 +99,7 @@ export const jsenvPluginHtmlSupervisor = ({
105
99
  const crossorigin = crossoriginAttribute
106
100
  ? crossoriginAttribute.value
107
101
  : undefined
102
+ removeHtmlNodeAttributeByName(node, "src")
108
103
  scriptsToSupervise.push({
109
104
  node,
110
105
  type: scriptCategory,
@@ -151,6 +146,7 @@ export const jsenvPluginHtmlSupervisor = ({
151
146
  }
152
147
  const [htmlSupervisorInstallerFileReference] = referenceUtils.inject({
153
148
  type: "js_import_export",
149
+ expectedType: "js_module",
154
150
  specifier: htmlSupervisorInstallerFileUrl,
155
151
  })
156
152
  injectScriptAsEarlyAsPossible(
@@ -159,25 +155,24 @@ export const jsenvPluginHtmlSupervisor = ({
159
155
  "tagName": "script",
160
156
  "type": "module",
161
157
  "textContent": `
162
- import { installHtmlSupervisor } from ${
163
- htmlSupervisorInstallerFileReference.generatedSpecifier
164
- }
165
- installHtmlSupervisor(${JSON.stringify(
166
- {
167
- logs,
168
- measurePerf,
169
- },
170
- null,
171
- " ",
172
- )})`,
158
+ import { installHtmlSupervisor } from ${
159
+ htmlSupervisorInstallerFileReference.generatedSpecifier
160
+ }
161
+ installHtmlSupervisor(${JSON.stringify(
162
+ {
163
+ logs,
164
+ measurePerf,
165
+ },
166
+ null,
167
+ " ",
168
+ )})`,
173
169
  "injected-by": "jsenv:html_supervisor",
174
170
  }),
175
171
  )
176
172
  const [htmlSupervisorSetupFileReference] = referenceUtils.inject({
177
173
  type: "script_src",
178
- specifier: injectQueryParams(htmlSupervisorSetupFileUrl, {
179
- js_classic: "",
180
- }),
174
+ expectedType: "js_classic",
175
+ specifier: htmlSupervisorSetupFileUrl,
181
176
  })
182
177
  injectScriptAsEarlyAsPossible(
183
178
  htmlAst,
@@ -188,14 +183,9 @@ installHtmlSupervisor(${JSON.stringify(
188
183
  }),
189
184
  )
190
185
  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({
186
+ ({ node, isInline, type, src, integrity, crossorigin }) => {
187
+ setHtmlNodeGeneratedText(node, {
188
+ generatedText: generateCodeToSuperviseScript({
199
189
  type,
200
190
  src,
201
191
  integrity,
@@ -203,7 +193,10 @@ installHtmlSupervisor(${JSON.stringify(
203
193
  htmlSupervisorInstallerSpecifier:
204
194
  htmlSupervisorInstallerFileReference.generatedSpecifier,
205
195
  }),
206
- )
196
+ generatedBy: "jsenv:html_supervisor",
197
+ generatedFromSrc: src,
198
+ generatedFromInlineContent: isInline,
199
+ })
207
200
  },
208
201
  )
209
202
  const htmlModified = stringifyHtmlAst(htmlAst)
@@ -226,8 +219,12 @@ const generateCodeToSuperviseScript = ({
226
219
  }) => {
227
220
  const paramsAsJson = JSON.stringify({ src, integrity, crossorigin })
228
221
  if (type === "module") {
229
- return `import { superviseScriptTypeModule } from ${htmlSupervisorInstallerSpecifier}
230
- superviseScriptTypeModule(${paramsAsJson})`
222
+ return `
223
+ import { superviseScriptTypeModule } from ${htmlSupervisorInstallerSpecifier}
224
+ superviseScriptTypeModule(${paramsAsJson})
225
+ `
231
226
  }
232
- return `window.__html_supervisor__.superviseScript(${paramsAsJson})`
227
+ return `
228
+ window.__html_supervisor__.superviseScript(${paramsAsJson})
229
+ `
233
230
  }
@@ -0,0 +1,12 @@
1
+ export const jsenvPluginHttpUrls = () => {
2
+ return {
3
+ name: "jsenv:http_urls",
4
+ appliesDuring: "*",
5
+ fetchUrlContent: (urlInfo) => {
6
+ if (urlInfo.url.startsWith("http") || urlInfo.url.startsWith("https")) {
7
+ return { external: true }
8
+ }
9
+ return null
10
+ },
11
+ }
12
+ }
@@ -16,13 +16,12 @@ export const babelPluginMetadataImportMetaHot = () => {
16
16
  }
17
17
  }
18
18
  const collectImportMetaProperties = (programPath) => {
19
- let importMetaHotDetected = false
19
+ const importMetaHotPaths = []
20
20
  let hotDecline = false
21
21
  let hotAcceptSelf = false
22
22
  let hotAcceptDependencies = []
23
23
  programPath.traverse({
24
24
  MemberExpression(path) {
25
- if (importMetaHotDetected) return
26
25
  const { node } = path
27
26
  const { object } = node
28
27
  if (object.type !== "MetaProperty") {
@@ -35,7 +34,7 @@ const collectImportMetaProperties = (programPath) => {
35
34
  const { property } = node
36
35
  const { name } = property
37
36
  if (name === "hot") {
38
- importMetaHotDetected = true
37
+ importMetaHotPaths.push(path)
39
38
  }
40
39
  },
41
40
  CallExpression(path) {
@@ -64,7 +63,7 @@ const collectImportMetaProperties = (programPath) => {
64
63
  )
65
64
  }
66
65
  return {
67
- specifierPath: firstArgPath.get(index),
66
+ specifierPath: firstArgPath.get(String(index)),
68
67
  }
69
68
  })
70
69
  return
@@ -79,7 +78,7 @@ const collectImportMetaProperties = (programPath) => {
79
78
  },
80
79
  })
81
80
  return {
82
- importMetaHotDetected,
81
+ importMetaHotPaths,
83
82
  hotDecline,
84
83
  hotAcceptSelf,
85
84
  hotAcceptDependencies,
@@ -40,7 +40,9 @@ export const createImportMetaHot = (importMetaUrl) => {
40
40
  })
41
41
  return
42
42
  }
43
- throw new Error(`invalid call to hot.accept()`)
43
+ throw new Error(
44
+ `invalid call to import.meta.hot.accept(), received ${firstArg}`,
45
+ )
44
46
  },
45
47
  dispose: (callback) => {
46
48
  addUrlMeta(url, {
@@ -53,7 +53,7 @@ export const collectHotDataFromHtmlAst = (htmlAst) => {
53
53
  })
54
54
  visitUrlSpecifierAttribute({
55
55
  node,
56
- attributeName: "content-href",
56
+ attributeName: "generated-from-href",
57
57
  hotAccepted,
58
58
  })
59
59
  }
@@ -65,7 +65,7 @@ export const collectHotDataFromHtmlAst = (htmlAst) => {
65
65
  })
66
66
  visitUrlSpecifierAttribute({
67
67
  node,
68
- attributeName: "content-src",
68
+ attributeName: "generated-from-src",
69
69
  hotAccepted,
70
70
  })
71
71
  }
@@ -0,0 +1,101 @@
1
+ import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
2
+ import { parseHtmlString } from "@jsenv/utils/html_ast/html_ast.js"
3
+ import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
4
+
5
+ import { collectHotDataFromHtmlAst } from "./html_hot_dependencies.js"
6
+ import { babelPluginMetadataImportMetaHot } from "./babel_plugin_metadata_import_meta_hot.js"
7
+
8
+ const importMetaHotClientFileUrl = new URL(
9
+ "./client/import_meta_hot.js",
10
+ import.meta.url,
11
+ ).href
12
+
13
+ export const jsenvPluginImportMetaHot = () => {
14
+ return {
15
+ name: "jsenv:import_meta_hot",
16
+ appliesDuring: "*",
17
+ transformUrlContent: {
18
+ html: (htmlUrlInfo, context) => {
19
+ // during build we don't really care to parse html hot dependencies
20
+ if (context.scenario === "build") {
21
+ return
22
+ }
23
+ const htmlAst = parseHtmlString(htmlUrlInfo.content)
24
+ const { hotReferences } = collectHotDataFromHtmlAst(htmlAst)
25
+ htmlUrlInfo.data.hotDecline = false
26
+ htmlUrlInfo.data.hotAcceptSelf = false
27
+ htmlUrlInfo.data.hotAcceptDependencies = hotReferences.map(
28
+ ({ type, specifier }) => {
29
+ const [reference] = context.referenceUtils.found({
30
+ type,
31
+ specifier,
32
+ })
33
+ return reference.url
34
+ },
35
+ )
36
+ },
37
+ css: (cssUrlInfo) => {
38
+ cssUrlInfo.data.hotDecline = false
39
+ cssUrlInfo.data.hotAcceptSelf = false
40
+ cssUrlInfo.data.hotAcceptDependencies = []
41
+ },
42
+ js_module: async (urlInfo, context) => {
43
+ if (!urlInfo.content.includes("import.meta.hot")) {
44
+ return null
45
+ }
46
+ const { metadata } = await applyBabelPlugins({
47
+ babelPlugins: [babelPluginMetadataImportMetaHot],
48
+ urlInfo,
49
+ })
50
+ const {
51
+ importMetaHotPaths,
52
+ hotDecline,
53
+ hotAcceptSelf,
54
+ hotAcceptDependencies,
55
+ } = metadata
56
+ urlInfo.data.hotDecline = hotDecline
57
+ urlInfo.data.hotAcceptSelf = hotAcceptSelf
58
+ urlInfo.data.hotAcceptDependencies = hotAcceptDependencies
59
+ if (importMetaHotPaths.length === 0) {
60
+ return null
61
+ }
62
+ if (context.scenario === "build") {
63
+ return removeImportMetaHots(urlInfo, importMetaHotPaths)
64
+ }
65
+ return injectImportMetaHot(urlInfo, context)
66
+ },
67
+ },
68
+ }
69
+ }
70
+
71
+ const removeImportMetaHots = (urlInfo, importMetaHotPaths) => {
72
+ const magicSource = createMagicSource(urlInfo.content)
73
+ importMetaHotPaths.forEach((path) => {
74
+ magicSource.replace({
75
+ start: path.node.start,
76
+ end: path.node.end,
77
+ replacement: "undefined",
78
+ })
79
+ })
80
+ return magicSource.toContentAndSourcemap()
81
+ }
82
+
83
+ // For some reason using magic source here produce
84
+ // better sourcemap than doing the equivalent with babel
85
+ // I suspect it's because I was doing injectAstAfterImport(programPath, ast.program.body[0])
86
+ // which is likely not well supported by babel
87
+ const injectImportMetaHot = (urlInfo, context) => {
88
+ const [importMetaHotClientFileReference] = context.referenceUtils.inject({
89
+ parentUrl: urlInfo.url,
90
+ type: "js_import_export",
91
+ expectedType: "js_module",
92
+ specifier: importMetaHotClientFileUrl,
93
+ })
94
+ const magicSource = createMagicSource(urlInfo.content)
95
+ magicSource.prepend(
96
+ `import { createImportMetaHot } from ${importMetaHotClientFileReference.generatedSpecifier}
97
+ import.meta.hot = createImportMetaHot(import.meta.url)
98
+ `,
99
+ )
100
+ return magicSource.toContentAndSourcemap()
101
+ }