@jsenv/core 27.0.0-alpha.5 → 27.0.0-alpha.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/event_source_client.js +545 -0
  2. package/dist/event_source_client.js.map +187 -0
  3. package/dist/html_supervisor_installer.js +1236 -0
  4. package/dist/html_supervisor_installer.js.map +337 -0
  5. package/dist/html_supervisor_setup.js +95 -0
  6. package/dist/html_supervisor_setup.js.map +57 -0
  7. package/dist/import_meta_hot.js +86 -0
  8. package/dist/import_meta_hot.js.map +42 -0
  9. package/main.js +8 -1
  10. package/package.json +22 -21
  11. package/readme.md +4 -12
  12. package/src/build/build.js +749 -437
  13. package/src/build/build_urls_generator.js +56 -22
  14. package/src/build/graph_utils.js +31 -0
  15. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +33 -15
  16. package/src/build/inject_service_worker_urls.js +79 -0
  17. package/src/build/resync_ressource_hints.js +68 -0
  18. package/src/build/start_build_server.js +255 -0
  19. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  20. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  21. package/src/dev/start_dev_server.js +136 -30
  22. package/src/execute/execute.js +31 -6
  23. package/src/execute/run.js +19 -56
  24. package/src/execute/runtimes/browsers/from_playwright.js +201 -147
  25. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  26. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  27. package/src/execute/runtimes/node/node_process.js +280 -39
  28. package/src/jsenv_root_directory_url.js +1 -0
  29. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  30. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +66 -4
  31. package/src/omega/compat/runtime_compat.js +50 -0
  32. package/src/omega/errors.js +51 -58
  33. package/src/omega/fetched_content_compliance.js +24 -0
  34. package/src/omega/file_url_converter.js +8 -50
  35. package/src/omega/kitchen.js +482 -292
  36. package/src/omega/omega_server.js +2 -3
  37. package/src/omega/server/file_service.js +38 -25
  38. package/src/omega/server/user_agent.js +4 -2
  39. package/src/omega/url_graph/url_graph_load.js +14 -7
  40. package/src/omega/url_graph/url_graph_report.js +17 -15
  41. package/src/omega/url_graph/url_info_transformations.js +26 -9
  42. package/src/omega/url_graph.js +91 -16
  43. package/src/omega/web_workers.js +42 -0
  44. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  45. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  46. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  47. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  48. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +46 -0
  49. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +204 -0
  50. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +27 -0
  51. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  52. package/src/plugins/bundling/css/bundle_css.js +21 -0
  53. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  54. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +150 -79
  55. package/src/plugins/bundling/jsenv_plugin_bundling.js +54 -0
  56. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  57. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  58. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +8 -5
  59. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  60. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  61. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +242 -0
  62. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +79 -0
  63. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  64. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  65. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +83 -58
  66. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  67. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  68. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  69. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  70. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +105 -0
  71. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  72. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  73. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  74. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +39 -33
  75. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +67 -0
  76. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  77. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  78. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +65 -44
  79. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  80. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  81. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +296 -0
  82. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  83. package/src/plugins/minification/css/minify_css.js +9 -0
  84. package/src/plugins/minification/html/minify_html.js +15 -0
  85. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  86. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  87. package/src/plugins/minification/json/minify_json.js +8 -0
  88. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +146 -0
  89. package/src/{omega → plugins}/plugin_controller.js +42 -11
  90. package/src/plugins/plugins.js +91 -0
  91. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  92. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  93. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  94. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  95. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +183 -0
  96. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +256 -0
  97. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +55 -0
  98. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  99. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  100. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  101. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +4 -22
  102. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  103. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +37 -21
  104. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  105. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  106. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  107. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  108. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  109. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  110. package/src/plugins/transpilation/fetch_original_url_info.js +30 -0
  111. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +181 -0
  112. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +70 -0
  113. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +44 -0
  114. package/src/plugins/url_analysis/css/css_urls.js +42 -0
  115. package/src/plugins/url_analysis/html/html_urls.js +273 -0
  116. package/src/plugins/url_analysis/js/js_urls.js +67 -0
  117. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +18 -0
  118. package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +17 -0
  119. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  120. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +12 -15
  121. package/src/test/execute_plan.js +30 -18
  122. package/src/test/execute_test_plan.js +23 -8
  123. package/src/test/logs_file_execution.js +8 -7
  124. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  125. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  126. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +0 -374
  127. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  128. package/src/execute/runtimes/node/controlled_process.js +0 -316
  129. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  130. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_installer.js +0 -168
  131. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_setup.js +0 -77
  132. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  133. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  134. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  135. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  136. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  137. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  138. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  139. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  140. package/src/omega/core_plugins.js +0 -39
  141. package/src/omega/runtime_support/runtime_support.js +0 -20
  142. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  143. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  144. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  145. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  146. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -0,0 +1,204 @@
