97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import type { Server, ServerWebSocket } from "bun";
|
|
import SSSG, { Plugin } from "..";
|
|
import * as fs from "fs";
|
|
import mime from "mime-types";
|
|
|
|
const script = `let reconnectTimeout,waitingForReconnect=!1;function connect(){console.log("[dev] connecting to dev server");var e=new WebSocket("ws://localhost:8080");e.addEventListener("message",e=>{"refresh"==e.data&&location.reload()}),e.addEventListener("open",()=>{console.log("[dev] connected"),waitingForReconnect&&location.reload()}),e.addEventListener("close",()=>{console.log("[dev] socket closed, restarting in 1s"),clearTimeout(reconnectTimeout),reconnectTimeout=setTimeout(()=>{connect(),waitingForReconnect=!0},1e3)})}window.addEventListener("load",()=>connect());`;
|
|
|
|
export default class DevPlugin extends Plugin {
|
|
build: undefined;
|
|
|
|
name = "dev";
|
|
rewriteTriggers = [];
|
|
renameTo = undefined;
|
|
longLasting = true;
|
|
server!: Server;
|
|
allConnections: ServerWebSocket<number>[] = [];
|
|
|
|
constructor(sssg: SSSG) {
|
|
super();
|
|
|
|
fs.watch(
|
|
sssg.inputFolder,
|
|
{
|
|
recursive: true,
|
|
},
|
|
async (e, f) => {
|
|
console.log("[dev] Noticed update in " + f + ", of type " + e + ".");
|
|
this.allConnections.forEach((z) => z.send("refresh"));
|
|
await sssg.build();
|
|
}
|
|
);
|
|
|
|
this.server = Bun.serve<number>({
|
|
fetch(req, server) {
|
|
const success = server.upgrade(req);
|
|
if (success) {
|
|
return undefined;
|
|
}
|
|
|
|
const url = new URL(req.url);
|
|
|
|
let cleanedPath = url.pathname;
|
|
if (cleanedPath == "/") cleanedPath = "/index.html";
|
|
if (cleanedPath.endsWith("/")) cleanedPath = cleanedPath.slice(0, -1);
|
|
|
|
let fsPath = sssg.outputFolder + cleanedPath;
|
|
|
|
if (fsPath.match(/\.\.\//g) !== null) {
|
|
return undefined;
|
|
}
|
|
let rawFile;
|
|
try {
|
|
rawFile = fs.readFileSync(fsPath);
|
|
} catch {
|
|
return new Response("404 Not Found", {
|
|
status: 404,
|
|
});
|
|
}
|
|
const type = fsPath.split(".").at(-1);
|
|
if (!type) return;
|
|
if (type == "html") {
|
|
|
|
rawFile = rawFile.toString().replace(
|
|
"<head>",
|
|
`<head><script>${script}</script>`
|
|
);
|
|
}
|
|
return new Response(rawFile, {
|
|
headers: {
|
|
"Cache-Control": "no-cache, no-store, must-revalidate",
|
|
"Pragma": "no-cache",
|
|
"Expires": "0",
|
|
"Content-Type": (mime.lookup(type) || "application/octet-stream") + "; charset=utf-8",
|
|
},
|
|
});
|
|
},
|
|
websocket: {
|
|
open: (ws) => {
|
|
ws.data = Math.random();
|
|
|
|
this.allConnections.push(ws);
|
|
},
|
|
message(ws, message) {},
|
|
close: (ws) => {
|
|
this.allConnections = this.allConnections.filter(
|
|
(z) => z.data != ws.data
|
|
);
|
|
},
|
|
},
|
|
port: 8080,
|
|
});
|
|
}
|
|
|
|
async rewriteFile(file: string, filePath: string) {
|
|
return undefined;
|
|
}
|
|
}
|