@jsenv/core 27.0.0-alpha.83 → 27.0.0-alpha.86

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 (62) hide show
  1. package/dist/html/explorer.html +1 -1
  2. package/dist/js/event_source_client.js +3 -3
  3. package/dist/js/s.js +2 -2
  4. package/dist/main.js +503 -417
  5. package/dist/s.js +2 -2
  6. package/dist/s.js.map +2 -1
  7. package/package.json +7 -3
  8. package/src/build/build.js +5 -8
  9. package/src/build/build_urls_generator.js +1 -2
  10. package/src/build/inject_global_version_mappings.js +4 -4
  11. package/src/build/inject_service_worker_urls.js +2 -2
  12. package/src/build/resync_ressource_hints.js +17 -18
  13. package/src/build/start_build_server.js +5 -1
  14. package/src/build/version_generator.js +60 -0
  15. package/src/dev/plugins/explorer/client/explorer.html +1 -1
  16. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -3
  17. package/src/dev/plugins/toolbar/client/util/fetching.js +1 -1
  18. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -3
  19. package/src/dev/start_dev_server.js +5 -1
  20. package/src/execute/runtimes/browsers/from_playwright.js +2 -2
  21. package/src/execute/runtimes/node/node_process.js +2 -2
  22. package/src/helpers/command/command.js +73 -0
  23. package/src/helpers/worker_reload.js +4 -3
  24. package/src/omega/compat/runtime_compat.js +2 -1
  25. package/src/omega/kitchen.js +4 -1
  26. package/src/omega/server/user_agent.js +2 -1
  27. package/src/omega/url_graph/sort_by_dependencies.js +27 -0
  28. package/src/omega/url_graph/url_info_transformations.js +24 -14
  29. package/src/plugins/autoreload/dev_sse/client/reload.js +6 -3
  30. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +3 -3
  31. package/src/plugins/bundling/css/bundle_css.js +4 -4
  32. package/src/plugins/bundling/js_module/bundle_js_module.js +86 -67
  33. package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +2 -2
  34. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +4 -5
  35. package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +62 -74
  36. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +10 -6
  37. package/src/plugins/import_meta_hot/html_hot_dependencies.js +9 -15
  38. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +3 -3
  39. package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +2 -2
  40. package/src/plugins/importmap/jsenv_plugin_importmap.js +25 -27
  41. package/src/plugins/inject_globals/inject_globals.js +4 -4
  42. package/src/plugins/inline/jsenv_plugin_data_urls.js +1 -1
  43. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +41 -43
  44. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +4 -4
  45. package/src/plugins/minification/css/minify_css.js +1 -1
  46. package/src/plugins/transpilation/as_js_classic/client/s.js +2 -2
  47. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +2 -4
  48. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +45 -67
  49. package/src/plugins/transpilation/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +2 -3
  50. package/src/plugins/transpilation/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +3 -4
  51. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -1
  52. package/src/plugins/transpilation/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +2 -3
  53. package/src/plugins/transpilation/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +2 -3
  54. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +1 -1
  55. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +1 -1
  56. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +2 -1
  57. package/src/plugins/url_analysis/css/css_urls.js +2 -3
  58. package/src/plugins/url_analysis/html/html_urls.js +98 -113
  59. package/src/plugins/url_analysis/js/js_urls.js +3 -2
  60. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +10 -6
  61. package/src/test/coverage/empty_coverage_factory.js +1 -1
  62. package/src/test/coverage/file_by_file_coverage.js +1 -2
@@ -1,8 +1,4 @@
1
- import {
2
- getHtmlNodeAttributeByName,
3
- parseLinkNode,
4
- } from "@jsenv/utils/html_ast/html_ast.js"
5
- import { htmlAttributeSrcSet } from "@jsenv/utils/html_ast/html_attribute_src_set.js"
1
+ import { getHtmlNodeAttribute, analyzeLinkNode, parseSrcSet } from "@jsenv/ast"
6
2
 
7
3
  // Some "smart" default applied to decide what should hot reload / fullreload:
8
4
  // By default:
@@ -28,8 +24,7 @@ export const collectHotDataFromHtmlAst = (htmlAst) => {
28
24
  }
29
25
 
