{"version":3,"file":"useHydration.mjs","sources":["../../../../src/lib/hydration/hooks/useHydration.ts"],"sourcesContent":["/**\n * @file useHydration Hook\n * @description Primary hook for accessing the hydration context and system controls.\n *\n * This hook provides access to the core hydration system functionality including:\n * - Global hydration controls (pause, resume, force hydrate)\n * - Configuration access\n * - Metrics retrieval\n * - System state information\n *\n * @module hydration/hooks/useHydration\n *\n * @example\n * ```tsx\n * function HydrationControls() {\n *   const {\n *     isPaused,\n *     pause,\n *     resume,\n *     forceHydrateAll,\n *     getMetrics,\n *   } = useHydration();\n *\n *   const metrics = getMetrics();\n *\n *   return (\n *     <div>\n *       <p>Hydrated: {metrics.hydratedCount}/{metrics.totalBoundaries}</p>\n *       <button onClick={isPaused ? resume : pause}>\n *         {isPaused ? 'Resume' : 'Pause'}\n *       </button>\n *       <button onClick={forceHydrateAll}>\n *         Hydrate All\n *       </button>\n *     </div>\n *   );\n * }\n * ```\n */\n\nimport { useCallback, useMemo } from 'react';\n\nimport { useOptionalHydrationContext } from '../HydrationProvider';\n\nimport type {\n  HydrationContextValue,\n  HydrationSchedulerConfig,\n  HydrationMetricsSnapshot,\n  HydrationBoundaryId,\n  HydrationPriority,\n  HydrationStatus,\n} from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Return type for the useHydration hook.\n */\nexport interface UseHydrationReturn {\n  /**\n   * Whether the hydration system is initialized.\n   */\n  readonly isInitialized: boolean;\n\n  /**\n   * Whether the hydration scheduler is currently paused.\n   */\n  readonly isPaused: boolean;\n\n  /**\n   * Pauses the hydration scheduler.\n   * Pending tasks remain in queue but processing stops.\n   */\n  readonly pause: () => void;\n\n  /**\n   * Resumes a paused hydration scheduler.\n   */\n  readonly resume: () => void;\n\n  /**\n   * Forces immediate hydration of a specific boundary.\n   *\n   * @param boundaryId - ID of the boundary to hydrate\n   */\n  readonly forceHydrate: (boundaryId: HydrationBoundaryId) => Promise<void>;\n\n  /**\n   * Forces hydration of all pending boundaries.\n   */\n  readonly forceHydrateAll: () => Promise<void>;\n\n  /**\n   * Gets the current status of a hydration boundary.\n   *\n   * @param boundaryId - ID of the boundary to check\n   * @returns The hydration status, or undefined if not found\n   */\n  readonly getStatus: (boundaryId: HydrationBoundaryId) => HydrationStatus | undefined;\n\n  /**\n   * Updates the priority of a hydration boundary.\n   *\n   * @param boundaryId - ID of the boundary to update\n   * @param priority - New priority level\n   */\n  readonly updatePriority: (boundaryId: HydrationBoundaryId, priority: HydrationPriority) => void;\n\n  /**\n   * Gets the current hydration metrics snapshot.\n   *\n   * @returns Aggregated hydration metrics\n   */\n  readonly getMetrics: () => HydrationMetricsSnapshot;\n\n  /**\n   * Gets the current hydration configuration.\n   */\n  readonly config: HydrationSchedulerConfig;\n}\n\n/**\n * Options for the useHydration hook.\n */\nexport interface UseHydrationOptions {\n  /**\n   * Whether to throw an error if used outside HydrationProvider.\n   * If false, returns null-safe defaults when no provider is present.\n   *\n   * @default true\n   */\n  readonly throwIfNoProvider?: boolean;\n}\n\n// ============================================================================\n// Default Values\n// ============================================================================\n\n/**\n * Default metrics snapshot for when no provider is available.\n */\nconst DEFAULT_METRICS: HydrationMetricsSnapshot = {\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 * Default config for when no provider is available.\n */\nconst DEFAULT_CONFIG: HydrationSchedulerConfig = {\n  budget: {\n    frameTimeLimit: 50,\n    maxTasksPerFrame: 10,\n    minIdleTime: 100,\n    yieldToMain: true,\n  },\n  visibility: {\n    root: null,\n    rootMargin: '100px 0px',\n    threshold: 0,\n    triggerOnce: true,\n  },\n  debug: false,\n  interactionStrategy: 'replay',\n  useIdleCallback: true,\n  maxQueueSize: 1000,\n  taskTimeout: 10000,\n  collectMetrics: true,\n  metricsSampleRate: 1.0,\n};\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\n/**\n * Primary hook for accessing the hydration system.\n *\n * Provides access to global hydration controls, metrics, and configuration.\n * Must be used within a HydrationProvider unless `throwIfNoProvider` is false.\n *\n * @param options - Hook options\n * @returns Hydration system interface\n * @throws If used outside HydrationProvider and throwIfNoProvider is true\n *\n * @example\n * ```tsx\n * // Basic usage\n * function MyComponent() {\n *   const { getMetrics, isPaused, pause, resume } = useHydration();\n *\n *   const metrics = getMetrics();\n *   console.log(`${metrics.hydratedCount} of ${metrics.totalBoundaries} hydrated`);\n *\n *   return (\n *     <button onClick={isPaused ? resume : pause}>\n *       {isPaused ? 'Resume' : 'Pause'} Hydration\n *     </button>\n *   );\n * }\n *\n * // Safe usage outside provider\n * function SafeComponent() {\n *   const hydration = useHydration({ throwIfNoProvider: false });\n *\n *   // hydration will have null-safe defaults if no provider\n *   return <div>Hydrated: {hydration.getMetrics().hydratedCount}</div>;\n * }\n * ```\n */\nexport function useHydration(options: UseHydrationOptions = {}): UseHydrationReturn {\n  const { throwIfNoProvider = true } = options;\n\n  // IMPORTANT: Always call hooks unconditionally to comply with Rules of Hooks.\n  // React hooks must be called in the same order on every render.\n  const optionalContext = useOptionalHydrationContext();\n\n  // If throwIfNoProvider is true and no context exists, throw an error after hooks are called\n  if (throwIfNoProvider && optionalContext === null) {\n    throw new Error(\n      'useHydration must be used within a HydrationProvider. ' +\n        'Wrap your app with <HydrationProvider> to use hydration features.'\n    );\n  }\n\n  // Use the optional context result (which may be null if no provider)\n  const context = optionalContext;\n\n  // ==========================================================================\n  // Memoized Callbacks\n  // ==========================================================================\n\n  const pause = useCallback(() => {\n    context?.pause();\n  }, [context]);\n\n  const resume = useCallback(() => {\n    context?.resume();\n  }, [context]);\n\n  const forceHydrate = useCallback(\n    async (boundaryId: HydrationBoundaryId): Promise<void> => {\n      await context?.forceHydrate(boundaryId);\n    },\n    [context]\n  );\n\n  const forceHydrateAll = useCallback(async (): Promise<void> => {\n    await context?.forceHydrateAll();\n  }, [context]);\n\n  const getStatus = useCallback(\n    (boundaryId: HydrationBoundaryId): HydrationStatus | undefined => {\n      return context?.getBoundaryStatus(boundaryId);\n    },\n    [context]\n  );\n\n  const updatePriority = useCallback(\n    (boundaryId: HydrationBoundaryId, priority: HydrationPriority): void => {\n      context?.updatePriority(boundaryId, priority);\n    },\n    [context]\n  );\n\n  const getMetrics = useCallback((): HydrationMetricsSnapshot => {\n    return context?.getMetrics() ?? DEFAULT_METRICS;\n  }, [context]);\n\n  // ==========================================================================\n  // Return Value\n  // ==========================================================================\n\n  return useMemo<UseHydrationReturn>(\n    () => ({\n      isInitialized: context?.isInitialized ?? false,\n      isPaused: context?.isPaused ?? false,\n      pause,\n      resume,\n      forceHydrate,\n      forceHydrateAll,\n      getStatus,\n      updatePriority,\n      getMetrics,\n      config: context?.config ?? DEFAULT_CONFIG,\n    }),\n    [\n      context?.isInitialized,\n      context?.isPaused,\n      context?.config,\n      pause,\n      resume,\n      forceHydrate,\n      forceHydrateAll,\n      getStatus,\n      updatePriority,\n      getMetrics,\n    ]\n  );\n}\n\n/**\n * Hook to check if hydration context is available.\n *\n * Useful for conditional rendering based on hydration support.\n *\n * @returns true if within a HydrationProvider\n *\n * @example\n * ```tsx\n * function ConditionalFeature() {\n *   const hasHydration = useHasHydrationContext();\n *\n *   if (!hasHydration) {\n *     return <FallbackComponent />;\n *   }\n *\n *   return <HydrationAwareComponent />;\n * }\n * ```\n */\nexport function useHasHydrationContext(): boolean {\n  const context = useOptionalHydrationContext();\n  return context !== null;\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport type { HydrationContextValue };\n"],"names":["DEFAULT_METRICS","DEFAULT_CONFIG","useHydration","options","throwIfNoProvider","optionalContext","useOptionalHydrationContext","context","pause","useCallback","resume","forceHydrate","boundaryId","forceHydrateAll","getStatus","updatePriority","priority","getMetrics","useMemo","useHasHydrationContext"],"mappings":";;AA+IA,MAAMA,IAA4C;AAAA,EAChD,iBAAiB;AAAA,EACjB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,aAAa;AAAA,EACb,0BAA0B;AAAA,EAC1B,sBAAsB;AAAA,EACtB,2BAA2B;AAAA,EAC3B,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,WAAW;AAAA,EACX,WAAW,KAAK,IAAA;AAClB,GAKMC,IAA2C;AAAA,EAC/C,QAAQ;AAAA,IACN,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,aAAa;AAAA,EAAA;AAAA,EAEf,YAAY;AAAA,IACV,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,aAAa;AAAA,EAAA;AAAA,EAEf,OAAO;AAAA,EACP,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,mBAAmB;AACrB;AAyCO,SAASC,EAAaC,IAA+B,IAAwB;AAClF,QAAM,EAAE,mBAAAC,IAAoB,GAAA,IAASD,GAI/BE,IAAkBC,EAAA;AAGxB,MAAIF,KAAqBC,MAAoB;AAC3C,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAMJ,QAAME,IAAUF,GAMVG,IAAQC,EAAY,MAAM;AAC9B,IAAAF,GAAS,MAAA;AAAA,EACX,GAAG,CAACA,CAAO,CAAC,GAENG,IAASD,EAAY,MAAM;AAC/B,IAAAF,GAAS,OAAA;AAAA,EACX,GAAG,CAACA,CAAO,CAAC,GAENI,IAAeF;AAAA,IACnB,OAAOG,MAAmD;AACxD,YAAML,GAAS,aAAaK,CAAU;AAAA,IACxC;AAAA,IACA,CAACL,CAAO;AAAA,EAAA,GAGJM,IAAkBJ,EAAY,YAA2B;AAC7D,UAAMF,GAAS,gBAAA;AAAA,EACjB,GAAG,CAACA,CAAO,CAAC,GAENO,IAAYL;AAAA,IAChB,CAACG,MACQL,GAAS,kBAAkBK,CAAU;AAAA,IAE9C,CAACL,CAAO;AAAA,EAAA,GAGJQ,IAAiBN;AAAA,IACrB,CAACG,GAAiCI,MAAsC;AACtE,MAAAT,GAAS,eAAeK,GAAYI,CAAQ;AAAA,IAC9C;AAAA,IACA,CAACT,CAAO;AAAA,EAAA,GAGJU,IAAaR,EAAY,MACtBF,GAAS,gBAAgBP,GAC/B,CAACO,CAAO,CAAC;AAMZ,SAAOW;AAAA,IACL,OAAO;AAAA,MACL,eAAeX,GAAS,iBAAiB;AAAA,MACzC,UAAUA,GAAS,YAAY;AAAA,MAC/B,OAAAC;AAAA,MACA,QAAAE;AAAA,MACA,cAAAC;AAAA,MACA,iBAAAE;AAAA,MACA,WAAAC;AAAA,MACA,gBAAAC;AAAA,MACA,YAAAE;AAAA,MACA,QAAQV,GAAS,UAAUN;AAAA,IAAA;AAAA,IAE7B;AAAA,MACEM,GAAS;AAAA,MACTA,GAAS;AAAA,MACTA,GAAS;AAAA,MACTC;AAAA,MACAE;AAAA,MACAC;AAAA,MACAE;AAAA,MACAC;AAAA,MACAC;AAAA,MACAE;AAAA,IAAA;AAAA,EACF;AAEJ;AAsBO,SAASE,IAAkC;AAEhD,SADgBb,EAAA,MACG;AACrB;"}