import { EventEmitter } from 'node:events';
import pg from 'pg';
import type { PoolConfig, PoolStats, CreatePoolOptions } from './types.ts';
import { type Registrable } from './registry.ts';
/**
 * A resilient PostgreSQL connection pool.
 *
 * Wraps the `pg` package's Pool and adds:
 * - Safe idle-client error handling (absorbed; pg.Pool self-heals)
 * - Query/connect retry on transient connection errors
 * - Connection state tracking
 * - Pool statistics
 *
 * @example
 * ```typescript
 * const pool = new PostgresPool({
 *   connectionString: process.env.DATABASE_URL,
 *   max: 20,
 *   reconnect: { maxAttempts: 5 }
 * });
 *
 * // Execute queries
 * const result = await pool.query('SELECT * FROM users WHERE id = $1', [userId]);
 *
 * // Close when done
 * await pool.close();
 * ```
 */
export declare class PostgresPool extends EventEmitter implements Registrable {
    private _pool;
    private _config;
    private _poolConfig;
    private _connected;
    private _reconnecting;
    private _closed;
    private _shuttingDown;
    private _signalHandlers;
    private _reconnectPromise;
    private _connectPromise;
    private _stats;
    /**
     * Creates a new PostgresPool.
     *
     * Note: By default, the actual connection is established lazily on first query.
     * Set `preconnect: true` in config to verify connectivity immediately.
     *
     * @param config - Connection configuration. Can be a connection URL string or a config object.
     *                 If not provided, uses `process.env.DATABASE_URL`.
     */
    constructor(config?: string | PoolConfig);
    /**
     * Whether the pool is currently connected.
     */
    get connected(): boolean;
    /**
     * Whether the pool is shutting down (won't attempt reconnection).
     */
    get shuttingDown(): boolean;
    /**
     * Whether a reconnection attempt is in progress.
     */
    get reconnecting(): boolean;
    /**
     * Pool statistics.
     */
    get stats(): Readonly<PoolStats>;
    /**
     * Total number of clients in the pool.
     */
    get totalCount(): number;
    /**
     * Number of idle clients in the pool.
     */
    get idleCount(): number;
    /**
     * Number of clients waiting to be acquired.
     */
    get waitingCount(): number;
    /**
     * Number of expired clients in the pool.
     */
    get expiredCount(): number;
    /**
     * Whether the pool is ending (compat with pg.Pool).
     */
    get ending(): boolean;
    /**
     * Whether the pool has ended (compat with pg.Pool).
     */
    get ended(): boolean;
    /**
     * Pool configuration options.
     */
    get options(): pg.PoolConfig;
    /**
     * Execute a query on the pool.
     * If reconnection is in progress, waits for it to complete before executing.
     * Automatically retries on retryable errors.
     *
     * @param text - The query string or query config object
     * @param values - Optional array of parameter values
     * @returns The query result
     *
     * @example
     * ```typescript
     * const result = await pool.query('SELECT * FROM users WHERE id = $1', [userId]);
     * console.log(result.rows);
     * ```
     */
    query<T extends pg.QueryResultRow = pg.QueryResultRow>(text: string | pg.QueryConfig<unknown[]>, values?: unknown[]): Promise<pg.QueryResult<T>>;
    query<T extends pg.QueryResultRow = pg.QueryResultRow>(text: string | pg.QueryConfig<unknown[]>, callback: (err: Error | null, result?: pg.QueryResult<T>) => void): void;
    query<T extends pg.QueryResultRow = pg.QueryResultRow>(text: string, values: unknown[], callback: (err: Error | null, result?: pg.QueryResult<T>) => void): void;
    /**
     * Acquire a client from the pool.
     * The client must be released back to the pool when done.
     *
     * @returns A pooled client
     *
     * @example
     * ```typescript
     * const client = await pool.connect();
     * try {
     *   await client.query('BEGIN');
     *   await client.query('INSERT INTO users (name) VALUES ($1)', ['Alice']);
     *   await client.query('COMMIT');
     * } catch (error) {
     *   await client.query('ROLLBACK');
     *   throw error;
     * } finally {
     *   client.release();
     * }
     * ```
     */
    connect(): Promise<pg.PoolClient>;
    connect(callback: (err: Error | null, client?: pg.PoolClient, release?: (err?: Error) => void) => void): void;
    /**
     * Signal that the application is shutting down.
     * This prevents reconnection attempts but doesn't immediately close the pool.
     * Use this when you want to gracefully drain connections before calling close().
     */
    shutdown(): void;
    /**
     * Close the pool and release all connections.
     * Alias for end() for compatibility with PostgresClient.
     */
    close(): Promise<void>;
    /**
     * Close the pool and release all connections.
     */
    end(): Promise<void>;
    /**
     * Access to the raw pg.Pool instance for advanced use cases.
     * Returns the underlying pg.Pool instance.
     */
    get raw(): pg.Pool;
    /**
     * Wait for the connection to be established.
     * If the connection hasn't been established yet (lazy connection), this will
     * warm the connection by acquiring and releasing a client.
     * If reconnection is in progress, waits for it to complete.
     *
     * @param timeoutMs - Optional timeout in milliseconds
     * @throws {ConnectionClosedError} If the pool has been closed or connection fails
     */
    waitForConnection(timeoutMs?: number): Promise<void>;
    /**
     * Registers signal handlers to detect application shutdown.
     * When shutdown is detected, reconnection is disabled.
     */
    private _registerShutdownHandlers;
    /**
     * Removes signal handlers registered for shutdown detection.
     */
    private _removeShutdownHandlers;
    /**
     * Initializes the pg.Pool instance.
     */
    private _initializePool;
    /**
     * Warms the connection by acquiring and releasing a client.
     * This verifies the pool can connect to the database.
     */
    private _warmConnection;
    /**
     * Handles idle-client errors from the underlying pg.Pool.
     *
     * pg.Pool emits `error` when a connected but idle client is dropped
     * (proxy idle timeout, server restart, network blip). The pool already
     * removes that client; remaining clients stay usable and the next
     * checkout opens a replacement. Treat this as a self-heal signal, not
     * pool death — do not mark the pool disconnected or tear it down.
     *
     * Emitting `error` with zero listeners crashes Node/Bun, so only forward
     * when a consumer has attached a listener.
     */
    private _handleIdleClientError;
    /**
     * Ensures the pool is initialized and returns it.
     */
    private _ensureConnected;
    /**
     * Ensures the pool is connected and returns it.
     * If reconnection is in progress, waits for it to complete.
     * If connection hasn't been established yet, warms it first.
     */
    private _ensureConnectedAsync;
    /**
     * Executes an operation with retry logic for retryable errors.
     * Waits for reconnection if one is in progress.
     */
    private _executeWithRetry;
}
/**
 * Creates a new PostgresPool.
 *
 * @param config - Connection configuration
 * @param options - Pool creation options. Set `shared: true` during Bun hot reload
 *                  development to reuse one pool across module re-evaluations.
 * @returns A PostgresPool instance
 */
export declare function createPool(config?: string | PoolConfig, options?: CreatePoolOptions): PostgresPool;
/**
 * Alias for PostgresPool for convenient imports.
 */
export { PostgresPool as Pool };
//# sourceMappingURL=pool.d.ts.map