@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
@@ -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
+ originalLine,
43
+ originalColumn,
44
+ specifier,
45
+ specifierLine: line,
46
+ specifierColumn: column,
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: "webmanifest",
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,67 @@
1
+ import { parseJsUrls } from "@jsenv/utils/js_ast/parse_js_urls.js"
2
+ import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
3
+ import { isWebWorkerUrlInfo } from "@jsenv/core/src/omega/web_workers.js"
4
+
5
+ export const parseAndTransformJsUrls = async (urlInfo, context) => {
6
+ const jsMentions = await parseJsUrls({
7
+ js: urlInfo.content,
8
+ url: (urlInfo.data && urlInfo.data.rawUrl) || urlInfo.url,
9
+ isJsModule: urlInfo.type === "js_module",
10
+ isWebWorker: isWebWorkerUrlInfo(urlInfo),
11
+ })
12
+ const { rootDirectoryUrl, referenceUtils } = context
13
+ const actions = []
14
+ const magicSource = createMagicSource(urlInfo.content)
15
+ urlInfo.data.usesImport = false
16
+ urlInfo.data.usesExport = false
17
+ urlInfo.data.usesImportAssertion = false
18
+ jsMentions.forEach((jsMention) => {
19
+ if (jsMention.assert) {
20
+ urlInfo.data.usesImportAssertion = true
21
+ }
22
+ if (
23
+ jsMention.subtype === "import_static" ||
24
+ jsMention.subtype === "import_dynamic"
25
+ ) {
26
+ urlInfo.data.usesImport = true
27
+ }
28
+ if (jsMention.subtype === "export") {
29
+ urlInfo.data.usesExport = true
30
+ }
31
+ const [reference] = referenceUtils.found({
32
+ type: jsMention.type,
33
+ subtype: jsMention.subtype,
34
+ expectedType: jsMention.expectedType,
35
+ expectedSubtype: jsMention.expectedSubtype || urlInfo.subtype,
36
+ specifier: jsMention.specifier,
37
+ specifierStart: jsMention.specifierStart,
38
+ specifierEnd: jsMention.specifierEnd,
39
+ specifierLine: jsMention.specifierLine,
40
+ specifierColumn: jsMention.specifierColumn,
41
+ data: jsMention.data,
42
+ baseUrl: {
43
+ "StringLiteral": jsMention.baseUrl,
44
+ "window.origin": rootDirectoryUrl,
45
+ "import.meta.url": urlInfo.url,
46
+ "context.meta.url": urlInfo.url,
47
+ "document.currentScript.src": urlInfo.url,
48
+ }[jsMention.baseUrlType],
49
+ assert: jsMention.assert,
50
+ assertNode: jsMention.assertNode,
51
+ typePropertyNode: jsMention.typePropertyNode,
52
+ })
53
+ actions.push(async () => {
54
+ magicSource.replace({
55
+ start: jsMention.specifierStart,
56
+ end: jsMention.specifierEnd,
57
+ replacement: await referenceUtils.readGeneratedSpecifier(reference),
58
+ })
59
+ if (reference.mutation) {
60
+ reference.mutation(magicSource)
61
+ }
62
+ })
63
+ })
64
+ await Promise.all(actions.map((action) => action()))
65
+ const { content, sourcemap } = magicSource.toContentAndSourcemap()
66
+ return { content, sourcemap }
67
+ }
@@ -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 jsenvPluginUrlAnalysis = () => {
7
+ return {
8
+ name: "jsenv:url_analysis",
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
  }
@@ -1,40 +1,37 @@
1
- export const jsenvPluginUrlVersion = ({
2
- longTermCache = false, // will become true once things get more stable
3
- } = {}) => {
1
+ export const jsenvPluginUrlVersion = ({ longTermCache = true } = {}) => {
4
2
  return {
5
3
  name: "jsenv:url_version",
6
4
  appliesDuring: "*", // maybe only during dev?
7
- normalize: ({ url }) => {
5
+ normalizeUrl: (reference) => {
8
6
  // "v" search param goal is to enable long-term cache
9
7
  // for server response headers
10
8
  // it is also used by hmr to bypass browser cache
11
9
  // this goal is achieved when we reach this part of the code
12
10
  // We get rid of this params so that urlGraph and other parts of the code
13
11
  // recognize the url (it is not considered as a different url)
14
- const urlObject = new URL(url)
12
+ const urlObject = new URL(reference.url)
15
13
  urlObject.searchParams.delete("v")
16
14
  return urlObject.href
17
15
  },
18
- transformReferencedUrl: ({ url, data }) => {
19
- if (!data.version) {
16
+ transformUrlSearchParams: (reference) => {
17
+ if (!reference.data.version) {
20
18
  return null
21
19
  }
22
- const urlObject = new URL(url)
23
- if (urlObject.searchParams.has("v")) {
20
+ if (reference.searchParams.has("v")) {
24
21
  return null
25
22
  }
26
- urlObject.searchParams.set("v", data.version)
27
- return urlObject.href
23
+ return {
24
+ v: reference.data.version,
25
+ }
28
26
  },
29
- augmentResponse: ({ url }) => {
27
+ augmentResponse: ({ reference }) => {
30
28
  if (!longTermCache) {
31
29
  return null
32
30
  }
33
- const urlObject = new URL(url)
34
- if (!urlObject.searchParams.has("v")) {
31
+ if (!reference.searchParams.has("v")) {
35
32
  return null
36
33
  }
37
- if (urlObject.searchParams.has("hmr")) {
34
+ if (reference.searchParams.has("hmr")) {
38
35
  return null
39
36
  }
40
37
  // When url is versioned put it in browser cache for 30 days
@@ -9,20 +9,16 @@ import {
9
9
  ensureEmptyDirectory,
10
10
  normalizeStructuredMetaMap,
11
11
  urlToMeta,
12
- writeFile,
12
+ writeFileSync,
13
13
  } from "@jsenv/filesystem"
14
- import {
15
- createLogger,
16
- createDetailedMessage,
17
- loggerToLevels,
18
- } from "@jsenv/logger"
14
+ import { createDetailedMessage, loggerToLevels } from "@jsenv/logger"
19
15
  import { createLog, startSpinner } from "@jsenv/log"
20
16
  import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
21
17
 
22
18
  import { babelPluginInstrument } from "@jsenv/utils/coverage/babel_plugin_instrument.js"
23
19
  import { reportToCoverage } from "@jsenv/utils/coverage/report_to_coverage.js"
24
20
  import { createUrlGraph } from "@jsenv/core/src/omega/url_graph.js"
25
- import { getCorePlugins } from "@jsenv/core/src/omega/core_plugins.js"
21
+ import { getCorePlugins } from "@jsenv/core/src/plugins/plugins.js"
26
22
  import { createKitchen } from "@jsenv/core/src/omega/kitchen.js"
27
23
  import { startOmegaServer } from "@jsenv/core/src/omega/omega_server.js"
28
24
  import { run } from "@jsenv/core/src/execute/run.js"
@@ -62,9 +58,13 @@ export const executePlan = async (
62
58
  coverageV8ConflictWarning,
63
59
  coverageTempDirectoryRelativeUrl,
64
60
 
65
- plugins = [],
66
- scenario = "test",
67
- sourcemaps = "inline",
61
+ scenario,
62
+ sourcemaps,
63
+ plugins,
64
+ injectedGlobals,
65
+ nodeEsmResolution,
66
+ fileSystemMagicResolution,
67
+ transpilation,
68
68
 
69
69
  protocol,
70
70
  privateKey,
@@ -132,12 +132,27 @@ export const executePlan = async (
132
132
  logger,
133
133
  rootDirectoryUrl,
134
134
  urlGraph,
135
+ scenario,
136
+ sourcemaps,
137
+ writeOnFileSystem: false,
135
138
  plugins: [
136
139
  ...plugins,
137
140
  ...getCorePlugins({
138
- babel: {
139
- getCustomBabelPlugins: ({ runtimeSupport }) => {
140
- if (coverage && Object.keys(runtimeSupport)[0] !== "chrome") {
141
+ rootDirectoryUrl,
142
+ urlGraph,
143
+ scenario,
144
+
145
+ htmlSupervisor: true,
146
+ nodeEsmResolution,
147
+ fileSystemMagicResolution,
148
+ injectedGlobals,
149
+ transpilation: {
150
+ ...transpilation,
151
+ getCustomBabelPlugins: ({ clientRuntimeCompat }) => {
152
+ if (
153
+ coverage &&
154
+ Object.keys(clientRuntimeCompat)[0] !== "chrome"
155
+ ) {
141
156
  return {
142
157
  "transform-instrument": [
143
158
  babelPluginInstrument,
@@ -153,13 +168,10 @@ export const executePlan = async (
153
168
  },
154
169
  }),
155
170
  ],
156
- scenario,
157
- sourcemaps,
158
171
  })
159
- const serverLogger = createLogger({ logLevel: "warn" })
160
172
  const server = await startOmegaServer({
161
173
  signal: multipleExecutionsOperation.signal,
162
- logger: serverLogger,
174
+ logLevel: "warn",
163
175
  rootDirectoryUrl,
164
176
  urlGraph,
165
177
  kitchen,
@@ -433,7 +445,7 @@ export const executePlan = async (
433
445
  }
434
446
  if (summary.counters.total !== summary.counters.completed) {
435
447
  const logFileUrl = new URL(logFileRelativeUrl, rootDirectoryUrl).href
436
- writeFile(logFileUrl, rawOutput)
448
+ writeFileSync(logFileUrl, rawOutput)
437
449
  logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`)
438
450
  }
439
451
  const result = await transformReturnValue({
@@ -13,6 +13,14 @@ import { generateCoverageHtmlDirectory } from "@jsenv/utils/coverage/coverage_re
13
13
  import { generateCoverageTextLog } from "@jsenv/utils/coverage/coverage_reporter_text_log.js"
14
14
  import { executePlan } from "./execute_plan.js"
15
15
 
16
+ export const defaultCoverageConfig = {
17
+ "./index.js": true,
18
+ "./main.js": true,
19
+ "./src/**/*.js": true,
20
+ "./**/*.test.*": false, // contains .test. -> nope
21
+ "./**/test/": false, // inside a test folder -> nope,
22
+ }
23
+
16
24
  /**
17
25
  * Execute a list of files and log how it goes
18
26
  * @param {Object} testPlanParameters
@@ -57,13 +65,7 @@ export const executeTestPlan = async ({
57
65
  coverage = process.argv.includes("--cover") ||
58
66
  process.argv.includes("--coverage"),
59
67
  coverageTempDirectoryRelativeUrl = "./.coverage/tmp/",
60
- coverageConfig = {
61
- "./index.js": true,
62
- "./main.js": true,
63
- "./src/**/*.js": true,
64
- "./**/*.test.*": false, // contains .test. -> nope
65
- "./**/test/": false, // inside a test folder -> nope,
66
- },
68
+ coverageConfig = defaultCoverageConfig,
67
69
  coverageIncludeMissing = true,
68
70
  coverageAndExecutionAllowed = false,
69
71
  coverageForceIstanbul = false,
@@ -80,6 +82,12 @@ export const executeTestPlan = async ({
80
82
  // skip full means file with 100% coverage won't appear in coverage reports (log and html)
81
83
  coverageSkipFull = false,
82
84
 
85
+ sourcemaps = "inline",
86
+ plugins = [],
87
+ injectedGlobals,
88
+ nodeEsmResolution,
89
+ fileSystemMagicResolution,
90
+
83
91
  protocol,
84
92
  privateKey,
85
93
  certificate,
@@ -143,8 +151,8 @@ export const executeTestPlan = async ({
143
151
  logFileRelativeUrl,
144
152
  completedExecutionLogMerging,
145
153
  completedExecutionLogAbbreviation,
146
-
147
154
  rootDirectoryUrl,
155
+
148
156
  maxExecutionsInParallel,
149
157
  defaultMsAllocatedPerExecution,
150
158
  failFast,
@@ -159,6 +167,13 @@ export const executeTestPlan = async ({
159
167
  coverageV8ConflictWarning,
160
168
  coverageTempDirectoryRelativeUrl,
161
169
 
170
+ scenario: "test",
171
+ sourcemaps,
172
+ plugins,
173
+ injectedGlobals,
174
+ nodeEsmResolution,
175
+ fileSystemMagicResolution,
176
+
162
177
  protocol,
163
178
  privateKey,
164
179
  certificate,
@@ -38,7 +38,8 @@ export const formatExecutionResult = (
38
38
  { completedExecutionLogAbbreviation, counters, memoryHeap },
39
39
  ) => {
40
40
  const { status } = executionResult
41
- const description = descriptionFormatters[status]({
41
+ const descriptionFormatter = descriptionFormatters[status]
42
+ const description = descriptionFormatter({
42
43
  index: executionIndex,
43
44
  total: counters.total,
44
45
  executionParams,
@@ -52,7 +53,7 @@ export const formatExecutionResult = (
52
53
  return `${description} ${summary}`
53
54
  }
54
55
  const { consoleCalls = [], error, duration } = executionResult
55
- const console = formatConsoleCalls(consoleCalls)
56
+ const consoleOutput = formatConsoleCalls(consoleCalls)
56
57
  return formatExecution({
57
58
  label: `${description} ${summary}`,
58
59
  details: {
@@ -61,7 +62,7 @@ export const formatExecutionResult = (
61
62
  duration: msAsDuration(duration),
62
63
  ...(error ? { error: error.stack } : {}),
63
64
  },
64
- console,
65
+ consoleOutput,
65
66
  })
66
67
  }
67
68
 
@@ -203,21 +204,21 @@ const formatConsoleCalls = (consoleCalls) => {
203
204
  if (consoleOutputTrimmed === "") {
204
205
  return ""
205
206
  }
206
- return `${ANSI.color(`-------- console --------`, ANSI.GREY)}
207
+ return `${ANSI.color(`-------- console output --------`, ANSI.GREY)}
207
208
  ${consoleOutputTrimmed}
208
209
  ${ANSI.color(`-------------------------`, ANSI.GREY)}`
209
210
  }
210
211
 
211
- const formatExecution = ({ label, details = {}, console }) => {
212
+ const formatExecution = ({ label, details = {}, consoleOutput }) => {
212
213
  let message = ``
213
214
  message += label
214
215
  Object.keys(details).forEach((key) => {
215
216
  message += `
216
217
  ${key}: ${details[key]}`
217
218
  })
218
- if (console) {
219
+ if (consoleOutput) {
219
220
  message += `
220
- ${console}`
221
+ ${consoleOutput}`
221
222
  }
222
223
  return message
223
224
  }