const isBrowser = ( typeof WebSocket !== 'undefined' ) ; const WS = isBrowser ? WebSocket : require ( 'ws' ) ; function ws ( { cert , key , secure } = { } ) { return function socket ( params , emitter ) : Socket { let listener ; function bind ( ) { if ( cert && key ) { const server = require ( 'https' ) . createServer ( { key , cert } , req => req . socket . end ( ) ) ; listener = new WS . Server ( { port : params . port , server } ) ; } else { listener = new WS . Server ( { port : params . port } ) ; } listener . on ( 'connection' , soc => emitter . emit ( 'socket' , soc ) ) ; listener . on ( 'error' , err => emitter . emit ( 'error' , err ) ) ; emitter . emit ( 'ready' ) ; } function send ( handle , payload ) { if ( handle && handle . readyState === 1 ) handle . send ( typeof payload === 'string' ? payload : JSON . stringify ( payload ) ) ; else handle . _queue . push ( JSON . stringify ( payload ) ) ; } function stop ( ) { if ( listener ) listener . close ( ) ; } function connect ( handle ? ) { const protocol = secure === true ? 'wss' : 'ws' ; const connection = handle || new WS ( `${ protocol }://${ params . host }:${ params . port }` ) ; connection . binaryType = 'arraybuffer' ; const evtType = isBrowser ? 'addEventListener' : 'on' ; connection . _queue = [ ] ; connection [ evtType ] ( 'message' , evt => emitter . emit ( 'frame' , JSON . parse ( evt . data || evt ) , ( evt . data || evt ) . length ) ) ; connection [ evtType ] ( 'error' , err => emitter . emit ( 'error' , err ) ) ; connection [ evtType ] ( 'close' , ( ) => emitter . emit ( 'disconnect' ) ) ; connection [ evtType ] ( 'open' , ( ) => { emitter . emit ( 'connect' , connection ) ; connection . _queue . forEach ( payload => send ( connection , payload ) ) ; } ) ; return connection ; } function remote ( handle ) { const h = handle && handle . headers || { } ; const headerHost = h && h [ 'x-forwarded-for' ] && h [ 'x-forwarded-for' ] . split ( ',' ) [ 0 ] ; const remoteHost = handle ?. connection ?. remoteAddress ; const socketHost = handle ?. _socket ?. server ?. _connectionKey ; return { host : headerHost || remoteHost || socketHost || null , port : handle ?. connection ?. remotePort || null , } ; } function disconnect ( handle ) { if ( handle ) { handle . end ( ) ; handle . close ( ) ; } } return { bind , connect , disconnect , remote , send , stop , } ; } ; } module . exports = ws ;