@jsenv/core 27.5.3 → 27.6.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.
- package/dist/js/autoreload.js +7 -0
- package/dist/js/html_supervisor_installer.js +259 -162
- package/dist/main.js +142 -101
- 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 +174 -66
- package/src/plugins/html_supervisor/client/error_overlay.js +29 -31
- package/src/plugins/html_supervisor/client/error_site_remap.js +85 -0
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +21 -63
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +70 -19
package/dist/js/autoreload.js
CHANGED
|
@@ -158,6 +158,7 @@ const reloader = {
|
|
|
158
158
|
isAutoreloadEnabled,
|
|
159
159
|
setAutoreloadPreference,
|
|
160
160
|
status: "idle",
|
|
161
|
+
currentExecution: null,
|
|
161
162
|
onstatuschange: () => {},
|
|
162
163
|
setStatus: status => {
|
|
163
164
|
reloader.status = status;
|
|
@@ -195,6 +196,7 @@ const reloader = {
|
|
|
195
196
|
const setReloadMessagePromise = (reloadMessage, promise) => {
|
|
196
197
|
promise.then(() => {
|
|
197
198
|
onApplied(reloadMessage);
|
|
199
|
+
reloader.currentExecution = null;
|
|
198
200
|
}, e => {
|
|
199
201
|
reloader.setStatus("failed");
|
|
200
202
|
|
|
@@ -206,6 +208,7 @@ const reloader = {
|
|
|
206
208
|
|
|
207
209
|
console.error(`[jsenv] Hot reload failed after ${reloadMessage.reason}.
|
|
208
210
|
This could be due to syntax errors or importing non-existent modules (see errors in console)`);
|
|
211
|
+
reloader.currentExecution = null;
|
|
209
212
|
});
|
|
210
213
|
};
|
|
211
214
|
|
|
@@ -299,6 +302,10 @@ const applyHotReload = async ({
|
|
|
299
302
|
}
|
|
300
303
|
|
|
301
304
|
console.log(`importing js module`);
|
|
305
|
+
reloader.currentExecution = {
|
|
306
|
+
type: "dynamic_import",
|
|
307
|
+
url: urlToFetch
|
|
308
|
+
};
|
|
302
309
|
const namespace = await reloadJsImport(urlToFetch);
|
|
303
310
|
|
|
304
311
|
if (urlHotMeta.acceptCallback) {
|
|
@@ -16,40 +16,74 @@ const formatError = (error, {
|
|
|
16
16
|
openInEditor,
|
|
17
17
|
url,
|
|
18
18
|
line,
|
|
19
|
-
column
|
|
20
|
-
codeFrame,
|
|
21
|
-
requestedRessource,
|
|
22
|
-
reportedBy
|
|
19
|
+
column
|
|
23
20
|
}) => {
|
|
24
21
|
let {
|
|
25
22
|
message,
|
|
26
23
|
stack
|
|
27
24
|
} = normalizeErrorParts(error);
|
|
28
|
-
let
|
|
25
|
+
let errorDetailsPromiseReference = {
|
|
29
26
|
current: null
|
|
30
27
|
};
|
|
31
|
-
let tip =
|
|
32
|
-
reportedBy,
|
|
33
|
-
requestedRessource
|
|
34
|
-
});
|
|
28
|
+
let tip = `Reported by the browser while executing <code>${window.location.pathname}${window.location.search}</code>.`;
|
|
35
29
|
let errorUrlSite;
|
|
30
|
+
const errorMeta = extractErrorMeta(error, {
|
|
31
|
+
url,
|
|
32
|
+
line,
|
|
33
|
+
column
|
|
34
|
+
});
|
|
36
35
|
|
|
37
36
|
const resolveUrlSite = ({
|
|
38
37
|
url,
|
|
39
38
|
line,
|
|
40
39
|
column
|
|
41
40
|
}) => {
|
|
42
|
-
const inlineUrlMatch = url.match(/@L([0-9]+)\-L([0-9]+)\.[\w]
|
|
41
|
+
const inlineUrlMatch = url.match(/@L([0-9]+)C([0-9]+)\-L([0-9]+)C([0-9]+)(\.[\w]+)$/);
|
|
43
42
|
|
|
44
43
|
if (inlineUrlMatch) {
|
|
45
44
|
const htmlUrl = url.slice(0, inlineUrlMatch.index);
|
|
46
|
-
const
|
|
47
|
-
const
|
|
45
|
+
const tagLineStart = parseInt(inlineUrlMatch[1]);
|
|
46
|
+
const tagColumnStart = parseInt(inlineUrlMatch[2]);
|
|
47
|
+
const tagLineEnd = parseInt(inlineUrlMatch[3]);
|
|
48
|
+
const tagColumnEnd = parseInt(inlineUrlMatch[4]);
|
|
49
|
+
const extension = inlineUrlMatch[5];
|
|
48
50
|
url = htmlUrl;
|
|
49
|
-
line =
|
|
50
|
-
|
|
51
|
+
line = tagLineStart + (line === undefined ? 0 : parseInt(line)); // stackTrace formatted by V8 (chrome)
|
|
52
|
+
|
|
53
|
+
if (Error.captureStackTrace) {
|
|
54
|
+
line--;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (errorMeta.type === "dynamic_import_syntax_error") {
|
|
58
|
+
// syntax error on inline script need line-1 for some reason
|
|
59
|
+
if (Error.captureStackTrace) {
|
|
60
|
+
line--;
|
|
61
|
+
} else {
|
|
62
|
+
// firefox and safari need line-2
|
|
63
|
+
line -= 2;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
column = tagColumnStart + (column === undefined ? 0 : parseInt(column));
|
|
68
|
+
const fileUrl = resolveFileUrl(url);
|
|
69
|
+
return {
|
|
70
|
+
isInline: true,
|
|
71
|
+
originalUrl: `${fileUrl}@L${tagLineStart}C${tagColumnStart}-L${tagLineEnd}C${tagColumnEnd}${extension}`,
|
|
72
|
+
url: fileUrl,
|
|
73
|
+
line,
|
|
74
|
+
column
|
|
75
|
+
};
|
|
51
76
|
}
|
|
52
77
|
|
|
78
|
+
return {
|
|
79
|
+
isInline: false,
|
|
80
|
+
url: resolveFileUrl(url),
|
|
81
|
+
line,
|
|
82
|
+
column
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const resolveFileUrl = url => {
|
|
53
87
|
let urlObject = new URL(url);
|
|
54
88
|
|
|
55
89
|
if (urlObject.origin === window.origin) {
|
|
@@ -61,19 +95,11 @@ const formatError = (error, {
|
|
|
61
95
|
|
|
62
96
|
if (atFsIndex > -1) {
|
|
63
97
|
const afterAtFs = urlObject.pathname.slice(atFsIndex + "/@fs/".length);
|
|
64
|
-
|
|
65
|
-
} else {
|
|
66
|
-
url = urlObject.href;
|
|
98
|
+
return new URL(afterAtFs, "file:///").href;
|
|
67
99
|
}
|
|
68
|
-
} else {
|
|
69
|
-
url = urlObject.href;
|
|
70
100
|
}
|
|
71
101
|
|
|
72
|
-
return
|
|
73
|
-
url,
|
|
74
|
-
line,
|
|
75
|
-
column
|
|
76
|
-
};
|
|
102
|
+
return urlObject.href;
|
|
77
103
|
};
|
|
78
104
|
|
|
79
105
|
const generateClickableText = text => {
|
|
@@ -110,22 +136,68 @@ const formatError = (error, {
|
|
|
110
136
|
return textWithHtmlLinks;
|
|
111
137
|
};
|
|
112
138
|
|
|
113
|
-
const
|
|
114
|
-
|
|
139
|
+
const formatErrorText = ({
|
|
140
|
+
message,
|
|
141
|
+
stack,
|
|
142
|
+
codeFrame
|
|
143
|
+
}) => {
|
|
144
|
+
let text;
|
|
115
145
|
|
|
116
|
-
if (
|
|
117
|
-
|
|
146
|
+
if (message && stack) {
|
|
147
|
+
text = `${generateClickableText(message)}\n${generateClickableText(stack)}`;
|
|
148
|
+
} else if (stack) {
|
|
149
|
+
text = generateClickableText(stack);
|
|
150
|
+
} else {
|
|
151
|
+
text = generateClickableText(message);
|
|
118
152
|
}
|
|
119
153
|
|
|
120
|
-
if (
|
|
121
|
-
|
|
154
|
+
if (codeFrame) {
|
|
155
|
+
text += `\n\n${generateClickableText(codeFrame)}`;
|
|
122
156
|
}
|
|
123
157
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
158
|
+
return text;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const onErrorLocated = urlSite => {
|
|
162
|
+
errorUrlSite = urlSite;
|
|
163
|
+
|
|
164
|
+
errorDetailsPromiseReference.current = (async () => {
|
|
165
|
+
if (errorMeta.type === "dynamic_import_fetch_error") {
|
|
166
|
+
const response = await window.fetch(`/__get_error_cause__/${urlSite.isInline ? urlSite.originalUrl : urlSite.url}`);
|
|
167
|
+
|
|
168
|
+
if (response.status !== 200) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const causeInfo = await response.json();
|
|
173
|
+
|
|
174
|
+
if (!causeInfo) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const causeText = causeInfo.code === "NOT_FOUND" ? formatErrorText({
|
|
179
|
+
message: causeInfo.reason,
|
|
180
|
+
stack: causeInfo.codeFrame
|
|
181
|
+
}) : formatErrorText({
|
|
182
|
+
message: causeInfo.stack,
|
|
183
|
+
stack: causeInfo.codeFrame
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
cause: causeText
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (urlSite.line !== undefined) {
|
|
191
|
+
const response = await window.fetch(`/__get_code_frame__/${formatUrlWithLineAndColumn(urlSite)}`);
|
|
192
|
+
const codeFrame = await response.text();
|
|
193
|
+
return {
|
|
194
|
+
codeFrame: formatErrorText({
|
|
195
|
+
message: codeFrame
|
|
196
|
+
})
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return null;
|
|
129
201
|
})();
|
|
130
202
|
}; // error.stack is more reliable than url/line/column reported on window error events
|
|
131
203
|
// so use it only when error.stack is not available
|
|
@@ -138,33 +210,99 @@ const formatError = (error, {
|
|
|
138
210
|
line,
|
|
139
211
|
column
|
|
140
212
|
}));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
let text;
|
|
144
|
-
|
|
145
|
-
if (message && stack) {
|
|
146
|
-
text = `${generateClickableText(message)}\n${generateClickableText(stack)}`;
|
|
147
|
-
} else if (stack) {
|
|
148
|
-
text = generateClickableText(stack);
|
|
149
|
-
} else {
|
|
150
|
-
text = generateClickableText(message);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (codeFrame) {
|
|
154
|
-
text += `\n\n${generateClickableText(codeFrame)}`;
|
|
213
|
+
} else if (errorMeta.url) {
|
|
214
|
+
onErrorLocated(resolveUrlSite(errorMeta));
|
|
155
215
|
}
|
|
156
216
|
|
|
157
217
|
return {
|
|
158
218
|
theme: error && error.cause && error.cause.code === "PARSE_ERROR" ? "light" : "dark",
|
|
159
219
|
title: "An error occured",
|
|
160
|
-
text
|
|
161
|
-
|
|
220
|
+
text: formatErrorText({
|
|
221
|
+
message,
|
|
222
|
+
stack
|
|
223
|
+
}),
|
|
162
224
|
tip: `${tip}
|
|
163
225
|
<br />
|
|
164
|
-
Click outside to close
|
|
226
|
+
Click outside to close.`,
|
|
227
|
+
errorDetailsPromise: errorDetailsPromiseReference.current
|
|
165
228
|
};
|
|
166
229
|
};
|
|
167
230
|
|
|
231
|
+
const extractErrorMeta = (error, {
|
|
232
|
+
line
|
|
233
|
+
}) => {
|
|
234
|
+
if (!error) {
|
|
235
|
+
return {};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const {
|
|
239
|
+
message
|
|
240
|
+
} = error;
|
|
241
|
+
|
|
242
|
+
if (!message) {
|
|
243
|
+
return {};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
{
|
|
247
|
+
// chrome
|
|
248
|
+
if (message.includes("does not provide an export named")) {
|
|
249
|
+
return {
|
|
250
|
+
type: "dynamic_import_export_missing"
|
|
251
|
+
};
|
|
252
|
+
} // firefox
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
if (message.startsWith("import not found:")) {
|
|
256
|
+
return {
|
|
257
|
+
type: "dynamic_import_export_missing",
|
|
258
|
+
browser: "firefox"
|
|
259
|
+
};
|
|
260
|
+
} // safari
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
if (message.startsWith("import binding name")) {
|
|
264
|
+
return {
|
|
265
|
+
type: "dynamic_import_export_missing"
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
{
|
|
271
|
+
if (error.name === "SyntaxError" && typeof line === "number") {
|
|
272
|
+
return {
|
|
273
|
+
type: "dynamic_import_syntax_error"
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
{
|
|
279
|
+
// chrome
|
|
280
|
+
if (message.startsWith("Failed to fetch dynamically imported module: ")) {
|
|
281
|
+
const url = error.message.slice("Failed to fetch dynamically imported module: ".length);
|
|
282
|
+
return {
|
|
283
|
+
type: "dynamic_import_fetch_error",
|
|
284
|
+
url
|
|
285
|
+
};
|
|
286
|
+
} // firefox
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
if (message === "error loading dynamically imported module") {
|
|
290
|
+
return {
|
|
291
|
+
type: "dynamic_import_fetch_error"
|
|
292
|
+
};
|
|
293
|
+
} // safari
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
if (message === "Importing a module script failed.") {
|
|
297
|
+
return {
|
|
298
|
+
type: "dynamic_import_fetch_error"
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return {};
|
|
304
|
+
};
|
|
305
|
+
|
|
168
306
|
const formatUrlWithLineAndColumn = ({
|
|
169
307
|
url,
|
|
170
308
|
line,
|
|
@@ -251,17 +389,6 @@ const getErrorStackWithoutErrorMessage = error => {
|
|
|
251
389
|
return stack;
|
|
252
390
|
};
|
|
253
391
|
|
|
254
|
-
const formatTip = ({
|
|
255
|
-
reportedBy,
|
|
256
|
-
requestedRessource
|
|
257
|
-
}) => {
|
|
258
|
-
if (reportedBy === "browser") {
|
|
259
|
-
return `Reported by the browser while executing <code>${window.location.pathname}${window.location.search}</code>.`;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return `Reported by the server while serving <code>${requestedRessource}</code>`;
|
|
263
|
-
};
|
|
264
|
-
|
|
265
392
|
const makeLinksClickable = (string, {
|
|
266
393
|
createLink = url => url
|
|
267
394
|
}) => {
|
|
@@ -359,7 +486,6 @@ const link = ({
|
|
|
359
486
|
}) => `<a href="${href}">${text}</a>`;
|
|
360
487
|
|
|
361
488
|
const JSENV_ERROR_OVERLAY_TAGNAME = "jsenv-error-overlay";
|
|
362
|
-
let previousErrorInfo = null;
|
|
363
489
|
const displayErrorInDocument = (error, {
|
|
364
490
|
rootDirectoryUrl,
|
|
365
491
|
errorBaseUrl,
|
|
@@ -367,32 +493,14 @@ const displayErrorInDocument = (error, {
|
|
|
367
493
|
url,
|
|
368
494
|
line,
|
|
369
495
|
column,
|
|
370
|
-
codeFrame
|
|
371
|
-
reportedBy,
|
|
372
|
-
requestedRessource
|
|
496
|
+
codeFrame
|
|
373
497
|
}) => {
|
|
374
|
-
const nowMs = Date.now(); // ensure error dispatched on window by browser is displayed first
|
|
375
|
-
// then the server error replaces it (because it contains more information)
|
|
376
|
-
|
|
377
|
-
if (previousErrorInfo) {
|
|
378
|
-
const previousErrorReportedBy = previousErrorInfo.reportedBy;
|
|
379
|
-
const msEllapsedSincePreviousError = nowMs - previousErrorInfo.ms;
|
|
380
|
-
|
|
381
|
-
if (previousErrorReportedBy === "server" && reportedBy === "browser" && msEllapsedSincePreviousError < 50) {
|
|
382
|
-
return () => {};
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
previousErrorInfo = {
|
|
387
|
-
ms: nowMs,
|
|
388
|
-
reportedBy
|
|
389
|
-
};
|
|
390
498
|
const {
|
|
391
499
|
theme,
|
|
392
500
|
title,
|
|
393
501
|
text,
|
|
394
|
-
|
|
395
|
-
|
|
502
|
+
tip,
|
|
503
|
+
errorDetailsPromise
|
|
396
504
|
} = formatError(error, {
|
|
397
505
|
rootDirectoryUrl,
|
|
398
506
|
errorBaseUrl,
|
|
@@ -400,16 +508,14 @@ const displayErrorInDocument = (error, {
|
|
|
400
508
|
url,
|
|
401
509
|
line,
|
|
402
510
|
column,
|
|
403
|
-
codeFrame
|
|
404
|
-
reportedBy,
|
|
405
|
-
requestedRessource
|
|
511
|
+
codeFrame
|
|
406
512
|
});
|
|
407
513
|
let jsenvErrorOverlay = new JsenvErrorOverlay({
|
|
408
514
|
theme,
|
|
409
515
|
title,
|
|
410
516
|
text,
|
|
411
|
-
|
|
412
|
-
|
|
517
|
+
tip,
|
|
518
|
+
errorDetailsPromise
|
|
413
519
|
});
|
|
414
520
|
document.querySelectorAll(JSENV_ERROR_OVERLAY_TAGNAME).forEach(node => {
|
|
415
521
|
node.parentNode.removeChild(node);
|
|
@@ -439,8 +545,8 @@ class JsenvErrorOverlay extends HTMLElement {
|
|
|
439
545
|
theme,
|
|
440
546
|
title,
|
|
441
547
|
text,
|
|
442
|
-
|
|
443
|
-
|
|
548
|
+
tip,
|
|
549
|
+
errorDetailsPromise
|
|
444
550
|
}) {
|
|
445
551
|
super();
|
|
446
552
|
this.root = this.attachShadow({
|
|
@@ -471,17 +577,46 @@ class JsenvErrorOverlay extends HTMLElement {
|
|
|
471
577
|
this.parentNode.removeChild(this);
|
|
472
578
|
};
|
|
473
579
|
|
|
474
|
-
if (
|
|
475
|
-
|
|
476
|
-
if (this.parentNode) {
|
|
580
|
+
if (errorDetailsPromise) {
|
|
581
|
+
errorDetailsPromise.then(errorDetails => {
|
|
582
|
+
if (!errorDetails || !this.parentNode) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const {
|
|
587
|
+
codeFrame,
|
|
588
|
+
cause
|
|
589
|
+
} = errorDetails;
|
|
590
|
+
|
|
591
|
+
if (codeFrame) {
|
|
477
592
|
this.root.querySelector(".text").innerHTML += `\n\n${codeFrame}`;
|
|
478
593
|
}
|
|
594
|
+
|
|
595
|
+
if (cause) {
|
|
596
|
+
const causeIndented = prefixRemainingLines(cause, " ");
|
|
597
|
+
this.root.querySelector(".text").innerHTML += `\n [cause]: ${causeIndented}`;
|
|
598
|
+
}
|
|
479
599
|
});
|
|
480
600
|
}
|
|
481
601
|
}
|
|
482
602
|
|
|
483
603
|
}
|
|
484
604
|
|
|
605
|
+
const prefixRemainingLines = (text, prefix) => {
|
|
606
|
+
const lines = text.split(/\r?\n/);
|
|
607
|
+
const firstLine = lines.shift();
|
|
608
|
+
let result = firstLine;
|
|
609
|
+
let i = 0;
|
|
610
|
+
|
|
611
|
+
while (i < lines.length) {
|
|
612
|
+
const line = lines[i];
|
|
613
|
+
i++;
|
|
614
|
+
result += line.length ? `\n${prefix}${line}` : `\n`;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
return result;
|
|
618
|
+
};
|
|
619
|
+
|
|
485
620
|
if (customElements && !customElements.get(JSENV_ERROR_OVERLAY_TAGNAME)) {
|
|
486
621
|
customElements.define(JSENV_ERROR_OVERLAY_TAGNAME, JsenvErrorOverlay);
|
|
487
622
|
}
|
|
@@ -683,14 +818,18 @@ const installHtmlSupervisor = ({
|
|
|
683
818
|
let completed;
|
|
684
819
|
let result;
|
|
685
820
|
let error;
|
|
821
|
+
const urlObject = new URL(src, window.location);
|
|
686
822
|
|
|
687
|
-
|
|
688
|
-
|
|
823
|
+
if (reload) {
|
|
824
|
+
urlObject.searchParams.set("hmr", Date.now());
|
|
825
|
+
}
|
|
689
826
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
827
|
+
__html_supervisor__.currentExecution = {
|
|
828
|
+
type: type === "module" ? "dynamic_import" : "script_injection",
|
|
829
|
+
url: urlObject.href
|
|
830
|
+
};
|
|
693
831
|
|
|
832
|
+
try {
|
|
694
833
|
result = await execute(urlObject.href);
|
|
695
834
|
completed = true;
|
|
696
835
|
} catch (e) {
|
|
@@ -711,6 +850,7 @@ const installHtmlSupervisor = ({
|
|
|
711
850
|
console.groupEnd();
|
|
712
851
|
}
|
|
713
852
|
|
|
853
|
+
__html_supervisor__.currentExecution = null;
|
|
714
854
|
return;
|
|
715
855
|
}
|
|
716
856
|
|
|
@@ -738,6 +878,8 @@ const installHtmlSupervisor = ({
|
|
|
738
878
|
if (logs) {
|
|
739
879
|
console.groupEnd();
|
|
740
880
|
}
|
|
881
|
+
|
|
882
|
+
__html_supervisor__.currentExecution = null;
|
|
741
883
|
};
|
|
742
884
|
|
|
743
885
|
const classicExecutionQueue = createExecutionQueue(performExecution);
|
|
@@ -826,6 +968,21 @@ const installHtmlSupervisor = ({
|
|
|
826
968
|
});
|
|
827
969
|
|
|
828
970
|
if (errorOverlay) {
|
|
971
|
+
const onErrorReportedByBrowser = (error, {
|
|
972
|
+
url,
|
|
973
|
+
line,
|
|
974
|
+
column
|
|
975
|
+
}) => {
|
|
976
|
+
displayErrorInDocument(error, {
|
|
977
|
+
rootDirectoryUrl,
|
|
978
|
+
errorBaseUrl,
|
|
979
|
+
openInEditor,
|
|
980
|
+
url,
|
|
981
|
+
line,
|
|
982
|
+
column
|
|
983
|
+
});
|
|
984
|
+
};
|
|
985
|
+
|
|
829
986
|
window.addEventListener("error", errorEvent => {
|
|
830
987
|
if (!errorEvent.isTrusted) {
|
|
831
988
|
// ignore custom error event (not sent by browser)
|
|
@@ -838,72 +995,12 @@ const installHtmlSupervisor = ({
|
|
|
838
995
|
lineno,
|
|
839
996
|
colno
|
|
840
997
|
} = errorEvent;
|
|
841
|
-
|
|
842
|
-
rootDirectoryUrl,
|
|
843
|
-
errorBaseUrl,
|
|
844
|
-
openInEditor,
|
|
998
|
+
onErrorReportedByBrowser(error, {
|
|
845
999
|
url: filename,
|
|
846
1000
|
line: lineno,
|
|
847
|
-
column: colno
|
|
848
|
-
reportedBy: "browser"
|
|
1001
|
+
column: colno
|
|
849
1002
|
});
|
|
850
1003
|
});
|
|
851
|
-
|
|
852
|
-
if (window.__server_events__) {
|
|
853
|
-
const isExecuting = () => {
|
|
854
|
-
if (pendingExecutionCount > 0) {
|
|
855
|
-
return true;
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if (document.readyState === "loading" || document.readyState === "interactive") {
|
|
859
|
-
return true;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
if (window.__reloader__ && window.__reloader__.status === "reloading") {
|
|
863
|
-
return true;
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
return false;
|
|
867
|
-
};
|
|
868
|
-
|
|
869
|
-
window.__server_events__.addEventCallbacks({
|
|
870
|
-
error_while_serving_file: serverErrorEvent => {
|
|
871
|
-
if (!isExecuting()) {
|
|
872
|
-
return;
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
const {
|
|
876
|
-
message,
|
|
877
|
-
stack,
|
|
878
|
-
traceUrl,
|
|
879
|
-
traceLine,
|
|
880
|
-
traceColumn,
|
|
881
|
-
traceMessage,
|
|
882
|
-
requestedRessource,
|
|
883
|
-
isFaviconAutoRequest
|
|
884
|
-
} = JSON.parse(serverErrorEvent.data);
|
|
885
|
-
|
|
886
|
-
if (isFaviconAutoRequest) {
|
|
887
|
-
return;
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
displayErrorInDocument({
|
|
891
|
-
message,
|
|
892
|
-
stack
|
|
893
|
-
}, {
|
|
894
|
-
rootDirectoryUrl,
|
|
895
|
-
errorBaseUrl,
|
|
896
|
-
openInEditor,
|
|
897
|
-
url: traceUrl,
|
|
898
|
-
line: traceLine,
|
|
899
|
-
column: traceColumn,
|
|
900
|
-
codeFrame: traceMessage,
|
|
901
|
-
reportedBy: "server",
|
|
902
|
-
requestedRessource
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
|
-
});
|
|
906
|
-
}
|
|
907
1004
|
}
|
|
908
1005
|
};
|
|
909
1006
|
|