@jsenv/core 28.1.1 → 28.2.0

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 (51) hide show
  1. package/dist/js/script_type_module_supervisor.js +8 -13
  2. package/dist/js/supervisor.js +702 -534
  3. package/dist/main.js +13275 -13164
  4. package/package.json +5 -5
  5. package/readme.md +3 -3
  6. package/src/build/build.js +960 -712
  7. package/src/build/inject_global_version_mappings.js +5 -20
  8. package/src/build/start_build_server.js +2 -2
  9. package/src/dev/start_dev_server.js +3 -2
  10. package/src/execute/run.js +1 -1
  11. package/src/execute/runtimes/browsers/from_playwright.js +1 -1
  12. package/src/omega/compat/runtime_compat.js +9 -6
  13. package/src/omega/errors.js +3 -0
  14. package/src/omega/fetched_content_compliance.js +2 -2
  15. package/src/omega/kitchen.js +189 -145
  16. package/src/omega/server/file_service.js +104 -71
  17. package/src/omega/url_graph/url_graph_loader.js +77 -0
  18. package/src/omega/url_graph/url_info_transformations.js +12 -15
  19. package/src/omega/url_graph.js +115 -101
  20. package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +1 -0
  21. package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +34 -36
  22. package/src/plugins/autoreload/jsenv_plugin_hmr.js +3 -2
  23. package/src/plugins/bundling/js_module/{bundle_js_module.js → bundle_js_modules.js} +51 -14
  24. package/src/plugins/bundling/jsenv_plugin_bundling.js +2 -2
  25. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +11 -0
  26. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +73 -62
  27. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +77 -89
  28. package/src/plugins/plugin_controller.js +26 -22
  29. package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +1 -0
  30. package/src/plugins/supervisor/client/script_type_module_supervisor.js +7 -9
  31. package/src/plugins/supervisor/client/supervisor.js +125 -96
  32. package/src/plugins/supervisor/jsenv_plugin_supervisor.js +2 -4
  33. package/src/plugins/toolbar/client/execution/toolbar_execution.js +1 -1
  34. package/src/plugins/transpilation/as_js_classic/async-to-promises.js +16 -0
  35. package/src/plugins/transpilation/as_js_classic/convert_js_module_to_js_classic.js +85 -0
  36. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +48 -190
  37. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_conversion.js +102 -0
  38. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +161 -240
  39. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_library.js +84 -0
  40. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +19 -12
  41. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -24
  42. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +82 -52
  43. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +12 -13
  44. package/src/plugins/url_analysis/html/html_urls.js +91 -34
  45. package/src/plugins/url_analysis/js/js_urls.js +5 -4
  46. package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +1 -0
  47. package/src/test/execute_plan.js +3 -8
  48. package/src/test/execute_test_plan.js +1 -1
  49. package/src/build/inject_service_worker_urls.js +0 -78
  50. package/src/build/resync_resource_hints.js +0 -112
  51. package/src/omega/url_graph/url_graph_load.js +0 -74
@@ -11,206 +11,64 @@
11
11
  * and prefer to unique identifier based solely on the specifier basename for instance
12
12
  */
13
13
 
14
- import { urlToFilename, injectQueryParams } from "@jsenv/urls"
15
- import { readFileSync } from "@jsenv/filesystem"
16
- import { createMagicSource, composeTwoSourcemaps } from "@jsenv/sourcemap"
17
- import { applyBabelPlugins } from "@jsenv/ast"
18
-
19
- import { requireFromJsenv } from "@jsenv/core/src/require_from_jsenv.js"
20
- import { requireBabelPlugin } from "../babel/require_babel_plugin.js"
21
- import { babelPluginTransformImportMetaUrl } from "./helpers/babel_plugin_transform_import_meta_url.js"
14
+ import { urlToFilename } from "@jsenv/urls"
15
+ import { jsenvPluginAsJsClassicConversion } from "./jsenv_plugin_as_js_classic_conversion.js"
22
16
  import { jsenvPluginAsJsClassicHtml } from "./jsenv_plugin_as_js_classic_html.js"
23
17
  import { jsenvPluginAsJsClassicWorkers } from "./jsenv_plugin_as_js_classic_workers.js"
