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