{"version":3,"file":"request-queue.mjs","sources":["../../../src/lib/services/request-queue.ts"],"sourcesContent":["/**\n * @file Request Queue\n * @description Enterprise-grade request queue with batching, rate limiting,\n * priority queuing, and deduplication\n */\n\nimport { Semaphore, sleep, defer, type Deferred } from '../shared/async-utils';\n\n// Ensure setTimeout is available in all environments\n// Timeout function for cross-platform compatibility\n// const timeoutFn = typeof setTimeout !== 'undefined' ? setTimeout : (globalThis as any).setTimeout;\n\n/**\n * Request priority levels\n */\nexport type RequestPriority = 'low' | 'normal' | 'high' | 'critical';\n\n/**\n * Priority weights\n */\nconst PRIORITY_WEIGHTS: Record<RequestPriority, number> = {\n  critical: 4,\n  high: 3,\n  normal: 2,\n  low: 1,\n};\n\n/**\n * Queue item\n */\ninterface QueueItem<T> {\n  id: string;\n  execute: () => Promise<T>;\n  priority: RequestPriority;\n  deferred: Deferred<T>;\n  createdAt: number;\n  retries: number;\n  maxRetries: number;\n  timeout?: number;\n  dedupKey?: string;\n}\n\n/**\n * Request queue configuration\n */\nexport interface RequestQueueConfig {\n  /** Maximum concurrent requests */\n  concurrency?: number;\n  /** Maximum queue size */\n  maxQueueSize?: number;\n  /** Default priority */\n  defaultPriority?: RequestPriority;\n  /** Default max retries */\n  maxRetries?: number;\n  /** Retry delay (ms) */\n  retryDelay?: number;\n  /** Request timeout (ms) */\n  timeout?: number;\n  /** Enable deduplication */\n  deduplication?: boolean;\n}\n\n/**\n * Request queue for managing concurrent requests\n */\nexport class RequestQueue {\n  private queue: QueueItem<unknown>[] = [];\n  private processing = false;\n  private semaphore: Semaphore;\n  private config: Required<RequestQueueConfig>;\n  private dedupMap: Map<string, Deferred<unknown>> = new Map();\n  private paused = false;\n\n  constructor(config: RequestQueueConfig = {}) {\n    this.config = {\n      concurrency: config.concurrency ?? 5,\n      maxQueueSize: config.maxQueueSize ?? 100,\n      defaultPriority: config.defaultPriority ?? 'normal',\n      maxRetries: config.maxRetries ?? 3,\n      retryDelay: config.retryDelay ?? 1000,\n      timeout: config.timeout ?? 30000,\n      deduplication: config.deduplication ?? true,\n    };\n\n    this.semaphore = new Semaphore(this.config.concurrency);\n  }\n\n  /**\n   * Add request to queue\n   */\n  async enqueue<T>(\n    execute: () => Promise<T>,\n    options?: {\n      priority?: RequestPriority;\n      maxRetries?: number;\n      timeout?: number;\n      dedupKey?: string;\n      id?: string;\n    }\n  ): Promise<T> {\n    const dedupKey = options?.dedupKey;\n\n    // Check for duplicate request\n    if (this.config.deduplication && dedupKey !== undefined && dedupKey !== '') {\n      const existing = this.dedupMap.get(dedupKey);\n      if (existing !== undefined) {\n        return existing.promise as Promise<T>;\n      }\n    }\n\n    // Check queue size\n    if (this.queue.length >= this.config.maxQueueSize) {\n      return Promise.reject(new Error('Request queue is full'));\n    }\n\n    const deferred = defer<T>();\n    const item: QueueItem<T> = {\n      id: options?.id ?? crypto.randomUUID(),\n      execute,\n      priority: options?.priority ?? this.config.defaultPriority,\n      deferred,\n      createdAt: Date.now(),\n      retries: 0,\n      maxRetries: options?.maxRetries ?? this.config.maxRetries,\n      timeout: options?.timeout ?? this.config.timeout,\n      dedupKey,\n    };\n\n    // Add to dedup map\n    if (dedupKey !== undefined && dedupKey !== null && dedupKey !== '') {\n      this.dedupMap.set(dedupKey, deferred as Deferred<unknown>);\n    }\n\n    // Insert based on priority\n    this.insertByPriority(item as QueueItem<unknown>);\n\n    // Start processing if not already\n    if (!this.processing && !this.paused) {\n      void this.process();\n    }\n\n    return deferred.promise;\n  }\n\n  /**\n   * Pause queue processing\n   */\n  pause(): void {\n    this.paused = true;\n  }\n\n  /**\n   * Resume queue processing\n   */\n  resume(): void {\n    this.paused = false;\n    if (this.queue.length > 0) {\n      void this.process();\n    }\n  }\n\n  /**\n   * Clear queue\n   */\n  clear(error?: Error): void {\n    const clearError = error ?? new Error('Queue cleared');\n    for (const item of this.queue) {\n      item.deferred.reject(clearError);\n      if (item.dedupKey !== undefined && item.dedupKey !== '') {\n        this.dedupMap.delete(item.dedupKey);\n      }\n    }\n    this.queue = [];\n  }\n\n  /**\n   * Get queue statistics\n   */\n  getStats(): {\n    queued: number;\n    processing: number;\n    maxConcurrency: number;\n    paused: boolean;\n  } {\n    return {\n      queued: this.queue.length,\n      processing: this.config.concurrency - this.semaphore.availablePermits(),\n      maxConcurrency: this.config.concurrency,\n      paused: this.paused,\n    };\n  }\n\n  /**\n   * Remove item from queue by id\n   */\n  remove(id: string): boolean {\n    const index = this.queue.findIndex((item) => item.id === id);\n    if (index !== -1) {\n      const item = this.queue[index];\n      if (item !== undefined) {\n        item.deferred.reject(new Error('Request removed from queue'));\n        if (item.dedupKey !== undefined && item.dedupKey !== '') {\n          this.dedupMap.delete(item.dedupKey);\n        }\n      }\n      this.queue.splice(index, 1);\n      return true;\n    }\n    return false;\n  }\n\n  /**\n   * Insert item by priority\n   */\n  private insertByPriority(item: QueueItem<unknown>): void {\n    const weight = PRIORITY_WEIGHTS[item.priority];\n    let inserted = false;\n\n    for (let i = 0; i < this.queue.length; i++) {\n      const queueItem = this.queue[i];\n      if (queueItem && PRIORITY_WEIGHTS[queueItem.priority] < weight) {\n        this.queue.splice(i, 0, item);\n        inserted = true;\n        break;\n      }\n    }\n\n    if (!inserted) {\n      this.queue.push(item);\n    }\n  }\n\n  /**\n   * Process queue\n   */\n  private process(): void {\n    if (this.processing || this.paused) return;\n    this.processing = true;\n\n    while (this.queue.length > 0 && !this.paused) {\n      const item = this.queue.shift();\n      if (item === undefined) continue;\n\n      // Process item with semaphore\n      void this.processItem(item);\n    }\n\n    this.processing = false;\n  }\n\n  /**\n   * Process single item\n   */\n  private async processItem(item: QueueItem<unknown>): Promise<void> {\n    const release = await this.semaphore.acquire();\n\n    try {\n      const result = await this.executeWithTimeout(item);\n      item.deferred.resolve(result);\n    } catch (error) {\n      // Retry logic\n      if (item.retries < item.maxRetries) {\n        item.retries++;\n        await sleep(this.config.retryDelay * item.retries);\n        this.insertByPriority(item);\n      } else {\n        item.deferred.reject(error);\n      }\n    } finally {\n      release();\n\n      // Clean up dedup map\n      if (item.dedupKey !== undefined && item.dedupKey !== null && item.dedupKey !== '') {\n        this.dedupMap.delete(item.dedupKey);\n      }\n\n      // Continue processing\n      if (!this.paused && this.queue.length > 0 && !this.processing) {\n        void this.process();\n      }\n    }\n  }\n\n  /**\n   * Execute with timeout\n   */\n  private async executeWithTimeout<T>(item: QueueItem<T>): Promise<T> {\n    return Promise.race([\n      item.execute(),\n      new Promise<never>((_, reject) =>\n        setTimeout(() => reject(new Error('Request timeout')), item.timeout)\n      ),\n    ]);\n  }\n}\n\n/**\n * Rate limiter configuration\n */\nexport interface RateLimiterConfig {\n  /** Maximum requests per window */\n  maxRequests: number;\n  /** Window duration (ms) */\n  windowMs: number;\n  /** Strategy when limit reached */\n  strategy?: 'queue' | 'reject' | 'delay';\n  /** Maximum queue size (for queue strategy) */\n  maxQueueSize?: number;\n}\n\n/**\n * Rate limiter for controlling request rate\n */\nexport class RateLimiter {\n  private requests: number[] = [];\n  private config: Required<RateLimiterConfig>;\n  private queue: Array<{\n    execute: () => void;\n    reject: (error: Error) => void;\n  }> = [];\n\n  constructor(config: RateLimiterConfig) {\n    this.config = {\n      maxRequests: config.maxRequests,\n      windowMs: config.windowMs,\n      strategy: config.strategy ?? 'delay',\n      maxQueueSize: config.maxQueueSize ?? 100,\n    };\n  }\n\n  /**\n   * Acquire rate limit slot\n   */\n  async acquire(): Promise<() => void> {\n    if (this.isAllowed()) {\n      const timestamp = Date.now();\n      this.requests.push(timestamp);\n      return () => {\n        const index = this.requests.indexOf(timestamp);\n        if (index !== -1) {\n          this.requests.splice(index, 1);\n        }\n        this.processQueue();\n      };\n    }\n\n    switch (this.config.strategy) {\n      case 'reject':\n        throw new RateLimitError('Rate limit exceeded', this.getWaitTime());\n\n      case 'queue': {\n        if (this.queue.length >= this.config.maxQueueSize) {\n          throw new RateLimitError('Rate limit queue full', this.getWaitTime());\n        }\n\n        return new Promise((resolve, reject) => {\n          this.queue.push({\n            execute: () => {\n              const timestamp = Date.now();\n              this.requests.push(timestamp);\n              resolve(() => {\n                const index = this.requests.indexOf(timestamp);\n                if (index !== -1) {\n                  this.requests.splice(index, 1);\n                }\n                this.processQueue();\n              });\n            },\n            reject,\n          });\n        });\n      }\n\n      case 'delay':\n      default: {\n        const waitTime = this.getWaitTime();\n        await sleep(waitTime);\n        return this.acquire();\n      }\n    }\n  }\n\n  /**\n   * Execute with rate limiting\n   */\n  async execute<T>(fn: () => Promise<T>): Promise<T> {\n    const release = await this.acquire();\n    try {\n      return await fn();\n    } finally {\n      release();\n    }\n  }\n\n  /**\n   * Get rate limit status\n   */\n  getStatus(): {\n    remaining: number;\n    limit: number;\n    resetMs: number;\n    queued: number;\n  } {\n    this.cleanOldRequests();\n    const oldestRequest = this.requests.length > 0 ? Math.min(...this.requests) : 0;\n\n    return {\n      remaining: Math.max(0, this.config.maxRequests - this.requests.length),\n      limit: this.config.maxRequests,\n      resetMs: oldestRequest ? oldestRequest + this.config.windowMs - Date.now() : 0,\n      queued: this.queue.length,\n    };\n  }\n\n  /**\n   * Clear rate limit\n   */\n  clear(): void {\n    this.requests = [];\n    const error = new Error('Rate limiter cleared');\n    for (const item of this.queue) {\n      item.reject(error);\n    }\n    this.queue = [];\n  }\n\n  /**\n   * Check if request is allowed\n   */\n  private isAllowed(): boolean {\n    this.cleanOldRequests();\n    return this.requests.length < this.config.maxRequests;\n  }\n\n  /**\n   * Clean requests outside window\n   */\n  private cleanOldRequests(): void {\n    const cutoff = Date.now() - this.config.windowMs;\n    this.requests = this.requests.filter((time) => time > cutoff);\n  }\n\n  /**\n   * Get time until next available slot\n   */\n  private getWaitTime(): number {\n    if (this.isAllowed()) return 0;\n\n    this.cleanOldRequests();\n    if (this.requests.length === 0) return 0;\n\n    const oldestRequest = Math.min(...this.requests);\n    return Math.max(0, oldestRequest + this.config.windowMs - Date.now());\n  }\n\n  /**\n   * Process queued requests\n   */\n  private processQueue(): void {\n    if (this.queue.length === 0) return;\n\n    const waitTime = this.getWaitTime();\n    if (waitTime > 0) {\n      // Schedule check for next available slot\n      setTimeout(() => this.processQueue(), waitTime);\n    }\n  }\n}\n\n/**\n * Rate limit error\n */\nexport class RateLimitError extends Error {\n  readonly isRateLimitError = true;\n  readonly retryAfterMs: number;\n\n  constructor(message: string, retryAfterMs: number) {\n    super(message);\n    this.name = 'RateLimitError';\n    this.retryAfterMs = retryAfterMs;\n  }\n}\n\n/**\n * Request batcher configuration\n */\nexport interface BatcherConfig<K, V> {\n  /** Maximum batch size */\n  maxBatchSize?: number;\n  /** Maximum wait time (ms) */\n  maxWaitMs?: number;\n  /** Batch executor */\n  batchFn: (keys: K[]) => Promise<Map<K, V> | V[]>;\n}\n\n/**\n * Request batcher for combining multiple requests\n */\nexport class RequestBatcher<K, V> {\n  private batch: Map<K, Deferred<V>> = new Map();\n  private timer: ReturnType<typeof setTimeout> | null = null;\n  private config: Required<Omit<BatcherConfig<K, V>, 'batchFn'>> & Pick<BatcherConfig<K, V>, 'batchFn'>;\n\n  constructor(config: BatcherConfig<K, V>) {\n    this.config = {\n      maxBatchSize: config.maxBatchSize ?? 50,\n      maxWaitMs: config.maxWaitMs ?? 10,\n      batchFn: config.batchFn,\n    };\n  }\n\n  /**\n   * Load a single item\n   */\n  async load(key: K): Promise<V> {\n    // Check for existing request\n    const existing = this.batch.get(key);\n    if (existing) {\n      return existing.promise;\n    }\n\n    // Create new deferred\n    const deferred = defer<V>();\n    this.batch.set(key, deferred);\n\n    // Schedule batch execution\n    this.scheduleBatch();\n\n    // Check if batch is full\n    if (this.batch.size >= this.config.maxBatchSize) {\n      void this.executeBatch();\n    }\n\n    return deferred.promise;\n  }\n\n  /**\n   * Load multiple items\n   */\n  async loadMany(keys: K[]): Promise<(V | Error)[]> {\n    return Promise.all(\n      keys.map(async (key) =>\n        this.load(key).catch((error) => error as Error)\n      )\n    );\n  }\n\n  /**\n   * Clear pending batch\n   */\n  clear(): void {\n    if (this.timer) {\n      clearTimeout(this.timer);\n      this.timer = null;\n    }\n\n    const error = new Error('Batcher cleared');\n    for (const [, deferred] of this.batch) {\n      deferred.reject(error);\n    }\n    this.batch.clear();\n  }\n\n  /**\n   * Get pending count\n   */\n  getPendingCount(): number {\n    return this.batch.size;\n  }\n\n  /**\n   * Schedule batch execution\n   */\n  private scheduleBatch(): void {\n    if (this.timer) return;\n\n    this.timer = setTimeout(() => {\n      void this.executeBatch();\n    }, this.config.maxWaitMs);\n  }\n\n  /**\n   * Execute batch\n   */\n  private async executeBatch(): Promise<void> {\n    if (this.timer) {\n      clearTimeout(this.timer);\n      this.timer = null;\n    }\n\n    if (this.batch.size === 0) return;\n\n    // Get current batch\n    const currentBatch = new Map(this.batch);\n    this.batch.clear();\n\n    const keys = Array.from(currentBatch.keys());\n\n    try {\n      const result = await this.config.batchFn(keys);\n\n      // Handle Map or Array result\n      if (result instanceof Map) {\n        for (const [key, deferred] of currentBatch) {\n          const value = result.get(key);\n          if (value !== undefined) {\n            deferred.resolve(value);\n          } else {\n            deferred.reject(new Error(`No result for key: ${String(key)}`));\n          }\n        }\n      } else {\n        // Array result - assume same order as keys\n        let i = 0;\n        for (const [, deferred] of currentBatch) {\n          const resultValue = result[i];\n          if (i < result.length && resultValue !== undefined) {\n            deferred.resolve(resultValue);\n          } else {\n            deferred.reject(new Error('Result array too short'));\n          }\n          i++;\n        }\n      }\n    } catch (error) {\n      // Reject all pending requests\n      for (const [, deferred] of currentBatch) {\n        deferred.reject(error as Error);\n      }\n    }\n  }\n}\n\n/**\n * Create a global request queue instance\n */\nexport const globalRequestQueue = new RequestQueue();\n\n/**\n * Create a rate limiter with common presets\n */\nexport const rateLimiters = {\n  /** Standard API rate limiter (100 req/min) */\n  standard: (): RateLimiter => new RateLimiter({ maxRequests: 100, windowMs: 60000 }),\n\n  /** Burst rate limiter (10 req/sec) */\n  burst: (): RateLimiter => new RateLimiter({ maxRequests: 10, windowMs: 1000 }),\n\n  /** Strict rate limiter (1 req/sec) */\n  strict: (): RateLimiter => new RateLimiter({ maxRequests: 1, windowMs: 1000 }),\n\n  /** Custom rate limiter */\n  custom: (maxRequests: number, windowMs: number, strategy?: RateLimiterConfig['strategy']): RateLimiter =>\n    new RateLimiter({ maxRequests, windowMs, strategy }),\n};\n"],"names":["PRIORITY_WEIGHTS","RequestQueue","config","Semaphore","execute","options","dedupKey","existing","deferred","defer","item","error","clearError","id","index","weight","inserted","queueItem","release","result","sleep","_","reject","RateLimiter","timestamp","RateLimitError","resolve","waitTime","fn","oldestRequest","cutoff","time","message","retryAfterMs","RequestBatcher","key","keys","currentBatch","value","resultValue","globalRequestQueue","rateLimiters","maxRequests","windowMs","strategy"],"mappings":"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"}