import * as Timeout from './Timeout.js' /** Installs the default outbound fetch timeout once for this runtime. */ export function install(): void { if (isInstalled(globalThis.fetch)) return const fetch = withTimeout(globalThis.fetch.bind(globalThis), { timeout: Timeout.duration }) Object.defineProperty(fetch, timeoutMarker, { value: true }) globalThis.fetch = fetch } /** Adds a default maximum duration to fetch calls that do not carry a signal. */ export function withTimeout( fetch: typeof globalThis.fetch, options: withTimeout.Options, ): typeof globalThis.fetch { return ((input, init) => { const signal = resolveSignal(input, { init, timeout: options.timeout }) return fetch(input, { ...init, signal }) }) as typeof globalThis.fetch } /** Resolves a caller signal or creates the default fetch deadline signal. */ export function resolveSignal( input: Parameters[0], options: resolveSignal.Options, ): AbortSignal { return ( options.init?.signal ?? (input instanceof Request ? input.signal : Timeout.signal({ timeout: options.timeout })) ) } export declare namespace resolveSignal { /** Options for {@link resolveSignal}. */ type Options = { /** Optional fetch initialization carrying a caller signal. */ init?: Parameters[1] /** Default maximum duration in milliseconds. */ timeout: number } } export declare namespace withTimeout { /** Options for {@link withTimeout}. */ type Options = { /** Maximum fetch duration in milliseconds. */ timeout: number } } const timeoutMarker = Symbol.for('tempo.api.fetch.timeout') function isInstalled(fetch: typeof globalThis.fetch): boolean { return timeoutMarker in fetch }