{"version":3,"file":"usePerformanceMonitor.mjs","sources":["../../../src/lib/hooks/usePerformanceMonitor.ts"],"sourcesContent":["/**\n * @file Performance Monitoring Hook\n * @description Enterprise-grade performance monitoring with Web Vitals and custom metrics\n */\n\nimport { useEffect, useRef, useCallback, useState } from 'react';\nimport { onCLS, onFCP, onINP, onLCP, onTTFB, type Metric } from 'web-vitals';\nimport { useBuffer } from './shared/useBuffer';\n\ninterface PerformanceMetrics {\n  CLS?: number; // Cumulative Layout Shift\n  FCP?: number; // First Contentful Paint\n  INP?: number; // Interaction to Next Paint (replaced FID)\n  LCP?: number; // Largest Contentful Paint\n  TTFB?: number; // Time to First Byte\n  customMetrics: Map<string, number>;\n  resourceTimings: PerformanceResourceTiming[];\n  longTasks: PerformanceEntry[];\n  memoryUsage?: {\n    usedJSHeapSize: number;\n    totalJSHeapSize: number;\n    jsHeapSizeLimit: number;\n  };\n}\n\ninterface PerformanceThresholds {\n  CLS?: number;\n  FCP?: number;\n  INP?: number;\n  LCP?: number;\n  TTFB?: number;\n  memoryUsage?: number;\n}\n\ninterface UsePerformanceMonitorOptions {\n  enableWebVitals?: boolean;\n  enableResourceTiming?: boolean;\n  enableLongTaskDetection?: boolean;\n  enableMemoryMonitoring?: boolean;\n  sampleRate?: number; // 0-1, for sampling metrics collection\n  thresholds?: PerformanceThresholds;\n  onMetricUpdate?: (metric: Partial<PerformanceMetrics>) => void;\n  onThresholdExceeded?: (metricName: string, value: number, threshold: number) => void;\n  reportingEndpoint?: string;\n  batchSize?: number;\n  flushInterval?: number;\n}\n\nconst DEFAULT_THRESHOLDS: PerformanceThresholds = {\n  CLS: 0.1,\n  FCP: 1800,\n  INP: 200,\n  LCP: 2500,\n  TTFB: 800,\n  memoryUsage: 0.9, // 90% of heap limit\n};\n\nexport function usePerformanceMonitor(options: UsePerformanceMonitorOptions = {}): {\n  metrics: PerformanceMetrics;\n  trackMetric: (name: string, value: number) => void;\n  markNavigationTiming: (name: string) => (() => void) | undefined;\n  getResourceStats: () => {\n    totalResources: number;\n    totalSize: number;\n    totalDuration: number;\n    byType: Record<string, { count: number; size: number; duration: number }>;\n    slowResources: PerformanceResourceTiming[];\n  };\n  flushMetrics: () => void;\n} {\n  const {\n    enableWebVitals = true,\n    enableResourceTiming = true,\n    enableLongTaskDetection = true,\n    enableMemoryMonitoring = true,\n    sampleRate = 1,\n    thresholds = DEFAULT_THRESHOLDS,\n    onMetricUpdate,\n    onThresholdExceeded,\n    reportingEndpoint,\n    batchSize = 10,\n    flushInterval = 30000, // 30 seconds\n  } = options;\n\n  const [metrics, setMetrics] = useState<PerformanceMetrics>({\n    customMetrics: new Map(),\n    resourceTimings: [],\n    longTasks: [],\n  });\n\n  const observersRef = useRef<{ disconnect: () => void }[]>([]);\n\n  // Send metrics to reporting endpoint\n  const sendMetrics = useCallback(\n    async (metricsToSend: Partial<PerformanceMetrics>[]): Promise<void> => {\n      if (reportingEndpoint == null || metricsToSend.length === 0) return;\n\n      try {\n        await fetch(reportingEndpoint, {\n          method: 'POST',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({\n            metrics: metricsToSend,\n            timestamp: Date.now(),\n            url: window.location.href,\n            userAgent: navigator.userAgent,\n          }),\n          keepalive: true, // Ensure request completes even if page unloads\n        });\n      } catch (error) {\n        console.error('Failed to send performance metrics:', error);\n      }\n    },\n    [reportingEndpoint]\n  );\n\n  // Use shared buffer for metrics batching\n  const metricsBuffer = useBuffer<Partial<PerformanceMetrics>>({\n    maxSize: batchSize,\n    flushInterval,\n    onFlush: sendMetrics,\n    flushOnUnmount: true,\n  });\n\n  // Check if we should collect metrics based on sample rate\n  const shouldCollect = useCallback(() => {\n    return Math.random() < sampleRate;\n  }, [sampleRate]);\n\n  // Check and report threshold violations\n  const checkThreshold = useCallback(\n    (metricName: string, value: number) => {\n      const threshold = thresholds[metricName as keyof PerformanceThresholds];\n      if (threshold != null && value > threshold) {\n        onThresholdExceeded?.(metricName, value, threshold);\n\n        // Log critical performance issues\n        console.warn(\n          `Performance threshold exceeded: ${metricName} = ${value}ms (threshold: ${threshold}ms)`\n        );\n      }\n    },\n    [thresholds, onThresholdExceeded]\n  );\n\n  // Track custom metric\n  const trackMetric = useCallback(\n    (name: string, value: number) => {\n      if (!shouldCollect()) return;\n\n      setMetrics((prev) => {\n        const newMetrics = { ...prev };\n        newMetrics.customMetrics.set(name, value);\n        return newMetrics;\n      });\n\n      const metric = { customMetrics: new Map([[name, value]]) };\n      onMetricUpdate?.(metric);\n      metricsBuffer.add(metric);\n      checkThreshold(name, value);\n    },\n    [shouldCollect, onMetricUpdate, metricsBuffer, checkThreshold]\n  );\n\n  // Mark navigation timing\n  const markNavigationTiming = useCallback(\n    (name: string) => {\n      if (!shouldCollect()) return;\n\n      performance.mark(name);\n      return () => {\n        performance.measure(name, name);\n        const [measure] = performance.getEntriesByName(name, 'measure');\n        if (measure != null) {\n          trackMetric(`navigation.${name}`, measure.duration);\n        }\n      };\n    },\n    [shouldCollect, trackMetric]\n  );\n\n  // Get resource load statistics\n  const getResourceStats = useCallback((): {\n    totalResources: number;\n    totalSize: number;\n    totalDuration: number;\n    byType: Record<string, { count: number; size: number; duration: number }>;\n    slowResources: PerformanceResourceTiming[];\n  } => {\n    const resources = performance.getEntriesByType(\n      'resource'\n    ) as unknown as PerformanceResourceTiming[];\n\n    const stats = {\n      totalResources: resources.length,\n      totalSize: 0,\n      totalDuration: 0,\n      byType: {} as Record<string, { count: number; size: number; duration: number }>,\n      slowResources: [] as PerformanceResourceTiming[],\n    };\n\n    resources.forEach((resource: PerformanceResourceTiming) => {\n      const type = resource.initiatorType ?? 'other';\n\n      stats.byType[type] ??= { count: 0, size: 0, duration: 0 };\n\n      stats.byType[type].count++;\n      stats.byType[type].size += resource.transferSize || 0;\n      stats.byType[type].duration += resource.duration;\n\n      stats.totalSize += resource.transferSize || 0;\n      stats.totalDuration += resource.duration;\n\n      // Track slow resources (> 1 second)\n      if (resource.duration > 1000) {\n        stats.slowResources.push(resource);\n      }\n    });\n\n    return stats;\n  }, []);\n\n  // Setup Web Vitals monitoring\n  useEffect(() => {\n    if (!enableWebVitals || !shouldCollect()) return;\n\n    const handleMetric = (metric: Metric): void => {\n      const value = Math.round(metric.value);\n\n      setMetrics((prev) => ({\n        ...prev,\n        [metric.name]: value,\n      }));\n\n      const update = { [metric.name]: value };\n      onMetricUpdate?.(update);\n      metricsBuffer.add(update);\n      checkThreshold(metric.name, value);\n    };\n\n    // Register Web Vitals observers\n    // Note: FID was deprecated in web-vitals v4 and replaced by INP\n    onCLS(handleMetric);\n    onFCP(handleMetric);\n    onINP(handleMetric);\n    onLCP(handleMetric);\n    onTTFB(handleMetric);\n  }, [enableWebVitals, shouldCollect, onMetricUpdate, metricsBuffer, checkThreshold]);\n\n  // Setup resource timing monitoring\n  useEffect(() => {\n    if (!enableResourceTiming || !shouldCollect()) return;\n\n    const observer = new PerformanceObserver((list) => {\n      const entries = list.getEntries() as PerformanceResourceTiming[];\n\n      setMetrics((prev) => ({\n        ...prev,\n        resourceTimings: [...prev.resourceTimings, ...entries],\n      }));\n\n      // Track slow resources\n      entries.forEach((entry) => {\n        if (entry.duration > 1000) {\n          console.warn(`Slow resource detected: ${entry.name} (${Math.round(entry.duration)}ms)`);\n        }\n      });\n    });\n\n    try {\n      observer.observe({ entryTypes: ['resource'] });\n      observersRef.current.push(observer);\n    } catch (error) {\n      console.error('Failed to setup resource timing observer:', error);\n    }\n\n    return () => observer.disconnect();\n  }, [enableResourceTiming, shouldCollect]);\n\n  // Setup long task detection\n  useEffect(() => {\n    if (!enableLongTaskDetection || !shouldCollect() || !('PerformanceObserver' in window)) {\n      return;\n    }\n\n    const observer = new PerformanceObserver((list) => {\n      const entries = list.getEntries();\n\n      setMetrics((prev) => ({\n        ...prev,\n        longTasks: [...prev.longTasks, ...entries],\n      }));\n\n      entries.forEach((entry) => {\n        console.warn(`Long task detected: ${Math.round(entry.duration)}ms`);\n        trackMetric('longTask', entry.duration);\n      });\n    });\n\n    try {\n      observer.observe({ entryTypes: ['longtask'] });\n      observersRef.current.push(observer);\n    } catch (error) {\n      console.error('Failed to setup long task observer:', error);\n    }\n\n    return () => observer.disconnect();\n  }, [enableLongTaskDetection, shouldCollect, trackMetric]);\n\n  // Setup memory monitoring\n  useEffect(() => {\n    if (!enableMemoryMonitoring || !shouldCollect()) return;\n\n    const checkMemory = (): void => {\n      interface PerformanceMemory {\n        usedJSHeapSize: number;\n        totalJSHeapSize: number;\n        jsHeapSizeLimit: number;\n      }\n\n      interface PerformanceWithMemory extends Performance {\n        memory?: PerformanceMemory;\n      }\n\n      const perf = performance as PerformanceWithMemory;\n      if (perf.memory != null) {\n        const usage = {\n          usedJSHeapSize: perf.memory.usedJSHeapSize,\n          totalJSHeapSize: perf.memory.totalJSHeapSize,\n          jsHeapSizeLimit: perf.memory.jsHeapSizeLimit,\n        };\n\n        setMetrics((prev) => ({\n          ...prev,\n          memoryUsage: usage,\n        }));\n\n        // Check memory threshold\n        const usageRatio = usage.usedJSHeapSize / usage.jsHeapSizeLimit;\n        if (thresholds.memoryUsage != null && usageRatio > thresholds.memoryUsage) {\n          onThresholdExceeded?.('memoryUsage', usageRatio * 100, thresholds.memoryUsage * 100);\n        }\n      }\n    };\n\n    const interval = setInterval(checkMemory, 10000); // Check every 10 seconds\n    checkMemory(); // Initial check\n\n    return () => clearInterval(interval);\n  }, [enableMemoryMonitoring, shouldCollect, thresholds.memoryUsage, onThresholdExceeded]);\n\n  // Cleanup observers on unmount\n  useEffect(() => {\n    return () => {\n      // Cleanup observers\n      observersRef.current.forEach((observer) => observer.disconnect());\n      observersRef.current = [];\n    };\n  }, []);\n\n  return {\n    metrics,\n    trackMetric,\n    markNavigationTiming,\n    getResourceStats,\n    flushMetrics: metricsBuffer.flush,\n  };\n}\n\n// Export types for external use\nexport type { PerformanceMetrics, PerformanceThresholds, UsePerformanceMonitorOptions };\n"],"names":["DEFAULT_THRESHOLDS","usePerformanceMonitor","options","enableWebVitals","enableResourceTiming","enableLongTaskDetection","enableMemoryMonitoring","sampleRate","thresholds","onMetricUpdate","onThresholdExceeded","reportingEndpoint","batchSize","flushInterval","metrics","setMetrics","useState","observersRef","useRef","sendMetrics","useCallback","metricsToSend","error","metricsBuffer","useBuffer","shouldCollect","checkThreshold","metricName","value","threshold","trackMetric","name","prev","newMetrics","metric","markNavigationTiming","measure","getResourceStats","resources","stats","resource","type","useEffect","handleMetric","update","onCLS","onFCP","onINP","onLCP","onTTFB","observer","list","entries","entry","checkMemory","perf","usage","usageRatio","interval"],"mappings":"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"}