@jsenv/core 27.0.0-alpha.12 → 27.0.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/main.js +4 -0
  2. package/package.json +15 -11
  3. package/readme.md +4 -12
  4. package/src/build/build.js +451 -388
  5. package/src/build/build_urls_generator.js +23 -20
  6. package/src/build/graph_utils.js +31 -0
  7. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +31 -14
  8. package/src/build/inject_service_worker_urls.js +66 -12
  9. package/src/build/resync_ressource_hints.js +83 -0
  10. package/src/build/start_build_server.js +176 -0
  11. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  12. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  13. package/src/dev/start_dev_server.js +16 -22
  14. package/src/execute/execute.js +19 -6
  15. package/src/execute/run.js +17 -54
  16. package/src/execute/runtimes/browsers/from_playwright.js +167 -146
  17. package/src/execute/runtimes/node/node_process.js +281 -37
  18. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  19. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +30 -7
  20. package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +14 -16
  21. package/src/omega/errors.js +51 -58
  22. package/src/omega/fetched_content_compliance.js +24 -0
  23. package/src/omega/kitchen.js +403 -283
  24. package/src/omega/server/file_service.js +9 -11
  25. package/src/omega/url_graph/url_graph_load.js +13 -7
  26. package/src/omega/url_graph/url_graph_report.js +7 -5
  27. package/src/omega/url_graph.js +22 -10
  28. package/src/omega/web_workers.js +42 -0
  29. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  30. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  31. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  32. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  33. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +41 -0
  34. package/src/{dev/plugins/autoreload/jsenv_plugin_autoreload.js → plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js} +25 -166
  35. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
  36. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  37. package/src/plugins/bundling/css/bundle_css.js +17 -0
  38. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  39. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +100 -75
  40. package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
  41. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +48 -41
  42. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  43. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +7 -4
  44. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  45. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  46. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
  47. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
  48. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  49. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  50. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +38 -46
  51. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  52. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  53. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  54. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  55. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +98 -0
  56. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +26 -8
  57. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  58. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  59. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
  60. package/src/{omega/core_plugins → plugins}/inject_globals/jsenv_plugin_inject_globals.js +4 -6
  61. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  62. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  63. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
  64. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  65. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  66. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +263 -0
  67. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  68. package/src/plugins/minification/css/minify_css.js +9 -0
  69. package/src/plugins/minification/html/minify_html.js +15 -0
  70. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  71. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  72. package/src/plugins/minification/json/minify_json.js +8 -0
  73. package/src/{omega/core_plugins → plugins}/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +15 -15
  74. package/src/{omega → plugins}/plugin_controller.js +18 -10
  75. package/src/plugins/plugins.js +73 -0
  76. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  77. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  78. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  79. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  80. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +191 -0
  81. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +156 -0
  82. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_top_level_await.js +37 -0
  83. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +133 -0
  84. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  85. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  86. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  87. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +3 -21
  88. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  89. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +29 -27
  90. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +0 -0
  91. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  92. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  93. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  94. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  95. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  96. package/src/{omega/core_plugins → plugins/transpilation}/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -0
  97. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +243 -0
  98. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +40 -0
  99. package/src/plugins/url_references/css/css_urls.js +49 -0
  100. package/src/plugins/url_references/html/html_urls.js +273 -0
  101. package/src/plugins/url_references/js/js_urls.js +170 -0
  102. package/src/plugins/url_references/jsenv_plugin_url_references.js +18 -0
  103. package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
  104. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  105. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +8 -8
  106. package/src/test/execute_plan.js +23 -11
  107. package/src/test/execute_test_plan.js +9 -6
  108. package/src/test/logs_file_execution.js +8 -7
  109. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  110. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  111. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  112. package/src/execute/runtimes/node/controlled_process.js +0 -316
  113. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  114. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  115. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  116. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  117. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  118. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -207
  119. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  120. package/src/omega/core_plugins.js +0 -42
  121. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  122. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  123. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  124. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  125. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -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) {
@@ -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,13 @@ 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
+ injectedGlobals,
69
+ nodeEsmResolution,
70
+ fileSystemMagicResolution,
71
+ transpilation,
69
72
 
70
73
  protocol,
71
74
  privateKey,
@@ -133,12 +136,24 @@ export const executePlan = async (
133
136
  logger,
134
137
  rootDirectoryUrl,
135
138
  urlGraph,
139
+ scenario,
140
+ sourcemaps,
141
+ writeOnFileSystem: false,
136
142
  plugins: [
137
143
  ...plugins,
138
144
  ...getCorePlugins({
139
- babel: {
140
- getCustomBabelPlugins: ({ runtimeSupport }) => {
141
- if (coverage && Object.keys(runtimeSupport)[0] !== "chrome") {
145
+ scenario,
146
+ htmlSupervisor: true,
147
+ nodeEsmResolution,
148
+ fileSystemMagicResolution,
149
+ injectedGlobals,
150
+ transpilation: {
151
+ ...transpilation,
152
+ getCustomBabelPlugins: ({ clientRuntimeCompat }) => {
153
+ if (
154
+ coverage &&
155
+ Object.keys(clientRuntimeCompat)[0] !== "chrome"
156
+ ) {
142
157
  return {
143
158
  "transform-instrument": [
144
159
  babelPluginInstrument,
@@ -152,11 +167,8 @@ export const executePlan = async (
152
167
  return {}
153
168
  },
154
169
  },
155
- injectedGlobals,
156
170
  }),
157
171
  ],
158
- scenario,
159
- sourcemaps,
160
172
  })
161
173
  const serverLogger = createLogger({ logLevel: "warn" })
162
174
  const server = await startOmegaServer({
@@ -435,7 +447,7 @@ export const executePlan = async (
435
447
  }
436
448
  if (summary.counters.total !== summary.counters.completed) {
437
449
  const logFileUrl = new URL(logFileRelativeUrl, rootDirectoryUrl).href
438
- writeFile(logFileUrl, rawOutput)
450
+ writeFileSync(logFileUrl, rawOutput)
439
451
  logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`)
440
452
  }
441
453
  const result = await transformReturnValue({
@@ -80,10 +80,11 @@ 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,
86
+ nodeEsmResolution,
87
+ fileSystemMagicResolution,
87
88
 
88
89
  protocol,
89
90
  privateKey,
@@ -164,10 +165,12 @@ export const executeTestPlan = async ({
164
165
  coverageV8ConflictWarning,
165
166
  coverageTempDirectoryRelativeUrl,
166
167
 
167
- injectedGlobals,
168
- plugins,
169
- scenario,
168
+ scenario: "test",
170
169
  sourcemaps,
170
+ plugins,
171
+ injectedGlobals,
172
+ nodeEsmResolution,
173
+ fileSystemMagicResolution,
171
174
 
172
175
  protocol,
173
176
  privateKey,