{"version":3,"file":"middleware.cjs","names":[],"sources":["../src/middleware.ts"],"sourcesContent":["/**\n * Subscriber middleware system for transforming, filtering, and enriching events\n *\n * Provides composable middleware for adding cross-cutting concerns:\n * - Retry logic, rate limiting, and circuit breaker patterns\n * - Event filtering, transformation, and enrichment\n * - Idempotency and batching\n * - Event logging and observability\n *\n * @example\n * ```typescript\n * import { applyMiddleware, retryMiddleware, rateLimitMiddleware } from 'autotel-subscribers/middleware'\n *\n * const subscriber = applyMiddleware(\n *   createPostHogSubscriber({ apiKey: '...' }),\n *   [\n *     retryMiddleware({ maxRetries: 3 }),\n *     rateLimitMiddleware({ requestsPerSecond: 100 })\n *   ]\n * )\n * ```\n */\n\nimport type {\n  EventSubscriber,\n  EventAttributes,\n  FunnelStatus,\n  OutcomeStatus,\n  EventTrackingOptions,\n} from 'autotel/event-subscriber';\n\n/** Normalized event for middleware processing */\nexport type EventsEvent =\n  | {\n      type: 'event';\n      name: string;\n      attributes?: EventAttributes;\n      options?: EventTrackingOptions;\n    }\n  | {\n      type: 'funnel';\n      funnel: string;\n      step: FunnelStatus;\n      attributes?: EventAttributes;\n      options?: EventTrackingOptions;\n    }\n  | {\n      type: 'outcome';\n      operation: string;\n      outcome: OutcomeStatus;\n      attributes?: EventAttributes;\n      options?: EventTrackingOptions;\n    }\n  | {\n      type: 'value';\n      name: string;\n      value: number;\n      attributes?: EventAttributes;\n      options?: EventTrackingOptions;\n    };\n\nexport type SendEventRecord = {\n  subscriberName: string;\n  eventType: EventsEvent['type'];\n  eventName: string;\n  status: 'success' | 'error';\n  durationMs: number;\n  startedAt: Date;\n  endedAt: Date;\n  error?: { name: string; message: string; code?: string };\n};\n\nexport type SendEventSink = {\n  write(event: SendEventRecord): Promise<void>;\n};\n\nexport type RateLimitAlgorithm = 'fixed' | 'sliding';\nexport type RateLimitRecord = { count: number; resetAtMs: number };\n\nexport type RateLimitStore = {\n  record(\n    key: string,\n    windowMs: number,\n    algorithm: RateLimitAlgorithm,\n  ): Promise<RateLimitRecord>;\n};\n\nexport type IdempotencyStore<TResult = unknown> = {\n  get(key: string): Promise<TResult | null>;\n  set(key: string, result: TResult, ttlMs: number): Promise<void>;\n};\n\nexport type SubscriberMiddleware<TCtxIn = Record<string, unknown>, TCtxOut = TCtxIn> = (\n  params: {\n    event: EventsEvent;\n    ctx: TCtxIn;\n    subscriber: Pick<EventSubscriber, 'name' | 'version'>;\n    next: (update?: { event?: EventsEvent; ctxPatch?: Partial<TCtxOut> }) => Promise<void>;\n  },\n) => Promise<void>;\n\n/** Type-safe middleware factory helper */\nexport const createMiddleware = <TCtxIn = Record<string, unknown>, TCtxOut = TCtxIn>(\n  fn: SubscriberMiddleware<TCtxIn, TCtxOut>,\n): SubscriberMiddleware<TCtxIn, TCtxOut> => fn;\n\nfunction eventNameOf(event: EventsEvent): string {\n  switch (event.type) {\n    case 'event':\n    case 'value': {\n      return event.name;\n    }\n    case 'funnel': {\n      return `${event.funnel}.${event.step}`;\n    }\n    case 'outcome': {\n      return `${event.operation}.${event.outcome}`;\n    }\n  }\n}\n\nfunction defaultContextFactory() {\n  return {} as Record<string, unknown>;\n}\n\nasync function dispatchEvent(subscriber: EventSubscriber, event: EventsEvent): Promise<void> {\n  switch (event.type) {\n    case 'event': {\n      await subscriber.trackEvent(event.name, event.attributes, event.options);\n      return;\n    }\n    case 'funnel': {\n      await subscriber.trackFunnelStep(event.funnel, event.step, event.attributes, event.options);\n      return;\n    }\n    case 'outcome': {\n      await subscriber.trackOutcome(\n        event.operation,\n        event.outcome,\n        event.attributes,\n        event.options,\n      );\n      return;\n    }\n    case 'value': {\n      await subscriber.trackValue(event.name, event.value, event.attributes, event.options);\n    }\n  }\n}\n\n/**\n * Apply middleware to a subscriber\n *\n * Chains middleware in order, each can transform events or context before passing to next\n *\n * @example\n * ```typescript\n * const enriched = applyMiddleware(\n *   subscriber,\n *   [enrichmentMiddleware(event => ({ ...event, timestamp: Date.now() }))]\n * )\n * ```\n */\nexport function applyMiddleware<TCtx = Record<string, unknown>>(\n  subscriber: EventSubscriber,\n  middlewares: Array<SubscriberMiddleware<TCtx, TCtx>>,\n  options?: { initialContext?: () => TCtx },\n): EventSubscriber {\n  const runChain = async (initialEvent: EventsEvent): Promise<void> => {\n    const baseCtx = (options?.initialContext ?? defaultContextFactory)() as TCtx;\n\n    const execute = async (index: number, event: EventsEvent, ctx: TCtx): Promise<void> => {\n      const middleware = middlewares[index];\n      if (!middleware) {\n        await dispatchEvent(subscriber, event);\n        return;\n      }\n\n      await middleware({\n        event,\n        ctx,\n        subscriber,\n        next: async (update) => {\n          const nextEvent = update?.event ?? event;\n          const nextCtx = update?.ctxPatch\n            ? ({ ...ctx, ...update.ctxPatch } as TCtx)\n            : ctx;\n          await execute(index + 1, nextEvent, nextCtx);\n        },\n      });\n    };\n\n    await execute(0, initialEvent, baseCtx);\n  };\n\n  return {\n    name: `${subscriber.name}(middleware)`,\n    version: subscriber.version,\n    trackEvent: async (name, attributes, options_) =>\n      runChain({ type: 'event', name, attributes, options: options_ }),\n    trackFunnelStep: async (funnel, step, attributes, options_) =>\n      runChain({ type: 'funnel', funnel, step, attributes, options: options_ }),\n    trackOutcome: async (operation, outcome, attributes, options_) =>\n      runChain({ type: 'outcome', operation, outcome, attributes, options: options_ }),\n    trackValue: async (name, value, attributes, options_) =>\n      runChain({ type: 'value', name, value, attributes, options: options_ }),\n    shutdown: async () => {\n      await subscriber.shutdown?.();\n    },\n  };\n}\n\n/**\n * Retry middleware with exponential backoff\n *\n * Automatically retries failed events with exponential backoff delay\n */\nexport function retryMiddleware(options: {\n  maxRetries?: number;\n  delayMs?: number;\n  onRetry?: (attempt: number, error: Error, event: EventsEvent) => void;\n}): SubscriberMiddleware {\n  const { maxRetries = 3, delayMs = 1000, onRetry } = options;\n\n  return async ({ event, next }) => {\n    let lastError: Error | undefined;\n\n    for (let attempt = 1; attempt <= maxRetries; attempt++) {\n      try {\n        await next();\n        return;\n      } catch (error) {\n        lastError = error instanceof Error ? error : new Error(String(error));\n        if (attempt < maxRetries) {\n          onRetry?.(attempt, lastError, event);\n          await new Promise((resolve) => setTimeout(resolve, delayMs * 2 ** (attempt - 1)));\n        }\n      }\n    }\n\n    throw lastError;\n  };\n}\n\n/**\n * Sampling middleware to reduce event volume\n *\n * Only passes through a percentage of events based on the rate (0.0 to 1.0)\n */\nexport function samplingMiddleware(rate: number): SubscriberMiddleware {\n  if (rate < 0 || rate > 1) throw new Error('Sample rate must be between 0 and 1');\n\n  return async ({ next }) => {\n    if (Math.random() < rate) await next();\n  };\n}\n\n/**\n * Enrichment middleware to add or modify event data\n *\n * Apply a transformation function to each event before sending\n */\nexport function enrichmentMiddleware(enricher: (event: EventsEvent) => EventsEvent): SubscriberMiddleware {\n  return async ({ event, next }) => {\n    await next({ event: enricher(event) });\n  };\n}\n\n/**\n * Logging middleware for debugging event flow\n *\n * Logs event type and name (optionally full event) to console\n */\nexport function loggingMiddleware(options: { prefix?: string; logAttributes?: boolean } = {}): SubscriberMiddleware {\n  const { prefix = '[Events]', logAttributes = false } = options;\n\n  return async ({ event, next }) => {\n    if (logAttributes) {\n      console.log(prefix, event.type, event);\n    } else {\n      console.log(prefix, event.type, eventNameOf(event));\n    }\n    await next();\n  };\n}\n\n/**\n * Filter middleware to selectively process events\n *\n * Only forwards events that match the predicate\n */\nexport function filterMiddleware(predicate: (event: EventsEvent) => boolean): SubscriberMiddleware {\n  return async ({ event, next }) => {\n    if (predicate(event)) await next();\n  };\n}\n\n/**\n * Transform middleware to modify event structure\n *\n * Similar to enrichment but replaces entire event\n */\nexport function transformMiddleware(transformer: (event: EventsEvent) => EventsEvent): SubscriberMiddleware {\n  return async ({ event, next }) => {\n    await next({ event: transformer(event) });\n  };\n}\n\n/**\n * Batching middleware to group events for bulk sending\n *\n * Collects events into batches before forwarding\n */\nexport function batchingMiddleware(options: {\n  batchSize?: number;\n  flushInterval?: number;\n}): SubscriberMiddleware {\n  const { batchSize = 100, flushInterval = 5000 } = options;\n  const queue: Array<() => Promise<void>> = [];\n  let timer: NodeJS.Timeout | null = null;\n\n  const flush = async () => {\n    const pending = queue.splice(0);\n    await Promise.all(pending.map((run) => run()));\n  };\n\n  return async ({ next }) => {\n    await new Promise<void>((resolve, reject) => {\n      queue.push(async () => {\n        try {\n          await next();\n          resolve();\n        } catch (error) {\n          reject(error);\n        }\n      });\n\n      if (queue.length >= batchSize) {\n        if (timer) clearTimeout(timer);\n        timer = null;\n        void flush().catch(reject);\n        return;\n      }\n\n      if (!timer) {\n        timer = setTimeout(() => {\n          timer = null;\n          void flush().catch(reject);\n        }, flushInterval);\n      }\n    });\n  };\n}\n\n/**\n * Rate limit middleware to control event sending rate\n *\n * Enforces a maximum rate of events sent per second\n */\nexport function rateLimitMiddleware(options: { requestsPerSecond: number }): SubscriberMiddleware {\n  const intervalMs = 1000 / options.requestsPerSecond;\n  let lastAt = 0;\n\n  return async ({ next }) => {\n    const now = Date.now();\n    const waitMs = Math.max(0, intervalMs - (now - lastAt));\n    if (waitMs > 0) {\n      await new Promise((resolve) => setTimeout(resolve, waitMs));\n    }\n    lastAt = Date.now();\n    await next();\n  };\n}\n\n/**\n * Circuit breaker middleware for fault tolerance\n *\n * Prevents cascading failures by stopping requests when error rate exceeds threshold\n */\nexport function circuitBreakerMiddleware(options: {\n  failureThreshold?: number;\n  timeout?: number;\n  onOpen?: () => void;\n  onClose?: () => void;\n}): SubscriberMiddleware {\n  const { failureThreshold = 5, timeout = 60_000, onOpen, onClose } = options;\n  let failureCount = 0;\n  let lastFailureAt = 0;\n  let open = false;\n\n  return async ({ next }) => {\n    if (open) {\n      if (Date.now() - lastFailureAt > timeout) {\n        open = false;\n        failureCount = 0;\n        onClose?.();\n      } else {\n        throw new Error('Circuit breaker is open');\n      }\n    }\n\n    try {\n      await next();\n      failureCount = 0;\n    } catch (error) {\n      failureCount += 1;\n      lastFailureAt = Date.now();\n      if (failureCount >= failureThreshold) {\n        open = true;\n        onOpen?.();\n      }\n      throw error;\n    }\n  };\n}\n\n/**\n * Timeout middleware to prevent hanging requests\n *\n * Rejects the event if processing exceeds the specified timeout\n */\nexport function timeoutMiddleware(options: { timeoutMs: number }): SubscriberMiddleware {\n  return async ({ next }) => {\n    const timeoutPromise = new Promise<never>((_, reject) => {\n      setTimeout(() => reject(new Error(`Timeout after ${options.timeoutMs}ms`)), options.timeoutMs);\n    });\n\n    await Promise.race([next(), timeoutPromise]);\n  };\n}\n\n/**\n * Create an idempotency store with custom get/set operations\n *\n * Used with withIdempotency middleware to prevent duplicate event processing\n */\nexport function createIdempotencyStore<TResult = unknown>(options: {\n  get: (key: string) => Promise<TResult | null>;\n  set: (key: string, result: TResult, ttlMs: number) => Promise<void>;\n}): IdempotencyStore<TResult> {\n  return { get: options.get, set: options.set };\n}\n\n/**\n * In-memory idempotency store\n *\n * Useful for testing or single-process applications\n */\nexport function inMemoryIdempotencyStore<TResult = unknown>(): IdempotencyStore<TResult> {\n  type Entry = { result: TResult; expiresAtMs: number };\n  const map = new Map<string, Entry>();\n\n  return createIdempotencyStore<TResult>({\n    get: async (key) => {\n      const entry = map.get(key);\n      if (!entry) return null;\n      if (entry.expiresAtMs <= Date.now()) {\n        map.delete(key);\n        return null;\n      }\n      return entry.result;\n    },\n    set: async (key, result, ttlMs) => {\n      map.set(key, { result, expiresAtMs: Date.now() + ttlMs });\n    },\n  });\n}\n\n/**\n * Create a rate limit store with custom record operation\n *\n * Used with withRateLimit middleware for distributed rate limiting\n */\nexport function createRateLimitStore(options: {\n  record: (\n    key: string,\n    windowMs: number,\n    algorithm: RateLimitAlgorithm,\n  ) => Promise<RateLimitRecord>;\n}): RateLimitStore {\n  return { record: options.record };\n}\n\n/**\n * In-memory rate limit store\n *\n * Supports fixed and sliding window algorithms\n */\nexport function inMemoryRateLimitStore(): RateLimitStore {\n  type FixedEntry = { count: number; expireAtMs: number };\n  const fixed = new Map<string, FixedEntry>();\n  const sliding = new Map<string, number[]>();\n\n  return {\n    async record(key, windowMs, algorithm) {\n      const now = Date.now();\n      if (algorithm === 'fixed') {\n        const entry = fixed.get(key);\n        if (!entry || entry.expireAtMs <= now) {\n          const next = { count: 1, expireAtMs: now + windowMs };\n          fixed.set(key, next);\n          return { count: 1, resetAtMs: next.expireAtMs };\n        }\n        entry.count += 1;\n        return { count: entry.count, resetAtMs: entry.expireAtMs };\n      }\n\n      const cutoff = now - windowMs;\n      const points = (sliding.get(key) ?? []).filter((ts) => ts > cutoff);\n      points.push(now);\n      sliding.set(key, points);\n      return { count: points.length, resetAtMs: points[0]! + windowMs };\n    },\n  };\n}\n\n/**\n * Idempotency middleware to prevent duplicate processing\n *\n * Skips processing if the same event (by key) was processed within TTL\n *\n * @example\n * ```typescript\n * const middleware = withIdempotency({\n *   store: inMemoryIdempotencyStore(),\n *   key: event => event.name,\n *   ttlMs: 60000\n * })\n * ```\n */\nexport function withIdempotency(options: {\n  store: IdempotencyStore<boolean>;\n  key: string | ((event: EventsEvent) => string);\n  ttlMs: number;\n}): SubscriberMiddleware {\n  return async ({ event, next }) => {\n    const key = typeof options.key === 'function' ? options.key(event) : options.key;\n    const cached = await options.store.get(key);\n    if (cached) return;\n\n    await next();\n    await options.store.set(key, true, options.ttlMs);\n  };\n}\n\n/**\n * Rate limiting middleware with store-based tracking\n *\n * Enforces rate limits across distributed systems using a store backend\n *\n * @example\n * ```typescript\n * const middleware = withRateLimit({\n *   store: inMemoryRateLimitStore(),\n *   key: event => 'global',\n *   max: 1000,\n *   windowMs: 60000\n * })\n * ```\n */\nexport function withRateLimit(options: {\n  store: RateLimitStore;\n  key: string | ((event: EventsEvent) => string);\n  max: number;\n  windowMs: number;\n  algorithm?: RateLimitAlgorithm;\n}): SubscriberMiddleware {\n  const algorithm = options.algorithm ?? 'fixed';\n\n  return async ({ event, next }) => {\n    const key = typeof options.key === 'function' ? options.key(event) : options.key;\n    const { count, resetAtMs } = await options.store.record(key, options.windowMs, algorithm);\n    if (count > options.max) {\n      const retryAfterMs = Math.max(0, resetAtMs - Date.now());\n      throw new Error(`Rate limited for key \"${key}\". Retry after ${retryAfterMs}ms.`);\n    }\n    await next();\n  };\n}\n\n/**\n * Event logger middleware for observability\n *\n * Writes event records to a sink for monitoring, audit logging, or analytics\n *\n * @example\n * ```typescript\n * const middleware = withEventLogger({\n *   sink: {\n *     write: async (record) => {\n *       await db.eventLogs.insert(record)\n *     }\n *   }\n * })\n * ```\n */\nexport function withEventLogger(options: { sink: SendEventSink }): SubscriberMiddleware {\n  return async ({ event, next, subscriber }) => {\n    const startedAt = new Date();\n    const start = performance.now();\n\n    try {\n      await next();\n      const endedAt = new Date();\n      await options.sink.write({\n        subscriberName: subscriber.name ?? 'unknown',\n        eventType: event.type,\n        eventName: eventNameOf(event),\n        status: 'success',\n        durationMs: performance.now() - start,\n        startedAt,\n        endedAt,\n      });\n    } catch (error) {\n      const err = error instanceof Error ? error : new Error(String(error));\n      const endedAt = new Date();\n      const maybeCode = (err as { code?: unknown }).code;\n\n      await options.sink.write({\n        subscriberName: subscriber.name ?? 'unknown',\n        eventType: event.type,\n        eventName: eventNameOf(event),\n        status: 'error',\n        durationMs: performance.now() - start,\n        startedAt,\n        endedAt,\n        error: {\n          name: err.name,\n          message: err.message,\n          code: typeof maybeCode === 'string' ? maybeCode : undefined,\n        },\n      });\n      throw err;\n    }\n  };\n}\n"],"mappings":"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"}