{"version":3,"file":"useDeferredHydration.mjs","sources":["../../../../src/lib/hydration/hooks/useDeferredHydration.ts"],"sourcesContent":["/**\n * @file useDeferredHydration Hook\n * @description Hook for manual control over component hydration timing.\n *\n * This hook provides explicit control over when hydration occurs,\n * useful for components that need programmatic hydration triggers.\n *\n * @module hydration/hooks/useDeferredHydration\n *\n * @example\n * ```tsx\n * function ManualHydrationComponent() {\n *   const {\n *     isHydrated,\n *     hydrate,\n *     cancel,\n *     scheduleHydration,\n *   } = useDeferredHydration({\n *     id: 'manual-component',\n *     priority: 'low',\n *   });\n *\n *   // Hydrate after user clicks a button\n *   const handleClick = async () => {\n *     await hydrate();\n *     console.log('Component is now interactive!');\n *   };\n *\n *   // Or schedule for later\n *   useEffect(() => {\n *     scheduleHydration(5000); // Hydrate after 5 seconds\n *   }, [scheduleHydration]);\n *\n *   return (\n *     <div>\n *       <button onClick={handleClick}>Hydrate Now</button>\n *       {isHydrated ? <InteractiveContent /> : <Placeholder />}\n *     </div>\n *   );\n * }\n * ```\n */\n\nimport { useState, useEffect, useCallback, useRef, useMemo, useId } from 'react';\n\nimport { useOptionalHydrationContext } from '../HydrationProvider';\nimport { getHydrationScheduler } from '../hydration-scheduler';\n\nimport type {\n  HydrationPriority,\n  HydrationBoundaryId,\n  HydrationTask,\n  HydrationState,\n} from '../types';\n\nimport { createBoundaryId } from '../types';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration for deferred hydration.\n */\nexport interface DeferredHydrationConfig {\n  /**\n   * Unique identifier for this hydration boundary.\n   * Will be auto-generated if not provided.\n   */\n  readonly id?: string;\n\n  /**\n   * Priority level for when hydration is triggered.\n   *\n   * @default 'normal'\n   */\n  readonly priority?: HydrationPriority;\n\n  /**\n   * Function to execute during hydration.\n   * If not provided, hydration is a no-op state transition.\n   */\n  readonly onHydrate?: () => void | Promise<void>;\n\n  /**\n   * Callback when hydration completes.\n   */\n  readonly onComplete?: (duration: number) => void;\n\n  /**\n   * Callback when hydration fails.\n   */\n  readonly onError?: (error: Error) => void;\n\n  /**\n   * Maximum time to wait for hydration in milliseconds.\n   *\n   * @default 10000\n   */\n  readonly timeout?: number;\n\n  /**\n   * Whether to auto-register with the scheduler.\n   *\n   * @default false\n   */\n  readonly autoRegister?: boolean;\n}\n\n/**\n * Return type for the useDeferredHydration hook.\n */\nexport interface UseDeferredHydrationReturn {\n  /**\n   * Current hydration state.\n   */\n  readonly state: HydrationState;\n\n  /**\n   * Whether the component is fully hydrated.\n   */\n  readonly isHydrated: boolean;\n\n  /**\n   * Whether hydration is in progress.\n   */\n  readonly isHydrating: boolean;\n\n  /**\n   * Whether hydration is pending (not started).\n   */\n  readonly isPending: boolean;\n\n  /**\n   * Error that occurred during hydration, if any.\n   */\n  readonly error: Error | null;\n\n  /**\n   * Duration of hydration in milliseconds, if completed.\n   */\n  readonly duration: number | null;\n\n  /**\n   * The boundary ID for this deferred hydration.\n   */\n  readonly boundaryId: HydrationBoundaryId;\n\n  /**\n   * Triggers immediate hydration.\n   *\n   * @returns Promise that resolves when hydration completes\n   */\n  readonly hydrate: () => Promise<void>;\n\n  /**\n   * Schedules hydration to occur after a delay.\n   *\n   * @param delay - Delay in milliseconds before hydration\n   * @returns Function to cancel the scheduled hydration\n   */\n  readonly scheduleHydration: (delay: number) => () => void;\n\n  /**\n   * Cancels any pending or scheduled hydration.\n   */\n  readonly cancel: () => void;\n\n  /**\n   * Resets the hydration state to pending.\n   * Allows re-hydration after error or completion.\n   */\n  readonly reset: () => void;\n\n  /**\n   * Props to spread on a container element for the scheduler.\n   * Includes ref callback and data attributes.\n   */\n  readonly containerProps: DeferredHydrationContainerProps;\n}\n\n/**\n * Props to spread on the container element.\n */\nexport interface DeferredHydrationContainerProps {\n  readonly ref: (element: HTMLElement | null) => void;\n  readonly 'data-hydration-boundary-id': string;\n  readonly 'data-hydration-state': HydrationState;\n  readonly 'data-hydration-deferred': boolean;\n}\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\n/**\n * Hook for manual control over component hydration.\n *\n * Provides explicit control over hydration timing, useful for:\n * - Components that should only hydrate on user action\n * - Delayed hydration after initial render\n * - Conditional hydration based on external factors\n * - Testing hydration behavior\n *\n * @param config - Deferred hydration configuration\n * @returns Deferred hydration control interface\n *\n * @example\n * ```tsx\n * // Basic manual hydration\n * function ManualComponent() {\n *   const { isHydrated, hydrate, containerProps } = useDeferredHydration({\n *     id: 'manual-section',\n *     onHydrate: async () => {\n *       // Initialize component\n *       await loadData();\n *     },\n *   });\n *\n *   return (\n *     <div {...containerProps}>\n *       {isHydrated ? (\n *         <InteractiveContent />\n *       ) : (\n *         <button onClick={hydrate}>Load Content</button>\n *       )}\n *     </div>\n *   );\n * }\n *\n * // Scheduled hydration\n * function DelayedComponent() {\n *   const { isHydrated, scheduleHydration, cancel } = useDeferredHydration({\n *     id: 'delayed-section',\n *   });\n *\n *   useEffect(() => {\n *     // Hydrate after 3 seconds of visibility\n *     const cancelSchedule = scheduleHydration(3000);\n *\n *     return cancelSchedule;\n *   }, [scheduleHydration]);\n *\n *   return (\n *     <div>\n *       {isHydrated ? <Content /> : <Loading />}\n *       <button onClick={cancel}>Cancel Hydration</button>\n *     </div>\n *   );\n * }\n *\n * // Conditional hydration\n * function ConditionalComponent({ shouldHydrate }: { shouldHydrate: boolean }) {\n *   const { isHydrated, hydrate } = useDeferredHydration({\n *     id: 'conditional-section',\n *   });\n *\n *   useEffect(() => {\n *     if (shouldHydrate && !isHydrated) {\n *       hydrate();\n *     }\n *   }, [shouldHydrate, isHydrated, hydrate]);\n *\n *   return <div>{isHydrated ? <Interactive /> : <Static />}</div>;\n * }\n * ```\n */\nexport function useDeferredHydration(\n  config: DeferredHydrationConfig = {}\n): UseDeferredHydrationReturn {\n  const {\n    id: providedId,\n    priority = 'normal',\n    onHydrate,\n    onComplete,\n    onError,\n    timeout = 10000,\n    autoRegister = false,\n  } = config;\n\n  // Generate stable ID\n  const reactId = useId();\n  const boundaryId = useMemo(\n    () => createBoundaryId(providedId ?? `deferred-${reactId.replace(/:/g, '-')}`),\n    [providedId, reactId]\n  );\n\n  // Get context (optional)\n  const context = useOptionalHydrationContext();\n\n  // ==========================================================================\n  // State\n  // ==========================================================================\n\n  const [state, setState] = useState<HydrationState>('pending');\n  const [error, setError] = useState<Error | null>(null);\n  const [duration, setDuration] = useState<number | null>(null);\n\n  // ==========================================================================\n  // Refs\n  // ==========================================================================\n\n  const elementRef = useRef<HTMLElement | null>(null);\n  const scheduleTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n  const hydrationStartRef = useRef<number | null>(null);\n  const isCancelledRef = useRef(false);\n\n  // ==========================================================================\n  // Element Ref Callback\n  // ==========================================================================\n\n  const setElementRef = useCallback((element: HTMLElement | null) => {\n    elementRef.current = element;\n  }, []);\n\n  // ==========================================================================\n  // Hydration Function\n  // ==========================================================================\n\n  const performHydration = useCallback(async (): Promise<void> => {\n    if (state === 'hydrated' || state === 'hydrating') {\n      return;\n    }\n\n    if (isCancelledRef.current) {\n      isCancelledRef.current = false;\n      return;\n    }\n\n    // Clear any scheduled hydration\n    if (scheduleTimeoutRef.current) {\n      clearTimeout(scheduleTimeoutRef.current);\n      scheduleTimeoutRef.current = null;\n    }\n\n    // Start hydration\n    setState('hydrating');\n    hydrationStartRef.current = performance.now();\n\n    // Create timeout promise\n    const timeoutPromise = new Promise<never>((_, reject) => {\n      setTimeout(() => {\n        reject(new Error(`Hydration timeout after ${timeout}ms`));\n      }, timeout);\n    });\n\n    try {\n      // Execute hydration with timeout\n      await Promise.race([\n        Promise.resolve(onHydrate?.()),\n        timeoutPromise,\n      ]);\n\n      // Check if cancelled during hydration\n      if (isCancelledRef.current) {\n        isCancelledRef.current = false;\n        setState('pending');\n        return;\n      }\n\n      // Calculate duration\n      const hydrationDuration = performance.now() - (hydrationStartRef.current ?? 0);\n      setDuration(hydrationDuration);\n\n      // Mark as hydrated\n      setState('hydrated');\n\n      // Callback\n      onComplete?.(hydrationDuration);\n    } catch (err) {\n      const hydrationError = err instanceof Error ? err : new Error(String(err));\n      setError(hydrationError);\n      setState('error');\n      onError?.(hydrationError);\n      throw hydrationError;\n    }\n  }, [state, timeout, onHydrate, onComplete, onError]);\n\n  // ==========================================================================\n  // Schedule Function\n  // ==========================================================================\n\n  const scheduleHydration = useCallback(\n    (delay: number): (() => void) => {\n      // Clear any existing schedule\n      if (scheduleTimeoutRef.current) {\n        clearTimeout(scheduleTimeoutRef.current);\n      }\n\n      // Schedule new hydration\n      scheduleTimeoutRef.current = setTimeout(() => {\n        void performHydration();\n      }, delay);\n\n      // Return cancel function\n      return () => {\n        if (scheduleTimeoutRef.current) {\n          clearTimeout(scheduleTimeoutRef.current);\n          scheduleTimeoutRef.current = null;\n        }\n      };\n    },\n    [performHydration]\n  );\n\n  // ==========================================================================\n  // Cancel Function\n  // ==========================================================================\n\n  const cancel = useCallback((): void => {\n    // Cancel scheduled hydration\n    if (scheduleTimeoutRef.current) {\n      clearTimeout(scheduleTimeoutRef.current);\n      scheduleTimeoutRef.current = null;\n    }\n\n    // Mark as cancelled if hydrating\n    if (state === 'hydrating') {\n      isCancelledRef.current = true;\n    }\n  }, [state]);\n\n  // ==========================================================================\n  // Reset Function\n  // ==========================================================================\n\n  const reset = useCallback((): void => {\n    cancel();\n    setState('pending');\n    setError(null);\n    setDuration(null);\n    isCancelledRef.current = false;\n  }, [cancel]);\n\n  // ==========================================================================\n  // Auto-Registration\n  // ==========================================================================\n\n  useEffect(() => {\n    if (!autoRegister) {\n      return;\n    }\n\n    const task: HydrationTask = {\n      id: boundaryId,\n      priority,\n      trigger: 'manual',\n      hydrate: performHydration,\n      enqueuedAt: Date.now(),\n      element: elementRef.current,\n      cancellable: true,\n      metadata: {\n        componentName: providedId,\n      },\n    };\n\n    if (context) {\n      context.registerBoundary(task);\n      return () => context.unregisterBoundary(boundaryId);\n    } else {\n      try {\n        const scheduler = getHydrationScheduler();\n        scheduler.register(task);\n        return () => scheduler.unregister(boundaryId);\n      } catch {\n        // Scheduler not available\n        return;\n      }\n    }\n  }, [autoRegister, boundaryId, priority, performHydration, context, providedId]);\n\n  // ==========================================================================\n  // Cleanup\n  // ==========================================================================\n\n  useEffect(() => {\n    return () => {\n      if (scheduleTimeoutRef.current) {\n        clearTimeout(scheduleTimeoutRef.current);\n      }\n    };\n  }, []);\n\n  // ==========================================================================\n  // Container Props\n  // ==========================================================================\n\n  const containerProps = useMemo<DeferredHydrationContainerProps>(\n    () => ({\n      ref: setElementRef,\n      'data-hydration-boundary-id': boundaryId,\n      'data-hydration-state': state,\n      'data-hydration-deferred': true,\n    }),\n    [boundaryId, state, setElementRef]\n  );\n\n  // ==========================================================================\n  // Return\n  // ==========================================================================\n\n  return useMemo<UseDeferredHydrationReturn>(\n    () => ({\n      state,\n      isHydrated: state === 'hydrated',\n      isHydrating: state === 'hydrating',\n      isPending: state === 'pending',\n      error,\n      duration,\n      boundaryId,\n      hydrate: performHydration,\n      scheduleHydration,\n      cancel,\n      reset,\n      containerProps,\n    }),\n    [\n      state,\n      error,\n      duration,\n      boundaryId,\n      performHydration,\n      scheduleHydration,\n      cancel,\n      reset,\n      containerProps,\n    ]\n  );\n}\n\n/**\n * Hook for creating a simple deferred hydration trigger.\n *\n * Simplified version of useDeferredHydration for common use cases.\n *\n * @param id - Optional boundary ID\n * @returns Tuple of [isHydrated, hydrate function]\n *\n * @example\n * ```tsx\n * function SimpleDeferred() {\n *   const [isHydrated, hydrate] = useSimpleDeferredHydration('my-component');\n *\n *   return (\n *     <div>\n *       {isHydrated ? (\n *         <InteractiveContent />\n *       ) : (\n *         <button onClick={hydrate}>Load</button>\n *       )}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useSimpleDeferredHydration(\n  id?: string\n): [boolean, () => Promise<void>] {\n  const { isHydrated, hydrate } = useDeferredHydration({ id });\n  return [isHydrated, hydrate];\n}\n\n/**\n * Hook for hydration that triggers on idle.\n *\n * Schedules hydration to occur during browser idle time.\n *\n * @param config - Deferred hydration configuration\n * @returns Deferred hydration control interface\n *\n * @example\n * ```tsx\n * function IdleHydratedComponent() {\n *   const { isHydrated } = useIdleHydration({\n *     id: 'idle-component',\n *     idleTimeout: 5000,\n *   });\n *\n *   return <div>{isHydrated ? <Content /> : <Skeleton />}</div>;\n * }\n * ```\n */\nexport function useIdleHydration(\n  config: DeferredHydrationConfig & { idleTimeout?: number } = {}\n): UseDeferredHydrationReturn {\n  const { idleTimeout = 2000, ...restConfig } = config;\n  const deferredHydration = useDeferredHydration(restConfig);\n\n  useEffect(() => {\n    if (deferredHydration.isHydrated || deferredHydration.isHydrating) {\n      return;\n    }\n\n    // Use requestIdleCallback if available\n    if ('requestIdleCallback' in window) {\n      const handle = window.requestIdleCallback(\n        () => {\n          void deferredHydration.hydrate();\n        },\n        { timeout: idleTimeout }\n      );\n\n      return () => window.cancelIdleCallback(handle);\n    } else {\n      // Fallback to setTimeout\n      const timeoutId = setTimeout(() => {\n        void deferredHydration.hydrate();\n      }, idleTimeout);\n\n      return () => clearTimeout(timeoutId);\n    }\n  }, [deferredHydration, idleTimeout]);\n\n  return deferredHydration;\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n// Types are already exported inline above\n"],"names":["useDeferredHydration","config","providedId","priority","onHydrate","onComplete","onError","timeout","autoRegister","reactId","useId","boundaryId","useMemo","createBoundaryId","context","useOptionalHydrationContext","state","setState","useState","error","setError","duration","setDuration","elementRef","useRef","scheduleTimeoutRef","hydrationStartRef","isCancelledRef","setElementRef","useCallback","element","performHydration","timeoutPromise","_","reject","hydrationDuration","err","hydrationError","scheduleHydration","delay","cancel","reset","useEffect","task","scheduler","getHydrationScheduler","containerProps","useSimpleDeferredHydration","id","isHydrated","hydrate","useIdleHydration","idleTimeout","restConfig","deferredHydration","handle","timeoutId"],"mappings":"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"}