{"version":3,"file":"useModuleHydration.mjs","sources":["../../../../src/lib/vdom/hooks/useModuleHydration.ts"],"sourcesContent":["/**\n * @file useModuleHydration Hook\n * @module vdom/hooks/useModuleHydration\n * @description Hook for controlling module hydration with manual triggers,\n * state tracking, and hydration data access.\n *\n * @author Agent 5 - PhD Virtual DOM Expert\n * @version 1.0.0\n */\n\nimport { useState, useCallback, useMemo, useEffect, useLayoutEffect, useRef } from 'react';\nimport {\n  type UseModuleHydrationReturn,\n  type HydrationData,\n  HydrationState,\n  type HydrationPriority,\n  HydrationTrigger,\n} from '../types';\nimport { useModuleContext } from '../ModuleBoundary';\n\n/**\n * Hook for controlling module hydration.\n * Provides hydration state, manual triggers, and hydration data access.\n *\n * @returns Hydration state and controls\n * @throws Error if used outside a ModuleBoundary\n *\n * @example\n * ```tsx\n * function HeavyComponent() {\n *   const {\n *     hydrationState,\n *     isHydrated,\n *     isPending,\n *     hydrate,\n *     progress,\n *     data,\n *   } = useModuleHydration();\n *\n *   if (!isHydrated) {\n *     return (\n *       <div>\n *         <p>Loading... {Math.round(progress * 100)}%</p>\n *         <button onClick={hydrate}>Hydrate Now</button>\n *       </div>\n *     );\n *   }\n *\n *   return <ExpensiveContent initialData={data?.state} />;\n * }\n * ```\n */\nexport function useModuleHydration(): UseModuleHydrationReturn {\n  const context = useModuleContext();\n\n  // Local state for progress tracking\n  const [progress, setProgress] = useState(0);\n  const [error, setError] = useState<Error | null>(null);\n\n  // Track hydration state from context\n  const { hydrationState } = context.state;\n\n  // Derived states\n  const isHydrated = hydrationState === HydrationState.HYDRATED;\n  const isPending = hydrationState === HydrationState.PENDING;\n  const isHydrating = hydrationState === HydrationState.HYDRATING;\n  const hasFailed = hydrationState === HydrationState.FAILED;\n\n  // Progress simulation during hydration\n  useEffect(() => {\n    if (isHydrating) {\n      let progressValue = 0;\n      const interval = setInterval(() => {\n        progressValue += 0.1;\n        if (progressValue >= 0.9) {\n          clearInterval(interval);\n        }\n        setProgress(Math.min(progressValue, 0.9));\n      }, 50);\n\n      return () => clearInterval(interval);\n    }\n    return undefined;\n  }, [isHydrating]);\n\n  // Update progress when hydration completes or fails\n  useLayoutEffect(() => {\n    if (isHydrated) {\n      // Use a microtask to avoid synchronous setState during render\n      void Promise.resolve().then(() => {\n        setProgress(1);\n      });\n    } else if (hasFailed) {\n      void Promise.resolve().then(() => {\n        setProgress(0);\n      });\n    }\n  }, [isHydrated, hasFailed]);\n\n  // Update error state from context\n  useLayoutEffect(() => {\n    if (context.state.error && hasFailed) {\n      // Use a microtask to avoid synchronous setState during render\n      void Promise.resolve().then(() => {\n        setError(context.state.error);\n      });\n    }\n  }, [context.state.error, hasFailed]);\n\n  // Manual hydration trigger\n  const hydrate = useCallback(async () => {\n    if (isHydrated || isHydrating) {\n      return;\n    }\n\n    setProgress(0);\n    setError(null);\n\n    try {\n      await context.hydrate();\n    } catch (err) {\n      const hydrationError = err instanceof Error ? err : new Error(String(err));\n      setError(hydrationError);\n      throw hydrationError;\n    }\n  }, [context, isHydrated, isHydrating]);\n\n  // Skip hydration (client-only)\n  const skip = useCallback(() => {\n    context.dispatch({\n      type: 'TRANSITION_STATE',\n      to: context.state.lifecycleState, // Keep current lifecycle state\n    });\n    // Mark hydration as skipped through a different mechanism\n    // This would require extending the action types\n  }, [context]);\n\n  // Get hydration data from context\n  const hydrationData: HydrationData | null = null; // TODO: Implement hydration data retrieval\n\n  // Return memoized object\n  return useMemo<UseModuleHydrationReturn>(\n    () => ({\n      hydrationState,\n      isHydrated,\n      isPending,\n      isHydrating,\n      hasFailed,\n      error,\n      progress,\n      hydrate,\n      skip,\n      data: hydrationData,\n    }),\n    [\n      hydrationState,\n      isHydrated,\n      isPending,\n      isHydrating,\n      hasFailed,\n      error,\n      progress,\n      hydrate,\n      skip,\n      hydrationData,\n    ]\n  );\n}\n\n/**\n * Hook to check if the module is hydrated.\n * @returns Whether module is hydrated\n */\nexport function useIsHydrated(): boolean {\n  const { isHydrated } = useModuleHydration();\n  return isHydrated;\n}\n\n/**\n * Hook to trigger hydration imperatively.\n * @returns Hydration trigger function\n */\nexport function useHydrateTrigger(): () => Promise<void> {\n  const { hydrate } = useModuleHydration();\n  return hydrate;\n}\n\n/**\n * Hook to get hydration progress.\n * @returns Progress value (0-1)\n */\nexport function useHydrationProgress(): number {\n  const { progress } = useModuleHydration();\n  return progress;\n}\n\n/**\n * Hook to execute callback when hydration completes.\n * @param callback - Callback to execute\n *\n * @example\n * ```tsx\n * useOnHydrated(() => {\n *   analytics.track('module_hydrated', { moduleId });\n * });\n * ```\n */\nexport function useOnHydrated(callback: () => void): void {\n  const { isHydrated } = useModuleHydration();\n  const callbackRef = useRef(callback);\n\n  // Update ref on callback change\n  useEffect(() => {\n    callbackRef.current = callback;\n  }, [callback]);\n\n  // Call when hydrated\n  useEffect(() => {\n    if (isHydrated) {\n      callbackRef.current();\n    }\n  }, [isHydrated]);\n}\n\n/**\n * Hook to execute callback when hydration fails.\n * @param callback - Callback to execute with error\n *\n * @example\n * ```tsx\n * useOnHydrationError((error) => {\n *   errorReporter.capture(error);\n * });\n * ```\n */\nexport function useOnHydrationError(callback: (error: Error) => void): void {\n  const { hasFailed, error } = useModuleHydration();\n  const callbackRef = useRef(callback);\n\n  useEffect(() => {\n    callbackRef.current = callback;\n  }, [callback]);\n\n  useEffect(() => {\n    if (hasFailed && error) {\n      callbackRef.current(error);\n      return;\n    }\n  }, [hasFailed, error]);\n}\n\n/**\n * Hook to defer rendering until hydration is complete.\n * @param fallback - Content to show while hydrating\n * @param children - Content to show when hydrated\n * @returns Appropriate content based on hydration state\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   return useHydrationGuard(\n *     <LoadingSkeleton />,\n *     <ActualContent />\n *   );\n * }\n * ```\n */\nexport function useHydrationGuard<T>(fallback: T, content: T): T {\n  const { isHydrated } = useModuleHydration();\n\n  if (isHydrated) {\n    return content;\n  }\n\n  return fallback;\n}\n\n/**\n * Hook for controlling hydration timing.\n * @param options - Hydration timing options\n * @returns Hydration controls\n */\nexport function useHydrationTiming(options: {\n  delay?: number;\n  priority?: HydrationPriority;\n  trigger?: HydrationTrigger;\n}): {\n  shouldHydrate: boolean;\n  scheduleHydration: () => void;\n  cancelHydration: () => void;\n} {\n  const { hydrate, isHydrated, isHydrating } = useModuleHydration();\n  const [shouldHydrate, setShouldHydrate] = useState(false);\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n  const scheduleHydration = useCallback(() => {\n    if (isHydrated || isHydrating) {\n      return;\n    }\n\n    const delay = options.delay ?? 0;\n\n    if (delay > 0) {\n      timeoutRef.current = setTimeout(() => {\n        setShouldHydrate(true);\n        void hydrate();\n      }, delay);\n    } else {\n      setShouldHydrate(true);\n      void hydrate();\n    }\n  }, [options.delay, hydrate, isHydrated, isHydrating]);\n\n  const cancelHydration = useCallback(() => {\n    if (timeoutRef.current) {\n      clearTimeout(timeoutRef.current);\n      timeoutRef.current = null;\n    }\n    setShouldHydrate(false);\n  }, []);\n\n  // Cleanup on unmount\n  useEffect(() => {\n    return () => {\n      if (timeoutRef.current) {\n        clearTimeout(timeoutRef.current);\n      }\n    };\n  }, []);\n\n  // Handle trigger-based hydration\n  useEffect(() => {\n    if (options.trigger === HydrationTrigger.IMMEDIATE) {\n      // Use queueMicrotask to avoid synchronous setState\n      queueMicrotask(() => {\n        scheduleHydration();\n      });\n      return undefined;\n    } else if (options.trigger === HydrationTrigger.IDLE) {\n      if ('requestIdleCallback' in window) {\n        const id = window.requestIdleCallback(() => {\n          scheduleHydration();\n        });\n        return () => window.cancelIdleCallback(id);\n      } else {\n        const timeout = setTimeout(scheduleHydration, 100);\n        return () => clearTimeout(timeout);\n      }\n    }\n    return undefined;\n  }, [options.trigger, scheduleHydration]);\n\n  return useMemo(\n    () => ({\n      shouldHydrate,\n      scheduleHydration,\n      cancelHydration,\n    }),\n    [shouldHydrate, scheduleHydration, cancelHydration]\n  );\n}\n"],"names":["useModuleHydration","context","useModuleContext","progress","setProgress","useState","error","setError","hydrationState","isHydrated","HydrationState","isPending","isHydrating","hasFailed","useEffect","progressValue","interval","useLayoutEffect","hydrate","useCallback","err","hydrationError","skip","hydrationData","useMemo","useIsHydrated","useHydrateTrigger","useHydrationProgress","useOnHydrated","callback","callbackRef","useRef","useOnHydrationError","useHydrationGuard","fallback","content","useHydrationTiming","options","shouldHydrate","setShouldHydrate","timeoutRef","scheduleHydration","delay","cancelHydration","HydrationTrigger","id","timeout"],"mappings":"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"}