{"version":3,"file":"ws-test-backend.cjs","names":["config: TestBackendConfig","WebSocketServer","ws","connection: WSConnection","ws: WebSocket","data: string","WebSocket","data: Buffer | ArrayBuffer | Uint8Array","code?: number","reason?: string","callback: (data: string) => void","callback: (data: Buffer) => void","callback: (code: number, reason: string) => void","callback: (error: Error) => void"],"sources":["../src/ws-test-backend.ts"],"sourcesContent":["import WebSocket, { WebSocketServer } from 'ws'\n\nexport interface TestBackendConfig {\n  port: number\n}\n\nexport interface WSConnection {\n  send(data: string): void\n  sendBinary(data: Buffer | ArrayBuffer | Uint8Array): void\n  close(code?: number, reason?: string): void\n  onMessage(callback: (data: string) => void): void\n  onBinaryMessage(callback: (data: Buffer) => void): void\n  onClose(callback: (code: number, reason: string) => void): void\n  onError(callback: (error: Error) => void): void\n  readonly readyState: number\n}\n\nexport class WSTestBackend {\n  private server: WebSocketServer | null = null\n  private connection: WebSocket | null = null\n  private connectionPromise: Promise<WSConnection> | null = null\n\n  constructor(private config: TestBackendConfig) {}\n\n  static async create(config: TestBackendConfig): Promise<WSTestBackend> {\n    const backend = new WSTestBackend(config)\n    await backend.start()\n    return backend\n  }\n\n  async start(): Promise<void> {\n    return new Promise((resolve, reject) => {\n      this.server = new WebSocketServer({ port: this.config.port })\n\n      this.server.on('listening', () => {\n        console.log(`Test WebSocket backend listening on port ${this.config.port}`)\n        // Set up connection handler immediately\n        this.setupConnectionHandler()\n        resolve()\n      })\n\n      this.server.on('error', reject)\n    })\n  }\n\n  private setupConnectionHandler(): void {\n    if (!this.server) return\n\n    this.server.on('connection', (ws) => {\n      if (this.connection) {\n        // Only allow one connection - reject immediately\n        console.log('Test backend: Rejecting additional connection')\n        ws.close(1013, 'Only one connection allowed')\n        return\n      }\n\n      console.log('Test backend: Client connected')\n      this.connection = ws\n\n      // Resolve any pending connection promise\n      if (this.connectionResolve) {\n        const connectionWrapper = this.createConnectionWrapper(ws)\n        this.connectionResolve(connectionWrapper)\n        this.connectionResolve = null\n        this.connectionPromise = null\n      }\n\n      // Set up cleanup on close\n      ws.on('close', () => {\n        console.log('Test backend: Client disconnected')\n        this.connection = null\n        this.connectionPromise = null\n        this.connectionResolve = null\n      })\n    })\n  }\n\n  private connectionResolve: ((connection: WSConnection) => void) | null = null\n\n  async wsConnection(): Promise<WSConnection> {\n    if (!this.server) {\n      throw new Error('Backend not started. Call start() first.')\n    }\n\n    // If we already have a connection, return it\n    if (this.connection) {\n      return this.createConnectionWrapper(this.connection)\n    }\n\n    if (this.connectionPromise) {\n      return this.connectionPromise\n    }\n\n    this.connectionPromise = new Promise((resolve, reject) => {\n      this.connectionResolve = resolve\n\n      const timeout = setTimeout(() => {\n        this.connectionResolve = null\n        this.connectionPromise = null\n        reject(new Error('Connection timeout - no client connected within 10 seconds'))\n      }, 10000)\n\n      // Store the timeout so we can clear it when connection is made\n      const originalResolve = this.connectionResolve\n      this.connectionResolve = (connection: WSConnection) => {\n        clearTimeout(timeout)\n        originalResolve(connection)\n      }\n    })\n\n    return this.connectionPromise\n  }\n\n  private createConnectionWrapper(ws: WebSocket): WSConnection {\n    return {\n      send: (data: string) => {\n        if (ws.readyState === WebSocket.OPEN) {\n          ws.send(data)\n        }\n      },\n\n      sendBinary: (data: Buffer | ArrayBuffer | Uint8Array) => {\n        if (ws.readyState === WebSocket.OPEN) {\n          ws.send(data)\n        }\n      },\n\n      close: (code?: number, reason?: string) => {\n        ws.close(code, reason)\n      },\n\n      onMessage: (callback: (data: string) => void) => {\n        ws.on('message', (data) => {\n          callback(data.toString())\n        })\n      },\n\n      onBinaryMessage: (callback: (data: Buffer) => void) => {\n        ws.on('message', (data) => {\n          if (Buffer.isBuffer(data)) {\n            callback(data)\n          } else if (data instanceof ArrayBuffer) {\n            callback(Buffer.from(data))\n          } else {\n            // Convert other types to Buffer\n            callback(Buffer.from(data as any))\n          }\n        })\n      },\n\n      onClose: (callback: (code: number, reason: string) => void) => {\n        ws.on('close', (code, reason) => {\n          callback(code, reason.toString())\n        })\n      },\n\n      onError: (callback: (error: Error) => void) => {\n        ws.on('error', (error) => {\n          console.error('Test backend: WebSocket error:', error)\n          callback(error)\n        })\n      },\n\n      get readyState() {\n        return ws.readyState\n      },\n    }\n  }\n\n  hasConnection(): boolean {\n    return this.connection !== null && this.connection.readyState === WebSocket.OPEN\n  }\n\n  async stop(): Promise<void> {\n    if (this.connection) {\n      this.connection.close()\n      this.connection = null\n    }\n\n    this.connectionPromise = null\n\n    if (!this.server) return\n\n    return new Promise((resolve) => {\n      this.server!.close(() => {\n        console.log('Test WebSocket backend shut down')\n        this.server = null\n        resolve()\n      })\n    })\n  }\n}\n"],"mappings":";;;;AAiBA,IAAa,gBAAb,MAAa,cAAc;CACzB,AAAQ,SAAiC;CACzC,AAAQ,aAA+B;CACvC,AAAQ,oBAAkD;CAE1D,YAAoBA,QAA2B;EAA3B;CAA6B;CAEjD,aAAa,OAAOA,QAAmD;EACrE,MAAM,UAAU,IAAI,cAAc;AAClC,QAAM,QAAQ,OAAO;AACrB,SAAO;CACR;CAED,MAAM,QAAuB;AAC3B,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAK,SAAS,IAAIC,mBAAgB,EAAE,MAAM,KAAK,OAAO,KAAM;AAE5D,QAAK,OAAO,GAAG,aAAa,MAAM;AAChC,YAAQ,KAAK,2CAA2C,KAAK,OAAO,KAAK,EAAE;AAE3E,SAAK,wBAAwB;AAC7B,aAAS;GACV,EAAC;AAEF,QAAK,OAAO,GAAG,SAAS,OAAO;EAChC;CACF;CAED,AAAQ,yBAA+B;AACrC,OAAK,KAAK,OAAQ;AAElB,OAAK,OAAO,GAAG,cAAc,CAACC,SAAO;AACnC,OAAI,KAAK,YAAY;AAEnB,YAAQ,IAAI,gDAAgD;AAC5D,SAAG,MAAM,MAAM,8BAA8B;AAC7C;GACD;AAED,WAAQ,IAAI,iCAAiC;AAC7C,QAAK,aAAaA;AAGlB,OAAI,KAAK,mBAAmB;IAC1B,MAAM,oBAAoB,KAAK,wBAAwBA,KAAG;AAC1D,SAAK,kBAAkB,kBAAkB;AACzC,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;GAC1B;AAGD,QAAG,GAAG,SAAS,MAAM;AACnB,YAAQ,IAAI,oCAAoC;AAChD,SAAK,aAAa;AAClB,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;GAC1B,EAAC;EACH,EAAC;CACH;CAED,AAAQ,oBAAiE;CAEzE,MAAM,eAAsC;AAC1C,OAAK,KAAK,OACR,OAAM,IAAI,MAAM;AAIlB,MAAI,KAAK,WACP,QAAO,KAAK,wBAAwB,KAAK,WAAW;AAGtD,MAAI,KAAK,kBACP,QAAO,KAAK;AAGd,OAAK,oBAAoB,IAAI,QAAQ,CAAC,SAAS,WAAW;AACxD,QAAK,oBAAoB;GAEzB,MAAM,UAAU,WAAW,MAAM;AAC/B,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;AACzB,WAAO,IAAI,MAAM,8DAA8D;GAChF,GAAE,IAAM;GAGT,MAAM,kBAAkB,KAAK;AAC7B,QAAK,oBAAoB,CAACC,eAA6B;AACrD,iBAAa,QAAQ;AACrB,oBAAgB,WAAW;GAC5B;EACF;AAED,SAAO,KAAK;CACb;CAED,AAAQ,wBAAwBC,MAA6B;AAC3D,SAAO;GACL,MAAM,CAACC,SAAiB;AACtB,QAAIH,KAAG,eAAeI,WAAU,KAC9B,MAAG,KAAK,KAAK;GAEhB;GAED,YAAY,CAACC,SAA4C;AACvD,QAAIL,KAAG,eAAeI,WAAU,KAC9B,MAAG,KAAK,KAAK;GAEhB;GAED,OAAO,CAACE,MAAeC,WAAoB;AACzC,SAAG,MAAM,MAAM,OAAO;GACvB;GAED,WAAW,CAACC,aAAqC;AAC/C,SAAG,GAAG,WAAW,CAAC,SAAS;AACzB,cAAS,KAAK,UAAU,CAAC;IAC1B,EAAC;GACH;GAED,iBAAiB,CAACC,aAAqC;AACrD,SAAG,GAAG,WAAW,CAAC,SAAS;AACzB,SAAI,OAAO,SAAS,KAAK,CACvB,UAAS,KAAK;cACL,gBAAgB,YACzB,UAAS,OAAO,KAAK,KAAK,CAAC;SAG3B,UAAS,OAAO,KAAK,KAAY,CAAC;IAErC,EAAC;GACH;GAED,SAAS,CAACC,aAAqD;AAC7D,SAAG,GAAG,SAAS,CAAC,MAAM,WAAW;AAC/B,cAAS,MAAM,OAAO,UAAU,CAAC;IAClC,EAAC;GACH;GAED,SAAS,CAACC,aAAqC;AAC7C,SAAG,GAAG,SAAS,CAAC,UAAU;AACxB,aAAQ,MAAM,kCAAkC,MAAM;AACtD,cAAS,MAAM;IAChB,EAAC;GACH;GAED,IAAI,aAAa;AACf,WAAOX,KAAG;GACX;EACF;CACF;CAED,gBAAyB;AACvB,SAAO,KAAK,eAAe,QAAQ,KAAK,WAAW,eAAeI,WAAU;CAC7E;CAED,MAAM,OAAsB;AAC1B,MAAI,KAAK,YAAY;AACnB,QAAK,WAAW,OAAO;AACvB,QAAK,aAAa;EACnB;AAED,OAAK,oBAAoB;AAEzB,OAAK,KAAK,OAAQ;AAElB,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,QAAK,OAAQ,MAAM,MAAM;AACvB,YAAQ,IAAI,mCAAmC;AAC/C,SAAK,SAAS;AACd,aAAS;GACV,EAAC;EACH;CACF;AACF"}