import RAL from '../common/ral' ; import { TextDecoder } from 'util' ; import { Disposable } from '../common/disposable' ; import { Message } from '../common/messages' ; import { ContentTypeEncoderOptions , ContentTypeDecoderOptions } from '../common/encoding' ; import { AbstractMessageBuffer } from '../common/messageBuffer' ; class MessageBuffer extends AbstractMessageBuffer { private static readonly emptyBuffer : Buffer = Buffer . allocUnsafe ( 0 ) ; constructor ( encoding = 'utf-8' ) { super ( encoding ) ; } protected emptyBuffer ( ) { return MessageBuffer . emptyBuffer ; } protected fromString ( value , encoding ) { return Buffer . from ( value , encoding ) ; } protected toString ( value , encoding ) { if ( value instanceof Buffer ) { return value . toString ( encoding ) ; } else { return new TextDecoder ( encoding ) . decode ( value ) ; } } protected asNative ( buffer , length ? ) { if ( length === undefined ) { return buffer instanceof Buffer ? buffer : Buffer . from ( buffer ) ; } else { return buffer instanceof Buffer ? buffer . slice ( 0 , length ) : Buffer . from ( buffer , 0 , length ) ; } } protected allocNative ( length ) { return Buffer . allocUnsafe ( length ) ; } } class ReadableStreamWrapper implements RAL . ReadableStream { constructor ( private stream ) { } public onClose ( listener ) { this . stream . on ( 'close' , listener ) ; return Disposable . create ( ( ) => this . stream . off ( 'close' , listener ) ) ; } public onError ( listener ) { this . stream . on ( 'error' , listener ) ; return Disposable . create ( ( ) => this . stream . off ( 'error' , listener ) ) ; } public onEnd ( listener ) { this . stream . on ( 'end' , listener ) ; return Disposable . create ( ( ) => this . stream . off ( 'end' , listener ) ) ; } public onData ( listener ) { this . stream . on ( 'data' , listener ) ; return Disposable . create ( ( ) => this . stream . off ( 'data' , listener ) ) ; } } class WritableStreamWrapper implements RAL . WritableStream { constructor ( private stream ) { } public onClose ( listener ) { this . stream . on ( 'close' , listener ) ; return Disposable . create ( ( ) => this . stream . off ( 'close' , listener ) ) ; } public onError ( listener ) { this . stream . on ( 'error' , listener ) ; return Disposable . create ( ( ) => this . stream . off ( 'error' , listener ) ) ; } public onEnd ( listener ) { this . stream . on ( 'end' , listener ) ; return Disposable . create ( ( ) => this . stream . off ( 'end' , listener ) ) ; } public write ( data , encoding ? ) { return new Promise ( ( resolve , reject ) => { const callback = ( error ) => { if ( error === undefined || error === null ) { resolve ( ) ; } else { reject ( error ) ; } } ; if ( typeof data === 'string' ) { this . stream . write ( data , encoding , callback ) ; } else { this . stream . write ( data , callback ) ; } } ) ; } public end ( ) { this . stream . end ( ) ; } } interface RIL extends RAL { readonly stream : { readonly asReadableStream : ( stream : NodeJS . ReadableStream ) => RAL . ReadableStream ; readonly asWritableStream : ( stream : NodeJS . WritableStream ) => RAL . WritableStream ; } ; } const _ril = Object . freeze < RIL > ( { messageBuffer : Object . freeze ( { create : ( encoding ) => new MessageBuffer ( encoding ) } ) , applicationJson : Object . freeze ( { encoder : Object . freeze ( { name : 'application/json' , encode : ( msg , options ) : Promise < Buffer > => { try { return Promise . resolve ( Buffer . from ( JSON . stringify ( msg , undefined , 0 ) , options . charset ) ) ; } catch ( err ) { return Promise . reject ( err ) ; } } } ) , decoder : Object . freeze ( { name : 'application/json' , decode : ( buffer , options ) : Promise < Message > => { try { if ( buffer instanceof Buffer ) { return Promise . resolve ( JSON . parse ( buffer . toString ( options . charset ) ) ) ; } else { return Promise . resolve ( JSON . parse ( new TextDecoder ( options . charset ) . decode ( buffer ) ) ) ; } } catch ( err ) { return Promise . reject ( err ) ; } } } ) } ) , stream : Object . freeze ( { asReadableStream : ( stream ) => new ReadableStreamWrapper ( stream ) , asWritableStream : ( stream ) => new WritableStreamWrapper ( stream ) } ) , console : console , timer : Object . freeze ( { setTimeout ( callback , ms , ... args ) { const handle = setTimeout ( callback , ms , ... args ) ; return { dispose : ( ) => clearTimeout ( handle ) } ; } , setImmediate ( callback , ... args ) { const handle = setImmediate ( callback , ... args ) ; return { dispose : ( ) => clearImmediate ( handle ) } ; } , setInterval ( callback , ms , ... args ) { const handle = setInterval ( callback , ms , ... args ) ; return { dispose : ( ) => clearInterval ( handle ) } ; } } ) } ) ; function RIL ( ) { return _ril ; } namespace RIL { export function install ( ) { RAL . install ( _ril ) ; } } export default RIL ;