Newer
Older
navi-1 / client / js / ws.js
/** 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;
  }
}