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 };
