import net from 'net' ; interface TCPSocket extends net . Socket { _peername : { address : string ; port : number ; } ; } function tcp ( { socketTimeout = 30000 } = { } ) { return function socket ( params , emitter ) : Socket { let listener ; function bind ( ) { listener = net . createServer ( soc => emitter . emit ( 'socket' , soc ) ) ; listener . on ( 'error' , err => emitter . emit ( 'error' , err ) ) ; listener . listen ( params . port , ( ) => emitter . emit ( 'ready' ) ) ; } function remote ( handle ) { return { host : handle ?. remoteAddress || handle ?. _peername ?. address || null , port : handle ?. remotePort || handle ?. _peername ?. port || null , } ; } function disconnect ( handle ) { if ( handle ) { handle . end ( ) ; handle . destroy ( ) ; } } function connect ( handle ) { const connection = handle || net . connect ( params . port , params . host ) ; let buffer = '' ; connection . on ( 'data' , req => { buffer += req . toString ( ) ; const chunks = buffer . split ( '\n\n' ) ; if ( buffer . substring ( buffer . length - 2 ) !== '\n\n' ) { buffer = chunks [ chunks . length - 1 ] ; chunks . pop ( ) ; } else { buffer = '' ; } for ( let i = 0 ; i < chunks . length ; i ++ ) { if ( chunks [ i ] !== '' ) emitter . emit ( 'frame' , JSON . parse ( chunks [ i ] ) , req . length ) ; } } ) ; connection . on ( 'error' , err => emitter . emit ( 'error' , err ) ) ; connection . on ( 'connect' , ( ) => emitter . emit ( 'connect' , connection ) ) ; connection . on ( 'close' , ( ) => emitter . emit ( 'disconnect' ) ) ; connection . setTimeout ( socketTimeout , ( ) => disconnect ( handle ) ) ; return connection ; } function stop ( ) { if ( listener ) listener . close ( ) ; } function send ( handle , payload ) { if ( handle ) handle . write ( `${ JSON . stringify ( payload ) }\n\n` ) ; } return { bind , connect , disconnect , remote , send , stop , } ; } ; } module . exports = tcp ;