64 lines
1.6 KiB
TypeScript
64 lines
1.6 KiB
TypeScript
import { decode } from "./protocol";
|
|
import { type Client, getOrCreateSession, getSession } from "./session";
|
|
|
|
const PORT = Number(process.env.PORT) || 4040;
|
|
|
|
const server = Bun.serve({
|
|
port: PORT,
|
|
fetch(req, server) {
|
|
const url = new URL(req.url);
|
|
if (url.pathname === "/ws") {
|
|
const upgraded = server.upgrade(req, { data: { room: null } });
|
|
if (!upgraded) {
|
|
return new Response("websocket upgrade failed", { status: 400 });
|
|
}
|
|
return;
|
|
}
|
|
return new Response("collabd running");
|
|
},
|
|
websocket: {
|
|
open(ws) {
|
|
console.debug("client connected");
|
|
},
|
|
message(ws, raw) {
|
|
const msg = decode(raw.toString());
|
|
if (!msg) return;
|
|
|
|
const client: Client = { ws };
|
|
|
|
switch (msg.type) {
|
|
case "join": {
|
|
const session = getOrCreateSession(msg.room);
|
|
ws.data.room = msg.room;
|
|
session.join(client);
|
|
console.debug(`client joined room: ${msg.room}`);
|
|
break;
|
|
}
|
|
case "leave": {
|
|
if (ws.data.room) {
|
|
const session = getSession(ws.data.room);
|
|
session?.leave(client);
|
|
ws.data.room = null;
|
|
}
|
|
break;
|
|
}
|
|
case "update": {
|
|
if (ws.data.room) {
|
|
const session = getSession(ws.data.room);
|
|
session?.applyUpdate(new Uint8Array(msg.data), client);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
},
|
|
close(ws) {
|
|
if (ws.data.room) {
|
|
const session = getSession(ws.data.room);
|
|
session?.leave({ ws });
|
|
}
|
|
console.debug("client disconnected");
|
|
},
|
|
},
|
|
});
|
|
|
|
console.log(`collabd listening on :${PORT}`);
|