@jsenv/core 27.0.0-alpha.81 → 27.0.0-alpha.84
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/babel_helpers/applyDecs/applyDecs.js +756 -0
- package/dist/babel_helpers/construct/construct.js +1 -1
- package/dist/babel_helpers/extends/extends.js +1 -1
- package/dist/babel_helpers/get/get.js +1 -1
- package/dist/babel_helpers/getPrototypeOf/getPrototypeOf.js +1 -1
- package/dist/babel_helpers/identity/identity.js +3 -0
- package/dist/babel_helpers/setPrototypeOf/setPrototypeOf.js +2 -2
- package/dist/js/event_source_client.js +206 -2
- package/dist/main.js +934 -90
- package/dist/s.js.map +2 -1
- package/package.json +9 -9
- package/src/build/build.js +5 -5
- package/src/build/build_urls_generator.js +1 -2
- package/src/build/inject_global_version_mappings.js +2 -2
- package/src/build/inject_service_worker_urls.js +2 -2
- package/src/build/resync_ressource_hints.js +1 -1
- package/src/build/start_build_server.js +33 -26
- package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +1 -2
- package/src/dev/plugins/toolbar/client/util/fetching.js +1 -1
- package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +1 -1
- package/src/dev/start_dev_server.js +38 -30
- package/src/execute/runtimes/browsers/from_playwright.js +5 -4
- package/src/execute/runtimes/node/node_process.js +2 -2
- package/src/helpers/command/command.js +73 -0
- package/src/helpers/event_source/event_source.js +197 -0
- package/src/helpers/event_source/sse_service.js +53 -0
- package/src/helpers/worker_reload.js +57 -0
- package/src/omega/compat/runtime_compat.js +2 -1
- package/src/omega/kitchen.js +2 -1
- package/src/omega/server/user_agent.js +2 -1
- package/src/omega/url_graph/sort_by_dependencies.js +27 -0
- package/src/omega/url_graph/url_info_transformations.js +24 -14
- package/src/plugins/autoreload/dev_sse/client/event_source_client.js +1 -1
- package/src/plugins/autoreload/dev_sse/client/reload.js +1 -1
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +1 -1
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +1 -1
- package/src/plugins/bundling/css/bundle_css.js +5 -4
- package/src/plugins/bundling/js_module/bundle_js_module.js +2 -2
- package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +2 -2
- package/src/plugins/file_urls/jsenv_plugin_file_urls.js +1 -2
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +1 -1
- package/src/plugins/import_meta_hot/html_hot_dependencies.js +2 -2
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +4 -3
- package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +2 -2
- package/src/plugins/importmap/jsenv_plugin_importmap.js +2 -3
- package/src/plugins/inject_globals/inject_globals.js +2 -2
- package/src/plugins/inline/jsenv_plugin_data_urls.js +1 -1
- package/src/plugins/inline/jsenv_plugin_html_inline_content.js +3 -3
- package/src/plugins/inline/jsenv_plugin_js_inline_content.js +4 -4
- package/src/plugins/minification/css/minify_css.js +1 -1
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +2 -4
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +5 -5
- package/src/plugins/transpilation/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +1 -1
- package/src/plugins/transpilation/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +2 -3
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +1 -1
- package/src/plugins/transpilation/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +1 -2
- package/src/plugins/transpilation/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +1 -2
- package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +1 -1
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +1 -1
- package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +2 -1
- package/src/plugins/url_analysis/css/css_urls.js +3 -3
- package/src/plugins/url_analysis/html/html_urls.js +2 -2
- package/src/plugins/url_analysis/js/js_urls.js +3 -2
- package/src/test/coverage/babel_plugin_instrument.js +82 -0
- package/src/test/coverage/coverage_reporter_html_directory.js +36 -0
- package/src/test/coverage/coverage_reporter_json_file.js +22 -0
- package/src/test/coverage/coverage_reporter_text_log.js +19 -0
- package/src/test/coverage/empty_coverage_factory.js +52 -0
- package/src/test/coverage/file_by_file_coverage.js +25 -0
- package/src/test/coverage/istanbul_coverage_composition.js +28 -0
- package/src/test/coverage/istanbul_coverage_map_from_coverage.js +16 -0
- package/src/test/coverage/list_files_not_covered.js +15 -0
- package/src/test/coverage/missing_coverage.js +41 -0
- package/src/test/coverage/report_to_coverage.js +196 -0
- package/src/test/coverage/v8_and_istanbul.js +37 -0
- package/src/test/coverage/v8_coverage_composition.js +24 -0
- package/src/test/coverage/v8_coverage_from_directory.js +87 -0
- package/src/test/coverage/v8_coverage_to_istanbul.js +99 -0
- package/src/test/execute_plan.js +2 -2
- package/src/test/execute_test_plan.js +3 -3
- package/dist/babel_helpers/readme.md +0 -8
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { exec } from "node:child_process"
|
|
2
|
+
import { createDetailedMessage, createLogger, UNICODE } from "@jsenv/log"
|
|
3
|
+
|
|
4
|
+
export const executeCommand = (
|
|
5
|
+
command,
|
|
6
|
+
{
|
|
7
|
+
logLevel = "info",
|
|
8
|
+
signal = new AbortController().signal,
|
|
9
|
+
onStdout = () => {},
|
|
10
|
+
onStderr = () => {},
|
|
11
|
+
cwd,
|
|
12
|
+
env,
|
|
13
|
+
timeout,
|
|
14
|
+
} = {},
|
|
15
|
+
) => {
|
|
16
|
+
const logger = createLogger({ logLevel })
|
|
17
|
+
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
logger.debug(`${UNICODE.COMMAND} ${command}`)
|
|
20
|
+
const commandProcess = exec(command, {
|
|
21
|
+
signal,
|
|
22
|
+
cwd:
|
|
23
|
+
cwd && typeof cwd === "string" && cwd.startsWith("file:")
|
|
24
|
+
? new URL(cwd)
|
|
25
|
+
: cwd,
|
|
26
|
+
env,
|
|
27
|
+
timeout,
|
|
28
|
+
silent: true,
|
|
29
|
+
})
|
|
30
|
+
commandProcess.on("error", (error) => {
|
|
31
|
+
if (error && error.code === "ETIMEDOUT") {
|
|
32
|
+
logger.error(`timeout after ${timeout} ms`)
|
|
33
|
+
reject(error)
|
|
34
|
+
} else {
|
|
35
|
+
reject(error)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
const stdoutDatas = []
|
|
39
|
+
commandProcess.stdout.on("data", (data) => {
|
|
40
|
+
stdoutDatas.push(data)
|
|
41
|
+
logger.debug(data)
|
|
42
|
+
onStderr(data)
|
|
43
|
+
})
|
|
44
|
+
let stderrDatas = []
|
|
45
|
+
commandProcess.stderr.on("data", (data) => {
|
|
46
|
+
stderrDatas.push(data)
|
|
47
|
+
logger.debug(data)
|
|
48
|
+
onStdout(data)
|
|
49
|
+
})
|
|
50
|
+
if (commandProcess.stdin) {
|
|
51
|
+
commandProcess.stdin.on("error", (error) => {
|
|
52
|
+
reject(error)
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
commandProcess.on("exit", (exitCode, signal) => {
|
|
56
|
+
if (signal) {
|
|
57
|
+
reject(new Error(`killed with ${signal}`))
|
|
58
|
+
}
|
|
59
|
+
if (exitCode) {
|
|
60
|
+
reject(
|
|
61
|
+
new Error(
|
|
62
|
+
createDetailedMessage(`failed with exit code ${exitCode}`, {
|
|
63
|
+
"command stderr": stderrDatas.join(""),
|
|
64
|
+
// "command stdout": stdoutDatas.join(""),
|
|
65
|
+
}),
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
resolve({ exitCode, signal })
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/* eslint-env browser */
|
|
2
|
+
|
|
3
|
+
export const createEventSourceConnection = (
|
|
4
|
+
eventSourceUrl,
|
|
5
|
+
events = {},
|
|
6
|
+
{ retryMaxAttempt = Infinity, retryAllocatedMs = Infinity, lastEventId } = {},
|
|
7
|
+
) => {
|
|
8
|
+
const { EventSource } = window
|
|
9
|
+
if (typeof EventSource !== "function") {
|
|
10
|
+
return () => {}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const eventSourceOrigin = new URL(eventSourceUrl).origin
|
|
14
|
+
Object.keys(events).forEach((eventName) => {
|
|
15
|
+
const eventCallback = events[eventName]
|
|
16
|
+
events[eventName] = (e) => {
|
|
17
|
+
if (e.origin === eventSourceOrigin) {
|
|
18
|
+
if (e.lastEventId) {
|
|
19
|
+
lastEventId = e.lastEventId
|
|
20
|
+
}
|
|
21
|
+
eventCallback(e)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const status = {
|
|
27
|
+
value: "default",
|
|
28
|
+
goTo: (value) => {
|
|
29
|
+
if (value === status.value) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
status.value = value
|
|
33
|
+
status.onchange()
|
|
34
|
+
},
|
|
35
|
+
onchange: () => {},
|
|
36
|
+
}
|
|
37
|
+
let _disconnect = () => {}
|
|
38
|
+
|
|
39
|
+
const attemptConnection = (url) => {
|
|
40
|
+
const eventSource = new EventSource(url, {
|
|
41
|
+
withCredentials: true,
|
|
42
|
+
})
|
|
43
|
+
_disconnect = () => {
|
|
44
|
+
if (status.value !== "connecting" && status.value !== "connected") {
|
|
45
|
+
console.warn(
|
|
46
|
+
`disconnect() ignored because connection is ${status.value}`,
|
|
47
|
+
)
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
eventSource.onerror = undefined
|
|
51
|
+
eventSource.close()
|
|
52
|
+
Object.keys(events).forEach((eventName) => {
|
|
53
|
+
eventSource.removeEventListener(eventName, events[eventName])
|
|
54
|
+
})
|
|
55
|
+
status.goTo("disconnected")
|
|
56
|
+
}
|
|
57
|
+
let retryCount = 0
|
|
58
|
+
let firstRetryMs = Date.now()
|
|
59
|
+
eventSource.onerror = (errorEvent) => {
|
|
60
|
+
if (errorEvent.target.readyState === EventSource.CONNECTING) {
|
|
61
|
+
if (retryCount > retryMaxAttempt) {
|
|
62
|
+
console.info(`could not connect after ${retryMaxAttempt} attempt`)
|
|
63
|
+
_disconnect()
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (retryCount === 0) {
|
|
68
|
+
firstRetryMs = Date.now()
|
|
69
|
+
} else {
|
|
70
|
+
const allRetryDuration = Date.now() - firstRetryMs
|
|
71
|
+
if (retryAllocatedMs && allRetryDuration > retryAllocatedMs) {
|
|
72
|
+
console.info(
|
|
73
|
+
`could not connect in less than ${retryAllocatedMs} ms`,
|
|
74
|
+
)
|
|
75
|
+
_disconnect()
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
retryCount++
|
|
81
|
+
status.goTo("connecting")
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (errorEvent.target.readyState === EventSource.CLOSED) {
|
|
86
|
+
_disconnect()
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
eventSource.onopen = () => {
|
|
91
|
+
status.goTo("connected")
|
|
92
|
+
}
|
|
93
|
+
Object.keys(events).forEach((eventName) => {
|
|
94
|
+
eventSource.addEventListener(eventName, events[eventName])
|
|
95
|
+
})
|
|
96
|
+
if (!events.hasOwnProperty("welcome")) {
|
|
97
|
+
eventSource.addEventListener("welcome", (e) => {
|
|
98
|
+
if (e.origin === eventSourceOrigin && e.lastEventId) {
|
|
99
|
+
lastEventId = e.lastEventId
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
status.goTo("connecting")
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let connect = () => {
|
|
107
|
+
attemptConnection(eventSourceUrl)
|
|
108
|
+
connect = () => {
|
|
109
|
+
attemptConnection(
|
|
110
|
+
lastEventId
|
|
111
|
+
? addLastEventIdIntoUrlSearchParams(eventSourceUrl, lastEventId)
|
|
112
|
+
: eventSourceUrl,
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const removePageUnloadListener = listenPageUnload(() => {
|
|
118
|
+
if (status.value === "connecting" || status.value === "connected") {
|
|
119
|
+
_disconnect()
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
const destroy = () => {
|
|
124
|
+
removePageUnloadListener()
|
|
125
|
+
_disconnect()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
status,
|
|
130
|
+
connect,
|
|
131
|
+
disconnect: () => _disconnect(),
|
|
132
|
+
destroy,
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const addLastEventIdIntoUrlSearchParams = (url, lastEventId) => {
|
|
137
|
+
if (url.indexOf("?") === -1) {
|
|
138
|
+
url += "?"
|
|
139
|
+
} else {
|
|
140
|
+
url += "&"
|
|
141
|
+
}
|
|
142
|
+
return `${url}last-event-id=${encodeURIComponent(lastEventId)}`
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// const listenPageMightFreeze = (callback) => {
|
|
146
|
+
// const removePageHideListener = listenEvent(window, "pagehide", (pageHideEvent) => {
|
|
147
|
+
// if (pageHideEvent.persisted === true) {
|
|
148
|
+
// callback(pageHideEvent)
|
|
149
|
+
// }
|
|
150
|
+
// })
|
|
151
|
+
// return removePageHideListener
|
|
152
|
+
// }
|
|
153
|
+
|
|
154
|
+
// const listenPageFreeze = (callback) => {
|
|
155
|
+
// const removeFreezeListener = listenEvent(document, "freeze", (freezeEvent) => {
|
|
156
|
+
// callback(freezeEvent)
|
|
157
|
+
// })
|
|
158
|
+
// return removeFreezeListener
|
|
159
|
+
// }
|
|
160
|
+
|
|
161
|
+
// const listenPageIsRestored = (callback) => {
|
|
162
|
+
// const removeResumeListener = listenEvent(document, "resume", (resumeEvent) => {
|
|
163
|
+
// removePageshowListener()
|
|
164
|
+
// callback(resumeEvent)
|
|
165
|
+
// })
|
|
166
|
+
// const removePageshowListener = listenEvent(window, "pageshow", (pageshowEvent) => {
|
|
167
|
+
// if (pageshowEvent.persisted === true) {
|
|
168
|
+
// removePageshowListener()
|
|
169
|
+
// removeResumeListener()
|
|
170
|
+
// callback(pageshowEvent)
|
|
171
|
+
// }
|
|
172
|
+
// })
|
|
173
|
+
// return () => {
|
|
174
|
+
// removeResumeListener()
|
|
175
|
+
// removePageshowListener()
|
|
176
|
+
// }
|
|
177
|
+
// }
|
|
178
|
+
|
|
179
|
+
const listenPageUnload = (callback) => {
|
|
180
|
+
const removePageHideListener = listenEvent(
|
|
181
|
+
window,
|
|
182
|
+
"pagehide",
|
|
183
|
+
(pageHideEvent) => {
|
|
184
|
+
if (pageHideEvent.persisted !== true) {
|
|
185
|
+
callback(pageHideEvent)
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
)
|
|
189
|
+
return removePageHideListener
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const listenEvent = (emitter, event, callback) => {
|
|
193
|
+
emitter.addEventListener(event, callback)
|
|
194
|
+
return () => {
|
|
195
|
+
emitter.removeEventListener(event, callback)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { createSSERoom } from "@jsenv/server"
|
|
2
|
+
import { createCallbackListNotifiedOnce } from "@jsenv/abort"
|
|
3
|
+
|
|
4
|
+
export const createSSEService = ({ serverEventCallbackList }) => {
|
|
5
|
+
const destroyCallbackList = createCallbackListNotifiedOnce()
|
|
6
|
+
|
|
7
|
+
const cache = []
|
|
8
|
+
const sseRoomLimit = 100
|
|
9
|
+
const getOrCreateSSERoom = (request) => {
|
|
10
|
+
const htmlFileRelativeUrl = request.ressource.slice(1)
|
|
11
|
+
const cacheEntry = cache.find(
|
|
12
|
+
(cacheEntryCandidate) =>
|
|
13
|
+
cacheEntryCandidate.htmlFileRelativeUrl === htmlFileRelativeUrl,
|
|
14
|
+
)
|
|
15
|
+
if (cacheEntry) {
|
|
16
|
+
return cacheEntry.sseRoom
|
|
17
|
+
}
|
|
18
|
+
const sseRoom = createSSERoom({
|
|
19
|
+
retryDuration: 2000,
|
|
20
|
+
historyLength: 100,
|
|
21
|
+
welcomeEventEnabled: true,
|
|
22
|
+
effect: () => {
|
|
23
|
+
return serverEventCallbackList.add((event) => {
|
|
24
|
+
sseRoom.sendEvent(event)
|
|
25
|
+
})
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
const removeSSECleanupCallback = destroyCallbackList.add(() => {
|
|
29
|
+
removeSSECleanupCallback()
|
|
30
|
+
sseRoom.close()
|
|
31
|
+
})
|
|
32
|
+
cache.push({
|
|
33
|
+
htmlFileRelativeUrl,
|
|
34
|
+
sseRoom,
|
|
35
|
+
cleanup: () => {
|
|
36
|
+
removeSSECleanupCallback()
|
|
37
|
+
sseRoom.close()
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
if (cache.length >= sseRoomLimit) {
|
|
41
|
+
const firstCacheEntry = cache.shift()
|
|
42
|
+
firstCacheEntry.cleanup()
|
|
43
|
+
}
|
|
44
|
+
return sseRoom
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
getOrCreateSSERoom,
|
|
49
|
+
destroy: () => {
|
|
50
|
+
destroyCallbackList.notify()
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url"
|
|
2
|
+
import { Worker, workerData } from "node:worker_threads"
|
|
3
|
+
|
|
4
|
+
// https://nodejs.org/api/worker_threads.html
|
|
5
|
+
export const createReloadableWorker = (workerFileUrl, options = {}) => {
|
|
6
|
+
const workerFilePath = fileURLToPath(workerFileUrl)
|
|
7
|
+
const isPrimary = !workerData || workerData.workerFilePath !== workerFilePath
|
|
8
|
+
let worker
|
|
9
|
+
|
|
10
|
+
const terminate = async () => {
|
|
11
|
+
if (worker) {
|
|
12
|
+
let _worker = worker
|
|
13
|
+
worker = null
|
|
14
|
+
const exitPromise = new Promise((resolve) => {
|
|
15
|
+
_worker.once("exit", resolve)
|
|
16
|
+
})
|
|
17
|
+
_worker.terminate()
|
|
18
|
+
await exitPromise
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const load = async () => {
|
|
23
|
+
if (!isPrimary) {
|
|
24
|
+
throw new Error(`worker can be loaded from primary file only`)
|
|
25
|
+
}
|
|
26
|
+
worker = new Worker(workerFilePath, {
|
|
27
|
+
...options,
|
|
28
|
+
workerData: {
|
|
29
|
+
...options.workerData,
|
|
30
|
+
workerFilePath,
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
worker.once("error", (error) => {
|
|
35
|
+
console.error(error)
|
|
36
|
+
})
|
|
37
|
+
await new Promise((resolve) => {
|
|
38
|
+
worker.once("online", resolve)
|
|
39
|
+
})
|
|
40
|
+
worker.once("exit", () => {
|
|
41
|
+
worker = null
|
|
42
|
+
})
|
|
43
|
+
return worker
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const reload = async () => {
|
|
47
|
+
await terminate()
|
|
48
|
+
await load()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
isPrimary,
|
|
53
|
+
load,
|
|
54
|
+
reload,
|
|
55
|
+
terminate,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { findHighestVersion } from "@jsenv/utils/semantic_versioning/highest_version.js"
|
|
1
|
+
import { findHighestVersion } from "@jsenv/utils/src/semantic_versioning/highest_version.js"
|
|
2
|
+
|
|
2
3
|
import { featureCompats } from "./features_compats.js"
|
|
3
4
|
|
|
4
5
|
export const RUNTIME_COMPAT = {
|
package/src/omega/kitchen.js
CHANGED
|
@@ -8,7 +8,8 @@ import {
|
|
|
8
8
|
} from "@jsenv/urls"
|
|
9
9
|
import { writeFileSync, ensureWindowsDriveLetter } from "@jsenv/filesystem"
|
|
10
10
|
import { createDetailedMessage } from "@jsenv/log"
|
|
11
|
-
import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
|
|
11
|
+
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
|
|
12
|
+
|
|
12
13
|
import { createPluginController } from "../plugins/plugin_controller.js"
|
|
13
14
|
import { urlSpecifierEncoding } from "./url_specifier_encoding.js"
|
|
14
15
|
import { createUrlInfoTransformer } from "./url_graph/url_info_transformations.js"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { memoizeByFirstArgument } from "@jsenv/utils/memoize/memoize_by_first_argument.js"
|
|
1
|
+
import { memoizeByFirstArgument } from "@jsenv/utils/src/memoize/memoize_by_first_argument.js"
|
|
2
|
+
|
|
2
3
|
import { requireFromJsenv } from "@jsenv/core/src/require_from_jsenv.js"
|
|
3
4
|
|
|
4
5
|
export const parseUserAgentHeader = memoizeByFirstArgument((userAgent) => {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const sortByDependencies = (nodes) => {
|
|
2
|
+
const visited = []
|
|
3
|
+
const sorted = []
|
|
4
|
+
const circular = []
|
|
5
|
+
const visit = (url) => {
|
|
6
|
+
const isSorted = sorted.includes(url)
|
|
7
|
+
if (isSorted) {
|
|
8
|
+
return
|
|
9
|
+
}
|
|
10
|
+
const isVisited = visited.includes(url)
|
|
11
|
+
if (isVisited) {
|
|
12
|
+
circular.push(url)
|
|
13
|
+
sorted.push(url)
|
|
14
|
+
} else {
|
|
15
|
+
visited.push(url)
|
|
16
|
+
nodes[url].dependencies.forEach((dependencyUrl) => {
|
|
17
|
+
visit(dependencyUrl, url)
|
|
18
|
+
})
|
|
19
|
+
sorted.push(url)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
Object.keys(nodes).forEach((url) => {
|
|
23
|
+
visit(url)
|
|
24
|
+
})
|
|
25
|
+
sorted.circular = circular
|
|
26
|
+
return sorted
|
|
27
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url"
|
|
1
2
|
import { bufferToEtag } from "@jsenv/filesystem"
|
|
2
|
-
import { urlToRelativeUrl } from "@jsenv/urls"
|
|
3
|
-
|
|
4
|
-
import { composeTwoSourcemaps } from "@jsenv/utils/sourcemap/sourcemap_composition_v3.js"
|
|
3
|
+
import { urlToRelativeUrl, isFileSystemPath } from "@jsenv/urls"
|
|
5
4
|
import {
|
|
5
|
+
composeTwoSourcemaps,
|
|
6
6
|
SOURCEMAP,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} from "@jsenv/
|
|
7
|
+
generateSourcemapFileUrl,
|
|
8
|
+
generateSourcemapDataUrl,
|
|
9
|
+
} from "@jsenv/sourcemap"
|
|
10
10
|
|
|
11
11
|
export const createUrlInfoTransformer = ({
|
|
12
12
|
logger,
|
|
@@ -23,18 +23,25 @@ export const createUrlInfoTransformer = ({
|
|
|
23
23
|
sourcemaps === "programmatic"
|
|
24
24
|
|
|
25
25
|
const normalizeSourcemap = (urlInfo, sourcemap) => {
|
|
26
|
+
let { sources } = sourcemap
|
|
27
|
+
if (sources) {
|
|
28
|
+
sources = sources.map((source) => {
|
|
29
|
+
if (source && isFileSystemPath(source)) {
|
|
30
|
+
return String(pathToFileURL(source))
|
|
31
|
+
}
|
|
32
|
+
return source
|
|
33
|
+
})
|
|
34
|
+
}
|
|
26
35
|
const wantSourcesContent =
|
|
27
36
|
// for inline content (<script> insdide html)
|
|
28
37
|
// chrome won't be able to fetch the file as it does not exists
|
|
29
38
|
// so sourcemap must contain sources
|
|
30
39
|
sourcemapsSourcesContent ||
|
|
31
40
|
urlInfo.isInline ||
|
|
32
|
-
(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (sourcemap.sources && sourcemap.sources.length > 1) {
|
|
37
|
-
sourcemap.sources = sourcemap.sources.map(
|
|
41
|
+
(sources &&
|
|
42
|
+
sources.some((source) => !source || !source.startsWith("file:")))
|
|
43
|
+
if (sources && sources.length > 1) {
|
|
44
|
+
sourcemap.sources = sources.map(
|
|
38
45
|
(source) => new URL(source, urlInfo.originalUrl).href,
|
|
39
46
|
)
|
|
40
47
|
if (!wantSourcesContent) {
|
|
@@ -65,7 +72,9 @@ export const createUrlInfoTransformer = ({
|
|
|
65
72
|
// when jsenv is done cooking the file
|
|
66
73
|
// during build it's urlInfo.url to be inside the build
|
|
67
74
|
// but otherwise it's generatedUrl to be inside .jsenv/ directory
|
|
68
|
-
urlInfo.sourcemapGeneratedUrl =
|
|
75
|
+
urlInfo.sourcemapGeneratedUrl = generateSourcemapFileUrl(
|
|
76
|
+
urlInfo.generatedUrl,
|
|
77
|
+
)
|
|
69
78
|
const [sourcemapReference, sourcemapUrlInfo] = injectSourcemapPlaceholder({
|
|
70
79
|
urlInfo,
|
|
71
80
|
specifier: urlInfo.sourcemapGeneratedUrl,
|
|
@@ -154,7 +163,8 @@ export const createUrlInfoTransformer = ({
|
|
|
154
163
|
}
|
|
155
164
|
sourcemapUrlInfo.content = JSON.stringify(sourcemap, null, " ")
|
|
156
165
|
if (sourcemaps === "inline") {
|
|
157
|
-
sourcemapReference.generatedSpecifier =
|
|
166
|
+
sourcemapReference.generatedSpecifier =
|
|
167
|
+
generateSourcemapDataUrl(sourcemap)
|
|
158
168
|
}
|
|
159
169
|
if (sourcemaps === "file" || sourcemaps === "inline") {
|
|
160
170
|
urlInfo.content = SOURCEMAP.writeComment({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createEventSourceConnection } from "@jsenv/
|
|
1
|
+
import { createEventSourceConnection } from "@jsenv/core/src/helpers/event_source/event_source.js"
|
|
2
2
|
import { urlHotMetas } from "../../../import_meta_hot/client/import_meta_hot.js"
|
|
3
3
|
import {
|
|
4
4
|
isAutoreloadEnabled,
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
stringifyHtmlAst,
|
|
4
4
|
injectScriptAsEarlyAsPossible,
|
|
5
5
|
createHtmlNode,
|
|
6
|
-
} from "@jsenv/utils/html_ast/html_ast.js"
|
|
6
|
+
} from "@jsenv/utils/src/html_ast/html_ast.js"
|
|
7
7
|
|
|
8
8
|
export const jsenvPluginDevSSEClient = () => {
|
|
9
9
|
const eventSourceClientFileUrl = new URL(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { urlToRelativeUrl } from "@jsenv/urls"
|
|
2
2
|
import { createCallbackList } from "@jsenv/abort"
|
|
3
3
|
|
|
4
|
-
import { createSSEService } from "@jsenv/
|
|
4
|
+
import { createSSEService } from "@jsenv/core/src/helpers/event_source/sse_service.js"
|
|
5
5
|
|
|
6
6
|
export const jsenvPluginDevSSEServer = ({
|
|
7
7
|
rootDirectoryUrl,
|
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
* It can be quite challenging, see "bundle_sourcemap.js"
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
|
|
9
|
+
import { createMagicSource } from "@jsenv/sourcemap"
|
|
10
|
+
import { applyPostCss } from "@jsenv/utils/src/css_ast/apply_post_css.js"
|
|
11
|
+
import { postCssPluginUrlVisitor } from "@jsenv/utils/src/css_ast/postcss_plugin_url_visitor.js"
|
|
12
|
+
|
|
13
|
+
import { sortByDependencies } from "@jsenv/core/src/omega/url_graph/sort_by_dependencies.js"
|
|
13
14
|
|
|
14
15
|
// Do not use until https://github.com/parcel-bundler/parcel-css/issues/181
|
|
15
16
|
export const bundleCss = async ({ cssUrlInfos, context }) => {
|
|
@@ -4,8 +4,8 @@ import { URL_META } from "@jsenv/url-meta"
|
|
|
4
4
|
import { isFileSystemPath } from "@jsenv/urls"
|
|
5
5
|
import { createDetailedMessage } from "@jsenv/log"
|
|
6
6
|
import { babelHelperNameFromUrl } from "@jsenv/babel-plugins"
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { sourcemapConverter } from "@jsenv/sourcemap"
|
|
8
|
+
import { applyRollupPlugins } from "@jsenv/utils/src/js_ast/apply_rollup_plugins.js"
|
|
9
9
|
import { fileUrlConverter } from "@jsenv/core/src/omega/file_url_converter.js"
|
|
10
10
|
|
|
11
11
|
const globalThisClientFileUrl = new URL(
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* - global
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { createMagicSource } from "@jsenv/sourcemap"
|
|
11
|
+
import { applyBabelPlugins } from "@jsenv/utils/src/js_ast/apply_babel_plugins.js"
|
|
12
12
|
|
|
13
13
|
export const jsenvPluginCommonJsGlobals = () => {
|
|
14
14
|
const transformCommonJsGlobals = async (urlInfo, { scenario }) => {
|
|
@@ -6,12 +6,11 @@ import {
|
|
|
6
6
|
urlToFilename,
|
|
7
7
|
ensurePathnameTrailingSlash,
|
|
8
8
|
} from "@jsenv/urls"
|
|
9
|
-
|
|
10
9
|
import {
|
|
11
10
|
applyFileSystemMagicResolution,
|
|
12
11
|
getExtensionsToTry,
|
|
13
12
|
} from "@jsenv/node-esm-resolution"
|
|
14
|
-
import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
|
|
13
|
+
import { CONTENT_TYPE } from "@jsenv/utils/src/content_type/content_type.js"
|
|
15
14
|
|
|
16
15
|
export const jsenvPluginFileUrls = ({
|
|
17
16
|
magicExtensions = ["inherit", ".js"],
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
getHtmlNodeTextNode,
|
|
18
18
|
removeHtmlNodeText,
|
|
19
19
|
setHtmlNodeGeneratedText,
|
|
20
|
-
} from "@jsenv/utils/html_ast/html_ast.js"
|
|
20
|
+
} from "@jsenv/utils/src/html_ast/html_ast.js"
|
|
21
21
|
import { generateInlineContentUrl } from "@jsenv/urls"
|
|
22
22
|
|
|
23
23
|
export const jsenvPluginHtmlSupervisor = ({
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getHtmlNodeAttributeByName,
|
|
3
3
|
parseLinkNode,
|
|
4
|
-
} from "@jsenv/utils/html_ast/html_ast.js"
|
|
5
|
-
import { htmlAttributeSrcSet } from "@jsenv/utils/html_ast/html_attribute_src_set.js"
|
|
4
|
+
} from "@jsenv/utils/src/html_ast/html_ast.js"
|
|
5
|
+
import { htmlAttributeSrcSet } from "@jsenv/utils/src/html_ast/html_attribute_src_set.js"
|
|
6
6
|
|
|
7
7
|
// Some "smart" default applied to decide what should hot reload / fullreload:
|
|
8
8
|
// By default:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { createMagicSource } from "@jsenv/
|
|
2
|
-
import { parseHtmlString } from "@jsenv/utils/html_ast/html_ast.js"
|
|
3
|
-
import { applyBabelPlugins } from "@jsenv/utils/js_ast/apply_babel_plugins.js"
|
|
1
|
+
import { createMagicSource } from "@jsenv/sourcemap"
|
|
2
|
+
import { parseHtmlString } from "@jsenv/utils/src/html_ast/html_ast.js"
|
|
3
|
+
import { applyBabelPlugins } from "@jsenv/utils/src/js_ast/apply_babel_plugins.js"
|
|
4
|
+
|
|
4
5
|
import { collectHotDataFromHtmlAst } from "./html_hot_dependencies.js"
|
|
5
6
|
import { babelPluginMetadataImportMetaHot } from "./babel_plugin_metadata_import_meta_hot.js"
|
|
6
7
|
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { createMagicSource } from "@jsenv/sourcemap"
|
|
13
|
+
import { applyBabelPlugins } from "@jsenv/utils/src/js_ast/apply_babel_plugins.js"
|
|
14
14
|
|
|
15
15
|
export const jsenvPluginImportMetaScenarios = () => {
|
|
16
16
|
return {
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
composeTwoImportMaps,
|
|
23
23
|
normalizeImportMap,
|
|
24
24
|
} from "@jsenv/importmap"
|
|
25
|
-
|
|
25
|
+
import { generateInlineContentUrl } from "@jsenv/urls"
|
|
26
26
|
import {
|
|
27
27
|
parseHtmlString,
|
|
28
28
|
stringifyHtmlAst,
|
|
@@ -33,8 +33,7 @@ import {
|
|
|
33
33
|
setHtmlNodeGeneratedText,
|
|
34
34
|
getHtmlNodeTextNode,
|
|
35
35
|
removeHtmlNode,
|
|
36
|
-
} from "@jsenv/utils/html_ast/html_ast.js"
|
|
37
|
-
import { generateInlineContentUrl } from "@jsenv/urls"
|
|
36
|
+
} from "@jsenv/utils/src/html_ast/html_ast.js"
|
|
38
37
|
|
|
39
38
|
export const jsenvPluginImportmap = () => {
|
|
40
39
|
let finalImportmap = null
|