z-ipc
Version:
Z-IPC is an easy-to-use, extensible and fully type-safe IPC solution for JavaScript environments.
139 lines (131 loc) • 5.17 kB
text/typescript
import { A as Adapter } from './adapter-6ny_hedX.cjs';
export { d as defineAdapter } from './adapter-6ny_hedX.cjs';
type Values<T> = T[keyof T];
type UnionToIntersection<U> = (U extends unknown ? (arg: U) => void : never) extends (arg: infer I) => void ? I : never;
declare namespace Message {
type RpcRequest = {
kind: "rpc-request";
id: number;
method: string;
args: unknown[];
};
type RpcResponse = {
kind: "rpc-response";
id: number;
result: {
error: false;
value: unknown;
} | {
error: true;
message: string;
stack: string;
};
};
type Event = {
kind: "event";
name: string;
payload: unknown;
};
}
type Message = Message.RpcRequest | Message.RpcResponse | Message.Event;
declare function createOkResponse(id: number, value: unknown): Message;
declare function createErrorResponse(id: number, error: Error): Message;
/**
* A method is an IPC primitive for RPC style communication.
*/
type Method<TArgs extends unknown[] = never, TResult = unknown> = {
kind: "method";
handler: (...args: TArgs) => TResult;
};
declare function defineMethod<TArgs extends unknown[] = never, TResult = unknown>(handler: (...args: TArgs) => TResult): Method<TArgs, TResult>;
/**
* An event is an IPC primitive that allows to send a message.
*/
type Event<TPayload = never> = {
kind: "event";
/**
* Dummy handler to allow to infer the payload type.
*/
handler?: (payload: TPayload) => void;
};
declare function defineEvent<TPayload = void>(): Event<TPayload>;
/**
* A protocol is a collection of methods and events.
* It is used to define the contract between a client and a server.
*/
type Protocol = Record<string, Method | Event>;
declare namespace Protocol {
type InferMethods<TProtocol extends Protocol> = {
[K in keyof TProtocol as TProtocol[K] extends Method ? K : never]: TProtocol[K];
};
type InferEvents<TProtocol extends Protocol> = {
[K in keyof TProtocol as TProtocol[K] extends Event ? K : never]: TProtocol[K];
};
}
type DefineProtocol<TProtocol extends Protocol> = TProtocol;
type DefineMethod<TSignature extends (...args: never) => unknown = () => void> = Method<Parameters<TSignature>, ReturnType<TSignature>>;
type DefineEvent<TPayload = void> = Event<TPayload>;
type InferPayloadArgument$1<T> = [T] extends [void] ? [] : [payload: T];
type InferCallSignature<TProtocol extends Protocol> = UnionToIntersection<Values<{
[K in keyof TProtocol as TProtocol[K] extends Method ? K : never]: (method: K, ...args: Parameters<NonNullable<TProtocol[K]["handler"]>>) => Promise<ReturnType<NonNullable<TProtocol[K]["handler"]>>>;
}>>;
type InferSubscribeSignature<TProtocol extends Protocol> = UnionToIntersection<Values<{
[K in keyof TProtocol as TProtocol[K] extends Event ? K : never]: (method: K, listener: (...payload: InferPayloadArgument$1<Parameters<NonNullable<TProtocol[K]["handler"]>>[0]>) => void) => void;
}>>;
/**
* A client is responsible for calling methods and subscribing to events.
*/
type Client<TProtocol extends Protocol> = {
/**
* The protocol used by the client (should match the server's protocol).
*
* This field is only used for type inference and does not exist at runtime.
*/
readonly protocol: TProtocol;
/**
* Call a remote method.
*/
call: InferCallSignature<TProtocol>;
/**
* Subscribe to an event.
*/
subscribe: InferSubscribeSignature<TProtocol>;
/**
* Unsubscribe from an event.
*/
unsubscribe: InferSubscribeSignature<TProtocol>;
};
/**
* Create a client with the given adapter and protocol.
*/
declare function createClient<TProtocol extends Protocol>(adapter: Adapter<Message>): Client<TProtocol>;
/**
* Error thrown when an RPC call fails.
* Provides a remote stack trace.
*/
declare class RpcError extends Error {
readonly remoteStack: string;
constructor(message: string, remoteStack: string);
}
type InferPayloadArgument<T> = [T] extends [void] ? [] : [payload: T];
type InferEmitSignature<TProtocol extends Protocol> = UnionToIntersection<Values<{
[K in keyof TProtocol as TProtocol[K] extends Event ? K : never]: (method: K, ...payload: InferPayloadArgument<Parameters<NonNullable<TProtocol[K]["handler"]>>[0]>) => void;
}>>;
/**
* A server is responsible for handling method calls and emitting events.
*/
type Server<TProtocol extends Protocol> = {
/**
* The protocol used by the server.
*/
readonly protocol: TProtocol;
/**
* Emit an event.
*/
emit: InferEmitSignature<TProtocol>;
};
/**
* Create a server with the given adapter and protocol.
*/
declare function createServer<TProtocol extends Protocol>(adapter: Adapter<Message>, protocol: TProtocol): Server<TProtocol>;
export { Adapter, type Client, type DefineEvent, type DefineMethod, type DefineProtocol, type Event, Message, type Method, Protocol, RpcError, type Server, createClient, createErrorResponse, createOkResponse, createServer, defineEvent, defineMethod };