@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.
- package/dist/js/script_type_module_supervisor.js +8 -13
- package/dist/js/supervisor.js +690 -504
- package/dist/main.js +13332 -13179
- package/package.json +5 -5
- package/readme.md +3 -3
- package/src/build/build.js +980 -713
- package/src/build/inject_global_version_mappings.js +5 -20
- package/src/build/start_build_server.js +2 -2
- package/src/dev/start_dev_server.js +6 -3
- package/src/omega/compat/runtime_compat.js +9 -6
- package/src/omega/errors.js +3 -0
- package/src/omega/fetched_content_compliance.js +2 -2
- package/src/omega/kitchen.js +191 -146
- package/src/omega/server/file_service.js +104 -71
- package/src/omega/url_graph/url_graph_loader.js +77 -0
- package/src/omega/url_graph/url_info_transformations.js +12 -15
- package/src/omega/url_graph.js +118 -101
- package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +1 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +34 -36
- package/src/plugins/autoreload/jsenv_plugin_hmr.js +3 -2
- package/src/plugins/bundling/js_module/{bundle_js_module.js → bundle_js_modules.js} +51 -14
- package/src/plugins/bundling/jsenv_plugin_bundling.js +2 -2
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +11 -0
- package/src/plugins/inline/jsenv_plugin_html_inline_content.js +73 -62
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +77 -89
- package/src/plugins/plugin_controller.js +26 -22
- package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +1 -0
- package/src/plugins/supervisor/client/script_type_module_supervisor.js +7 -9
- package/src/plugins/supervisor/client/supervisor.js +99 -52
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +2 -4
- package/src/plugins/transpilation/as_js_classic/async-to-promises.js +16 -0
- package/src/plugins/transpilation/as_js_classic/convert_js_module_to_js_classic.js +85 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +48 -190
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_conversion.js +104 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +161 -240
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_library.js +92 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +19 -12
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -24
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +82 -52
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +12 -13
- package/src/plugins/url_analysis/html/html_urls.js +91 -34
- package/src/plugins/url_analysis/js/js_urls.js +5 -4
- package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +1 -0
- package/src/test/execute_plan.js +3 -8
- package/src/build/inject_service_worker_urls.js +0 -78
- package/src/build/resync_resource_hints.js +0 -112
- package/src/omega/url_graph/url_graph_load.js +0 -74
package/src/test/execute_plan.js
CHANGED
|
@@ -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 =
|
|
213
|
-
const executionLogsEnabled =
|
|
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
|
-
}
|