/** * Engine Config Types * * This file defines the Config interface independently of the FetchEngine class * to avoid circular dependencies. The FetchEngine.Config namespace type in * types.ts is defined to match this interface. */ import type { HookCallback } from '@logosdx/hooks'; import type { _InternalHttpMethods, HttpMethodOpts, RetryConfig, DeduplicationConfig, CacheConfig, RateLimitConfig, DictAndT, MethodHeaders } from '../types.ts'; import type { FetchError } from '../helpers/fetch-error.ts'; import type { FetchLifecycle, FetchPlugin } from '../engine/types.ts'; import type { CookieConfig } from '../plugins/cookies/types.ts'; /** * Response type that can be returned from the server. */ export type EngineType = 'arrayBuffer' | 'blob' | 'formData' | 'json' | 'text'; /** * Base headers interface that users can augment. */ export interface InstanceHeaders { Authorization?: string; 'Content-Type'?: string; Accept?: string; 'Accept-Language'?: string; } /** * Base params interface that users can augment. */ export interface InstanceParams { } /** * Base state interface that users can augment. */ export interface InstanceState { } /** * Result from determineType function. */ export interface DetermineTypeResult { type: Exclude; isJson: boolean; } /** * Function type for determining response body type. */ export interface DetermineTypeFn { (response: Response): DetermineTypeResult; } /** * Base request configuration shared between per-request and instance-level config. * * Extends native fetch RequestInit with typed headers/params and timeout settings. * This is the foundation for both CallConfig and EngineConfig. * * @template H - Headers type * @template P - Params type */ export interface RequestConfig extends Omit { /** Request headers (merged with instance defaults) */ headers?: DictAndT | undefined; /** URL parameters (merged with instance defaults) */ params?: DictAndT

| undefined; /** AbortSignal for request cancellation */ signal?: AbortSignal | undefined; /** Total timeout for entire request lifecycle including retries (ms) */ totalTimeout?: number | undefined; /** Per-attempt timeout (ms) - each retry gets fresh timeout */ attemptTimeout?: number | undefined; /** Function to determine response body type based on response */ determineType?: DetermineTypeFn | undefined; /** Retry configuration */ retry?: RetryConfig | boolean | undefined; } /** * Per-request configuration passed to HTTP methods (get, post, etc). * * Extends RequestConfig with per-request lifecycle hooks and abort controller. * * @template H - Headers type * @template P - Params type */ export interface CallConfig extends RequestConfig, EngineLifecycle { /** AbortController for manual request cancellation */ abortController?: AbortController | undefined; /** * Per-request hooks appended after all engine-level hooks. * * These run at the end of the hook chain for this single request only. */ hooks?: { beforeRequest?: HookCallback['beforeRequest']>; afterRequest?: HookCallback['afterRequest']>; } | undefined; /** * Override the auto-generated request ID for this request. * * When provided, this value is used instead of `generateRequestId()` * or the default `generateId()`. Useful for propagating an external * trace ID from an upstream service or user-defined correlation ID. * * @example * ```typescript * await api.get('/orders', { * requestId: incomingTraceId * }); * ``` */ requestId?: string | undefined; /** * Bypass the response cache for this request — no lookup, no store. * * The request always hits the network, and its response does not * overwrite any existing cache entry. */ skipCache?: boolean | undefined; /** @deprecated Use totalTimeout instead */ timeout?: number | undefined; } /** * Request config passed to callbacks. * * This is what callbacks receive - includes the controller that was created * for the request. */ export interface EngineRequestConfig extends RequestConfig { /** The AbortController created for this request */ controller: AbortController; } /** * Lifecycle hooks for requests. */ export interface EngineLifecycle { onError?: ((err: FetchError) => void | Promise) | undefined; onBeforeReq?: ((opts: EngineRequestConfig) => void | Promise) | undefined; onAfterReq?: ((response: Response, opts: EngineRequestConfig) => void | Promise) | undefined; } /** * Validation configuration for headers, params, and state. */ export interface ValidateConfig { headers?: ((headers: DictAndT, method?: _InternalHttpMethods) => void) | undefined; params?: ((params: DictAndT

, method?: _InternalHttpMethods) => void) | undefined; state?: ((state: S) => void) | undefined; perRequest?: { headers?: boolean | undefined; params?: boolean | undefined; } | undefined; } /** * Full configuration options for FetchEngine. * * This is the primary configuration interface. It's defined here * independently of the FetchEngine class to avoid circular dependencies. * * Extends native fetch RequestInit to allow instance-level defaults for * options like `credentials`, `mode`, `cache`, `redirect`, etc. * * @template H - Headers type * @template P - Params type * @template S - State type */ export interface EngineConfig extends Omit, EngineLifecycle { /** * The base URL for all requests. */ baseUrl: string; /** * The default type of response expected from the server. */ defaultType?: EngineType | undefined; /** * The headers to be set on all requests. */ headers?: DictAndT | undefined; /** * The headers to be set on requests of a specific method. */ methodHeaders?: MethodHeaders | undefined; /** * URL parameters to be set on all requests. */ params?: DictAndT

| undefined; /** * URL parameters to be set on requests of a specific method. */ methodParams?: HttpMethodOpts>> | undefined; /** * Validators for headers, params, and state. */ validate?: ValidateConfig; /** * Optional name for this FetchEngine instance. */ name?: string | undefined; /** * Spy function that receives all event emissions. */ spy?: ((action: { event: string | RegExp | '*'; fn: 'on' | 'once' | 'off' | 'emit' | 'cleanup'; data?: unknown; listener?: Function | null; context: any; }) => void) | undefined; /** * Deduplication policy configuration. */ dedupePolicy?: boolean | DeduplicationConfig | undefined; /** * Cache policy configuration. */ cachePolicy?: boolean | CacheConfig | undefined; /** * Rate limit policy configuration. */ rateLimitPolicy?: boolean | RateLimitConfig | undefined; /** * Cookie management configuration. * * `true` enables a basic in-memory cookie jar with RFC 6265 defaults. * Pass a `CookieConfig` to configure persistence adapters, limits, or * domain exclusions. For full control (init/flush/jar access), use * `plugins: [cookiePlugin(config)]` instead. */ cookies?: boolean | CookieConfig | undefined; /** * Plugins to install at construction time. * * Each plugin's `install()` is called with the engine instance. * Cleanup functions are collected and called on `destroy()`. */ plugins?: FetchPlugin[] | undefined; /** * Custom function to generate request IDs for tracing. * When omitted, uses `generateId` from `@logosdx/utils`. */ generateRequestId?: (() => string) | undefined; /** * Header name for sending the request ID with every request. * * When set, each outgoing request includes this header with the * generated `requestId` value, enabling end-to-end distributed tracing. * * @example * ```typescript * const api = new FetchEngine({ * baseUrl: 'https://api.example.com', * requestIdHeader: 'X-Request-Id' * }); * ``` */ requestIdHeader?: string | undefined; totalTimeout?: number | undefined; attemptTimeout?: number | undefined; determineType?: DetermineTypeFn | undefined; retry?: RetryConfig | boolean | undefined; }