44 lines
1.5 KiB
TypeScript
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(); |