1
+ import { urlToRelativeUrl } from "@jsenv/filesystem"
2
+ import { createCallbackList } from "@jsenv/abort"
3
+
4
+ import { createSSEService } from "@jsenv/utils/event_source/sse_service.js"
5
+
6
+ export const jsenvPluginDevSSEServer = ({
7
+ rootDirectoryUrl,
8
+ urlGraph,
9
+ clientFileChangeCallbackList,
10
+ clientFilesPruneCallbackList,
11
+ }) => {
12
+ const serverEventCallbackList = createCallbackList()
13
+ const sseService = createSSEService({ serverEventCallbackList })
14
+
15
+ const notifyDeclined = ({ cause, reason, declinedBy }) => {
16
+ serverEventCallbackList.notify({
17
+ type: "reload",
18
+ data: JSON.stringify({
19
+ cause,
20
+ type: "full",
21
+ typeReason: reason,
22
+ declinedBy,
23
+ }),
24
+ })
25
+ }
26
+ const notifyAccepted = ({ cause, reason, instructions }) => {
27
+ serverEventCallbackList.notify({
28
+ type: "reload",
29
+ data: JSON.stringify({
30
+ cause,
31
+ type: "hot",
32
+ typeReason: reason,
33
+ hotInstructions: instructions,
34
+ }),
35
+ })
36
+ }
37
+ const propagateUpdate = (firstUrlInfo) => {
38
+ const urlInfos = urlGraph.urlInfos
39
+ const iterate = (urlInfo, trace) => {
40
+ if (urlInfo.data.hotAcceptSelf) {
41
+ return {
42
+ accepted: true,
43
+ reason:
44
+ urlInfo === firstUrlInfo
45
+ ? `file accepts hot reload`
46
+ : `a dependent file accepts hot reload`,
47
+ instructions: [
48
+ {
49
+ type: urlInfo.type,
50
+ boundary: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
51
+ acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
52
+ },
53
+ ],
54
+ }
55
+ }
56
+ const { dependents } = urlInfo
57
+ const instructions = []
58
+ for (const dependentUrl of dependents) {
59
+ const dependentUrlInfo = urlInfos[dependentUrl]
60
+ if (dependentUrlInfo.data.hotDecline) {
61
+ return {
62
+ declined: true,
63
+ reason: `a dependent file declines hot reload`,
64
+ declinedBy: dependentUrl,
65
+ }
66
+ }
67
+ const { hotAcceptDependencies = [] } = dependentUrlInfo.data
68
+ if (hotAcceptDependencies.includes(urlInfo.url)) {
69
+ instructions.push({
70
+ type: dependentUrlInfo.type,
71
+ boundary: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
72
+ acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
73
+ })
74
+ continue
75
+ }
76
+ if (trace.includes(dependentUrl)) {
77
+ return {
78
+ declined: true,
79
+ reason: "circular dependency",
80
+ declinedBy: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
81
+ }
82
+ }
83
+ const dependentPropagationResult = iterate(dependentUrlInfo, [
84
+ ...trace,
85
+ dependentUrl,
86
+ ])
87
+ if (dependentPropagationResult.accepted) {
88
+ instructions.push(...dependentPropagationResult.instructions)
89
+ continue
90
+ }
91
+ if (
92
+ // declined explicitely by an other file, it must decline the whole update
93
+ dependentPropagationResult.declinedBy
94
+ ) {
95
+ return dependentPropagationResult
96
+ }
97
+ // declined by absence of boundary, we can keep searching
98
+ continue
99
+ }
100
+ if (instructions.length === 0) {
101
+ return {
102
+ declined: true,
103
+ reason: `there is no file accepting hot reload while propagating update`,
104
+ }
105
+ }
106
+ return {
107
+ accepted: true,
108
+ reason: `${instructions.length} dependent file(s) accepts hot reload`,
109
+ instructions,
110
+ }
111
+ }
112
+ const trace = []
113
+ return iterate(firstUrlInfo, trace)
114
+ }
115
+ clientFileChangeCallbackList.push(({ url, event }) => {
116
+ const urlInfo = urlGraph.urlInfos[url]
117
+ // file not part of dependency graph
118
+ if (!urlInfo) {
119
+ return
120
+ }
121
+ const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl)
122
+ const hotUpdate = propagateUpdate(urlInfo)
123
+ if (hotUpdate.declined) {
124
+ notifyDeclined({
125
+ cause: `${relativeUrl} ${event}`,
126
+ reason: hotUpdate.reason,
127
+ declinedBy: hotUpdate.declinedBy,
128
+ })
129
+ } else {
130
+ notifyAccepted({
131
+ cause: `${relativeUrl} ${event}`,
132
+ reason: hotUpdate.reason,
133
+ instructions: hotUpdate.instructions,
134
+ })
135
+ }
136
+ })
137
+ clientFilesPruneCallbackList.push(({ prunedUrlInfos, firstUrlInfo }) => {
138
+ const mainHotUpdate = propagateUpdate(firstUrlInfo)
139
+ const cause = `following files are no longer referenced: ${prunedUrlInfos.map(
140
+ (prunedUrlInfo) => urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
141
+ )}`
142
+ // now check if we can hot update the main ressource
143
+ // then if we can hot update all dependencies
144
+ if (mainHotUpdate.declined) {
145
+ notifyDeclined({
146
+ cause,
147
+ reason: mainHotUpdate.reason,
148
+ declinedBy: mainHotUpdate.declinedBy,
149
+ })
150
+ return
151
+ }
152
+ // main can hot update
153
+ let i = 0
154
+ const instructions = []
155
+ while (i < prunedUrlInfos.length) {
156
+ const prunedUrlInfo = prunedUrlInfos[i++]
157
+ if (prunedUrlInfo.data.hotDecline) {
158
+ notifyDeclined({
159
+ cause,
160
+ reason: `a pruned file declines hot reload`,
161
+ declinedBy: urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
162
+ })
163
+ return
164
+ }
165
+ instructions.push({
166
+ type: "prune",
167
+ boundary: urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
168
+ acceptedBy: urlToRelativeUrl(firstUrlInfo.url, rootDirectoryUrl),
169
+ })
170
+ }
171
+ notifyAccepted({
172
+ cause,
173
+ reason: mainHotUpdate.reason,
174
+ instructions,
175
+ })
176
+ })
177
+
178
+ return {
179
+ name: "jsenv:sse_server",
180
+ appliesDuring: { dev: true },
181
+ serve: (request) => {
182
+ if (request.ressource === "/__graph__") {
183
+ const graphJson = JSON.stringify(urlGraph.toJSON(rootDirectoryUrl))
184
+ return {
185
+ status: 200,
186
+ headers: {
187
+ "content-type": "application/json",
188
+ "content-length": Buffer.byteLength(graphJson),
189
+ },
190
+ body: graphJson,
191
+ }
192
+ }
193
+ const { accept } = request.headers
194
+ if (accept && accept.includes("text/event-stream")) {
195
+ const room = sseService.getOrCreateSSERoom(request)
196
+ return room.join(request)
197
+ }
198
+ return null
199
+ },
200
+ destroy: () => {
201
+ sseService.destroy()
202
+ },
203
+ }
204
+ }
@@ -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
+ clientFileChangeCallbackList,
10
+ clientFilesPruneCallbackList,
11
+ }) => {
12
+ if (scenario === "build") {
13
+ return []
14
+ }
15
+ return [
16
+ jsenvPluginHmr(),
17
+ jsenvPluginDevSSEClient({
18
+ rootDirectoryUrl,
19
+ }),
20
+ jsenvPluginDevSSEServer({
21
+ rootDirectoryUrl,
22
+ urlGraph,
23
+ clientFileChangeCallbackList,
24
+ clientFilesPruneCallbackList,
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.modifiedTimestamp) {
27
+ return null
28
+ }
29
+ return {
30
+ hmr: "",
31
+ v: urlInfo.modifiedTimestamp,
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,41 @@
1
- import { isFileSystemPath, urlToRelativeUrl } from "@jsenv/filesystem"
1
+ import {
2
+ isFileSystemPath,
3
+ normalizeStructuredMetaMap,
4
+ urlToMeta,
5
+ } from "@jsenv/filesystem"
6
+ import { createDetailedMessage } from "@jsenv/logger"
2
7
 
3
8
  import { applyRollupPlugins } from "@jsenv/utils/js_ast/apply_rollup_plugins.js"
4
9
  import { sourcemapConverter } from "@jsenv/utils/sourcemap/sourcemap_converter.js"
5
10
  import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
6
11
 
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,
12
+ export const bundleJsModule = async ({
13
+ jsModuleUrlInfos,
14
+ context,
15
+ options,
16
+ }) => {
17
+ const {
18
+ signal,
19
+ logger,
20
+ rootDirectoryUrl,
21
+ buildDirectoryUrl,
22
+ urlGraph,
23
+ runtimeCompat,
24
+ sourcemaps,
25
+ } = context
26
+ const { jsModuleBundleUrlInfos } = await buildWithRollup({
27
+ signal,
28
+ logger,
29
+ rootDirectoryUrl,
30
+ buildDirectoryUrl,
31
+ urlGraph,
32
+ jsModuleUrlInfos,
33
33
 
34
- runtimeSupport,
35
- sourcemaps,
36
- })
37
- return jsModuleBundleUrlInfos
38
- },
39
- },
40
- }
34
+ runtimeCompat,
35
+ sourcemaps,
36
+ options,
37
+ })
38
+ return jsModuleBundleUrlInfos
41
39
  }
