From 42fd8cd3560047c88a2167a4d5c5845dd81eb3ec Mon Sep 17 00:00:00 2001 From: Martin Hafskjold Thoresen Date: Sat, 11 Jan 2025 01:01:10 +0100 Subject: Add styling and hot reload --- src/hot_reload.js | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/hot_reload.js (limited to 'src/hot_reload.js') diff --git a/src/hot_reload.js b/src/hot_reload.js new file mode 100644 index 0000000..0777380 --- /dev/null +++ b/src/hot_reload.js @@ -0,0 +1,81 @@ +const WS_RETRY_MS = 1_000; + +function refetchCSS(file) { + const node = Array.from(document.head.childNodes).find( + (n) => n.href && n.href.includes(file), + ); + if (!node) { + console.warn("Could not find node", file); + console.log(Array.from(document.head.childNodes)); + return; + } + const url = new URL(node.href); + url.searchParams.set("v", parseInt(url.searchParams.get("v") || "0") + 1); + + const n2 = node.cloneNode(); + n2.href = url.toString(); + document.head.appendChild(n2); + setTimeout(() => { + document.head.removeChild(node); + }, 100); +} + +let __file_to_module = {}; +function refetchJS(file) { + if (file in __file_to_module) { + const o = __file_to_module[file]; + if ("__cleanup" in o) { + o.__cleanup(); + } else { + console.warn("no cleanup"); + } + } + import(`/static/${file}?v=${Date.now()}`) + .then((m) => { + __file_to_module[file] = m; + }) + .catch((e) => { + console.error(e); + }); + return; +} + +function connect() { + console.log("try to connect through websocket"); + const ws = new WebSocket(`ws://${window.location.host}/dev-hr/ws`); + + const file2timeout = new Map(); + ws.addEventListener("message", (msg) => { + const file = msg.data; // the path to a changed file relative to `static/`. + if (file2timeout.has(file)) clearTimeout(file2timeout.get(file)); + file2timeout.set( + file, + setTimeout(() => { + if (file.slice(-4) === ".css") refetchCSS(file); + else if (file.slice(-3) === ".js") refetchJS(file); + else console.warn("unknown file extension", file); + }, 100), + ); + }); + + ws.addEventListener("open", () => { + console.log("websocket connected"); + }); + + ws.addEventListener("close", () => { + console.log("websocket disconnected"); + setTimeout(() => { + try { + connect(); + } catch (e) { + console.error(e); + } + }, WS_RETRY_MS); + }); + + ws.addEventListener("error", (e) => { + console.error(e); + ws.close(); + }); +} +setTimeout(() => connect(), WS_RETRY_MS); -- cgit v1.2.3