UNPKG

message-port-rpc

Version:

Turns a MessagePort into an remote procedure call (RPC) stub.

96 lines (92 loc) 5.95 kB
type GeneratorSubroutine = (...args: any[]) => AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>; type CallInit$1 = { signal?: AbortSignal; transfer?: Transferable[]; }; type NextOfGenerator<T extends AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>> = T extends AsyncGenerator<unknown, unknown, infer U> ? U : T extends Generator<unknown, unknown, infer V> ? V : never; type ReturnOfGenerator<T extends AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>> = T extends AsyncGenerator<unknown, infer U> ? U : T extends Generator<unknown, infer V> ? V : never; type YieldOfGenerator<T extends AsyncGenerator | Generator | AsyncIterator<unknown> | Iterator<unknown>> = T extends AsyncGenerator<infer U> ? U : T extends Generator<infer U> ? U : T extends AsyncIterator<infer U> ? U : T extends Iterator<infer U> ? U : never; type ClientGeneratorStub<T extends GeneratorSubroutine> = (...args: Parameters<T>) => AsyncGenerator<YieldOfGenerator<ReturnType<T>>, ReturnOfGenerator<ReturnType<T>>, NextOfGenerator<ReturnType<T>>>; type ClientGeneratorStubWithExtra<T extends GeneratorSubroutine> = ClientGeneratorStub<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$1) => ClientGeneratorStub<T>; }; type ServerStub$1<T extends GeneratorSubroutine> = (...args: Parameters<T>) => ReturnType<T>; /** * Binds a generator 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 generator function with `fn` argument, the returned function should be ignored; * - client should call this generator 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. * * Notes: if `next()` is used on the client stub and did not iterate until `{ done: true }`, caller must use the `withOptions({ signal: AbortSignal })` * to release resources. * * @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 generator function to invoke. If not set, this RPC cannot be invoked by the other side of `MessagePort`. * * @returns An asynchronous generator function, when called, will invoke the generator function on the other side of `MessagePort`. */ declare function forGenerator<C extends GeneratorSubroutine>(port: MessagePort): ClientGeneratorStubWithExtra<C>; declare function forGenerator<C extends GeneratorSubroutine, S extends GeneratorSubroutine = C>(port: MessagePort, fn: ServerStub$1<S>): ClientGeneratorStubWithExtra<C>; declare function forGenerator<C extends GeneratorSubroutine, S extends GeneratorSubroutine = C>(port: MessagePort, fn: ServerStub$1<S>, options: { signal: AbortSignal; }): ClientGeneratorStubWithExtra<C>; type ReturnValueOfPromise<T> = T extends Promise<infer R> ? R : T; type Subroutine = (...args: any[]) => Promise<unknown> | unknown; type CallInit = { signal?: AbortSignal | undefined; transfer?: readonly Transferable[] | undefined; }; 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 An asynchronous function, when called, will invoke the function on the other side of `MessagePort`. */ declare function messagePortRPC<C extends Subroutine>(port: MessagePort): ClientStubWithExtra<C>; declare function messagePortRPC<C extends Subroutine, S extends Subroutine = C>(port: MessagePort, fn: ServerStub<S>): ClientStubWithExtra<C>; declare function messagePortRPC<C extends Subroutine, S extends Subroutine = C>(port: MessagePort, fn: ServerStub<S>, options: { signal: AbortSignal; }): ClientStubWithExtra<C>; export { forGenerator, messagePortRPC };