42
40
 
43
41
  export const buildWithRollup = async ({
@@ -48,36 +46,48 @@ export const buildWithRollup = async ({
48
46
  urlGraph,
49
47
  jsModuleUrlInfos,
50
48
 
51
- runtimeSupport,
49
+ runtimeCompat,
52
50
  sourcemaps,
51
+ options,
53
52
  }) => {
54
53
  const resultRef = { current: null }
55
- await applyRollupPlugins({
56
- rollupPlugins: [
57
- rollupPluginJsenv({
58
- signal,
59
- logger,
60
- rootDirectoryUrl,
61
- buildDirectoryUrl,
62
- urlGraph,
63
- jsModuleUrlInfos,
54
+ try {
55
+ await applyRollupPlugins({
56
+ rollupPlugins: [
57
+ rollupPluginJsenv({
58
+ signal,
59
+ logger,
60
+ rootDirectoryUrl,
61
+ buildDirectoryUrl,
62
+ urlGraph,
63
+ jsModuleUrlInfos,
64
64
 
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))
65
+ runtimeCompat,
66
+ sourcemaps,
67
+ options,
68
+ resultRef,
69
+ }),
70
+ ],
71
+ inputOptions: {
72
+ input: [],
73
+ onwarn: (warning) => {
74
+ if (warning.code === "CIRCULAR_DEPENDENCY") {
75
+ return
76
+ }
77
+ logger.warn(String(warning))
78
+ },
77
79
  },
78
- },
79
- })
80
- return resultRef.current
80
+ })
81
+ return resultRef.current
82
+ } catch (e) {
83
+ if (e.code === "MISSING_EXPORT") {
84
+ const detailedMessage = createDetailedMessage(e.message, {
85
+ frame: e.frame,
86
+ })
87
+ throw new Error(detailedMessage, { cause: e })
88
+ }
89
+ throw e
90
+ }
81
91
  }
82
92
 
83
93
  const rollupPluginJsenv = ({
@@ -87,6 +97,7 @@ const rollupPluginJsenv = ({
87
97
  urlGraph,
88
98
  jsModuleUrlInfos,
89
99
  sourcemaps,
100
+ options,
90
101
 
91
102
  resultRef,
92
103
  }) => {
@@ -99,6 +110,21 @@ const rollupPluginJsenv = ({
99
110
  ...chunk,
100
111
  })
101
112
  }
113
+ let importCanBeBundled = () => true
114
+ if (options.include) {
115
+ const bundleIncludeConfig = normalizeStructuredMetaMap(
116
+ {
117
+ bundle: options.include,
118
+ },
119
+ rootDirectoryUrl,
120
+ )
121
+ importCanBeBundled = (url) => {
122
+ return urlToMeta({
123
+ url,
124
+ structuredMetaMap: bundleIncludeConfig,
125
+ }).bundle
126
+ }
127
+ }
102
128
  const urlImporters = {}
103
129
 
104
130
  return {
@@ -119,6 +145,7 @@ const rollupPluginJsenv = ({
119
145
  implicitlyLoadedAfterOneOf: previousNonEntryPointModuleId
120
146
  ? [previousNonEntryPointModuleId]
121
147
  : null,
148
+ preserveSignature: "allow-extension",
122
149
  })
123
150
  previousNonEntryPointModuleId = id
124
151
  })
@@ -131,24 +158,25 @@ const rollupPluginJsenv = ({
131
158
  const rollupFileInfo = rollupResult[fileName]
132
159
  // there is 3 types of file: "placeholder", "asset", "chunk"
133
160
  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
161
  const jsModuleBundleUrlInfo = {
144
- // buildRelativeUrl: rollupFileInfo.fileName,
145
162
  data: {
146
163
  generatedBy: "rollup",
164
+ bundleRelativeUrl: rollupFileInfo.fileName,
165
+ usesImport:
166
+ rollupFileInfo.imports.length > 0 ||
167
+ rollupFileInfo.dynamicImports.length > 0,
168
+ usesExport: rollupFileInfo.exports.length > 0,
147
169
  },
148
- contentType: "application/javascript",
170
+ contentType: "text/javascript",
149
171
  content: rollupFileInfo.code,
150
172
  sourcemap: rollupFileInfo.map,
151
173
  }
174
+ let url
175
+ if (rollupFileInfo.facadeModuleId) {
176
+ url = fileUrlConverter.asFileUrl(rollupFileInfo.facadeModuleId)
177
+ } else {
178
+ url = new URL(rollupFileInfo.fileName, buildDirectoryUrl).href
179
+ }
152
180
  jsModuleBundleUrlInfos[url] = jsModuleBundleUrlInfo
153
181
  }
154
182
  })
@@ -170,14 +198,23 @@ const rollupPluginJsenv = ({
170
198
  return `[name].js`
171
199
  },
172
200
  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
201
+ const insideJs = willBeInsideJsDirectory({
202
+ chunkInfo,
203
+ fileUrlConverter,
204
+ jsModuleUrlInfos,
205
+ })
206
+ let nameFromUrlInfo
207
+ if (chunkInfo.facadeModuleId) {
208
+ const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
209
+ const urlInfo = jsModuleUrlInfos.find(
210
+ (jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
211
+ )
212
+ if (urlInfo) {
213
+ nameFromUrlInfo = urlInfo.filename
214
+ }
215
+ }
216
+ const name = nameFromUrlInfo || `${chunkInfo.name}.js`
217
+ return insideJs ? `js/${name}` : `${name}`
181
218
  },
182
219
  // https://rollupjs.org/guide/en/#outputpaths
183
220
  // paths: (id) => {
@@ -195,7 +232,10 @@ const rollupPluginJsenv = ({
195
232
  urlImporters[url] = importer
196
233
  }
197
234
  if (!url.startsWith("file:")) {
198
- return { url, external: true }
235
+ return { id: url, external: true }
236
+ }
237
+ if (!importCanBeBundled(url)) {
238
+ return { id: url, external: true }
199
239
  }
200
240
  const filePath = fileUrlConverter.asFilePath(url)
201
241
  return filePath
@@ -223,3 +263,34 @@ const rollupPluginJsenv = ({
223
263
  },
224
264
  }
225
265
  }
266
+
267
+ const willBeInsideJsDirectory = ({
268
+ chunkInfo,
269
+ fileUrlConverter,
270
+ jsModuleUrlInfos,
271
+ }) => {
272
+ // if the chunk is generated dynamically by rollup
273
+ // for an entry point jsenv will put that file inside js/ directory
274
+ // if it's generated dynamically for a file already in js/ directory
275
+ // both will be inside the js/ directory
276
+ if (!chunkInfo.facadeModuleId) {
277
+ // generated by rollup
278
+ return true
279
+ }
280
+ const url = fileUrlConverter.asFileUrl(chunkInfo.facadeModuleId)
281
+ const jsModuleUrlInfo = jsModuleUrlInfos.find(
282
+ (jsModuleUrlInfo) => jsModuleUrlInfo.url === url,
283
+ )
284
+ if (!jsModuleUrlInfo) {
285
+ // generated by rollup
286
+ return true
287
+ }
288
+ if (
289
+ !jsModuleUrlInfo.data.isEntryPoint &&
290
+ !jsModuleUrlInfo.data.isWebWorkerEntryPoint
291
+ ) {
292
+ // not an entry point, jsenv will put it inside js/ directory
293
+ return true
294
+ }
295
+ return false
296
+ }
@@ -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
+ }