import type { ExchangeParams, ExchangeType, QueueParams } from "./amqp-channel.js";
/**
 * Options for {@link AMQPSession#queue}. Combines queue declaration
 * parameters (`passive`, `durable`, `autoDelete`, `exclusive`) with the
 * queue arguments table (`x-message-ttl`, `x-delivery-limit`, ...) so
 * callers don't have to pass `undefined` placeholders to reach the
 * arguments table.
 */
export type QueueOptions = QueueParams & {
    /** Queue arguments table (e.g. `{ "x-delivery-limit": 3 }`). */
    arguments?: Record<string, unknown>;
};
/**
 * Options for {@link AMQPSession#exchange} and the typed-exchange
 * shortcuts. Combines exchange declaration parameters (`passive`,
 * `durable`, `autoDelete`, `internal`) with the exchange arguments table
 * (`x-delayed-type`, `alternate-exchange`, ...).
 */
export type ExchangeOptions = ExchangeParams & {
    /** Exchange arguments table (e.g. `{ "x-delayed-type": "direct" }`). */
    arguments?: Record<string, unknown>;
};
import type { ParserMap, CoderMap, ParserRegistry, CoderRegistry } from "./amqp-codec-registry.js";
import type { AMQPProperties } from "./amqp-properties.js";
import type { ResolveBody } from "./amqp-publisher.js";
import { AMQPQueue } from "./amqp-queue.js";
import type { AMQPTlsOptions } from "./amqp-tls-options.js";
import type { Logger } from "./types.js";
import { AMQPExchange } from "./amqp-exchange.js";
import { AMQPRPCClient } from "./amqp-rpc-client.js";
import { AMQPRPCServer } from "./amqp-rpc-server.js";
import type { RPCHandler } from "./amqp-rpc-server.js";
import type { AMQPMessage } from "./amqp-message.js";
/**
 * Options for {@link AMQPSession.connect}.
 */
export interface AMQPSessionOptions<P extends ParserMap = {}, C extends CoderMap = {}, KP extends keyof P & string = never, KC extends keyof C & string = never> {
    /** Initial delay in milliseconds before reconnecting (default: 1000) */
    reconnectInterval?: number;
    /** Maximum delay in milliseconds between reconnection attempts (default: 30000) */
    maxReconnectInterval?: number;
    /** Multiplier for exponential backoff (default: 2) */
    backoffMultiplier?: number;
    /** Maximum number of reconnection attempts — 0 means infinite (default: 0) */
    maxRetries?: number;
    /** TLS options — only used when connecting via amqp/amqps */
    tlsOptions?: AMQPTlsOptions;
    /** Logger instance. Pass `null` to disable logging explicitly. */
    logger?: Logger | null;
    /** Parser registry for automatic message serialization/deserialization. */
    parsers?: ParserRegistry<P>;
    /** Coder registry for automatic message encoding/decoding. */
    coders?: CoderRegistry<C>;
    /** Default content-type applied to published messages when not set explicitly. */
    defaultContentType?: KP;
    /** Default content-encoding applied to published messages when not set explicitly. */
    defaultContentEncoding?: KC;
    /**
     * AMQP virtual host. For WebSocket URLs the URL path is the relay endpoint,
     * not the vhost — use this option to specify the vhost explicitly.
     * Defaults to `"/"` for WebSocket connections and to the URL path for TCP connections.
     */
    vhost?: string;
    /**
     * Connection name, shown in the RabbitMQ management UI. Overrides any
     * `?name=` in the URL.
     */
    name?: string;
    /**
     * Heartbeat interval in seconds (0 disables). Overrides any `?heartbeat=` in
     * the URL.
     */
    heartbeat?: number;
    /**
     * Max AMQP frame size in bytes (minimum 8192). Overrides any `?frameMax=` in
     * the URL.
     */
    frameMax?: number;
    /**
     * Max channels the session may open on this connection (0 = unlimited).
     * Overrides any `?channelMax=` in the URL.
     */
    channelMax?: number;
    /**
     * Fires after a successful (re)connection — both the initial connect and
     * every reconnect after consumer recovery completes. Registering here
     * rather than after `connect()` resolves means a single handler covers
     * both code paths.
     *
     * The session is passed in because on the initial connect this fires
     * before the `connect()` call returns, so closures over the outer
     * `session` variable would still see `undefined`. Use the argument —
     * it's the same instance either way.
     *
     * Fire-and-forget. If your handler does async setup that the rest of
     * your code depends on, drive it yourself (e.g. `await setup(session)`
     * after `connect()` resolves) and use `onconnect` to re-run it on
     * reconnects.
     */
    onconnect?(session: AMQPSession<P, C, KP, KC>): void;
    /**
     * Fires when the underlying connection drops, before the reconnect loop
     * starts. Useful for visibility into the gap between disconnect and
     * reconnect.
     */
    ondisconnect?: (error?: Error) => void;
    /** Fires when max reconnect retries are exhausted. */
    onfailed?: (error?: Error) => void;
    /**
     * Fires when the broker blocks the connection from publishing — usually
     * triggered by a resource alarm (memory or disk) on the server. Subsequent
     * publishes reject with `Connection blocked by server` until the broker
     * unblocks. Use this to apply backpressure upstream.
     */
    onblocked?: (reason: string) => void;
    /** Fires when the broker lifts a previous block on the connection. */
    onunblocked?: () => void;
    /**
     * Fires when a `mandatory: true` publish is returned by the broker because
     * it had no route to a queue. The session wires this onto every channel it
     * opens for publishing, so a single handler covers all session publishes.
     */
    onreturn?: (msg: AMQPMessage<P>) => void;
}
/**
 * High-level session with automatic reconnection and consumer recovery.
 *
 * The generic parameters thread parser/coder type information through all
 * session-owned handles (queues, exchanges, RPC clients/servers).
 *
 * Users never write the generics explicitly — they're inferred from the `connect()` call.
 *
 * Create via `AMQPSession.connect(url, options)`.
 */
