import type { HttpMethods, DictAndT, FetchResponse } from '../types.ts'; import type { FetchError } from '../helpers/fetch-error.ts'; /** * Base event data payload for FetchEngine events. * * Contains common fields shared across all fetch-related events. * * @template S - Instance state type * @template H - Instance headers type * @template P - Instance params type */ export interface EventData { state: S; url?: string | URL | undefined; method?: HttpMethods | undefined; headers?: DictAndT | undefined; params?: DictAndT

| undefined; error?: Error | FetchError> | undefined; response?: Response | undefined; data?: unknown; payload?: unknown; attempt?: number | undefined; nextAttempt?: number | undefined; delay?: number | undefined; step?: 'fetch' | 'parse' | undefined; status?: number | undefined; path?: string | undefined; aborted?: boolean | undefined; /** Unique ID for this request, flows through all events */ requestId?: string | undefined; /** Timestamp (ms) when the request entered the execution pipeline */ requestStart?: number | undefined; /** Timestamp (ms) when the request resolved (success, error, or abort) */ requestEnd?: number | undefined; } /** * Event data for deduplication events. * * Extends base event data with deduplication-specific fields. * * @template S - Instance state type * @template H - Instance headers type * @template P - Instance params type */ export interface DedupeEventData extends EventData { /** The generated deduplication key */ key: string; /** Number of callers waiting on this request (join events only) */ waitingCount?: number | undefined; } /** * Event data for cache events. * * Extends base event data with cache-specific fields. * * @template S - Instance state type * @template H - Instance headers type * @template P - Instance params type */ export interface CacheEventData extends EventData { /** The generated cache key */ key: string; /** Whether the cache entry is stale (SWR) */ isStale?: boolean | undefined; /** Time until expiration (ms) */ expiresIn?: number | undefined; /** * The cause of a `cache-revalidate-error`: either a transport `FetchError` * or a resolved `ok: false` `FetchResponse` (a non-2xx revalidation never * throws under resolve-on-response, so the cause isn't always an `Error`). */ outcome?: FetchResponse, DictAndT

> | FetchError> | undefined; } /** * Event data for rate limit events. * * Extends base event data with rate limiting-specific fields. * * @template S - Instance state type * @template H - Instance headers type * @template P - Instance params type */ export interface RateLimitEventData extends EventData { /** The rate limit bucket key */ key: string; /** Current tokens available in the bucket */ currentTokens: number; /** Maximum capacity of the bucket */ capacity: number; /** Time to wait before next token is available (ms) */ waitTimeMs: number; /** When the next token will be available */ nextAvailable: Date; } /** * Event data for retry events. * * Extends base event data with the outcome that triggered the retry — a * resolved `ok: false` response for an HTTP-status retry, or a rejected * transport `FetchError` for a transport retry. Mirrors the union * `shouldRetry` is invoked with. * * @template S - Instance state type * @template H - Instance headers type * @template P - Instance params type */ export interface RetryEventData extends EventData { /** The response or error that triggered this retry attempt. */ outcome: FetchResponse, DictAndT

> | FetchError>; } /** * Event data for state mutation events. * * @template S - Instance state type */ export interface StateEventData { /** Key that was set (for single key updates) */ key?: keyof S | undefined; /** Value that was set */ value?: S[keyof S] | Partial | undefined; /** Previous state before the change */ previous?: S | undefined; /** Current state after the change */ current: S; } /** * Event data for property (header/param) events. * * @template T - Property type (headers or params) */ export interface PropertyEventData { /** Key that was added/removed */ key?: string | string[] | undefined; /** Value that was set (for add events) */ value?: string | Partial | undefined; /** HTTP method this change applies to (undefined = all methods) */ method?: HttpMethods | undefined; } /** * Event data for options change events. */ export interface OptionsEventData { /** Path that was changed (for path-based sets) */ path?: string | undefined; /** Value that was set */ value?: unknown; } /** * Event map for FetchEngine - maps event names to their data types. * * Event names have been simplified by removing the `fetch-` prefix. * This provides cleaner API while maintaining full type safety. * * @template S - Instance state type * @template H - Instance headers type * @template P - Instance params type * * @example * ```typescript * // Subscribe to events * engine.on('before-request', (data) => console.log('Request starting:', data.url)); * engine.on('cache-hit', (data) => console.log('Cache hit:', data.key)); * engine.on('state-set', (data) => console.log('State changed:', data.current)); * ``` */ export interface EventMap { 'before-request': EventData; 'after-request': EventData; 'abort': EventData; /** Transport failure or a parse failure on an `ok: true` body. Never non-2xx. */ 'error': EventData; /** Fires for every completed exchange, any status. */ 'response': EventData; /** Fires alongside `response` when `status` is 400-499. */ 'response-4xx': EventData; /** Fires alongside `response` when `status` is 500-599. */ 'response-5xx': EventData; 'retry': RetryEventData; 'header-add': PropertyEventData>; 'header-remove': PropertyEventData>; 'param-add': PropertyEventData>; 'param-remove': PropertyEventData>; 'state-set': StateEventData; 'state-reset': StateEventData; 'config-change': OptionsEventData; 'url-change': { url: string; state: S; }; 'dedupe-start': DedupeEventData; 'dedupe-join': DedupeEventData; 'cache-hit': CacheEventData; 'cache-stale': CacheEventData; 'cache-miss': CacheEventData; 'cache-set': CacheEventData; 'cache-revalidate': CacheEventData; 'cache-revalidate-error': CacheEventData; 'ratelimit-wait': RateLimitEventData; 'ratelimit-reject': RateLimitEventData; 'ratelimit-acquire': RateLimitEventData; /** Terminal event for a wait that ended because the request aborted. Pairs with `ratelimit-wait`. */ 'ratelimit-abort': RateLimitEventData; } /** * Helper type to extract event names from EventMap. */ export type EventNames = keyof EventMap;