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

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 +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 +30 -28
  11. package/readme.md +6 -14
  12. package/src/build/build.js +943 -555
  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 +192 -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 +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 +482 -304
  36. package/src/omega/omega_server.js +2 -3
  37. package/src/omega/server/file_service.js +53 -25
  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 +98 -48
  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 +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 +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 +2 -2
  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 +30 -18
  123. package/src/test/execute_test_plan.js +23 -8
  124. package/src/test/logs_file_execution.js +9 -8
  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,309 @@
1
+ import {
2
+ isFileSystemPath,
3
+ normalizeStructuredMetaMap,
4
+ urlIsInsideOf,
5
+ urlToMeta,
6
+ } from "@jsenv/filesystem"
7
+ import { createDetailedMessage } from "@jsenv/logger"
8
+
9
+ import { applyRollupPlugins } from "@jsenv/utils/js_ast/apply_rollup_plugins.js"
10
+ import { sourcemapConverter } from "@jsenv/utils/sourcemap/sourcemap_converter.js"
11
+ import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
12
+ import { babelHelperNameFromUrl } from "@jsenv/babel-plugins"
13
+
14
+ const jsenvBabelPluginDirectoryUrl = new URL(
15
+ "../../transpilation/babel/",
16
+ import.meta.url,
17
+ ).href
18
+
19
+ export const bundleJsModule = async ({
20
+ jsModuleUrlInfos,
21
+ context,
22
+ options,
23
+ }) => {
24
+ const {
25
+ signal,
26
+ logger,
27
+ rootDirectoryUrl,
28
+ buildDirectoryUrl,
29
+ urlGraph,
30
+ runtimeCompat,
31
+ sourcemaps,
32
+ } = context
33
+ const { jsModuleBundleUrlInfos } = await buildWithRollup({
34
+ signal,
35
+ logger,
36
+ rootDirectoryUrl,
37
+ buildDirectoryUrl,
38
+ urlGraph,
39
+ jsModuleUrlInfos,
40
+
41
+ runtimeCompat,
42
+ sourcemaps,
43
+ options,
44
+ })
45
+ return jsModuleBundleUrlInfos
46
+ }
47
+
48
+ export const buildWithRollup = async ({
49
+ signal,
50
+ logger,
51
+ rootDirectoryUrl,
52
+ buildDirectoryUrl,
53
+ urlGraph,
54
+ jsModuleUrlInfos,
55
+
56
+ runtimeCompat,
57
+ sourcemaps,
58
+ options,
59
+ }) => {
60
+ const resultRef = { current: null }
61
+ try {
62
+ await applyRollupPlugins({
63
+ rollupPlugins: [
64
+ rollupPluginJsenv({
65
+ signal,
66
+ logger,
67
+ rootDirectoryUrl,
68
+ buildDirectoryUrl,
69
+ urlGraph,
70
+ jsModuleUrlInfos,
71
+
72
+ runtimeCompat,
73
+ sourcemaps,
74
+ options,
75
+ resultRef,
76
+ }),
77
+ ],
78
+ inputOptions: {
79
+ input: [],
80
+ onwarn: (warning) => {
81
+ if (warning.code === "CIRCULAR_DEPENDENCY") {
82
+ return
83
+ }
84
+ logger.warn(String(warning))
85
+ },
86
+ },
87
+ })
88
+ return resultRef.current
89
+ } catch (e) {
90
+ if (e.code === "MISSING_EXPORT") {
91
+ const detailedMessage = createDetailedMessage(e.message, {
92
+ frame: e.frame,
93
+ })
94
+ throw new Error(detailedMessage, { cause: e })
95
+ }
96
+ throw e
97
+ }
98
+ }
99
+
100
+ const rollupPluginJsenv = ({
101
+ // logger,
102
+ rootDirectoryUrl,
103
+ buildDirectoryUrl,
104
+ urlGraph,
105
+ jsModuleUrlInfos,
106
+ sourcemaps,
107
+ options,
108
+
109
+ resultRef,
110
+ }) => {
111
+ let _rollupEmitFile = () => {
112
+ throw new Error("not implemented")
113
+ }
114
+ const emitChunk = (chunk) => {
115
+ return _rollupEmitFile({
116
+ type: "chunk",
117
+ ...chunk,
118
+ })
119
+ }
120
+ let importCanBeBundled = () => true
121
+ if (options.include) {
122
+ const bundleIncludeConfig = normalizeStructuredMetaMap(
123
+ {
124
+ bundle: options.include,
125
+ },
126
+ rootDirectoryUrl,
127
+ )
128
+ importCanBeBundled = (url) => {
129
+ return urlToMeta({
130
+ url,
131
+ structuredMetaMap: bundleIncludeConfig,
132
+ }).bundle
133
+ }
134
+ }
135
+ const urlImporters = {}
136
+
137
+ return {
138
+ name: "jsenv",
139
+ async buildStart() {
140
+ _rollupEmitFile = (...args) => this.emitFile(...args)
141
+ let previousNonEntryPointModuleId
142
+ jsModuleUrlInfos.forEach((jsModuleUrlInfo) => {
143
+ const id = jsModuleUrlInfo.url
144
+ if (jsModuleUrlInfo.data.isEntryPoint) {
145
+ emitChunk({
146
+ id,
147
+ })
148
+ return
149
+ }
150
+ emitChunk({
151
+ id,
152
+ implicitlyLoadedAfterOneOf: previousNonEntryPointModuleId
153
+ ? [previousNonEntryPointModuleId]
154
+ : null,
155
+ preserveSignature: "allow-extension",
156
+ })
157
+ previousNonEntryPointModuleId = id
158
+ })
159
+ },
160
+ async generateBundle(outputOptions, rollupResult) {
161
+ _rollupEmitFile = (...args) => this.emitFile(...args)
162
+
163
+ const jsModuleBundleUrlInfos = {}
164
+ Object.keys(rollupResult).forEach((fileName) => {
165
+ const rollupFileInfo = rollupResult[fileName]
166
+ // there is 3 types of file: "placeholder", "asset", "chunk"
167
+ if (rollupFileInfo.type === "chunk") {
168
+ const jsModuleBundleUrlInfo = {
169
+ data: {
170
+ generatedBy: "rollup",
171
+ bundleRelativeUrl: rollupFileInfo.fileName,
172
+ usesImport:
173
+ rollupFileInfo.imports.length > 0 ||
174
+ rollupFileInfo.dynamicImports.length > 0,
175
+ usesExport: rollupFileInfo.exports.length > 0,
176
+ },
177
+ contentType: "text/javascript",
178
+ content: rollupFileInfo.code,
179
+ sourcemap: rollupFileInfo.map,
180
+ }
181
+ let url
182
+ if (rollupFileInfo.facadeModuleId) {
183
+ url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
184
+ } else {
185
+ url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
186
+ }
187
+ jsModuleBundleUrlInfos[url] = jsModuleBundleUrlInfo
188
+ }
189
+ })
190
+ resultRef.current = {
191
+ jsModuleBundleUrlInfos,
192
+ }
193
+ },
194
+ outputOptions: (outputOptions) => {
195
+ // const sourcemapFile = buildDirectoryUrl
196
+ Object.assign(outputOptions, {
197
+ format: "esm",
198
+ dir: fileUrlConverter.asFilePath(buildDirectoryUrl),
199
+ sourcemap: sourcemaps === "file" || sourcemaps === "inline",
200
+ // sourcemapFile,
201
+ sourcemapPathTransform: (relativePath) => {
202
+ return new URL(relativePath, buildDirectoryUrl).href
203
+ },
204
+ entryFileNames: () => {
205
+ return `[name].js`
206
+ },
207
+ chunkFileNames: (chunkInfo) => {
208
+ const insideJs = willBeInsideJsDirectory({
209
+ chunkInfo,
210
+ fileUrlConverter,
211
+ jsModuleUrlInfos,
212
+ })
213
+ let nameFromUrlInfo
214
+ if (chunkInfo.facadeModuleId) {
215
+ const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
216
+ const urlInfo = jsModuleUrlInfos.find(
217
+ (jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
218
+ )
219
+ if (urlInfo) {
220
+ nameFromUrlInfo = urlInfo.filename
221
+ }
222
+ }
223
+ const name = nameFromUrlInfo || `${chunkInfo.name}.js`
224
+ return insideJs ? `js/${name}` : `${name}`
225
+ },
226
+ manualChunks: (id) => {
227
+ const fileUrl = fileUrlConverter.asFileUrl(id)
228
+ if (
229
+ fileUrl.endsWith(
230
+ "babel-plugin-transform-async-to-promises/helpers.mjs",
231
+ )
232
+ ) {
233
+ return "babel_helpers"
234
+ }
235
+ if (babelHelperNameFromUrl(fileUrl)) {
236
+ return "babel_helpers"
237
+ }
238
+ if (urlIsInsideOf(fileUrl, jsenvBabelPluginDirectoryUrl)) {
239
+ return "babel_helpers"
240
+ }
241
+ return null
242
+ },
243
+ // https://rollupjs.org/guide/en/#outputpaths
244
+ // paths: (id) => {
245
+ // return id
246
+ // },
247
+ })
248
+ },
249
+ resolveId: (specifier, importer = rootDirectoryUrl) => {
250
+ if (isFileSystemPath(importer)) {
251
+ importer = fileUrlConverter.asFileUrl(importer)
252
+ }
253
+ const url = new URL(specifier, importer).href
254
+ const existingImporter = urlImporters[url]
255
+ if (!existingImporter) {
256
+ urlImporters[url] = importer
257
+ }
258
+ if (!url.startsWith("file:")) {
259
+ return { id: url, external: true }
260
+ }
261
+ if (!importCanBeBundled(url)) {
262
+ return { id: url, external: true }
263
+ }
264
+ const filePath = fileUrlConverter.asFilePath(url)
265
+ return filePath
266
+ },
267
+ async load(rollupId) {
268
+ const fileUrl = fileUrlConverter.asFileUrl(rollupId)
269
+ const urlInfo = urlGraph.getUrlInfo(fileUrl)
270
+ return {
271
+ code: urlInfo.content,
272
+ map: urlInfo.sourcemap
273
+ ? sourcemapConverter.toFilePaths(urlInfo.sourcemap)
274
+ : null,
275
+ }
276
+ },
277
+ }
278
+ }
279
+
280
+ const willBeInsideJsDirectory = ({
281
+ chunkInfo,
282
+ fileUrlConverter,
283
+ jsModuleUrlInfos,
284
+ }) => {
285
+ // if the chunk is generated dynamically by rollup
286
+ // for an entry point jsenv will put that file inside js/ directory
287
+ // if it's generated dynamically for a file already in js/ directory
288
+ // both will be inside the js/ directory
289
+ if (!chunkInfo.facadeModuleId) {
290
+ // generated by rollup
291
+ return true
292
+ }
293
+ const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
294
+ const jsModuleUrlInfo = jsModuleUrlInfos.find(
295
+ (jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
296
+ )
297
+ if (!jsModuleUrlInfo) {
298
+ // generated by rollup
299
+ return true
300
+ }
301
+ if (
302
+ !jsModuleUrlInfo.data.isEntryPoint &&
303
+ !jsModuleUrlInfo.data.isWebWorkerEntryPoint
304
+ ) {
305
+ // not an entry point, jsenv will put it inside js/ directory
306
+ return true
307
+ }
308
+ return false
309
+ }
@@ -0,0 +1,54 @@
1
+ import { bundleCss } from "./css/bundle_css.js"
2
+ import { bundleJsClassicWorkers } from "./js_classic_workers/bundle_js_classic_workers.js"
3
+ import { bundleJsModule } from "./js_module/bundle_js_module.js"
4
+
5
+ export const jsenvPluginBundling = (bundling) => {
6
+ if (typeof bundling === "boolean") {
7
+ bundling = {
8
+ css: bundling,
9
+ js_classic_workers: bundling,
10
+ js_module: bundling,
11
+ }
12
+ } else if (typeof bundling !== "object") {
13
+ throw new Error(`bundling must be a boolean or an object, got ${bundling}`)
14
+ }
15
+ Object.keys(bundling).forEach((key) => {
16
+ if (bundling[key] === true) bundling[key] = {}
17
+ })
18
+
19
+ return {
20
+ name: "jsenv:bundling",
21
+ appliesDuring: {
22
+ build: true,
23
+ },
24
+ bundle: {
25
+ css: bundling.css
26
+ ? (cssUrlInfos, context) => {
27
+ return bundleCss({
28
+ cssUrlInfos,
29
+ context,
30
+ options: bundling.css,
31
+ })
32
+ }
33
+ : undefined,
34
+ js_classic: bundling.js_classic
35
+ ? (jsClassicUrlInfos, context) => {
36
+ return bundleJsClassicWorkers({
37
+ jsClassicUrlInfos,
38
+ context,
39
+ options: bundling.js_classic_workers,
40
+ })
41
+ }
42
+ : undefined,
43
+ js_module: bundling.js_module
44
+ ? (jsModuleUrlInfos, context) => {
45
+ return bundleJsModule({
46
+ jsModuleUrlInfos,
47
+ context,
48
+ options: bundling.js_module,
49
+ })
50
+ }
51
+ : undefined,
52
+ },
53
+ }
54
+ }
@@ -0,0 +1,34 @@
1
+ export const jsenvPluginCacheControl = () => {
2
+ return {
3
+ name: "jsenv:cache_control",
4
+ appliesDuring: {
5
+ dev: true,
6
+ test: true,
7
+ },
8
+ augmentResponse: ({ reference }, context) => {
9
+ if (context.scenario === "dev") {
10
+ // During dev, all files are put into browser cache for 1 hour because:
11
+ // 1: Browser cache is a temporary directory created by playwright
12
+ // 2: We assume source files won't be modified while tests are running
13
+ return {
14
+ headers: {
15
+ "cache-control": `private,max-age=3600,immutable`,
16
+ },
17
+ }
18
+ }
19
+ if (
20
+ reference.searchParams.has("v") &&
21
+ !reference.searchParams.has("hmr")
22
+ ) {
23
+ return {
24
+ headers: {
25
+ "cache-control": `private,max-age=${SECONDS_IN_30_DAYS},immutable`,
26
+ },
27
+ }
28
+ }
29
+ return null
30
+ },
31
+ }
32
+ }
33
+
34
+ const SECONDS_IN_30_DAYS = 60 * 60 * 24 * 30
@@ -11,50 +11,63 @@ import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
11
11
  import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
12
12
 
13
13
  export const jsenvPluginCommonJsGlobals = () => {
14
+ const transformCommonJsGlobals = async (urlInfo, { scenario }) => {
15
+ if (
16
+ !urlInfo.content.includes("process.env.NODE_ENV") &&
17
+ !urlInfo.content.includes("__filename") &&
18
+ !urlInfo.content.includes("__dirname")
19
+ ) {
20
+ return null
21
+ }
22
+ const isJsModule = urlInfo.type === "js_module"
23
+ const replaceMap = {
24
+ "process.env.NODE_ENV": `("${
25
+ scenario === "dev" || scenario === "test" ? "dev" : "prod"
26
+ }")`,
27
+ "global": "globalThis",
28
+ "__filename": isJsModule
29
+ ? `import.meta.url.slice('file:///'.length)`
30
+ : `document.currentScript.src`,
31
+ "__dirname": isJsModule
32
+ ? `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`
33
+ : `new URL('./', document.currentScript.src).href`,
34
+ }
35
+ const { metadata } = await applyBabelPlugins({
36
+ babelPlugins: [
37
+ [
38
+ babelPluginMetadataExpressionPaths,
39
+ {
40
+ replaceMap,
41
+ allowConflictingReplacements: true,
42
+ },
43
+ ],
44
+ ],
45
+ urlInfo,
46
+ })
47
+ const { expressionPaths } = metadata
48
+ const keys = Object.keys(expressionPaths)
49
+ if (keys.length === 0) {
50
+ return null
51
+ }
52
+ const magicSource = createMagicSource(urlInfo.content)
53
+ keys.forEach((key) => {
54
+ expressionPaths[key].forEach((path) => {
55
+ magicSource.replace({
56
+ start: path.node.start,
57
+ end: path.node.end,
58
+ replacement: replaceMap[key],
59
+ })
60
+ })
61
+ })
62
+ return magicSource.toContentAndSourcemap()
63
+ }
64
+
14
65
  return {
15
66
  name: "jsenv:commonjs_globals",
16
67
  appliesDuring: "*",
17
- transform: {
18
- js_module: async ({ url, generatedUrl, content }, { scenario }) => {
19
- const replaceMap = {
20
- "process.env.NODE_ENV": `("${
21
- scenario === "dev" || scenario === "test" ? "dev" : "prod"
22
- }")`,
23
- "global": "globalThis",
24
- "__filename": `import.meta.url.slice('file:///'.length)`,
25
- "__dirname": `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`,
26
- }
27
- const { metadata } = await applyBabelPlugins({
28
- babelPlugins: [
29
- [
30
- babelPluginMetadataExpressionPaths,
31
- {
32
- replaceMap,
33
- allowConflictingReplacements: true,
34
- },
35
- ],
36
- ],
37
- url,
38
- generatedUrl,
39
- content,
40
- })
41
- const { expressionPaths } = metadata
42
- const keys = Object.keys(expressionPaths)
43
- if (keys.length === 0) {
44
- return null
45
- }
46
- const magicSource = createMagicSource(content)
47
- keys.forEach((key) => {
48
- expressionPaths[key].forEach((path) => {
49
- magicSource.replace({
50
- start: path.node.start,
51
- end: path.node.end,
52
- replacement: replaceMap[key],
53
- })
54
- })
55
- })
56
- return magicSource.toContentAndSourcemap()
57
- },
68
+ transformUrlContent: {
69
+ js_classic: transformCommonJsGlobals,
70
+ js_module: transformCommonJsGlobals,
58
71
  },
59
72
  }
60
73
  }
@@ -0,0 +1,66 @@
1
+ import { readFileSync } from "node:fs"
2
+ import { urlIsInsideOf, urlToRelativeUrl } from "@jsenv/filesystem"
3
+
4
+ import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
5
+
6
+ export const jsenvPluginFileUrls = () => {
7
+ return [jsenvPluginResolveAbsoluteFileUrls(), jsenvPluginFetchFileUrls()]
8
+ }
9
+
10
+ const jsenvPluginResolveAbsoluteFileUrls = () => {
11
+ return {
12
+ name: "jsenv:resolve_absolute_file_urls",
13
+ appliesDuring: {
14
+ // during dev and test it's a browser running the code
15
+ // so absolute file urls needs to be relativized
16
+ dev: true,
17
+ test: true,
18
+ // during build it's fine to use file:// urls
19
+ build: false,
20
+ },
21
+ resolveUrl: (reference) => {
22
+ if (!reference.specifier.startsWith("/@fs/")) {
23
+ return null
24
+ }
25
+ const fsRootRelativeUrl = reference.specifier.slice("/@fs/".length)
26
+ return `file:///${fsRootRelativeUrl}`
27
+ },
28
+ formatUrl: (reference, context) => {
29
+ if (!reference.generatedUrl.startsWith("file:")) {
30
+ return null
31
+ }
32
+ if (urlIsInsideOf(reference.generatedUrl, context.rootDirectoryUrl)) {
33
+ return `/${urlToRelativeUrl(
34
+ reference.generatedUrl,
35
+ context.rootDirectoryUrl,
36
+ )}`
37
+ }
38
+ return `/@fs/${reference.generatedUrl.slice("file:///".length)}`
39
+ },
40
+ }
41
+ }
42
+
43
+ const jsenvPluginFetchFileUrls = () => {
44
+ return {
45
+ name: "jsenv:fetch_file_urls",
46
+ appliesDuring: "*",
47
+ fetchUrlContent: (urlInfo) => {
48
+ if (!urlInfo.url.startsWith("file:")) {
49
+ return null
50
+ }
51
+ const urlObject = new URL(urlInfo.url)
52
+ const fileBuffer = readFileSync(urlObject)
53
+ const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url)
54
+ if (CONTENT_TYPE.isTextual(contentType)) {
55
+ return {
56
+ contentType,
57
+ content: String(fileBuffer),
58
+ }
59
+ }
60
+ return {
61
+ contentType,
62
+ content: fileBuffer,
63
+ }
64
+ },
65
+ }
66
+ }
@@ -6,19 +6,19 @@ import { urlToExtension } from "@jsenv/filesystem"
6
6
  import { applyFileSystemMagicResolution } from "@jsenv/node-esm-resolution"
7
7
 
8
8
  export const jsenvPluginFileSystemMagic = ({
9
- magicExtensions = ["inherit"],
9
+ magicExtensions = ["inherit", ".js"],
10
10
  magicDirectoryIndex = true,
11
11
  preservesSymlink = true,
12
12
  } = {}) => {
13
13
  return {
14
14
  name: "jsenv:filesystem_magic",
15
15
  appliesDuring: "*",
16
- normalize: ({ parentUrl, url }) => {
16
+ redirectUrl: (reference) => {
17
17
  // http, https, data, about, etc
18
- if (!url.startsWith("file:")) {
18
+ if (!reference.url.startsWith("file:")) {
19
19
  return null
20
20
  }
21
- const urlObject = new URL(url)
21
+ const urlObject = new URL(reference.url)
22
22
  const { search, hash } = urlObject
23
23
  urlObject.search = ""
24
24
  urlObject.hash = ""
@@ -26,7 +26,10 @@ export const jsenvPluginFileSystemMagic = ({
26
26
  urlObject.href,
27
27
  {
28
28
  magicDirectoryIndex,
29
- magicExtensions: getExtensionsToTry(magicExtensions, parentUrl),
29
+ magicExtensions: getExtensionsToTry(
30
+ magicExtensions,
31
+ reference.parentUrl,
32
+ ),
30
33
  },
31
34
  )
32
35
  if (!filesystemResolution.found) {