diff --git a/client/bun.lockb b/client/bun.lockb deleted file mode 100755 index b7bf71a..0000000 Binary files a/client/bun.lockb and /dev/null differ diff --git a/client/deno.json b/client/deno.json new file mode 100644 index 0000000..99389ae --- /dev/null +++ b/client/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "dev": "deno run -A npm:vite", + "build": "deno run -A npm:vite build", + "preview": "deno run -A npm:vite preview", + "serve": "deno run --allow-net --allow-read https://deno.land/std@0.157.0/http/file_server.ts dist/" + } +} diff --git a/client/deno.lock b/client/deno.lock new file mode 100644 index 0000000..6ee4a70 --- /dev/null +++ b/client/deno.lock @@ -0,0 +1,240 @@ +{ + "version": "3", + "packages": { + "specifiers": { + "npm:vite@^5.0.8": "npm:vite@5.2.2" + }, + "npm": { + "@esbuild/aix-ppc64@0.20.2": { + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "dependencies": {} + }, + "@esbuild/android-arm64@0.20.2": { + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "dependencies": {} + }, + "@esbuild/android-arm@0.20.2": { + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "dependencies": {} + }, + "@esbuild/android-x64@0.20.2": { + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "dependencies": {} + }, + "@esbuild/darwin-arm64@0.20.2": { + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "dependencies": {} + }, + "@esbuild/darwin-x64@0.20.2": { + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "dependencies": {} + }, + "@esbuild/freebsd-arm64@0.20.2": { + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "dependencies": {} + }, + "@esbuild/freebsd-x64@0.20.2": { + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "dependencies": {} + }, + "@esbuild/linux-arm64@0.20.2": { + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "dependencies": {} + }, + "@esbuild/linux-arm@0.20.2": { + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "dependencies": {} + }, + "@esbuild/linux-ia32@0.20.2": { + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "dependencies": {} + }, + "@esbuild/linux-loong64@0.20.2": { + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "dependencies": {} + }, + "@esbuild/linux-mips64el@0.20.2": { + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "dependencies": {} + }, + "@esbuild/linux-ppc64@0.20.2": { + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "dependencies": {} + }, + "@esbuild/linux-riscv64@0.20.2": { + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "dependencies": {} + }, + "@esbuild/linux-s390x@0.20.2": { + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "dependencies": {} + }, + "@esbuild/linux-x64@0.20.2": { + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "dependencies": {} + }, + "@esbuild/netbsd-x64@0.20.2": { + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "dependencies": {} + }, + "@esbuild/openbsd-x64@0.20.2": { + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "dependencies": {} + }, + "@esbuild/sunos-x64@0.20.2": { + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "dependencies": {} + }, + "@esbuild/win32-arm64@0.20.2": { + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "dependencies": {} + }, + "@esbuild/win32-ia32@0.20.2": { + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "dependencies": {} + }, + "@esbuild/win32-x64@0.20.2": { + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "dependencies": {} + }, + "@rollup/rollup-android-arm-eabi@4.13.0": { + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "dependencies": {} + }, + "@rollup/rollup-android-arm64@4.13.0": { + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "dependencies": {} + }, + "@rollup/rollup-darwin-arm64@4.13.0": { + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "dependencies": {} + }, + "@rollup/rollup-darwin-x64@4.13.0": { + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "dependencies": {} + }, + "@rollup/rollup-linux-arm-gnueabihf@4.13.0": { + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "dependencies": {} + }, + "@rollup/rollup-linux-arm64-gnu@4.13.0": { + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "dependencies": {} + }, + "@rollup/rollup-linux-arm64-musl@4.13.0": { + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "dependencies": {} + }, + "@rollup/rollup-linux-riscv64-gnu@4.13.0": { + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "dependencies": {} + }, + "@rollup/rollup-linux-x64-gnu@4.13.0": { + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "dependencies": {} + }, + "@rollup/rollup-linux-x64-musl@4.13.0": { + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "dependencies": {} + }, + "@rollup/rollup-win32-arm64-msvc@4.13.0": { + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "dependencies": {} + }, + "@rollup/rollup-win32-ia32-msvc@4.13.0": { + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "dependencies": {} + }, + "@rollup/rollup-win32-x64-msvc@4.13.0": { + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "dependencies": {} + }, + "@types/estree@1.0.5": { + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dependencies": {} + }, + "esbuild@0.20.2": { + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dependencies": { + "@esbuild/aix-ppc64": "@esbuild/aix-ppc64@0.20.2", + "@esbuild/android-arm": "@esbuild/android-arm@0.20.2", + "@esbuild/android-arm64": "@esbuild/android-arm64@0.20.2", + "@esbuild/android-x64": "@esbuild/android-x64@0.20.2", + "@esbuild/darwin-arm64": "@esbuild/darwin-arm64@0.20.2", + "@esbuild/darwin-x64": "@esbuild/darwin-x64@0.20.2", + "@esbuild/freebsd-arm64": "@esbuild/freebsd-arm64@0.20.2", + "@esbuild/freebsd-x64": "@esbuild/freebsd-x64@0.20.2", + "@esbuild/linux-arm": "@esbuild/linux-arm@0.20.2", + "@esbuild/linux-arm64": "@esbuild/linux-arm64@0.20.2", + "@esbuild/linux-ia32": "@esbuild/linux-ia32@0.20.2", + "@esbuild/linux-loong64": "@esbuild/linux-loong64@0.20.2", + "@esbuild/linux-mips64el": "@esbuild/linux-mips64el@0.20.2", + "@esbuild/linux-ppc64": "@esbuild/linux-ppc64@0.20.2", + "@esbuild/linux-riscv64": "@esbuild/linux-riscv64@0.20.2", + "@esbuild/linux-s390x": "@esbuild/linux-s390x@0.20.2", + "@esbuild/linux-x64": "@esbuild/linux-x64@0.20.2", + "@esbuild/netbsd-x64": "@esbuild/netbsd-x64@0.20.2", + "@esbuild/openbsd-x64": "@esbuild/openbsd-x64@0.20.2", + "@esbuild/sunos-x64": "@esbuild/sunos-x64@0.20.2", + "@esbuild/win32-arm64": "@esbuild/win32-arm64@0.20.2", + "@esbuild/win32-ia32": "@esbuild/win32-ia32@0.20.2", + "@esbuild/win32-x64": "@esbuild/win32-x64@0.20.2" + } + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dependencies": {} + }, + "nanoid@3.3.7": { + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dependencies": {} + }, + "picocolors@1.0.0": { + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dependencies": {} + }, + "postcss@8.4.38": { + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dependencies": { + "nanoid": "nanoid@3.3.7", + "picocolors": "picocolors@1.0.0", + "source-map-js": "source-map-js@1.2.0" + } + }, + "rollup@4.13.0": { + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "dependencies": { + "@rollup/rollup-android-arm-eabi": "@rollup/rollup-android-arm-eabi@4.13.0", + "@rollup/rollup-android-arm64": "@rollup/rollup-android-arm64@4.13.0", + "@rollup/rollup-darwin-arm64": "@rollup/rollup-darwin-arm64@4.13.0", + "@rollup/rollup-darwin-x64": "@rollup/rollup-darwin-x64@4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "@rollup/rollup-linux-arm-gnueabihf@4.13.0", + "@rollup/rollup-linux-arm64-gnu": "@rollup/rollup-linux-arm64-gnu@4.13.0", + "@rollup/rollup-linux-arm64-musl": "@rollup/rollup-linux-arm64-musl@4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "@rollup/rollup-linux-riscv64-gnu@4.13.0", + "@rollup/rollup-linux-x64-gnu": "@rollup/rollup-linux-x64-gnu@4.13.0", + "@rollup/rollup-linux-x64-musl": "@rollup/rollup-linux-x64-musl@4.13.0", + "@rollup/rollup-win32-arm64-msvc": "@rollup/rollup-win32-arm64-msvc@4.13.0", + "@rollup/rollup-win32-ia32-msvc": "@rollup/rollup-win32-ia32-msvc@4.13.0", + "@rollup/rollup-win32-x64-msvc": "@rollup/rollup-win32-x64-msvc@4.13.0", + "@types/estree": "@types/estree@1.0.5", + "fsevents": "fsevents@2.3.3" + } + }, + "source-map-js@1.2.0": { + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dependencies": {} + }, + "vite@5.2.2": { + "integrity": "sha512-FWZbz0oSdLq5snUI0b6sULbz58iXFXdvkZfZWR/F0ZJuKTSPO7v72QPXt6KqYeMFb0yytNp6kZosxJ96Nr/wDQ==", + "dependencies": { + "esbuild": "esbuild@0.20.2", + "fsevents": "fsevents@2.3.3", + "postcss": "postcss@8.4.38", + "rollup": "rollup@4.13.0" + } + } + } + }, + "remote": {} +} diff --git a/client/tsconfig.json b/client/tsconfig.json deleted file mode 100644 index 75abdef..0000000 --- a/client/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"] -} diff --git a/flake.nix b/flake.nix index 8e669bc..2df695a 100644 --- a/flake.nix +++ b/flake.nix @@ -9,9 +9,7 @@ in { devShell.${system} = pkgs.mkShell rec { buildInputs = [ - pkgs.nodejs-18_x - pkgs.nodePackages.pnpm - pkgs.bun + pkgs.deno ]; }; }; diff --git a/server/bun.lockb b/server/bun.lockb deleted file mode 100755 index 9605651..0000000 Binary files a/server/bun.lockb and /dev/null differ diff --git a/server/deno.json b/server/deno.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/server/deno.json @@ -0,0 +1 @@ +{} diff --git a/server/index.ts b/server/index.ts index e5e8b35..cacea3e 100644 --- a/server/index.ts +++ b/server/index.ts @@ -1,63 +1,68 @@ -import { type ServerWebSocket } from "bun" - type WebsocketData = { clientId: string } type Message = + | { type: 'welcome', id: string } | { type: 'presence-information', others: number } | { type: 'ripple', position: [number, number], maxRadius: number } -const clients: Map> = new Map() +const clients: Map = new Map() -const server = Bun.serve({ - fetch(req, server) { - // TODO Allow creating private ponds - server.upgrade(req, { - data: { - clientId: crypto.randomUUID() - } +const _server = Deno.serve((req) => { + if (req.headers.get("upgrade") !== "websocket") { + return new Response(null, { status: 501 }) + } + + const { socket, response } = Deno.upgradeWebSocket(req) + // TODO Allow creating private ponds + const clientId = crypto.randomUUID() + console.log('generated clientId', clientId) + + socket.addEventListener("open", () => { + // register newly connected client and tell them how many other people are there + console.log('Connection opened', clientId, clients) + socket.send(JSON.stringify({ + type: 'welcome', + id: clientId + })) + const enterNotice = JSON.stringify({ + type: 'presence-information', + others: clients.size, }) - }, - websocket: { - open(ws) { - // register newly connected client and tell them how many other people are there - console.log('Connection opened', ws.data.clientId) - const enterNotice = JSON.stringify({ - type: 'presence-information', - others: clients.size, - }) - clients.set(ws.data.clientId, ws) - for (const client of clients.values()) { - 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) - } + clients.set(clientId, socket) + for (const client of clients.values()) { + client.send(enterNotice) + } + }) + + socket.addEventListener("message", (event) => { + const message = `${event.data}` + // broadcast message to all other clients + // TODO: Validate message shape + const msg = JSON.parse(`${message}`) + console.log('Relaying message from', clientId, msg) + for (const [uuid, client] of clients.entries()) { + if (uuid !== clientId) { + client.send(message) } } - }, -}) + }) -console.log(`Server running on ${server.hostname}:${server.port}`) + socket.addEventListener("close", () => { + // remove client from list of registered clients and tell other clients how many people are there + console.log('Connection closed', clientId, clients) + clients.delete(clientId) + const leaveNotice = JSON.stringify({ + type: 'presence-information', + others: clients.size - 1, + }) + for (const [uuid, client] of clients.entries()) { + if (uuid !== clientId) { + client.send(leaveNotice) + } + } + }) + + return response +}) diff --git a/server/tsconfig.json b/server/tsconfig.json deleted file mode 100644 index dcd8fc5..0000000 --- a/server/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "lib": ["ESNext"], - "target": "ESNext", - "module": "ESNext", - "moduleDetection": "force", - "jsx": "react-jsx", - "allowJs": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "noEmit": true, - - /* Linting */ - "skipLibCheck": true, - "strict": true, - "noFallthroughCasesInSwitch": true, - "forceConsistentCasingInFileNames": true - } -}