{"version":3,"file":"memory-guardian.mjs","sources":["../../../src/lib/performance/memory-guardian.ts"],"sourcesContent":["/**\n * @file Memory Guardian System\n * @description PhD-level proactive memory management with automatic leak prevention,\n * cleanup orchestration, and memory pressure handling for React applications.\n *\n * Features:\n * - Real-time memory pressure monitoring\n * - Automatic cleanup orchestration\n * - Component memory budget tracking\n * - Leak detection and prevention\n * - GC hint coordination\n * - Subscription and listener tracking\n * - WeakRef-based cache management\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Memory pressure levels\n */\nexport type MemoryPressureLevel = 'normal' | 'moderate' | 'critical';\n\n/**\n * Memory snapshot\n */\nexport interface MemorySnapshot {\n  /** Used JS heap size in bytes */\n  usedJSHeapSize: number;\n  /** Total JS heap size in bytes */\n  totalJSHeapSize: number;\n  /** Heap size limit in bytes */\n  jsHeapSizeLimit: number;\n  /** Usage percentage (0-100) */\n  usagePercent: number;\n  /** Current pressure level */\n  pressureLevel: MemoryPressureLevel;\n  /** Timestamp */\n  timestamp: number;\n}\n\n/**\n * Cleanup handler registration\n */\nexport interface CleanupHandler {\n  /** Unique identifier */\n  id: string;\n  /** Cleanup priority (higher runs first) */\n  priority: number;\n  /** The cleanup function */\n  cleanup: () => void | Promise<void>;\n  /** Component or context name */\n  context?: string;\n  /** Estimated memory freed */\n  estimatedBytes?: number;\n}\n\n/**\n * Memory budget for a component\n */\nexport interface ComponentMemoryBudget {\n  /** Component identifier */\n  componentId: string;\n  /** Maximum allowed memory in bytes */\n  maxBytes: number;\n  /** Current usage in bytes */\n  currentBytes: number;\n  /** Warning threshold (0-1) */\n  warningThreshold: number;\n  /** Cleanup callback when exceeded */\n  onExceed?: () => void;\n}\n\n/**\n * Subscription tracker entry\n */\nexport interface TrackedSubscription {\n  /** Unique ID */\n  id: string;\n  /** Subscription type */\n  type: 'event' | 'interval' | 'timeout' | 'observer' | 'websocket' | 'custom';\n  /** Context/component name */\n  context: string;\n  /** Unsubscribe function */\n  unsubscribe: () => void;\n  /** Creation timestamp */\n  createdAt: number;\n  /** Whether it's been cleaned up */\n  cleaned: boolean;\n}\n\n/**\n * Memory guardian configuration\n */\nexport interface MemoryGuardianConfig {\n  /** Enable automatic monitoring */\n  autoMonitor?: boolean;\n  /** Monitoring interval in ms */\n  monitorInterval?: number;\n  /** Moderate pressure threshold (0-1) */\n  moderateThreshold?: number;\n  /** Critical pressure threshold (0-1) */\n  criticalThreshold?: number;\n  /** Enable automatic cleanup on pressure */\n  autoCleanup?: boolean;\n  /** Enable debug logging */\n  debug?: boolean;\n  /** Maximum tracked subscriptions */\n  maxTrackedSubscriptions?: number;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_CONFIG: Required<MemoryGuardianConfig> = {\n  autoMonitor: true,\n  monitorInterval: 5000,\n  moderateThreshold: 0.7,\n  criticalThreshold: 0.9,\n  autoCleanup: true,\n  debug: false,\n  maxTrackedSubscriptions: 1000,\n};\n\n// ============================================================================\n// Memory Guardian Class\n// ============================================================================\n\n/**\n * Proactive memory management guardian\n */\nexport class MemoryGuardian {\n  private static instance: MemoryGuardian;\n  private config: Required<MemoryGuardianConfig>;\n  private cleanupHandlers: Map<string, CleanupHandler> = new Map();\n  private componentBudgets: Map<string, ComponentMemoryBudget> = new Map();\n  private subscriptions: Map<string, TrackedSubscription> = new Map();\n  private memoryHistory: MemorySnapshot[] = [];\n  private monitorIntervalId: ReturnType<typeof setInterval> | null = null;\n  private pressureCallbacks: Set<(level: MemoryPressureLevel) => void> = new Set();\n  private lastPressureLevel: MemoryPressureLevel = 'normal';\n  private subscriptionIdCounter = 0;\n  private cleanupIdCounter = 0;\n\n  constructor(config: MemoryGuardianConfig = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n\n    if (this.config.autoMonitor) {\n      this.startMonitoring();\n    }\n  }\n\n  /**\n   * Get singleton instance\n   */\n  static getInstance(config?: MemoryGuardianConfig): MemoryGuardian {\n    MemoryGuardian.instance ??= new MemoryGuardian(config);\n    return MemoryGuardian.instance;\n  }\n\n  /**\n   * Reset singleton (for testing)\n   */\n  static reset(): void {\n    if (MemoryGuardian.instance !== null && MemoryGuardian.instance !== undefined) {\n      MemoryGuardian.instance.stopMonitoring();\n      // Type-safe null assignment for singleton reset\n      (MemoryGuardian as unknown as { instance: MemoryGuardian | null }).instance = null;\n    }\n  }\n\n  // ============================================================================\n  // Memory Monitoring\n  // ============================================================================\n\n  /**\n   * Format bytes for display\n   */\n  static formatBytes(bytes: number): string {\n    if (bytes < 1024) return `${bytes} B`;\n    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n    if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n    return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n  }\n\n  /**\n   * Start memory monitoring\n   */\n  startMonitoring(): void {\n    if (this.monitorIntervalId) return;\n\n    this.monitorIntervalId = setInterval(() => {\n      this.checkMemory();\n    }, this.config.monitorInterval);\n\n    // Initial check\n    this.checkMemory();\n\n    this.log('Memory monitoring started');\n  }\n\n  /**\n   * Stop memory monitoring\n   */\n  stopMonitoring(): void {\n    if (this.monitorIntervalId) {\n      clearInterval(this.monitorIntervalId);\n      this.monitorIntervalId = null;\n    }\n  }\n\n  /**\n   * Check current memory status\n   */\n  checkMemory(): MemorySnapshot {\n    const snapshot = this.getMemorySnapshot();\n\n    // Store history (keep last 60 snapshots)\n    this.memoryHistory.push(snapshot);\n    if (this.memoryHistory.length > 60) {\n      this.memoryHistory.shift();\n    }\n\n    // Check pressure level changes\n    if (snapshot.pressureLevel !== this.lastPressureLevel) {\n      this.lastPressureLevel = snapshot.pressureLevel;\n      this.notifyPressureChange(snapshot.pressureLevel);\n\n      // Trigger auto cleanup on pressure\n      if (this.config.autoCleanup && snapshot.pressureLevel !== 'normal') {\n        void this.triggerCleanup(snapshot.pressureLevel);\n      }\n    }\n\n    // Check component budgets\n    this.checkComponentBudgets();\n\n    return snapshot;\n  }\n\n  /**\n   * Get current memory snapshot\n   */\n  getMemorySnapshot(): MemorySnapshot {\n    const timestamp = Date.now();\n\n    // Check if performance.memory is available\n    const perfWithMemory = performance as Performance & {\n      memory?: {\n        usedJSHeapSize: number;\n        totalJSHeapSize: number;\n        jsHeapSizeLimit: number;\n      };\n    };\n\n    if (!perfWithMemory.memory) {\n      return {\n        usedJSHeapSize: 0,\n        totalJSHeapSize: 0,\n        jsHeapSizeLimit: 0,\n        usagePercent: 0,\n        pressureLevel: 'normal',\n        timestamp,\n      };\n    }\n\n    const { usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit } = perfWithMemory.memory;\n    const usagePercent = (usedJSHeapSize / jsHeapSizeLimit) * 100;\n\n    let pressureLevel: MemoryPressureLevel = 'normal';\n    if (usagePercent >= this.config.criticalThreshold * 100) {\n      pressureLevel = 'critical';\n    } else if (usagePercent >= this.config.moderateThreshold * 100) {\n      pressureLevel = 'moderate';\n    }\n\n    return {\n      usedJSHeapSize,\n      totalJSHeapSize,\n      jsHeapSizeLimit,\n      usagePercent,\n      pressureLevel,\n      timestamp,\n    };\n  }\n\n  /**\n   * Subscribe to pressure changes\n   */\n  onPressureChange(callback: (level: MemoryPressureLevel) => void): () => void {\n    this.pressureCallbacks.add(callback);\n    return () => this.pressureCallbacks.delete(callback);\n  }\n\n  // ============================================================================\n  // Cleanup Management\n  // ============================================================================\n\n  /**\n   * Register a cleanup handler\n   */\n  registerCleanup(\n    cleanup: () => void | Promise<void>,\n    options: {\n      priority?: number;\n      context?: string;\n      estimatedBytes?: number;\n    } = {}\n  ): string {\n    const id = `cleanup-${++this.cleanupIdCounter}`;\n\n    const handler: CleanupHandler = {\n      id,\n      priority: options.priority ?? 0,\n      cleanup,\n      context: options.context,\n      estimatedBytes: options.estimatedBytes,\n    };\n\n    this.cleanupHandlers.set(id, handler);\n    this.log(`Registered cleanup handler: ${id}`, options.context);\n\n    return id;\n  }\n\n  /**\n   * Unregister a cleanup handler\n   */\n  unregisterCleanup(id: string): boolean {\n    return this.cleanupHandlers.delete(id);\n  }\n\n  /**\n   * Trigger cleanup based on pressure level\n   */\n  async triggerCleanup(pressureLevel: MemoryPressureLevel): Promise<number> {\n    const handlers = Array.from(this.cleanupHandlers.values());\n\n    // Sort by priority (higher first)\n    handlers.sort((a, b) => b.priority - a.priority);\n\n    let cleanedBytes = 0;\n    const handlersToRun = pressureLevel === 'critical'\n      ? handlers\n      : handlers.filter((h) => h.priority > 50);\n\n    this.log(`Running ${handlersToRun.length} cleanup handlers`);\n\n    for (const handler of handlersToRun) {\n      try {\n        await handler.cleanup();\n        cleanedBytes += handler.estimatedBytes ?? 0;\n      } catch (error) {\n        this.log(`Cleanup failed for ${handler.id}:`, error);\n      }\n    }\n\n    // Clean up stale subscriptions\n    this.cleanStaleSubscriptions();\n\n    // Hint GC\n    this.hintGC();\n\n    return cleanedBytes;\n  }\n\n  /**\n   * Set memory budget for a component\n   */\n  setComponentBudget(\n    componentId: string,\n    budget: Omit<ComponentMemoryBudget, 'componentId' | 'currentBytes'>\n  ): void {\n    this.componentBudgets.set(componentId, {\n      componentId,\n      currentBytes: 0,\n      ...budget,\n    });\n  }\n\n  // ============================================================================\n  // Component Memory Budgets\n  // ============================================================================\n\n  /**\n   * Update component memory usage\n   */\n  updateComponentMemory(componentId: string, bytes: number): void {\n    const budget = this.componentBudgets.get(componentId);\n    if (budget) {\n      budget.currentBytes = bytes;\n    }\n  }\n\n  /**\n   * Remove component budget\n   */\n  removeComponentBudget(componentId: string): void {\n    this.componentBudgets.delete(componentId);\n  }\n\n  /**\n   * Track a subscription for automatic cleanup\n   */\n  trackSubscription(\n    type: TrackedSubscription['type'],\n    context: string,\n    unsubscribe: () => void\n  ): string {\n    const id = `sub-${++this.subscriptionIdCounter}`;\n\n    // Enforce max tracked subscriptions\n    if (this.subscriptions.size >= this.config.maxTrackedSubscriptions) {\n      this.cleanStaleSubscriptions();\n    }\n\n    const subscription: TrackedSubscription = {\n      id,\n      type,\n      context,\n      unsubscribe,\n      createdAt: Date.now(),\n      cleaned: false,\n    };\n\n    this.subscriptions.set(id, subscription);\n    return id;\n  }\n\n  /**\n   * Untrack and cleanup a subscription\n   */\n  untrackSubscription(id: string): boolean {\n    const subscription = this.subscriptions.get(id);\n    if (subscription && !subscription.cleaned) {\n      try {\n        subscription.unsubscribe();\n        subscription.cleaned = true;\n      } catch (error) {\n        this.log(`Failed to unsubscribe ${id}:`, error);\n      }\n      this.subscriptions.delete(id);\n      return true;\n    }\n    return false;\n  }\n\n  // ============================================================================\n  // Subscription Tracking\n  // ============================================================================\n\n  /**\n   * Clean up subscriptions for a context\n   */\n  cleanupContext(context: string): number {\n    let cleaned = 0;\n    for (const [id, subscription] of this.subscriptions) {\n      if (subscription.context === context && !subscription.cleaned) {\n        this.untrackSubscription(id);\n        cleaned++;\n      }\n    }\n    return cleaned;\n  }\n\n  /**\n   * Get subscription statistics\n   */\n  getSubscriptionStats(): {\n    total: number;\n    byType: Record<string, number>;\n    byContext: Record<string, number>;\n  } {\n    const stats = {\n      total: this.subscriptions.size,\n      byType: {} as Record<string, number>,\n      byContext: {} as Record<string, number>,\n    };\n\n    for (const subscription of this.subscriptions.values()) {\n      stats.byType[subscription.type] = (stats.byType[subscription.type] ?? 0) + 1;\n      stats.byContext[subscription.context] = (stats.byContext[subscription.context] ?? 0) + 1;\n    }\n\n    return stats;\n  }\n\n  /**\n   * Detect potential memory leaks\n   */\n  detectLeaks(): {\n    potentialLeaks: boolean;\n    growthRate: number;\n    suggestions: string[];\n  } {\n    if (this.memoryHistory.length < 10) {\n      return { potentialLeaks: false, growthRate: 0, suggestions: [] };\n    }\n\n    const recentHistory = this.memoryHistory.slice(-10);\n    const firstUsage = recentHistory[0]?.usedJSHeapSize ?? 0;\n    const lastUsage = recentHistory[recentHistory.length - 1]?.usedJSHeapSize ?? 0;\n    const growthRate = (lastUsage - firstUsage) / firstUsage;\n\n    const potentialLeaks = growthRate > 0.1; // 10% growth indicates leak\n\n    const suggestions: string[] = [];\n    if (potentialLeaks) {\n      suggestions.push('Memory usage is growing rapidly');\n\n      const subStats = this.getSubscriptionStats();\n      if (subStats.total > 50) {\n        suggestions.push(`High subscription count (${subStats.total}) - check for cleanup`);\n      }\n\n      if (this.cleanupHandlers.size < 5) {\n        suggestions.push('Consider registering more cleanup handlers');\n      }\n    }\n\n    return { potentialLeaks, growthRate, suggestions };\n  }\n\n  /**\n   * Get memory trend\n   */\n  getMemoryTrend(): 'increasing' | 'stable' | 'decreasing' {\n    if (this.memoryHistory.length < 5) return 'stable';\n\n    const recent = this.memoryHistory.slice(-5);\n    const changes = recent.slice(1).map((s, i) => s.usedJSHeapSize - (recent[i]?.usedJSHeapSize ?? 0));\n    const avgChange = changes.reduce((a, b) => a + b, 0) / changes.length;\n\n    if (avgChange > 1024 * 1024) return 'increasing'; // Growing >1MB per check\n    if (avgChange < -1024 * 1024) return 'decreasing';\n    return 'stable';\n  }\n\n  /**\n   * Notify pressure change callbacks\n   */\n  private notifyPressureChange(level: MemoryPressureLevel): void {\n    this.log(`Memory pressure changed to: ${level}`);\n    this.pressureCallbacks.forEach((callback) => callback(level));\n  }\n\n  // ============================================================================\n  // Memory Leak Detection\n  // ============================================================================\n\n  /**\n   * Hint garbage collection (non-blocking)\n   */\n  private hintGC(): void {\n    // Use requestIdleCallback to hint GC during idle time\n    if (typeof requestIdleCallback !== 'undefined') {\n      requestIdleCallback(() => {\n        // Trigger minor GC by creating and releasing objects\n        const temp: unknown[] = [];\n        for (let i = 0; i < 1000; i++) {\n          temp.push({});\n        }\n        temp.length = 0;\n      });\n    }\n  }\n\n  // ============================================================================\n  // Utilities\n  // ============================================================================\n\n  /**\n   * Check all component budgets\n   */\n  private checkComponentBudgets(): void {\n    for (const budget of this.componentBudgets.values()) {\n      const usageRatio = budget.currentBytes / budget.maxBytes;\n\n      if (usageRatio >= 1) {\n        this.log(`Component ${budget.componentId} exceeded memory budget`);\n        budget.onExceed?.();\n      } else if (usageRatio >= budget.warningThreshold) {\n        this.log(`Component ${budget.componentId} approaching memory limit: ${(usageRatio * 100).toFixed(1)}%`);\n      }\n    }\n  }\n\n  /**\n   * Clean stale subscriptions (older than 5 minutes)\n   */\n  private cleanStaleSubscriptions(): number {\n    const staleThreshold = Date.now() - 5 * 60 * 1000;\n    let cleaned = 0;\n\n    for (const [id, subscription] of this.subscriptions) {\n      if (subscription.createdAt < staleThreshold || subscription.cleaned) {\n        this.subscriptions.delete(id);\n        cleaned++;\n      }\n    }\n\n    return cleaned;\n  }\n\n  /**\n   * Debug logging\n   */\n  private log(message: string, ...args: unknown[]): void {\n    if (this.config.debug) {\n      console.info(`[MemoryGuardian] ${message}`, ...args);\n    }\n  }\n}\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\n/**\n * Hook for component-level memory management\n */\nexport function useMemoryGuard(\n  componentId: string,\n  options: {\n    maxBytes?: number;\n    warningThreshold?: number;\n    onExceed?: () => void;\n  } = {}\n): {\n  updateUsage: (bytes: number) => void;\n  snapshot: MemorySnapshot | null;\n  pressureLevel: MemoryPressureLevel;\n} {\n  const { maxBytes = 10 * 1024 * 1024, warningThreshold = 0.8, onExceed } = options;\n  const guardian = useRef(MemoryGuardian.getInstance());\n  const [snapshot, setSnapshot] = useState<MemorySnapshot | null>(null);\n  const [pressureLevel, setPressureLevel] = useState<MemoryPressureLevel>('normal');\n\n  useEffect(() => {\n    const currentGuardian = guardian.current;\n    currentGuardian.setComponentBudget(componentId, {\n      maxBytes,\n      warningThreshold,\n      onExceed,\n    });\n\n    const unsubPressure = currentGuardian.onPressureChange(setPressureLevel);\n\n    // Get initial snapshot\n    setSnapshot(currentGuardian.getMemorySnapshot());\n\n    return () => {\n      currentGuardian.removeComponentBudget(componentId);\n      unsubPressure();\n    };\n  }, [componentId, maxBytes, warningThreshold, onExceed]);\n\n  const updateUsage = useCallback(\n    (bytes: number) => {\n      guardian.current.updateComponentMemory(componentId, bytes);\n    },\n    [componentId]\n  );\n\n  return { updateUsage, snapshot, pressureLevel };\n}\n\n/**\n * Hook for automatic subscription cleanup\n */\nexport function useTrackedSubscription(\n  context: string\n): {\n  track: (type: TrackedSubscription['type'], unsubscribe: () => void) => string;\n  untrack: (id: string) => void;\n  cleanupAll: () => void;\n} {\n  const guardian = useRef(MemoryGuardian.getInstance());\n  const trackedIds = useRef<Set<string>>(new Set());\n\n  const track = useCallback(\n    (type: TrackedSubscription['type'], unsubscribe: () => void) => {\n      const id = guardian.current.trackSubscription(type, context, unsubscribe);\n      trackedIds.current.add(id);\n      return id;\n    },\n    [context]\n  );\n\n  const untrack = useCallback((id: string) => {\n    guardian.current.untrackSubscription(id);\n    trackedIds.current.delete(id);\n  }, []);\n\n  const cleanupAll = useCallback(() => {\n    for (const id of trackedIds.current) {\n      guardian.current.untrackSubscription(id);\n    }\n    trackedIds.current.clear();\n  }, []);\n\n  // Cleanup on unmount\n  useEffect(() => {\n    return () => {\n      cleanupAll();\n    };\n  }, [cleanupAll]);\n\n  return { track, untrack, cleanupAll };\n}\n\n/**\n * Hook for registering cleanup handlers\n */\nexport function useCleanupHandler(\n  cleanup: () => void | Promise<void>,\n  options: {\n    priority?: number;\n    context?: string;\n    estimatedBytes?: number;\n  } = {}\n): void {\n  const guardian = useRef(MemoryGuardian.getInstance());\n  const cleanupIdRef = useRef<string | null>(null);\n\n  useEffect(() => {\n    const currentGuardian = guardian.current;\n    cleanupIdRef.current = currentGuardian.registerCleanup(cleanup, options);\n\n    return () => {\n      if (cleanupIdRef.current !== null && cleanupIdRef.current !== undefined) {\n        currentGuardian.unregisterCleanup(cleanupIdRef.current);\n      }\n    };\n  }, [cleanup, options]);\n}\n\n/**\n * Hook for memory pressure awareness\n * Performance optimized: memoizes expensive getMemoryTrend() and detectLeaks() calls\n */\nexport function useMemoryPressureAwareness(): {\n  pressureLevel: MemoryPressureLevel;\n  isUnderPressure: boolean;\n  snapshot: MemorySnapshot | null;\n  trend: 'increasing' | 'stable' | 'decreasing';\n  leakDetection: {\n    potentialLeaks: boolean;\n    growthRate: number;\n    suggestions: string[];\n  };\n} {\n  const guardian = useRef(MemoryGuardian.getInstance());\n  const [pressureLevel, setPressureLevel] = useState<MemoryPressureLevel>('normal');\n  const [snapshot, setSnapshot] = useState<MemorySnapshot | null>(null);\n\n  // Track snapshot version to trigger memoized value updates\n  const [snapshotVersion, setSnapshotVersion] = useState(0);\n\n  useEffect(() => {\n    const unsub = guardian.current.onPressureChange(setPressureLevel);\n\n    const intervalId = setInterval(() => {\n      setSnapshot(guardian.current.getMemorySnapshot());\n      // Increment version to invalidate memoized trend/leak detection\n      setSnapshotVersion((v) => v + 1);\n    }, 5000);\n\n    return () => {\n      unsub();\n      clearInterval(intervalId);\n    };\n  }, []);\n\n  // Memoize expensive getMemoryTrend() - only recalculate when snapshot updates\n  const trend = useCallback(() => {\n    return guardian.current.getMemoryTrend();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [snapshotVersion])();\n\n  // Memoize expensive detectLeaks() - only recalculate when snapshot updates\n  const leakDetection = useCallback(() => {\n    return guardian.current.detectLeaks();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [snapshotVersion])();\n\n  return {\n    pressureLevel,\n    isUnderPressure: pressureLevel !== 'normal',\n    snapshot,\n    trend,\n    leakDetection,\n  };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Get the global memory guardian instance\n */\nexport function getMemoryGuardian(config?: MemoryGuardianConfig): MemoryGuardian {\n  return MemoryGuardian.getInstance(config);\n}\n\n/**\n * Reset the global guardian (for testing)\n */\nexport function resetMemoryGuardian(): void {\n  MemoryGuardian.reset();\n}\n\n/**\n * Trigger cleanup manually\n */\nexport async function triggerMemoryCleanup(pressureLevel: MemoryPressureLevel = 'moderate'): Promise<number> {\n  return MemoryGuardian.getInstance().triggerCleanup(pressureLevel);\n}\n\n/**\n * Check current memory status\n */\nexport function checkMemory(): MemorySnapshot {\n  return MemoryGuardian.getInstance().checkMemory();\n}\n\n/**\n * Format bytes helper\n */\nexport const formatBytes: (bytes: number) => string = MemoryGuardian.formatBytes.bind(MemoryGuardian);\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n  MemoryGuardian,\n  getMemoryGuardian,\n  resetMemoryGuardian,\n  triggerMemoryCleanup,\n  checkMemory,\n  formatBytes,\n  useMemoryGuard,\n  useTrackedSubscription,\n  useCleanupHandler,\n  useMemoryPressureAwareness,\n};\n\n// ============================================================================\n// HMR Support\n// ============================================================================\n\n// Vite HMR disposal to prevent memory leaks during hot module replacement\nif (import.meta.hot) {\n  import.meta.hot.dispose(() => {\n    MemoryGuardian.reset();\n  });\n}\n"],"names":["DEFAULT_CONFIG","MemoryGuardian","config","bytes","snapshot","timestamp","perfWithMemory","usedJSHeapSize","totalJSHeapSize","jsHeapSizeLimit","usagePercent","pressureLevel","callback","cleanup","options","id","handler","handlers","a","b","cleanedBytes","handlersToRun","h","error","componentId","budget","type","context","unsubscribe","subscription","cleaned","stats","recentHistory","firstUsage","growthRate","potentialLeaks","suggestions","subStats","recent","changes","s","i","avgChange","level","usageRatio","staleThreshold","message","args","useMemoryGuard","maxBytes","warningThreshold","onExceed","guardian","useRef","setSnapshot","useState","setPressureLevel","useEffect","currentGuardian","unsubPressure","useCallback","useTrackedSubscription","trackedIds","track","untrack","cleanupAll","useCleanupHandler","cleanupIdRef","useMemoryPressureAwareness","snapshotVersion","setSnapshotVersion","unsub","intervalId","v","trend","leakDetection","getMemoryGuardian","resetMemoryGuardian","triggerMemoryCleanup","checkMemory"],"mappings":"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"}