ws.mjs raw

   1  // TinyJS Runtime — WebSocket Bridge
   2  // Provides Go-callable WebSocket operations.
   3  // Function names match Go signatures (PascalCase).
   4  
   5  const _conns = new Map();
   6  let _nextId = 1;
   7  
   8  // Open a WebSocket connection. Returns connection ID.
   9  // Callback params are Go closures compiled to JS functions.
  10  export function Dial(url, onMessage, onOpen, onClose, onError) {
  11    const id = _nextId++;
  12    const ws = new WebSocket(url);
  13    const conn = { ws, id, closed: false };
  14    _conns.set(id, conn);
  15  
  16    ws.onopen = () => {
  17      if (onOpen) onOpen(id);
  18    };
  19  
  20    ws.onmessage = (ev) => {
  21      if (onMessage) {
  22        try {
  23          onMessage(id, String(ev.data));
  24        } catch (e) {
  25          console.error('relay-sw: WS onmessage CRASH:', e.message, e.stack);
  26        }
  27      }
  28    };
  29  
  30    ws.onclose = (ev) => {
  31      conn.closed = true;
  32      if (onClose) onClose(id, ev.code, ev.reason);
  33    };
  34  
  35    ws.onerror = (ev) => {
  36      if (onError) onError(id);
  37    };
  38  
  39    return id;
  40  }
  41  
  42  // Send a string message on a connection.
  43  export function Send(connId, msg) {
  44    const conn = _conns.get(connId);
  45    if (conn && !conn.closed && conn.ws.readyState === WebSocket.OPEN) {
  46      conn.ws.send(msg);
  47      return true;
  48    }
  49    return false;
  50  }
  51  
  52  // Close a connection.
  53  export function Close(connId) {
  54    const conn = _conns.get(connId);
  55    if (conn) {
  56      conn.closed = true;
  57      conn.ws.close();
  58      _conns.delete(connId);
  59    }
  60  }
  61  
  62  // Get connection readyState.
  63  export function ReadyState(connId) {
  64    const conn = _conns.get(connId);
  65    if (!conn) return -1;
  66    return conn.ws.readyState;
  67  }
  68