{"version":3,"file":"HydrationProvider.mjs","sources":["../../../src/lib/hydration/HydrationProvider.tsx"],"sourcesContent":["/**\n * @file Hydration Provider\n * @description Global context provider for the Auto-Prioritized Hydration System.\n *\n * The HydrationProvider:\n * - Manages the hydration scheduler lifecycle\n * - Provides hydration context to child components\n * - Integrates with performance monitoring\n * - Collects and reports hydration metrics\n *\n * @module hydration/HydrationProvider\n *\n * @example\n * ```tsx\n * import { HydrationProvider } from '@/lib/hydration';\n *\n * function App() {\n *   return (\n *     <HydrationProvider\n *       config={{ debug: true }}\n *       onMetric={(metric) => console.log('Hydration metric:', metric)}\n *     >\n *       <MainContent />\n *     </HydrationProvider>\n *   );\n * }\n * ```\n */\n\n/* eslint-disable react-refresh/only-export-components */\nimport React, {\n  createContext,\n  useContext,\n  useEffect,\n  useRef,\n  useState,\n  useCallback,\n  useMemo,\n} from 'react';\n\nimport {\n  type HydrationScheduler,\n  getHydrationScheduler,\n  type SchedulerState,\n} from './hydration-scheduler';\n\nimport type {\n  HydrationContextValue,\n  HydrationProviderProps,\n  HydrationSchedulerConfig,\n  HydrationTask,\n  HydrationStatus,\n  HydrationPriority,\n  HydrationBoundaryId,\n  HydrationMetricsSnapshot,\n  HydrationMetricsReporter,\n  HydrationEvent,\n  PartialHydrationConfig,\n} from './types';\n\nimport { mergeWithDefaults } from './types';\n\n// ============================================================================\n// Context\n// ============================================================================\n\n/**\n * Hydration context for accessing the hydration system.\n */\nconst HydrationContext = createContext<HydrationContextValue | null>(null);\n\n/**\n * Display name for React DevTools.\n */\nHydrationContext.displayName = 'HydrationContext';\n\n// ============================================================================\n// Internal Types\n// ============================================================================\n\ninterface HydrationProviderState {\n  isInitialized: boolean;\n  isPaused: boolean;\n  schedulerState: SchedulerState | null;\n}\n\n// ============================================================================\n// HydrationProvider Component\n// ============================================================================\n\n/**\n * Global provider for the Auto-Prioritized Hydration System.\n *\n * This component manages the hydration scheduler and provides context to all\n * HydrationBoundary components in the tree.\n *\n * @param props - Provider props\n * @returns The provider wrapping children\n *\n * @example\n * ```tsx\n * <HydrationProvider\n *   config={{\n *     debug: process.env.NODE_ENV === 'development',\n *     budget: { frameTimeLimit: 50 },\n *   }}\n *   autoStart={true}\n *   onMetric={(metric, snapshot) => {\n *     analytics.track('hydration_complete', metric);\n *   }}\n * >\n *   <App />\n * </HydrationProvider>\n * ```\n */\nexport function HydrationProvider({\n  children,\n  config: configOverrides,\n  onMetric,\n  autoStart = true,\n  integrateWithPerformance = true,\n}: HydrationProviderProps): React.JSX.Element {\n  // ==========================================================================\n  // Refs\n  // ==========================================================================\n\n  /**\n   * Scheduler instance reference.\n   * Using ref to avoid re-creating on every render.\n   */\n  const schedulerRef = useRef<HydrationScheduler | null>(null);\n\n  /**\n   * Metrics callback reference.\n   * Using ref to avoid stale closures in event handlers.\n   */\n  const onMetricRef = useRef<HydrationMetricsReporter | undefined>(onMetric);\n\n  // Update ref in effect to avoid ref access during render\n  useEffect(() => {\n    onMetricRef.current = onMetric;\n  }, [onMetric]);\n\n  /**\n   * Configuration merged with defaults.\n   */\n  const config = useMemo<HydrationSchedulerConfig>(\n    () => mergeWithDefaults(configOverrides as PartialHydrationConfig),\n    [configOverrides]\n  );\n\n  // ==========================================================================\n  // State\n  // ==========================================================================\n\n  const [state, setState] = useState<HydrationProviderState>({\n    isInitialized: false,\n    isPaused: false,\n    schedulerState: null,\n  });\n\n  // ==========================================================================\n  // Scheduler Initialization\n  // ==========================================================================\n\n  useEffect(() => {\n    // Create or get scheduler\n    schedulerRef.current ??= getHydrationScheduler(config);\n\n    const scheduler = schedulerRef.current;\n\n    // Setup event listeners\n    const unsubscribeComplete = scheduler.on('hydration:complete', (event) => {\n      // Update state\n      setState((prev) => ({\n        ...prev,\n        schedulerState: scheduler.getState(),\n      }));\n\n      // Report metric\n      if (onMetricRef.current) {\n        const payload = event.payload as { duration: number; replayedCount: number } | undefined;\n        if (event.boundaryId && payload) {\n          const status = scheduler.getStatus(event.boundaryId);\n          if (status) {\n            const metric = {\n              boundaryId: event.boundaryId,\n              priority: 'normal' as HydrationPriority, // Would need to track this\n              trigger: 'visible' as const,\n              queueDuration: 0,\n              hydrationDuration: payload.duration,\n              totalDuration: payload.duration,\n              success: true,\n              replayedInteractions: payload.replayedCount,\n              timestamp: event.timestamp,\n            };\n            onMetricRef.current(metric, scheduler.getMetrics());\n          }\n        }\n      }\n    });\n\n    const unsubscribeError = scheduler.on('hydration:error', (event) => {\n      setState((prev) => ({\n        ...prev,\n        schedulerState: scheduler.getState(),\n      }));\n\n      // Report error metric\n      if (onMetricRef.current && event.boundaryId) {\n        const payload = event.payload as { error: Error; duration: number } | undefined;\n        if (payload) {\n          const metric = {\n            boundaryId: event.boundaryId,\n            priority: 'normal' as HydrationPriority,\n            trigger: 'visible' as const,\n            queueDuration: 0,\n            hydrationDuration: payload.duration,\n            totalDuration: payload.duration,\n            success: false,\n            errorMessage: payload.error.message,\n            replayedInteractions: 0,\n            timestamp: event.timestamp,\n          };\n          onMetricRef.current(metric, scheduler.getMetrics());\n        }\n      }\n    });\n\n    const unsubscribePaused = scheduler.on('scheduler:paused', () => {\n      setState((prev) => ({\n        ...prev,\n        isPaused: true,\n        schedulerState: scheduler.getState(),\n      }));\n    });\n\n    const unsubscribeResumed = scheduler.on('scheduler:resumed', () => {\n      setState((prev) => ({\n        ...prev,\n        isPaused: false,\n        schedulerState: scheduler.getState(),\n      }));\n    });\n\n    // Mark as initialized\n    setState({\n      isInitialized: true,\n      isPaused: false,\n      schedulerState: scheduler.getState(),\n    });\n\n    // Auto-start if configured\n    if (autoStart) {\n      scheduler.start();\n    }\n\n    // Performance monitoring integration\n    let vitalsUnsubscribe: (() => void) | undefined;\n\n    if (integrateWithPerformance && typeof window !== 'undefined') {\n      // Report hydration metrics as custom performance entries\n      const reportToPerformance = (event: HydrationEvent): void => {\n        if ('performance' in window && 'mark' in performance) {\n          const name = `hydration:${event.boundaryId ?? 'unknown'}`;\n\n          if (event.type === 'hydration:start') {\n            performance.mark(`${name}:start`);\n          } else if (event.type === 'hydration:complete') {\n            performance.mark(`${name}:end`);\n            try {\n              performance.measure(name, `${name}:start`, `${name}:end`);\n            } catch {\n              // Marks might not exist, ignore\n            }\n          }\n        }\n      };\n\n      const unsubStart = scheduler.on('hydration:start', reportToPerformance);\n      const unsubComplete = scheduler.on('hydration:complete', reportToPerformance);\n\n      vitalsUnsubscribe = () => {\n        unsubStart();\n        unsubComplete();\n      };\n    }\n\n    // Cleanup\n    return () => {\n      unsubscribeComplete();\n      unsubscribeError();\n      unsubscribePaused();\n      unsubscribeResumed();\n      vitalsUnsubscribe?.();\n    };\n  }, [autoStart, integrateWithPerformance, config]);\n\n  // ==========================================================================\n  // Context Methods\n  // ==========================================================================\n\n  const registerBoundary = useCallback((task: HydrationTask): void => {\n    schedulerRef.current?.register(task);\n  }, []);\n\n  const unregisterBoundary = useCallback((id: HydrationBoundaryId): void => {\n    schedulerRef.current?.unregister(id);\n  }, []);\n\n  const getBoundaryStatus = useCallback((id: HydrationBoundaryId): HydrationStatus | undefined => {\n    return schedulerRef.current?.getStatus(id);\n  }, []);\n\n  const updatePriority = useCallback(\n    (id: HydrationBoundaryId, priority: HydrationPriority): void => {\n      schedulerRef.current?.updatePriority(id, priority);\n    },\n    []\n  );\n\n  const forceHydrate = useCallback(async (id: HydrationBoundaryId): Promise<void> => {\n    await schedulerRef.current?.forceHydrate(id);\n  }, []);\n\n  const forceHydrateAll = useCallback(async (): Promise<void> => {\n    await schedulerRef.current?.forceHydrateAll();\n  }, []);\n\n  const pause = useCallback((): void => {\n    schedulerRef.current?.pause();\n  }, []);\n\n  const resume = useCallback((): void => {\n    schedulerRef.current?.resume();\n  }, []);\n\n  const getMetrics = useCallback((): HydrationMetricsSnapshot => {\n    return (\n      schedulerRef.current?.getMetrics() ?? {\n        totalBoundaries: 0,\n        hydratedCount: 0,\n        pendingCount: 0,\n        failedCount: 0,\n        averageHydrationDuration: 0,\n        p95HydrationDuration: 0,\n        totalReplayedInteractions: 0,\n        timeToFullHydration: null,\n        timeToAboveFoldHydration: null,\n        queueSize: 0,\n        timestamp: Date.now(),\n      }\n    );\n  }, []);\n\n  // ==========================================================================\n  // Context Value\n  // ==========================================================================\n\n  const contextValue = useMemo<HydrationContextValue>(\n    () => ({\n      registerBoundary,\n      unregisterBoundary,\n      getBoundaryStatus,\n      updatePriority,\n      forceHydrate,\n      forceHydrateAll,\n      pause,\n      resume,\n      isPaused: state.isPaused,\n      getMetrics,\n      config,\n      isInitialized: state.isInitialized,\n    }),\n    [\n      registerBoundary,\n      unregisterBoundary,\n      getBoundaryStatus,\n      updatePriority,\n      forceHydrate,\n      forceHydrateAll,\n      pause,\n      resume,\n      state.isPaused,\n      state.isInitialized,\n      getMetrics,\n      config,\n    ]\n  );\n\n  // ==========================================================================\n  // Render\n  // ==========================================================================\n\n  return <HydrationContext.Provider value={contextValue}>{children}</HydrationContext.Provider>;\n}\n\n// ============================================================================\n// Hook for Accessing Context\n// ============================================================================\n\n/**\n * Hook to access the hydration context.\n *\n * @returns The hydration context value\n * @throws If used outside of HydrationProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const { forceHydrate, getMetrics } = useHydrationContext();\n *\n *   const handleClick = () => {\n *     forceHydrate('my-boundary');\n *   };\n *\n *   return <button onClick={handleClick}>Hydrate Now</button>;\n * }\n * ```\n */\nexport function useHydrationContext(): HydrationContextValue {\n  const context = useContext(HydrationContext);\n\n  if (!context) {\n    throw new Error(\n      'useHydrationContext must be used within a HydrationProvider. ' +\n        'Wrap your app with <HydrationProvider> to use hydration features.'\n    );\n  }\n\n  return context;\n}\n\n/**\n * Hook to optionally access the hydration context.\n * Returns null if not within a HydrationProvider.\n *\n * @returns The hydration context value, or null\n *\n * @example\n * ```tsx\n * function OptionalHydrationComponent() {\n *   const hydration = useOptionalHydrationContext();\n *\n *   if (!hydration) {\n *     // Render without hydration features\n *     return <div>No hydration</div>;\n *   }\n *\n *   return <div>Hydration enabled</div>;\n * }\n * ```\n */\nexport function useOptionalHydrationContext(): HydrationContextValue | null {\n  return useContext(HydrationContext);\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { HydrationContext };\nexport type { HydrationContextValue, HydrationProviderProps };\n"],"names":["HydrationContext","createContext","HydrationProvider","children","configOverrides","onMetric","autoStart","integrateWithPerformance","schedulerRef","useRef","onMetricRef","useEffect","config","useMemo","mergeWithDefaults","state","setState","useState","getHydrationScheduler","scheduler","unsubscribeComplete","event","prev","payload","metric","unsubscribeError","unsubscribePaused","unsubscribeResumed","vitalsUnsubscribe","reportToPerformance","name","unsubStart","unsubComplete","registerBoundary","useCallback","task","unregisterBoundary","id","getBoundaryStatus","updatePriority","priority","forceHydrate","forceHydrateAll","pause","resume","getMetrics","contextValue","useHydrationContext","context","useContext","useOptionalHydrationContext"],"mappings":"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"}