Spaces:
Running
Running
| 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); | |
| } | |
| } | |
| } | |