try to fix websockets

This commit is contained in:
Dylan Pizzo
2026-06-11 14:32:55 -04:00
parent f0e522b039
commit 064528b178
4 changed files with 94 additions and 98 deletions
-19
View File
@@ -1,19 +0,0 @@
import { Type } from "@sinclair/typebox";
import { FirRouteInput, FirRouteOptions } from "../util/routewrap.js";
const method = "POST";
const url = "/api/webhook-gh";
const payloadT = Type.Any();
const handler = ({payload}: FirRouteInput<typeof payloadT>) => {
console.log(payload);
return {};
};
export default {
method,
url,
payloadT,
handler,
} as const satisfies FirRouteOptions<typeof payloadT>;
+1 -1
View File
@@ -9,7 +9,7 @@ const server = Fastify({
logger: true,
});
server.register(fastifyWebsocket);
server.register<any>(fastifyWebsocket, { server: server.server });
server.register(fastifyStatic, {
root: new URL("public", import.meta.url).toString().slice("file://".length),
+1 -2
View File
@@ -2,8 +2,7 @@ import echo from "./api/echo.ts";
import getAuthor from "./api/getAuthor.ts";
import getGame from "./api/getGame.ts";
import room from "./api/room.ts";
import webhook from "./api/webhook.ts";
export const routeList = [echo, webhook, getAuthor, room, getGame];
export const routeList = [echo, getAuthor, room, getGame];
export type RouteList = typeof routeList;
+92 -76
View File
@@ -1,6 +1,6 @@
import { Static, TSchema } from "@sinclair/typebox";
import { Value } from "@sinclair/typebox/value";
import { FastifyInstance, FastifyRequest, HTTPMethods } from "fastify"
import { FastifyInstance, FastifyRequest, HTTPMethods } from "fastify";
import { RouteOptions } from "fastify/types/route.js";
import { type WebSocket } from "@fastify/websocket";
@@ -9,113 +9,129 @@ type WebsocketConnection = Parameters<Defined<RouteOptions["wsHandler"]>>[0];
type URLString = string;
export type FirRouteInput<TPayloadSchema extends TSchema> = {
payload: Static<TPayloadSchema>,
}
export type FirWebsocketInput<TPayloadSchema extends TSchema> = {
socket: WebsocketConnection,
req: FastifyRequest,
payload: Static<TPayloadSchema>,
}
export type FirWebsocketHandler<TIn extends TSchema = TSchema> = {
onMessage?(input: FirWebsocketInput<TIn>): void,
onOpen?(input: {socket: WebSocket, req: FastifyRequest}): void,
onClose?(input: {socket: WebSocket, req: FastifyRequest}): void,
onError?(input: {socket: WebSocket, req: FastifyRequest, error: unknown}): void,
payload: Static<TPayloadSchema>;
};
export type FirRouteOptions<TIn extends TSchema = TSchema, TOut extends TSchema = TSchema> = {
method: HTTPMethods,
url: URLString,
payloadT: TIn,
responseT?: TOut,
} & ({
handler: (input: FirRouteInput<TIn>) => Static<TOut> | Promise<Static<TOut>>,
} | {
websocket: FirWebsocketHandler<TIn>,
})
export type FirWebsocketInput<TPayloadSchema extends TSchema> = {
socket: WebsocketConnection;
req: FastifyRequest;
payload: Static<TPayloadSchema>;
};
export type FirWebsocketHandler<TIn extends TSchema = TSchema> = {
onMessage?(input: FirWebsocketInput<TIn>): void;
onOpen?(input: { socket: WebSocket; req: FastifyRequest }): void;
onClose?(input: { socket: WebSocket; req: FastifyRequest }): void;
onError?(input: {
socket: WebSocket;
req: FastifyRequest;
error: unknown;
}): void;
};
export type FirRouteOptions<
TIn extends TSchema = TSchema,
TOut extends TSchema = TSchema,
> = {
method: HTTPMethods;
url: URLString;
payloadT: TIn;
responseT?: TOut;
} & (
| {
handler: (
input: FirRouteInput<TIn>,
) => Static<TOut> | Promise<Static<TOut>>;
}
| {
websocket: FirWebsocketHandler<TIn>;
}
);
type Defined<T> = T extends undefined ? never : T;
export const attachRoute = <TIn extends TSchema, TOut extends TSchema>(server: FastifyInstance, routeOptions: FirRouteOptions<TIn, TOut>) => {
const {
method,
url,
payloadT,
} = routeOptions;
export const attachRoute = <TIn extends TSchema, TOut extends TSchema>(
server: FastifyInstance,
routeOptions: FirRouteOptions<TIn, TOut>,
) => {
const { method, url, payloadT } = routeOptions;
if ("websocket" in routeOptions) {
console.log('SETTING UP WS');
const {websocket} = routeOptions;
server.register(async function(fastify: FastifyInstance) {
fastify.get('/api/ws/room', { websocket: true }, (socket: WebSocket, req: FastifyRequest) => {
websocket.onOpen && websocket.onOpen({socket, req});
socket.on('message', (message: any) => {
const payload = JSON.parse(message.toString());
if (Value.Check(payloadT, payload)) {
websocket.onMessage && websocket.onMessage({socket, payload, req});
} else {
throw new Error("Payload wrong shape.");
}
});
socket.on('close', () => {
websocket.onClose && websocket.onClose({socket, req});
});
socket.on('error', (error: any) => {
websocket.onError && websocket.onError({socket, error, req});
});
})
console.log("SETTING UP WS");
const { websocket } = routeOptions;
server.register(async function (fastify: FastifyInstance) {
fastify.get(
"/api/ws/room",
{ websocket: true },
(socket: WebSocket, req: FastifyRequest) => {
websocket.onOpen && websocket.onOpen({ socket, req });
socket.on("message", (message: any) => {
const payload = JSON.parse(message.toString());
if (Value.Check(payloadT, payload)) {
websocket.onMessage &&
websocket.onMessage({ socket, payload, req });
} else {
throw new Error("Payload wrong shape.");
}
});
socket.on("close", () => {
websocket.onClose && websocket.onClose({ socket, req });
});
socket.on("error", (error: any) => {
websocket.onError &&
websocket.onError({ socket, error, req });
});
},
);
});
return;
// const {websocket} = routeOptions;
// const augmentedWsHandler = (conn: Parameters<Defined<RouteOptions["wsHandler"]>>[0]) => {
// console.log('HELLO');
// conn.on("message", (message) => {
// const payload = JSON.parse(message.toString());
// if (Value.Check(payloadT, payload)) {
// websocket({socket: conn, payload});
// } else {
// throw new Error("Payload wrong shape.");
// }
// });
// console.log('HELLO');
// conn.on("message", (message) => {
// const payload = JSON.parse(message.toString());
// if (Value.Check(payloadT, payload)) {
// websocket({socket: conn, payload});
// } else {
// throw new Error("Payload wrong shape.");
// }
// });
// }
// return {
// method: 'GET', // WebSocket upgrades are GET requests
// url,
// method: 'GET', // WebSocket upgrades are GET requests
// url,
// // websocket: true,
// wsHandler: augmentedWsHandler,
// wsHandler: augmentedWsHandler,
// handler: (...args) => {
// console.log('socket!');
// const socket = args[0].socket.on("message", () => {
// console.log("connected!");
// })
// },
// // handler: (request, reply) => {
// // reply.code(405).send({ message: 'Method Not Allowed' }); // Handle non-WebSocket requests
// // }
// }
// // handler: (request, reply) => {
// // reply.code(405).send({ message: 'Method Not Allowed' }); // Handle non-WebSocket requests
// // }
// }
}
const {handler} = routeOptions;
const augmentedHandler = (request: Parameters<RouteOptions["handler"]>[0]) => {
const {
body,
query,
} = request;
const { handler } = routeOptions;
const augmentedHandler = (
request: Parameters<RouteOptions["handler"]>[0],
) => {
const { body, query } = request;
const payload = body ?? query;
if (Value.Check(payloadT, payload)) {
return handler({payload});
return handler({ payload });
} else {
throw new Error("Payload wrong shape.");
}
}
};
server.route({
method,
url,
handler: augmentedHandler,
});
}
};