@jsenv/core 27.5.2 → 27.6.1
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/autoreload.js +7 -0
- package/dist/js/html_supervisor_installer.js +275 -154
- package/dist/main.js +171 -109
- package/package.json +2 -2
- package/src/dev/start_dev_server.js +4 -0
- package/src/omega/kitchen.js +13 -15
- package/src/omega/omega_server.js +4 -0
- package/src/omega/server/file_service.js +9 -66
- package/src/omega/url_graph/url_graph_load.js +0 -2
- package/src/omega/url_graph/url_info_transformations.js +27 -0
- package/src/omega/url_graph.js +1 -0
- package/src/plugins/autoreload/client/autoreload.js +7 -0
- package/src/plugins/html_supervisor/client/error_formatter.js +187 -67
- package/src/plugins/html_supervisor/client/error_overlay.js +29 -10
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +25 -73
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +94 -25
- package/src/test/execute_test_plan.js +1 -2
|
@@ -88,11 +88,15 @@ export const installHtmlSupervisor = ({
|
|
|
88
88
|
let completed
|
|
89
89
|
let result
|
|
90
90
|
let error
|
|
91
|
+
const urlObject = new URL(src, window.location)
|
|
92
|
+
if (reload) {
|
|
93
|
+
urlObject.searchParams.set("hmr", Date.now())
|
|
94
|
+
}
|
|
95
|
+
__html_supervisor__.currentExecution = {
|
|
96
|
+
type: type === "module" ? "dynamic_import" : "script_injection",
|
|
97
|
+
url: urlObject.href,
|
|
98
|
+
}
|
|
91
99
|
try {
|
|
92
|
-
const urlObject = new URL(src, window.location)
|
|
93
|
-
if (reload) {
|
|
94
|
-
urlObject.searchParams.set("hmr", Date.now())
|
|
95
|
-
}
|
|
96
100
|
result = await execute(urlObject.href)
|
|
97
101
|
completed = true
|
|
98
102
|
} catch (e) {
|
|
@@ -110,6 +114,7 @@ export const installHtmlSupervisor = ({
|
|
|
110
114
|
console.log(`${type} load ended`)
|
|
111
115
|
console.groupEnd()
|
|
112
116
|
}
|
|
117
|
+
__html_supervisor__.currentExecution = null
|
|
113
118
|
return
|
|
114
119
|
}
|
|
115
120
|
const executionResult = {
|
|
@@ -140,6 +145,7 @@ export const installHtmlSupervisor = ({
|
|
|
140
145
|
if (logs) {
|
|
141
146
|
console.groupEnd()
|
|
142
147
|
}
|
|
148
|
+
__html_supervisor__.currentExecution = null
|
|
143
149
|
}
|
|
144
150
|
|
|
145
151
|
const classicExecutionQueue = createExecutionQueue(performExecution)
|
|
@@ -220,82 +226,28 @@ export const installHtmlSupervisor = ({
|
|
|
220
226
|
})
|
|
221
227
|
|
|
222
228
|
if (errorOverlay) {
|
|
223
|
-
|
|
224
|
-
if (!errorEvent.isTrusted) {
|
|
225
|
-
// ignore custom error event (not sent by browser)
|
|
226
|
-
return
|
|
227
|
-
}
|
|
228
|
-
const { error } = errorEvent
|
|
229
|
+
const onErrorReportedByBrowser = (error, { url, line, column }) => {
|
|
229
230
|
displayErrorInDocument(error, {
|
|
230
231
|
rootDirectoryUrl,
|
|
231
232
|
errorBaseUrl,
|
|
232
233
|
openInEditor,
|
|
233
|
-
url
|
|
234
|
-
line
|
|
235
|
-
column
|
|
236
|
-
reportedBy: "browser",
|
|
234
|
+
url,
|
|
235
|
+
line,
|
|
236
|
+
column,
|
|
237
237
|
})
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
if (
|
|
245
|
-
document.readyState === "loading" ||
|
|
246
|
-
document.readyState === "interactive"
|
|
247
|
-
) {
|
|
248
|
-
return true
|
|
249
|
-
}
|
|
250
|
-
if (window.__reloader__ && window.__reloader__.status === "reloading") {
|
|
251
|
-
return true
|
|
252
|
-
}
|
|
253
|
-
return false
|
|
238
|
+
}
|
|
239
|
+
window.addEventListener("error", (errorEvent) => {
|
|
240
|
+
if (!errorEvent.isTrusted) {
|
|
241
|
+
// ignore custom error event (not sent by browser)
|
|
242
|
+
return
|
|
254
243
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
const {
|
|
262
|
-
message,
|
|
263
|
-
stack,
|
|
264
|
-
traceUrl,
|
|
265
|
-
traceLine,
|
|
266
|
-
traceColumn,
|
|
267
|
-
traceMessage,
|
|
268
|
-
requestedRessource,
|
|
269
|
-
isFaviconAutoRequest,
|
|
270
|
-
} = JSON.parse(serverErrorEvent.data)
|
|
271
|
-
if (isFaviconAutoRequest) {
|
|
272
|
-
return
|
|
273
|
-
}
|
|
274
|
-
// setTimeout is to ensure the error
|
|
275
|
-
// dispatched on window by browser is displayed first,
|
|
276
|
-
// then the server error replaces it (because it contains more information)
|
|
277
|
-
setTimeout(() => {
|
|
278
|
-
displayErrorInDocument(
|
|
279
|
-
{
|
|
280
|
-
message,
|
|
281
|
-
stack,
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
rootDirectoryUrl,
|
|
285
|
-
errorBaseUrl,
|
|
286
|
-
openInEditor,
|
|
287
|
-
url: traceUrl,
|
|
288
|
-
line: traceLine,
|
|
289
|
-
column: traceColumn,
|
|
290
|
-
codeFrame: traceMessage,
|
|
291
|
-
reportedBy: "server",
|
|
292
|
-
requestedRessource,
|
|
293
|
-
},
|
|
294
|
-
)
|
|
295
|
-
}, 10)
|
|
296
|
-
},
|
|
244
|
+
const { error, filename, lineno, colno } = errorEvent
|
|
245
|
+
onErrorReportedByBrowser(error, {
|
|
246
|
+
url: filename,
|
|
247
|
+
line: lineno,
|
|
248
|
+
column: colno,
|
|
297
249
|
})
|
|
298
|
-
}
|
|
250
|
+
})
|
|
299
251
|
}
|
|
300
252
|
}
|
|
301
253
|
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
setHtmlNodeText,
|
|
21
21
|
} from "@jsenv/ast"
|
|
22
22
|
import { generateInlineContentUrl, stringifyUrlSite } from "@jsenv/urls"
|
|
23
|
+
import { getOriginalPosition } from "@jsenv/sourcemap"
|
|
23
24
|
|
|
24
25
|
import { requireFromJsenv } from "@jsenv/core/src/require_from_jsenv.js"
|
|
25
26
|
|
|
@@ -46,44 +47,42 @@ export const jsenvPluginHtmlSupervisor = ({
|
|
|
46
47
|
dev: true,
|
|
47
48
|
test: true,
|
|
48
49
|
},
|
|
49
|
-
serve: (request, context) => {
|
|
50
|
-
if (request.ressource.startsWith("/__open_in_editor__/")) {
|
|
51
|
-
const file = request.ressource.slice("/__open_in_editor__/".length)
|
|
52
|
-
if (!file) {
|
|
53
|
-
return {
|
|
54
|
-
status: 400,
|
|
55
|
-
body: "Missing file in url",
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
const launch = requireFromJsenv("launch-editor")
|
|
59
|
-
launch(fileURLToPath(file), () => {
|
|
60
|
-
// ignore error for now
|
|
61
|
-
})
|
|
62
|
-
return {
|
|
63
|
-
status: 200,
|
|
64
|
-
headers: {
|
|
65
|
-
"cache-control": "no-store",
|
|
66
|
-
},
|
|
67
|
-
}
|
|
68
|
-
}
|
|
50
|
+
serve: async (request, context) => {
|
|
69
51
|
if (request.ressource.startsWith("/__get_code_frame__/")) {
|
|
70
|
-
const
|
|
71
|
-
const
|
|
52
|
+
const { pathname, searchParams } = new URL(request.url)
|
|
53
|
+
const urlWithLineAndColumn = pathname.slice(
|
|
54
|
+
"/__get_code_frame__/".length,
|
|
55
|
+
)
|
|
56
|
+
const match = urlWithLineAndColumn.match(/:([0-9]+):([0-9]+)$/)
|
|
72
57
|
if (!match) {
|
|
73
58
|
return {
|
|
74
59
|
status: 400,
|
|
75
60
|
body: "Missing line and column in url",
|
|
76
61
|
}
|
|
77
62
|
}
|
|
78
|
-
const file =
|
|
79
|
-
|
|
80
|
-
|
|
63
|
+
const file = urlWithLineAndColumn.slice(0, match.index)
|
|
64
|
+
let line = parseInt(match[1])
|
|
65
|
+
let column = parseInt(match[2])
|
|
81
66
|
const urlInfo = context.urlGraph.getUrlInfo(file)
|
|
82
67
|
if (!urlInfo) {
|
|
83
68
|
return {
|
|
84
69
|
status: 404,
|
|
85
70
|
}
|
|
86
71
|
}
|
|
72
|
+
const remap = searchParams.has("remap")
|
|
73
|
+
if (remap) {
|
|
74
|
+
const sourcemap = urlInfo.sourcemap
|
|
75
|
+
if (sourcemap) {
|
|
76
|
+
const original = await getOriginalPosition({
|
|
77
|
+
sourcemap,
|
|
78
|
+
url: file,
|
|
79
|
+
line,
|
|
80
|
+
column,
|
|
81
|
+
})
|
|
82
|
+
line = original.line
|
|
83
|
+
column = original.column
|
|
84
|
+
}
|
|
85
|
+
}
|
|
87
86
|
const codeFrame = stringifyUrlSite({
|
|
88
87
|
url: file,
|
|
89
88
|
line,
|
|
@@ -99,6 +98,76 @@ export const jsenvPluginHtmlSupervisor = ({
|
|
|
99
98
|
body: codeFrame,
|
|
100
99
|
}
|
|
101
100
|
}
|
|
101
|
+
if (request.ressource.startsWith("/__get_error_cause__/")) {
|
|
102
|
+
const file = request.ressource.slice("/__get_error_cause__/".length)
|
|
103
|
+
if (!file) {
|
|
104
|
+
return {
|
|
105
|
+
status: 400,
|
|
106
|
+
body: "Missing file in url",
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const getErrorCauseInfo = () => {
|
|
110
|
+
const urlInfo = context.urlGraph.getUrlInfo(file)
|
|
111
|
+
if (!urlInfo) {
|
|
112
|
+
return null
|
|
113
|
+
}
|
|
114
|
+
const { error } = urlInfo
|
|
115
|
+
if (error) {
|
|
116
|
+
return error
|
|
117
|
+
}
|
|
118
|
+
// search in direct dependencies (404 or 500)
|
|
119
|
+
const { dependencies } = urlInfo
|
|
120
|
+
for (const dependencyUrl of dependencies) {
|
|
121
|
+
const dependencyUrlInfo = context.urlGraph.getUrlInfo(dependencyUrl)
|
|
122
|
+
if (dependencyUrlInfo.error) {
|
|
123
|
+
return dependencyUrlInfo.error
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
const causeInfo = getErrorCauseInfo()
|
|
129
|
+
const body = JSON.stringify(
|
|
130
|
+
causeInfo
|
|
131
|
+
? {
|
|
132
|
+
code: causeInfo.code,
|
|
133
|
+
message: causeInfo.message,
|
|
134
|
+
reason: causeInfo.reason,
|
|
135
|
+
stack: causeInfo.stack,
|
|
136
|
+
codeFrame: causeInfo.traceMessage,
|
|
137
|
+
}
|
|
138
|
+
: null,
|
|
139
|
+
null,
|
|
140
|
+
" ",
|
|
141
|
+
)
|
|
142
|
+
return {
|
|
143
|
+
status: 200,
|
|
144
|
+
headers: {
|
|
145
|
+
"cache-control": "no-cache",
|
|
146
|
+
"content-type": "application/json",
|
|
147
|
+
"content-length": Buffer.byteLength(body),
|
|
148
|
+
},
|
|
149
|
+
body,
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (request.ressource.startsWith("/__open_in_editor__/")) {
|
|
153
|
+
const file = request.ressource.slice("/__open_in_editor__/".length)
|
|
154
|
+
if (!file) {
|
|
155
|
+
return {
|
|
156
|
+
status: 400,
|
|
157
|
+
body: "Missing file in url",
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const launch = requireFromJsenv("launch-editor")
|
|
161
|
+
launch(fileURLToPath(file), () => {
|
|
162
|
+
// ignore error for now
|
|
163
|
+
})
|
|
164
|
+
return {
|
|
165
|
+
status: 200,
|
|
166
|
+
headers: {
|
|
167
|
+
"cache-control": "no-store",
|
|
168
|
+
},
|
|
169
|
+
}
|
|
170
|
+
}
|
|
102
171
|
return null
|
|
103
172
|
},
|
|
104
173
|
transformUrlContent: {
|
|
@@ -60,8 +60,7 @@ export const executeTestPlan = async ({
|
|
|
60
60
|
cooldownBetweenExecutions = 0,
|
|
61
61
|
gcBetweenExecutions = logMemoryHeapUsage,
|
|
62
62
|
|
|
63
|
-
coverageEnabled = process.argv.includes("--
|
|
64
|
-
process.argv.includes("--coverage"),
|
|
63
|
+
coverageEnabled = process.argv.includes("--coverage"),
|
|
65
64
|
coverageConfig = {
|
|
66
65
|
"./src/": true,
|
|
67
66
|
},
|