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); } } }