@jsenv/core 28.1.3 → 28.2.2

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 (47) hide show
  1. package/dist/js/script_type_module_supervisor.js +8 -13
  2. package/dist/js/supervisor.js +690 -504
  3. package/dist/main.js +13332 -13179
  4. package/package.json +5 -5
  5. package/readme.md +3 -3
  6. package/src/build/build.js +980 -713
  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 +6 -3
  10. package/src/omega/compat/runtime_compat.js +9 -6
  11. package/src/omega/errors.js +3 -0
  12. package/src/omega/fetched_content_compliance.js +2 -2
  13. package/src/omega/kitchen.js +191 -146
  14. package/src/omega/server/file_service.js +104 -71
  15. package/src/omega/url_graph/url_graph_loader.js +77 -0
  16. package/src/omega/url_graph/url_info_transformations.js +12 -15
  17. package/src/omega/url_graph.js +118 -101
  18. package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +1 -0
  19. package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +34 -36
  20. package/src/plugins/autoreload/jsenv_plugin_hmr.js +3 -2
  21. package/src/plugins/bundling/js_module/{bundle_js_module.js → bundle_js_modules.js} +51 -14
  22. package/src/plugins/bundling/jsenv_plugin_bundling.js +2 -2
  23. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +11 -0
  24. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +73 -62
  25. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +77 -89
  26. package/src/plugins/plugin_controller.js +26 -22
  27. package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +1 -0
  28. package/src/plugins/supervisor/client/script_type_module_supervisor.js +7 -9
  29. package/src/plugins/supervisor/client/supervisor.js +99 -52
  30. package/src/plugins/supervisor/jsenv_plugin_supervisor.js +2 -4
  31. package/src/plugins/transpilation/as_js_classic/async-to-promises.js +16 -0
  32. package/src/plugins/transpilation/as_js_classic/convert_js_module_to_js_classic.js +85 -0
  33. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +48 -190
  34. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_conversion.js +104 -0
  35. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +161 -240
  36. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_library.js +92 -0
  37. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +19 -12
  38. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -24
  39. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +82 -52
  40. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +12 -13
  41. package/src/plugins/url_analysis/html/html_urls.js +91 -34
  42. package/src/plugins/url_analysis/js/js_urls.js +5 -4
  43. package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +1 -0
  44. package/src/test/execute_plan.js +3 -8
  45. package/src/build/inject_service_worker_urls.js +0 -78
  46. package/src/build/resync_resource_hints.js +0 -112
  47. package/src/omega/url_graph/url_graph_load.js +0 -74
@@ -5,12 +5,7 @@ import wrapAnsi from "wrap-ansi"
5
5
  import stripAnsi from "strip-ansi"
6
6
 
7
7
  import { urlToFileSystemPath } from "@jsenv/urls"
8
- import {
9
- createDetailedMessage,
10
- loggerToLevels,
11
- createLog,
12
- startSpinner,
13
- } from "@jsenv/log"
8
+ import { createDetailedMessage, createLog, startSpinner } from "@jsenv/log"
14
9
  import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
15
10
  import { ensureEmptyDirectory, writeFileSync } from "@jsenv/filesystem"
16
11
 
@@ -209,8 +204,8 @@ export const executePlan = async (
209
204
  `Force completedExecutionLogMerging to false because process.stdout.isTTY is false`,
210
205
  )
211
206
  }
212
- const debugLogsEnabled = loggerToLevels(logger).debug
213
- const executionLogsEnabled = loggerToLevels(logger).info
207
+ const debugLogsEnabled = logger.levels.debug
208
+ const executionLogsEnabled = logger.levels.info
214
209
  const executionSpinner =
215
210
  logRefresh &&
216
211
  !debugLogsEnabled &&
