@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
@@ -1,177 +1,35 @@
1
1
  import { urlToRelativeUrl } from "@jsenv/filesystem"
2
2
  import { createCallbackList } from "@jsenv/abort"
3
3
 
4
- import { injectQueryParams } from "@jsenv/utils/urls/url_utils.js"
5
- import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
6
- import {
7
- parseHtmlString,
8
- stringifyHtmlAst,
9
- injectScriptAsEarlyAsPossible,
10
- createHtmlNode,
11
- } from "@jsenv/utils/html_ast/html_ast.js"
12
- import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
4
+ import { createSSEService } from "@jsenv/utils/event_source/sse_service.js"
13
5
 
14
- import { createSSEService } from "./sse_service.js"
15
- import { collectHotDataFromHtmlAst } from "./html_hot_dependencies.js"
16
- import { babelPluginMetadataImportMetaHot } from "./babel_plugin_metadata_import_meta_hot.js"
17
-
18
- export const jsenvPluginAutoreload = ({
6
+ export const jsenvPluginDevSSEServer = ({
19
7
  rootDirectoryUrl,
20
8
  urlGraph,
21
- autoreloadPatterns,
9
+ watchedFilePatterns,
10
+ cooldownBetweenFileEvents,
22
11
  }) => {
23
- return [
24
- jsenvPluginHot(),
25
- jsenvPluginHotSSE({
26
- rootDirectoryUrl,
27
- urlGraph,
28
- autoreloadPatterns,
29
- }),
30
- ]
31
- }
32
-
33
- const jsenvPluginHot = () => {
34
- const eventSourceClientFileUrl = new URL(
35
- "./client/event_source_client.js",
36
- import.meta.url,
37
- ).href
38
- const importMetaHotClientFileUrl = new URL(
39
- "./client/import_meta_hot.js",
40
- import.meta.url,
41
- ).href
42
-
43
- return {
44
- name: "jsenv:hot",
45
- appliesDuring: { dev: true },
46
- normalize: ({ url, data }) => {
47
- const urlObject = new URL(url)
48
- if (!urlObject.searchParams.has("hmr")) {
49
- data.hmr = false
50
- return null
51
- }
52
- data.hmr = true
53
- // "hmr" search param goal is to mark url as enabling hmr:
54
- // this goal is achieved when we reach this part of the code
55
- // We get rid of this params so that urlGraph and other parts of the code
56
- // recognize the url (it is not considered as a different url)
57
- urlObject.searchParams.delete("hmr")
58
- urlObject.searchParams.delete("v")
59
- return urlObject.href
60
- },
61
- transformReferencedUrl: ({ parentUrl, url, data }, { urlGraph }) => {
62
- const parentUrlInfo = urlGraph.getUrlInfo(parentUrl)
63
- if (!parentUrlInfo || !parentUrlInfo.data.hmr) {
64
- return null
65
- }
66
- if (!data.hmrTimestamp) {
67
- return null
68
- }
69
- return injectQueryParams(url, {
70
- hmr: "",
71
- v: data.hmrTimestamp,
72
- })
73
- },
74
- transform: {
75
- html: ({ data, content }, { referenceUtils }) => {
76
- const htmlAst = parseHtmlString(content)
77
- const { hotReferences } = collectHotDataFromHtmlAst(htmlAst)
78
- data.hotDecline = false
79
- data.hotAcceptSelf = false
80
- data.hotAcceptDependencies = hotReferences.map(
81
- ({ type, specifier }) => {
82
- const [reference] = referenceUtils.inject({
83
- type,
84
- specifier,
85
- })
86
- return reference.url
87
- },
88
- )
89
- const [eventSourceClientReference] = referenceUtils.inject({
90
- type: "script_src",
91
- specifier: eventSourceClientFileUrl,
92
- })
93
- injectScriptAsEarlyAsPossible(
94
- htmlAst,
95
- createHtmlNode({
96
- "tagName": "script",
97
- "type": "module",
98
- "src": eventSourceClientReference.generatedSpecifier,
99
- "injected-by": "jsenv:hot",
100
- }),
101
- )
102
- const htmlModified = stringifyHtmlAst(htmlAst)
103
- return {
104
- content: htmlModified,
105
- }
106
- },
107
- css: ({ data }) => {
108
- data.hotDecline = false
109
- data.hotAcceptSelf = false
110
- data.hotAcceptDependencies = []
111
- },
112
- js_module: async (
113
- { url, generatedUrl, data, content },
114
- { referenceUtils },
115
- ) => {
116
- const { metadata } = await applyBabelPlugins({
117
- babelPlugins: [babelPluginMetadataImportMetaHot],
118
- url,
119
- generatedUrl,
120
- content,
121
- })
122
- const {
123
- importMetaHotDetected,
124
- hotDecline,
125
- hotAcceptSelf,
126
- hotAcceptDependencies,
127
- } = metadata
128
- data.hotDecline = hotDecline
129
- data.hotAcceptSelf = hotAcceptSelf
130
- data.hotAcceptDependencies = hotAcceptDependencies
131
- if (!importMetaHotDetected) {
132
- return null
133
- }
134
- // For some reason using magic source here produce
135
- // better sourcemap than doing the equivalent with babel
136
- // I suspect it's because I was doing injectAstAfterImport(programPath, ast.program.body[0])
137
- // which is likely not well supported by babel
138
- const [importMetaHotClientFileReference] = referenceUtils.inject({
139
- parentUrl: url,
140
- type: "js_import_export",
141
- specifier: importMetaHotClientFileUrl,
142
- })
143
- const magicSource = createMagicSource(content)
144
- magicSource.prepend(
145
- `import { createImportMetaHot } from ${importMetaHotClientFileReference.generatedSpecifier}
146
- import.meta.hot = createImportMetaHot(import.meta.url)
147
- `,
148
- )
149
- return magicSource.toContentAndSourcemap()
150
- },
151
- },
152
- }
153
- }
154
-
155
- const jsenvPluginHotSSE = ({
156
- rootDirectoryUrl,
157
- urlGraph,
158
- autoreloadPatterns,
159
- }) => {
160
- const hotUpdateCallbackList = createCallbackList()
12
+ const serverEventCallbackList = createCallbackList()
161
13
  const notifyDeclined = ({ cause, reason, declinedBy }) => {
162
- hotUpdateCallbackList.notify({
163
- declined: true,
164
- cause,
165
- reason,
166
- declinedBy,
14
+ serverEventCallbackList.notify({
15
+ type: "reload",
16
+ data: JSON.stringify({
17
+ cause,
18
+ type: "full",
19
+ typeReason: reason,
20
+ declinedBy,
21
+ }),
167
22
  })
168
23
  }
169
24
  const notifyAccepted = ({ cause, reason, instructions }) => {
170
- hotUpdateCallbackList.notify({
171
- accepted: true,
172
- cause,
173
- reason,
174
- instructions,
25
+ serverEventCallbackList.notify({
26
+ type: "reload",
27
+ data: JSON.stringify({
28
+ cause,
29
+ type: "hot",
30
+ typeReason: reason,
31
+ hotInstructions: instructions,
32
+ }),
175
33
  })
176
34
  }
177
35
  const updateHmrTimestamp = (urlInfo, hmrTimestamp) => {
@@ -185,9 +43,8 @@ const jsenvPluginHotSSE = ({
185
43
  urlInfo.data.hmrTimestamp = hmrTimestamp
186
44
  urlInfo.dependents.forEach((dependentUrl) => {
187
45
  const dependentUrlInfo = urlInfos[dependentUrl]
188
- if (
189
- !dependentUrlInfo.data.hotAcceptDependencies.includes(urlInfo.url)
190
- ) {
46
+ const { hotAcceptDependencies = [] } = dependentUrlInfo.data
47
+ if (!hotAcceptDependencies.includes(urlInfo.url)) {
191
48
  iterate(dependentUrlInfo, hmrTimestamp)
192
49
  }
193
50
  })
@@ -224,7 +81,8 @@ const jsenvPluginHotSSE = ({
224
81
  declinedBy: dependentUrl,
225
82
  }
226
83
  }
227
- if (dependentUrlInfo.data.hotAcceptDependencies.includes(urlInfo.url)) {
84
+ const { hotAcceptDependencies = [] } = dependentUrlInfo.data
85
+ if (hotAcceptDependencies.includes(urlInfo.url)) {
228
86
  instructions.push({
229
87
  type: dependentUrlInfo.type,
230
88
  boundary: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
@@ -273,9 +131,11 @@ const jsenvPluginHotSSE = ({
273
131
  }
274
132
  const sseService = createSSEService({
275
133
  rootDirectoryUrl,
276
- autoreloadPatterns,
277
- onFileChange: ({ relativeUrl, event }) => {
278
- const url = new URL(relativeUrl, rootDirectoryUrl).href
134
+ watchedFilePatterns,
135
+ cooldownBetweenFileEvents,
136
+ serverEventCallbackList,
137
+ onFileChange: ({ url, event }) => {
138
+ const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl)
279
139
  const urlInfo = urlGraph.urlInfos[url]
280
140
  // file not part of dependency graph
281
141
  if (!urlInfo) {
@@ -297,7 +157,6 @@ const jsenvPluginHotSSE = ({
297
157
  })
298
158
  }
299
159
  },
300
- hotUpdateCallbackList,
301
160
  })
302
161
  urlGraph.prunedCallbackList.add(({ prunedUrlInfos, firstUrlInfo }) => {
303
162
  prunedUrlInfos.forEach((prunedUrlInfo) => {
@@ -346,7 +205,7 @@ const jsenvPluginHotSSE = ({
346
205
  })
347
206
 
348
207
  return {
349
- name: "jsenv:hot_sse",
208
+ name: "jsenv:sse_server",
350
209
  appliesDuring: { dev: true },
351
210
  serve: (request, { urlGraph, rootDirectoryUrl }) => {
352
211
  if (request.ressource === "/__graph__") {
@@ -0,0 +1,27 @@
1
+ import { jsenvPluginHmr } from "./jsenv_plugin_hmr.js"
2
+ import { jsenvPluginDevSSEClient } from "./dev_sse/jsenv_plugin_dev_sse_client.js"
3
+ import { jsenvPluginDevSSEServer } from "./dev_sse/jsenv_plugin_dev_sse_server.js"
4
+
5
+ export const jsenvPluginAutoreload = ({
6
+ rootDirectoryUrl,
7
+ urlGraph,
8
+ scenario,
9
+ watchedFilePatterns,
10
+ cooldownBetweenFileEvents,
11
+ }) => {
12
+ if (scenario === "build") {
13
+ return []
14
+ }
15
+ return [
16
+ jsenvPluginHmr(),
17
+ jsenvPluginDevSSEClient({
18
+ rootDirectoryUrl,
19
+ }),
20
+ jsenvPluginDevSSEServer({
21
+ rootDirectoryUrl,
22
+ urlGraph,
23
+ watchedFilePatterns,
24
+ cooldownBetweenFileEvents,
25
+ }),
26
+ ]
27
+ }
@@ -0,0 +1,35 @@
1
+ export const jsenvPluginHmr = () => {
2
+ return {
3
+ name: "jsenv:hmr",
4
+ appliesDuring: { dev: true },
5
+ normalizeUrl: (reference) => {
6
+ const urlObject = new URL(reference.url)
7
+ if (!urlObject.searchParams.has("hmr")) {
8
+ reference.data.hmr = false
9
+ return null
10
+ }
11
+ reference.data.hmr = true
12
+ // "hmr" search param goal is to mark url as enabling hmr:
13
+ // this goal is achieved when we reach this part of the code
14
+ // We get rid of this params so that urlGraph and other parts of the code
15
+ // recognize the url (it is not considered as a different url)
16
+ urlObject.searchParams.delete("hmr")
17
+ urlObject.searchParams.delete("v")
18
+ return urlObject.href
19
+ },
20
+ transformUrlSearchParams: (reference, context) => {
21
+ const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
22
+ if (!parentUrlInfo || !parentUrlInfo.data.hmr) {
23
+ return null
24
+ }
25
+ const urlInfo = context.urlGraph.getUrlInfo(reference.url)
26
+ if (!urlInfo.data.hmrTimestamp) {
27
+ return null
28
+ }
29
+ return {
30
+ hmr: "",
31
+ v: urlInfo.data.hmrTimestamp,
32
+ }
33
+ },
34
+ }
35
+ }
@@ -0,0 +1,21 @@
1
+ import { bundleWithParcel } from "@jsenv/utils/css_ast/parcel_css.js"
2
+
3
+ export const bundleCss = async ({ cssUrlInfos, context }) => {
4
+ const bundledCssUrlInfos = {}
5
+ cssUrlInfos.forEach((cssUrlInfo) => {
6
+ const { code, map } = bundleWithParcel(cssUrlInfo, context)
7
+ const content = String(code)
8
+ const sourcemap = map
9
+ // here we need to replace css urls to ensure
10
+ // all urls targets the correct stuff
11
+ bundledCssUrlInfos[cssUrlInfo.url] = {
12
+ data: {
13
+ generatedBy: "parcel",
14
+ },
15
+ contentType: "text/css",
16
+ content,
17
+ sourcemap,
18
+ }
19
+ })
20
+ return bundledCssUrlInfos
21
+ }
@@ -0,0 +1,13 @@
1
+ /*
2
+ * TODO:
3
+ * for each js_classic where subtype is a worker
4
+ * take the url info and find importScripts calls
5
+ * and replace them with the corresponding url info file content
6
+ * we'll ikely need to save the importScripts node location to be able to do that
7
+ */
8
+
9
+ // import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
10
+
11
+ export const bundleJsClassicWorkers = () => {
12
+ return {}
13
+ }
@@ -1,43 +1,32 @@
1
- import { isFileSystemPath, urlToRelativeUrl } from "@jsenv/filesystem"
1
+ import { isFileSystemPath } from "@jsenv/filesystem"
2
+ import { createDetailedMessage } from "@jsenv/logger"
2
3
 
3
4
  import { applyRollupPlugins } from "@jsenv/utils/js_ast/apply_rollup_plugins.js"
4
5
  import { sourcemapConverter } from "@jsenv/utils/sourcemap/sourcemap_converter.js"
5
6
  import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
6
7
 
7
- export const jsenvPluginBundleJsModule = () => {
8
- return {
9
- name: "jsenv:bundle_js_module",
10
- appliesDuring: {
11
- build: true,
12
- },
13
- bundle: {
14
- js_module: async (
15
- jsModuleUrlInfos,
16
- {
17
- signal,
18
- logger,
19
- rootDirectoryUrl,
20
- buildDirectoryUrl,
21
- urlGraph,
22
- runtimeSupport,
23
- sourcemaps,
24
- },
25
- ) => {
26
- const { jsModuleBundleUrlInfos } = await buildWithRollup({
27
- signal,
28
- logger,
29
- rootDirectoryUrl,
30
- buildDirectoryUrl,
31
- urlGraph,
32
- jsModuleUrlInfos,
8
+ export const bundleJsModule = async ({ jsModuleUrlInfos, context }) => {
9
+ const {
10
+ signal,
11
+ logger,
12
+ rootDirectoryUrl,
13
+ buildDirectoryUrl,
14
+ urlGraph,
15
+ runtimeCompat,
16
+ sourcemaps,
17
+ } = context
18
+ const { jsModuleBundleUrlInfos } = await buildWithRollup({
19
+ signal,
20
+ logger,
21
+ rootDirectoryUrl,
22
+ buildDirectoryUrl,
23
+ urlGraph,
24
+ jsModuleUrlInfos,
33
25
 
34
- runtimeSupport,
35
- sourcemaps,
36
- })
37
- return jsModuleBundleUrlInfos
38
- },
39
- },
40
- }
26
+ runtimeCompat,
27
+ sourcemaps,
28
+ })
29
+ return jsModuleBundleUrlInfos
41
30
  }
42
31
 
43
32
  export const buildWithRollup = async ({
@@ -48,36 +37,46 @@ export const buildWithRollup = async ({
48
37
  urlGraph,
49
38
  jsModuleUrlInfos,
50
39
 
51
- runtimeSupport,
40
+ runtimeCompat,
52
41
  sourcemaps,
53
42
  }) => {
54
43
  const resultRef = { current: null }
55
- await applyRollupPlugins({
56
- rollupPlugins: [
57
- rollupPluginJsenv({
58
- signal,
59
- logger,
60
- rootDirectoryUrl,
61
- buildDirectoryUrl,
62
- urlGraph,
63
- jsModuleUrlInfos,
44
+ try {
45
+ await applyRollupPlugins({
46
+ rollupPlugins: [
47
+ rollupPluginJsenv({
48
+ signal,
49
+ logger,
50
+ rootDirectoryUrl,
51
+ buildDirectoryUrl,
52
+ urlGraph,
53
+ jsModuleUrlInfos,
64
54
 
65
- runtimeSupport,
66
- sourcemaps,
67
- resultRef,
68
- }),
69
- ],
70
- inputOptions: {
71
- input: [],
72
- onwarn: (warning) => {
73
- if (warning.code === "CIRCULAR_DEPENDENCY") {
74
- return
75
- }
76
- logger.warn(String(warning))
55
+ runtimeCompat,
56
+ sourcemaps,
57
+ resultRef,
58
+ }),
59
+ ],
60
+ inputOptions: {
61
+ input: [],
62
+ onwarn: (warning) => {
63
+ if (warning.code === "CIRCULAR_DEPENDENCY") {
64
+ return
65
+ }
66
+ logger.warn(String(warning))
67
+ },
77
68
  },
78
- },
79
- })
80
- return resultRef.current
69
+ })
70
+ return resultRef.current
71
+ } catch (e) {
72
+ if (e.code === "MISSING_EXPORT") {
73
+ const detailedMessage = createDetailedMessage(e.message, {
74
+ frame: e.frame,
75
+ })
76
+ throw new Error(detailedMessage, { cause: e })
77
+ }
78
+ throw e
79
+ }
81
80
  }
82
81
 
83
82
  const rollupPluginJsenv = ({
@@ -119,6 +118,7 @@ const rollupPluginJsenv = ({
119
118
  implicitlyLoadedAfterOneOf: previousNonEntryPointModuleId
120
119
  ? [previousNonEntryPointModuleId]
121
120
  : null,
121
+ preserveSignature: "allow-extension",
122
122
  })
123
123
  previousNonEntryPointModuleId = id
124
124
  })
@@ -131,24 +131,25 @@ const rollupPluginJsenv = ({
131
131
  const rollupFileInfo = rollupResult[fileName]
132
132
  // there is 3 types of file: "placeholder", "asset", "chunk"
133
133
  if (rollupFileInfo.type === "chunk") {
134
- const { facadeModuleId } = rollupFileInfo
135
- let url
136
- if (facadeModuleId) {
137
- url = fileUrlConverter.asFileUrl(facadeModuleId)
138
- } else {
139
- const { sources } = rollupFileInfo.map
140
- const sourcePath = sources[sources.length - 1]
141
- url = fileUrlConverter.asFileUrl(sourcePath)
142
- }
143
134
  const jsModuleBundleUrlInfo = {
144
- // buildRelativeUrl: rollupFileInfo.fileName,
145
135
  data: {
146
136
  generatedBy: "rollup",
137
+ bundleRelativeUrl: rollupFileInfo.fileName,
138
+ usesImport:
139
+ rollupFileInfo.imports.length > 0 ||
140
+ rollupFileInfo.dynamicImports.length > 0,
141
+ usesExport: rollupFileInfo.exports.length > 0,
147
142
  },
148
- contentType: "application/javascript",
143
+ contentType: "text/javascript",
149
144
  content: rollupFileInfo.code,
150
145
  sourcemap: rollupFileInfo.map,
151
146
  }
147
+ let url
148
+ if (rollupFileInfo.facadeModuleId) {
149
+ url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
150
+ } else {
151
+ url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
152
+ }
152
153
  jsModuleBundleUrlInfos[url] = jsModuleBundleUrlInfo
153
154
  }
154
155
  })
@@ -170,14 +171,23 @@ const rollupPluginJsenv = ({
170
171
  return `[name].js`
171
172
  },
172
173
  chunkFileNames: (chunkInfo) => {
173
- // preserves relative path parts:
174
- // the goal is to mantain the original relative path (relative to the root directory)
175
- // so that later in the build process, when resolving these urls, we are able to
176
- // re-resolve the specifier againt the original parent url and find the original url
177
- const { facadeModuleId } = chunkInfo
178
- const fileUrl = fileUrlConverter.asFileUrl(facadeModuleId)
179
- const relativePath = urlToRelativeUrl(fileUrl, rootDirectoryUrl)
180
- return relativePath
174
+ const insideJs = willBeInsideJsDirectory({
175
+ chunkInfo,
176
+ fileUrlConverter,
177
+ jsModuleUrlInfos,
178
+ })
179
+ let nameFromUrlInfo
180
+ if (chunkInfo.facadeModuleId) {
181
+ const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
182
+ const urlInfo = jsModuleUrlInfos.find(
183
+ (jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
184
+ )
185
+ if (urlInfo) {
186
+ nameFromUrlInfo = urlInfo.filename
187
+ }
188
+ }
189
+ const name = nameFromUrlInfo || `${chunkInfo.name}.js`
190
+ return insideJs ? `js/${name}` : `${name}`
181
191
  },
182
192
  // https://rollupjs.org/guide/en/#outputpaths
183
193
  // paths: (id) => {
@@ -195,7 +205,7 @@ const rollupPluginJsenv = ({
195
205
  urlImporters[url] = importer
196
206
  }
197
207
  if (!url.startsWith("file:")) {
198
- return { url, external: true }
208
+ return { id: url, external: true }
199
209
  }
200
210
  const filePath = fileUrlConverter.asFilePath(url)
201
211
  return filePath
@@ -223,3 +233,34 @@ const rollupPluginJsenv = ({
223
233
  },
224
234
  }
225
235
  }
236
+
237
+ const willBeInsideJsDirectory = ({
238
+ chunkInfo,
239
+ fileUrlConverter,
240
+ jsModuleUrlInfos,
241
+ }) => {
242
+ // if the chunk is generated dynamically by rollup
243
+ // for an entry point jsenv will put that file inside js/ directory
244
+ // if it's generated dynamically for a file already in js/ directory
245
+ // both will be inside the js/ directory
246
+ if (!chunkInfo.facadeModuleId) {
247
+ // generated by rollup
248
+ return true
249
+ }
250
+ const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
251
+ const jsModuleUrlInfo = jsModuleUrlInfos.find(
252
+ (jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
253
+ )
254
+ if (!jsModuleUrlInfo) {
255
+ // generated by rollup
256
+ return true
257
+ }
258
+ if (
259
+ !jsModuleUrlInfo.data.isEntryPoint &&
260
+ !jsModuleUrlInfo.data.isWebWorkerEntryPoint
261
+ ) {
262
+ // not an entry point, jsenv will put it inside js/ directory
263
+ return true
264
+ }
265
+ return false
266
+ }
@@ -0,0 +1,51 @@
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
+ bundleCss({
28
+ cssUrlInfos,
29
+ context,
30
+ options: bundling.css,
31
+ })
32
+ : undefined,
33
+ js_classic: bundling.js_classic
34
+ ? (jsClassicUrlInfos, context) =>
35
+ bundleJsClassicWorkers({
36
+ jsClassicUrlInfos,
37
+ context,
38
+ options: bundling.js_classic_workers,
39
+ })
40
+ : undefined,
41
+ js_module: bundling.js_module
42
+ ? (jsModuleUrlInfos, context) =>
43
+ bundleJsModule({
44
+ jsModuleUrlInfos,
45
+ context,
46
+ options: bundling.js_module,
47
+ })
48
+ : undefined,
49
+ },
50
+ }
51
+ }