24
- // because of https://github.com/rpetrich/babel-plugin-transform-async-to-promises/issues/84
25
- import customAsyncToPromises from "./async-to-promises.js"
26
-
27
- export const jsenvPluginAsJsClassic = ({ systemJsInjection = true }) => {
28
- const systemJsClientFileUrl = new URL(
29
- "./client/s.js?js_classic",
30
- import.meta.url,
31
- ).href
32
-
33
- return [
34
- jsenvPluginAsJsClassicConversion({
35
- systemJsInjection,
36
- systemJsClientFileUrl,
37
- }),
38
- jsenvPluginAsJsClassicHtml({
39
- systemJsInjection,
40
- systemJsClientFileUrl,
41
- generateJsClassicFilename,
42
- }),
43
- jsenvPluginAsJsClassicWorkers({
44
- generateJsClassicFilename,
45
- }),
46
- ]
47
- }
18
+ import { jsenvPluginAsJsClassicLibrary } from "./jsenv_plugin_as_js_classic_library.js"
48
19
 
49
- // propagate ?as_js_classic to referenced urls
50
- // and perform the conversion during fetchUrlContent
51
- const jsenvPluginAsJsClassicConversion = ({
20
+ export const jsenvPluginAsJsClassic = ({
21
+ jsClassicLibrary,
22
+ jsClassicFallback,
52
23
  systemJsInjection,
53
- systemJsClientFileUrl,
54
24
  }) => {
55
- const propagateJsClassicSearchParam = (reference, context) => {
56
- const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
25
+ const systemJsClientFileUrl = new URL("./client/s.js", import.meta.url).href
26
+
27
+ const generateJsClassicFilename = (url) => {
28
+ const filename = urlToFilename(url)
29
+ let [basename, extension] = splitFileExtension(filename)
30
+ const { searchParams } = new URL(url)
57
31
  if (
58
- !parentUrlInfo ||
59
- !new URL(parentUrlInfo.url).searchParams.has("as_js_classic")
32
+ searchParams.has("as_json_module") ||
33
+ searchParams.has("as_css_module") ||
34
+ searchParams.has("as_text_module")
60
35
  ) {
61
- return null
36
+ extension = ".js"
62
37
  }
63
- const urlTransformed = injectQueryParams(reference.url, {
64
- as_js_classic: "",
65
- })
66
- reference.filename = generateJsClassicFilename(reference.url)
67
- return urlTransformed
68
- }
69
-
70
- return {
71
- name: "jsenv:as_js_classic_conversion",
72
- appliesDuring: "*",
73
- redirectUrl: {
74
- // We want to propagate transformation of js module to js classic to:
75
- // - import specifier (static/dynamic import + re-export)
76
- // - url specifier when inside System.register/_context.import()
77
- // (because it's the transpiled equivalent of static and dynamic imports)
78
- // And not other references otherwise we could try to transform inline resources
79
- // or specifiers inside new URL()...
80
- js_import_export: propagateJsClassicSearchParam,
81
- js_url_specifier: (reference, context) => {
82
- if (
83
- reference.subtype === "system_register_arg" ||
84
- reference.subtype === "system_import_arg"
85
- ) {
86
- return propagateJsClassicSearchParam(reference, context)
87
- }
88
- return null
89
- },
90
- },
91
- fetchUrlContent: async (urlInfo, context) => {
92
- const originalUrlInfo = await context.fetchOriginalUrlInfo({
93
- urlInfo,
94
- context,
95
- searchParam: "as_js_classic",
96
- // override the expectedType to "js_module"
97
- // because when there is ?as_js_classic it means the underlying resource
98
- // is a js_module
99
- expectedType: "js_module",
100
- })
101
- if (!originalUrlInfo) {
102
- return null
103
- }
104
- const jsClassicFormat =
105
- // in general html file are entry points, but js can be entry point when:
106
- // - passed in entryPoints to build
107
- // - is used by web worker
108
- // - the reference contains ?entry_point
109
- // When js is entry point there can be no HTML to inject systemjs
110
- // and systemjs must be injected into the js file
111
- urlInfo.isEntryPoint &&
112
- // if it's an entry point without dependency (it does not use import)
113
- // then we can use UMD, otherwise we have to use systemjs
114
- // because it is imported by systemjs
115
- !originalUrlInfo.data.usesImport
116
- ? "umd"
117
- : "system"
118
- const { content, sourcemap } = await convertJsModuleToJsClassic({
119
- systemJsInjection,
120
- systemJsClientFileUrl,
121
- urlInfo,
122
- originalUrlInfo,
123
- jsClassicFormat,
124
- })
125
- urlInfo.data.jsClassicFormat = jsClassicFormat
126
- return {
127
- content,
128
- contentType: "text/javascript",
129
- type: "js_classic",
130
- originalUrl: originalUrlInfo.originalUrl,
131
- originalContent: originalUrlInfo.originalContent,
132
- sourcemap,
133
- }
134
- },
135
- }
136
- }
137
-
138
- const generateJsClassicFilename = (url) => {
139
- const filename = urlToFilename(url)
140
- let [basename, extension] = splitFileExtension(filename)
141
- const { searchParams } = new URL(url)
142
- if (
143
- searchParams.has("as_json_module") ||
144
- searchParams.has("as_css_module") ||
145
- searchParams.has("as_text_module")
146
- ) {
147
- extension = ".js"
148
- }
149
- return `${basename}.nomodule${extension}`
150
- }
151
-
152
- const splitFileExtension = (filename) => {
153
- const dotLastIndex = filename.lastIndexOf(".")
154
- if (dotLastIndex === -1) {
155
- return [filename, ""]
38
+ return `${basename}.nomodule${extension}`
156
39
  }
157
- return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)]
158
- }
159
40
 
160
- const convertJsModuleToJsClassic = async ({
161
- systemJsInjection,
162
- systemJsClientFileUrl,
163
- urlInfo,
164
- originalUrlInfo,
165
- jsClassicFormat,
166
- }) => {
167
- const { code, map } = await applyBabelPlugins({
168
- babelPlugins: [
169
- ...(jsClassicFormat === "system"
170
- ? [
171
- // propposal-dynamic-import required with systemjs for babel8:
172
- // https://github.com/babel/babel/issues/10746
173
- requireFromJsenv("@babel/plugin-proposal-dynamic-import"),
174
- requireFromJsenv("@babel/plugin-transform-modules-systemjs"),
175
- [
176
- customAsyncToPromises,
177
- {
178
- topLevelAwait: "return",
179
- },
180
- ],
181
- ]
182
- : [
183
- [
184
- requireBabelPlugin("babel-plugin-transform-async-to-promises"),
185
- {
186
- topLevelAwait: "simple",
187
- },
188
- ],
189
- babelPluginTransformImportMetaUrl,
190
- requireFromJsenv("@babel/plugin-transform-modules-umd"),
191
- ]),
192
- ],
193
- urlInfo: originalUrlInfo,
194
- })
195
- let sourcemap = originalUrlInfo.sourcemap
196
- sourcemap = await composeTwoSourcemaps(sourcemap, map)
197
- if (
198
- systemJsInjection &&
199
- jsClassicFormat === "system" &&
200
- urlInfo.isEntryPoint
201
- ) {
202
- const magicSource = createMagicSource(code)
203
- const systemjsCode = readFileSync(systemJsClientFileUrl, { as: "string" })
204
- magicSource.prepend(`${systemjsCode}\n\n`)
205
- const magicResult = magicSource.toContentAndSourcemap()
206
- sourcemap = await composeTwoSourcemaps(sourcemap, magicResult.sourcemap)
207
- return {
208
- content: magicResult.content,
209
- sourcemap,
41
+ const splitFileExtension = (filename) => {
42
+ const dotLastIndex = filename.lastIndexOf(".")
43
+ if (dotLastIndex === -1) {
44
+ return [filename, ""]
210
45
  }
46
+ return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)]
211
47
  }
212
- return {
213
- content: code,
214
- sourcemap,
215
- }
48
+
49
+ return [
50
+ ...(jsClassicLibrary
51
+ ? [
52
+ jsenvPluginAsJsClassicLibrary({
53
+ systemJsInjection,
54
+ systemJsClientFileUrl,
55
+ generateJsClassicFilename,
56
+ }),
57
+ ]
58
+ : []),
59
+ ...(jsClassicFallback
60
+ ? [
61
+ jsenvPluginAsJsClassicHtml({
62
+ systemJsInjection,
63
+ systemJsClientFileUrl,
64
+ }),
65
+ jsenvPluginAsJsClassicWorkers(),
66
+ jsenvPluginAsJsClassicConversion({
67
+ systemJsInjection,
68
+ systemJsClientFileUrl,
69
+ generateJsClassicFilename,
70
+ }),
71
+ ]
72
+ : []),
73
+ ]
216
74
  }
@@ -0,0 +1,102 @@
1
+ // propagate ?as_js_classic to referenced urls
2
+ // and perform the conversion during fetchUrlContent
3
+
4
+ import { injectQueryParams } from "@jsenv/urls"
5
+ import { convertJsModuleToJsClassic } from "./convert_js_module_to_js_classic.js"
6
+
7
+ export const jsenvPluginAsJsClassicConversion = ({
8
+ systemJsInjection,
9
+ systemJsClientFileUrl,
10
+ generateJsClassicFilename,
11
+ }) => {
12
+ const shouldPropagateJsClassic = (reference, context) => {
13
+ const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
14
+ if (!parentUrlInfo) {
15
+ return false
16
+ }
17
+ return new URL(parentUrlInfo.url).searchParams.has("as_js_classic")
18
+ }
19
+ const markAsJsClassicProxy = (reference) => {
20
+ reference.expectedType = "js_classic"
21
+ reference.filename = generateJsClassicFilename(reference.url)
22
+ }
23
+ const turnIntoJsClassicProxy = (reference) => {
24
+ const urlTransformed = injectQueryParams(reference.url, {
25
+ as_js_classic: "",
26
+ })
27
+ markAsJsClassicProxy(reference)
28
+ return urlTransformed
29
+ }
30
+
31
+ return {
32
+ name: "jsenv:as_js_classic_conversion",
33
+ appliesDuring: "*",
34
+ redirectUrl: (reference, context) => {
35
+ if (reference.searchParams.has("as_js_classic")) {
36
+ markAsJsClassicProxy(reference)
37
+ return null
38
+ }
39
+ if (
40
+ reference.type === "js_import_export" ||
41
+ reference.subtype === "system_register_arg" ||
42
+ reference.subtype === "system_import_arg"
43
+ ) {
44
+ // We want to propagate transformation of js module to js classic to:
45
+ // - import specifier (static/dynamic import + re-export)
46
+ // - url specifier when inside System.register/_context.import()
47
+ // (because it's the transpiled equivalent of static and dynamic imports)
48
+ // And not other references otherwise we could try to transform inline resources
49
+ // or specifiers inside new URL()...
50
+ if (shouldPropagateJsClassic(reference, context)) {
51
+ return turnIntoJsClassicProxy(reference, context)
52
+ }
53
+ }
54
+ return null
55
+ },
56
+ fetchUrlContent: async (urlInfo, context) => {
57
+ const [jsModuleReference, jsModuleUrlInfo] =
58
+ context.getWithoutSearchParam({
59
+ urlInfo,
60
+ context,
61
+ searchParam: "as_js_classic",
62
+ // override the expectedType to "js_module"
63
+ // because when there is ?as_js_classic it means the underlying resource
64
+ // is a js_module
65
+ expectedType: "js_module",
66
+ })
67
+ if (!jsModuleReference) {
68
+ return null
69
+ }
70
+ await context.fetchUrlContent(jsModuleUrlInfo, {
71
+ reference: jsModuleReference,
72
+ })
73
+ if (context.scenarios.dev) {
74
+ context.referenceUtils.found({
75
+ type: "js_import_export",
76
+ subtype: jsModuleReference.subtype,
77
+ specifier: jsModuleReference.url,
78
+ expectedType: "js_module",
79
+ })
80
+ } else if (
81
+ context.scenarios.build &&
82
+ jsModuleUrlInfo.dependents.size === 0
83
+ ) {
84
+ context.urlGraph.deleteUrlInfo(jsModuleUrlInfo.url)
85
+ }
86
+ const { content, sourcemap } = await convertJsModuleToJsClassic({
87
+ systemJsInjection,
88
+ systemJsClientFileUrl,
89
+ urlInfo,
90
+ jsModuleUrlInfo,
91
+ })
92
+ return {
93
+ content,
94
+ contentType: "text/javascript",
95
+ type: "js_classic",
96
+ originalUrl: jsModuleUrlInfo.originalUrl,
97
+ originalContent: jsModuleUrlInfo.originalContent,
98
+ sourcemap,
99
+ }
100
+ },
101
+ }
102
+ }