import type { ErrorOf } from '../../types.ts'; import { type ByteWindow } from '../../utils/ranges.ts'; export interface RetryPolicy { /** Response statuses worth retrying. */ readonly statuses: ReadonlySet; /** Retries allowed after the first attempt. */ readonly maxRetries: number; /** * Ceiling on every inter-attempt wait, whether the server asked for it * or the exponential fallback chose it. */ readonly maxBackoff: number; /** * Where the wait between attempts comes from: 'header' reads Retry-After * and falls back to exponential backoff (Graph's convention); 'body' * reads a JSON `retry_after` field and falls back to 1s (Discord's). */ readonly delaySource: 'header' | 'body'; /** * Also retry connection-level failures, which never carry a response; * the wait for those is the exponential backoff. */ readonly retryTransport?: boolean; } export declare const NO_RETRY: RetryPolicy; /** * How to read the reply: 'json' parses the body (an empty one reads as * null); 'none' ignores it; 'bytes' returns it raw, trimmed to the window * when the server ignored the Range; 'text' returns it as a string; * 'location' returns the Location header. */ export type ReadMode = 'json' | 'none' | 'bytes' | 'text' | 'location' | 'response'; /** Decoded body plus the wire metadata cursor pagination reads. Mirrors * python's `ApiResponse`; a caller asking for `read: 'response'` gets this * rather than the bare body, because a `Link` header is the only thing that * says whether another page exists. */ export interface ApiResponse { data: unknown; status: number; /** Lower-cased, the way python's dump spells them, so one header is read * by one name in both languages. */ headers: Record; } export interface ApiRequestOptions { errorOf: ErrorOf; /** Request headers, already merged by the caller. */ headers?: Record | undefined; params?: Record | undefined; /** JSON request body; absent sends no body, so a caller that means "send * an empty object" passes `{}` explicitly. */ json?: unknown; /** Raw request body (bytes, form data), for endpoints that do not speak * JSON; exclusive with `json`. */ body?: BodyInit | undefined; retry?: RetryPolicy | undefined; read?: ReadMode | undefined; /** The byte range to request; the Range header and the trim-if-unranged * guard both come from it. */ window?: ByteWindow | undefined; /** Per-attempt timeout; absent leaves the platform default. */ timeoutSeconds?: number | undefined; /** The fetch to use, so transports keep their injection seam. */ fetchFn?: typeof fetch | undefined; } /** * Whether a server-supplied delay is one we can actually wait out. NaN and * infinity are unusable (`setTimeout` silently clamps both to 1ms, turning * the wait into a hot retry), and a negative delay is malformed per RFC * 9110, so all three fall back the way an unparseable header does. */ export declare function usableDelay(value: number): boolean; export declare function headerDelay(response: Response, attempt: number, retry: RetryPolicy): number; export declare function bodyDelay(response: Response, retry: RetryPolicy): Promise; /** * One round-trip against an HTTP API, with retry and error mapping. * Returns the reply per `options.read`, defaulting to the parsed JSON * body (null when the body is empty, e.g. a 204). */ export declare function apiRequest(method: string, url: string, options: ApiRequestOptions): Promise; //# sourceMappingURL=client.d.ts.map