import type { Readable, Writable } from "node:stream";
/**
 * Minimal JSON-RPC 2.0 connection over a byte stream pair with LSP-style
 * Content-Length framing. Zero dependencies by design — this module must
 * never pull in vscode-jsonrpc or any other package (hard distribution
 * constraint: LSP diagnostics add no install weight).
 */
interface JsonRpcMessage {
    jsonrpc?: string;
    id?: number | string;
    method?: string;
    params?: unknown;
    result?: unknown;
    error?: {
        code: number;
        message: string;
        data?: unknown;
    };
}
export declare class JsonRpcRequestError extends Error {
    readonly code: number;
    constructor(method: string, code: number, message: string);
}
export type NotificationHandler = (params: unknown) => void;
/** Observer for every framed message crossing the wire, in both directions. */
export type WireTracer = (direction: "out" | "in", message: JsonRpcMessage) => void;
/**
 * JSON-RPC connection speaking Content-Length framed messages.
 *
 * Server→client REQUESTS are auto-replied with safe defaults so language
 * servers never stall waiting on us: `workspace/configuration` gets one null
 * per requested item; everything else (`client/registerCapability`,
 * `window/workDoneProgress/create`, …) gets a plain null result.
 */
export declare class JsonRpcConnection {
    private readonly output;
    /**
     * Optional wire tracer. Diagnosing a server that accepts a document and
     * then never publishes requires seeing whether our notification actually
     * went out and whether anything came back — indistinguishable from outside,
     * because LSP failures are silent by design. Off unless a caller passes
     * one, so the normal path is byte-identical.
     */
    private readonly trace?;
    private buffer;
    private nextId;
    private readonly pending;
    private readonly notificationHandlers;
    private disposed;
    constructor(input: Readable, output: Writable, 
    /**
     * Optional wire tracer. Diagnosing a server that accepts a document and
     * then never publishes requires seeing whether our notification actually
     * went out and whether anything came back — indistinguishable from outside,
     * because LSP failures are silent by design. Off unless a caller passes
     * one, so the normal path is byte-identical.
     */
    trace?: WireTracer | undefined);
    onNotification(method: string, handler: NotificationHandler): void;
    request(method: string, params: unknown, timeoutMs: number): Promise<unknown>;
    notify(method: string, params?: unknown): void;
    /** Reject all in-flight requests and stop accepting new work. */
    dispose(): void;
    private send;
    private onData;
    private onMessage;
}
export {};
//# sourceMappingURL=jsonrpc.d.ts.map