30
26
  const visitUrlSpecifierAttribute = ({ node, attributeName, hotAccepted }) => {
31
- const attribute = getHtmlNodeAttributeByName(node, attributeName)
32
- const value = attribute ? attribute.value : undefined
27
+ const value = getHtmlNodeAttribute(node, attributeName)
33
28
  if (value) {
34
29
  onSpecifier({
35
30
  specifier: value,
@@ -70,10 +65,9 @@ export const collectHotDataFromHtmlAst = (htmlAst) => {
70
65
  })
71
66
  }
72
67
  if (nodeNamesWithSrcset.includes(node.nodeName)) {
73
- const srcsetAttribute = getHtmlNodeAttributeByName(node, "srcset")
74
- const srcset = srcsetAttribute ? srcsetAttribute.value : undefined
68
+ const srcset = getHtmlNodeAttribute(node, "srcset")
75
69
  if (srcset) {
76
- const srcCandidates = htmlAttributeSrcSet.parse(srcset)
70
+ const srcCandidates = parseSrcSet(srcset)
77
71
  srcCandidates.forEach((srcCandidate) => {
78
72
  onSpecifier({
79
73
  node,
@@ -112,12 +106,12 @@ const nodeNamesWithSrcset = ["img", "source"]
112
106
 
113
107
  const getNodeContext = (node) => {
114
108
  const context = {}
115
- const hotAcceptAttribute = getHtmlNodeAttributeByName(node, "hot-accept")
116
- if (hotAcceptAttribute) {
109
+ const hotAccept = getHtmlNodeAttribute(node, "hot-accept")
110
+ if (hotAccept !== undefined) {
117
111
  context.hotAccepted = true
118
112
  }
119
- const hotDeclineAttribute = getHtmlNodeAttributeByName(node, "hot-decline")
120
- if (hotDeclineAttribute) {
113
+ const hotDecline = getHtmlNodeAttribute(node, "hot-decline")
114
+ if (hotDecline !== undefined) {
121
115
  context.hotAccepted = false
122
116
  }
123
117
  return context
@@ -125,7 +119,7 @@ const getNodeContext = (node) => {
125
119
 
126
120
  const htmlNodeCanHotReload = (node) => {
127
121
  if (node.nodeName === "link") {
128
- const { isStylesheet, isRessourceHint, rel } = parseLinkNode(node)
122
+ const { isStylesheet, isRessourceHint, rel } = analyzeLinkNode(node)
129
123
  if (isStylesheet) {
130
124
  // stylesheets can be hot replaced by default
131
125
  return true
@@ -1,6 +1,6 @@
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"
1
+ import { createMagicSource } from "@jsenv/sourcemap"
2
+ import { parseHtmlString, applyBabelPlugins } from "@jsenv/ast"
3
+
4
4
  import { collectHotDataFromHtmlAst } from "./html_hot_dependencies.js"
5
5
  import { babelPluginMetadataImportMetaHot } from "./babel_plugin_metadata_import_meta_hot.js"
6
6
 
@@ -9,8 +9,8 @@
9
9
  * - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
10
10
  */
11
11
 
12
- import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
13
- import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
12
+ import { createMagicSource } from "@jsenv/sourcemap"
13
+ import { applyBabelPlugins } from "@jsenv/ast"
14
14
 
15
15
  export const jsenvPluginImportMetaScenarios = () => {
16
16
  return {
@@ -22,19 +22,18 @@ import {
22
22
  composeTwoImportMaps,
23
23
  normalizeImportMap,
24
24
  } from "@jsenv/importmap"
25
-
25
+ import { generateInlineContentUrl } from "@jsenv/urls"
26
26
  import {
27
27
  parseHtmlString,
28
28
  stringifyHtmlAst,
29
- findNode,
30
- getHtmlNodeAttributeByName,
31
- htmlNodePosition,
32
- removeHtmlNodeAttributeByName,
33
- setHtmlNodeGeneratedText,
34
- getHtmlNodeTextNode,
29
+ findHtmlNode,
30
+ getHtmlNodeAttribute,
31
+ setHtmlNodeAttributes,
32
+ getHtmlNodePosition,
33
+ getHtmlNodeText,
34
+ setHtmlNodeText,
35
35
  removeHtmlNode,
36
- } from "@jsenv/utils/html_ast/html_ast.js"
37
- import { generateInlineContentUrl } from "@jsenv/urls"
36
+ } from "@jsenv/ast"
38
37
 
39
38
  export const jsenvPluginImportmap = () => {
40
39
  let finalImportmap = null
@@ -93,12 +92,12 @@ export const jsenvPluginImportmap = () => {
93
92
  transformUrlContent: {
94
93
  html: async (htmlUrlInfo, context) => {
95
94
  const htmlAst = parseHtmlString(htmlUrlInfo.content)
96
- const importmap = findNode(htmlAst, (node) => {
95
+ const importmap = findHtmlNode(htmlAst, (node) => {
97
96
  if (node.nodeName !== "script") {
98
97
  return false
99
98
  }
100
- const typeAttribute = getHtmlNodeAttributeByName(node, "type")
101
- if (!typeAttribute || typeAttribute.value !== "importmap") {
99
+ const type = getHtmlNodeAttribute(node, "type")
100
+ if (type === undefined || type !== "importmap") {
102
101
  return false
103
102
  }
104
103
  return true
@@ -109,7 +108,7 @@ export const jsenvPluginImportmap = () => {
109
108
  }
110
109
  const handleInlineImportmap = async (importmap, textNode) => {
111
110
  const { line, column, lineEnd, columnEnd, isOriginal } =
112
- htmlNodePosition.readNodePosition(importmap, {
111
+ getHtmlNodePosition(importmap, {
113
112
  preferOriginal: true,
114
113
  })
115
114
  const inlineImportmapUrl = generateInlineContentUrl({
@@ -133,9 +132,9 @@ export const jsenvPluginImportmap = () => {
133
132
  await context.cook(inlineImportmapUrlInfo, {
134
133
  reference: inlineImportmapReference,
135
134
  })
136
- setHtmlNodeGeneratedText(importmap, {
137
- generatedText: inlineImportmapUrlInfo.content,
138
- generatedBy: "jsenv:importmap",
135
+ setHtmlNodeText(importmap, inlineImportmapUrlInfo.content)
136
+ setHtmlNodeAttributes(importmap, {
137
+ "generated-by": "jsenv:importmap",
139
138
  })
140
139
  onHtmlImportmapParsed(
141
140
  JSON.parse(inlineImportmapUrlInfo.content),
@@ -160,15 +159,15 @@ export const jsenvPluginImportmap = () => {
160
159
  JSON.parse(importmapUrlInfo.content),
161
160
  htmlUrlInfo.url,
162
161
  )
163
- removeHtmlNodeAttributeByName(importmap, "src")
164
- setHtmlNodeGeneratedText(importmap, {
165
- generatedText: importmapUrlInfo.content,
166
- generatedBy: "jsenv:importmap",
167
- generatedFromSrc: src,
162
+ setHtmlNodeText(importmap, importmapUrlInfo.content)
163
+ setHtmlNodeAttributes(importmap, {
164
+ "src": undefined,
165
+ "generated-by": "jsenv:importmap",
166
+ "generated-from-src": src,
168
167
  })
169
168
 
170
169
  const { line, column, lineEnd, columnEnd, isOriginal } =
171
- htmlNodePosition.readNodePosition(importmap, {
170
+ getHtmlNodePosition(importmap, {
172
171
  preferOriginal: true,
173
172
  })
174
173
  const inlineImportmapUrl = generateInlineContentUrl({
@@ -189,14 +188,13 @@ export const jsenvPluginImportmap = () => {
189
188
  })
190
189
  }
191
190
 
192
- const srcAttribute = getHtmlNodeAttributeByName(importmap, "src")
193
- const src = srcAttribute ? srcAttribute.value : undefined
191
+ const src = getHtmlNodeAttribute(importmap, "src")
194
192
  if (src) {
195
193
  await handleImportmapWithSrc(importmap, src)
196
194
  } else {
197
- const textNode = getHtmlNodeTextNode(importmap)
198
- if (textNode) {
199
- await handleInlineImportmap(importmap, textNode)
195
+ const htmlNodeText = getHtmlNodeText(importmap)
196
+ if (htmlNodeText) {
197
+ await handleInlineImportmap(importmap, htmlNodeText)
200
198
  }
201
199
  }
202
200
  // once this plugin knows the importmap, it will use it
@@ -1,10 +1,10 @@
1
+ import { createMagicSource } from "@jsenv/sourcemap"
1
2
  import {
2
3
  parseHtmlString,
3
- injectScriptAsEarlyAsPossible,
4
+ injectScriptNodeAsEarlyAsPossible,
4
5
  createHtmlNode,
5
6
  stringifyHtmlAst,
6
- } from "@jsenv/utils/html_ast/html_ast.js"
7
- import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
7
+ } from "@jsenv/ast"
8
8
 
9
9
  export const injectGlobals = (urlInfo, globals) => {
10
10
  if (urlInfo.type === "html") {
@@ -27,7 +27,7 @@ const globalInjectorOnHtml = async (urlInfo, globals) => {
27
27
  globals,
28
28
  isWebWorker: false,
29
29
  })
30
- injectScriptAsEarlyAsPossible(
30
+ injectScriptNodeAsEarlyAsPossible(
31
31
  htmlAst,
32
32
  createHtmlNode({
33
33
  "tagName": "script",
@@ -1,5 +1,5 @@
1
1
  import { DATA_URL } from "@jsenv/urls"
2
- import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
2
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
3
3
 
4
4
  export const jsenvPluginDataUrls = () => {
5
5
  return {
@@ -1,15 +1,16 @@
1
+ import { generateInlineContentUrl } from "@jsenv/urls"
1
2
  import {
2
3
  parseHtmlString,
3
4
  stringifyHtmlAst,
4
- visitHtmlAst,
5
- getHtmlNodeTextNode,
6
- htmlNodePosition,
7
- parseScriptNode,
8
- setHtmlNodeGeneratedText,
9
- getHtmlNodeAttributeByName,
10
- } from "@jsenv/utils/html_ast/html_ast.js"
11
- import { generateInlineContentUrl } from "@jsenv/urls"
12
- import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
5
+ visitHtmlNodes,
6
+ getHtmlNodeText,
7
+ getHtmlNodePosition,
8
+ analyzeScriptNode,
9
+ setHtmlNodeAttributes,
10
+ setHtmlNodeText,
11
+ getHtmlNodeAttribute,
12
+ } from "@jsenv/ast"
13
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
13
14
 
14
15
  export const jsenvPluginHtmlInlineContent = ({ analyzeConvertedScripts }) => {
15
16
  return {
@@ -20,16 +21,13 @@ export const jsenvPluginHtmlInlineContent = ({ analyzeConvertedScripts }) => {
20
21
  const htmlAst = parseHtmlString(urlInfo.content)
21
22
  const actions = []
22
23
  const handleInlineStyle = (node) => {
23
- if (node.nodeName !== "style") {
24
- return
25
- }
26
- const textNode = getHtmlNodeTextNode(node)
27
- if (!textNode) {
24
+ const htmlNodeText = getHtmlNodeText(node)
25
+ if (!htmlNodeText) {
28
26
  return
29
27
  }
30
28
  actions.push(async () => {
31
29
  const { line, column, lineEnd, columnEnd, isOriginal } =
32
- htmlNodePosition.readNodePosition(node, {
30
+ getHtmlNodePosition(node, {
33
31
  preferOriginal: true,
34
32
  })
35
33
  const inlineStyleUrl = generateInlineContentUrl({
@@ -52,43 +50,39 @@ export const jsenvPluginHtmlInlineContent = ({ analyzeConvertedScripts }) => {
52
50
  specifierColumn: column,
53
51
  specifier: inlineStyleUrl,
54
52
  contentType: "text/css",
55
- content: textNode.value,
53
+ content: htmlNodeText,
56
54
  })
57
55
  await context.cook(inlineStyleUrlInfo, {
58
56
  reference: inlineStyleReference,
59
57
  })
60
- setHtmlNodeGeneratedText(node, {
61
- generatedText: inlineStyleUrlInfo.content,
62
- generatedBy: "jsenv:html_inline_content",
58
+ setHtmlNodeText(node, inlineStyleUrlInfo.content)
59
+ setHtmlNodeAttributes(node, {
60
+ "generated-by": "jsenv:html_inline_content",
63
61
  })
64
62
  })
65
63
  }
66
64
  const handleInlineScript = (node) => {
67
- if (node.nodeName !== "script") {
68
- return
69
- }
70
- const textNode = getHtmlNodeTextNode(node)
71
- if (!textNode) {
65
+ const htmlNodeText = getHtmlNodeText(node)
66
+ if (!htmlNodeText) {
72
67
  return
73
68
  }
74
69
  // If the inline script was already handled by an other plugin, ignore it
75
70
  // - we want to preserve inline scripts generated by html supervisor during dev
76
71
  // - we want to avoid cooking twice a script during build
77
- const generatedBy = getHtmlNodeAttributeByName(node, "generated-by")
78
- if (generatedBy) {
79
- if (generatedBy.value === "jsenv:as_js_classic_html") {
80
- if (!analyzeConvertedScripts) {
81
- return
82
- }
83
- }
84
- if (generatedBy.value === "jsenv:html_supervisor") {
85
- return
86
- }
72
+ const generatedBy = getHtmlNodeAttribute(node, "generated-by")
73
+ if (
74
+ generatedBy === "jsenv:as_js_classic_html" &&
75
+ !analyzeConvertedScripts
76
+ ) {
77
+ return
78
+ }
79
+ if (generatedBy === "jsenv:html_supervisor") {
80
+ return
87
81
  }
88
82
  actions.push(async () => {
89
- const scriptCategory = parseScriptNode(node)
83
+ const scriptCategory = analyzeScriptNode(node)
90
84
  const { line, column, lineEnd, columnEnd, isOriginal } =
91
- htmlNodePosition.readNodePosition(node, {
85
+ getHtmlNodePosition(node, {
92
86
  preferOriginal: true,
93
87
  })
94
88
  // from MDN about [type] attribute:
@@ -131,21 +125,25 @@ export const jsenvPluginHtmlInlineContent = ({ analyzeConvertedScripts }) => {
131
125
  isOriginalPosition: isOriginal,
132
126
  specifier: inlineScriptUrl,
133
127
  contentType,
134
- content: textNode.value,
128
+ content: htmlNodeText,
135
129
  })
136
130
 
137
131
  await context.cook(inlineScriptUrlInfo, {
138
132
  reference: inlineScriptReference,
139
133
  })
140
- setHtmlNodeGeneratedText(node, {
141
- generatedText: inlineScriptUrlInfo.content,
142
- generatedBy: "jsenv:html_inline_content",
134
+ setHtmlNodeText(node, inlineScriptUrlInfo.content)
135
+ setHtmlNodeAttributes(node, {
136
+ "generated-by": "jsenv:html_inline_content",
143
137
  })
144
138
  })
145
139
  }
146
- visitHtmlAst(htmlAst, (node) => {
147
- handleInlineStyle(node)
148
- handleInlineScript(node)
140
+ visitHtmlNodes(htmlAst, {
141
+ style: (node) => {
142
+ handleInlineStyle(node)
143
+ },
144
+ script: (node) => {
145
+ handleInlineScript(node)
146
+ },
149
147
  })
150
148
  if (actions.length === 0) {
151
149
  return null
@@ -1,8 +1,8 @@
1
- import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
2
- import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
3
- import { JS_QUOTES } from "@jsenv/utils/string/js_quotes.js"
4
- import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
5
1
  import { generateInlineContentUrl } from "@jsenv/urls"
2
+ import { createMagicSource } from "@jsenv/sourcemap"
3
+ import { applyBabelPlugins } from "@jsenv/ast"
4
+ import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
5
+ import { JS_QUOTES } from "@jsenv/utils/src/string/js_quotes.js"
6
6
 
7
7
  export const jsenvPluginJsInlineContent = ({ allowEscapeForVersioning }) => {
8
8
  const parseAndTransformInlineContentCalls = async (urlInfo, context) => {
@@ -1,4 +1,4 @@
1
- import { minifyWithParcel } from "@jsenv/utils/css_ast/parcel_css.js"
1
+ import { minifyWithParcel } from "@jsenv/ast"
2
2
 
3
3
  export const minifyCss = ({ cssUrlInfo, context }) => {
4
4
  const { code, map } = minifyWithParcel(cssUrlInfo, context)
@@ -43,7 +43,7 @@
43
43
  }
44
44
  System.register = (deps, declare) => {
45
45
  if (!document.currentScript) {
46
- throw new Error("unexpected call")
46
+ throw new Error("unexpected call to System.register (document.currentScript is undefined)")
47
47
  }
48
48
  if (document.currentScript.__s__) {
49
49
  registerRegistry[document.currentScript.src] = [deps, declare]
@@ -169,7 +169,7 @@
169
169
 
170
170
  System.register = async (deps, declare) => {
171
171
  System.register = () => {
172
- throw new Error("unexpected call")
172
+ throw new Error("unexpected call to System.register (called outside url instantiation)")
173
173
  }
174
174
  const url = self.location.href
175
175
  registerRegistry[url] = [deps, declare]
@@ -13,12 +13,10 @@
13
13
 
14
14
  import { urlToFilename, injectQueryParams } from "@jsenv/urls"
15
15
  import { readFileSync } from "@jsenv/filesystem"
16
+ import { createMagicSource, composeTwoSourcemaps } from "@jsenv/sourcemap"
17
+ import { applyBabelPlugins } from "@jsenv/ast"
16
18
 
17
19
  import { requireFromJsenv } from "@jsenv/core/src/require_from_jsenv.js"
18
- import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
19
- import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
20
- import { composeTwoSourcemaps } from "@jsenv/utils/sourcemap/sourcemap_composition_v3.js"
21
-
22
20
  import { requireBabelPlugin } from "../babel/require_babel_plugin.js"
23
21
  import { babelPluginTransformImportMetaUrl } from "./helpers/babel_plugin_transform_import_meta_url.js"
24
22
  import { jsenvPluginAsJsClassicHtml } from "./jsenv_plugin_as_js_classic_html.js"
@@ -1,20 +1,19 @@
1
- import {
2
- getHtmlNodeAttributeByName,
3
- getHtmlNodeTextNode,
4
- parseHtmlString,
5
- removeHtmlNodeAttributeByName,
6
- assignHtmlNodeAttributes,
7
- stringifyHtmlAst,
8
- visitHtmlAst,
9
- htmlNodePosition,
10
- setHtmlNodeGeneratedText,
11
- injectScriptAsEarlyAsPossible,
12
- createHtmlNode,
13
- } from "@jsenv/utils/html_ast/html_ast.js"
14
1
  import {
15
2
  generateInlineContentUrl,
16
3
  injectQueryParamsIntoSpecifier,
17
4
  } from "@jsenv/urls"
5
+ import {
6
+ parseHtmlString,
7
+ visitHtmlNodes,
8
+ stringifyHtmlAst,
9
+ getHtmlNodeAttribute,
10
+ getHtmlNodeText,
11
+ getHtmlNodePosition,
12
+ setHtmlNodeAttributes,
13
+ setHtmlNodeText,
14
+ injectScriptNodeAsEarlyAsPossible,
15
+ createHtmlNode,
16
+ } from "@jsenv/ast"
18
17
 
19
18
  export const jsenvPluginAsJsClassicHtml = ({
20
19
  systemJsInjection,
@@ -35,18 +34,13 @@ export const jsenvPluginAsJsClassicHtml = ({
35
34
  const moduleScriptNodes = []
36
35
  const classicScriptNodes = []
37
36
  const visitLinkNodes = (node) => {
38
- if (node.nodeName !== "link") {
39
- return
40
- }
41
- const relAttribute = getHtmlNodeAttributeByName(node, "rel")
42
- const rel = relAttribute ? relAttribute.value : undefined
37
+ const rel = getHtmlNodeAttribute(node, "rel")
43
38
  if (rel === "modulepreload") {
44
39
  modulePreloadNodes.push(node)
45
40
  return
46
41
  }
47
42
  if (rel === "preload") {
48
- const asAttribute = getHtmlNodeAttributeByName(node, "as")
49
- const asValue = asAttribute ? asAttribute.value : undefined
43
+ const asValue = getHtmlNodeAttribute(node, "as")
50
44
  if (asValue === "script") {
51
45
  preloadAsScriptNodes.push(node)
52
46
  }
@@ -54,11 +48,7 @@ export const jsenvPluginAsJsClassicHtml = ({
54
48
  }
55
49
  }
56
50
  const visitScriptNodes = (node) => {
57
- if (node.nodeName !== "script") {
58
- return
59
- }
60
- const typeAttribute = getHtmlNodeAttributeByName(node, "type")
61
- const type = typeAttribute ? typeAttribute.value : undefined
51
+ const type = getHtmlNodeAttribute(node, "type")
62
52
  if (type === "module") {
63
53
  moduleScriptNodes.push(node)
64
54
  return
@@ -68,9 +58,13 @@ export const jsenvPluginAsJsClassicHtml = ({
68
58
  return
69
59
  }
70
60
  }
71
- visitHtmlAst(htmlAst, (node) => {
72
- visitLinkNodes(node)
73
- visitScriptNodes(node)
61
+ visitHtmlNodes(htmlAst, {
62
+ link: (node) => {
63
+ visitLinkNodes(node)
64
+ },
65
+ script: (node) => {
66
+ visitScriptNodes(node)
67
+ },
74
68
  })
75
69
 
76
70
  const actions = []
@@ -113,15 +107,11 @@ export const jsenvPluginAsJsClassicHtml = ({
113
107
  }
114
108
 
115
109
  classicScriptNodes.forEach((classicScriptNode) => {
116
- const srcAttribute = getHtmlNodeAttributeByName(
117
- classicScriptNode,
118
- "src",
119
- )
120
- if (srcAttribute) {
110
+ const src = getHtmlNodeAttribute(classicScriptNode, "src")
111
+ if (src !== undefined) {
121
112
  const reference = urlInfo.references.find(
122
113
  (ref) =>
123
- ref.generatedSpecifier === srcAttribute.value &&
124
- ref.type === "script_src",
114
+ ref.generatedSpecifier === src && ref.type === "script_src",
125
115
  )
126
116
  const urlObject = new URL(reference.url)
127
117
  if (urlObject.searchParams.has("as_js_classic")) {
@@ -138,14 +128,11 @@ export const jsenvPluginAsJsClassicHtml = ({
138
128
  }
139
129
  })
140
130
  moduleScriptNodes.forEach((moduleScriptNode) => {
141
- const srcAttribute = getHtmlNodeAttributeByName(
142
- moduleScriptNode,
143
- "src",
144
- )
145
- if (srcAttribute) {
131
+ const src = getHtmlNodeAttribute(moduleScriptNode, "src")
132
+ if (src !== undefined) {
146
133
  const reference = urlInfo.references.find(
147
134
  (ref) =>
148
- ref.generatedSpecifier === srcAttribute.value &&
135
+ ref.generatedSpecifier === src &&
149
136
  ref.type === "script_src" &&
150
137
  ref.expectedType === "js_module",
151
138
  )
@@ -158,17 +145,19 @@ export const jsenvPluginAsJsClassicHtml = ({
158
145
  cookIt: true,
159
146
  },
160
147
  )
161
- removeHtmlNodeAttributeByName(moduleScriptNode, "type")
162
- srcAttribute.value = newReference.generatedSpecifier
148
+ setHtmlNodeAttributes(moduleScriptNode, {
149
+ type: undefined,
150
+ src: newReference.generatedSpecifier,
151
+ })
163
152
  })
164
153
  }
165
154
  return
166
155
  }
167
156
  if (shouldTransformScriptTypeModule) {
168
- const textNode = getHtmlNodeTextNode(moduleScriptNode)
157
+ const htmlNodeText = getHtmlNodeText(moduleScriptNode)
169
158
  actions.push(async () => {
170
159
  const { line, column, lineEnd, columnEnd, isOriginal } =
171
- htmlNodePosition.readNodePosition(moduleScriptNode, {
160
+ getHtmlNodePosition(moduleScriptNode, {
172
161
  preferOriginal: true,
173
162
  })
174
163
  let inlineScriptUrl = generateInlineContentUrl({
@@ -191,27 +180,23 @@ export const jsenvPluginAsJsClassicHtml = ({
191
180
  specifierColumn: column,
192
181
  specifier: inlineScriptUrl,
193
182
  contentType: "text/javascript",
194
- content: textNode.value,
183
+ content: htmlNodeText,
195
184
  })
196
185
  const [, newUrlInfo] = await getReferenceAsJsClassic(
197
186
  inlineReference,
198
187
  { cookIt: true },
199
188
  )
200
- removeHtmlNodeAttributeByName(moduleScriptNode, "type")
201
- setHtmlNodeGeneratedText(moduleScriptNode, {
202
- generatedText: newUrlInfo.content,
203
- generatedBy: "jsenv:as_js_classic_html",
189
+ setHtmlNodeText(moduleScriptNode, newUrlInfo.content)
190
+ setHtmlNodeAttributes(moduleScriptNode, {
191
+ "type": undefined,
192
+ "generated-by": "jsenv:as_js_classic_html",
204
193
  })
205
194
  })
206
195
  }
207
196
  })
208
197
  if (shouldTransformScriptTypeModule) {
209
198
  preloadAsScriptNodes.forEach((preloadAsScriptNode) => {
210
- const hrefAttribute = getHtmlNodeAttributeByName(
211
- preloadAsScriptNode,
212
- "href",
213
- )
214
- const href = hrefAttribute.value
199
+ const href = getHtmlNodeAttribute(preloadAsScriptNode, "href")
215
200
  const reference = urlInfo.references.find(
216
201
  (ref) =>
217
202
  ref.generatedSpecifier === href &&
@@ -233,22 +218,15 @@ export const jsenvPluginAsJsClassicHtml = ({
233
218
  // but it's unlikely to happen and people should use "modulepreload" in that case anyway
234
219
  ;[newReference] = await getReferenceAsJsClassic(reference)
235
220
  }
236
- assignHtmlNodeAttributes(preloadAsScriptNode, {
221
+ setHtmlNodeAttributes(preloadAsScriptNode, {
237
222
  href: newReference.generatedSpecifier,
223
+ crossorigin: undefined,
238
224
  })
239
- removeHtmlNodeAttributeByName(
240
- preloadAsScriptNode,
241
- "crossorigin",
242
- )
243
225
  })
244
226
  }
245
227
  })
246
228
  modulePreloadNodes.forEach((modulePreloadNode) => {
247
- const hrefAttribute = getHtmlNodeAttributeByName(
248
- modulePreloadNode,
249
- "href",
250
- )
251
- const href = hrefAttribute.value
229
+ const href = getHtmlNodeAttribute(modulePreloadNode, "href")
252
230
  const reference = urlInfo.references.find(
253
231
  (ref) =>
254
232
  ref.generatedSpecifier === href &&
@@ -262,7 +240,7 @@ export const jsenvPluginAsJsClassicHtml = ({
262
240
  } else {
263
241
  ;[newReference] = await getReferenceAsJsClassic(reference)
264
242
  }
265
- assignHtmlNodeAttributes(modulePreloadNode, {
243
+ setHtmlNodeAttributes(modulePreloadNode, {
266
244
  rel: "preload",
267
245
  as: "script",
268
246
  href: newReference.generatedSpecifier,
@@ -287,7 +265,7 @@ export const jsenvPluginAsJsClassicHtml = ({
287
265
  expectedType: "js_classic",
288
266
  specifier: systemJsClientFileUrl,
289
267
  })
290
- injectScriptAsEarlyAsPossible(
268
+ injectScriptNodeAsEarlyAsPossible(
291
269
  htmlAst,
292
270
  createHtmlNode({
293
271
  "tagName": "script",
@@ -1,6 +1,5 @@
1
1
  import { pathToFileURL } from "node:url"
2
-
3
- import { injectImport } from "@jsenv/utils/js_ast/babel_utils.js"
2
+ import { injectJsImport } from "@jsenv/ast"
4
3
 
5
4
  export const babelPluginGlobalThisAsJsenvImport = (
6
5
  babel,
@@ -23,7 +22,7 @@ export const babelPluginGlobalThisAsJsenvImport = (
23
22
  const { node } = path
24
23
  // we should do this once, tree shaking will remote it but still
25
24
  if (node.name === "globalThis") {
26
- injectImport({
25
+ injectJsImport({
27
26
  programPath: path.scope.getProgramParent().path,
28
27
  from: getImportSpecifier(globalThisClientFileUrl),
29
28
  sideEffect: true,