{"version":3,"sources":["../src/metric.ts"],"names":["getConfig"],"mappings":"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","file":"chunk-TC5ZPWM4.cjs","sourcesContent":["/**\n * Metrics API for OpenTelemetry\n *\n * Track business metrics for OpenTelemetry (Prometheus/Grafana).\n * For business people who think in metrics.\n *\n * @example Track business metrics\n * ```typescript\n * const metrics = new Metric('checkout')\n *\n * // Track events as metrics\n * metrics.trackEvent('order.completed', {\n *   amount: 99.99,\n *   currency: 'USD'\n * })\n *\n * // Track conversion funnels\n * metrics.trackFunnelStep('checkout', 'started', { cartValue: 99.99 })\n * metrics.trackFunnelStep('checkout', 'completed', { cartValue: 99.99 })\n *\n * // Track outcomes\n * metrics.trackOutcome('payment.process', 'success', { amount: 99.99 })\n * metrics.trackOutcome('payment.process', 'failure', { error: 'insufficient_funds' })\n *\n * // Track values\n * metrics.trackValue('revenue', 149.99, { currency: 'USD' })\n * ```\n */\n\nimport {\n  type Counter,\n  type Histogram,\n  type Attributes,\n} from '@opentelemetry/api';\nimport { getConfig } from './config';\nimport { type Logger } from './logger';\nimport {\n  type EventAttributes,\n  type FunnelStatus,\n  type OutcomeStatus,\n} from './event-subscriber';\nimport { type MetricsCollector } from './metric-testing';\n\n// Re-export types for convenience\nexport type {\n  EventAttributes,\n  FunnelStatus,\n  OutcomeStatus,\n} from './event-subscriber';\n\n/**\n * Metrics class for tracking business metrics in OpenTelemetry\n *\n * Track critical business indicators such as:\n * - User events (signups, purchases, feature usage) as metrics\n * - Conversion funnels (signup → activation → purchase)\n * - Business outcomes (success/failure rates)\n * - Value metrics (revenue, counts, etc.)\n *\n * All metrics are sent to OpenTelemetry (OTLP/Prometheus/Grafana).\n */\n/**\n * Metric configuration for customizing metric names and descriptions\n */\nexport interface MetricConfig {\n  /** Metric name (e.g., 'metrics.events' or 'custom.events') */\n  name?: string;\n  /** Metric description */\n  description?: string;\n  /** Metric unit (default: '1') */\n  unit?: string;\n}\n\n/**\n * Metrics options\n */\nexport interface MetricsOptions {\n  /** Optional logger for audit trail */\n  logger?: Logger;\n  /** Optional collector for testing (captures metrics in memory) */\n  collector?: MetricsCollector;\n\n  /**\n   * Namespace for metrics (default: 'metrics')\n   * Results in metrics like: {serviceName}.{namespace}.events\n   */\n  namespace?: string;\n\n  /**\n   * Custom metric configurations\n   * Override metric names, descriptions, and units\n   */\n  metrics?: {\n    events?: MetricConfig;\n    funnel?: MetricConfig;\n    outcomes?: MetricConfig;\n    value?: MetricConfig;\n  };\n}\n\nexport class Metric {\n  private serviceName: string;\n  private eventCounter: Counter;\n  private funnelCounter: Counter;\n  private outcomeCounter: Counter;\n  private valueHistogram: Histogram;\n  private logger?: Logger;\n  private collector?: MetricsCollector;\n\n  /**\n   * Create a new Metrics instance\n   *\n   * @param serviceName - Service name for metric namespacing\n   * @param options - Optional configuration (logger, collector, namespace, metrics)\n   *\n   * @example Basic usage (default 'metrics' namespace)\n   * ```typescript\n   * const metrics = new Metric('checkout');\n   * // Creates: checkout.metrics.events, checkout.metrics.funnel, etc.\n   * ```\n   *\n   * @example Custom namespace\n   * ```typescript\n   * const metrics = new Metric('api', { namespace: 'business' });\n   * // Creates: api.business.events, api.business.funnel, etc.\n   * ```\n   *\n   * @example Custom metric names and descriptions\n   * ```typescript\n   * const metrics = new Metric('payments', {\n   *   metrics: {\n   *     outcomes: {\n   *       name: 'payments.transactions',\n   *       description: 'Payment transaction outcomes',\n   *       unit: 'transactions'\n   *     },\n   *     value: {\n   *       name: 'payments.revenue',\n   *       description: 'Payment revenue in USD',\n   *       unit: 'USD'\n   *     }\n   *   }\n   * });\n   * ```\n   */\n  constructor(serviceName: string, options: MetricsOptions = {}) {\n    this.serviceName = serviceName;\n    this.logger = options.logger;\n    this.collector = options.collector;\n\n    const config = getConfig();\n    const meter = config.meter;\n\n    // Default namespace and metric configurations\n    const namespace = options.namespace || 'metrics';\n    const metricsConfig = options.metrics || {};\n\n    // Event counter configuration\n    const eventsConfig = metricsConfig.events || {};\n    this.eventCounter = meter.createCounter(\n      eventsConfig.name || `${serviceName}.${namespace}.events`,\n      {\n        description: eventsConfig.description || 'Count of business events',\n        unit: eventsConfig.unit || '1',\n      },\n    );\n\n    // Funnel counter configuration\n    const funnelConfig = metricsConfig.funnel || {};\n    this.funnelCounter = meter.createCounter(\n      funnelConfig.name || `${serviceName}.${namespace}.funnel`,\n      {\n        description: funnelConfig.description || 'Conversion funnel tracking',\n        unit: funnelConfig.unit || '1',\n      },\n    );\n\n    // Outcome counter configuration\n    const outcomesConfig = metricsConfig.outcomes || {};\n    this.outcomeCounter = meter.createCounter(\n      outcomesConfig.name || `${serviceName}.${namespace}.outcomes`,\n      {\n        description:\n          outcomesConfig.description || 'Outcome tracking (success/failure)',\n        unit: outcomesConfig.unit || '1',\n      },\n    );\n\n    // Value histogram configuration\n    const valueConfig = metricsConfig.value || {};\n    this.valueHistogram = meter.createHistogram(\n      valueConfig.name || `${serviceName}.${namespace}.value`,\n      {\n        description:\n          valueConfig.description || 'Value metrics (revenue, counts, etc.)',\n        unit: valueConfig.unit || '1',\n      },\n    );\n  }\n\n  /**\n   * Track a business event as a metric\n   *\n   * Use this for tracking user actions, business events, product usage as metrics:\n   * - \"user.signup\"\n   * - \"order.completed\"\n   * - \"feature.used\"\n   *\n   * @example\n   * ```typescript\n   * // Track user signup as metric\n   * metrics.trackEvent('user.signup', {\n   *   userId: '123',\n   *   plan: 'pro'\n   * })\n   *\n   * // Track order as metric\n   * metrics.trackEvent('order.completed', {\n   *   orderId: 'ord_123',\n   *   amount: 99.99\n   * })\n   * ```\n   */\n  trackEvent(eventName: string, attributes?: EventAttributes): void {\n    const attrs: Attributes = {\n      service: this.serviceName,\n      event: eventName,\n      ...attributes,\n    };\n\n    this.eventCounter.add(1, attrs);\n\n    this.logger?.info(\n      {\n        event: eventName,\n        attributes,\n      },\n      'Metric event tracked',\n    );\n\n    // Record for testing\n    this.collector?.recordEvent({\n      event: eventName,\n      attributes,\n      service: this.serviceName,\n      timestamp: Date.now(),\n    });\n  }\n\n  /**\n   * Track conversion funnel steps as metrics\n   *\n   * Monitor where users drop off in multi-step processes.\n   *\n   * @example\n   * ```typescript\n   * // Track signup funnel\n   * metrics.trackFunnelStep('signup', 'started', { userId: '123' })\n   * metrics.trackFunnelStep('signup', 'email_verified', { userId: '123' })\n   * metrics.trackFunnelStep('signup', 'completed', { userId: '123' })\n   *\n   * // Track checkout flow\n   * metrics.trackFunnelStep('checkout', 'started', { cartValue: 99.99 })\n   * metrics.trackFunnelStep('checkout', 'payment_info', { cartValue: 99.99 })\n   * metrics.trackFunnelStep('checkout', 'completed', { cartValue: 99.99 })\n   * ```\n   */\n  trackFunnelStep(\n    funnelName: string,\n    status: FunnelStatus,\n    attributes?: EventAttributes,\n  ): void {\n    const attrs: Attributes = {\n      service: this.serviceName,\n      funnel: funnelName,\n      status,\n      ...attributes,\n    };\n\n    this.funnelCounter.add(1, attrs);\n\n    this.logger?.info(\n      {\n        funnel: funnelName,\n        status,\n        attributes,\n      },\n      'Funnel step tracked',\n    );\n\n    // Record for testing\n    this.collector?.recordFunnelStep({\n      funnel: funnelName,\n      status,\n      attributes,\n      service: this.serviceName,\n      timestamp: Date.now(),\n    });\n  }\n\n  /**\n   * Track outcomes (success/failure/partial) as metrics\n   *\n   * Monitor success rates of critical operations.\n   *\n   * @example\n   * ```typescript\n   * // Track email delivery\n   * metrics.trackOutcome('email.delivery', 'success', {\n   *   recipientType: 'user',\n   *   emailType: 'welcome'\n   * })\n   *\n   * metrics.trackOutcome('email.delivery', 'failure', {\n   *   recipientType: 'user',\n   *   errorCode: 'invalid_email'\n   * })\n   *\n   * // Track payment processing\n   * metrics.trackOutcome('payment.process', 'success', { amount: 99.99 })\n   * metrics.trackOutcome('payment.process', 'failure', { error: 'insufficient_funds' })\n   * ```\n   */\n  trackOutcome(\n    operationName: string,\n    status: OutcomeStatus,\n    attributes?: EventAttributes,\n  ): void {\n    const attrs: Attributes = {\n      service: this.serviceName,\n      operation: operationName,\n      status,\n      ...attributes,\n    };\n\n    this.outcomeCounter.add(1, attrs);\n\n    this.logger?.info(\n      {\n        operation: operationName,\n        status,\n        attributes,\n      },\n      'Outcome tracked',\n    );\n\n    // Record for testing\n    this.collector?.recordOutcome({\n      operation: operationName,\n      status,\n      attributes,\n      service: this.serviceName,\n      timestamp: Date.now(),\n    });\n  }\n\n  /**\n   * Track value metrics\n   *\n   * Record numerical values like revenue, transaction amounts,\n   * item counts, processing times, engagement scores, etc.\n   *\n   * @example\n   * ```typescript\n   * // Track revenue\n   * metrics.trackValue('order.revenue', 149.99, {\n   *   currency: 'USD',\n   *   productCategory: 'electronics'\n   * })\n   *\n   * // Track items per cart\n   * metrics.trackValue('cart.item_count', 5, {\n   *   userId: '123'\n   * })\n   *\n   * // Track processing time\n   * metrics.trackValue('api.response_time', 250, {\n   *   unit: 'ms',\n   *   endpoint: '/api/checkout'\n   * })\n   * ```\n   */\n  trackValue(\n    metricName: string,\n    value: number,\n    attributes?: EventAttributes,\n  ): void {\n    const attrs: Attributes = {\n      service: this.serviceName,\n      metric: metricName,\n      ...attributes,\n    };\n\n    this.valueHistogram.record(value, attrs);\n\n    this.logger?.debug(\n      {\n        metric: metricName,\n        value,\n        attributes,\n      },\n      'Value metric tracked',\n    );\n\n    // Record for testing\n    this.collector?.recordValue({\n      metric: metricName,\n      value,\n      attributes,\n      service: this.serviceName,\n      timestamp: Date.now(),\n    });\n  }\n}\n\n/**\n * Global metrics instances (singleton pattern)\n */\nconst metricsInstances = new Map<string, Metric>();\n\n/**\n * Get or create a Metrics instance for a service\n *\n * @param serviceName - Service name for metric namespacing\n * @param logger - Optional logger\n * @returns Metrics instance\n *\n * @example\n * ```typescript\n * const metrics = getMetrics('checkout')\n * metrics.trackEvent('order.completed', { orderId: '123' })\n * ```\n */\nexport function getMetrics(serviceName: string, logger?: Logger): Metric {\n  if (!metricsInstances.has(serviceName)) {\n    metricsInstances.set(serviceName, new Metric(serviceName, { logger }));\n  }\n  return metricsInstances.get(serviceName)!;\n}\n\n/**\n * Reset all metrics instances (mainly for testing)\n */\nexport function resetMetrics(): void {\n  metricsInstances.clear();\n}\n"]}