/// <reference types="node" />
/// <reference types="node" />
import { BufferAndSlot, ProgramAccountSubscriber, ResubOpts } from './types';
import { DriftProgram } from '../config';
import { Commitment, Context, MemcmpFilter, PublicKey } from '@solana/web3.js';
import { AccountInfoBase, AccountInfoWithBase58EncodedData, AccountInfoWithBase64EncodedData, Address } from 'gill';
/**
 * WebSocketProgramAccountsSubscriberV2
 *
 * High-level overview
 * - WebSocket-first subscriber for Solana program accounts that also layers in
 *   targeted polling to detect missed updates reliably.
 * - Emits decoded account updates via the provided `onChange` callback.
 * - Designed to focus extra work on the specific accounts the consumer cares
 *   about ("monitored accounts") while keeping baseline WS behavior for the
 *   full program subscription.
 *
 * Why polling if this is a WebSocket subscriber?
 * - WS infra can stall, drop, or reorder notifications under network stress or
 *   provider hiccups. When that happens, critical account changes can be missed.
 * - To mitigate this, the class accepts a set of accounts (provided via constructor) to monitor
 *   and uses light polling to verify whether a WS change was missed.
 * - If polling detects a newer slot with different data than the last seen
 *   buffer, a centralized resubscription is triggered to restore a clean stream.
 *
 * Initial fetch (on subscribe)
 * - On `subscribe()`, we first perform a single batched fetch of all monitored
 *   accounts ("initial monitor fetch").
 * - Purpose: seed the internal `bufferAndSlotMap` and emit the latest state so
 *   consumers have up-to-date data immediately, even before WS events arrive.
 * - This step does not decide resubscription; it only establishes ground truth.
 *
 * Continuous polling (only for monitored accounts)
 * - After seeding, each monitored account is put into a monitoring cycle:
 *   1) If no WS notification for an account is observed for `pollingIntervalMs`,
 *      we enqueue it for a batched fetch (buffered for a short window).
 *   2) Once an account enters the "currently polling" set, a shared batch poll
 *      runs every `pollingIntervalMs` across all such accounts.
 *   3) If WS notifications resume for an account, that account is removed from
 *      the polling set and returns to passive monitoring.
 * - Polling compares the newly fetched buffer with the last stored buffer at a
 *   later slot. A difference indicates a missed update; we schedule a single
 *   resubscription (coalesced across accounts) to re-sync.
 *
 * Accounts the consumer cares about
 * - Provide accounts up-front via the constructor `accountsToMonitor`, or add
 *   them dynamically with `addAccountToMonitor()` and remove with
 *   `removeAccountFromMonitor()`.
 * - Only these accounts incur additional polling safeguards; other accounts are
 *   still processed from the WS stream normally.
 *
 * Resubscription strategy
 * - Missed updates from any monitored account are coalesced and trigger a single
 *   resubscription after a short delay. This avoids rapid churn.
 * - If `resubOpts.resubTimeoutMs` is set, an inactivity timer also performs a
 *   batch check of monitored accounts. If a missed update is found, the same
 *   centralized resubscription flow is used.
 *
 * Tuning knobs
 * - `setPollingInterval(ms)`: adjust how often monitoring/polling runs
 *   (default 30s). Shorter = faster detection, higher RPC load.
 * - Debounced immediate poll (~100ms): batches accounts added to polling right after inactivity.
 * - Batch size for `getMultipleAccounts` is limited to 100, requests are chunked
 *   and processed concurrently.
 */
export declare class WebSocketProgramAccountsSubscriberV2<T> implements ProgramAccountSubscriber<T> {
    subscriptionName: string;
    accountDiscriminator: string;
    bufferAndSlotMap: Map<string, BufferAndSlot>;
    program: DriftProgram;
    decodeBuffer: (accountName: string, ix: Buffer) => T;
    onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void;
    listenerId?: number;
    resubOpts: ResubOpts;
    isUnsubscribing: boolean;
    timeoutId?: ReturnType<typeof setTimeout>;
    options: {
        filters: MemcmpFilter[];
        commitment?: Commitment;
    };
    receivingData: boolean;
    private rpc;
    private rpcSubscriptions;
    private abortController?;
    private accountsToMonitor;
    private pollingIntervalMs;
    private pollingTimeouts;
    private lastWsNotificationTime;
    private accountsCurrentlyPolling;
    private batchPollingTimeout?;
    private debouncedImmediatePollTimeout?;
    private debouncedImmediatePollMs;
    private missedChangeDetected;
    private resubscriptionTimeout?;
    private accountsWithMissedUpdates;
    constructor(subscriptionName: string, accountDiscriminator: string, program: DriftProgram, decodeBufferFn: (accountName: string, ix: Buffer) => T, options?: {
        filters: MemcmpFilter[];
        commitment?: Commitment;
    }, resubOpts?: ResubOpts, accountsToMonitor?: PublicKey[]);
    private handleNotificationLoop;
    subscribe(onChange: (accountId: PublicKey, data: T, context: Context, buffer: Buffer) => void): Promise<void>;
    protected setTimeout(): void;
    handleRpcResponse(context: {
        slot: bigint;
    }, accountId: Address, accountInfo?: AccountInfoBase & (AccountInfoWithBase58EncodedData | AccountInfoWithBase64EncodedData)['data']): void;
    private startMonitoringForAccounts;
    private startMonitoringForAccount;
    private scheduleDebouncedImmediatePoll;
    private startBatchPolling;
    private pollAllAccounts;
    /**
     * Fetches and populates all monitored accounts data without checking for missed changes
     * This is used during initial subscription to populate data
     */
    private fetchAndPopulateAllMonitoredAccounts;
    /**
     * Fetches all monitored accounts and checks for missed changes
     * Returns true if a missed change was detected and resubscription is needed
     */
    private fetchAllMonitoredAccounts;
    private fetchAccountsBatch;
    private clearPollingTimeouts;
    /**
     * Centralized resubscription handler that only resubscribes once after checking all accounts
     */
    private handleResubscription;
    /**
     * Signal that a missed change was detected and schedule resubscription
     */
    private signalMissedChange;
    unsubscribe(onResub?: boolean): Promise<void>;
    /**
     * Add an account to the monitored set.
     * - Monitored accounts are subject to initial fetch and periodic batch polls
     *   if WS notifications are not observed within `pollingIntervalMs`.
     */
    addAccountToMonitor(accountId: PublicKey): void;
    removeAccountFromMonitor(accountId: PublicKey): void;
    /**
     * Set the monitoring/polling interval for monitored accounts.
     * Shorter intervals detect missed updates sooner but increase RPC load.
     */
    setPollingInterval(intervalMs: number): void;
    private updateBufferAndHandleChange;
}
