import { contentType } from "jsr:@std/media-types"; // Parse the port from the command-line arguments, defaulting to 8000 const port = parseInt(Deno.args[0] || "8000", 10); const sockets: WebSocket[] = []; const connect = ``; const bundle = await fetch(import.meta.resolve("./bundle.js")).then(r=>r.text()); let html: string; try { html = Deno.readTextFileSync("./index.html").replace("
", ""+connect); } catch (_) { html = ` ${connect} `; } function extension(path: string): string { // Remove trailing slash if it exists const normalizedPath = path.endsWith("/") ? path.slice(0, -1) : path; // Get the last part of the path const lastPart = normalizedPath.split("/").pop() || ""; // Check if the last part contains a "." return lastPart.split(".")[1] || ""; } // Start the HTTP server using Deno.serve Deno.serve({ port }, async (req: Request) => { const url = new URL(req.url); // Handle WebSocket connections if (url.pathname === "/ws") { const { socket, response } = Deno.upgradeWebSocket(req); sockets.push(socket); return response; } // Serve static files or the predefined HTML for non-file routes const path = new URL(req.url).pathname; const ext = extension(path); // Serve the predefined HTML for non-file routes if (!ext) { return new Response(html, { headers: { "Content-Type": "text/html" }, }); } try { const file = await Deno.open("." + path, { read: true }); return new Response(file.readable, { headers: { "Content-Type": contentType(ext) || "application/javascript" }, }); } catch (err) { if (err instanceof Deno.errors.NotFound) { return new Response("File not found", { status: 404 }); } else { return new Response("Internal server error", { status: 500 }); } } }); // Start watching for file changes const watcher = Deno.watchFs("."); for await (const event of watcher) { if (event.kind === "modify") { for (const ws of sockets) { if (ws.readyState === WebSocket.OPEN) { ws.send("reload"); continue; } } } }