import { viewToBuffer } from "@miniflare/shared" ; import StandardWebSocket from "ws" ; import { ErrorEvent , WebSocket , kAccepted , kClose , kClosed , kCoupled , } from "./websocket" ; export async function coupleWebSocket ( ws , pair ) { if ( pair [ kCoupled ] ) { throw new TypeError ( "Can't return WebSocket that was already used in a response." ) ; } if ( pair [ kAccepted ] ) { throw new TypeError ( "Can't return WebSocket in a Response after calling accept()." ) ; } ws . on ( "message" , ( message , isBinary ) => { if ( isBinary ) { pair . send ( viewToBuffer ( message ) ) ; } else { pair . send ( message . toString ( ) ) ; } } ) ; ws . on ( "close" , ( code , reason ) => { if ( ! pair [ kClosed ] ) pair [ kClose ] ( code , reason . toString ( ) ) ; } ) ; ws . on ( "error" , ( error ) => { pair . dispatchEvent ( new ErrorEvent ( "error" , { error } ) ) ; } ) ; pair . addEventListener ( "message" , ( e ) => { ws . send ( e . data ) ; } ) ; pair . addEventListener ( "close" , ( e ) => { if ( ws . readyState < StandardWebSocket . CLOSING ) ws . close ( e . code , e . reason ) ; } ) ; if ( ws . readyState === StandardWebSocket . CONNECTING ) { await new Promise < void > ( ( resolve , reject ) => { ws . once ( "open" , ( ) => { pair . accept ( ) ; pair [ kCoupled ] = true ; ws . off ( "close" , reject ) ; ws . off ( "error" , reject ) ; resolve ( ) ; } ) ; ws . once ( "close" , reject ) ; ws . once ( "error" , reject ) ; } ) ; } else { pair . accept ( ) ; pair [ kCoupled ] = true ; if ( ws . readyState >= StandardWebSocket . CLOSING ) { throw new TypeError ( "Incoming WebSocket connection already closed." ) ; } } }