{"version":3,"sources":["../src/drain-pipeline.ts"],"names":[],"mappings":"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","file":"chunk-7EQ4G4SI.cjs","sourcesContent":["export interface DrainPipelineOptions<T = unknown> {\n  batch?: {\n    /** Maximum events per batch. @default 50 */\n    size?: number;\n    /** Max time an event can stay buffered before flush. @default 5000 */\n    intervalMs?: number;\n  };\n  retry?: {\n    /** Total attempts including first try. @default 3 */\n    maxAttempts?: number;\n    /** Delay strategy between attempts. @default 'exponential' */\n    backoff?: 'exponential' | 'linear' | 'fixed';\n    /** Base delay for first retry. @default 1000 */\n    initialDelayMs?: number;\n    /** Max delay cap. @default 30000 */\n    maxDelayMs?: number;\n    /** Add random jitter to delays. @default true */\n    jitter?: boolean;\n  };\n  /** Max buffered events before dropping. @default 1000 */\n  maxBufferSize?: number;\n  /** Overflow policy. @default 'oldest' */\n  dropPolicy?: 'oldest' | 'newest';\n  /** Called when events are dropped from overflow or exhausted retries. */\n  onDropped?: (events: T[], error?: Error) => void;\n}\n\nexport interface PipelineDrainFn<T> {\n  (ctx: T): void;\n  /** Flush all buffered events. */\n  flush: () => Promise<void>;\n  /** Flush and stop scheduling future timer work. */\n  shutdown: () => Promise<void>;\n  readonly pending: number;\n}\n\nfunction wait(ms: number): Promise<void> {\n  return new Promise((resolve) => {\n    const timer = setTimeout(resolve, ms);\n    timer.unref?.();\n  });\n}\n\nexport function createDrainPipeline<T = unknown>(\n  options?: DrainPipelineOptions<T>,\n): (drain: (batch: T[]) => void | Promise<void>) => PipelineDrainFn<T> {\n  const batchSize = options?.batch?.size ?? 50;\n  const intervalMs = options?.batch?.intervalMs ?? 5000;\n  const maxBufferSize = options?.maxBufferSize ?? 1000;\n  const maxAttempts = options?.retry?.maxAttempts ?? 3;\n  const backoff = options?.retry?.backoff ?? 'exponential';\n  const initialDelayMs = options?.retry?.initialDelayMs ?? 1000;\n  const maxDelayMs = options?.retry?.maxDelayMs ?? 30_000;\n  const jitter = options?.retry?.jitter ?? true;\n  const dropPolicy = options?.dropPolicy ?? 'oldest';\n  const onDropped = options?.onDropped;\n\n  if (!Number.isFinite(batchSize) || batchSize <= 0) {\n    throw new Error(\n      `[autotel/drain-pipeline] batch.size must be a positive finite number, got: ${batchSize}`,\n    );\n  }\n  if (!Number.isFinite(intervalMs) || intervalMs <= 0) {\n    throw new Error(\n      `[autotel/drain-pipeline] batch.intervalMs must be a positive finite number, got: ${intervalMs}`,\n    );\n  }\n  if (!Number.isFinite(maxBufferSize) || maxBufferSize <= 0) {\n    throw new Error(\n      `[autotel/drain-pipeline] maxBufferSize must be a positive finite number, got: ${maxBufferSize}`,\n    );\n  }\n  if (!Number.isFinite(maxAttempts) || maxAttempts <= 0) {\n    throw new Error(\n      `[autotel/drain-pipeline] retry.maxAttempts must be a positive finite number, got: ${maxAttempts}`,\n    );\n  }\n\n  return (drain: (batch: T[]) => void | Promise<void>): PipelineDrainFn<T> => {\n    const buffer: T[] = [];\n    let timer: ReturnType<typeof setTimeout> | null = null;\n    let activeFlush: Promise<void> | null = null;\n    let isShutdown = false;\n\n    const clearTimer = () => {\n      if (timer) {\n        clearTimeout(timer);\n        timer = null;\n      }\n    };\n\n    const computeDelay = (attempt: number): number => {\n      const base =\n        backoff === 'fixed'\n          ? initialDelayMs\n          : backoff === 'linear'\n            ? initialDelayMs * attempt\n            : initialDelayMs * 2 ** (attempt - 1);\n\n      const bounded = Math.min(base, maxDelayMs);\n      if (!jitter || bounded <= 0) return bounded;\n      const factor = 0.5 + Math.random(); // [0.5, 1.5)\n      return Math.max(0, Math.round(bounded * factor));\n    };\n\n    const sendWithRetry = async (batch: T[]): Promise<void> => {\n      let lastError: Error | undefined;\n      for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n        try {\n          await drain(batch);\n          return;\n        } catch (error) {\n          lastError = error instanceof Error ? error : new Error(String(error));\n          if (attempt < maxAttempts) {\n            await wait(computeDelay(attempt));\n          }\n        }\n      }\n      onDropped?.(batch, lastError);\n    };\n\n    const drainBuffer = async (): Promise<void> => {\n      while (buffer.length > 0) {\n        const batch = buffer.splice(0, batchSize);\n        await sendWithRetry(batch);\n      }\n    };\n\n    const scheduleFlush = () => {\n      if (isShutdown || timer || activeFlush) return;\n      timer = setTimeout(() => {\n        timer = null;\n        startFlush();\n      }, intervalMs);\n      timer.unref?.();\n    };\n\n    const startFlush = () => {\n      if (activeFlush || isShutdown) return;\n      activeFlush = drainBuffer().finally(() => {\n        activeFlush = null;\n        if (isShutdown) return;\n        if (buffer.length >= batchSize) {\n          startFlush();\n        } else if (buffer.length > 0) {\n          scheduleFlush();\n        }\n      });\n    };\n\n    const push = (ctx: T) => {\n      if (isShutdown) return;\n\n      if (buffer.length >= maxBufferSize) {\n        if (dropPolicy === 'newest') {\n          onDropped?.([ctx]);\n          return;\n        }\n        const dropped = buffer.splice(0, 1);\n        onDropped?.(dropped);\n      }\n\n      buffer.push(ctx);\n      if (buffer.length >= batchSize) {\n        clearTimer();\n        startFlush();\n      } else {\n        scheduleFlush();\n      }\n    };\n\n    const flush = async (): Promise<void> => {\n      clearTimer();\n      if (activeFlush) await activeFlush;\n\n      const snapshot = buffer.length;\n      if (snapshot <= 0) return;\n      const toFlush = buffer.splice(0, snapshot);\n      while (toFlush.length > 0) {\n        const batch = toFlush.splice(0, batchSize);\n        await sendWithRetry(batch);\n      }\n    };\n\n    const shutdown = async (): Promise<void> => {\n      isShutdown = true;\n      await flush();\n    };\n\n    const fn = push as PipelineDrainFn<T>;\n    fn.flush = flush;\n    fn.shutdown = shutdown;\n    Object.defineProperty(fn, 'pending', {\n      enumerable: true,\n      get: () => buffer.length,\n    });\n    return fn;\n  };\n}\n"]}