@jsenv/core 27.0.0-alpha.4 → 27.0.0-alpha.40

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 (141) 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 +1145 -0
  4. package/dist/html_supervisor_installer.js.map +322 -0
  5. package/dist/html_supervisor_setup.js +92 -0
  6. package/dist/html_supervisor_setup.js.map +57 -0
  7. package/main.js +8 -1
  8. package/package.json +22 -21
  9. package/readme.md +4 -12
  10. package/src/build/build.js +731 -433
  11. package/src/build/build_urls_generator.js +55 -21
  12. package/src/build/graph_utils.js +31 -0
  13. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +33 -15
  14. package/src/build/inject_service_worker_urls.js +79 -0
  15. package/src/build/resync_ressource_hints.js +68 -0
  16. package/src/build/start_build_server.js +205 -0
  17. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  18. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  19. package/src/dev/start_dev_server.js +58 -26
  20. package/src/execute/execute.js +30 -4
  21. package/src/execute/run.js +19 -56
  22. package/src/execute/runtimes/browsers/from_playwright.js +201 -147
  23. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  24. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  25. package/src/execute/runtimes/node/node_process.js +280 -39
  26. package/src/jsenv_root_directory_url.js +1 -0
  27. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  28. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +66 -4
  29. package/src/omega/compat/runtime_compat.js +50 -0
  30. package/src/omega/errors.js +51 -58
  31. package/src/omega/fetched_content_compliance.js +24 -0
  32. package/src/omega/file_url_converter.js +8 -50
  33. package/src/omega/kitchen.js +414 -285
  34. package/src/omega/server/file_service.js +21 -22
  35. package/src/omega/url_graph/url_graph_load.js +14 -7
  36. package/src/omega/url_graph/url_graph_report.js +17 -15
  37. package/src/omega/url_graph/url_info_transformations.js +17 -5
  38. package/src/omega/url_graph.js +33 -10
  39. package/src/omega/web_workers.js +42 -0
  40. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  41. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  42. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  43. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  44. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +46 -0
  45. package/src/{dev/plugins/autoreload/jsenv_plugin_autoreload.js → plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js} +31 -172
  46. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +27 -0
  47. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  48. package/src/plugins/bundling/css/bundle_css.js +21 -0
  49. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  50. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +120 -79
  51. package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
  52. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  53. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  54. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +8 -5
  55. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  56. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  57. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
  58. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
  59. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  60. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  61. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +52 -55
  62. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  63. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  64. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  65. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  66. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +101 -0
  67. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  68. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  69. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  70. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
  71. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +67 -0
  72. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  73. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  74. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
  75. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  76. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  77. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +296 -0
  78. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  79. package/src/plugins/minification/css/minify_css.js +9 -0
  80. package/src/plugins/minification/html/minify_html.js +15 -0
  81. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  82. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  83. package/src/plugins/minification/json/minify_json.js +8 -0
  84. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +146 -0
  85. package/src/{omega → plugins}/plugin_controller.js +39 -11
  86. package/src/plugins/plugins.js +89 -0
  87. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  88. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  89. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  90. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  91. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +183 -0
  92. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +256 -0
  93. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +93 -0
  94. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  95. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  96. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  97. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +4 -22
  98. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  99. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +37 -21
  100. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  101. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  102. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  103. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  104. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  105. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  106. package/src/plugins/transpilation/fetch_original_url_info.js +30 -0
  107. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +200 -0
  108. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +70 -0
  109. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +44 -0
  110. package/src/plugins/url_references/css/css_urls.js +49 -0
  111. package/src/plugins/url_references/html/html_urls.js +273 -0
  112. package/src/plugins/url_references/js/js_urls.js +43 -0
  113. package/src/plugins/url_references/jsenv_plugin_imports_analysis.js +46 -0
  114. package/src/plugins/url_references/jsenv_plugin_url_analysis.js +18 -0
  115. package/src/plugins/url_references/jsenv_plugin_url_references.js +6 -0
  116. package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
  117. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  118. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +12 -15
  119. package/src/test/execute_plan.js +28 -11
  120. package/src/test/execute_test_plan.js +23 -8
  121. package/src/test/logs_file_execution.js +8 -7
  122. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  123. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  124. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  125. package/src/execute/runtimes/node/controlled_process.js +0 -316
  126. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  127. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  128. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  129. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  130. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  131. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  132. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  133. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  134. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  135. package/src/omega/core_plugins.js +0 -39
  136. package/src/omega/runtime_support/runtime_support.js +0 -20
  137. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  138. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  139. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  140. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  141. 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: "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,43 @@
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
+ jsMentions.forEach((jsMention) => {
16
+ const [reference] = referenceUtils.found({
17
+ type: jsMention.type,
18
+ subtype: jsMention.subtype,
19
+ expectedType: jsMention.expectedType,
20
+ expectedSubtype: jsMention.expectedSubtype || urlInfo.subtype,
21
+ line: jsMention.line,
22
+ column: jsMention.column,
23
+ specifier: jsMention.specifier,
24
+ data: jsMention.data,
25
+ baseUrl: {
26
+ "StringLiteral": jsMention.baseUrl,
27
+ "window.origin": rootDirectoryUrl,
28
+ "import.meta.url": urlInfo.url,
29
+ "context.meta.url": urlInfo.url,
30
+ "document.currentScript.src": urlInfo.url,
31
+ }[jsMention.baseUrlType],
32
+ })
33
+ actions.push(async () => {
34
+ magicSource.replace({
35
+ start: jsMention.start,
36
+ end: jsMention.end,
37
+ replacement: await referenceUtils.readGeneratedSpecifier(reference),
38
+ })
39
+ })
40
+ })
41
+ await Promise.all(actions.map((action) => action()))
42
+ return magicSource.toContentAndSourcemap()
43
+ }
@@ -0,0 +1,46 @@
1
+ import { parseJsModuleImports } from "@jsenv/utils/js_ast/parse_js_module_imports.js"
2
+ import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
3
+
4
+ export const jsenvPluginImportsAnalysis = () => {
5
+ return {
6
+ name: "jsenv:imports_analysis",
7
+ appliesDuring: "*",
8
+ transformUrlContent: {
9
+ js_module: async (urlInfo, context) => {
10
+ const [imports, exports] = await parseJsModuleImports({
11
+ js: urlInfo.content,
12
+ url: (urlInfo.data && urlInfo.data.rawUrl) || urlInfo.url,
13
+ })
14
+ const actions = []
15
+ const magicSource = createMagicSource(urlInfo.content)
16
+ urlInfo.data.usesImport = imports.length > 0
17
+ urlInfo.data.usesExport = exports.length > 0
18
+ urlInfo.data.usesImportAssertion = imports.some(
19
+ (importInfo) => typeof importInfo.usesAssert,
20
+ )
21
+ imports.forEach((importInfo) => {
22
+ const [reference] = context.referenceUtils.found({
23
+ type: "js_import_export",
24
+ subtype: importInfo.subtype,
25
+ expectedType: importInfo.expectedType, // can be json for import assertions
26
+ expectedSubtype: urlInfo.subtype,
27
+ line: importInfo.specifierLine,
28
+ column: importInfo.specifierColumn,
29
+ specifier: importInfo.specifier,
30
+ })
31
+ actions.push(async () => {
32
+ magicSource.replace({
33
+ start: importInfo.specifierStart,
34
+ end: importInfo.specifierEnd,
35
+ replacement: await context.referenceUtils.readGeneratedSpecifier(
36
+ reference,
37
+ ),
38
+ })
39
+ })
40
+ })
41
+ await Promise.all(actions.map((action) => action()))
42
+ return magicSource.toContentAndSourcemap()
43
+ },
44
+ },
45
+ }
46
+ }
@@ -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,6 @@
1
+ import { jsenvPluginImportsAnalysis } from "./jsenv_plugin_imports_analysis.js"
2
+ import { jsenvPluginUrlAnalysis } from "./jsenv_plugin_url_analysis.js"
3
+
4
+ export const jsenvPluginUrlReferences = () => {
5
+ return [jsenvPluginImportsAnalysis(), jsenvPluginUrlAnalysis()]
6
+ }
@@ -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,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,9 +62,13 @@ export const executePlan = async (
62
62
  coverageV8ConflictWarning,
63
63
  coverageTempDirectoryRelativeUrl,
64
64
 
65
- plugins = [],
66
- scenario = "test",
67
- sourcemaps = "inline",
65
+ scenario,
66
+ sourcemaps,
67
+ plugins,
68
+ injectedGlobals,
69
+ nodeEsmResolution,
70
+ fileSystemMagicResolution,
71
+ transpilation,
68
72
 
69
73
  protocol,
70
74
  privateKey,
@@ -132,12 +136,27 @@ export const executePlan = async (
132
136
  logger,
133
137
  rootDirectoryUrl,
134
138
  urlGraph,
139
+ scenario,
140
+ sourcemaps,
141
+ writeOnFileSystem: false,
135
142
  plugins: [
136
143
  ...plugins,
137
144
  ...getCorePlugins({
138
- babel: {
139
- getCustomBabelPlugins: ({ runtimeSupport }) => {
140
- if (coverage && Object.keys(runtimeSupport)[0] !== "chrome") {
145
+ rootDirectoryUrl,
146
+ urlGraph,
147
+ scenario,
148
+
149
+ htmlSupervisor: true,
150
+ nodeEsmResolution,
151
+ fileSystemMagicResolution,
152
+ injectedGlobals,
153
+ transpilation: {
154
+ ...transpilation,
155
+ getCustomBabelPlugins: ({ clientRuntimeCompat }) => {
156
+ if (
157
+ coverage &&
158
+ Object.keys(clientRuntimeCompat)[0] !== "chrome"
159
+ ) {
141
160
  return {
142
161
  "transform-instrument": [
143
162
  babelPluginInstrument,
@@ -153,8 +172,6 @@ export const executePlan = async (
153
172
  },
154
173
  }),
155
174
  ],
156
- scenario,
157
- sourcemaps,
158
175
  })
159
176
  const serverLogger = createLogger({ logLevel: "warn" })
160
177
  const server = await startOmegaServer({
@@ -433,7 +450,7 @@ export const executePlan = async (
433
450
  }
434
451
  if (summary.counters.total !== summary.counters.completed) {
435
452
  const logFileUrl = new URL(logFileRelativeUrl, rootDirectoryUrl).href
436
- writeFile(logFileUrl, rawOutput)
453
+ writeFileSync(logFileUrl, rawOutput)
437
454
  logger.info(`-> ${urlToFileSystemPath(logFileUrl)}`)
438
455
  }
439
456
  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,