import {Configure, Transpile, Extension, Root} from "./run-serve.tsx"; import * as Collect from "./hmr-static.tsx"; const SocketsLive:Set = new Set(); const SocketsSend =(inData:string)=>{ for (const socket of SocketsLive){ socket.send(inData); } } Configure({ SWCOp: { sourceMaps: "inline", minify: false, jsc: { target:"es2022", parser: { syntax: "typescript", tsx: true, }, transform: { react: { runtime: "automatic" } } } }, Remap: (inImports, inConfig)=> { inImports["react-original"] = inImports["react"]; inImports["react"] = `/>able/hmr-react.tsx`; inImports["signals-original"] = inImports["@preact/signals"]; inImports["@preact/signals"] = `/>able/hmr-signal.tsx`; return inImports; }, async Extra(inReq, inURL, inExt, inMap, inConfig) { if(!inURL.pathname.startsWith(encodeURI("/>"))) { if(Transpile.Check(inExt) && !inURL.searchParams.get("reload")) { // we dont need to add ?reload= because this fetch is by way the file system not the hosted url const [local, foreign] = await Collect.FileExports(Root+inURL.pathname); const code =` import {FileListen} from ">able/hmr-listen.tsx"; import * as Import from "${inURL.pathname}?reload=0"; ${ local.map(m=>`let proxy_${m} = Import.${m}; export { proxy_${m} as ${m} };`).join("\n") } FileListen("${inURL.pathname}", (updatedModule)=> { ${ local.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n") } }); ${ foreign.join(";\n") } ` return new Response(code, {headers:{"content-type":"application/javascript"}}); } if(inReq.headers.get("upgrade") == "websocket") { try { const { response, socket } = Deno.upgradeWebSocket(inReq); socket.onopen = () => SocketsLive.add(socket); socket.onclose = () => SocketsLive.delete(socket); socket.onmessage = (e) => {}; socket.onerror = (e) => console.log("Socket errored:", e); return response; } catch(e){ /**/ } } } } }); const Watcher =async()=> { let blocking = false; const filesChanged:Map = new Map(); for await (const event of Deno.watchFs(Deno.cwd())) { event.paths.forEach( path => filesChanged.set(path, event.kind) ); if(!blocking) { blocking = true; setTimeout(async()=> { for await (const [path, action] of filesChanged) { if(Transpile.Check(Extension(path))) { const key = path.substring(Deno.cwd().length).replaceAll("\\", "/"); if(action != "remove") { const tsx = await Transpile.Fetch(Root+key, key, true); tsx && SocketsSend(key); } else { Transpile.Cache.delete(key); } } } filesChanged.clear(); blocking = false; } , 1000); } } } Watcher();