@jsenv/core 27.3.4 → 27.5.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 +359 -0
- package/dist/js/execute_using_dynamic_import.js +1 -1
- package/dist/js/html_supervisor_installer.js +524 -147
- package/dist/js/html_supervisor_setup.js +3 -4
- package/dist/js/new_stylesheet.js +26 -58
- package/dist/js/server_events_client.js +307 -0
- package/dist/main.js +7709 -7324
- package/package.json +15 -15
- package/{README.md → readme.md} +18 -7
- package/src/build/build.js +16 -18
- package/src/build/start_build_server.js +24 -28
- package/src/dev/start_dev_server.js +34 -96
- package/src/execute/execute.js +17 -35
- package/src/omega/errors.js +43 -9
- package/src/omega/kitchen.js +42 -25
- package/src/omega/omega_server.js +96 -74
- package/src/omega/server/file_service.js +256 -28
- package/src/omega/url_graph.js +33 -20
- package/src/plugins/autoreload/client/autoreload.js +201 -0
- package/src/plugins/autoreload/{dev_sse/client → client}/autoreload_preference.js +0 -0
- package/src/plugins/autoreload/{dev_sse/client → client}/reload.js +29 -10
- package/src/plugins/autoreload/{dev_sse/client → client}/url_helpers.js +0 -0
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +4 -8
- package/src/plugins/autoreload/{dev_sse/jsenv_plugin_dev_sse_client.js → jsenv_plugin_autoreload_client.js} +8 -8
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +196 -0
- package/src/{dev/plugins → plugins}/explorer/client/explorer.html +0 -0
- package/src/{dev/plugins → plugins}/explorer/client/jsenv.png +0 -0
- package/src/{dev/plugins → plugins}/explorer/jsenv_plugin_explorer.js +1 -3
- package/src/plugins/html_supervisor/client/error_overlay.js +401 -0
- package/src/plugins/html_supervisor/client/html_supervisor_installer.js +138 -23
- package/src/plugins/html_supervisor/client/html_supervisor_setup.js +3 -4
- package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +55 -23
- package/src/plugins/inline/jsenv_plugin_html_inline_content.js +97 -117
- package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +66 -58
- package/src/plugins/plugin_controller.js +102 -67
- package/src/plugins/plugins.js +10 -10
- package/src/{helpers/event_source/event_source.js → plugins/server_events/client/event_source_connection.js} +125 -33
- package/src/plugins/server_events/client/server_events_client.js +17 -0
- package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +48 -0
- package/src/plugins/server_events/server_events_dispatcher.js +69 -0
- package/src/{dev/plugins → plugins}/toolbar/client/animation/toolbar_animation.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/eventsource/eventsource.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/eventsource/toolbar_eventsource.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/execution/execution.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/execution/toolbar_execution.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/focus/focus.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/focus/toolbar_focus.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/jsenv_logo.svg +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/notification/toolbar_notification.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/responsive/overflow_menu.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/responsive/toolbar_responsive.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/settings/settings.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/settings/toolbar_settings.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/theme/jsenv_theme.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/theme/light_theme.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/theme/toolbar_theme.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/toolbar.html +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/toolbar_injector.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/toolbar_main.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/toolbar_main.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/tooltip/tooltip.css +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/tooltip/tooltip.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/animation.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/dom.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/fetch_using_xhr.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/fetching.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/iframe_to_parent_href.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/jsenv_logger.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/preferences.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/responsive.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/util/util.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/client/variant/variant.js +0 -0
- package/src/{dev/plugins → plugins}/toolbar/jsenv_plugin_toolbar.js +0 -0
- package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +4 -3
- package/src/plugins/transpilation/babel/new_stylesheet/client/new_stylesheet.js +25 -55
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +44 -24
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +6 -1
- package/src/plugins/url_analysis/html/html_urls.js +8 -8
- package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +3 -1
- package/src/test/execute_plan.js +36 -54
- package/src/test/execute_test_plan.js +2 -2
- package/src/test/logs_file_execution.js +60 -27
- package/src/test/logs_file_execution.test.mjs +41 -0
- package/dist/js/event_source_client.js +0 -528
- package/src/helpers/event_source/sse_service.js +0 -53
- package/src/plugins/autoreload/dev_sse/client/event_source_client.js +0 -193
- package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +0 -203
- package/src/plugins/html_supervisor/client/error_in_document.js +0 -198
|
@@ -10,109 +10,411 @@ const unevalException = value => {
|
|
|
10
10
|
});
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
13
|
+
const JSENV_ERROR_OVERLAY_TAGNAME = "jsenv-error-overlay";
|
|
14
|
+
const displayErrorInDocument = (error, {
|
|
15
|
+
rootDirectoryUrl,
|
|
16
|
+
openInEditor,
|
|
17
|
+
url,
|
|
18
|
+
line,
|
|
19
|
+
column,
|
|
20
|
+
reportedBy,
|
|
21
|
+
requestedRessource
|
|
22
|
+
}) => {
|
|
23
|
+
document.querySelectorAll(JSENV_ERROR_OVERLAY_TAGNAME).forEach(node => {
|
|
24
|
+
node.parentNode.removeChild(node);
|
|
25
|
+
});
|
|
26
|
+
const {
|
|
27
|
+
theme,
|
|
28
|
+
title,
|
|
29
|
+
message,
|
|
30
|
+
stack,
|
|
31
|
+
tip
|
|
32
|
+
} = errorToHTML(error, {
|
|
33
|
+
url,
|
|
34
|
+
line,
|
|
35
|
+
column,
|
|
36
|
+
reportedBy,
|
|
37
|
+
requestedRessource
|
|
38
|
+
});
|
|
39
|
+
let jsenvErrorOverlay = new JsenvErrorOverlay({
|
|
40
|
+
theme,
|
|
41
|
+
title,
|
|
42
|
+
text: createErrorText({
|
|
43
|
+
rootDirectoryUrl,
|
|
44
|
+
openInEditor,
|
|
45
|
+
message,
|
|
46
|
+
stack
|
|
47
|
+
}),
|
|
48
|
+
tip
|
|
49
|
+
});
|
|
50
|
+
document.body.appendChild(jsenvErrorOverlay);
|
|
32
51
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
52
|
+
const removeErrorOverlay = () => {
|
|
53
|
+
if (jsenvErrorOverlay && jsenvErrorOverlay.parentNode) {
|
|
54
|
+
document.body.removeChild(jsenvErrorOverlay);
|
|
55
|
+
jsenvErrorOverlay = null;
|
|
37
56
|
}
|
|
57
|
+
};
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
if (window.__reloader__) {
|
|
60
|
+
window.__reloader__.onstatuschange = () => {
|
|
61
|
+
if (window.__reloader__.status === "reloading") {
|
|
62
|
+
removeErrorOverlay();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
42
66
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
max-width: 70em;
|
|
46
|
-
/* avoid scrollbar to hide the text behind it */
|
|
47
|
-
padding: 20px;
|
|
48
|
-
}
|
|
67
|
+
return removeErrorOverlay;
|
|
68
|
+
};
|
|
49
69
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
const createErrorText = ({
|
|
71
|
+
rootDirectoryUrl,
|
|
72
|
+
openInEditor,
|
|
73
|
+
message,
|
|
74
|
+
stack
|
|
75
|
+
}) => {
|
|
76
|
+
if (message && stack) {
|
|
77
|
+
return `${replaceLinks(message, {
|
|
78
|
+
rootDirectoryUrl,
|
|
79
|
+
openInEditor
|
|
80
|
+
})}\n${replaceLinks(stack, {
|
|
81
|
+
rootDirectoryUrl,
|
|
82
|
+
openInEditor
|
|
83
|
+
})}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (stack) {
|
|
87
|
+
return replaceLinks(stack, {
|
|
88
|
+
rootDirectoryUrl,
|
|
89
|
+
openInEditor
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return replaceLinks(message, {
|
|
94
|
+
rootDirectoryUrl,
|
|
95
|
+
openInEditor
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
class JsenvErrorOverlay extends HTMLElement {
|
|
100
|
+
constructor({
|
|
101
|
+
theme,
|
|
102
|
+
title,
|
|
103
|
+
text,
|
|
104
|
+
tip
|
|
105
|
+
}) {
|
|
106
|
+
super();
|
|
107
|
+
this.root = this.attachShadow({
|
|
108
|
+
mode: "open"
|
|
109
|
+
});
|
|
110
|
+
this.root.innerHTML = overlayHtml;
|
|
111
|
+
|
|
112
|
+
this.root.querySelector(".backdrop").onclick = () => {
|
|
113
|
+
if (!this.parentNode) {
|
|
114
|
+
// not in document anymore
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.root.querySelector(".backdrop").onclick = null;
|
|
119
|
+
this.parentNode.removeChild(this);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
this.root.querySelector(".overlay").setAttribute("data-theme", theme);
|
|
123
|
+
this.root.querySelector(".title").innerHTML = title;
|
|
124
|
+
this.root.querySelector(".text").innerHTML = text;
|
|
125
|
+
this.root.querySelector(".tip").innerHTML = tip;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (customElements && !customElements.get(JSENV_ERROR_OVERLAY_TAGNAME)) {
|
|
131
|
+
customElements.define(JSENV_ERROR_OVERLAY_TAGNAME, JsenvErrorOverlay);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const overlayHtml = `
|
|
135
|
+
<style>
|
|
136
|
+
:host {
|
|
137
|
+
position: fixed;
|
|
138
|
+
z-index: 99999;
|
|
139
|
+
top: 0;
|
|
140
|
+
left: 0;
|
|
141
|
+
width: 100%;
|
|
142
|
+
height: 100%;
|
|
143
|
+
overflow-y: scroll;
|
|
144
|
+
margin: 0;
|
|
145
|
+
background: rgba(0, 0, 0, 0.66);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.backdrop {
|
|
149
|
+
position: absolute;
|
|
150
|
+
left: 0;
|
|
151
|
+
right: 0;
|
|
152
|
+
top: 0;
|
|
153
|
+
bottom: 0;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.overlay {
|
|
157
|
+
position: relative;
|
|
158
|
+
background: rgba(0, 0, 0, 0.95);
|
|
159
|
+
width: 800px;
|
|
160
|
+
margin: 30px auto;
|
|
161
|
+
padding: 25px 40px;
|
|
162
|
+
padding-top: 0;
|
|
163
|
+
overflow: hidden; /* for h1 margins */
|
|
164
|
+
border-radius: 4px 8px;
|
|
165
|
+
box-shadow: 0 20px 40px rgb(0 0 0 / 30%), 0 15px 12px rgb(0 0 0 / 20%);
|
|
166
|
+
box-sizing: border-box;
|
|
167
|
+
font-family: monospace;
|
|
168
|
+
direction: ltr;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
h1 {
|
|
172
|
+
color: red;
|
|
173
|
+
text-align: center;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
pre {
|
|
177
|
+
overflow: auto;
|
|
178
|
+
max-width: 100%;
|
|
179
|
+
/* padding is nice + prevents scrollbar from hiding the text behind it */
|
|
180
|
+
/* does not work nicely on firefox though https://bugzilla.mozilla.org/show_bug.cgi?id=748518 */
|
|
181
|
+
padding: 20px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.tip {
|
|
185
|
+
border-top: 1px solid #999;
|
|
186
|
+
padding-top: 12px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
[data-theme="dark"] {
|
|
190
|
+
color: #999;
|
|
191
|
+
}
|
|
192
|
+
[data-theme="dark"] pre {
|
|
193
|
+
background: #111;
|
|
194
|
+
border: 1px solid #333;
|
|
195
|
+
color: #eee;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
[data-theme="light"] {
|
|
199
|
+
color: #EEEEEE;
|
|
200
|
+
}
|
|
201
|
+
[data-theme="light"] pre {
|
|
202
|
+
background: #1E1E1E;
|
|
203
|
+
border: 1px solid white;
|
|
204
|
+
color: #EEEEEE;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
pre a {
|
|
208
|
+
color: inherit;
|
|
209
|
+
}
|
|
210
|
+
</style>
|
|
211
|
+
<div class="backdrop"></div>
|
|
212
|
+
<div class="overlay">
|
|
213
|
+
<h1 class="title"></h1>
|
|
214
|
+
<pre class="text"></pre>
|
|
215
|
+
<div class="tip"></div>
|
|
216
|
+
</div>
|
|
217
|
+
`;
|
|
218
|
+
|
|
219
|
+
const parseErrorInfo = error => {
|
|
220
|
+
if (error === undefined) {
|
|
221
|
+
return {
|
|
222
|
+
message: "undefined"
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (error === null) {
|
|
227
|
+
return {
|
|
228
|
+
message: "null"
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (typeof error === "string") {
|
|
233
|
+
return {
|
|
234
|
+
message: error
|
|
235
|
+
};
|
|
236
|
+
}
|
|
55
237
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
238
|
+
if (error instanceof Error) {
|
|
239
|
+
if (error.name === "SyntaxError") {
|
|
240
|
+
return {
|
|
241
|
+
message: error.message
|
|
242
|
+
};
|
|
60
243
|
}
|
|
61
244
|
|
|
62
|
-
.
|
|
63
|
-
|
|
245
|
+
if (error.cause && error.cause.code === "PARSE_ERROR") {
|
|
246
|
+
if (error.messageHTML) {
|
|
247
|
+
return {
|
|
248
|
+
message: error.messageHTML
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
message: error.message
|
|
254
|
+
};
|
|
255
|
+
} // stackTrace formatted by V8
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
if (Error.captureStackTrace) {
|
|
259
|
+
return {
|
|
260
|
+
message: error.message,
|
|
261
|
+
stack: getErrorStackWithoutErrorMessage(error)
|
|
262
|
+
};
|
|
64
263
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
message: error.message,
|
|
267
|
+
stack: error.stack ? ` ${error.stack}` : null
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (typeof error === "object") {
|
|
272
|
+
return error;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
message: JSON.stringify(error)
|
|
77
277
|
};
|
|
78
278
|
};
|
|
79
279
|
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
}
|
|
280
|
+
const getErrorStackWithoutErrorMessage = error => {
|
|
281
|
+
let stack = error.stack;
|
|
282
|
+
const messageInStack = `${error.name}: ${error.message}`;
|
|
83
283
|
|
|
84
|
-
|
|
85
|
-
|
|
284
|
+
if (stack.startsWith(messageInStack)) {
|
|
285
|
+
stack = stack.slice(messageInStack.length);
|
|
286
|
+
}
|
|
86
287
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
288
|
+
const nextLineIndex = stack.indexOf("\n");
|
|
289
|
+
|
|
290
|
+
if (nextLineIndex > -1) {
|
|
291
|
+
stack = stack.slice(nextLineIndex + 1);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return stack;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const errorToHTML = (error, {
|
|
298
|
+
url,
|
|
299
|
+
line,
|
|
300
|
+
column,
|
|
301
|
+
reportedBy,
|
|
302
|
+
requestedRessource
|
|
303
|
+
}) => {
|
|
304
|
+
let {
|
|
305
|
+
message,
|
|
306
|
+
stack
|
|
307
|
+
} = parseErrorInfo(error);
|
|
308
|
+
|
|
309
|
+
if (url) {
|
|
310
|
+
if (!stack || error && error.name === "SyntaxError") {
|
|
311
|
+
stack = ` at ${appendLineAndColumn(url, {
|
|
312
|
+
line,
|
|
313
|
+
column
|
|
314
|
+
})}`;
|
|
97
315
|
}
|
|
98
|
-
} else if (typeof error === "string") {
|
|
99
|
-
html = error;
|
|
100
|
-
} else if (error === undefined) {
|
|
101
|
-
html = "undefined";
|
|
102
|
-
} else {
|
|
103
|
-
html = JSON.stringify(error);
|
|
104
316
|
}
|
|
105
317
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
318
|
+
let tip = formatTip({
|
|
319
|
+
reportedBy,
|
|
320
|
+
requestedRessource
|
|
321
|
+
});
|
|
322
|
+
return {
|
|
323
|
+
theme: error && error.cause && error.cause.code === "PARSE_ERROR" ? "light" : "dark",
|
|
324
|
+
title: "An error occured",
|
|
325
|
+
message,
|
|
326
|
+
stack,
|
|
327
|
+
tip: `${tip}
|
|
328
|
+
<br />
|
|
329
|
+
Click outside to close.`
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const formatTip = ({
|
|
334
|
+
reportedBy,
|
|
335
|
+
requestedRessource
|
|
336
|
+
}) => {
|
|
337
|
+
if (reportedBy === "browser") {
|
|
338
|
+
return `Reported by the browser while executing <code>${window.location.pathname}${window.location.search}</code>.`;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return `Reported by the server while serving <code>${requestedRessource}</code>`;
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
const replaceLinks = (string, {
|
|
345
|
+
rootDirectoryUrl,
|
|
346
|
+
openInEditor
|
|
347
|
+
}) => {
|
|
348
|
+
// normalize line breaks
|
|
349
|
+
string = string.replace(/\n/g, "\n");
|
|
350
|
+
string = escapeHtml(string); // render links
|
|
351
|
+
|
|
352
|
+
string = stringToStringWithLink(string, {
|
|
353
|
+
transform: (url, {
|
|
354
|
+
line,
|
|
355
|
+
column
|
|
356
|
+
}) => {
|
|
357
|
+
const urlObject = new URL(url);
|
|
358
|
+
|
|
359
|
+
const onFileUrl = fileUrlObject => {
|
|
360
|
+
const atFsIndex = fileUrlObject.pathname.indexOf("/@fs/");
|
|
361
|
+
let fileUrl;
|
|
362
|
+
|
|
363
|
+
if (atFsIndex > -1) {
|
|
364
|
+
const afterAtFs = fileUrlObject.pathname.slice(atFsIndex + "/@fs/".length);
|
|
365
|
+
fileUrl = new URL(afterAtFs, "file:///").href;
|
|
366
|
+
} else {
|
|
367
|
+
fileUrl = fileUrlObject.href;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
fileUrl = appendLineAndColumn(fileUrl, {
|
|
371
|
+
line,
|
|
372
|
+
column
|
|
373
|
+
});
|
|
374
|
+
return link({
|
|
375
|
+
href: openInEditor ? `javascript:window.fetch('/__open_in_editor__/${fileUrl}')` : fileUrl,
|
|
376
|
+
text: fileUrl
|
|
377
|
+
});
|
|
112
378
|
};
|
|
379
|
+
|
|
380
|
+
if (urlObject.origin === window.origin) {
|
|
381
|
+
const fileUrlObject = new URL(`${urlObject.pathname.slice(1)}${urlObject.search}`, rootDirectoryUrl);
|
|
382
|
+
return onFileUrl(fileUrlObject);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (urlObject.href.startsWith("file:")) {
|
|
386
|
+
return onFileUrl(urlObject);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return link({
|
|
390
|
+
href: url,
|
|
391
|
+
text: appendLineAndColumn(url, {
|
|
392
|
+
line,
|
|
393
|
+
column
|
|
394
|
+
})
|
|
395
|
+
});
|
|
113
396
|
}
|
|
114
397
|
});
|
|
115
|
-
return
|
|
398
|
+
return string;
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
const escapeHtml = string => {
|
|
402
|
+
return string.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const appendLineAndColumn = (url, {
|
|
406
|
+
line,
|
|
407
|
+
column
|
|
408
|
+
}) => {
|
|
409
|
+
if (line !== undefined && column !== undefined) {
|
|
410
|
+
return `${url}:${line}:${column}`;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (line !== undefined) {
|
|
414
|
+
return `${url}:${line}`;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
return url;
|
|
116
418
|
}; // `Error: yo
|
|
117
419
|
// at Object.execute (http://127.0.0.1:57300/build/src/__test__/file-throw.js:9:13)
|
|
118
420
|
// at doExec (http://127.0.0.1:3000/src/__test__/file-throw.js:452:38)
|
|
@@ -147,14 +449,9 @@ const stringToStringWithLink = (source, {
|
|
|
147
449
|
const lineAndColumnString = lineAndColumMatch[0];
|
|
148
450
|
const lineNumber = lineAndColumMatch[1];
|
|
149
451
|
const columnNumber = lineAndColumMatch[2];
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
text
|
|
154
|
-
} = transform(url);
|
|
155
|
-
linkHTML = link({
|
|
156
|
-
href,
|
|
157
|
-
text: `${text}:${lineNumber}:${columnNumber}`
|
|
452
|
+
linkHTML = transform(match.slice(0, -lineAndColumnString.length), {
|
|
453
|
+
line: lineNumber,
|
|
454
|
+
column: columnNumber
|
|
158
455
|
});
|
|
159
456
|
} else {
|
|
160
457
|
const linePattern = /:([0-9]+)$/;
|
|
@@ -163,25 +460,11 @@ const stringToStringWithLink = (source, {
|
|
|
163
460
|
if (lineMatch) {
|
|
164
461
|
const lineString = lineMatch[0];
|
|
165
462
|
const lineNumber = lineMatch[1];
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
href,
|
|
169
|
-
text
|
|
170
|
-
} = transform(url);
|
|
171
|
-
linkHTML = link({
|
|
172
|
-
href,
|
|
173
|
-
text: `${text}:${lineNumber}`
|
|
463
|
+
linkHTML = transform(match.slice(0, -lineString.length), {
|
|
464
|
+
line: lineNumber
|
|
174
465
|
});
|
|
175
466
|
} else {
|
|
176
|
-
|
|
177
|
-
const {
|
|
178
|
-
href,
|
|
179
|
-
text
|
|
180
|
-
} = transform(url);
|
|
181
|
-
linkHTML = link({
|
|
182
|
-
href,
|
|
183
|
-
text
|
|
184
|
-
});
|
|
467
|
+
linkHTML = transform(match, {});
|
|
185
468
|
}
|
|
186
469
|
}
|
|
187
470
|
|
|
@@ -198,31 +481,6 @@ const link = ({
|
|
|
198
481
|
text = href
|
|
199
482
|
}) => `<a href="${href}">${text}</a>`;
|
|
200
483
|
|
|
201
|
-
const appendHMTLInside = (html, parentNode) => {
|
|
202
|
-
const temoraryParent = document.createElement("div");
|
|
203
|
-
temoraryParent.innerHTML = html;
|
|
204
|
-
return transferChildren(temoraryParent, parentNode);
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const transferChildren = (fromNode, toNode) => {
|
|
208
|
-
const childNodes = [].slice.call(fromNode.childNodes, 0);
|
|
209
|
-
let i = 0;
|
|
210
|
-
|
|
211
|
-
while (i < childNodes.length) {
|
|
212
|
-
toNode.appendChild(childNodes[i]);
|
|
213
|
-
i++;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return () => {
|
|
217
|
-
let c = 0;
|
|
218
|
-
|
|
219
|
-
while (c < childNodes.length) {
|
|
220
|
-
fromNode.appendChild(childNodes[c]);
|
|
221
|
-
c++;
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
};
|
|
225
|
-
|
|
226
484
|
const {
|
|
227
485
|
Notification
|
|
228
486
|
} = window;
|
|
@@ -250,9 +508,13 @@ const displayErrorNotification = typeof Notification === "function" ? displayErr
|
|
|
250
508
|
const {
|
|
251
509
|
__html_supervisor__
|
|
252
510
|
} = window;
|
|
511
|
+
const supervisedScripts = [];
|
|
253
512
|
const installHtmlSupervisor = ({
|
|
513
|
+
rootDirectoryUrl,
|
|
254
514
|
logs,
|
|
255
|
-
measurePerf
|
|
515
|
+
measurePerf,
|
|
516
|
+
errorOverlay,
|
|
517
|
+
openInEditor
|
|
256
518
|
}) => {
|
|
257
519
|
|
|
258
520
|
const scriptExecutionResults = {};
|
|
@@ -288,15 +550,14 @@ const installHtmlSupervisor = ({
|
|
|
288
550
|
|
|
289
551
|
const onExecutionError = (executionResult, {
|
|
290
552
|
currentScript,
|
|
291
|
-
errorExposureInNotification = false
|
|
292
|
-
errorExposureInDocument = true
|
|
553
|
+
errorExposureInNotification = false
|
|
293
554
|
}) => {
|
|
294
555
|
const error = executionResult.error;
|
|
295
556
|
|
|
296
557
|
if (error && error.code === "NETWORK_FAILURE") {
|
|
297
558
|
if (currentScript) {
|
|
298
|
-
const
|
|
299
|
-
currentScript.dispatchEvent(
|
|
559
|
+
const currentScriptErrorEvent = new Event("error");
|
|
560
|
+
currentScript.dispatchEvent(currentScriptErrorEvent);
|
|
300
561
|
}
|
|
301
562
|
} else if (typeof error === "object") {
|
|
302
563
|
const globalErrorEvent = new Event("error");
|
|
@@ -311,10 +572,6 @@ const installHtmlSupervisor = ({
|
|
|
311
572
|
displayErrorNotification(error);
|
|
312
573
|
}
|
|
313
574
|
|
|
314
|
-
if (errorExposureInDocument) {
|
|
315
|
-
displayErrorInDocument(error);
|
|
316
|
-
}
|
|
317
|
-
|
|
318
575
|
executionResult.exceptionSource = unevalException(error);
|
|
319
576
|
delete executionResult.error;
|
|
320
577
|
};
|
|
@@ -333,7 +590,9 @@ const installHtmlSupervisor = ({
|
|
|
333
590
|
currentScript,
|
|
334
591
|
execute // https://developer.mozilla.org/en-US/docs/web/html/element/script
|
|
335
592
|
|
|
336
|
-
}
|
|
593
|
+
}, {
|
|
594
|
+
reload = false
|
|
595
|
+
} = {}) => {
|
|
337
596
|
if (logs) {
|
|
338
597
|
console.group(`[jsenv] loading ${type} ${src}`);
|
|
339
598
|
}
|
|
@@ -344,7 +603,13 @@ const installHtmlSupervisor = ({
|
|
|
344
603
|
let error;
|
|
345
604
|
|
|
346
605
|
try {
|
|
347
|
-
|
|
606
|
+
const urlObject = new URL(src, window.location);
|
|
607
|
+
|
|
608
|
+
if (reload) {
|
|
609
|
+
urlObject.searchParams.set("hmr", Date.now());
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
result = await execute(urlObject.href);
|
|
348
613
|
completed = true;
|
|
349
614
|
} catch (e) {
|
|
350
615
|
completed = false;
|
|
@@ -408,12 +673,22 @@ const installHtmlSupervisor = ({
|
|
|
408
673
|
}));
|
|
409
674
|
|
|
410
675
|
__html_supervisor__.addScriptToExecute = async scriptToExecute => {
|
|
676
|
+
if (!supervisedScripts.includes(scriptToExecute)) {
|
|
677
|
+
supervisedScripts.push(scriptToExecute);
|
|
678
|
+
|
|
679
|
+
scriptToExecute.reload = () => {
|
|
680
|
+
return performExecution(scriptToExecute, {
|
|
681
|
+
reload: true
|
|
682
|
+
});
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
411
686
|
if (scriptToExecute.async) {
|
|
412
687
|
performExecution(scriptToExecute);
|
|
413
688
|
return;
|
|
414
689
|
}
|
|
415
690
|
|
|
416
|
-
const useDeferQueue = scriptToExecute.defer || scriptToExecute.type === "
|
|
691
|
+
const useDeferQueue = scriptToExecute.defer || scriptToExecute.type === "module";
|
|
417
692
|
|
|
418
693
|
if (useDeferQueue) {
|
|
419
694
|
// defer must wait for classic script to be done
|
|
@@ -467,16 +742,118 @@ const installHtmlSupervisor = ({
|
|
|
467
742
|
copy.forEach(scriptToExecute => {
|
|
468
743
|
__html_supervisor__.addScriptToExecute(scriptToExecute);
|
|
469
744
|
});
|
|
745
|
+
|
|
746
|
+
if (errorOverlay) {
|
|
747
|
+
window.addEventListener("error", errorEvent => {
|
|
748
|
+
if (!errorEvent.isTrusted) {
|
|
749
|
+
// ignore custom error event (not sent by browser)
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const {
|
|
754
|
+
error
|
|
755
|
+
} = errorEvent;
|
|
756
|
+
displayErrorInDocument(error, {
|
|
757
|
+
rootDirectoryUrl,
|
|
758
|
+
openInEditor,
|
|
759
|
+
url: errorEvent.filename,
|
|
760
|
+
line: errorEvent.lineno,
|
|
761
|
+
column: errorEvent.colno,
|
|
762
|
+
reportedBy: "browser"
|
|
763
|
+
});
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
if (window.__server_events__) {
|
|
767
|
+
const isExecuting = () => {
|
|
768
|
+
if (pendingExecutionCount > 0) {
|
|
769
|
+
return true;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
if (document.readyState === "loading" || document.readyState === "interactive") {
|
|
773
|
+
return true;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
if (window.__reloader__ && window.__reloader__.status === "reloading") {
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
return false;
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
window.__server_events__.addEventCallbacks({
|
|
784
|
+
error_while_serving_file: serverErrorEvent => {
|
|
785
|
+
if (!isExecuting()) {
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
const {
|
|
790
|
+
message,
|
|
791
|
+
stack,
|
|
792
|
+
traceUrl,
|
|
793
|
+
traceLine,
|
|
794
|
+
traceColumn,
|
|
795
|
+
traceMessage,
|
|
796
|
+
requestedRessource,
|
|
797
|
+
isFaviconAutoRequest
|
|
798
|
+
} = JSON.parse(serverErrorEvent.data);
|
|
799
|
+
|
|
800
|
+
if (isFaviconAutoRequest) {
|
|
801
|
+
return;
|
|
802
|
+
} // setTimeout is to ensure the error
|
|
803
|
+
// dispatched on window by browser is displayed first,
|
|
804
|
+
// then the server error replaces it (because it contains more information)
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
setTimeout(() => {
|
|
808
|
+
displayErrorInDocument({
|
|
809
|
+
message,
|
|
810
|
+
stack: stack && traceMessage ? `${stack}\n\n${traceMessage}` : stack ? stack : traceMessage ? `\n${traceMessage}` : ""
|
|
811
|
+
}, {
|
|
812
|
+
rootDirectoryUrl,
|
|
813
|
+
openInEditor,
|
|
814
|
+
url: traceUrl,
|
|
815
|
+
line: traceLine,
|
|
816
|
+
column: traceColumn,
|
|
817
|
+
reportedBy: "server",
|
|
818
|
+
requestedRessource
|
|
819
|
+
});
|
|
820
|
+
}, 10);
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
__html_supervisor__.reloadSupervisedScript = ({
|
|
828
|
+
type,
|
|
829
|
+
src
|
|
830
|
+
}) => {
|
|
831
|
+
const supervisedScript = supervisedScripts.find(supervisedScriptCandidate => {
|
|
832
|
+
if (type && supervisedScriptCandidate.type !== type) {
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
if (supervisedScriptCandidate.src !== src) {
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
return true;
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
if (supervisedScript) {
|
|
844
|
+
supervisedScript.reload();
|
|
845
|
+
}
|
|
470
846
|
};
|
|
847
|
+
|
|
471
848
|
const superviseScriptTypeModule = ({
|
|
472
849
|
src,
|
|
473
850
|
isInline
|
|
474
851
|
}) => {
|
|
475
852
|
__html_supervisor__.addScriptToExecute({
|
|
476
853
|
src,
|
|
477
|
-
type: "
|
|
854
|
+
type: "module",
|
|
478
855
|
isInline,
|
|
479
|
-
execute:
|
|
856
|
+
execute: url => import(url)
|
|
480
857
|
});
|
|
481
858
|
};
|
|
482
859
|
|