{"version":3,"file":"timeout.cjs","names":[],"sources":["../../src/http/timeout.ts"],"sourcesContent":["/**\n * The timeout half of `createApiClient`'s request plumbing.\n *\n * It lives beside the client rather than inside it because it is the one piece\n * with no knowledge of the SDK: given a caller's signal and a deadline it hands\n * back a signal to pass `fetch`, a way to tell whose abort fired, and the\n * cleanup. That makes it testable on its own and keeps the client file about\n * requests.\n */\n\n/** A signal to hand `fetch`, plus how to read the outcome and clean up. */\nexport interface TimedSignal {\n    /** Pass this to `fetch`. */\n    signal: AbortSignal | undefined;\n    /** Whether the abort came from the timeout rather than the caller. */\n    timedOut: () => boolean;\n    /** Clear the timer and drop the listener. Always call it. */\n    dispose: () => void;\n}\n\n/**\n * Compose the caller's signal with a timeout, tracking which one fires.\n *\n * Written with an explicit flag rather than `AbortSignal.timeout()`, whose\n * `TimeoutError` reason would tell the two apart for free. Two reasons: this\n * needs no `AbortSignal.any`, which is Baseline 2024 and would raise the\n * package's support floor for one line of convenience, and the flag is read\n * directly instead of through a reason string that a polyfill could reshape.\n *\n * A caller signal that is already aborted aborts immediately, so a request never\n * goes out for a query react-query has already cancelled.\n *\n * @param signal - The caller's signal, if any.\n * @param ms - Timeout in milliseconds, or `null` to only forward the signal.\n * @returns The composed signal, the outcome reader, and the cleanup.\n */\nexport function withTimeout(\n    signal: AbortSignal | null | undefined,\n    ms: number | null,\n): TimedSignal {\n    if (ms === null) {\n        return { signal: signal ?? undefined, timedOut: () => false, dispose: () => {} };\n    }\n\n    const controller = new AbortController();\n    let timedOut = false;\n    const timer = setTimeout(() => {\n        timedOut = true;\n        controller.abort();\n    }, ms);\n    const onAbort = (): void => controller.abort();\n\n    if (signal) {\n        if (signal.aborted) controller.abort();\n        else signal.addEventListener(\"abort\", onAbort, { once: true });\n    }\n\n    return {\n        signal: controller.signal,\n        timedOut: () => timedOut,\n        dispose: () => {\n            clearTimeout(timer);\n            signal?.removeEventListener(\"abort\", onAbort);\n        },\n    };\n}\n"],"mappings":"AAoCA,SAAgB,EACZ,EACA,EACW,CACX,GAAI,IAAO,KACP,MAAO,CAAE,OAAQ,GAAU,IAAA,GAAW,aAAgB,GAAO,YAAe,CAAC,CAAE,EAGnF,IAAM,EAAa,IAAI,gBACnB,EAAW,GACT,EAAQ,eAAiB,CAC3B,EAAW,GACX,EAAW,MAAM,CACrB,EAAG,CAAE,EACC,MAAsB,EAAW,MAAM,EAO7C,OALI,IACI,EAAO,QAAS,EAAW,MAAM,EAChC,EAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,GAG1D,CACH,OAAQ,EAAW,OACnB,aAAgB,EAChB,YAAe,CACX,aAAa,CAAK,EAClB,GAAQ,oBAAoB,QAAS,CAAO,CAChD,CACJ,CACJ"}