///
import { EventEmitter } from "events";
export declare type EventCallback = (event: string, ...args: any[]) => void;
export declare type EncodingOptions = {
encoding?: BufferEncoding | null;
flag?: string;
mode?: string;
persistent?: boolean;
recursive?: boolean;
} | BufferEncoding | undefined | null;
export declare type EncodingOptionsCallback = EncodingOptions | ((err: NodeJS.ErrnoException | null, ...args: any[]) => void);
/**
* Client-side emitter that just forwards server proxy events to its own
* emitter. It also turns a promisified server proxy into a non-promisified
* proxy so we don't need a bunch of `then` calls everywhere.
*/
export declare abstract class ClientProxy extends EventEmitter {
private _proxyPromise;
private readonly bindEvents;
private _proxy;
/**
* You can specify not to bind events in order to avoid emitting twice for
* duplex streams.
*/
constructor(_proxyPromise: Promise | T, bindEvents?: boolean);
/**
* Bind to the error event without counting as a listener for the purpose of
* throwing if nothing is listening.
*/
onInternalError(listener: (...args: any[]) => void): void;
/**
* Bind the event locally and ensure the event is bound on the server.
*/
addListener(event: string, listener: (...args: any[]) => void): this;
/**
* Alias for `addListener`.
*/
on(event: string, listener: (...args: any[]) => void): this;
/**
* Same as the parent except also emit the internal error event for errors.
*/
emit(event: string | symbol, ...args: any[]): boolean;
/**
* Original promise for the server proxy. Can be used to be passed as an
* argument.
*/
readonly proxyPromise: Promise | T;
/**
* Server proxy.
*/
protected readonly proxy: T;
/**
* Initialize the proxy by unpromisifying if necessary and binding to its
* events.
*/
protected initialize(proxyPromise: Promise | T): T;
/**
* Perform necessary cleanup on disconnect (or reconnect).
*/
protected abstract handleDisconnect(): void;
/**
* Emit an error event if the promise errors.
*/
protected catch(promise?: Promise): this;
}
export interface ServerProxyOptions {
/**
* The events to bind immediately.
*/
bindEvents: string[];
/**
* Events that signal the proxy is done.
*/
doneEvents: string[];
/**
* Events that should only be bound when asked
*/
delayedEvents?: string[];
/**
* Whatever is emitting events (stream, child process, etc).
*/
instance: T;
}
/**
* The actual proxy instance on the server. Every method must only accept
* serializable arguments and must return promises with serializable values.
*
* If a proxy itself has proxies on creation (like how ChildProcess has stdin),
* then it should return all of those at once, otherwise you will miss events
* from those child proxies and fail to dispose them properly.
*
* Events listeners are added client-side (since all events automatically
* forward to the client), so onDone and onEvent do not need to be asynchronous.
*/
export declare abstract class ServerProxy {
private readonly options;
readonly instance: T;
private readonly callbacks;
constructor(options: ServerProxyOptions);
/**
* Dispose the proxy.
*/
dispose(): Promise;
/**
* This is used instead of an event to force it to be implemented since there
* would be no guarantee the implementation would remember to emit the event.
*/
onDone(cb: () => void): void;
/**
* Bind an event that will not fire without first binding it and shouldn't be
* bound immediately.
* For example, binding to `data` switches a stream to flowing mode, so we
* don't want to do it until we're asked. Otherwise something like `pipe`
* won't work because potentially some or all of the data will already have
* been flushed out.
*/
bindDelayedEvent(event: string): Promise;
/**
* Listen to all possible events. On the client, this is to reduce boilerplate
* that would just be a bunch of error-prone forwarding of each individual
* event from the proxy to its own emitter.
*
* It also fixes a timing issue because we just always send all events from
* the server, so we never miss any due to listening too late.
*
* This cannot be async because then we can bind to the events too late.
*/
onEvent(cb: EventCallback): void;
}
/**
* A server-side proxy stored on the client. The proxy ID only exists on the
* client-side version of the server proxy. The event listeners are handled by
* the client and the remaining methods are proxied to the server.
*/
export interface ClientServerProxy extends ServerProxy {
proxyId: number | Module;
}
/**
* Supported top-level module proxies.
*/
export declare enum Module {
Buffer = "buffer",
ChildProcess = "child_process",
Crypto = "crypto",
Events = "events",
Fs = "fs",
Net = "net",
Os = "os",
Path = "path",
Process = "process",
Stream = "stream",
StringDecoder = "string_decoder",
Timers = "timers",
Tty = "tty",
Util = "util"
}
/**
* Batch remote calls.
*/
export declare abstract class Batch {
/**
* Flush after reaching this amount of time.
*/
private readonly maxTime;
/**
* Flush after reaching this count.
*/
private readonly maxCount;
/**
* Flush after not receiving more requests for this amount of time.
* This is pretty low by default so essentially we just end up batching
* requests that are all made at the same time.
*/
private readonly idleTime;
private idleTimeout;
private maxTimeout;
private batch;
constructor(
/**
* Flush after reaching this amount of time.
*/
maxTime?: number,
/**
* Flush after reaching this count.
*/
maxCount?: number,
/**
* Flush after not receiving more requests for this amount of time.
* This is pretty low by default so essentially we just end up batching
* requests that are all made at the same time.
*/
idleTime?: number);
add: (args: A) => Promise;
/**
* Perform remote call for a batch.
*/
protected abstract remoteCall(batch: A[]): Promise<(T | Error)[]>;
/**
* Flush out the current batch.
*/
private readonly flush;
}
export declare class NotImplementedProxy {
constructor(name: string);
}