/** * @file DataLoader Batching * @description DataLoader-inspired request batching with automatic coalescing, * caching, deduplication, and GraphQL batch query support. * Optimized for microservices with N+1 query prevention. */ /** * Batch function that processes multiple keys at once */ export type BatchFunction = (keys: K[]) => Promise | V[] | (V | Error)[]>; /** * Cache key serializer */ export type KeySerializer = (key: K) => string; /** * DataLoader configuration */ export interface DataLoaderConfig { /** Maximum items per batch */ maxBatchSize?: number; /** Maximum wait time before executing batch (ms) */ batchInterval?: number; /** Batch execution function */ batchFn: BatchFunction; /** Enable caching */ cache?: boolean; /** Cache TTL (ms) */ cacheTtl?: number; /** Key serializer for cache */ keySerializer?: KeySerializer; /** Handle batch errors */ onBatchError?: (error: Error, keys: K[]) => void; /** Handle individual item errors */ onItemError?: (error: Error, key: K) => void; /** Enable coalescing of identical requests */ coalesce?: boolean; /** Schedule batch on next tick */ batchScheduler?: (callback: () => void) => ReturnType; } /** * DataLoader statistics */ export interface DataLoaderStats { /** Total loads requested */ totalLoads: number; /** Cache hits */ cacheHits: number; /** Cache misses */ cacheMisses: number; /** Batches executed */ batchesExecuted: number; /** Average batch size */ avgBatchSize: number; /** Coalesced requests */ coalescedRequests: number; /** Current cache size */ cacheSize: number; } /** * DataLoader for batching and caching requests * Inspired by Facebook's DataLoader pattern */ export declare class DataLoader { private config; private batch; private cache; private batchTimer; private cacheCleanupTimer; private stats; constructor(config: DataLoaderConfig); /** * Dispose of the loader and clean up resources */ dispose(): void; /** * Load a single value by key */ load(key: K): Promise; /** * Load multiple values by keys */ loadMany(keys: K[]): Promise<(V | Error)[]>; /** * Prime the cache with a value */ prime(key: K, value: V): this; /** * Prime multiple values */ primeMany(entries: Array<[K, V]>): this; /** * Clear a specific key from cache */ clear(key: K): this; /** * Clear multiple keys from cache */ clearMany(keys: K[]): this; /** * Clear all cached values */ clearAll(): this; /** * Clear expired cache entries */ clearExpired(): this; /** * Get loader statistics */ getStats(): DataLoaderStats; /** * Reset statistics */ resetStats(): this; /** * Schedule batch execution */ private scheduleBatch; /** * Execute the current batch */ private executeBatch; /** * Process Map results from batch function */ private processMapResults; /** * Process Array results from batch function */ private processArrayResults; } /** * Request deduplication configuration */ export interface DeduplicatorConfig { /** Deduplication window (ms) */ window?: number; /** Key generator for requests */ getKey?: (url: string, options?: RequestInit) => string; } /** * Request deduplicator for preventing duplicate concurrent requests */ export declare class RequestDeduplicator { private inFlight; private config; constructor(config?: DeduplicatorConfig); /** * Execute request with deduplication */ execute(key: string, requestFn: () => Promise): Promise; /** * Execute fetch with deduplication * * Note: This method intentionally uses raw fetch() rather than apiClient because: * 1. This is a low-level utility that wraps the fetch API for deduplication * 2. Users may want to use this with non-API endpoints * 3. The apiClient already has its own deduplication built-in * * For API calls, prefer using apiClient directly which provides retry, * authentication, and error handling out of the box. * * @see {@link @/lib/api/api-client} for the recommended API client */ fetch(url: string, options?: RequestInit): Promise; /** * Clear all in-flight requests */ clear(): void; /** * Get deduplication statistics */ getStats(): { inFlight: number; }; } /** * GraphQL operation */ export interface GraphQLOperation { id: string; query: string; variables?: Record | undefined; operationName?: string | undefined; } /** * GraphQL batch response */ export interface GraphQLBatchResponse { id: string; data?: unknown; errors?: Array<{ message: string; path?: Array; }>; } /** * GraphQL batcher configuration */ export interface GraphQLBatcherConfig { /** GraphQL endpoint */ endpoint: string; /** Maximum batch size */ maxBatchSize?: number; /** Batch interval (ms) */ batchInterval?: number; /** Request headers */ headers?: Record; /** Fetch function */ fetchFn?: typeof fetch; } /** * GraphQL request batcher */ export declare class GraphQLBatcher { private queries; private batchTimer; private config; constructor(config: GraphQLBatcherConfig); /** * Execute a GraphQL query */ query(query: string, variables?: Record, operationName?: string): Promise; /** * Execute a GraphQL mutation (not batched by default) */ mutate(mutation: string, variables?: Record, operationName?: string): Promise; /** * Flush pending queries immediately */ flush(): Promise; /** * Schedule batch execution */ private scheduleBatch; /** * Execute batched queries */ private executeBatch; } /** * Create a DataLoader for fetching resources by ID */ export declare function createResourceLoader(fetchMany: (ids: string[]) => Promise, config?: Partial>): DataLoader; /** * Create a DataLoader with automatic key serialization */ export declare function createKeyedLoader, V>(batchFn: (keys: K[]) => Promise | V[]>, config?: Partial>): DataLoader; /** * Global request deduplicator */ export declare const globalDeduplicator: RequestDeduplicator; /** * Deduplicated fetch function */ export declare function deduplicatedFetch(url: string, options?: RequestInit): Promise;