import type { MessageStreamEvent } from "#protocol/message.js";
import type { MessageStreamVersion } from "#protocol/message-version.js";
import type { ClientRedirectPolicy, StreamReconnectPolicy } from "#client/types.js";
interface RetryPolicy {
    readonly baseDelayMs: number;
    readonly maxAttempts: number;
    readonly maxDelayMs: number;
}
interface ResolvedStreamReconnectPolicy {
    readonly retryableErrorStatuses: ReadonlySet<number>;
    readonly streamIdleReconnectPolicy: RetryPolicy;
    readonly streamOpenReconnectPolicy: RetryPolicy;
}
/**
 * Internal configuration for following a durable event stream.
 */
interface FollowStreamInput {
    /** Called once after consuming the durable tail captured when the connection opens. */
    readonly onCaughtUp?: () => void;
    readonly host: string;
    /** Keep following empty streams unless the caller configures an idle retry limit. */
    readonly keepAlive?: boolean;
    readonly resolveReconnectPolicy?: () => StreamReconnectPolicy | undefined;
    readonly streamReconnectPolicy?: StreamReconnectPolicy;
    /** @internal Test override for reconnecting an open stream that stops producing bytes. */
    readonly streamReadIdleTimeoutMs?: number;
    readonly resolveHeaders: () => Promise<Headers>;
    readonly redirect?: ClientRedirectPolicy;
    readonly sessionId: string;
    readonly signal?: AbortSignal;
    readonly startIndex: number;
    /** Follow the live stream after the durable tail (default). `false` bounds the read at the tail. */
    readonly follow?: boolean;
}
/** One connection open; `requestTailIndex` asks the server to report the durable tail index. */
interface OpenStreamInput extends FollowStreamInput {
    readonly requestTailIndex?: boolean;
}
/**
 * Follows a session's durable event stream from an absolute cursor,
 * transparently reconnecting whenever the transport ends.
 *
 * Transport endings reconnect from the advanced cursor. Progress resets the
 * idle budget; repeated empty streams eventually stop the follow. Callers own
 * boundary handling. Negative tail-relative cursors use one connection because
 * they cannot be advanced safely.
 *
 * With `follow: false`, the first connection fixes the bound: the iterator
 * yields events until the cursor passes that tail, reconnecting as needed,
 * then returns instead of following.
 */
export declare function followStreamIterable(input: FollowStreamInput): AsyncGenerator<MessageStreamEvent>;
/** An opened connection: the response body plus the tail index from the response header, if any. */
interface OpenedStream {
    readonly body: ReadableStream<Uint8Array>;
    close(): void;
    readonly controlVersion: "1" | undefined;
    readonly streamVersion: MessageStreamVersion;
    readonly tailIndex: number | undefined;
}
/**
 * Opens one stream response body, retrying transient failures with capped
 * exponential backoff (~35s total): brief network outages and the short
 * propagation window where a just-acknowledged session may not yet be
 * readable from the stream route.
 */
export declare function openStreamBody(input: OpenStreamInput & {
    readonly retryPolicy?: ResolvedStreamReconnectPolicy;
}): Promise<OpenedStream>;
export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
export {};
