@jsenv/core 27.0.0-alpha.6 → 27.0.0-alpha.62

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 (150) hide show
  1. package/dist/event_source_client.js +549 -0
  2. package/dist/event_source_client.js.map +188 -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 +36 -29
  11. package/readme.md +6 -14
  12. package/src/build/build.js +961 -559
  13. package/src/build/build_urls_generator.js +48 -23
  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 +200 -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 +150 -34
  22. package/src/execute/execute.js +33 -6
  23. package/src/execute/run.js +19 -56
  24. package/src/execute/runtimes/browsers/from_playwright.js +207 -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 +475 -308
  36. package/src/omega/omega_server.js +2 -3
  37. package/src/omega/server/file_service.js +57 -26
  38. package/src/omega/server/user_agent.js +4 -2
  39. package/src/omega/url_graph/url_graph_load.js +22 -7
  40. package/src/omega/url_graph/url_graph_report.js +94 -51
  41. package/src/omega/url_graph/url_info_transformations.js +26 -9
  42. package/src/omega/url_graph.js +80 -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 +19 -12
  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 +140 -0
  53. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  54. package/src/plugins/bundling/js_module/bundle_js_module.js +309 -0
  55. package/src/plugins/bundling/jsenv_plugin_bundling.js +54 -0
  56. package/src/plugins/cache_control/jsenv_plugin_cache_control.js +34 -0
  57. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  58. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  59. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +8 -5
  60. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  61. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  62. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +242 -0
  63. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +79 -0
  64. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  65. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  66. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +83 -61
  67. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  68. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  69. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  70. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +7 -4
  71. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +105 -0
  72. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  73. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  74. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  75. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +39 -33
  76. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +67 -0
  77. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  78. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  79. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +65 -44
  80. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  81. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  82. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +297 -0
  83. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  84. package/src/plugins/minification/css/minify_css.js +9 -0
  85. package/src/plugins/minification/html/minify_html.js +15 -0
  86. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  87. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  88. package/src/plugins/minification/json/minify_json.js +8 -0
  89. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +146 -0
  90. package/src/{omega → plugins}/plugin_controller.js +42 -11
  91. package/src/plugins/plugins.js +92 -0
  92. package/src/plugins/transpilation/as_js_classic/client/s.js +874 -0
  93. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  94. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  95. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  96. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +199 -0
  97. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +270 -0
  98. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +55 -0
  99. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  100. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  101. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  102. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +12 -19
  103. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  104. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +45 -27
  105. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  106. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  107. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  108. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  109. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  110. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  111. package/src/plugins/transpilation/fetch_original_url_info.js +30 -0
  112. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +181 -0
  113. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +80 -0
  114. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +44 -0
  115. package/src/plugins/url_analysis/css/css_urls.js +49 -0
  116. package/src/plugins/url_analysis/html/html_urls.js +269 -0
  117. package/src/plugins/url_analysis/js/js_urls.js +67 -0
  118. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +18 -0
  119. package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +17 -0
  120. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  121. package/src/plugins/url_version/jsenv_plugin_url_version.js +28 -0
  122. package/src/test/execute_plan.js +38 -19
  123. package/src/test/execute_test_plan.js +25 -8
  124. package/src/test/logs_file_execution.js +10 -12
  125. package/src/build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js +0 -225
  126. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  127. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  128. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +0 -374
  129. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  130. package/src/execute/runtimes/node/controlled_process.js +0 -316
  131. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  132. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_installer.js +0 -168
  133. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_setup.js +0 -77
  134. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  135. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  136. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  137. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  138. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  139. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  140. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  141. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  142. package/src/omega/core_plugins/url_version/jsenv_plugin_url_version.js +0 -50
  143. package/src/omega/core_plugins.js +0 -39
  144. package/src/omega/runtime_support/runtime_support.js +0 -20
  145. package/src/omega/url_graph/url_graph_sort.js +0 -29
  146. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  147. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  148. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  149. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  150. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -0,0 +1,269 @@
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 visitors = {
100
+ link: (node) => {
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
+ },
118
+ // style: () => {},
119
+ script: (node) => {
120
+ const typeAttributeNode = getHtmlNodeAttributeByName(node, "type")
121
+ visitAttributeAsUrlSpecifier({
122
+ type: "script_src",
123
+ expectedType: {
124
+ "undefined": "js_classic",
125
+ "text/javascript": "js_classic",
126
+ "module": "js_module",
127
+ "importmap": "importmap",
128
+ }[typeAttributeNode ? typeAttributeNode.value : undefined],
129
+ node,
130
+ attributeName: "src",
131
+ })
132
+ },
133
+ a: (node) => {
134
+ visitAttributeAsUrlSpecifier({
135
+ type: "a_href",
136
+ node,
137
+ attributeName: "href",
138
+ })
139
+ },
140
+ iframe: (node) => {
141
+ visitAttributeAsUrlSpecifier({
142
+ type: "iframe_src",
143
+ node,
144
+ attributeName: "src",
145
+ })
146
+ },
147
+ img: (node) => {
148
+ visitAttributeAsUrlSpecifier({
149
+ type: "img_src",
150
+ node,
151
+ attributeName: "src",
152
+ })
153
+ visitSrcset({
154
+ type: "img_srcset",
155
+ node,
156
+ })
157
+ },
158
+ souce: (node) => {
159
+ visitAttributeAsUrlSpecifier({
160
+ type: "source_src",
161
+ node,
162
+ attributeName: "src",
163
+ })
164
+ visitSrcset({
165
+ type: "source_srcset",
166
+ node,
167
+ })
168
+ },
169
+ // svg <image> tag
170
+ image: (node) => {
171
+ visitAttributeAsUrlSpecifier({
172
+ type: "image_href",
173
+ node,
174
+ attributeName: "href",
175
+ })
176
+ },
177
+ use: (node) => {
178
+ visitAttributeAsUrlSpecifier({
179
+ type: "use_href",
180
+ node,
181
+ attributeName: "href",
182
+ })
183
+ },
184
+ }
185
+ const visitAttributeAsUrlSpecifier = ({
186
+ type,
187
+ subtype,
188
+ expectedType,
189
+ node,
190
+ attributeName,
191
+ }) => {
192
+ const attribute = getHtmlNodeAttributeByName(node, attributeName)
193
+ const value = attribute ? attribute.value : undefined
194
+ if (value) {
195
+ const generatedBy = getHtmlNodeAttributeByName(node, "generated-by")
196
+ if (generatedBy) {
197
+ // during build the importmap is inlined
198
+ // and shoud not be considered as a dependency anymore
199
+ return
200
+ }
201
+ addDependency({
202
+ type,
203
+ subtype,
204
+ expectedType,
205
+ node,
206
+ attribute,
207
+ specifier:
208
+ attributeName === "generated-from-src" ||
209
+ attributeName === "generated-from-href"
210
+ ? new URL(value, url).href
211
+ : value,
212
+ })
213
+ } else if (attributeName === "src") {
214
+ visitAttributeAsUrlSpecifier({
215
+ type,
216
+ subtype,
217
+ expectedType,
218
+ node,
219
+ attributeName: "generated-from-src",
220
+ })
221
+ } else if (attributeName === "href") {
222
+ visitAttributeAsUrlSpecifier({
223
+ type,
224
+ subtype,
225
+ expectedType,
226
+ node,
227
+ attributeName: "generated-from-href",
228
+ })
229
+ }
230
+ }
231
+ const visitSrcset = ({ type, node }) => {
232
+ const srcsetAttribute = getHtmlNodeAttributeByName(node, "srcset")
233
+ const srcset = srcsetAttribute ? srcsetAttribute.value : undefined
234
+ if (srcset) {
235
+ const srcCandidates = htmlAttributeSrcSet.parse(srcset)
236
+ srcCandidates.forEach((srcCandidate) => {
237
+ addDependency({
238
+ type,
239
+ node,
240
+ attribute: srcsetAttribute,
241
+ specifier: srcCandidate.specifier,
242
+ })
243
+ })
244
+ }
245
+ }
246
+ visitHtmlAst(htmlAst, (node) => {
247
+ const visitor = visitors[node.nodeName]
248
+ if (visitor) {
249
+ visitor(node)
250
+ }
251
+ })
252
+ }
253
+
254
+ const crossOriginCompatibleTagNames = ["script", "link", "img", "source"]
255
+ const integrityCompatibleTagNames = ["script", "link", "img", "source"]
256
+ const readFetchMetas = (node) => {
257
+ const meta = {}
258
+ if (crossOriginCompatibleTagNames.includes(node.nodeName)) {
259
+ const crossoriginAttribute = getHtmlNodeAttributeByName(node, "crossorigin")
260
+ meta.crossorigin = crossoriginAttribute
261
+ ? crossoriginAttribute.value
262
+ : undefined
263
+ }
264
+ if (integrityCompatibleTagNames.includes(node.nodeName)) {
265
+ const integrityAttribute = getHtmlNodeAttributeByName(node, "integrity")
266
+ meta.integrity = integrityAttribute ? integrityAttribute.value : undefined
267
+ }
268
+ return meta
269
+ }
@@ -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
  }
