@jsenv/core 27.0.0-alpha.10 → 27.0.0-alpha.13

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 (116) hide show
  1. package/main.js +4 -0
  2. package/package.json +13 -7
  3. package/readme.md +4 -12
  4. package/src/build/build.js +438 -387
  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/dev/plugins/autoreload/babel_plugin_metadata_import_meta_hot.js +1 -1
  11. package/src/dev/plugins/autoreload/client/import_meta_hot.js +3 -1
  12. package/src/dev/plugins/autoreload/html_hot_dependencies.js +2 -2
  13. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +61 -51
  14. package/src/dev/plugins/autoreload/sse_service.js +23 -3
  15. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  16. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  17. package/src/dev/start_dev_server.js +10 -5
  18. package/src/execute/execute.js +10 -4
  19. package/src/execute/run.js +17 -54
  20. package/src/execute/runtimes/browsers/from_playwright.js +167 -146
  21. package/src/execute/runtimes/node/node_process.js +281 -37
  22. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  23. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +30 -7
  24. package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +14 -16
  25. package/src/omega/errors.js +51 -58
  26. package/src/omega/fetched_content_compliance.js +24 -0
  27. package/src/omega/kitchen.js +396 -280
  28. package/src/omega/server/file_service.js +9 -11
  29. package/src/omega/url_graph/url_graph_load.js +13 -7
  30. package/src/omega/url_graph/url_graph_report.js +7 -5
  31. package/src/omega/url_graph.js +22 -10
  32. package/src/omega/web_workers.js +42 -0
  33. package/src/plugins/bundling/css/bundle_css.js +17 -0
  34. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  35. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +100 -75
  36. package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
  37. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +48 -41
  38. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  39. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +7 -4
  40. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  41. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  42. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
  43. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
  44. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  45. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  46. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +38 -46
  47. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  48. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +26 -8
  49. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  50. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  51. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
  52. package/src/{omega/core_plugins → plugins}/inject_globals/jsenv_plugin_inject_globals.js +5 -7
  53. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  54. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  55. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
  56. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  57. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  58. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +263 -0
  59. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  60. package/src/plugins/minification/css/minify_css.js +9 -0
  61. package/src/plugins/minification/html/minify_html.js +15 -0
  62. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  63. package/src/plugins/minification/jsenv_plugin_minification.js +77 -0
  64. package/src/plugins/minification/json/minify_json.js +8 -0
  65. package/src/{omega/core_plugins → plugins}/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +15 -15
  66. package/src/{omega → plugins}/plugin_controller.js +18 -10
  67. package/src/plugins/plugins.js +50 -0
  68. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  69. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  70. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  71. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  72. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +178 -0
  73. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +156 -0
  74. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_top_level_await.js +37 -0
  75. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +133 -0
  76. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  77. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  78. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  79. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +3 -21
  80. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  81. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +29 -27
  82. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +0 -0
  83. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  84. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  85. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  86. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  87. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  88. package/src/{omega/core_plugins → plugins/transpilation}/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -0
  89. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +243 -0
  90. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +40 -0
  91. package/src/plugins/url_references/css/css_urls.js +49 -0
  92. package/src/plugins/url_references/html/html_urls.js +273 -0
  93. package/src/plugins/url_references/js/js_urls.js +170 -0
  94. package/src/plugins/url_references/jsenv_plugin_url_references.js +18 -0
  95. package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
  96. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  97. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +8 -8
  98. package/src/preview/preview.js +3 -0
  99. package/src/test/execute_plan.js +18 -11
  100. package/src/test/execute_test_plan.js +5 -6
  101. package/src/test/logs_file_execution.js +8 -7
  102. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  103. package/src/execute/runtimes/node/controlled_process.js +0 -316
  104. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  105. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  106. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  107. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  108. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  109. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -207
  110. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  111. package/src/omega/core_plugins.js +0 -42
  112. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  113. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  114. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  115. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  116. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -0,0 +1,273 @@
