{"version":3,"file":"vitals-collector.mjs","sources":["../../../../src/lib/performance/monitoring/vitals-collector.ts"],"sourcesContent":["/**\n * @file Enhanced Vitals Collector\n * @description Extended Core Web Vitals collection with advanced attribution,\n * custom metrics, and detailed analysis.\n *\n * Features:\n * - Core Web Vitals (LCP, FID, CLS, INP, FCP, TTFB)\n * - Custom metric definitions\n * - Attribution analysis\n * - Element-level tracking\n * - Historical comparison\n * - Threshold management\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Metric name type\n */\nexport type MetricName =\n  | 'LCP'\n  | 'FID'\n  | 'CLS'\n  | 'INP'\n  | 'FCP'\n  | 'TTFB'\n  | 'FMP'\n  | 'TTI'\n  | 'TBT'\n  | 'custom';\n\n/**\n * Metric rating\n */\nexport type MetricRating = 'good' | 'needs-improvement' | 'poor';\n\n/**\n * Collected metric data\n */\nexport interface CollectedMetric {\n  name: MetricName | string;\n  value: number;\n  rating: MetricRating;\n  delta: number;\n  id: string;\n  navigationType: string;\n  timestamp: number;\n  attribution: MetricAttribution | null;\n  entries: PerformanceEntry[];\n}\n\n/**\n * Metric attribution data\n */\nexport interface MetricAttribution {\n  element?: string;\n  url?: string;\n  timeToFirstByte?: number;\n  resourceLoadDelay?: number;\n  elementRenderDelay?: number;\n  lcpResourceEntry?: PerformanceResourceTiming;\n  largestShiftTarget?: string;\n  largestShiftTime?: number;\n  loadState?: string;\n  eventTarget?: string;\n  eventType?: string;\n  eventTime?: number;\n  nextPaintTime?: number;\n}\n\n/**\n * Metric thresholds\n */\nexport interface MetricThresholds {\n  good: number;\n  poor: number;\n}\n\n/**\n * Collection configuration\n */\nexport interface VitalsCollectionConfig {\n  /** Enable collection */\n  enabled: boolean;\n  /** Metrics to collect */\n  metrics: MetricName[];\n  /** Custom thresholds */\n  thresholds?: Partial<Record<MetricName, MetricThresholds>>;\n  /** Enable attribution */\n  attribution: boolean;\n  /** Sample rate (0-1) */\n  sampleRate: number;\n  /** Report endpoint */\n  reportEndpoint?: string;\n  /** Batch reports */\n  batchReports: boolean;\n  /** Batch interval in ms */\n  batchInterval: number;\n  /** Debug mode */\n  debug: boolean;\n}\n\n/**\n * Metric callback\n */\nexport type MetricCallback = (metric: CollectedMetric) => void;\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Default thresholds based on Google recommendations\n */\nexport const DEFAULT_THRESHOLDS: Record<MetricName, MetricThresholds> = {\n  LCP: { good: 2500, poor: 4000 },\n  FID: { good: 100, poor: 300 },\n  CLS: { good: 0.1, poor: 0.25 },\n  INP: { good: 200, poor: 500 },\n  FCP: { good: 1800, poor: 3000 },\n  TTFB: { good: 800, poor: 1800 },\n  FMP: { good: 2000, poor: 4000 },\n  TTI: { good: 3800, poor: 7300 },\n  TBT: { good: 200, poor: 600 },\n  custom: { good: 100, poor: 500 },\n};\n\nconst DEFAULT_CONFIG: VitalsCollectionConfig = {\n  enabled: true,\n  metrics: ['LCP', 'FID', 'CLS', 'INP', 'FCP', 'TTFB'],\n  attribution: true,\n  sampleRate: 1.0,\n  batchReports: true,\n  batchInterval: 5000,\n  debug: false,\n};\n\n// ============================================================================\n// Enhanced Vitals Collector\n// ============================================================================\n\n/**\n * Enhanced vitals collection with attribution\n */\nexport class EnhancedVitalsCollector {\n  private config: VitalsCollectionConfig;\n  private thresholds: Record<string, MetricThresholds>;\n  private metrics: Map<string, CollectedMetric[]> = new Map();\n  private callbacks: Set<MetricCallback> = new Set();\n  private reportBuffer: CollectedMetric[] = [];\n  private flushTimer: ReturnType<typeof setTimeout> | null = null;\n  private observers: PerformanceObserver[] = [];\n  private isInitialized = false;\n\n  constructor(config: Partial<VitalsCollectionConfig> = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n    this.thresholds = {\n      ...DEFAULT_THRESHOLDS,\n      ...config.thresholds,\n    };\n  }\n\n  /**\n   * Initialize vitals collection\n   */\n  init(): () => void {\n    if (this.isInitialized || !this.config.enabled) {\n      return () => {};\n    }\n\n    // Check sample rate\n    if (Math.random() > this.config.sampleRate) {\n      this.log('Skipping collection (sample rate)');\n      return () => {};\n    }\n\n    this.isInitialized = true;\n    this.log('Initializing enhanced vitals collector');\n\n    // Set up metric collection\n    this.setupMetricCollection();\n\n    // Set up batch reporting\n    if (this.config.batchReports) {\n      this.startBatchFlush();\n    }\n\n    // Set up page lifecycle handlers\n    this.setupLifecycleHandlers();\n\n    // Return cleanup function\n    return () => this.cleanup();\n  }\n\n  /**\n   * Subscribe to metric updates\n   */\n  subscribe(callback: MetricCallback): () => void {\n    this.callbacks.add(callback);\n    return () => this.callbacks.delete(callback);\n  }\n\n  /**\n   * Get all collected metrics\n   */\n  getMetrics(): Map<string, CollectedMetric[]> {\n    return new Map(this.metrics);\n  }\n\n  /**\n   * Get specific metric\n   */\n  getMetric(name: MetricName): CollectedMetric[] {\n    return this.metrics.get(name) ?? [];\n  }\n\n  /**\n   * Get latest value for a metric\n   */\n  getLatestValue(name: MetricName): CollectedMetric | null {\n    const metrics = this.metrics.get(name);\n    return metrics?.[metrics.length - 1] ?? null;\n  }\n\n  /**\n   * Track a custom metric\n   */\n  trackCustomMetric(name: string, value: number, thresholds?: MetricThresholds): void {\n    const effectiveThresholds = thresholds ?? this.thresholds.custom;\n    const rating =\n      effectiveThresholds !== undefined ? this.calculateRating(value, effectiveThresholds) : 'good';\n\n    const metric: CollectedMetric = {\n      name,\n      value,\n      rating,\n      delta: value,\n      id: this.generateId(),\n      navigationType: 'custom',\n      timestamp: Date.now(),\n      attribution: null,\n      entries: [],\n    };\n\n    this.recordMetric(metric);\n  }\n\n  /**\n   * Start a custom timing\n   */\n  startTiming(name: string): () => void {\n    const startTime = performance.now();\n    const startMark = `${name}-start`;\n    performance.mark(startMark);\n\n    return () => {\n      const endMark = `${name}-end`;\n      performance.mark(endMark);\n      performance.measure(name, startMark, endMark);\n\n      const duration = performance.now() - startTime;\n      this.trackCustomMetric(name, duration);\n    };\n  }\n\n  /**\n   * Flush any pending reports\n   */\n  flush(): void {\n    if (this.reportBuffer.length === 0) return;\n\n    const reports = [...this.reportBuffer];\n    this.reportBuffer = [];\n\n    if (this.config.reportEndpoint != null && this.config.reportEndpoint !== '') {\n      void this.sendToEndpoint(reports);\n    }\n  }\n\n  /**\n   * Get summary statistics\n   */\n  getSummary(): Record<string, { value: number; rating: MetricRating } | null> {\n    const summary: Record<string, { value: number; rating: MetricRating } | null> = {};\n\n    for (const name of this.config.metrics) {\n      const latest = this.getLatestValue(name);\n      summary[name] = latest ? { value: latest.value, rating: latest.rating } : null;\n    }\n\n    return summary;\n  }\n\n  /**\n   * Calculate overall performance score\n   */\n  calculateScore(): number {\n    const weights: Record<MetricName, number> = {\n      LCP: 0.25,\n      INP: 0.3,\n      CLS: 0.25,\n      FCP: 0.1,\n      TTFB: 0.1,\n      FID: 0,\n      FMP: 0,\n      TTI: 0,\n      TBT: 0,\n      custom: 0,\n    };\n\n    let totalWeight = 0;\n    let weightedScore = 0;\n\n    for (const name of this.config.metrics) {\n      const latest = this.getLatestValue(name);\n      if (latest && weights[name] > 0) {\n        const score = this.ratingToScore(latest.rating);\n        weightedScore += score * weights[name];\n        totalWeight += weights[name];\n      }\n    }\n\n    return totalWeight > 0 ? Math.round(weightedScore / totalWeight) : 0;\n  }\n\n  // ============================================================================\n  // Private Methods\n  // ============================================================================\n\n  private setupMetricCollection(): void {\n    if (typeof PerformanceObserver === 'undefined') {\n      this.log('PerformanceObserver not supported');\n      return;\n    }\n\n    // LCP\n    if (this.config.metrics.includes('LCP')) {\n      this.observeLCP();\n    }\n\n    // FID\n    if (this.config.metrics.includes('FID')) {\n      this.observeFID();\n    }\n\n    // CLS\n    if (this.config.metrics.includes('CLS')) {\n      this.observeCLS();\n    }\n\n    // INP\n    if (this.config.metrics.includes('INP')) {\n      this.observeINP();\n    }\n\n    // FCP\n    if (this.config.metrics.includes('FCP')) {\n      this.observeFCP();\n    }\n\n    // TTFB\n    if (this.config.metrics.includes('TTFB')) {\n      this.observeTTFB();\n    }\n  }\n\n  private observeLCP(): void {\n    try {\n      const observer = new PerformanceObserver((list) => {\n        const entries = list.getEntries();\n        const lastEntry = entries[entries.length - 1] as PerformanceEntry & {\n          element?: Element;\n          url?: string;\n          renderTime?: number;\n          loadTime?: number;\n        };\n\n        if (lastEntry != null) {\n          const value = lastEntry.startTime;\n          const attribution = this.config.attribution\n            ? {\n                element: this.getElementSelector(lastEntry.element),\n                url: lastEntry.url,\n                elementRenderDelay: lastEntry.renderTime,\n                resourceLoadDelay: lastEntry.loadTime,\n              }\n            : null;\n\n          this.recordMetric({\n            name: 'LCP',\n            value,\n            rating: this.calculateRating(value, this.thresholds.LCP ?? DEFAULT_THRESHOLDS.LCP),\n            delta: value,\n            id: this.generateId(),\n            navigationType: this.getNavigationType(),\n            timestamp: Date.now(),\n            attribution,\n            entries: [lastEntry],\n          });\n        }\n      });\n\n      observer.observe({ type: 'largest-contentful-paint', buffered: true });\n      this.observers.push(observer);\n    } catch (e) {\n      this.log('Failed to observe LCP', e);\n    }\n  }\n\n  private observeFID(): void {\n    try {\n      const observer = new PerformanceObserver((list) => {\n        const entries = list.getEntries() as Array<\n          PerformanceEventTiming & {\n            target?: Element;\n          }\n        >;\n\n        for (const entry of entries) {\n          const value = entry.processingStart - entry.startTime;\n          const attribution = this.config.attribution\n            ? {\n                eventTarget: this.getElementSelector(entry.target),\n                eventType: entry.name,\n                eventTime: entry.startTime,\n              }\n            : null;\n\n          this.recordMetric({\n            name: 'FID',\n            value,\n            rating: this.calculateRating(value, this.thresholds.FID ?? DEFAULT_THRESHOLDS.FID),\n            delta: value,\n            id: this.generateId(),\n            navigationType: this.getNavigationType(),\n            timestamp: Date.now(),\n            attribution,\n            entries: [entry],\n          });\n        }\n      });\n\n      observer.observe({ type: 'first-input', buffered: true });\n      this.observers.push(observer);\n    } catch (e) {\n      this.log('Failed to observe FID', e);\n    }\n  }\n\n  private observeCLS(): void {\n    try {\n      let clsValue = 0;\n      let clsEntries: PerformanceEntry[] = [];\n      let sessionValue = 0;\n      let sessionEntries: PerformanceEntry[] = [];\n      let previousEndTime = 0;\n\n      const observer = new PerformanceObserver((list) => {\n        for (const entry of list.getEntries() as Array<\n          PerformanceEntry & {\n            hadRecentInput?: boolean;\n            value?: number;\n            sources?: Array<{ node?: Element }>;\n          }\n        >) {\n          // Ignore entries with recent input\n          if (entry.hadRecentInput === true) continue;\n\n          const firstEntryTime = sessionEntries[0]?.startTime ?? 0;\n          const timeSinceFirstEntry = entry.startTime - firstEntryTime;\n          const timeSinceLastEntry = entry.startTime - previousEndTime;\n\n          // Start new session if gap > 1s or total duration > 5s\n          if (timeSinceLastEntry > 1000 || timeSinceFirstEntry > 5000) {\n            if (sessionValue > clsValue) {\n              clsValue = sessionValue;\n              clsEntries = sessionEntries;\n            }\n            sessionValue = 0;\n            sessionEntries = [];\n          }\n\n          sessionValue += entry.value ?? 0;\n          sessionEntries.push(entry);\n          previousEndTime = entry.startTime + (entry.duration || 0);\n\n          // Update if new session is larger\n          if (sessionValue > clsValue) {\n            clsValue = sessionValue;\n            clsEntries = sessionEntries;\n\n            const largestShift = clsEntries.reduce((a, b) => {\n              const aValue = (a as { value?: number }).value ?? 0;\n              const bValue = (b as { value?: number }).value ?? 0;\n              return aValue > bValue ? a : b;\n            }) as PerformanceEntry & { sources?: Array<{ node?: Element }> };\n\n            const attribution = this.config.attribution\n              ? {\n                  largestShiftTarget: this.getElementSelector(largestShift.sources?.[0]?.node),\n                  largestShiftTime: largestShift.startTime,\n                }\n              : null;\n\n            this.recordMetric({\n              name: 'CLS',\n              value: clsValue,\n              rating:\n                this.thresholds.CLS !== undefined\n                  ? this.calculateRating(clsValue, this.thresholds.CLS)\n                  : 'good',\n              delta: entry.value ?? 0,\n              id: this.generateId(),\n              navigationType: this.getNavigationType(),\n              timestamp: Date.now(),\n              attribution,\n              entries: clsEntries,\n            });\n          }\n        }\n      });\n\n      observer.observe({ type: 'layout-shift', buffered: true });\n      this.observers.push(observer);\n    } catch (e) {\n      this.log('Failed to observe CLS', e);\n    }\n  }\n\n  private observeINP(): void {\n    try {\n      const interactionEntries: PerformanceEventTiming[] = [];\n      let maxINP = 0;\n\n      const observer = new PerformanceObserver((list) => {\n        const entries = list.getEntries() as PerformanceEventTiming[];\n\n        for (const entry of entries) {\n          // Filter for meaningful interactions\n          if (\n            entry.interactionId &&\n            entry.entryType === 'event' &&\n            ['pointerdown', 'pointerup', 'keydown', 'keyup', 'click'].includes(entry.name)\n          ) {\n            interactionEntries.push(entry);\n\n            // Calculate INP (98th percentile of interactions)\n            const sortedDurations = interactionEntries.map((e) => e.duration).sort((a, b) => b - a);\n\n            const idx = Math.ceil(sortedDurations.length * 0.02) - 1;\n            const inp = sortedDurations[Math.max(0, idx)] ?? 0;\n\n            if (inp > maxINP) {\n              maxINP = inp;\n\n              const longestEntry = interactionEntries.reduce((a, b) =>\n                a.duration > b.duration ? a : b\n              ) as PerformanceEventTiming & { target?: Element };\n\n              const attribution = this.config.attribution\n                ? {\n                    eventTarget: this.getElementSelector(longestEntry.target),\n                    eventType: longestEntry.name,\n                    eventTime: longestEntry.startTime,\n                    nextPaintTime: longestEntry.processingEnd,\n                  }\n                : null;\n\n              this.recordMetric({\n                name: 'INP',\n                value: inp,\n                rating: this.calculateRating(inp, this.thresholds.INP ?? DEFAULT_THRESHOLDS.INP),\n                delta: inp - maxINP,\n                id: this.generateId(),\n                navigationType: this.getNavigationType(),\n                timestamp: Date.now(),\n                attribution,\n                entries: [longestEntry],\n              });\n            }\n          }\n        }\n      });\n\n      observer.observe({\n        type: 'event',\n        buffered: true,\n        durationThreshold: 16,\n      });\n      this.observers.push(observer);\n    } catch (e) {\n      this.log('Failed to observe INP', e);\n    }\n  }\n\n  private observeFCP(): void {\n    try {\n      const observer = new PerformanceObserver((list) => {\n        const entries = list.getEntries();\n        const fcpEntry = entries.find((e) => e.name === 'first-contentful-paint');\n\n        if (fcpEntry) {\n          const value = fcpEntry.startTime;\n\n          this.recordMetric({\n            name: 'FCP',\n            value,\n            rating: this.calculateRating(value, this.thresholds.FCP ?? DEFAULT_THRESHOLDS.FCP),\n            delta: value,\n            id: this.generateId(),\n            navigationType: this.getNavigationType(),\n            timestamp: Date.now(),\n            attribution: null,\n            entries: [fcpEntry],\n          });\n        }\n      });\n\n      observer.observe({ type: 'paint', buffered: true });\n      this.observers.push(observer);\n    } catch (e) {\n      this.log('Failed to observe FCP', e);\n    }\n  }\n\n  private observeTTFB(): void {\n    try {\n      const navEntries = performance.getEntriesByType('navigation');\n      const [navEntry] = navEntries;\n\n      if (navEntry !== undefined) {\n        const value = navEntry.responseStart - navEntry.requestStart;\n\n        const attribution = this.config.attribution\n          ? {\n              timeToFirstByte: value,\n              url: navEntry.name,\n            }\n          : null;\n\n        this.recordMetric({\n          name: 'TTFB',\n          value,\n          rating: this.calculateRating(value, this.thresholds.TTFB ?? DEFAULT_THRESHOLDS.TTFB),\n          delta: value,\n          id: this.generateId(),\n          navigationType: this.getNavigationType(),\n          timestamp: Date.now(),\n          attribution,\n          entries: [navEntry],\n        });\n      }\n    } catch (e) {\n      this.log('Failed to observe TTFB', e);\n    }\n  }\n\n  private recordMetric(metric: CollectedMetric): void {\n    const existing = this.metrics.get(metric.name) ?? [];\n    existing.push(metric);\n    this.metrics.set(metric.name, existing);\n\n    this.log(`Recorded ${metric.name}: ${metric.value} (${metric.rating})`);\n\n    // Notify callbacks\n    this.callbacks.forEach((cb) => cb(metric));\n\n    // Buffer for batch reporting\n    if (this.config.batchReports) {\n      this.reportBuffer.push(metric);\n    }\n  }\n\n  private calculateRating(value: number, thresholds: MetricThresholds): MetricRating {\n    if (value <= thresholds.good) return 'good';\n    if (value <= thresholds.poor) return 'needs-improvement';\n    return 'poor';\n  }\n\n  private ratingToScore(rating: MetricRating): number {\n    switch (rating) {\n      case 'good':\n        return 100;\n      case 'needs-improvement':\n        return 50;\n      case 'poor':\n        return 0;\n    }\n  }\n\n  private getElementSelector(element?: Element | null): string | undefined {\n    if (element === undefined || element === null) return undefined;\n\n    const tag = element.tagName.toLowerCase();\n    const id = element.id ? `#${element.id}` : '';\n    const classes =\n      element.classList.length > 0 ? `.${Array.from(element.classList).join('.')}` : '';\n\n    return `${tag}${id}${classes}`;\n  }\n\n  private getNavigationType(): string {\n    const navEntries = performance.getEntriesByType('navigation');\n    return navEntries[0]?.type ?? 'unknown';\n  }\n\n  private setupLifecycleHandlers(): void {\n    const handleVisibilityChange = (): void => {\n      if (document.visibilityState === 'hidden') {\n        this.flush();\n      }\n    };\n\n    const handlePagehide = (): void => {\n      this.flush();\n    };\n\n    window.addEventListener('visibilitychange', handleVisibilityChange);\n    window.addEventListener('pagehide', handlePagehide);\n  }\n\n  private startBatchFlush(): void {\n    this.flushTimer = setInterval(() => {\n      this.flush();\n    }, this.config.batchInterval);\n  }\n\n  /**\n   * Send collected metrics to the reporting endpoint.\n   *\n   * Note: This method intentionally uses raw fetch/sendBeacon because:\n   * 1. Web Vitals reporting should be independent of the main API client\n   * 2. Uses keepalive/sendBeacon for reliability when page is unloading\n   * 3. Reporting endpoints are often third-party analytics services\n   *\n   * @see {@link @/lib/api/api-client} for application API calls\n   */\n  private async sendToEndpoint(metrics: CollectedMetric[]): Promise<void> {\n    if (this.config.reportEndpoint === undefined || this.config.reportEndpoint === null) return;\n\n    try {\n      const payload = {\n        metrics,\n        url: window.location.href,\n        userAgent: navigator.userAgent,\n        timestamp: Date.now(),\n      };\n\n      if (typeof navigator.sendBeacon === 'function') {\n        navigator.sendBeacon(this.config.reportEndpoint, JSON.stringify(payload));\n      } else {\n        // Raw fetch is intentional - uses keepalive for page unload reliability\n        await fetch(this.config.reportEndpoint, {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify(payload),\n          keepalive: true,\n        });\n      }\n\n      this.log(`Sent ${metrics.length} metrics to endpoint`);\n    } catch (e) {\n      this.log('Failed to send metrics', e);\n    }\n  }\n\n  private cleanup(): void {\n    this.isInitialized = false;\n\n    // Disconnect observers\n    this.observers.forEach((o) => o.disconnect());\n    this.observers = [];\n\n    // Clear timer\n    if (this.flushTimer !== null) {\n      clearInterval(this.flushTimer);\n      this.flushTimer = null;\n    }\n\n    // Final flush\n    this.flush();\n  }\n\n  private generateId(): string {\n    return `v-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n  }\n\n  private log(message: string, ...args: unknown[]): void {\n    if (this.config.debug) {\n      console.info(`[VitalsCollector] ${message}`, ...args);\n    }\n  }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet collectorInstance: EnhancedVitalsCollector | null = null;\n\n/**\n * Get or create the global vitals collector\n */\nexport function getEnhancedVitalsCollector(\n  config?: Partial<VitalsCollectionConfig>\n): EnhancedVitalsCollector {\n  collectorInstance ??= new EnhancedVitalsCollector(config);\n  return collectorInstance;\n}\n\n/**\n * Reset the collector instance\n */\nexport function resetEnhancedVitalsCollector(): void {\n  collectorInstance = null;\n}\n"],"names":["DEFAULT_THRESHOLDS","DEFAULT_CONFIG","EnhancedVitalsCollector","config","callback","name","metrics","value","thresholds","effectiveThresholds","rating","metric","startTime","startMark","endMark","duration","reports","summary","latest","weights","totalWeight","weightedScore","score","observer","list","entries","lastEntry","attribution","e","entry","clsValue","clsEntries","sessionValue","sessionEntries","previousEndTime","firstEntryTime","timeSinceFirstEntry","largestShift","a","b","aValue","bValue","interactionEntries","maxINP","sortedDurations","idx","inp","longestEntry","fcpEntry","navEntries","navEntry","existing","cb","element","tag","id","classes","handleVisibilityChange","handlePagehide","payload","o","message","args","collectorInstance","getEnhancedVitalsCollector","resetEnhancedVitalsCollector"],"mappings":"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"}