UNPKG

@ch1/rpc

Version:

JavaScript Remote Procedure Call (RPC)

203 lines (202 loc) 5.52 kB
/** * Project interfaces */ /** * Generic Dictionary */ export interface Dictionary<T> { [key: string]: T; } /** * Where `T` is the type of the complete interface you wish to expose */ export interface Remote<T> extends Dictionary<Function | Object> { } /** * Specify async types on the remote */ export interface RemoteDesc extends Dictionary<number | Dictionary<number>> { } /** * Async style function union */ export declare type RPCAsync<T> = RPCDefer<T> | RPCNodeCallback<T> | RPCNodeEventInternal | RPCNotify<T>; /** * Ensures correct async response */ export interface RPCAsyncContainer<T> { type: number; async: RPCAsync<T> | Dictionary<RPCNodeEventInternal>; } export interface RPCNodeEventInternal { listener: Function; uid: string; } export declare type RPCAsyncContainerDictionary = Dictionary<RPCAsyncContainer<any>>; export interface RPCNodeCallback<T> { (error: Error, param?: T): any; (error: Error, ...rest: any[]): any; } /** * tl;dr these are used in `RemoteDesc` to describe given API functions * * js-rpc uses these strings to identify types of "real world" functions that * it can interface with. * * These types are actually used by consumers of the library since they are the * specific strings enforced by `RemoteDesc` * * - ### "nodeCallback" * nodeCallback refers to JavaScript callback functions that strictly follow * two rules: * * - the _last_ parameter passed to a function is the callback * - a "Nullable Error" is the _first_ parameter passed to the callback * * Example: * * ```js * function add(a, b, callback) { * setTimeout(() => { * if (isNumber(a) && (isNumber(b)) { * callback(null, result); * } else { * callback(new TypeError('add is for numbers')); * } * }, 0); * } * * add(1, 2, (err, result) => expect(result).toBe(3); * add(1, 2, (err, result) => expect(error).toBeFalsey(); * add('1', 2), (erro, result) => expect(error instanceof Error).toBe(true); * ``` * * - ### "nodeEvent"/"nodeEventInternal" * nodeEvents are a _limited_ interface to * * [node EventEmitters](https://nodejs.org/api/events.html "docs") * * - ### "observable" * In this case observables refer to * [RxJS5](https://github.com/ReactiveX/rxjs, "RxJS") * * - ### "promise" * promises are es6 promises or any A+ promises that implement `.then` and * `.catch` along with the global `Promise` */ export declare const RPCAsyncType: { observable: number; promise: number; }; export interface RPCDefer<T> { resolve: (any: any) => any; reject: (any: any) => any; promise: Promise<T>; } /** * The Different Types of RPC Events */ export declare const RPCEventType: Readonly<{ ack: number; create: number; createReturn: number; destroy: number; destroyReturn: number; fnReturn: number; invoke: number; promise: number; subscribe: number; unsubscribe: number; }>; export interface RPCEmit { (message: string, payload: RPCEvent): any; } export interface ConfiguredRPCEmit { (payload: RPCEvent): any; } export interface RPCNotify<T> { (param: T, ...args: any[]): any; (...args: any[]): any; } export interface RPCObservable<T> { subscribe: (next: (param: T) => any, onError: (error: Error) => any, onComplete: () => any) => () => void; } export interface RPCOn { (message: string, callback: (payload: RPCEvent) => void): () => void; } export interface ConfiguredRPCOn { (callback: (payload: RPCEvent) => any): () => any; } export interface RPCOptions { defaultAsyncType?: number; defaultCreateRetry?: number; defaultCreateRetryCurve?: number; defaultCreateWait?: number; enableStackTrace?: boolean; maxAckDelay?: number; useAcks?: Dictionary<number>; } export interface FunctionalState { responders: RPCEventRegistry; successHandlers: RPCEventRegistry; errorHandlers: RPCEventRegistry; } export interface RPCAbstractConfig extends RPCOptions { message?: string; remote?: Object; emit?: ConfiguredRPCEmit; on?: ConfiguredRPCOn; functionalState?: FunctionalState; callbacks?: RPCAsyncContainerDictionary; uid?: () => string; } export interface RPCConfig extends RPCAbstractConfig { emit: ConfiguredRPCEmit; on: ConfiguredRPCOn; } export declare type RPCEventRegistry = { [key: number]: (...args: any[]) => any; }; export declare type RPCAsyncRegistry = { [key: number]: (...args: any[]) => any; }; export declare type RPCRegister = (key: number, value: (...args: any[]) => any) => void; /** * JavaScript error with a code number */ export interface CodedError extends Error { code?: number; stack?: string; } /** * Serializable Error */ export interface RPCError { code?: number; message: string; stack?: string; type?: string; } export interface RPCInvocationPayload { fn: string; args: any[]; } export interface RPCErrorPayload { error: RPCError; } export interface RPCReturnPayload { result: any[]; } export declare type RPCPayload = RPCInvocationPayload | RPCReturnPayload | RPCErrorPayload; export interface RPCEvent { type: number; payload: RPCPayload; uid: string; useAcks?: boolean; } export interface RPC<T> { config: RPCConfig; destroy: (reason?: string) => Promise<void>; onDestroy: (callback: (reason?: string) => any) => () => void; ready: Promise<void>; remote: T; }