@@ -1,78 +0,0 @@
1
- import { createMagicSource } from "@jsenv/sourcemap"
2
-
3
- import { GRAPH } from "./graph_utils.js"
4
- import { createVersionGenerator } from "./version_generator.js"
5
-
6
- export const injectServiceWorkerUrls = async ({
7
- finalGraph,
8
- finalGraphKitchen,
9
- lineBreakNormalization,
10
- }) => {
11
- const serviceWorkerEntryUrlInfos = GRAPH.filter(
12
- finalGraph,
13
- (finalUrlInfo) => {
14
- return (
15
- finalUrlInfo.subtype === "service_worker" && finalUrlInfo.isEntryPoint
16
- )
17
- },
18
- )
19
- if (serviceWorkerEntryUrlInfos.length === 0) {
20
- return
21
- }
22
- const serviceWorkerUrls = {}
23
- GRAPH.forEach(finalGraph, (urlInfo) => {
24
- if (urlInfo.isInline || !urlInfo.shouldHandle) {
25
- return
26
- }
27
- if (!urlInfo.url.startsWith("file:")) {
28
- return
29
- }
30
- if (urlInfo.data.buildUrlIsVersioned) {
31
- serviceWorkerUrls[urlInfo.data.buildUrlSpecifier] = {
32
- versioned: true,
33
- }
34
- return
35
- }
36
- if (!urlInfo.data.version) {
37
- // when url is not versioned we compute a "version" for that url anyway
38
- // so that service worker source still changes and navigator
39
- // detect there is a change
40
- const versionGenerator = createVersionGenerator()
41
- versionGenerator.augmentWithContent({
42
- content: urlInfo.content,
43
- contentType: urlInfo.contentType,
44
- lineBreakNormalization,
45
- })
46
- const version = versionGenerator.generate()
47
- urlInfo.data.version = version
48
- }
49
- serviceWorkerUrls[urlInfo.data.buildUrlSpecifier] = {
50
- versioned: false,
51
- version: urlInfo.data.version,
52
- }
53
- })
54
- await Promise.all(
55
- serviceWorkerEntryUrlInfos.map(async (serviceWorkerEntryUrlInfo) => {
56
- const magicSource = createMagicSource(serviceWorkerEntryUrlInfo.content)
57
- const urlsWithoutSelf = {
58
- ...serviceWorkerUrls,
59
- }
60
- delete urlsWithoutSelf[serviceWorkerEntryUrlInfo.data.buildUrlSpecifier]
61
- magicSource.prepend(generateClientCode(urlsWithoutSelf))
62
- const { content, sourcemap } = magicSource.toContentAndSourcemap()
63
- await finalGraphKitchen.urlInfoTransformer.applyFinalTransformations(
64
- serviceWorkerEntryUrlInfo,
65
- {
66
- content,
67
- sourcemap,
68
- },
69
- )
70
- }),
71
- )
72
- }
73
-
74
- const generateClientCode = (serviceWorkerUrls) => {
75
- return `
76
- self.serviceWorkerUrls = ${JSON.stringify(serviceWorkerUrls, null, " ")};
77
- `
78
- }
@@ -1,112 +0,0 @@
1
- /*
2
- * Update <link rel="preload"> and friends after build (once we know everything)
3
- *
4
- * - Used to remove resource hint targeting an url that is no longer used:
5
- * - Happens because of import assertions transpilation (file is inlined into JS)
6
- */
7
-
8
- import {
9
- parseHtmlString,
10
- visitHtmlNodes,
11
- getHtmlNodeAttribute,
12
- setHtmlNodeAttributes,
13
- removeHtmlNode,
14
- stringifyHtmlAst,
15
- } from "@jsenv/ast"
16
-
17
- import { GRAPH } from "./graph_utils.js"
18
-
19
- export const resyncResourceHints = async ({
20
- logger,
21
- finalGraphKitchen,
22
- finalGraph,
23
- rawUrls,
24
- postBuildRedirections,
25
- }) => {
26
- const resourceHintActions = []
27
- GRAPH.forEach(finalGraph, (urlInfo) => {
28
- if (urlInfo.type !== "html") {
29
- return
30
- }
31
- resourceHintActions.push(async () => {
32
- const htmlAst = parseHtmlString(urlInfo.content, {
33
- storeOriginalPositions: false,
34
- })
35
- const actions = []
36
- const visitLinkWithHref = (linkNode, href) => {
37
- if (!href || href.startsWith("data:")) {
38
- return
39
- }
40
- const rel = getHtmlNodeAttribute(linkNode, "rel")
41
- const isresourceHint = [
42
- "preconnect",
43
- "dns-prefetch",
44
- "prefetch",
45
- "preload",
46
- "modulepreload",
47
- ].includes(rel)
48
- if (!isresourceHint) {
49
- return
50
- }
51
-
52
- let buildUrl
53
- for (const key of Object.keys(rawUrls)) {
54
- if (rawUrls[key] === href) {
55
- buildUrl = key
56
- break
57
- }
58
- }
59
- if (!buildUrl) {
60
- logger.warn(`remove resource hint because cannot find "${href}"`)
61
- actions.push(() => {
62
- removeHtmlNode(linkNode)
63
- })
64
- return
65
- }
66
- buildUrl = postBuildRedirections[buildUrl] || buildUrl
67
- const urlInfo = finalGraph.getUrlInfo(buildUrl)
68
- if (!urlInfo) {
69
- logger.warn(
70
- `remove resource hint because cannot find "${buildUrl}" in the graph`,
71
- )
72
- actions.push(() => {
73
- removeHtmlNode(linkNode)
74
- })
75
- return
76
- }
77
- if (urlInfo.dependents.size === 0) {
78
- logger.info(`remove resource hint because "${href}" not used anymore`)
79
- actions.push(() => {
80
- removeHtmlNode(linkNode)
81
- })
82
- return
83
- }
84
- actions.push(() => {
85
- setHtmlNodeAttributes(linkNode, {
86
- href: urlInfo.data.buildUrlSpecifier,
87
- })
88
- })
89
- }
90
- visitHtmlNodes(htmlAst, {
91
- link: (node) => {
92
- const href = getHtmlNodeAttribute(node, "href")
93
- if (href !== undefined) {
94
- visitLinkWithHref(node, href)
95
- }
96
- },
97
- })
98
- if (actions.length) {
99
- actions.forEach((action) => action())
100
- await finalGraphKitchen.urlInfoTransformer.applyFinalTransformations(
101
- urlInfo,
102
- {
103
- content: stringifyHtmlAst(htmlAst),
104
- },
105
- )
106
- }
107
- })
108
- })
109
- await Promise.all(
110
- resourceHintActions.map((resourceHintAction) => resourceHintAction()),
111
- )
112
- }
@@ -1,74 +0,0 @@
1
- import { ensureEmptyDirectory } from "@jsenv/filesystem"
2
-
3
- export const loadUrlGraph = async ({
4
- operation,
5
- urlGraph,
6
- kitchen,
7
- startLoading,
8
- writeGeneratedFiles,
9
- outDirectoryUrl,
10
- }) => {
11
- if (writeGeneratedFiles && outDirectoryUrl) {
12
- await ensureEmptyDirectory(outDirectoryUrl)
13
- }
14
- const promises = []
15
- const promiseMap = new Map()
16
- const cook = (urlInfo, context) => {
17
- const promiseFromData = promiseMap.get(urlInfo)
18
- if (promiseFromData) return promiseFromData
19
- const promise = _cook(urlInfo, {
20
- outDirectoryUrl,
21
- ...context,
22
- })
23
- promises.push(promise)
24
- promiseMap.set(urlInfo, promise)
25
- return promise
26
- }
27
- const _cook = async (urlInfo, context) => {
28
- await kitchen.cook(urlInfo, {
29
- cookDuringCook: cook,
30
- ...context,
31
- })
32
- const { references } = urlInfo
33
- references.forEach((reference) => {
34
- // we don't cook resource hints
35
- // because they might refer to resource that will be modified during build
36
- // It also means something else have to reference that url in order to cook it
37
- // so that the preload is deleted by "resync_resource_hints.js" otherwise
38
- if (reference.isResourceHint) {
39
- return
40
- }
41
- // we use reference.generatedUrl to mimic what a browser would do:
42
- // do a fetch to the specifier as found in the file
43
- const referencedUrlInfo = urlGraph.reuseOrCreateUrlInfo(
44
- reference.generatedUrl,
45
- )
46
- cook(referencedUrlInfo, { reference })
47
- })
48
- }
49
- startLoading(
50
- ({ trace, parentUrl = kitchen.rootDirectoryUrl, type, specifier }) => {
51
- const [entryReference, entryUrlInfo] = kitchen.prepareEntryPoint({
52
- trace,
53
- parentUrl,
54
- type,
55
- specifier,
56
- })
57
- cook(entryUrlInfo, { reference: entryReference })
58
- return [entryReference, entryUrlInfo]
59
- },
60
- )
61
-
62
- const waitAll = async () => {
63
- operation.throwIfAborted()
64
- if (promises.length === 0) {
65
- return
66
- }
67
- const promisesToWait = promises.slice()
68
- promises.length = 0
69
- await Promise.all(promisesToWait)
70
- await waitAll()
71
- }
72
- await waitAll()
73
- promiseMap.clear()
74
- }