From 287c19fc0def8c642f91d3cda07ba4683e3d2760 Mon Sep 17 00:00:00 2001 From: Daniel McCrystal Date: Mon, 18 Aug 2025 23:31:28 -0400 Subject: [PATCH] cooking with websockets --- .dockerignore | 10 -- Dockerfile | 11 -- packages/client/src/app.tsx | 53 +++++---- packages/client/src/components/Game.tsx | 46 +++++--- packages/client/src/routes/[game]/index.tsx | 2 +- packages/client/src/style.css | 1 - .../migration.sql | 15 +++ packages/server/db/schema.prisma | 4 +- packages/server/package.json | 3 + packages/server/src/games/simple.ts | 109 +++++++++++++++--- packages/server/src/index.ts | 2 +- pnpm-lock.yaml | 30 +++++ 12 files changed, 205 insertions(+), 81 deletions(-) delete mode 100644 .dockerignore delete mode 100644 Dockerfile create mode 100644 packages/server/db/migrations/20250819011115_gamestate_nullable/migration.sql diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 27b82d1..0000000 --- a/.dockerignore +++ /dev/null @@ -1,10 +0,0 @@ -node_modules -Dockerfile -Makefile -README.md -.output -.vinxi -.git -.gitignore -.dockerignore -*.db \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 9933f5b..0000000 --- a/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM node:22-alpine -WORKDIR /app -EXPOSE 3000 - -COPY package.json ./ -RUN --mount=type=cache,target=/root/.npm npm install - -COPY . . -RUN --mount=type=cache,target=/app/.vinxi npm run build - -CMD ["npm", "run", "start"] diff --git a/packages/client/src/app.tsx b/packages/client/src/app.tsx index 6e22a44..09de5f3 100644 --- a/packages/client/src/app.tsx +++ b/packages/client/src/app.tsx @@ -34,30 +34,33 @@ const Profile = () => { ); }; -const App = () => ( - ( - <> - {props.children} - +const App = () => { + api.whoami.post(); + return ( + ( + <> + {props.children} + - {/* Version */} - - {"v" + pkg.version} - - - )} - > - import("./routes/index"))} /> - import("./routes/[game]/index"))} - /> - import("./routes/[game]/[instance]"))} - /> - -); + {/* Version */} + + {"v" + pkg.version} + + + )} + > + import("./routes/index"))} /> + import("./routes/[game]/index"))} + /> + import("./routes/[game]/[instance]"))} + /> + + ); +}; -api.whoami.post().then(() => render(App, document.getElementById("app")!)); +render(App, document.getElementById("app")!); diff --git a/packages/client/src/components/Game.tsx b/packages/client/src/components/Game.tsx index 588ff47..de4e762 100644 --- a/packages/client/src/components/Game.tsx +++ b/packages/client/src/components/Game.tsx @@ -1,4 +1,12 @@ -import { Accessor, createContext, createResource, Show } from "solid-js"; +import { + Accessor, + createContext, + createResource, + createSignal, + For, + onCleanup, + Show, +} from "solid-js"; import { GameState, Action, @@ -15,28 +23,36 @@ export const GameContext = createContext<{ }>(); export default (props: { instanceId: string }) => { - const [view, { mutate }] = createResource(() => - api - .simple(props) - .get() - .then((res) => res.data as PlayerView) - ); - const submitAction = (action: Action) => - api - .simple(props) - .post({ action }) - .then((res) => res.status == 200 && mutate(res.data as PlayerView)); + const [view, setView] = createSignal(); + const [players, setPlayers] = createSignal([]); + const ws = api.simple(props).subscribe(); + onCleanup(() => ws.close()); + ws.on("message", (evt) => { + if (evt.data.players) { + setPlayers(evt.data.players); + } + }); + + const submitAction = (action: Action) => api.simple(props).post({ action }); + + const Lobby = () => { + return ( +
+ {(player) =>

{player}

}
+
+ ); + }; return ( - + }> submitAction({ type: "draw" })} /> - + ); diff --git a/packages/client/src/routes/[game]/index.tsx b/packages/client/src/routes/[game]/index.tsx index 80588ef..30dc219 100644 --- a/packages/client/src/routes/[game]/index.tsx +++ b/packages/client/src/routes/[game]/index.tsx @@ -16,7 +16,7 @@ export default () => {

{param.game}