{"version":3,"file":"CrashAnalytics.mjs","sources":["../../../src/lib/monitoring/CrashAnalytics.ts"],"sourcesContent":["/**\n * @file Crash Analytics\n * @description Session recording, breadcrumbs, and crash diagnostics\n *\n * This module provides comprehensive crash analytics capabilities:\n * - Breadcrumb tracking for user action history\n * - Session recording for debugging\n * - Performance metrics collection\n * - Device information capture\n * - Error context aggregation\n */\n\nimport type { AppError } from './errorTypes';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Breadcrumb types for categorization\n */\nexport type BreadcrumbType =\n  | 'navigation'\n  | 'ui'\n  | 'http'\n  | 'console'\n  | 'error'\n  | 'user'\n  | 'custom';\n\n/**\n * Breadcrumb severity levels\n */\nexport type BreadcrumbLevel = 'debug' | 'info' | 'warning' | 'error';\n\n/**\n * Single breadcrumb entry\n */\nexport interface Breadcrumb {\n  /** Type of breadcrumb */\n  type: BreadcrumbType;\n  /** Category for grouping */\n  category: string;\n  /** Human-readable message */\n  message: string;\n  /** Additional data */\n  data?: Record<string, unknown>;\n  /** Timestamp in ms */\n  timestamp: number;\n  /** Severity level */\n  level: BreadcrumbLevel;\n}\n\n/**\n * User action for session recording\n */\nexport interface UserAction {\n  /** Action type */\n  type: 'click' | 'input' | 'scroll' | 'navigation' | 'focus' | 'blur';\n  /** CSS selector or element identifier */\n  target: string;\n  /** Value (masked if sensitive) */\n  value?: string;\n  /** Timestamp in ms */\n  timestamp: number;\n  /** Additional metadata */\n  metadata?: Record<string, unknown>;\n}\n\n/**\n * Performance metrics snapshot\n */\nexport interface PerformanceMetrics {\n  /** Page load time in ms */\n  pageLoadTime?: number;\n  /** DOM content loaded time in ms */\n  domContentLoaded?: number;\n  /** First contentful paint in ms */\n  firstContentfulPaint?: number;\n  /** Largest contentful paint in ms */\n  largestContentfulPaint?: number;\n  /** First input delay in ms */\n  firstInputDelay?: number;\n  /** Cumulative layout shift score */\n  cumulativeLayoutShift?: number;\n  /** JS heap size in bytes */\n  jsHeapSize?: number;\n  /** Total memory usage in bytes */\n  memoryUsage?: number;\n}\n\n/**\n * Device information\n */\nexport interface DeviceInfo {\n  /** User agent string */\n  userAgent: string;\n  /** Platform (OS) */\n  platform: string;\n  /** Browser language */\n  language: string;\n  /** Screen resolution */\n  screenResolution: string;\n  /** Viewport size */\n  viewportSize: string;\n  /** Device pixel ratio */\n  devicePixelRatio: number;\n  /** Color depth */\n  colorDepth: number;\n  /** Timezone */\n  timezone: string;\n  /** Cookies enabled */\n  cookiesEnabled: boolean;\n  /** Do Not Track enabled */\n  doNotTrack: boolean;\n}\n\n/**\n * Complete session data for crash report\n */\nexport interface SessionData {\n  /** Unique session ID */\n  sessionId: string;\n  /** User ID if available */\n  userId?: string;\n  /** Session start time */\n  startTime: number;\n  /** Session end time (if ended) */\n  endTime?: number;\n  /** Breadcrumb trail */\n  breadcrumbs: Breadcrumb[];\n  /** Recorded user actions */\n  userActions: UserAction[];\n  /** Performance metrics */\n  performanceMetrics: PerformanceMetrics;\n  /** Device information */\n  deviceInfo: DeviceInfo;\n  /** Errors that occurred */\n  errors: AppError[];\n}\n\n/**\n * Crash analytics configuration\n */\nexport interface CrashAnalyticsConfig {\n  /** Maximum breadcrumbs to keep */\n  maxBreadcrumbs?: number;\n  /** Maximum user actions to keep */\n  maxUserActions?: number;\n  /** Auto-capture click events */\n  autoCaptureClicks?: boolean;\n  /** Auto-capture navigation events */\n  autoCaptureNavigation?: boolean;\n  /** Auto-capture console messages */\n  autoCaptureConsole?: boolean;\n  /** Auto-capture network requests */\n  autoCaptureNetwork?: boolean;\n  /** Mask sensitive input values */\n  maskInputs?: boolean;\n  /** Session recording sample rate (0-1) */\n  sessionSampleRate?: number;\n  /** Custom user ID getter */\n  getUserId?: () => string | undefined;\n}\n\n// ============================================================================\n// Default Configuration\n// ============================================================================\n\nconst DEFAULT_CONFIG: Required<Omit<CrashAnalyticsConfig, 'getUserId'>> & {\n  getUserId?: CrashAnalyticsConfig['getUserId'];\n} = {\n  maxBreadcrumbs: 100,\n  maxUserActions: 500,\n  autoCaptureClicks: true,\n  autoCaptureNavigation: true,\n  autoCaptureConsole: true,\n  autoCaptureNetwork: true,\n  maskInputs: true,\n  sessionSampleRate: 1.0,\n  getUserId: undefined,\n};\n\n// ============================================================================\n// Crash Analytics Manager\n// ============================================================================\n\n/**\n * Crash analytics manager for session recording and breadcrumb tracking\n *\n * @example\n * ```tsx\n * // Initialize crash analytics\n * crashAnalytics.init();\n *\n * // Add custom breadcrumb\n * crashAnalytics.addBreadcrumb({\n *   type: 'custom',\n *   category: 'checkout',\n *   message: 'User started checkout',\n *   level: 'info',\n *   data: { cartItems: 3 }\n * });\n *\n * // Get session data for crash report\n * const sessionData = crashAnalytics.getSessionData();\n * ```\n */\nclass CrashAnalyticsManager {\n  private config: typeof DEFAULT_CONFIG;\n  private sessionId: string;\n  private breadcrumbs: Breadcrumb[] = [];\n  private userActions: UserAction[] = [];\n  private errors: AppError[] = [];\n  private startTime: number;\n  private isRecording: boolean;\n  private cleanupFns: Array<() => void> = [];\n  private initialized = false;\n\n  constructor(config: CrashAnalyticsConfig = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n    this.sessionId = this.generateSessionId();\n    this.startTime = Date.now();\n    this.isRecording = Math.random() < this.config.sessionSampleRate;\n  }\n\n  /**\n   * Initialize crash analytics\n   */\n  init(): void {\n    if (this.initialized || typeof window === 'undefined') return;\n\n    this.initialized = true;\n\n    if (this.config.autoCaptureClicks) {\n      this.setupClickCapture();\n    }\n\n    if (this.config.autoCaptureNavigation) {\n      this.setupNavigationCapture();\n    }\n\n    if (this.config.autoCaptureConsole) {\n      this.setupConsoleCapture();\n    }\n\n    if (this.config.autoCaptureNetwork) {\n      this.setupNetworkCapture();\n    }\n\n    // Capture performance metrics after page load\n    this.capturePerformanceMetrics();\n\n    // Record initial breadcrumb\n    this.addBreadcrumb({\n      type: 'navigation',\n      category: 'session',\n      message: 'Session started',\n      level: 'info',\n      data: {\n        url: window.location.href,\n        referrer: document.referrer,\n      },\n    });\n  }\n\n  /**\n   * Add a breadcrumb\n   */\n  addBreadcrumb(crumb: Omit<Breadcrumb, 'timestamp'>): void {\n    const breadcrumb: Breadcrumb = {\n      ...crumb,\n      timestamp: Date.now(),\n    };\n\n    this.breadcrumbs.push(breadcrumb);\n\n    // Trim to max size\n    if (this.breadcrumbs.length > this.config.maxBreadcrumbs) {\n      this.breadcrumbs = this.breadcrumbs.slice(-this.config.maxBreadcrumbs);\n    }\n  }\n\n  /**\n   * Add a user action\n   */\n  addUserAction(action: Omit<UserAction, 'timestamp'>): void {\n    if (!this.isRecording) return;\n\n    const userAction: UserAction = {\n      ...action,\n      timestamp: Date.now(),\n    };\n\n    // Mask sensitive input values\n    if (this.config.maskInputs && (action.value !== undefined) && (action.value !== null) && (action.value !== '')) {\n      userAction.value = '***';\n    }\n\n    this.userActions.push(userAction);\n\n    // Trim to max size\n    if (this.userActions.length > this.config.maxUserActions) {\n      this.userActions = this.userActions.slice(-this.config.maxUserActions);\n    }\n  }\n\n  /**\n   * Record an error\n   */\n  recordError(error: AppError): void {\n    this.errors.push(error);\n\n    this.addBreadcrumb({\n      type: 'error',\n      category: error.category,\n      message: error.message,\n      level: 'error',\n      data: {\n        id: error.id,\n        severity: error.severity,\n      },\n    });\n  }\n\n  /**\n   * Get session data for crash report\n   */\n  getSessionData(): SessionData {\n    return {\n      sessionId: this.sessionId,\n      userId: this.config.getUserId?.(),\n      startTime: this.startTime,\n      breadcrumbs: [...this.breadcrumbs],\n      userActions: [...this.userActions],\n      performanceMetrics: this.getPerformanceMetrics(),\n      deviceInfo: this.getDeviceInfo(),\n      errors: [...this.errors],\n    };\n  }\n\n  /**\n   * Get breadcrumbs\n   */\n  getBreadcrumbs(): Breadcrumb[] {\n    return [...this.breadcrumbs];\n  }\n\n  /**\n   * Get recent breadcrumbs (last N)\n   */\n  getRecentBreadcrumbs(count: number = 20): Breadcrumb[] {\n    return this.breadcrumbs.slice(-count);\n  }\n\n  /**\n   * Clear all data\n   */\n  clear(): void {\n    this.breadcrumbs = [];\n    this.userActions = [];\n    this.errors = [];\n  }\n\n  /**\n   * Start new session\n   */\n  startNewSession(): void {\n    this.clear();\n    this.sessionId = this.generateSessionId();\n    this.startTime = Date.now();\n    this.isRecording = Math.random() < this.config.sessionSampleRate;\n  }\n\n  /**\n   * Dispose and cleanup\n   */\n  dispose(): void {\n    this.cleanupFns.forEach((fn) => fn());\n    this.cleanupFns = [];\n    this.initialized = false;\n  }\n\n  /**\n   * Check if initialized\n   */\n  isInitialized(): boolean {\n    return this.initialized;\n  }\n\n  /**\n   * Get session ID\n   */\n  getSessionId(): string {\n    return this.sessionId;\n  }\n\n  /**\n   * Generate unique session ID\n   */\n  private generateSessionId(): string {\n    return `session_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n  }\n\n  /**\n   * Setup click capture\n   */\n  private setupClickCapture(): void {\n    const handler = (event: MouseEvent): void => {\n      const target = event.target as HTMLElement;\n      if (target === null || target === undefined) return;\n\n      const selector = this.getElementSelector(target);\n      const text = this.getElementText(target);\n\n      this.addUserAction({\n        type: 'click',\n        target: selector,\n        metadata: {\n          text: text.substring(0, 100),\n          tagName: target.tagName,\n          className: target.className,\n        },\n      });\n\n      this.addBreadcrumb({\n        type: 'ui',\n        category: 'click',\n        message: `Clicked ${target.tagName.toLowerCase()}`,\n        level: 'info',\n        data: { selector, text: text.substring(0, 50) },\n      });\n    };\n\n    document.addEventListener('click', handler, { capture: true, passive: true });\n    this.cleanupFns.push(() =>\n      document.removeEventListener('click', handler, { capture: true })\n    );\n  }\n\n  /**\n   * Setup navigation capture\n   */\n  private setupNavigationCapture(): void {\n    // History API\n    const originalPushState = history.pushState.bind(history);\n    const originalReplaceState = history.replaceState.bind(history);\n\n    history.pushState = (...args: Parameters<typeof history.pushState>) => {\n      this.addBreadcrumb({\n        type: 'navigation',\n        category: 'navigation',\n        message: `Navigated to ${String(args[2])}`,\n        level: 'info',\n        data: { to: args[2], from: window.location.href },\n      });\n      return originalPushState(...args);\n    };\n\n    history.replaceState = (...args: Parameters<typeof history.replaceState>) => {\n      this.addBreadcrumb({\n        type: 'navigation',\n        category: 'navigation',\n        message: `Replaced state: ${String(args[2])}`,\n        level: 'info',\n      });\n      return originalReplaceState(...args);\n    };\n\n    // Popstate\n    const popstateHandler = (): void => {\n      this.addBreadcrumb({\n        type: 'navigation',\n        category: 'navigation',\n        message: `Navigated back/forward to ${window.location.href}`,\n        level: 'info',\n      });\n    };\n\n    window.addEventListener('popstate', popstateHandler);\n    this.cleanupFns.push(() => {\n      history.pushState = originalPushState;\n      history.replaceState = originalReplaceState;\n      window.removeEventListener('popstate', popstateHandler);\n    });\n  }\n\n  /**\n   * Setup console capture\n   */\n  private setupConsoleCapture(): void {\n    const levels = ['log', 'warn', 'error'] as const;\n    const originals = {} as Record<(typeof levels)[number], (...args: unknown[]) => void>;\n\n    levels.forEach((level) => {\n      // eslint-disable-next-line no-console -- intentionally capturing console\n      originals[level] = console[level].bind(console);\n      // eslint-disable-next-line no-console -- intentionally capturing console\n      console[level] = (...args: unknown[]): void => {\n        let breadcrumbLevel: 'error' | 'warning' | 'debug';\n        if (level === 'error') {\n          breadcrumbLevel = 'error';\n        } else if (level === 'warn') {\n          breadcrumbLevel = 'warning';\n        } else {\n          breadcrumbLevel = 'debug';\n        }\n\n        this.addBreadcrumb({\n          type: 'console',\n          category: `console.${level}`,\n          message: args.map((arg) => this.stringify(arg)).join(' ').substring(0, 500),\n          level: breadcrumbLevel,\n        });\n        originals[level](...args);\n      };\n    });\n\n    this.cleanupFns.push(() => {\n      levels.forEach((level) => {\n        // eslint-disable-next-line no-console -- intentionally restoring console\n        console[level] = originals[level];\n      });\n    });\n  }\n\n  /**\n   * Setup network capture\n   */\n  private setupNetworkCapture(): void {\n    const originalFetch = window.fetch.bind(window);\n\n    window.fetch = async (\n      input: RequestInfo | URL,\n      init?: RequestInit\n    ): Promise<Response> => {\n      let url: string;\n      if (typeof input === 'string') {\n        url = input;\n      } else if (input instanceof URL) {\n        url = input.href;\n      } else {\n        const { url: requestUrl } = input;\n        url = requestUrl;\n      }\n      const method = init?.method ?? 'GET';\n      const startTime = performance.now();\n\n      this.addBreadcrumb({\n        type: 'http',\n        category: 'fetch',\n        message: `${method} ${url}`,\n        level: 'info',\n        data: { url, method },\n      });\n\n      try {\n        const response = await originalFetch(input, init);\n        const duration = performance.now() - startTime;\n\n        this.addBreadcrumb({\n          type: 'http',\n          category: 'fetch',\n          message: `${method} ${url} - ${response.status}`,\n          level: response.ok ? 'info' : 'warning',\n          data: { url, method, status: response.status, duration: Math.round(duration) },\n        });\n\n        return response;\n      } catch (error) {\n        const duration = performance.now() - startTime;\n\n        this.addBreadcrumb({\n          type: 'http',\n          category: 'fetch',\n          message: `${method} ${url} - Failed`,\n          level: 'error',\n          data: {\n            url,\n            method,\n            error: error instanceof Error ? error.message : String(error),\n            duration: Math.round(duration),\n          },\n        });\n\n        throw error;\n      }\n    };\n\n    this.cleanupFns.push(() => {\n      window.fetch = originalFetch;\n    });\n  }\n\n  /**\n   * Capture performance metrics\n   */\n  private capturePerformanceMetrics(): void {\n    if ((typeof window === 'undefined') || (window.performance === undefined)) return;\n\n    // Wait for page load\n    const captureMetrics = (): void => {\n      setTimeout(() => {\n        const navigation = performance.getEntriesByType(\n          'navigation'\n        )[0] as PerformanceNavigationTiming;\n        const paint = performance.getEntriesByType('paint');\n\n        const metrics: Partial<PerformanceMetrics> = {};\n\n        if (navigation !== undefined) {\n          metrics.pageLoadTime = navigation.loadEventEnd - navigation.startTime;\n          metrics.domContentLoaded = navigation.domContentLoadedEventEnd - navigation.startTime;\n        }\n\n        paint.forEach((entry) => {\n          if (entry.name === 'first-contentful-paint') {\n            metrics.firstContentfulPaint = entry.startTime;\n          }\n        });\n\n        // Memory (Chrome only)\n        const performanceWithMemory = performance as Performance & {\n          memory?: { usedJSHeapSize: number };\n        };\n        if (performanceWithMemory.memory) {\n          metrics.jsHeapSize = performanceWithMemory.memory.usedJSHeapSize;\n        }\n\n        this.addBreadcrumb({\n          type: 'custom',\n          category: 'performance',\n          message: 'Performance metrics captured',\n          level: 'info',\n          data: metrics,\n        });\n      }, 1000);\n    };\n\n    if (document.readyState === 'complete') {\n      captureMetrics();\n    } else {\n      window.addEventListener('load', captureMetrics, { once: true });\n    }\n  }\n\n  /**\n   * Get current performance metrics\n   */\n  private getPerformanceMetrics(): PerformanceMetrics {\n    const metrics: PerformanceMetrics = {};\n\n    if ((typeof window === 'undefined') || (window.performance === undefined)) {\n      return metrics;\n    }\n\n    const navigation = performance.getEntriesByType(\n      'navigation'\n    )[0] as PerformanceNavigationTiming;\n    if (navigation !== undefined) {\n      metrics.pageLoadTime = navigation.loadEventEnd - navigation.startTime;\n      metrics.domContentLoaded = navigation.domContentLoadedEventEnd - navigation.startTime;\n    }\n\n    // Memory (Chrome only)\n    const performanceWithMemory = performance as Performance & {\n      memory?: { usedJSHeapSize: number };\n    };\n    if (performanceWithMemory.memory) {\n      metrics.jsHeapSize = performanceWithMemory.memory.usedJSHeapSize;\n    }\n\n    return metrics;\n  }\n\n  /**\n   * Get device info\n   */\n  private getDeviceInfo(): DeviceInfo {\n    if (typeof window === 'undefined' || typeof navigator === 'undefined') {\n      return {\n        userAgent: 'unknown',\n        platform: 'unknown',\n        language: 'unknown',\n        screenResolution: 'unknown',\n        viewportSize: 'unknown',\n        devicePixelRatio: 1,\n        colorDepth: 24,\n        timezone: 'unknown',\n        cookiesEnabled: false,\n        doNotTrack: true,\n      };\n    }\n\n    return {\n      userAgent: navigator.userAgent,\n      platform: navigator.platform,\n      language: navigator.language,\n      screenResolution: `${screen.width}x${screen.height}`,\n      viewportSize: `${window.innerWidth}x${window.innerHeight}`,\n      devicePixelRatio: window.devicePixelRatio,\n      colorDepth: screen.colorDepth,\n      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n      cookiesEnabled: navigator.cookieEnabled,\n      doNotTrack: navigator.doNotTrack === '1',\n    };\n  }\n\n  /**\n   * Get CSS selector for element\n   */\n  private getElementSelector(element: HTMLElement): string {\n    const parts: string[] = [];\n    let current: HTMLElement | null = element;\n\n    while (current && parts.length < 5) {\n      let selector = current.tagName.toLowerCase();\n\n      if (current.id) {\n        selector += `#${current.id}`;\n        parts.unshift(selector);\n        break;\n      }\n\n      if (current.className) {\n        const classes = current.className.split(' ').filter(Boolean).slice(0, 2);\n        if (classes.length) {\n          selector += `.${classes.join('.')}`;\n        }\n      }\n\n      parts.unshift(selector);\n      current = current.parentElement;\n    }\n\n    return parts.join(' > ');\n  }\n\n  /**\n   * Get element text content\n   */\n  private getElementText(element: HTMLElement): string {\n    if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n      return this.config.maskInputs ? '[MASKED]' : (element as HTMLInputElement).value;\n    }\n    return element.textContent?.trim() ?? '';\n  }\n\n  /**\n   * Stringify value safely\n   */\n  private stringify(value: unknown): string {\n    if (typeof value === 'string') return value;\n    if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n    if (value === null) return 'null';\n    if (value === undefined) return 'undefined';\n    if (value instanceof Error) return value.message;\n    try {\n      return JSON.stringify(value);\n    } catch {\n      return '[Object]';\n    }\n  }\n}\n\n/**\n * Global crash analytics instance\n */\nexport const crashAnalytics = new CrashAnalyticsManager();\n"],"names":["DEFAULT_CONFIG","CrashAnalyticsManager","config","crumb","breadcrumb","action","userAction","error","count","fn","handler","event","target","selector","text","originalPushState","originalReplaceState","args","popstateHandler","levels","originals","level","breadcrumbLevel","arg","originalFetch","input","init","url","requestUrl","method","startTime","response","duration","captureMetrics","navigation","paint","metrics","entry","performanceWithMemory","element","parts","current","classes","value","crashAnalytics"],"mappings":"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"}