optimization / frontends /react /src /websocket.ts
joel-woodfield's picture
Refactor file structure
7b67454
import type { Settings } from "./types.ts";
type WebSocketMessage =
| { type: "init"; settings: Settings }
| { type: "reset" }
| { type: "next-step" }
| { type: "prev-step" }
| { type: "play" }
| { type: "pause" };
const RECONNECT_INTERVAL = 3000; // 3 seconds
export default class WebSocketApi {
private socket: WebSocket | null = null;
private onMessageHandler: ((data: unknown) => void) | null = null;
private onReconnectHandler: (() => void) | null = null;
private pendingMessages: WebSocketMessage[] = [];
connect(url: string) {
this.socket = new WebSocket(url);
this.socket.onopen = () => {
console.log("WebSocket connection established.");
if (this.onReconnectHandler) {
this.onReconnectHandler();
}
for (const message of this.pendingMessages) {
this.sendMessage(message);
}
this.pendingMessages = [];
}
this.socket.onclose = () => {
console.log("WebSocket connection closed - reconnecting...");
setTimeout(() => {
this.connect(url);
}, RECONNECT_INTERVAL);
};
this.socket.onerror = (error) => {
console.error("WebSocket error:", error);
};
this.socket.onmessage = (event) => {
if (!this.onMessageHandler) return;
try {
const data = JSON.parse(event.data);
this.onMessageHandler(data);
} catch (parseError) {
console.error("WebSocket message parse error:", parseError);
}
};
}
disconnect() {
if (this.socket) {
this.socket.close();
this.socket = null;
}
}
sendInit(settings: Settings) {
this.sendMessage({ type: "init", settings });
}
sendReset() {
this.sendMessage({ type: "reset" });
}
sendNextStep() {
this.sendMessage({ type: "next-step" });
}
sendPrevStep() {
this.sendMessage({ type: "prev-step" });
}
sendPlay() {
this.sendMessage({ type: "play" });
}
sendPause() {
this.sendMessage({ type: "pause" });
}
onMessage(handler: (data: unknown) => void) {
this.onMessageHandler = handler;
}
onReconnect(handler: () => void) {
this.onReconnectHandler = handler;
}
private sendMessage(message: WebSocketMessage) {
if (this.socket?.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(message));
} else {
console.log("WebSocket not connected, queuing message:", message);
this.pendingMessages.push(message);
}
}
}