import { EventEmitter } from "events" ; import * as stream from "stream" ; import { ServerProxy } from "../common/proxy" ; export class WritableProxy < T extends stream . Writable = stream . Writable > extends ServerProxy < T > { public constructor ( instance , bindEvents = [ ] , delayedEvents ? ) { super ( { bindEvents : [ "close" , "drain" , "error" , "finish" ] . concat ( bindEvents ) , doneEvents : [ "close" ] , delayedEvents , instance , } ) ; } public async destroy ( ) { this . instance . destroy ( ) ; } public async end ( data ? , encoding ? ) { return new Promise ( ( resolve ) : void => { this . instance . end ( data , encoding ! , ( ) => { resolve ( ) ; } ) ; } ) ; } public async setDefaultEncoding ( encoding ) { this . instance . setDefaultEncoding ( encoding ) ; } public async write ( data , encoding ? ) { return new Promise ( ( resolve , reject ) : void => { this . instance . write ( data , encoding ! , ( error ) => { if ( error ) { reject ( error ) ; } else { resolve ( ) ; } } ) ; } ) ; } public async dispose ( ) { this . instance . end ( ) ; await super . dispose ( ) ; } } /**
 * This noise is because we can't do multiple extends and we also can't seem to
 * do `extends WritableProxy<T> implement ReadableProxy<T>` (for `DuplexProxy`).
 */ export interface CommonReadableProxy < T extends EventEmitter > extends ServerProxy < T > { pipe < P extends WritableProxy > ( destination , options ? ) : Promise < void > ; setEncoding ( encoding ) : Promise < void > ; } export class ReadableProxy < T extends stream . Readable = stream . Readable > extends ServerProxy < T > implements CommonReadableProxy < T > { public constructor ( instance , bindEvents = [ ] ) { super ( { bindEvents : [ "close" , "end" , "error" ] . concat ( bindEvents ) , doneEvents : [ "close" ] , delayedEvents : [ "data" ] , instance , } ) ; } public async pipe < P extends WritableProxy > ( destination , options ? ) { this . instance . pipe ( destination . instance , options ) ; await this . bindDelayedEvent ( "data" ) ; } public async destroy ( ) { this . instance . destroy ( ) ; } public async setEncoding ( encoding ) { this . instance . setEncoding ( encoding ) ; } public async dispose ( ) { this . instance . destroy ( ) ; await super . dispose ( ) ; } } export class DuplexProxy < T extends stream . Duplex = stream . Duplex > extends WritableProxy < T > implements CommonReadableProxy < T > { public constructor ( stream , bindEvents = [ ] ) { super ( stream , [ "end" ] . concat ( bindEvents ) , [ "data" ] ) ; } public async pipe < P extends WritableProxy > ( destination , options ? ) { this . instance . pipe ( destination . instance , options ) ; await this . bindDelayedEvent ( "data" ) ; } public async setEncoding ( encoding ) { this . instance . setEncoding ( encoding ) ; } public async dispose ( ) { this . instance . destroy ( ) ; await super . dispose ( ) ; } }