/** * Cancellation and deadline plumbing shared by the ergonomic layer. * * Two facts shape this module. Handing a signal to `fetch` does **not** bound a call: the * generated client awaits authentication and request interceptors before it constructs the * `Request` (see `client/client/client.gen.ts`), and a caller-supplied `fetch` may ignore * the signal entirely. So a deadline both carries a signal *and* offers {@link Deadline.fired} * to race the whole execution against. * * And a cancelled call must still speak the result contract. Anything that waits here * reports cancellation as a value rather than rejecting, so a `DOMException` never escapes * to a caller who was promised `{ data, error }`. */ import { NeonAbortError, NeonRequestTimeoutError } from "./errors.js"; /** Why a bounded wait ended. */ export type DelayOutcome = "elapsed" | "cancelled"; /** What ended a call: the caller's own signal, or the request-timeout budget. */ export type DeadlineSource = "caller" | "timeout"; export interface Deadline { /** * Attach to every request the call makes. `undefined` when the call is unbounded and * the caller passed no signal, so nothing extra is allocated for the common case. */ readonly signal: AbortSignal | undefined; /** Finite `requestTimeoutMs` when this deadline has a request budget. */ readonly timeoutMs: number | undefined; /** Budget left in milliseconds; `Infinity` when no request timeout applies. */ remainingMs(): number; /** * What ended the call, or `undefined` while it may still proceed. * * Reads the clock rather than trusting the timer to have run, and trips the deadline * itself if the budget is already spent. A loop that only ever awaits * already-resolved promises — paginating a cursor the API keeps repeating, say — * yields to the microtask queue but never to the timer phase, so a timer-only * deadline would never fire and the call would spin forever. */ source(): DeadlineSource | undefined; /** * Resolves when the deadline fires, and otherwise never settles. Used to bound the * phases a request signal cannot reach. Never rejects. */ fired(): Promise; /** Release the timer and the caller-signal listener. Safe to call more than once. */ dispose(): void; } /** * Normalize a `requestTimeoutMs`, rejecting values `setTimeout` would mistreat. * * Shared by the client config and by per-call overrides — validating only at construction * left `requestTimeoutMs: NaN` on a call silently meaning *unbounded*, and a value past * {@link MAX_TIMER_MS} silently meaning *1ms*. Both are worse than an error, because the * call still returns a plausible-looking result. * * `undefined` and `Infinity` both mean unbounded; `Infinity` is the documented way to opt * a single call out of a client-wide deadline. */ export declare function resolveTimeoutMs(value: number | undefined): number; /** * The typed error for a deadline that has fired, or `undefined` if it has not. * * Cancellation is classified from the deadline's own state rather than from the shape of * the error that came back. The generated client funnels authentication, serialization, * interceptor, transport and parsing faults through one channel, so an error merely named * `AbortError` is not evidence that the caller cancelled. */ export declare function cancelled(deadline: Deadline): NeonAbortError | NeonRequestTimeoutError | undefined; /** * Race `run()` against the deadline, resolving `undefined` when the deadline wins. * * The signal alone does not bound a call. The generated client awaits authentication and * request interceptors before it constructs the `Request`, and a caller-supplied `fetch` * need not honour a signal at all, so an `apiKey` function that never resolves would * otherwise hang forever even with a deadline set. */ export declare function runBounded(deadline: Deadline, run: () => Promise): Promise; /** * Wait `ms`, or stop early when `signal` aborts. Resolves either way — an abort is * reported as `"cancelled"` rather than thrown, and the listener is always removed so a * long-lived caller signal doesn't accumulate one per wait. */ export declare function delay(ms: number, signal?: AbortSignal): Promise; /** * Build the deadline for one call. * * `timeoutMs` is `Infinity` when no request timeout applies. With no timeout and no caller * signal there is nothing to cancel, so a shared no-op deadline is returned and no timer * or controller is allocated. */ export declare function createDeadline(timeoutMs: number, callerSignal?: AbortSignal): Deadline; //# sourceMappingURL=deadline.d.ts.map