@jsenv/core 35.0.2 → 35.0.4
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/html/explorer.html +107 -107
- package/dist/js/new_stylesheet.js +3 -0
- package/dist/js/s.js.map +3 -3
- package/dist/jsenv_core.js +15 -17
- package/package.json +1 -1
- package/src/build/build.js +589 -587
- package/src/build/build_urls_generator.js +44 -44
- package/src/build/graph_utils.js +14 -14
- package/src/build/jsenv_plugin_line_break_normalization.js +6 -6
- package/src/build/line_break_unix.js +11 -11
- package/src/build/start_build_server.js +37 -37
- package/src/build/version_generator.js +7 -7
- package/src/build/version_mappings_injection.js +23 -23
- package/src/dev/file_service.js +136 -135
- package/src/dev/start_dev_server.js +56 -56
- package/src/dev/user_agent.js +8 -8
- package/src/helpers/basic_fetch.js +24 -24
- package/src/helpers/command/command.js +28 -28
- package/src/helpers/lookup_package_directory.js +19 -16
- package/src/helpers/ping_server.js +17 -17
- package/src/helpers/require_from_jsenv.js +2 -2
- package/src/helpers/watch_source_files.js +9 -9
- package/src/helpers/web_url_converter.js +10 -10
- package/src/helpers/worker_reload.js +27 -27
- package/src/kitchen/compat/features_compatibility.js +1 -1
- package/src/kitchen/compat/runtime_compat.js +26 -24
- package/src/kitchen/errors.js +75 -75
- package/src/kitchen/fetched_content_compliance.js +8 -8
- package/src/kitchen/kitchen.js +251 -250
- package/src/kitchen/url_graph/sort_by_dependencies.js +17 -17
- package/src/kitchen/url_graph/url_graph_loader.js +30 -30
- package/src/kitchen/url_graph/url_graph_report.js +57 -57
- package/src/kitchen/url_graph/url_info_transformations.js +77 -77
- package/src/kitchen/url_graph.js +121 -121
- package/src/kitchen/url_specifier_encoding.js +21 -21
- package/src/kitchen/web_workers.js +5 -5
- package/src/main.js +3 -3
- package/src/plugins/autoreload/client/autoreload.js +96 -96
- package/src/plugins/autoreload/client/reload.js +56 -56
- package/src/plugins/autoreload/client/url_helpers.js +13 -13
- package/src/plugins/autoreload/jsenv_plugin_autoreload.js +5 -5
- package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +9 -9
- package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +61 -60
- package/src/plugins/autoreload/jsenv_plugin_hmr.js +15 -15
- package/src/plugins/cache_control/jsenv_plugin_cache_control.js +5 -5
- package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +57 -57
- package/src/plugins/explorer/client/explorer.html +107 -107
- package/src/plugins/explorer/jsenv_plugin_explorer.js +23 -25
- package/src/plugins/file_urls/jsenv_plugin_file_urls.js +60 -60
- package/src/plugins/global_scenarios/jsenv_plugin_global_scenarios.js +5 -5
- package/src/plugins/http_urls/jsenv_plugin_http_urls.js +3 -3
- package/src/plugins/import_meta_hot/babel_plugin_metadata_import_meta_hot.js +35 -35
- package/src/plugins/import_meta_hot/client/import_meta_hot.js +26 -26
- package/src/plugins/import_meta_hot/html_hot_dependencies.js +43 -43
- package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +44 -40
- package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +35 -35
- package/src/plugins/import_meta_url/client/import_meta_url_browser.js +21 -21
- package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +3 -3
- package/src/plugins/importmap/jsenv_plugin_importmap.js +54 -54
- package/src/plugins/inline_content_analysis/client/inline_content.js +3 -3
- package/src/plugins/inline_content_analysis/jsenv_plugin_data_urls.js +26 -26
- package/src/plugins/inline_content_analysis/jsenv_plugin_html_inline_content_analysis.js +47 -47
- package/src/plugins/inline_content_analysis/jsenv_plugin_inline_content_analysis.js +9 -9
- package/src/plugins/inline_content_analysis/jsenv_plugin_js_inline_content_analysis.js +101 -101
- package/src/plugins/inlining/jsenv_plugin_inlining.js +9 -9
- package/src/plugins/inlining/jsenv_plugin_inlining_as_data_url.js +11 -11
- package/src/plugins/inlining/jsenv_plugin_inlining_into_html.js +48 -46
- package/src/plugins/node_runtime/jsenv_plugin_node_runtime.js +4 -4
- package/src/plugins/plugin_controller.js +124 -124
- package/src/plugins/plugins.js +30 -30
- package/src/plugins/ribbon/client/ribbon.js +6 -6
- package/src/plugins/ribbon/jsenv_plugin_ribbon.js +15 -15
- package/src/plugins/server_events/client/connection_manager.js +52 -52
- package/src/plugins/server_events/client/event_source_connection.js +36 -36
- package/src/plugins/server_events/client/events_manager.js +37 -37
- package/src/plugins/server_events/client/server_events_client.js +7 -7
- package/src/plugins/server_events/client/web_socket_connection.js +39 -39
- package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +9 -9
- package/src/plugins/server_events/server_events_dispatcher.js +43 -43
- package/src/plugins/supervisor/client/supervisor.js +455 -450
- package/src/plugins/supervisor/html_supervisor_injection.js +64 -62
- package/src/plugins/supervisor/js_supervisor_injection.js +67 -67
- package/src/plugins/supervisor/jsenv_plugin_supervisor.js +54 -51
- package/src/plugins/transpilation/as_js_module/convert_js_classic_to_js_module.js +13 -13
- package/src/plugins/transpilation/as_js_module/jsenv_plugin_as_js_module.js +19 -19
- package/src/plugins/transpilation/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +10 -10
- package/src/plugins/transpilation/babel/global_this/client/global_this.js +8 -8
- package/src/plugins/transpilation/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +16 -16
- package/src/plugins/transpilation/babel/helpers/babel_plugin_structure.js +36 -36
- package/src/plugins/transpilation/babel/helpers/babel_plugins_compatibility.js +3 -3
- package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +24 -24
- package/src/plugins/transpilation/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +44 -44
- package/src/plugins/transpilation/babel/new_stylesheet/client/new_stylesheet.js +166 -166
- package/src/plugins/transpilation/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +10 -10
- package/src/plugins/transpilation/babel/require_babel_plugin.js +6 -6
- package/src/plugins/transpilation/css/jsenv_plugin_css_transpilation.js +20 -20
- package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +62 -62
- package/src/plugins/transpilation/js_module_fallback/client/s.js +214 -209
- package/src/plugins/transpilation/js_module_fallback/convert_js_module_to_js_classic.js +45 -45
- package/src/plugins/transpilation/js_module_fallback/helpers/babel_plugin_transform_import_meta_resolve.js +6 -6
- package/src/plugins/transpilation/js_module_fallback/helpers/babel_plugin_transform_import_meta_url.js +17 -17
- package/src/plugins/transpilation/js_module_fallback/helpers-string.js +1 -1
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_conversion.js +32 -32
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback.js +17 -17
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_inside_html.js +63 -63
- package/src/plugins/transpilation/js_module_fallback/jsenv_plugin_js_module_fallback_on_workers.js +15 -15
- package/src/plugins/transpilation/jsenv_plugin_import_meta_resolve.js +20 -20
- package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +23 -23
- package/src/plugins/transpilation/jsenv_plugin_transpilation.js +11 -11
- package/src/plugins/url_analysis/css/css_urls.js +12 -12
- package/src/plugins/url_analysis/html/html_urls.js +85 -85
- package/src/plugins/url_analysis/js/js_urls.js +16 -16
- package/src/plugins/url_analysis/jsenv_plugin_reference_expected_types.js +16 -16
- package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +40 -40
- package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +12 -12
- package/src/plugins/url_resolution/jsenv_plugin_url_resolution.js +36 -36
- package/src/plugins/url_resolution/node_esm_resolver.js +26 -26
- package/src/plugins/url_version/jsenv_plugin_url_version.js +11 -11
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { urlHotMetas } from "../../import_meta_hot/client/import_meta_hot.js"
|
|
2
|
-
import { compareTwoUrlPaths } from "./url_helpers.js"
|
|
1
|
+
import { urlHotMetas } from "../../import_meta_hot/client/import_meta_hot.js";
|
|
2
|
+
import { compareTwoUrlPaths } from "./url_helpers.js";
|
|
3
3
|
import {
|
|
4
4
|
reloadHtmlPage,
|
|
5
5
|
reloadJsImport,
|
|
6
6
|
getDOMNodesUsingUrl,
|
|
7
|
-
} from "./reload.js"
|
|
7
|
+
} from "./reload.js";
|
|
8
8
|
|
|
9
9
|
const reloader = {
|
|
10
10
|
urlHotMetas,
|
|
@@ -12,44 +12,44 @@ const reloader = {
|
|
|
12
12
|
value: "idle",
|
|
13
13
|
onchange: () => {},
|
|
14
14
|
goTo: (value) => {
|
|
15
|
-
reloader.status.value = value
|
|
16
|
-
reloader.status.onchange()
|
|
15
|
+
reloader.status.value = value;
|
|
16
|
+
reloader.status.onchange();
|
|
17
17
|
},
|
|
18
18
|
},
|
|
19
19
|
autoreload: {
|
|
20
20
|
enabled: ["1", null].includes(window.localStorage.getItem("autoreload")),
|
|
21
21
|
onchange: () => {},
|
|
22
22
|
enable: () => {
|
|
23
|
-
reloader.autoreload.enabled = true
|
|
24
|
-
window.localStorage.setItem("autoreload", "1")
|
|
25
|
-
reloader.autoreload.onchange()
|
|
23
|
+
reloader.autoreload.enabled = true;
|
|
24
|
+
window.localStorage.setItem("autoreload", "1");
|
|
25
|
+
reloader.autoreload.onchange();
|
|
26
26
|
},
|
|
27
27
|
disable: () => {
|
|
28
|
-
reloader.autoreload.enabled = false
|
|
29
|
-
window.localStorage.setItem("autoreload", "0")
|
|
30
|
-
reloader.autoreload.onchange()
|
|
28
|
+
reloader.autoreload.enabled = false;
|
|
29
|
+
window.localStorage.setItem("autoreload", "0");
|
|
30
|
+
reloader.autoreload.onchange();
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
33
|
changes: {
|
|
34
34
|
value: [],
|
|
35
35
|
onchange: () => {},
|
|
36
36
|
add: (reloadMessage) => {
|
|
37
|
-
reloader.changes.value.push(reloadMessage)
|
|
38
|
-
reloader.changes.onchange()
|
|
37
|
+
reloader.changes.value.push(reloadMessage);
|
|
38
|
+
reloader.changes.onchange();
|
|
39
39
|
if (reloader.autoreload.enabled) {
|
|
40
|
-
reloader.reload()
|
|
40
|
+
reloader.reload();
|
|
41
41
|
} else {
|
|
42
|
-
reloader.status.goTo("can_reload")
|
|
42
|
+
reloader.status.goTo("can_reload");
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
remove: (reloadMessage) => {
|
|
46
|
-
const index = reloader.changes.value.indexOf(reloadMessage)
|
|
46
|
+
const index = reloader.changes.value.indexOf(reloadMessage);
|
|
47
47
|
if (index > -1) {
|
|
48
|
-
reloader.changes.value.splice(index, 1)
|
|
48
|
+
reloader.changes.value.splice(index, 1);
|
|
49
49
|
if (reloader.changes.value.length === 0) {
|
|
50
|
-
reloader.status.goTo("idle")
|
|
50
|
+
reloader.status.goTo("idle");
|
|
51
51
|
}
|
|
52
|
-
reloader.changes.onchange()
|
|
52
|
+
reloader.changes.onchange();
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
55
|
},
|
|
@@ -57,169 +57,169 @@ const reloader = {
|
|
|
57
57
|
reload: () => {
|
|
58
58
|
const someEffectIsFullReload = reloader.changes.value.some(
|
|
59
59
|
(reloadMessage) => reloadMessage.type === "full",
|
|
60
|
-
)
|
|
60
|
+
);
|
|
61
61
|
if (someEffectIsFullReload) {
|
|
62
|
-
reloadHtmlPage()
|
|
63
|
-
return
|
|
62
|
+
reloadHtmlPage();
|
|
63
|
+
return;
|
|
64
64
|
}
|
|
65
|
-
reloader.status.goTo("reloading")
|
|
65
|
+
reloader.status.goTo("reloading");
|
|
66
66
|
const onApplied = (reloadMessage) => {
|
|
67
|
-
reloader.changes.remove(reloadMessage)
|
|
68
|
-
}
|
|
67
|
+
reloader.changes.remove(reloadMessage);
|
|
68
|
+
};
|
|
69
69
|
const setReloadMessagePromise = (reloadMessage, promise) => {
|
|
70
70
|
promise.then(
|
|
71
71
|
() => {
|
|
72
|
-
onApplied(reloadMessage)
|
|
73
|
-
reloader.currentExecution = null
|
|
72
|
+
onApplied(reloadMessage);
|
|
73
|
+
reloader.currentExecution = null;
|
|
74
74
|
},
|
|
75
75
|
(e) => {
|
|
76
|
-
reloader.status.goTo("failed")
|
|
76
|
+
reloader.status.goTo("failed");
|
|
77
77
|
if (typeof window.reportError === "function") {
|
|
78
|
-
window.reportError(e)
|
|
78
|
+
window.reportError(e);
|
|
79
79
|
} else {
|
|
80
|
-
console.error(e)
|
|
80
|
+
console.error(e);
|
|
81
81
|
}
|
|
82
82
|
console.error(
|
|
83
83
|
`[jsenv] Hot reload failed after ${reloadMessage.reason}.
|
|
84
84
|
This could be due to syntax errors or importing non-existent modules (see errors in console)`,
|
|
85
|
-
)
|
|
86
|
-
reloader.currentExecution = null
|
|
85
|
+
);
|
|
86
|
+
reloader.currentExecution = null;
|
|
87
87
|
},
|
|
88
|
-
)
|
|
89
|
-
}
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
90
|
reloader.changes.value.forEach((reloadMessage) => {
|
|
91
91
|
if (reloadMessage.type === "hot") {
|
|
92
92
|
const promise = addToHotQueue(() => {
|
|
93
|
-
return applyHotReload(reloadMessage)
|
|
94
|
-
})
|
|
95
|
-
setReloadMessagePromise(reloadMessage, promise)
|
|
93
|
+
return applyHotReload(reloadMessage);
|
|
94
|
+
});
|
|
95
|
+
setReloadMessagePromise(reloadMessage, promise);
|
|
96
96
|
} else {
|
|
97
|
-
setReloadMessagePromise(reloadMessage, Promise.resolve())
|
|
97
|
+
setReloadMessagePromise(reloadMessage, Promise.resolve());
|
|
98
98
|
}
|
|
99
|
-
})
|
|
99
|
+
});
|
|
100
100
|
},
|
|
101
|
-
}
|
|
101
|
+
};
|
|
102
102
|
|
|
103
|
-
let pendingCallbacks = []
|
|
104
|
-
let running = false
|
|
103
|
+
let pendingCallbacks = [];
|
|
104
|
+
let running = false;
|
|
105
105
|
const addToHotQueue = async (callback) => {
|
|
106
|
-
pendingCallbacks.push(callback)
|
|
107
|
-
dequeue()
|
|
108
|
-
}
|
|
106
|
+
pendingCallbacks.push(callback);
|
|
107
|
+
dequeue();
|
|
108
|
+
};
|
|
109
109
|
const dequeue = async () => {
|
|
110
110
|
if (running) {
|
|
111
|
-
return
|
|
111
|
+
return;
|
|
112
112
|
}
|
|
113
|
-
const callbacks = pendingCallbacks.slice()
|
|
114
|
-
pendingCallbacks = []
|
|
115
|
-
running = true
|
|
113
|
+
const callbacks = pendingCallbacks.slice();
|
|
114
|
+
pendingCallbacks = [];
|
|
115
|
+
running = true;
|
|
116
116
|
try {
|
|
117
117
|
await callbacks.reduce(async (previous, callback) => {
|
|
118
|
-
await previous
|
|
119
|
-
await callback()
|
|
120
|
-
}, Promise.resolve())
|
|
118
|
+
await previous;
|
|
119
|
+
await callback();
|
|
120
|
+
}, Promise.resolve());
|
|
121
121
|
} finally {
|
|
122
|
-
running = false
|
|
122
|
+
running = false;
|
|
123
123
|
if (pendingCallbacks.length) {
|
|
124
|
-
dequeue()
|
|
124
|
+
dequeue();
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
-
}
|
|
127
|
+
};
|
|
128
128
|
|
|
129
129
|
const applyHotReload = async ({ hotInstructions }) => {
|
|
130
130
|
await hotInstructions.reduce(
|
|
131
131
|
async (previous, { type, boundary, acceptedBy }) => {
|
|
132
|
-
await previous
|
|
132
|
+
await previous;
|
|
133
133
|
|
|
134
|
-
const urlToFetch = new URL(boundary, `${window.location.origin}/`).href
|
|
135
|
-
const urlHotMeta = urlHotMetas[urlToFetch]
|
|
134
|
+
const urlToFetch = new URL(boundary, `${window.location.origin}/`).href;
|
|
135
|
+
const urlHotMeta = urlHotMetas[urlToFetch];
|
|
136
136
|
// there is no url hot meta when:
|
|
137
137
|
// - code was not executed (code splitting with dynamic import)
|
|
138
138
|
// - import.meta.hot.accept() is not called (happens for HTML and CSS)
|
|
139
139
|
|
|
140
140
|
if (type === "prune") {
|
|
141
141
|
if (urlHotMeta) {
|
|
142
|
-
delete urlHotMetas[urlToFetch]
|
|
142
|
+
delete urlHotMetas[urlToFetch];
|
|
143
143
|
if (urlHotMeta.disposeCallback) {
|
|
144
144
|
console.groupCollapsed(
|
|
145
145
|
`[jsenv] cleanup ${boundary} (previously used in ${acceptedBy})`,
|
|
146
|
-
)
|
|
147
|
-
console.log(`call dispose callback`)
|
|
148
|
-
await urlHotMeta.disposeCallback()
|
|
149
|
-
console.groupEnd()
|
|
146
|
+
);
|
|
147
|
+
console.log(`call dispose callback`);
|
|
148
|
+
await urlHotMeta.disposeCallback();
|
|
149
|
+
console.groupEnd();
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
|
-
return null
|
|
152
|
+
return null;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
if (acceptedBy === boundary) {
|
|
156
|
-
console.groupCollapsed(`[jsenv] hot reloading ${boundary}`)
|
|
156
|
+
console.groupCollapsed(`[jsenv] hot reloading ${boundary}`);
|
|
157
157
|
} else {
|
|
158
158
|
console.groupCollapsed(
|
|
159
159
|
`[jsenv] hot reloading ${acceptedBy} usage in ${boundary}`,
|
|
160
|
-
)
|
|
160
|
+
);
|
|
161
161
|
}
|
|
162
162
|
if (type === "js_module") {
|
|
163
163
|
if (!urlHotMeta) {
|
|
164
164
|
// code was not executed, no need to re-execute it
|
|
165
|
-
return null
|
|
165
|
+
return null;
|
|
166
166
|
}
|
|
167
167
|
if (urlHotMeta.disposeCallback) {
|
|
168
|
-
console.log(`call dispose callback`)
|
|
169
|
-
await urlHotMeta.disposeCallback()
|
|
168
|
+
console.log(`call dispose callback`);
|
|
169
|
+
await urlHotMeta.disposeCallback();
|
|
170
170
|
}
|
|
171
|
-
console.log(`importing js module`)
|
|
171
|
+
console.log(`importing js module`);
|
|
172
172
|
reloader.currentExecution = {
|
|
173
173
|
type: "dynamic_import",
|
|
174
174
|
url: urlToFetch,
|
|
175
|
-
}
|
|
176
|
-
const namespace = await reloadJsImport(urlToFetch)
|
|
175
|
+
};
|
|
176
|
+
const namespace = await reloadJsImport(urlToFetch);
|
|
177
177
|
if (urlHotMeta.acceptCallback) {
|
|
178
|
-
await urlHotMeta.acceptCallback(namespace)
|
|
178
|
+
await urlHotMeta.acceptCallback(namespace);
|
|
179
179
|
}
|
|
180
|
-
console.log(`js module import done`)
|
|
181
|
-
console.groupEnd()
|
|
182
|
-
return namespace
|
|
180
|
+
console.log(`js module import done`);
|
|
181
|
+
console.groupEnd();
|
|
182
|
+
return namespace;
|
|
183
183
|
}
|
|
184
184
|
if (type === "html") {
|
|
185
185
|
const isRootHtmlFile =
|
|
186
186
|
window.location.pathname === "/" &&
|
|
187
|
-
new URL(urlToFetch).pathname.slice(1).indexOf("/") === -1
|
|
187
|
+
new URL(urlToFetch).pathname.slice(1).indexOf("/") === -1;
|
|
188
188
|
if (
|
|
189
189
|
!isRootHtmlFile &&
|
|
190
190
|
!compareTwoUrlPaths(urlToFetch, window.location.href)
|
|
191
191
|
) {
|
|
192
192
|
// we are not in that HTML page
|
|
193
|
-
return null
|
|
193
|
+
return null;
|
|
194
194
|
}
|
|
195
195
|
const urlToReload = new URL(acceptedBy, `${window.location.origin}/`)
|
|
196
|
-
.href
|
|
197
|
-
const domNodesUsingUrl = getDOMNodesUsingUrl(urlToReload)
|
|
198
|
-
const domNodesCount = domNodesUsingUrl.length
|
|
196
|
+
.href;
|
|
197
|
+
const domNodesUsingUrl = getDOMNodesUsingUrl(urlToReload);
|
|
198
|
+
const domNodesCount = domNodesUsingUrl.length;
|
|
199
199
|
if (domNodesCount === 0) {
|
|
200
|
-
console.log(`no dom node using ${acceptedBy}`)
|
|
200
|
+
console.log(`no dom node using ${acceptedBy}`);
|
|
201
201
|
} else if (domNodesCount === 1) {
|
|
202
|
-
console.log(`reloading`, domNodesUsingUrl[0].node)
|
|
203
|
-
domNodesUsingUrl[0].reload()
|
|
202
|
+
console.log(`reloading`, domNodesUsingUrl[0].node);
|
|
203
|
+
domNodesUsingUrl[0].reload();
|
|
204
204
|
} else {
|
|
205
|
-
console.log(`reloading ${domNodesCount} nodes using ${acceptedBy}`)
|
|
205
|
+
console.log(`reloading ${domNodesCount} nodes using ${acceptedBy}`);
|
|
206
206
|
domNodesUsingUrl.forEach((domNodesUsingUrl) => {
|
|
207
|
-
domNodesUsingUrl.reload()
|
|
208
|
-
})
|
|
207
|
+
domNodesUsingUrl.reload();
|
|
208
|
+
});
|
|
209
209
|
}
|
|
210
|
-
console.groupEnd()
|
|
211
|
-
return null
|
|
210
|
+
console.groupEnd();
|
|
211
|
+
return null;
|
|
212
212
|
}
|
|
213
|
-
console.warn(`unknown update type: "${type}"`)
|
|
214
|
-
return null
|
|
213
|
+
console.warn(`unknown update type: "${type}"`);
|
|
214
|
+
return null;
|
|
215
215
|
},
|
|
216
216
|
Promise.resolve(),
|
|
217
|
-
)
|
|
218
|
-
}
|
|
217
|
+
);
|
|
218
|
+
};
|
|
219
219
|
|
|
220
|
-
window.__reloader__ = reloader
|
|
220
|
+
window.__reloader__ = reloader;
|
|
221
221
|
window.__server_events__.listenEvents({
|
|
222
222
|
reload: (reloadServerEvent) => {
|
|
223
|
-
reloader.changes.add(reloadServerEvent.data)
|
|
223
|
+
reloader.changes.add(reloadServerEvent.data);
|
|
224
224
|
},
|
|
225
|
-
})
|
|
225
|
+
});
|
|
@@ -1,83 +1,83 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseSrcSet,
|
|
3
3
|
stringifySrcSet,
|
|
4
|
-
} from "@jsenv/ast/src/html/html_src_set.js"
|
|
4
|
+
} from "@jsenv/ast/src/html/html_src_set.js";
|
|
5
5
|
|
|
6
|
-
import { injectQuery, compareTwoUrlPaths } from "./url_helpers.js"
|
|
6
|
+
import { injectQuery, compareTwoUrlPaths } from "./url_helpers.js";
|
|
7
7
|
|
|
8
8
|
export const reloadHtmlPage = () => {
|
|
9
|
-
window.location.reload(true)
|
|
10
|
-
}
|
|
9
|
+
window.location.reload(true);
|
|
10
|
+
};
|
|
11
11
|
|
|
12
12
|
// This function can consider everything as hot reloadable:
|
|
13
13
|
// - no need to check [hot-accept]and [hot-decline] attributes for instance
|
|
14
14
|
// This is because if something should full reload, we receive "full_reload"
|
|
15
15
|
// from server and this function is not called
|
|
16
16
|
export const getDOMNodesUsingUrl = (urlToReload) => {
|
|
17
|
-
const nodes = []
|
|
17
|
+
const nodes = [];
|
|
18
18
|
const shouldReloadUrl = (urlCandidate) => {
|
|
19
|
-
return compareTwoUrlPaths(urlCandidate, urlToReload)
|
|
20
|
-
}
|
|
19
|
+
return compareTwoUrlPaths(urlCandidate, urlToReload);
|
|
20
|
+
};
|
|
21
21
|
const visitNodeAttributeAsUrl = (node, attributeName) => {
|
|
22
|
-
let attribute = node[attributeName]
|
|
22
|
+
let attribute = node[attributeName];
|
|
23
23
|
if (!attribute) {
|
|
24
|
-
return
|
|
24
|
+
return;
|
|
25
25
|
}
|
|
26
26
|
if (SVGAnimatedString && attribute instanceof SVGAnimatedString) {
|
|
27
|
-
attribute = attribute.animVal
|
|
27
|
+
attribute = attribute.animVal;
|
|
28
28
|
}
|
|
29
29
|
if (!shouldReloadUrl(attribute)) {
|
|
30
|
-
return
|
|
30
|
+
return;
|
|
31
31
|
}
|
|
32
32
|
nodes.push({
|
|
33
33
|
node,
|
|
34
34
|
reload: () => {
|
|
35
35
|
if (node.nodeName === "SCRIPT") {
|
|
36
|
-
const copy = document.createElement("script")
|
|
36
|
+
const copy = document.createElement("script");
|
|
37
37
|
Array.from(node.attributes).forEach((attribute) => {
|
|
38
|
-
copy.setAttribute(attribute.nodeName, attribute.nodeValue)
|
|
39
|
-
})
|
|
40
|
-
copy.src = injectQuery(node.src, { hmr: Date.now() })
|
|
38
|
+
copy.setAttribute(attribute.nodeName, attribute.nodeValue);
|
|
39
|
+
});
|
|
40
|
+
copy.src = injectQuery(node.src, { hmr: Date.now() });
|
|
41
41
|
if (node.parentNode) {
|
|
42
|
-
node.parentNode.replaceChild(copy, node)
|
|
42
|
+
node.parentNode.replaceChild(copy, node);
|
|
43
43
|
} else {
|
|
44
|
-
document.body.appendChild(copy)
|
|
44
|
+
document.body.appendChild(copy);
|
|
45
45
|
}
|
|
46
46
|
} else {
|
|
47
|
-
node[attributeName] = injectQuery(attribute, { hmr: Date.now() })
|
|
47
|
+
node[attributeName] = injectQuery(attribute, { hmr: Date.now() });
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
|
-
})
|
|
51
|
-
}
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
52
|
Array.from(document.querySelectorAll(`link[rel="stylesheet"]`)).forEach(
|
|
53
53
|
(link) => {
|
|
54
|
-
visitNodeAttributeAsUrl(link, "href")
|
|
54
|
+
visitNodeAttributeAsUrl(link, "href");
|
|
55
55
|
},
|
|
56
|
-
)
|
|
56
|
+
);
|
|
57
57
|
Array.from(document.querySelectorAll(`link[rel="icon"]`)).forEach((link) => {
|
|
58
|
-
visitNodeAttributeAsUrl(link, "href")
|
|
59
|
-
})
|
|
58
|
+
visitNodeAttributeAsUrl(link, "href");
|
|
59
|
+
});
|
|
60
60
|
Array.from(document.querySelectorAll("script")).forEach((script) => {
|
|
61
|
-
visitNodeAttributeAsUrl(script, "src")
|
|
62
|
-
const inlinedFromSrc = script.getAttribute("inlined-from-src")
|
|
61
|
+
visitNodeAttributeAsUrl(script, "src");
|
|
62
|
+
const inlinedFromSrc = script.getAttribute("inlined-from-src");
|
|
63
63
|
if (inlinedFromSrc) {
|
|
64
64
|
const inlinedFromUrl = new URL(inlinedFromSrc, window.location.origin)
|
|
65
|
-
.href
|
|
65
|
+
.href;
|
|
66
66
|
if (shouldReloadUrl(inlinedFromUrl)) {
|
|
67
67
|
nodes.push({
|
|
68
68
|
node: script,
|
|
69
69
|
reload: () =>
|
|
70
70
|
window.__supervisor__.reloadSupervisedScript(inlinedFromSrc),
|
|
71
|
-
})
|
|
71
|
+
});
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
})
|
|
74
|
+
});
|
|
75
75
|
// There is no real need to update a.href because the resource will be fetched when clicked.
|
|
76
76
|
// But in a scenario where the resource was already visited and is in browser cache, adding
|
|
77
77
|
// the dynamic query param ensure the cache is invalidated
|
|
78
78
|
Array.from(document.querySelectorAll("a")).forEach((a) => {
|
|
79
|
-
visitNodeAttributeAsUrl(a, "href")
|
|
80
|
-
})
|
|
79
|
+
visitNodeAttributeAsUrl(a, "href");
|
|
80
|
+
});
|
|
81
81
|
// About iframes:
|
|
82
82
|
// - By default iframe itself and everything inside trigger a parent page full-reload
|
|
83
83
|
// - Adding [hot-accept] on the iframe means parent page won't reload when iframe full/hot reload
|
|
@@ -85,49 +85,49 @@ export const getDOMNodesUsingUrl = (urlToReload) => {
|
|
|
85
85
|
// you must put import.meta.hot.decline() for code involved in communication.
|
|
86
86
|
// (both in parent and iframe)
|
|
87
87
|
Array.from(document.querySelectorAll("img")).forEach((img) => {
|
|
88
|
-
visitNodeAttributeAsUrl(img, "src")
|
|
89
|
-
const srcset = img.srcset
|
|
88
|
+
visitNodeAttributeAsUrl(img, "src");
|
|
89
|
+
const srcset = img.srcset;
|
|
90
90
|
if (srcset) {
|
|
91
|
-
const srcCandidates = parseSrcSet(srcset)
|
|
91
|
+
const srcCandidates = parseSrcSet(srcset);
|
|
92
92
|
srcCandidates.forEach((srcCandidate) => {
|
|
93
|
-
const url = new URL(srcCandidate.specifier, `${window.location.href}`)
|
|
93
|
+
const url = new URL(srcCandidate.specifier, `${window.location.href}`);
|
|
94
94
|
if (shouldReloadUrl(url)) {
|
|
95
|
-
srcCandidate.specifier = injectQuery(url, { hmr: Date.now() })
|
|
95
|
+
srcCandidate.specifier = injectQuery(url, { hmr: Date.now() });
|
|
96
96
|
}
|
|
97
|
-
})
|
|
97
|
+
});
|
|
98
98
|
nodes.push({
|
|
99
99
|
node: img,
|
|
100
100
|
reload: () => {
|
|
101
|
-
img.srcset = stringifySrcSet(srcCandidates)
|
|
101
|
+
img.srcset = stringifySrcSet(srcCandidates);
|
|
102
102
|
},
|
|
103
|
-
})
|
|
103
|
+
});
|
|
104
104
|
}
|
|
105
|
-
})
|
|
105
|
+
});
|
|
106
106
|
Array.from(document.querySelectorAll("source")).forEach((source) => {
|
|
107
|
-
visitNodeAttributeAsUrl(source, "src")
|
|
108
|
-
})
|
|
107
|
+
visitNodeAttributeAsUrl(source, "src");
|
|
108
|
+
});
|
|
109
109
|
// svg image tag
|
|
110
110
|
Array.from(document.querySelectorAll("image")).forEach((image) => {
|
|
111
|
-
visitNodeAttributeAsUrl(image, "href")
|
|
112
|
-
})
|
|
111
|
+
visitNodeAttributeAsUrl(image, "href");
|
|
112
|
+
});
|
|
113
113
|
// svg use
|
|
114
114
|
Array.from(document.querySelectorAll("use")).forEach((use) => {
|
|
115
|
-
visitNodeAttributeAsUrl(use, "href")
|
|
116
|
-
})
|
|
117
|
-
return nodes
|
|
118
|
-
}
|
|
115
|
+
visitNodeAttributeAsUrl(use, "href");
|
|
116
|
+
});
|
|
117
|
+
return nodes;
|
|
118
|
+
};
|
|
119
119
|
|
|
120
120
|
export const reloadJsImport = async (url) => {
|
|
121
|
-
const urlWithHmr = injectQuery(url, { hmr: Date.now() })
|
|
122
|
-
const namespace = await import(urlWithHmr)
|
|
123
|
-
return namespace
|
|
124
|
-
}
|
|
121
|
+
const urlWithHmr = injectQuery(url, { hmr: Date.now() });
|
|
122
|
+
const namespace = await import(urlWithHmr);
|
|
123
|
+
return namespace;
|
|
124
|
+
};
|
|
125
125
|
|
|
126
126
|
export const reloadAllCss = () => {
|
|
127
|
-
const links = Array.from(document.getElementsByTagName("link"))
|
|
127
|
+
const links = Array.from(document.getElementsByTagName("link"));
|
|
128
128
|
links.forEach((link) => {
|
|
129
129
|
if (link.rel === "stylesheet") {
|
|
130
|
-
link.href = injectQuery(link.href, { hmr: Date.now() })
|
|
130
|
+
link.href = injectQuery(link.href, { hmr: Date.now() });
|
|
131
131
|
}
|
|
132
|
-
})
|
|
133
|
-
}
|
|
132
|
+
});
|
|
133
|
+
};
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
export const compareTwoUrlPaths = (url, otherUrl) => {
|
|
2
2
|
if (url === otherUrl) {
|
|
3
|
-
return true
|
|
3
|
+
return true;
|
|
4
4
|
}
|
|
5
|
-
const urlObject = new URL(url)
|
|
6
|
-
const otherUrlObject = new URL(otherUrl)
|
|
5
|
+
const urlObject = new URL(url);
|
|
6
|
+
const otherUrlObject = new URL(otherUrl);
|
|
7
7
|
if (urlObject.origin !== otherUrlObject.origin) {
|
|
8
|
-
return false
|
|
8
|
+
return false;
|
|
9
9
|
}
|
|
10
10
|
if (urlObject.pathname !== otherUrlObject.pathname) {
|
|
11
|
-
return false
|
|
11
|
+
return false;
|
|
12
12
|
}
|
|
13
|
-
return true
|
|
14
|
-
}
|
|
13
|
+
return true;
|
|
14
|
+
};
|
|
15
15
|
|
|
16
16
|
export const injectQuery = (url, query) => {
|
|
17
|
-
const urlObject = new URL(url)
|
|
18
|
-
const { searchParams } = urlObject
|
|
17
|
+
const urlObject = new URL(url);
|
|
18
|
+
const { searchParams } = urlObject;
|
|
19
19
|
Object.keys(query).forEach((key) => {
|
|
20
|
-
searchParams.set(key, query[key])
|
|
21
|
-
})
|
|
22
|
-
return String(urlObject)
|
|
23
|
-
}
|
|
20
|
+
searchParams.set(key, query[key]);
|
|
21
|
+
});
|
|
22
|
+
return String(urlObject);
|
|
23
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsenvPluginHmr } from "./jsenv_plugin_hmr.js"
|
|
2
|
-
import { jsenvPluginAutoreloadClient } from "./jsenv_plugin_autoreload_client.js"
|
|
3
|
-
import { jsenvPluginAutoreloadServer } from "./jsenv_plugin_autoreload_server.js"
|
|
1
|
+
import { jsenvPluginHmr } from "./jsenv_plugin_hmr.js";
|
|
2
|
+
import { jsenvPluginAutoreloadClient } from "./jsenv_plugin_autoreload_client.js";
|
|
3
|
+
import { jsenvPluginAutoreloadServer } from "./jsenv_plugin_autoreload_server.js";
|
|
4
4
|
|
|
5
5
|
export const jsenvPluginAutoreload = ({
|
|
6
6
|
clientFileChangeCallbackList,
|
|
@@ -13,5 +13,5 @@ export const jsenvPluginAutoreload = ({
|
|
|
13
13
|
clientFileChangeCallbackList,
|
|
14
14
|
clientFilesPruneCallbackList,
|
|
15
15
|
}),
|
|
16
|
-
]
|
|
17
|
-
}
|
|
16
|
+
];
|
|
17
|
+
};
|
|
@@ -3,26 +3,26 @@ import {
|
|
|
3
3
|
stringifyHtmlAst,
|
|
4
4
|
injectHtmlNodeAsEarlyAsPossible,
|
|
5
5
|
createHtmlNode,
|
|
6
|
-
} from "@jsenv/ast"
|
|
6
|
+
} from "@jsenv/ast";
|
|
7
7
|
|
|
8
8
|
export const jsenvPluginAutoreloadClient = () => {
|
|
9
9
|
const autoreloadClientFileUrl = new URL(
|
|
10
10
|
"./client/autoreload.js",
|
|
11
11
|
import.meta.url,
|
|
12
|
-
).href
|
|
12
|
+
).href;
|
|
13
13
|
|
|
14
14
|
return {
|
|
15
15
|
name: "jsenv:autoreload_client",
|
|
16
16
|
appliesDuring: "dev",
|
|
17
17
|
transformUrlContent: {
|
|
18
18
|
html: (htmlUrlInfo, context) => {
|
|
19
|
-
const htmlAst = parseHtmlString(htmlUrlInfo.content)
|
|
19
|
+
const htmlAst = parseHtmlString(htmlUrlInfo.content);
|
|
20
20
|
const [autoreloadClientReference] = context.referenceUtils.inject({
|
|
21
21
|
type: "script",
|
|
22
22
|
subtype: "js_module",
|
|
23
23
|
expectedType: "js_module",
|
|
24
24
|
specifier: autoreloadClientFileUrl,
|
|
25
|
-
})
|
|
25
|
+
});
|
|
26
26
|
injectHtmlNodeAsEarlyAsPossible(
|
|
27
27
|
htmlAst,
|
|
28
28
|
createHtmlNode({
|
|
@@ -31,12 +31,12 @@ export const jsenvPluginAutoreloadClient = () => {
|
|
|
31
31
|
src: autoreloadClientReference.generatedSpecifier,
|
|
32
32
|
}),
|
|
33
33
|
"jsenv:autoreload_client",
|
|
34
|
-
)
|
|
35
|
-
const htmlModified = stringifyHtmlAst(htmlAst)
|
|
34
|
+
);
|
|
35
|
+
const htmlModified = stringifyHtmlAst(htmlAst);
|
|
36
36
|
return {
|
|
37
37
|
content: htmlModified,
|
|
38
|
-
}
|
|
38
|
+
};
|
|
39
39
|
},
|
|
40
40
|
},
|
|
41
|
-
}
|
|
42
|
-
}
|
|
41
|
+
};
|
|
42
|
+
};
|