From 62dcb0f297a664b5fa6e1c1332d1d5db13aed00d Mon Sep 17 00:00:00 2001
From: creations <creations@creations.works>
Date: Thu, 27 Feb 2025 11:57:09 -0500
Subject: [PATCH] update to support websockets, update depends and gitignore

---
 .gitignore              |  2 +-
 package.json            | 18 ++++++++--------
 src/server.ts           | 47 +++++++++++++++++++++++------------------
 src/webSocketHandler.ts | 34 +++++++++++++++++++++++++++++
 4 files changed, 70 insertions(+), 31 deletions(-)
 create mode 100644 src/webSocketHandler.ts

diff --git a/.gitignore b/.gitignore
index fd53c03..58b5bae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
 /node_modules
-bun.lockb
+bun.lock
diff --git a/package.json b/package.json
index de82eef..1931822 100644
--- a/package.json
+++ b/package.json
@@ -10,22 +10,22 @@
 		"cleanup": "rm -rf logs node_modules bun.lockdb"
 	},
 	"devDependencies": {
-		"@eslint/js": "^9.18.0",
-		"@types/bun": "^1.1.16",
+		"@eslint/js": "^9.21.0",
+		"@types/bun": "^1.2.4",
 		"@types/ejs": "^3.1.5",
-		"@typescript-eslint/eslint-plugin": "^8.20.0",
-		"@typescript-eslint/parser": "^8.20.0",
-		"eslint": "^9.18.0",
-		"eslint-plugin-prettier": "^5.2.2",
+		"@typescript-eslint/eslint-plugin": "^8.25.0",
+		"@typescript-eslint/parser": "^8.25.0",
+		"eslint": "^9.21.0",
+		"eslint-plugin-prettier": "^5.2.3",
 		"eslint-plugin-promise": "^7.2.1",
 		"eslint-plugin-simple-import-sort": "^12.1.1",
 		"eslint-plugin-unicorn": "^56.0.1",
 		"eslint-plugin-unused-imports": "^4.1.4",
-		"globals": "^15.14.0",
-		"prettier": "^3.4.2"
+		"globals": "^15.15.0",
+		"prettier": "^3.5.2"
 	},
 	"peerDependencies": {
-		"typescript": "^5.7.2"
+		"typescript": "^5.7.3"
 	},
 	"dependencies": {
 		"ejs": "^3.1.10"
diff --git a/src/server.ts b/src/server.ts
index b8b3f7a..627edc7 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -8,6 +8,8 @@ import {
 } from "bun";
 import { resolve } from "path";
 
+import { webSocketHandler } from "@/WebSocketHandler";
+
 class ServerHandler {
 	private router: FileSystemRouter;
 
@@ -27,6 +29,11 @@ class ServerHandler {
 			port: this.port,
 			hostname: this.host,
 			fetch: this.handleRequest.bind(this),
+			websocket: {
+				open: webSocketHandler.handleOpen.bind(webSocketHandler),
+				message: webSocketHandler.handleMessage.bind(webSocketHandler),
+				close: webSocketHandler.handleClose.bind(webSocketHandler),
+			},
 		});
 
 		logger.info(
@@ -195,29 +202,27 @@ class ServerHandler {
 			);
 		}
 
-		queueMicrotask(() => {
-			const headers: Headers = response.headers;
-			let ip: string | null = server.requestIP(request)?.address || null;
+		const headers: Headers = response.headers;
+		let ip: string | null = server.requestIP(request)?.address || null;
 
-			if (!ip) {
-				ip =
-					headers.get("CF-Connecting-IP") ||
-					headers.get("X-Real-IP") ||
-					headers.get("X-Forwarded-For") ||
-					null;
-			}
+		if (!ip) {
+			ip =
+				headers.get("CF-Connecting-IP") ||
+				headers.get("X-Real-IP") ||
+				headers.get("X-Forwarded-For") ||
+				null;
+		}
 
-			logger.custom(
-				`[${request.method}]`,
-				`(${response.status})`,
-				[
-					request.url,
-					`${(performance.now() - request.startPerf).toFixed(2)}ms`,
-					ip || "unknown",
-				],
-				"90",
-			);
-		});
+		logger.custom(
+			`[${request.method}]`,
+			`(${response.status})`,
+			[
+				request.url,
+				`${(performance.now() - request.startPerf).toFixed(2)}ms`,
+				ip || "unknown",
+			],
+			"90",
+		);
 
 		return response;
 	}
diff --git a/src/webSocketHandler.ts b/src/webSocketHandler.ts
new file mode 100644
index 0000000..48c37b5
--- /dev/null
+++ b/src/webSocketHandler.ts
@@ -0,0 +1,34 @@
+import { logger } from "@helpers/logger";
+import { type ServerWebSocket } from "bun";
+
+class WebSocketHandler {
+	public handleMessage(ws: ServerWebSocket, message: string): void {
+		logger.info(`WebSocket received: ${message}`);
+		try {
+			ws.send(`You said: ${message}`);
+		} catch (error) {
+			logger.error(`WebSocket send error: ${(error as Error).message}`);
+		}
+	}
+
+	public handleOpen(ws: ServerWebSocket): void {
+		logger.info("WebSocket connection opened.");
+		try {
+			ws.send("Welcome to the WebSocket server!");
+		} catch (error) {
+			logger.error(`WebSocket send error: ${(error as Error).message}`);
+		}
+	}
+
+	public handleClose(
+		ws: ServerWebSocket,
+		code: number,
+		reason: string,
+	): void {
+		logger.warn(`WebSocket closed with code ${code}, reason: ${reason}`);
+	}
+}
+
+const webSocketHandler: WebSocketHandler = new WebSocketHandler();
+
+export { webSocketHandler };