export declare class AMQPSession<P extends ParserMap = {}, C extends CoderMap = {}, KP extends keyof P & string = never, KC extends keyof C & string = never> {
    private readonly onconnect?;
    private readonly ondisconnect?;
    private readonly onfailed?;
    private readonly onreturn?;
    private readonly client;
    /** `true` when the underlying connection is closed. */
    get closed(): boolean;
    private readonly options;
    private readonly queues;
    private readonly rpcClients;
    private reconnectAttempts;
    private reconnectTimer;
    private reconnectResolve;
    private reconnecting;
    private stopped;
    private opsChannel;
    private confirmChannel;
    private opsChannelPromise;
    private confirmChannelPromise;
    private constructor();
    private logTag;
    /**
     * Connect to an AMQP broker and return a session with automatic reconnection.
     *
     * The transport is chosen from the URL scheme:
     * - `amqp://` / `amqps://` → TCP socket (`AMQPClient`)
     * - `ws://` / `wss://` → WebSocket (`AMQPWebSocketClient`)
     */
    static connect<P extends ParserMap = {}, C extends CoderMap = {}, KP extends keyof P & string = never, KC extends keyof C & string = never>(url: string, options?: AMQPSessionOptions<P, C, KP, KC>): Promise<AMQPSession<P, C, KP, KC>>;
    private wireReturnHandler;
    private wireManagedChannelErrorHandler;
    private opsLock;
    /**
     * Declare a queue and return a session-bound {@link AMQPQueue} handle.
     * The returned queue's `subscribe` uses auto-recovery and `publish` waits for
     * a broker confirm.
     *
     * Subsequent calls with the same (non-empty) name return the cached handle
     * without redeclaring, and `options` on those calls are ignored.
     *
     * Server-named queues (declared with `""`) are not cached or tracked for
     * auto-recovery: every call declares a fresh queue, and the broker assigns a
     * new name on every connection, so the old name is dead after a reconnect and
     * can't be recovered. Neither the queue nor its consumers are auto-recovered —
     * `AMQPQueue.subscribe()` recovery does not apply here. Re-declare such a queue
     * in an {@link AMQPSessionOptions.onconnect} handler — it runs again after every
     * reconnect — and bind/subscribe there.
     * @param name - queue name (use "" to let the broker generate a name)
     * @param [options] - queue declaration parameters and queue arguments
     */
    queue(name: string, options?: QueueOptions): Promise<AMQPQueue<P, C, KP, KC>>;
    /**
     * Declare an exchange and return a session-bound {@link AMQPExchange} handle.
     * @param name - exchange name
     * @param type - exchange type: `"direct"`, `"fanout"`, `"topic"`, `"headers"`, or a custom type
     * @param [options] - exchange declaration parameters and exchange arguments
     */
    exchange(name: string, type: ExchangeType, options?: ExchangeOptions): Promise<AMQPExchange<P, C, KP, KC>>;
    /**
     * Declare a direct exchange and return a session-bound {@link AMQPExchange} handle.
     * @param [name="amq.direct"] - exchange name
     */
    directExchange(name?: string, options?: ExchangeOptions): Promise<AMQPExchange<P, C, KP, KC>>;
    /**
     * Declare a fanout exchange and return a session-bound {@link AMQPExchange} handle.
     * @param [name="amq.fanout"] - exchange name
     */
    fanoutExchange(name?: string, options?: ExchangeOptions): Promise<AMQPExchange<P, C, KP, KC>>;
    /**
     * Declare a topic exchange and return a session-bound {@link AMQPExchange} handle.
     * @param [name="amq.topic"] - exchange name
     */
    topicExchange(name?: string, options?: ExchangeOptions): Promise<AMQPExchange<P, C, KP, KC>>;
    /**
     * Declare a headers exchange and return a session-bound {@link AMQPExchange} handle.
     * @param [name="amq.headers"] - exchange name
     */
    headersExchange(name?: string, options?: ExchangeOptions): Promise<AMQPExchange<P, C, KP, KC>>;
    /**
     * Perform an RPC call: publish a message and wait for the response.
     * Creates a temporary client per call — simple and sufficient for most use cases.
     *
     * For high-throughput scenarios where the per-call channel overhead matters,
     * use {@link rpcClient} to create a reusable client instead.
     *
     * @param queue - The routing key / queue name of the RPC server
     * @param body - The request body
     * @param options - Optional AMQP properties and timeout
     * @param options.timeout - Timeout in milliseconds
     * @returns The reply {@link AMQPMessage}
     */
    rpcCall(queue: string, body: ResolveBody<P, KP>, options?: AMQPProperties & {
        timeout?: number;
    }): Promise<AMQPMessage<P>>;
    /**
     * Create and start a reusable RPC client that keeps its channel open
     * across multiple calls. Prefer {@link rpcCall} for simplicity; use this
     * when you need to avoid the per-call channel overhead.
     *
     * @returns A started {@link AMQPRPCClient} ready for {@link AMQPRPCClient.call} invocations.
     */
    rpcClient(): Promise<AMQPRPCClient<P, C, KP, KC>>;
    /**
     * Create and start an RPC server that consumes from the given queue.
     * Each incoming message is passed to `handler`; the returned value is
     * published back to the caller's `replyTo` address.
     *
     * @param queue - Queue name to consume from
     * @param handler - Callback that receives the decoded message, returns the response body
     * @param prefetch - Channel prefetch count (default: 1)
     * @returns A started {@link AMQPRPCServer}
     */
    rpcServer(queue: string, handler: RPCHandler<P, KP>, prefetch?: number): Promise<AMQPRPCServer<P, C, KP, KC>>;
    /**
     * Stop the session: cancel reconnection, clear consumer tracking,
     * and close the underlying connection.
     */
    stop(reason?: string): Promise<void>;
    private reconnectLoop;
    private waitBeforeRetry;
    private cancelWait;
    private recoverQueues;
}
//# sourceMappingURL=amqp-session.d.ts.map