/** WebSocket client wrapper. */
export class WsClient {
#ws = null;
#handlers = {};
connect(sessionId, handlers) {
this.disconnect();
this.#handlers = handlers;
const proto = location.protocol === 'https:' ? 'wss' : 'ws';
this.#ws = new WebSocket(`${proto}://${location.host}/ws/sessions/${sessionId}`);
this.#ws.onopen = () => handlers.onOpen?.();
this.#ws.onclose = (e) => handlers.onClose?.(e);
this.#ws.onerror = (e) => handlers.onError?.(e);
this.#ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (!['stream_delta', 'thinking_delta'].includes(msg.type)) {
console.log('[ws]', msg.type, msg);
}
handlers.onMessage?.(msg);
};
}
send(content, images = null, files = null) {
if (this.#ws?.readyState === WebSocket.OPEN) {
const payload = { type: 'message', content };
if (images?.length) payload.images = images;
if (files?.length) payload.files = files;
this.#ws.send(JSON.stringify(payload));
return true;
}
return false;
}
disconnect() {
this.#ws?.close();
this.#ws = null;
}
get ready() {
return this.#ws?.readyState === WebSocket.OPEN;
}
}