import { type ServerWebSocket } from "bun" type WebsocketData = { clientId: string } type Message = | { type: 'presence-information', others: number } | { type: 'ripple', position: [number, number], maxRadius: number } const clients: Map> = new Map() const server = Bun.serve({ fetch(req, server) { // TODO Allow creating private ponds server.upgrade(req, { data: { clientId: crypto.randomUUID() } }) }, websocket: { open(ws) { // register newly connected client and tell them how many other people are there console.log('Connection opened', ws.data.clientId) clients.set(ws.data.clientId, ws) const enterNotice = JSON.stringify({ type: 'presence-information', others: clients.size, }) for (const [uuid, client] of clients.entries()) { if (uuid !== ws.data.clientId) { client.send(enterNotice, true) } } }, message(ws, message) { // broadcast message to all other clients // TODO: Validate message shape const msg = JSON.parse(`${message}`) console.log('Relaying message from', ws.data.clientId, msg) for (const [uuid, client] of clients.entries()) { if (uuid !== ws.data.clientId) { client.send(message) } } }, close(ws, code, reason) { // remove client from list of registered clients and tell other clients how many people are there console.log('Connection closed', ws.data.clientId) clients.delete(ws.data.clientId) const leaveNotice = JSON.stringify({ type: 'presence-information', others: clients.size, }) for (const [uuid, client] of clients.entries()) { if (uuid !== ws.data.clientId) { client.send(leaveNotice, true) } } } }, }) console.log(`Server running on ${server.hostname}:${server.port}`)