gale/hmr/hmr-listen.tsx

44 lines
1.5 KiB
TypeScript

import { HMR } from "./hmr-react.tsx";
const FileListeners = new Map() as Map<string, Array<(module:unknown)=>void>>;
export const FileListen =(inPath:string, inHandler:()=>void)=>
{
const members = FileListeners.get(inPath)??[];
members.push(inHandler);
FileListeners.set(inPath, members);
};
let socket: WebSocket;
let socketTimer: number | undefined;
let reconnectAttempts = 0;
function connect() {
socket = new WebSocket("ws://" + location.host);
socket.addEventListener("open", () => {
reconnectAttempts = 0;
socketTimer = window.setInterval(() => {
if (socket.readyState === WebSocket.OPEN) socket.send("ping");
}, 5000);
});
socket.addEventListener("message", async (ev) => {
try {
const reImport = await import(location.origin + ev.data + "?reload=" + Math.random());
FileListeners.get(ev.data)?.forEach(h => h(reImport));
HMR.update();
} catch (e) {
console.error("HMR import failed for", ev.data, e);
}
});
socket.addEventListener("close", () => {
if (socketTimer) { clearInterval(socketTimer); socketTimer = undefined; }
// simple exponential backoff reconnect
reconnectAttempts++;
const delay = Math.min(30000, 500 * (2 ** (reconnectAttempts - 1)));
setTimeout(connect, delay);
});
socket.addEventListener("error", () => {
if (socketTimer) { clearInterval(socketTimer); socketTimer = undefined; }
});
}
connect();