/**
 * clientSet — which clients the pool holds, and in which of its two sets.
 *
 * Pattern: two sets and their indexes, mutated only together.
 * Role:    § 5.3 of the design. The OPEN set holds every client that counts
 *          toward `maxClients` — opening, busy, idle, deferred, or an abandoned
 *          open that has not settled. The ENDING set holds every client from the
 *          decision to end it until that ending's work has settled, and counts
 *          toward `maxEnding`. A client leaves the open set only into the ending
 *          set — a lost handle too: its ending is its local close — or, when its
 *          open failed and left nothing to end, by being dropped. So the pool
 *          holds at most `maxClients + maxEnding` client objects.
 *
 * Each key has at most one CURRENT client — the one new leases go to. A client
 * named by `terminate`, or whose session expired, stops being current at once
 * while it stays in the open set, counted, until it can end.
 *
 * What the pool remembers of a key after its client left — the incarnation
 * count and why the last one left — is bounded (`KEY_MEMORY`), least recently
 * used forgotten first: after that a key's count starts again at 1. The record
 * reads it; no binding depends on it.
 */
import type { EndReason, PooledClient } from './pooledClient.js';
/** How many keys' incarnation counts the pool remembers. */
export declare const KEY_MEMORY = 4096;
/** Why a key's previous client left, as the record names it. */
export type PreviousEnd = 'idle' | 'evicted' | 'expired' | 'handle-lost' | 'terminated';
export declare class ClientSet {
    private readonly open;
    private readonly ending;
    private readonly current;
    private readonly perPrincipal;
    private readonly memory;
    /** Clients in the open set. */
    get openCount(): number;
    /** Clients in the ending set. */
    get endingCount(): number;
    /** Every client in the open set. */
    openClients(): readonly PooledClient[];
    /** Clients of the open set that count for `principal`. */
    principalCount(principal: string): number;
    /** The key's current client — opening or open, taking new leases — if it has one. */
    currentFor(key: string): PooledClient | undefined;
    /** The next incarnation number for `key`, and why its previous client left. */
    nextIncarnation(key: string): {
        readonly generation: number;
        readonly previous?: PreviousEnd;
    };
    /** A new client joins the open set as its key's current client. */
    admit(client: PooledClient): void;
    /**
     * The client stops taking new leases: its key has no current client until the
     * next open, and that open's record says `why`. A client that is no longer
     * its key's current one has already left it, so nothing is recorded again —
     * a later client of the key keeps its own reason.
     */
    retire(client: PooledClient, why: PreviousEnd): void;
    /** The client moves from the open set into the ending set. */
    moveToEnding(client: PooledClient, why: PreviousEnd | undefined): void;
    /** The client's ending settled: it leaves the ending set. */
    ended(client: PooledClient): void;
    /** The client leaves the open set without ending — a failed open, a lost handle. */
    drop(client: PooledClient, why?: PreviousEnd): void;
    /**
     * The least recently used idle client of the open set — among those `pick`
     * accepts — or `undefined` when every one is busy.
     */
    leastRecentlyUsedIdle(pick: (client: PooledClient) => boolean): PooledClient | undefined;
    private leaveOpen;
    private remember;
}
/** The record's `previous` for an end reason, when it names one. */
export declare function previousOf(reason: EndReason): PreviousEnd | undefined;
//# sourceMappingURL=clientSet.d.ts.map