1
+ import {
2
+ parseHtmlString,
3
+ stringifyHtmlAst,
4
+ getHtmlNodeAttributeByName,
5
+ htmlNodePosition,
6
+ visitHtmlAst,
7
+ } from "@jsenv/utils/html_ast/html_ast.js"
8
+ import { htmlAttributeSrcSet } from "@jsenv/utils/html_ast/html_attribute_src_set.js"
9
+
10
+ export const parseAndTransformHtmlUrls = async (urlInfo, context) => {
11
+ const url = urlInfo.data.rawUrl || urlInfo.url
12
+ const content = urlInfo.content
13
+ const { scenario, referenceUtils } = context
14
+ const htmlAst = parseHtmlString(content, {
15
+ storeOriginalPositions: scenario !== "build",
16
+ })
17
+ const actions = []
18
+ visitHtmlUrls({
19
+ url,
20
+ htmlAst,
21
+ onUrl: ({
22
+ type,
23
+ subtype,
24
+ expectedType,
25
+ line,
26
+ column,
27
+ originalLine,
28
+ originalColumn,
29
+ specifier,
30
+ attribute,
31
+ }) => {
32
+ const isRessourceHint = [
33
+ "preconnect",
34
+ "dns-prefetch",
35
+ "prefetch",
36
+ "preload",
37
+ "modulepreload",
38
+ ].includes(subtype)
39
+ const [reference] = referenceUtils.found({
40
+ type,
41
+ expectedType,
42
+ line,
43
+ column,
44
+ originalLine,
45
+ originalColumn,
46
+ specifier,
47
+ isRessourceHint,
48
+ })
49
+ actions.push(async () => {
50
+ attribute.value = await referenceUtils.readGeneratedSpecifier(reference)
51
+ })
52
+ },
53
+ })
54
+ await Promise.all(actions.map((action) => action()))
55
+ return {
56
+ content: stringifyHtmlAst(htmlAst),
57
+ }
58
+ }
59
+
60
+ const visitHtmlUrls = ({ url, htmlAst, onUrl }) => {
61
+ const addDependency = ({
62
+ type,
63
+ subtype,
64
+ expectedType,
65
+ node,
66
+ attribute,
67
+ specifier,
68
+ }) => {
69
+ const generatedFromInlineContent = Boolean(
70
+ getHtmlNodeAttributeByName(node, "generated-from-inline-content"),
71
+ )
72
+ let position
73
+ if (generatedFromInlineContent) {
74
+ // when generated from inline content,
75
+ // line, column is not "src" nor "generated-from-src" but "original-position"
76
+ position = htmlNodePosition.readNodePosition(node)
77
+ } else {
78
+ position = htmlNodePosition.readAttributePosition(node, attribute.name)
79
+ }
80
+ const {
81
+ line,
82
+ column,
83
+ // originalLine, originalColumn
84
+ } = position
85
+ onUrl({
86
+ type,
87
+ subtype,
88
+ expectedType,
89
+ line,
90
+ column,
91
+ // originalLine, originalColumn
92
+ specifier,
93
+ attribute,
94
+ // injected:Boolean(getHtmlNodeAttributeByName(node, "injected-by"))
95
+ // srcGeneratedFromInlineContent
96
+ ...readFetchMetas(node),
97
+ })
98
+ }
99
+ const onNode = (node) => {
100
+ if (node.nodeName === "link") {
101
+ const relAttribute = getHtmlNodeAttributeByName(node, "rel")
102
+ const rel = relAttribute ? relAttribute.value : undefined
103
+ const typeAttribute = getHtmlNodeAttributeByName(node, "type")
104
+ const type = typeAttribute ? typeAttribute.value : undefined
105
+ visitAttributeAsUrlSpecifier({
106
+ type: "link_href",
107
+ subtype: rel,
108
+ node,
109
+ attributeName: "href",
110
+ expectedContentType: type,
111
+ expectedType: {
112
+ manifest: "manifest",
113
+ modulepreload: "js_module",
114
+ stylesheet: "css",
115
+ }[rel],
116
+ })
117
+ return
118
+ }
119
+ // if (node.nodeName === "style") {
120
+ // // styles.push(node)
121
+ // return
122
+ // }
123
+ if (node.nodeName === "script") {
124
+ const typeAttributeNode = getHtmlNodeAttributeByName(node, "type")
125
+ visitAttributeAsUrlSpecifier({
126
+ type: "script_src",
127
+ expectedType: {
128
+ "undefined": "js_classic",
129
+ "text/javascript": "js_classic",
130
+ "module": "js_module",
131
+ "importmap": "importmap",
132
+ }[typeAttributeNode ? typeAttributeNode.value : undefined],
133
+ node,
134
+ attributeName: "src",
135
+ })
136
+ return
137
+ }
138
+ if (node.nodeName === "a") {
139
+ visitAttributeAsUrlSpecifier({
140
+ type: "a_href",
141
+ node,
142
+ attributeName: "href",
143
+ })
144
+ }
145
+ if (node.nodeName === "iframe") {
146
+ visitAttributeAsUrlSpecifier({
147
+ type: "iframe_src",
148
+ node,
149
+ attributeName: "src",
150
+ })
151
+ }
152
+ if (node.nodeName === "img") {
153
+ visitAttributeAsUrlSpecifier({
154
+ type: "img_src",
155
+ node,
156
+ attributeName: "src",
157
+ })
158
+ visitSrcset({
159
+ type: "img_srcset",
160
+ node,
161
+ })
162
+ return
163
+ }
164
+ if (node.nodeName === "source") {
165
+ visitAttributeAsUrlSpecifier({
166
+ type: "source_src",
167
+ node,
168
+ attributeName: "src",
169
+ })
170
+ visitSrcset({
171
+ type: "source_srcset",
172
+ node,
173
+ })
174
+ return
175
+ }
176
+ // svg <image> tag
177
+ if (node.nodeName === "image") {
178
+ visitAttributeAsUrlSpecifier({
179
+ type: "image_href",
180
+ node,
181
+ attributeName: "href",
182
+ })
183
+ return
184
+ }
185
+ if (node.nodeName === "use") {
186
+ visitAttributeAsUrlSpecifier({
187
+ type: "use_href",
188
+ node,
189
+ attributeName: "href",
190
+ })
191
+ return
192
+ }
193
+ }
194
+ const visitAttributeAsUrlSpecifier = ({
195
+ type,
196
+ subtype,
197
+ expectedType,
198
+ node,
199
+ attributeName,
200
+ }) => {
201
+ const attribute = getHtmlNodeAttributeByName(node, attributeName)
202
+ const value = attribute ? attribute.value : undefined
203
+ if (value) {
204
+ const generatedBy = getHtmlNodeAttributeByName(node, "generated-by")
205
+ if (generatedBy) {
206
+ // during build the importmap is inlined
207
+ // and shoud not be considered as a dependency anymore
208
+ return
209
+ }
210
+ addDependency({
211
+ type,
212
+ subtype,
213
+ expectedType,
214
+ node,
215
+ attribute,
216
+ specifier:
217
+ attributeName === "generated-from-src" ||
218
+ attributeName === "generated-from-href"
219
+ ? new URL(value, url).href
220
+ : value,
221
+ })
222
+ } else if (attributeName === "src") {
223
+ visitAttributeAsUrlSpecifier({
224
+ type,
225
+ subtype,
226
+ expectedType,
227
+ node,
228
+ attributeName: "generated-from-src",
229
+ })
230
+ } else if (attributeName === "href") {
231
+ visitAttributeAsUrlSpecifier({
232
+ type,
233
+ subtype,
234
+ expectedType,
235
+ node,
236
+ attributeName: "generated-from-href",
237
+ })
238
+ }
239
+ }
240
+ const visitSrcset = ({ type, node }) => {
241
+ const srcsetAttribute = getHtmlNodeAttributeByName(node, "srcset")
242
+ const srcset = srcsetAttribute ? srcsetAttribute.value : undefined
243
+ if (srcset) {
244
+ const srcCandidates = htmlAttributeSrcSet.parse(srcset)
245
+ srcCandidates.forEach((srcCandidate) => {
246
+ addDependency({
247
+ type,
248
+ node,
249
+ attribute: srcsetAttribute,
250
+ specifier: srcCandidate.specifier,
251
+ })
252
+ })
253
+ }
254
+ }
255
+ visitHtmlAst(htmlAst, onNode)
256
+ }
257
+
258
+ const crossOriginCompatibleTagNames = ["script", "link", "img", "source"]
259
+ const integrityCompatibleTagNames = ["script", "link", "img", "source"]
260
+ const readFetchMetas = (node) => {
261
+ const meta = {}
262
+ if (crossOriginCompatibleTagNames.includes(node.nodeName)) {
263
+ const crossoriginAttribute = getHtmlNodeAttributeByName(node, "crossorigin")
264
+ meta.crossorigin = crossoriginAttribute
265
+ ? crossoriginAttribute.value
266
+ : undefined
267
+ }
268
+ if (integrityCompatibleTagNames.includes(node.nodeName)) {
269
+ const integrityAttribute = getHtmlNodeAttributeByName(node, "integrity")
270
+ meta.integrity = integrityAttribute ? integrityAttribute.value : undefined
271
+ }
272
+ return meta
273
+ }
@@ -0,0 +1,170 @@
1
+ import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
2
+ import {
3
+ analyzeImportCall,
4
+ isImportCall,
5
+ analyzeImportExportDeclaration,
6
+ analyzeNewUrlCall,
7
+ analyzeNewWorkerOrNewSharedWorker,
8
+ analyzeImportScriptCalls,
9
+ analyzeSystemRegisterCall,
10
+ analyzeSystemImportCall,
11
+ analyzeServiceWorkerRegisterCall,
12
+ } from "@jsenv/utils/js_ast/js_static_analysis.js"
13
+ import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
14
+ import { isWebWorkerUrlInfo } from "@jsenv/core/src/omega/web_workers.js"
15
+
16
+ export const parseAndTransformJsUrls = async (urlInfo, context) => {
17
+ const isJsModule = urlInfo.type === "js_module"
18
+ const isWebWorker = isWebWorkerUrlInfo(urlInfo)
19
+ const { metadata } = await applyBabelPlugins({
20
+ babelPlugins: [
21
+ [
22
+ babelPluginMetadataJsUrlMentions,
23
+ { isJsModule, isWebWorker, searchSystemJs: !isJsModule },
24
+ ],
25
+ ],
26
+ urlInfo,
27
+ })
28
+ const { jsMentions, usesTopLevelAwait, usesImport, usesExport } = metadata
29
+ urlInfo.data.usesImport = usesImport
30
+ urlInfo.data.usesExport = usesExport
31
+ urlInfo.data.usesTopLevelAwait = usesTopLevelAwait
32
+
33
+ const { rootDirectoryUrl, referenceUtils } = context
34
+ const actions = []
35
+ const magicSource = createMagicSource(urlInfo.content)
36
+ jsMentions.forEach((jsMention) => {
37
+ const [reference] = referenceUtils.found({
38
+ type: jsMention.type,
39
+ subtype: jsMention.subtype,
40
+ expectedType: jsMention.expectedType,
41
+ expectedSubtype: jsMention.expectedSubtype || urlInfo.subtype,
42
+ line: jsMention.line,
43
+ column: jsMention.column,
44
+ specifier: jsMention.specifier,
45
+ data: jsMention.data,
46
+ baseUrl: {
47
+ "StringLiteral": jsMention.baseUrl,
48
+ "window.origin": rootDirectoryUrl,
49
+ "import.meta.url": urlInfo.url,
50
+ }[jsMention.baseUrlType],
51
+ })
52
+ actions.push(async () => {
53
+ magicSource.replace({
54
+ start: jsMention.start,
55
+ end: jsMention.end,
56
+ replacement: await referenceUtils.readGeneratedSpecifier(reference),
57
+ })
58
+ })
59
+ })
60
+ await Promise.all(actions.map((action) => action()))
61
+ return magicSource.toContentAndSourcemap()
62
+ }
63
+
64
+ /*
65
+ * see also
66
+ * https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md
67
+ * https://github.com/mjackson/babel-plugin-import-visitor
68
+ *
69
+ */
70
+ const babelPluginMetadataJsUrlMentions = (
71
+ _,
72
+ { isJsModule, isWebWorker, searchSystemJs },
73
+ ) => {
74
+ return {
75
+ name: "metadata-js-mentions",
76
+ visitor: {
77
+ Program(programPath, state) {
78
+ const jsMentions = []
79
+ let usesImport = false
80
+ let usesExport = false
81
+ let usesTopLevelAwait = false
82
+
83
+ const callOneStaticAnalyzer = (path, analyzer) => {
84
+ const returnValue = analyzer(path)
85
+ if (returnValue === null) {
86
+ return false
87
+ }
88
+ if (Array.isArray(returnValue)) {
89
+ jsMentions.push(...returnValue)
90
+ return true
91
+ }
92
+ if (typeof returnValue === "object") {
93
+ jsMentions.push(returnValue)
94
+ return true
95
+ }
96
+ return false
97
+ }
98
+ const callStaticAnalyzers = (path, analysers) => {
99
+ for (const analyzer of analysers) {
100
+ if (callOneStaticAnalyzer(path, analyzer)) {
101
+ break
102
+ }
103
+ }
104
+ }
105
+
106
+ const visitors = {
107
+ AwaitExpression: (path) => {
108
+ const closestFunction = path.getFunctionParent()
109
+ if (!closestFunction) {
110
+ usesTopLevelAwait = true
111
+ }
112
+ },
113
+ NewExpression: (path) => {
114
+ callStaticAnalyzers(path, [
115
+ analyzeNewWorkerOrNewSharedWorker,
116
+ analyzeNewUrlCall,
117
+ ])
118
+ },
119
+ }
120
+ const callExpressionStaticAnalysers = [
121
+ ...(isJsModule ? [analyzeImportCall] : []),
122
+ ...(isWebWorker ? [analyzeImportScriptCalls] : []),
123
+ ...(searchSystemJs
124
+ ? [analyzeSystemRegisterCall, analyzeSystemImportCall]
125
+ : []),
126
+ analyzeServiceWorkerRegisterCall,
127
+ ]
128
+ visitors.CallExpression = (path) => {
129
+ if (isJsModule && !usesImport && isImportCall(path.node)) {
130
+ usesImport = true
131
+ }
132
+ callStaticAnalyzers(path, callExpressionStaticAnalysers)
133
+ }
134
+
135
+ if (isJsModule) {
136
+ Object.assign(visitors, {
137
+ ExportNamedDeclaration: (path) => {
138
+ if (!usesImport && path.node.source) {
139
+ usesImport = true
140
+ }
141
+ usesExport = true
142
+ callStaticAnalyzers(path, [analyzeImportExportDeclaration])
143
+ },
144
+ ExportAllDeclaration: (path) => {
145
+ usesImport = true
146
+ usesExport = true
147
+ callStaticAnalyzers(path, [analyzeImportExportDeclaration])
148
+ },
149
+ ExportDefaultDeclaration: (path) => {
150
+ if (!usesImport && path.node.source) {
151
+ usesImport = true
152
+ }
153
+ usesExport = true
154
+ callStaticAnalyzers(path, [analyzeImportExportDeclaration])
155
+ },
156
+ ImportDeclaration: (path) => {
157
+ usesImport = true
158
+ callStaticAnalyzers(path, [analyzeImportExportDeclaration])
159
+ },
160
+ })
161
+ }
162
+ programPath.traverse(visitors)
163
+ state.file.metadata.jsMentions = jsMentions
164
+ state.file.metadata.usesImport = usesImport
165
+ state.file.metadata.usesExport = usesExport
166
+ state.file.metadata.usesTopLevelAwait = usesTopLevelAwait
167
+ },
168
+ },
169
+ }
170
+ }
@@ -0,0 +1,18 @@
1
+ import { parseAndTransformHtmlUrls } from "./html/html_urls.js"
2
+ import { parseAndTransformCssUrls } from "./css/css_urls.js"
3
+ import { parseAndTransformJsUrls } from "./js/js_urls.js"
4
+ import { parseAndTransformWebmanifestUrls } from "./webmanifest/webmanifest_urls.js"
5
+
6
+ export const jsenvPluginUrlReferences = () => {
7
+ return {
8
+ name: "jsenv:url_references",
9
+ appliesDuring: "*",
10
+ transformUrlContent: {
11
+ html: parseAndTransformHtmlUrls,
12
+ css: parseAndTransformCssUrls,
13
+ js_classic: parseAndTransformJsUrls,
14
+ js_module: parseAndTransformJsUrls,
15
+ webmanifest: parseAndTransformWebmanifestUrls,
16
+ },
17
+ }
18
+ }
@@ -0,0 +1,17 @@
1
+ export const parseAndTransformWebmanifestUrls = async (urlInfo, context) => {
2
+ const content = urlInfo.content
3
+ const manifest = JSON.parse(content)
4
+ const actions = []
5
+ const { icons = [] } = manifest
6
+ icons.forEach((icon) => {
7
+ const [reference] = context.referenceUtils.found({
8
+ type: "webmanifest_icon_src",
9
+ specifier: icon.src,
10
+ })
11
+ actions.push(async () => {
12
+ icon.src = await context.referenceUtils.readGeneratedSpecifier(reference)
13
+ })
14
+ })
15
+ await Promise.all(actions.map((action) => action()))
16
+ return JSON.stringify(manifest, null, " ")
17
+ }
@@ -1,13 +1,18 @@
1
1
  export const jsenvPluginUrlResolution = () => {
2
- const urlResolver = ({ parentUrl, specifier }) => {
3
- return new URL(specifier, parentUrl).href
2
+ const urlResolver = (reference) => {
3
+ if (reference.specifier[0] === "#") {
4
+ reference.external = true
5
+ }
6
+ return new URL(
7
+ reference.specifier,
8
+ reference.baseUrl || reference.parentUrl,
9
+ ).href
4
10
  }
5
11
  return {
6
12
  name: "jsenv:url_resolution",
7
13
  appliesDuring: "*",
8
- resolve: {
14
+ resolveUrl: {
9
15
  "entry_point": urlResolver,
10
- "js_import_export": urlResolver,
11
16
  "link_href": urlResolver,
12
17
  "script_src": urlResolver,
13
18
  "a_href": urlResolver,
@@ -21,8 +26,10 @@ export const jsenvPluginUrlResolution = () => {
21
26
  "css_@import": urlResolver,
22
27
  "css_url": urlResolver,
23
28
  "sourcemap_comment": urlResolver,
24
- "js_import_meta_url_pattern": urlResolver,
29
+ "js_import_export": urlResolver,
30
+ "js_url_specifier": urlResolver,
25
31
  "js_inline_content": urlResolver,
32
+ "webmanifest_icon_src": urlResolver,
26
33
  },
27
34
  }
28
35
  }
@@ -4,27 +4,27 @@ export const jsenvPluginUrlVersion = ({
4
4
  return {
5
5
  name: "jsenv:url_version",
6
6
  appliesDuring: "*", // maybe only during dev?
7
- normalize: ({ url }) => {
7
+ normalizeUrl: (reference) => {
8
8
  // "v" search param goal is to enable long-term cache
9
9
  // for server response headers
10
10
  // it is also used by hmr to bypass browser cache
11
11
  // this goal is achieved when we reach this part of the code
12
12
  // We get rid of this params so that urlGraph and other parts of the code
13
13
  // recognize the url (it is not considered as a different url)
14
- const urlObject = new URL(url)
14
+ const urlObject = new URL(reference.url)
15
15
  urlObject.searchParams.delete("v")
16
16
  return urlObject.href
17
17
  },
18
- transformReferencedUrl: ({ url, data }) => {
19
- if (!data.version) {
18
+ transformUrl: (reference) => {
19
+ if (!reference.data.version) {
20
20
  return null
21
21
  }
22
- const urlObject = new URL(url)
23
- if (urlObject.searchParams.has("v")) {
22
+ if (reference.searchParams.has("v")) {
24
23
  return null
25
24
  }
26
- urlObject.searchParams.set("v", data.version)
27
- return urlObject.href
25
+ return {
26
+ v: reference.data.version,
27
+ }
28
28
  },
29
29
  augmentResponse: ({ url }) => {
30
30
  if (!longTermCache) {
@@ -0,0 +1,3 @@
1
+ export const preview = () => {
2
+ // TODO
3
+ }
@@ -9,7 +9,7 @@ import {
9
9
  ensureEmptyDirectory,
10
10
  normalizeStructuredMetaMap,
11
11
  urlToMeta,
12
- writeFile,
12
+ writeFileSync,
13
13
  } from "@jsenv/filesystem"
14
14
  import {
15
15
  createLogger,
@@ -22,7 +22,7 @@ import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
22
22
  import { babelPluginInstrument } from "@jsenv/utils/coverage/babel_plugin_instrument.js"
23
23
  import { reportToCoverage } from "@jsenv/utils/coverage/report_to_coverage.js"
24
24
  import { createUrlGraph } from "@jsenv/core/src/omega/url_graph.js"
25
- import { getCorePlugins } from "@jsenv/core/src/omega/core_plugins.js"
25
+ import { getCorePlugins } from "@jsenv/core/src/plugins/plugins.js"
26
26
  import { createKitchen } from "@jsenv/core/src/omega/kitchen.js"
27
27
  import { startOmegaServer } from "@jsenv/core/src/omega/omega_server.js"
28
28
  import { run } from "@jsenv/core/src/execute/run.js"
@@ -62,10 +62,11 @@ export const executePlan = async (
62
62
  coverageV8ConflictWarning,
63
63
  coverageTempDirectoryRelativeUrl,
64
64
 
65
- injectedGlobals,
66
- plugins,
67
65
  scenario,
68
66
  sourcemaps,
67
+ plugins,
68
+ transpilation,
69
+ injectedGlobals,
69
70
 
70
71
  protocol,
71
72
  privateKey,
@@ -133,12 +134,21 @@ export const executePlan = async (
133
134
  logger,
134
135
  rootDirectoryUrl,
135
136
  urlGraph,
137
+ scenario,
138
+ sourcemaps,
139
+ writeOnFileSystem: false,
136
140
  plugins: [
137
141
  ...plugins,
138
142
  ...getCorePlugins({
139
- babel: {
140
- getCustomBabelPlugins: ({ runtimeSupport }) => {
141
- if (coverage && Object.keys(runtimeSupport)[0] !== "chrome") {
143
+ htmlSupervisor: true,
144
+ injectedGlobals,
145
+ transpilation: {
146
+ ...transpilation,
147
+ getCustomBabelPlugins: ({ clientRuntimeCompat }) => {
148
+ if (
149
+ coverage &&
150
+ Object.keys(clientRuntimeCompat)[0] !== "chrome"
151
+ ) {
142
152
  return {
143
153
  "transform-instrument": [
144
154
  babelPluginInstrument,
@@ -152,11 +162,8 @@ export const executePlan = async (
152
162
  return {}
153
163
  },
154
164
  },
155
- injectedGlobals,
156
165
  }),
157
166
  ],
158
- scenario,
159
- sourcemaps,
160
167
  })
161
168
  const serverLogger = createLogger({ logLevel: "warn" })
162
169
  const server = await startOmegaServer({
@@ -435,7 +442,7 @@ export const executePlan = async (
435
442
  }
436
443
  if (summary.counters.total !== summary.counters.completed) {
437
444
  const logFileUrl = new URL(logFileRelativeUrl, rootDirectoryUrl).href
438
- writeFile(logFileUrl, rawOutput)
445
+ writeFileSync(logFileUrl, rawOutput)
439
446
  logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`)
440
447
  }
441
448
  const result = await transformReturnValue({
@@ -80,10 +80,9 @@ export const executeTestPlan = async ({
80
80
  // skip full means file with 100% coverage won't appear in coverage reports (log and html)
81
81
  coverageSkipFull = false,
82
82
 
83
- injectedGlobals,
84
- plugins = [],
85
- scenario = "test",
86
83
  sourcemaps = "inline",
84
+ plugins = [],
85
+ injectedGlobals,
87
86
 
88
87
  protocol,
89
88
  privateKey,
@@ -164,10 +163,10 @@ export const executeTestPlan = async ({
164
163
  coverageV8ConflictWarning,
165
164
  coverageTempDirectoryRelativeUrl,
166
165
 
167
- injectedGlobals,
168
- plugins,
169
- scenario,
166
+ scenario: "test",
170
167
  sourcemaps,
168
+ plugins,
169
+ injectedGlobals,
171
170
 
172
171
  protocol,
173
172
  privateKey,