@@ -0,0 +1,28 @@
1
+ export const jsenvPluginUrlVersion = () => {
2
+ return {
3
+ name: "jsenv:url_version",
4
+ appliesDuring: "*",
5
+ redirectUrl: (reference) => {
6
+ // "v" search param goal is to enable long-term cache
7
+ // for server response headers
8
+ // it is also used by hmr to bypass browser cache
9
+ // this goal is achieved when we reach this part of the code
10
+ // We get rid of this params so that urlGraph and other parts of the code
11
+ // recognize the url (it is not considered as a different url)
12
+ const urlObject = new URL(reference.url)
13
+ urlObject.searchParams.delete("v")
14
+ return urlObject.href
15
+ },
16
+ transformUrlSearchParams: (reference) => {
17
+ if (!reference.data.version) {
18
+ return null
19
+ }
20
+ if (reference.searchParams.has("v")) {
21
+ return null
22
+ }
23
+ return {
24
+ v: reference.data.version,
25
+ }
26
+ },
27
+ }
28
+ }
@@ -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,14 @@ 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
+ writeGeneratedFiles,
68
69
 
69
70
  protocol,
70
71
  privateKey,
@@ -132,12 +133,27 @@ export const executePlan = async (
132
133
  logger,
133
134
  rootDirectoryUrl,
134
135
  urlGraph,
136
+ scenario,
137
+ sourcemaps,
138
+ writeGeneratedFiles,
135
139
  plugins: [
136
140
  ...plugins,
137
141
  ...getCorePlugins({
138
- babel: {
139
- getCustomBabelPlugins: ({ runtimeSupport }) => {
140
- if (coverage && Object.keys(runtimeSupport)[0] !== "chrome") {
142
+ rootDirectoryUrl,
143
+ urlGraph,
144
+ scenario,
145
+
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
+ ) {
141
157
  return {
142
158
  "transform-instrument": [
143
159
  babelPluginInstrument,
@@ -153,13 +169,10 @@ export const executePlan = async (
153
169
  },
154
170
  }),
155
171
  ],
156
- scenario,
157
- sourcemaps,
158
172
  })
159
- const serverLogger = createLogger({ logLevel: "warn" })
160
173
  const server = await startOmegaServer({
161
174
  signal: multipleExecutionsOperation.signal,
162
- logger: serverLogger,
175
+ logLevel: "warn",
163
176
  rootDirectoryUrl,
164
177
  urlGraph,
165
178
  kitchen,
@@ -196,7 +209,13 @@ export const executePlan = async (
196
209
  const debugLogsEnabled = loggerToLevels(logger).debug
197
210
  const executionLogsEnabled = loggerToLevels(logger).info
198
211
  const executionSpinner =
199
- !debugLogsEnabled && executionLogsEnabled && process.stdout.isTTY
212
+ !debugLogsEnabled &&
213
+ executionLogsEnabled &&
214
+ process.stdout.isTTY &&
215
+ // if there is an error during execution npm will mess up the output
216
+ // (happens when npm runs several command in a workspace)
217
+ // so we enable spinner only when !process.exitCode (no error so far)
218
+ !process.exitCode
200
219
 
201
220
  const startMs = Date.now()
202
221
  const report = {}
@@ -433,7 +452,7 @@ export const executePlan = async (
433
452
  }
434
453
  if (summary.counters.total !== summary.counters.completed) {
435
454
  const logFileUrl = new URL(logFileRelativeUrl, rootDirectoryUrl).href
436
- writeFile(logFileUrl, rawOutput)
455
+ writeFileSync(logFileUrl, rawOutput)
437
456
  logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`)
438
457
  }
439
458
  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,13 @@ 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
+ writeGeneratedFiles = false,
91
+
83
92
  protocol,
84
93
  privateKey,
85
94
  certificate,
@@ -143,8 +152,8 @@ export const executeTestPlan = async ({
143
152
  logFileRelativeUrl,
144
153
  completedExecutionLogMerging,
145
154
  completedExecutionLogAbbreviation,
146
-
147
155
  rootDirectoryUrl,
156
+
148
157
  maxExecutionsInParallel,
149
158
  defaultMsAllocatedPerExecution,
150
159
  failFast,
@@ -159,6 +168,14 @@ export const executeTestPlan = async ({
159
168
  coverageV8ConflictWarning,
160
169
  coverageTempDirectoryRelativeUrl,
161
170
 
171
+ scenario: "test",
172
+ sourcemaps,
173
+ plugins,
174
+ injectedGlobals,
175
+ nodeEsmResolution,
176
+ fileSystemMagicResolution,
177
+ writeGeneratedFiles,
178
+
162
179
  protocol,
163
180
  privateKey,
164
181
  certificate,
@@ -1,7 +1,4 @@
1
- import { ANSI, UNICODE } from "@jsenv/log"
2
-
3
- import { msAsDuration } from "@jsenv/utils/logs/duration_log.js"
4
- import { byteAsMemoryUsage } from "@jsenv/utils/logs/size_log.js"
1
+ import { ANSI, UNICODE, msAsDuration, byteAsMemoryUsage } from "@jsenv/log"
5
2
 
6
3
  import { EXECUTION_COLORS } from "./execution_colors.js"
7
4
 
@@ -38,7 +35,8 @@ export const formatExecutionResult = (
38
35
  { completedExecutionLogAbbreviation, counters, memoryHeap },
39
36
  ) => {
40
37
  const { status } = executionResult
41
- const description = descriptionFormatters[status]({
38
+ const descriptionFormatter = descriptionFormatters[status]
39
+ const description = descriptionFormatter({
42
40
  index: executionIndex,
43
41
  total: counters.total,
44
42
  executionParams,
@@ -52,16 +50,16 @@ export const formatExecutionResult = (
52
50
  return `${description} ${summary}`
53
51
  }
54
52
  const { consoleCalls = [], error, duration } = executionResult
55
- const console = formatConsoleCalls(consoleCalls)
53
+ const consoleOutput = formatConsoleCalls(consoleCalls)
56
54
  return formatExecution({
57
55
  label: `${description} ${summary}`,
58
56
  details: {
59
57
  file: fileRelativeUrl,
60
58
  runtime: `${runtimeName}/${runtimeVersion}`,
61
59
  duration: msAsDuration(duration),
62
- ...(error ? { error: error.stack } : {}),
60
+ ...(error ? { error: error.stack || error.message || error } : {}),
63
61
  },
64
- console,
62
+ consoleOutput,
65
63
  })
66
64
  }
67
65
 
@@ -203,21 +201,21 @@ const formatConsoleCalls = (consoleCalls) => {
203
201
  if (consoleOutputTrimmed === "") {
204
202
  return ""
205
203
  }
206
- return `${ANSI.color(`-------- console --------`, ANSI.GREY)}
204
+ return `${ANSI.color(`-------- console output --------`, ANSI.GREY)}
207
205
  ${consoleOutputTrimmed}
208
206
  ${ANSI.color(`-------------------------`, ANSI.GREY)}`
209
207
  }
210
208
 
211
- const formatExecution = ({ label, details = {}, console }) => {
209
+ const formatExecution = ({ label, details = {}, consoleOutput }) => {
212
210
  let message = ``
213
211
  message += label
214
212
  Object.keys(details).forEach((key) => {
215
213
  message += `
216
214
  ${key}: ${details[key]}`
217
215
  })
218
- if (console) {
216
+ if (consoleOutput) {
219
217
  message += `
220
- ${console}`
218
+ ${consoleOutput}`
221
219
  }
222
220
  return message
223
221
  }