message-port-rpc
Version:
Turns a MessagePort into an remote procedure call (RPC) stub.
45 lines (44 loc) • 2.42 kB
TypeScript
import type { ReturnValueOfPromise } from './private/types/ReturnValueOfPromise';
type Subroutine = (...args: any[]) => Promise<unknown> | unknown;
type CallInit = {
signal?: AbortSignal;
transfer?: Transferable[];
};
type ClientStub<T extends Subroutine> = (...args: Parameters<T>) => Promise<ReturnValueOfPromise<ReturnType<T>>>;
type ClientStubWithExtra<T extends Subroutine> = ClientStub<T> & {
/**
* Creates a new stub with options.
*
* @param {AbortSignal} init.signal - Abort signal to abort the call to the stub.
* @param {Transferable[]} init.transfer - Transfer ownership of objects specified in `args`.
*/
withOptions: (init: CallInit) => ClientStub<T>;
};
type ServerStub<T extends Subroutine> = (this: {
signal: AbortSignal;
}, ...args: Parameters<T>) => ReturnType<T>;
/**
* Binds a function to a `MessagePort` in RPC fashion and/or create a RPC function stub connected to a `MessagePort`.
*
* In a traditional RPC setting:
* - server should call this function with `fn` argument, the returned function should be ignored;
* - client should call this function without `fn` argument, the returned function is the stub to call the server.
*
* This function supports bidirectional RPC when both sides are passing the `fn` argument.
*
* When calling the returned function stub, the arguments and return value are transferred over `MessagePort`.
* Thus, they will be cloned by the underlying structured clone algorithm.
*
* The returned stub has a variant `withOptions` for passing transferables and abort signal.
*
* @param {MessagePort} port - The `MessagePort` object to send the calls. The underlying `MessageChannel` must be exclusively used by this function only.
* @param {Function} fn - The function to invoke. If not set, this RPC cannot be invoked by the other side of `MessagePort`.
*
* @returns A function, when called, will invoke the function on the other side of `MessagePort`.
*/
export default function messagePortRPC<C extends Subroutine>(port: MessagePort): ClientStubWithExtra<C>;
export default function messagePortRPC<C extends Subroutine, S extends Subroutine = C>(port: MessagePort, fn: ServerStub<S>): ClientStubWithExtra<C>;
export default function messagePortRPC<C extends Subroutine, S extends Subroutine = C>(port: MessagePort, fn: ServerStub<S>, options: {
signal: AbortSignal;
}): ClientStubWithExtra<C>;
export {};