{"version":3,"file":"iflytek_websocket_stream.cjs","names":[],"sources":["../../src/utils/iflytek_websocket_stream.ts"],"sourcesContent":["export interface WebSocketConnection<\n  T extends Uint8Array | string = Uint8Array | string,\n> {\n  readable: ReadableStream<T>;\n  writable: WritableStream<T>;\n  protocol: string;\n  extensions: string;\n}\n\nexport interface WebSocketCloseInfo {\n  code?: number;\n  reason?: string;\n}\n\nexport interface WebSocketStreamOptions {\n  protocols?: string[];\n  signal?: AbortSignal;\n}\n\n/**\n * [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) with [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)\n *\n * @see https://web.dev/websocketstream/\n */\nexport abstract class BaseWebSocketStream<\n  T extends Uint8Array | string = Uint8Array | string,\n> {\n  readonly url: string;\n\n  readonly connection: Promise<WebSocketConnection<T>>;\n\n  readonly closed: Promise<WebSocketCloseInfo>;\n\n  readonly close: (closeInfo?: WebSocketCloseInfo) => void;\n\n  constructor(url: string, options: WebSocketStreamOptions = {}) {\n    if (options.signal?.aborted) {\n      throw new DOMException(\"This operation was aborted\", \"AbortError\");\n    }\n\n    this.url = url;\n\n    const ws = this.openWebSocket(url, options);\n\n    const closeWithInfo = ({ code, reason }: WebSocketCloseInfo = {}) =>\n      ws.close(code, reason);\n\n    this.connection = new Promise((resolve, reject) => {\n      ws.onopen = () => {\n        resolve({\n          readable: new ReadableStream<T>({\n            start(controller) {\n              ws.onmessage = ({ data }) => controller.enqueue(data);\n              ws.onerror = (e) => controller.error(e);\n            },\n            cancel: closeWithInfo,\n          }),\n          writable: new WritableStream<T>({\n            write(chunk) {\n              ws.send(chunk);\n            },\n            abort() {\n              ws.close();\n            },\n            close: closeWithInfo,\n          }),\n          protocol: ws.protocol,\n          extensions: ws.extensions,\n        });\n        ws.removeEventListener(\"error\", reject);\n      };\n      ws.addEventListener(\"error\", reject);\n    });\n\n    this.closed = new Promise<WebSocketCloseInfo>((resolve, reject) => {\n      ws.onclose = ({ code, reason }) => {\n        resolve({ code, reason });\n        ws.removeEventListener(\"error\", reject);\n      };\n      ws.addEventListener(\"error\", reject);\n    });\n\n    if (options.signal) {\n      // Use bind() instead of an arrow function to avoid capturing the\n      // surrounding scope (which includes large objects). This prevents\n      // memory leaks when the user passes a long-lived AbortSignal.\n      // Using { once: true } ensures the listener auto-removes after firing.\n      const abort = ws.close.bind(ws);\n      options.signal.addEventListener(\"abort\", abort, { once: true });\n    }\n\n    this.close = closeWithInfo;\n  }\n\n  abstract openWebSocket(\n    url: string,\n    options: WebSocketStreamOptions\n  ): WebSocket;\n}\n"],"mappings":";;;;;;AAwBA,IAAsB,sBAAtB,MAEE;CACA;CAEA;CAEA;CAEA;CAEA,YAAY,KAAa,UAAkC,EAAE,EAAE;AAC7D,MAAI,QAAQ,QAAQ,QAClB,OAAM,IAAI,aAAa,8BAA8B,aAAa;AAGpE,OAAK,MAAM;EAEX,MAAM,KAAK,KAAK,cAAc,KAAK,QAAQ;EAE3C,MAAM,iBAAiB,EAAE,MAAM,WAA+B,EAAE,KAC9D,GAAG,MAAM,MAAM,OAAO;AAExB,OAAK,aAAa,IAAI,SAAS,SAAS,WAAW;AACjD,MAAG,eAAe;AAChB,YAAQ;KACN,UAAU,IAAI,eAAkB;MAC9B,MAAM,YAAY;AAChB,UAAG,aAAa,EAAE,WAAW,WAAW,QAAQ,KAAK;AACrD,UAAG,WAAW,MAAM,WAAW,MAAM,EAAE;;MAEzC,QAAQ;MACT,CAAC;KACF,UAAU,IAAI,eAAkB;MAC9B,MAAM,OAAO;AACX,UAAG,KAAK,MAAM;;MAEhB,QAAQ;AACN,UAAG,OAAO;;MAEZ,OAAO;MACR,CAAC;KACF,UAAU,GAAG;KACb,YAAY,GAAG;KAChB,CAAC;AACF,OAAG,oBAAoB,SAAS,OAAO;;AAEzC,MAAG,iBAAiB,SAAS,OAAO;IACpC;AAEF,OAAK,SAAS,IAAI,SAA6B,SAAS,WAAW;AACjE,MAAG,WAAW,EAAE,MAAM,aAAa;AACjC,YAAQ;KAAE;KAAM;KAAQ,CAAC;AACzB,OAAG,oBAAoB,SAAS,OAAO;;AAEzC,MAAG,iBAAiB,SAAS,OAAO;IACpC;AAEF,MAAI,QAAQ,QAAQ;GAKlB,MAAM,QAAQ,GAAG,MAAM,KAAK,GAAG;AAC/B,WAAQ,OAAO,iBAAiB,SAAS,OAAO,EAAE,MAAM,MAAM,CAAC;;AAGjE,OAAK,QAAQ"}