@jsenv/core 27.0.0-alpha.5 → 27.0.0-alpha.50

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 (146) hide show
  1. package/dist/event_source_client.js +545 -0
  2. package/dist/event_source_client.js.map +187 -0
  3. package/dist/html_supervisor_installer.js +1236 -0
  4. package/dist/html_supervisor_installer.js.map +337 -0
  5. package/dist/html_supervisor_setup.js +95 -0
  6. package/dist/html_supervisor_setup.js.map +57 -0
  7. package/dist/import_meta_hot.js +86 -0
  8. package/dist/import_meta_hot.js.map +42 -0
  9. package/main.js +8 -1
  10. package/package.json +22 -21
  11. package/readme.md +4 -12
  12. package/src/build/build.js +749 -437
  13. package/src/build/build_urls_generator.js +56 -22
  14. package/src/build/graph_utils.js +31 -0
  15. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +33 -15
  16. package/src/build/inject_service_worker_urls.js +79 -0
  17. package/src/build/resync_ressource_hints.js +68 -0
  18. package/src/build/start_build_server.js +255 -0
  19. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  20. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  21. package/src/dev/start_dev_server.js +136 -30
  22. package/src/execute/execute.js +31 -6
  23. package/src/execute/run.js +19 -56
  24. package/src/execute/runtimes/browsers/from_playwright.js +201 -147
  25. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  26. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  27. package/src/execute/runtimes/node/node_process.js +280 -39
  28. package/src/jsenv_root_directory_url.js +1 -0
  29. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  30. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +66 -4
  31. package/src/omega/compat/runtime_compat.js +50 -0
  32. package/src/omega/errors.js +51 -58
  33. package/src/omega/fetched_content_compliance.js +24 -0
  34. package/src/omega/file_url_converter.js +8 -50
  35. package/src/omega/kitchen.js +482 -292
  36. package/src/omega/omega_server.js +2 -3
  37. package/src/omega/server/file_service.js +38 -25
  38. package/src/omega/server/user_agent.js +4 -2
  39. package/src/omega/url_graph/url_graph_load.js +14 -7
  40. package/src/omega/url_graph/url_graph_report.js +17 -15
  41. package/src/omega/url_graph/url_info_transformations.js +26 -9
  42. package/src/omega/url_graph.js +91 -16
  43. package/src/omega/web_workers.js +42 -0
  44. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  45. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  46. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  47. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  48. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +46 -0
  49. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +204 -0
  50. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +27 -0
  51. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  52. package/src/plugins/bundling/css/bundle_css.js +21 -0
  53. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  54. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +150 -79
  55. package/src/plugins/bundling/jsenv_plugin_bundling.js +54 -0
  56. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  57. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  58. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +8 -5
  59. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  60. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  61. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +242 -0
  62. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +79 -0
  63. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  64. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  65. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +83 -58
  66. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  67. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  68. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  69. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  70. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +105 -0
  71. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  72. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  73. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  74. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +39 -33
  75. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +67 -0
  76. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  77. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  78. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +65 -44
  79. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  80. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  81. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +296 -0
  82. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  83. package/src/plugins/minification/css/minify_css.js +9 -0
  84. package/src/plugins/minification/html/minify_html.js +15 -0
  85. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  86. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  87. package/src/plugins/minification/json/minify_json.js +8 -0
  88. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +146 -0
  89. package/src/{omega → plugins}/plugin_controller.js +42 -11
  90. package/src/plugins/plugins.js +91 -0
  91. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  92. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  93. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  94. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  95. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +183 -0
  96. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +256 -0
  97. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +55 -0
  98. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  99. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  100. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  101. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +4 -22
  102. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  103. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +37 -21
  104. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  105. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  106. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  107. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  108. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  109. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  110. package/src/plugins/transpilation/fetch_original_url_info.js +30 -0
  111. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +181 -0
  112. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +70 -0
  113. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +44 -0
  114. package/src/plugins/url_analysis/css/css_urls.js +42 -0
  115. package/src/plugins/url_analysis/html/html_urls.js +273 -0
  116. package/src/plugins/url_analysis/js/js_urls.js +67 -0
  117. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +18 -0
  118. package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +17 -0
  119. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  120. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +12 -15
  121. package/src/test/execute_plan.js +30 -18
  122. package/src/test/execute_test_plan.js +23 -8
  123. package/src/test/logs_file_execution.js +8 -7
  124. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  125. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  126. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +0 -374
  127. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  128. package/src/execute/runtimes/node/controlled_process.js +0 -316
  129. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  130. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_installer.js +0 -168
  131. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_setup.js +0 -77
  132. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  133. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  134. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  135. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  136. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  137. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  138. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  139. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  140. package/src/omega/core_plugins.js +0 -39
  141. package/src/omega/runtime_support/runtime_support.js +0 -20
  142. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  143. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  144. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  145. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  146. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -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).href
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).href
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",
74
- line: line - 1,
75
- column,
76
- isOriginal,
68
+ expectedType: { classic: "js_classic", module: "js_module" }[
69
+ scriptCategory
70
+ ],
71
+ isOriginalPosition: isOriginal,
72
+ specifierLine: line - 1,
73
+ specifierColumn: column,
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,10 +99,17 @@ export const jsenvPluginHtmlSupervisor = ({
105
99
  const crossorigin = crossoriginAttribute
106
100
  ? crossoriginAttribute.value
107
101
  : undefined
102
+ const deferAttribute = getHtmlNodeAttributeByName(node, "crossorigin")
103
+ const defer = deferAttribute ? deferAttribute.value : undefined
104
+ const asyncAttribute = getHtmlNodeAttributeByName(node, "crossorigin")
105
+ const async = asyncAttribute ? asyncAttribute.value : undefined
106
+ removeHtmlNodeAttributeByName(node, "src")
108
107
  scriptsToSupervise.push({
109
108
  node,
110
109
  type: scriptCategory,
111
110
  src: srcAttribute.value,
111
+ defer,
112
+ async,
112
113
  integrity,
113
114
  crossorigin,
114
115
  })
@@ -151,6 +152,7 @@ export const jsenvPluginHtmlSupervisor = ({
151
152
  }
152
153
  const [htmlSupervisorInstallerFileReference] = referenceUtils.inject({
153
154
  type: "js_import_export",
155
+ expectedType: "js_module",
154
156
  specifier: htmlSupervisorInstallerFileUrl,
155
157
  })
156
158
  injectScriptAsEarlyAsPossible(
@@ -159,25 +161,24 @@ export const jsenvPluginHtmlSupervisor = ({
159
161
  "tagName": "script",
160
162
  "type": "module",
161
163
  "textContent": `
162
- import { installHtmlSupervisor } from ${
163
- htmlSupervisorInstallerFileReference.generatedSpecifier
164
- }
165
- installHtmlSupervisor(${JSON.stringify(
166
- {
167
- logs,
168
- measurePerf,
169
- },
170
- null,
171
- " ",
172
- )})`,
164
+ import { installHtmlSupervisor } from ${
165
+ htmlSupervisorInstallerFileReference.generatedSpecifier
166
+ }
167
+ installHtmlSupervisor(${JSON.stringify(
168
+ {
169
+ logs,
170
+ measurePerf,
171
+ },
172
+ null,
173
+ " ",
174
+ )})`,
173
175
  "injected-by": "jsenv:html_supervisor",
174
176
  }),
175
177
  )
176
178
  const [htmlSupervisorSetupFileReference] = referenceUtils.inject({
177
179
  type: "script_src",
178
- specifier: injectQueryParams(htmlSupervisorSetupFileUrl, {
179
- js_classic: "",
180
- }),
180
+ expectedType: "js_classic",
181
+ specifier: htmlSupervisorSetupFileUrl,
181
182
  })
182
183
  injectScriptAsEarlyAsPossible(
183
184
  htmlAst,
@@ -188,22 +189,32 @@ installHtmlSupervisor(${JSON.stringify(
188
189
  }),
189
190
  )
190
191
  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({
192
+ ({
193
+ node,
194
+ isInline,
195
+ type,
196
+ src,
197
+ defer,
198
+ async,
199
+ integrity,
200
+ crossorigin,
201
+ }) => {
202
+ setHtmlNodeGeneratedText(node, {
203
+ generatedText: generateCodeToSuperviseScript({
199
204
  type,
200
205
  src,
206
+ isInline,
207
+ defer,
208
+ async,
201
209
  integrity,
202
210
  crossorigin,
203
211
  htmlSupervisorInstallerSpecifier:
204
212
  htmlSupervisorInstallerFileReference.generatedSpecifier,
205
213
  }),
206
- )
214
+ generatedBy: "jsenv:html_supervisor",
215
+ generatedFromSrc: src,
216
+ generatedFromInlineContent: isInline,
217
+ })
207
218
  },
208
219
  )
209
220
  const htmlModified = stringifyHtmlAst(htmlAst)
@@ -220,14 +231,28 @@ installHtmlSupervisor(${JSON.stringify(
220
231
  const generateCodeToSuperviseScript = ({
221
232
  type,
222
233
  src,
234
+ isInline,
235
+ defer,
236
+ async,
223
237
  integrity,
224
238
  crossorigin,
225
239
  htmlSupervisorInstallerSpecifier,
226
240
  }) => {
227
- const paramsAsJson = JSON.stringify({ src, integrity, crossorigin })
241
+ const paramsAsJson = JSON.stringify({
242
+ src,
243
+ isInline,
244
+ defer,
245
+ async,
246
+ integrity,
247
+ crossorigin,
248
+ })
228
249
  if (type === "module") {
229
- return `import { superviseScriptTypeModule } from ${htmlSupervisorInstallerSpecifier}
230
- superviseScriptTypeModule(${paramsAsJson})`
250
+ return `
251
+ import { superviseScriptTypeModule } from ${htmlSupervisorInstallerSpecifier}
252
+ superviseScriptTypeModule(${paramsAsJson})
253
+ `
231
254
  }
232
- return `window.__html_supervisor__.superviseScript(${paramsAsJson})`
255
+ return `
256
+ window.__html_supervisor__.superviseScript(${paramsAsJson})
257
+ `
233
258
  }
@@ -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,105 @@
1
+ import { urlIsInsideOf } from "@jsenv/filesystem"
2
+
3
+ import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
4
+ import { parseHtmlString } from "@jsenv/utils/html_ast/html_ast.js"
5
+ import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
6
+ import { jsenvRootDirectoryUrl } from "@jsenv/core/src/jsenv_root_directory_url.js"
7
+ import { collectHotDataFromHtmlAst } from "./html_hot_dependencies.js"
8
+ import { babelPluginMetadataImportMetaHot } from "./babel_plugin_metadata_import_meta_hot.js"
9
+
10
+ export const jsenvPluginImportMetaHot = ({ rootDirectoryUrl }) => {
11
+ const preferSourceFiles =
12
+ rootDirectoryUrl === jsenvRootDirectoryUrl ||
13
+ urlIsInsideOf(rootDirectoryUrl, jsenvRootDirectoryUrl)
14
+ const importMetaHotClientFileUrl = preferSourceFiles
15
+ ? new URL("./client/import_meta_hot.js", import.meta.url).href
16
+ : new URL("./dist/import_meta_hot.js", jsenvRootDirectoryUrl).href
17
+
18
+ return {
19
+ name: "jsenv:import_meta_hot",
20
+ appliesDuring: "*",
21
+ transformUrlContent: {
22
+ html: (htmlUrlInfo, context) => {
23
+ // during build we don't really care to parse html hot dependencies
24
+ if (context.scenario === "build") {
25
+ return
26
+ }
27
+ const htmlAst = parseHtmlString(htmlUrlInfo.content)
28
+ const { hotReferences } = collectHotDataFromHtmlAst(htmlAst)
29
+ htmlUrlInfo.data.hotDecline = false
30
+ htmlUrlInfo.data.hotAcceptSelf = false
31
+ htmlUrlInfo.data.hotAcceptDependencies = hotReferences.map(
32
+ ({ type, specifier }) => {
33
+ const [reference] = context.referenceUtils.found({
34
+ type,
35
+ specifier,
36
+ })
37
+ return reference.url
38
+ },
39
+ )
40
+ },
41
+ css: (cssUrlInfo) => {
42
+ cssUrlInfo.data.hotDecline = false
43
+ cssUrlInfo.data.hotAcceptSelf = false
44
+ cssUrlInfo.data.hotAcceptDependencies = []
45
+ },
46
+ js_module: async (urlInfo, context) => {
47
+ if (!urlInfo.content.includes("import.meta.hot")) {
48
+ return null
49
+ }
50
+ const { metadata } = await applyBabelPlugins({
51
+ babelPlugins: [babelPluginMetadataImportMetaHot],
52
+ urlInfo,
53
+ })
54
+ const {
55
+ importMetaHotPaths,
56
+ hotDecline,
57
+ hotAcceptSelf,
58
+ hotAcceptDependencies,
59
+ } = metadata
60
+ urlInfo.data.hotDecline = hotDecline
61
+ urlInfo.data.hotAcceptSelf = hotAcceptSelf
62
+ urlInfo.data.hotAcceptDependencies = hotAcceptDependencies
63
+ if (importMetaHotPaths.length === 0) {
64
+ return null
65
+ }
66
+ if (context.scenario === "build") {
67
+ return removeImportMetaHots(urlInfo, importMetaHotPaths)
68
+ }
69
+ return injectImportMetaHot(urlInfo, context, importMetaHotClientFileUrl)
70
+ },
71
+ },
72
+ }
73
+ }
74
+
75
+ const removeImportMetaHots = (urlInfo, importMetaHotPaths) => {
76
+ const magicSource = createMagicSource(urlInfo.content)
77
+ importMetaHotPaths.forEach((path) => {
78
+ magicSource.replace({
79
+ start: path.node.start,
80
+ end: path.node.end,
81
+ replacement: "undefined",
82
+ })
83
+ })
84
+ return magicSource.toContentAndSourcemap()
85
+ }
86
+
87
+ // For some reason using magic source here produce
88
+ // better sourcemap than doing the equivalent with babel
89
+ // I suspect it's because I was doing injectAstAfterImport(programPath, ast.program.body[0])
90
+ // which is likely not well supported by babel
91
+ const injectImportMetaHot = (urlInfo, context, importMetaHotClientFileUrl) => {
92
+ const [importMetaHotClientFileReference] = context.referenceUtils.inject({
93
+ parentUrl: urlInfo.url,
94
+ type: "js_import_export",
95
+ expectedType: "js_module",
96
+ specifier: importMetaHotClientFileUrl,
97
+ })
98
+ const magicSource = createMagicSource(urlInfo.content)
99
+ magicSource.prepend(
100
+ `import { createImportMetaHot } from ${importMetaHotClientFileReference.generatedSpecifier}
101
+ import.meta.hot = createImportMetaHot(import.meta.url)
102
+ `,
103
+ )
104
+ return magicSource.toContentAndSourcemap()
105
+ }
@@ -12,18 +12,22 @@
12
12
  import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
13
13
  import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
14
14
 
15
- import { collectProgramImportMetas } from "@jsenv/utils/js_ast/program_import_metas.js"
16
-
17
15
  export const jsenvPluginImportMetaScenarios = () => {
18
16
  return {
19
17
  name: "jsenv:import_meta_scenario",
20
18
  appliesDuring: "*",
21
- transform: {
22
- js_module: async ({ url, content }, { scenario }) => {
19
+ transformUrlContent: {
20
+ js_module: async (urlInfo, { scenario }) => {
21
+ if (
22
+ !urlInfo.content.includes("import.meta.dev") &&
23
+ !urlInfo.content.includes("import.meta.test") &&
24
+ !urlInfo.content.includes("import.meta.build")
25
+ ) {
26
+ return null
27
+ }
23
28
  const { metadata } = await applyBabelPlugins({
24
29
  babelPlugins: [babelPluginMetadataImportMetaScenarios],
25
- url,
26
- content,
30
+ urlInfo,
27
31
  })
28
32
  const { dev = [], test = [], build = [] } = metadata.importMetaScenarios
29
33
  const replacements = []
@@ -59,7 +63,7 @@ export const jsenvPluginImportMetaScenarios = () => {
59
63
  replace(path, "true")
60
64
  })
61
65
  }
62
- const magicSource = createMagicSource(content)
66
+ const magicSource = createMagicSource(urlInfo.content)
63
67
  replacements.forEach(({ path, value }) => {
64
68
  magicSource.replace({
65
69
  start: path.node.start,
@@ -78,7 +82,28 @@ const babelPluginMetadataImportMetaScenarios = () => {
78
82
  name: "metadata-import-meta-scenarios",
79
83
  visitor: {
80
84
  Program(programPath, state) {
81
- const importMetas = collectProgramImportMetas(programPath)
85
+ const importMetas = {}
86
+ programPath.traverse({
87
+ MemberExpression(path) {
88
+ const { node } = path
89
+ const { object } = node
90
+ if (object.type !== "MetaProperty") {
91
+ return
92
+ }
93
+ const { property: objectProperty } = object
94
+ if (objectProperty.name !== "meta") {
95
+ return
96
+ }
97
+ const { property } = node
98
+ const { name } = property
99
+ const importMetaPaths = importMetas[name]
100
+ if (importMetaPaths) {
101
+ importMetaPaths.push(path)
102
+ } else {
103
+ importMetas[name] = [path]
104
+ }
105
+ },
106
+ })
82
107
  state.file.metadata.importMetaScenarios = {
83
108
  dev: importMetas.dev,
84
109
  test: importMetas.test,
@@ -0,0 +1,52 @@
1
+ const getCurrentScriptSrc = () => {
2
+ const { currentScript } = document
3
+ if (currentScript) return currentScript.src
4
+
5
+ // https://github.com/amiller-gh/currentScript-polyfill
6
+
7
+ const scripts = Array.prototype.slice.call(
8
+ document.getElementsByTagName("script"),
9
+ )
10
+
11
+ const readyScript = scripts.find((script) => {
12
+ return script.readyState === "interactive"
13
+ })
14
+ if (readyScript) return readyScript
15
+
16
+ try {
17
+ throw new Error()
18
+ } catch (err) {
19
+ // Find the second match for the "at" string to get file src url from stack.
20
+ // Specifically works with the format of stack traces in IE.
21
+ const stackDetails = /.*at [^(]*\((.*):(.+):(.+)\)$/gi.exec(err.stack)
22
+ const scriptLocation = (stackDetails || [false])[1]
23
+ const line = (stackDetails || [false])[2]
24
+ const currentLocation = document.location.href.replace(
25
+ document.location.hash,
26
+ "",
27
+ )
28
+
29
+ if (scriptLocation === currentLocation) {
30
+ const source = document.documentElement.outerHTML
31
+ const codeRegExp = new RegExp(
32
+ `(?:[^\\n]+?\\n){0,${
33
+ line - 2
34
+ }}[^<]*<script>([\\d\\D]*?)<\\/script>[\\d\\D]*`,
35
+ "i",
36
+ )
37
+ const code = source.replace(codeRegExp, "$1").trim()
38
+
39
+ return scripts.find((script) => {
40
+ return script.innerHTML && script.innerHTML.trim() === code
41
+ })
42
+ }
43
+
44
+ return scripts.find((script) => {
45
+ return script.src === scriptLocation
46
+ })
47
+ }
48
+ }
49
+
50
+ const url = getCurrentScriptSrc()
51
+
52
+ export default url
@@ -0,0 +1,9 @@
1
+ /* global __filename */
2
+
3
+ const filenameContainsBackSlashes = __filename.indexOf("\\") > -1
4
+
5
+ const url = filenameContainsBackSlashes
6
+ ? `file:///${__filename.replace(/\\/g, "/")}`
7
+ : `file://${__filename}`
8
+
9
+ export default url