/**
 * Transport — `fetch` wrapper with timeout, exponential-backoff
 * retries, and a normalized {@link TransportError} for predictable
 * downstream handling.
 *
 * Zero dependencies. Vanilla-JS-friendly — drop into CodePen,
 * StackBlitz, or any vanilla project.
 *
 * Runtime exports mirror `core/transport.js`. `.d.ts` authored in
 * v0.5.6 §191 to close the §178 audit-script baseline missing-sibling
 * gap.
 *
 * @see ./transport.js (runtime SoT)
 */

/**
 * Discriminator for {@link TransportError} kinds. Lets consumers
 * branch on user-cancellation (`abort`) vs network errors (`network`)
 * vs HTTP-level non-2xx (`http`) vs timeout exhaustion (`timeout`).
 */
export type TransportErrorKind = 'abort' | 'timeout' | 'network' | 'http';

/**
 * Options for {@link request} and {@link json}.
 */
export interface TransportOptions {
  /** Standard `fetch` init forwarded as-is (method, headers, body, …). */
  init?: RequestInit;
  /** Per-request timeout in ms. Default: 30 000. Aborts the underlying fetch. */
  timeout?: number;
  /** Retry attempts on 5xx + network failures. Default: 0. */
  retries?: number;
  /** Base retry delay in ms; exponential backoff applies. Default: 1000. */
  retryDelay?: number;
  /** External `AbortSignal` — aborts the request + skips retries. */
  signal?: AbortSignal;
}

/**
 * Resilient `fetch` with timeout + retries. Returns the raw `Response`
 * — consumers handle status codes (the `request()` path does NOT throw
 * on non-2xx responses; use {@link json} when 2xx-only is desired).
 *
 * Throws {@link TransportError} on:
 *  - Caller-driven abort (`kind: 'abort'`)
 *  - Timeout exhaustion (`kind: 'timeout'`)
 *  - Network failure after retries exhausted (`kind: 'network'`)
 */
export function request(url: string, options?: TransportOptions): Promise<Response>;

/**
 * JSON-typed variant of {@link request}. On 2xx responses, returns the
 * parsed JSON body. On non-2xx responses, throws {@link TransportError}
 * with `kind: 'http'` + the status code + the body (parsed as JSON if
 * possible, else raw text).
 */
export function json<T = unknown>(url: string, options?: TransportOptions): Promise<T>;

/**
 * Normalized error thrown by {@link request} and {@link json}. The
 * `kind` discriminator lets consumers branch on user-cancellation vs
 * timeout vs network vs HTTP-level failures.
 *
 * Inherits `message` + `cause` from `Error`.
 */
export class TransportError extends Error {
  /** Error category — see {@link TransportErrorKind}. */
  kind: TransportErrorKind;
  /** HTTP status code on `kind: 'http'`; `undefined` otherwise. */
  status?: number;
  /** Response body on `kind: 'http'` (parsed JSON or raw text). */
  body?: unknown;

  constructor(
    message: string,
    options?: { kind?: TransportErrorKind; status?: number; body?: unknown; cause?: unknown },
  );
}
