UNPKG

batch-process-manager

Version:

Batch multiple requests together with configurable timeouts and concurrency limits to optimize API calls and database queries.

111 lines (109 loc) 3.99 kB
type ValueOf<T> = T extends Map<string, infer V> ? V : never; type ProcessBatchFn = (batchKeys: string[]) => Promise<Map<string, any>>; type BatchManagerOpts<T extends ProcessBatchFn> = { /** * The maximum number of requests to process in parallel. * @default 20 */ batchSize?: number; /** * Time in milliseconds before the batch is sent if the batch size is not reached. * @default 1000 */ batchTimeout?: number; /** * The maximum number of requests to process in parallel. * @default Infinity */ concurrency?: number; processBatch: T; }; /** * BatchManager efficiently batches and processes requests with configurable * concurrency limits, batch sizes, and timeouts. * * This class collects individual requests into batches and processes them together * to improve performance and reduce the number of expensive operations (like API calls * or database queries). * * @template T - The type of the batch processing function * * @example * ```typescript * // Create a batch manager for API requests * const batchManager = new BatchManager({ * processBatch: async (productIds) => { * // Make a single API call for multiple products * const response = await fetch('/api/products', { * method: 'POST', * headers: { 'Content-Type': 'application/json' }, * body: JSON.stringify({ ids: productIds }), * }); * * const products = await response.json(); * const resultMap = new Map(); * * products.forEach(product => { * resultMap.set(product.id, product); * }); * * return resultMap; * }, * batchSize: 10, // Process 10 items at once * batchTimeout: 500, // Wait max 500ms before processing incomplete batch * concurrency: 3, // Allow up to 3 concurrent batch operations * }); * * // Use the batch manager * const product = await batchManager.get('product-123'); * console.log(product); * * // Process multiple requests efficiently * const promises = ['product-1', 'product-2', 'product-3'] * .map(id => batchManager.get(id)); * const products = await Promise.all(promises); * ``` */ declare class BatchManager<T extends ProcessBatchFn> { private batchSize; private batchTimeout; private currentBatch; private timeoutId; private processBatch; private limit; /** * Creates a new BatchManager instance. * * @param opts - Configuration options for the batch manager * @param opts.processBatch - Function that processes a batch of keys and returns a Map of results * @param opts.batchSize - Maximum number of requests to process in a single batch (default: 20) * @param opts.batchTimeout - Time in milliseconds to wait before processing an incomplete batch (default: 1000) * @param opts.concurrency - Maximum number of batch operations to run in parallel (default: Infinity) */ constructor(opts: BatchManagerOpts<T>); /** * Retrieves a value for the given key, automatically batching the request with others. * * This method adds the request to the current batch. The batch will be processed when: * - The batch reaches the configured `batchSize` * - The `batchTimeout` expires * * @param key - The key to retrieve data for * @returns A promise that resolves with the data for the given key, or undefined if the key is not found * * @example * ```typescript * // Single request * const result = await batchManager.get('user-123'); * * // Multiple concurrent requests (will be batched automatically) * const promises = ['user-1', 'user-2', 'user-3'] * .map(id => batchManager.get(id)); * const users = await Promise.all(promises); * ``` */ get(key: string): Promise<ValueOf<Awaited<ReturnType<T>>> | undefined>; private resetBatchTimeout; private _processBatch; } export { BatchManager, BatchManager as default };