aboutsummaryrefslogtreecommitdiffstats
path: root/backend/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'backend/index.ts')
-rw-r--r--backend/index.ts58
1 files changed, 58 insertions, 0 deletions
diff --git a/backend/index.ts b/backend/index.ts
new file mode 100644
index 0000000..5a974d6
--- /dev/null
+++ b/backend/index.ts
@@ -0,0 +1,58 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+import express from "express";
+import http from "http";
+import {
+ createPool,
+ DatabasePoolType,
+ DatabaseTransactionConnectionType,
+ sql,
+} from "slonik";
+import * as config from "./config";
+import { ValueRecord } from "../shared-types";
+import { Server as SocketIOServer, Socket } from "socket.io";
+
+const app = express();
+
+const httpServer = http.createServer(app);
+const io = new SocketIOServer(httpServer, {
+ cors: {
+ origin: "*",
+ },
+});
+
+type Connection = DatabasePoolType | DatabaseTransactionConnectionType;
+const _connection = createPool(config.postgresConnectionString);
+
+const getCurrentValue = async (conn: Connection): Promise<ValueRecord["value"]> => {
+ return await conn.oneFirst<ValueRecord["value"]>(sql`
+ SELECT value
+ FROM state
+ `);
+};
+
+const incrementCurrentValue = async (conn: Connection): Promise<number> =>
+ await conn.transaction(async (trans) => {
+ const current = await getCurrentValue(trans);
+
+ const newValue = current + 1;
+ await trans.query(sql`
+ UPDATE state
+ SET value = ${newValue}
+ `);
+ return newValue;
+ });
+
+io.on("connection", async (socket) => {
+ console.log(`a user connected: ${socket.id}`);
+ const currentValue = await getCurrentValue(_connection);
+ socket.emit("update", currentValue);
+
+ socket.on("increment", async () => {
+ const newValue = await incrementCurrentValue(_connection);
+ io.emit("update", newValue); // broadcast
+ });
+});
+
+httpServer.listen(config.port, () => {
+ console.log(`Listening on http://localhost:${config.port}`);
+});