{"version":3,"file":"useDeferredStream.mjs","sources":["../../../../src/lib/streaming/hooks/useDeferredStream.ts"],"sourcesContent":["/**\n * @file useDeferredStream Hook\n * @description Hook for deferring stream content until specific conditions are met.\n *\n * Enables intelligent deferral of streaming based on visibility,\n * browser idle state, user interaction, or custom events.\n *\n * @module streaming/hooks/useDeferredStream\n * @version 1.0.0\n * @author Harbor Framework Team\n *\n * @example\n * ```tsx\n * function LazySection({ children }: { children: ReactNode }) {\n *   const { isDeferred, ref, triggerNow } = useDeferredStream({\n *     deferUntilVisible: true,\n *     maxDeferMs: 5000,\n *   });\n *\n *   return (\n *     <div ref={ref}>\n *       {isDeferred ? <Placeholder /> : children}\n *       {isDeferred && <button onClick={triggerNow}>Load Now</button>}\n *     </div>\n *   );\n * }\n * ```\n */\n\nimport {\n  useState,\n  useEffect,\n  useRef,\n  useCallback,\n  useMemo,\n  useLayoutEffect,\n  type RefObject,\n} from 'react';\n\nimport { useOptionalStreamContext } from '../StreamProvider';\n\nimport { type UseDeferredStreamOptions, type UseDeferredStreamResult, DeferReason } from '../types';\n\n// ============================================================================\n// Default Options\n// ============================================================================\n\nconst DEFAULT_OPTIONS: Required<UseDeferredStreamOptions> = {\n  deferUntilVisible: false,\n  deferUntilIdle: false,\n  deferUntilEvent: '',\n  maxDeferMs: 30000,\n  visibilityThreshold: 0.1,\n};\n\n// ============================================================================\n// Default Result\n// ============================================================================\n\nconst DEFAULT_RESULT: UseDeferredStreamResult = {\n  isDeferred: false,\n  triggerNow: () => {},\n  ref: { current: null as HTMLElement | null } as RefObject<HTMLElement>,\n  deferReason: null,\n};\n\n// ============================================================================\n// Idle Callback Polyfill\n// ============================================================================\n\n/**\n * RequestIdleCallback with fallback for unsupported browsers.\n */\nfunction requestIdleCallbackPolyfill(\n  callback: IdleRequestCallback,\n  options?: IdleRequestOptions\n): number {\n  if (typeof requestIdleCallback !== 'undefined') {\n    return requestIdleCallback(callback, options);\n  }\n\n  // Fallback: use setTimeout with delay\n  const timeout = options?.timeout ?? 50;\n  const start = Date.now();\n\n  return window.setTimeout(\n    () => {\n      callback({\n        didTimeout: false,\n        timeRemaining: () => Math.max(0, 50 - (Date.now() - start)),\n      });\n    },\n    Math.min(timeout, 50)\n  ) as unknown as number;\n}\n\n/**\n * CancelIdleCallback with fallback.\n */\nfunction cancelIdleCallbackPolyfill(handle: number): void {\n  if (typeof cancelIdleCallback !== 'undefined') {\n    cancelIdleCallback(handle);\n  } else {\n    clearTimeout(handle);\n  }\n}\n\n// ============================================================================\n// Main Hook Implementation\n// ============================================================================\n\n/**\n * Hook for deferring stream content.\n *\n * @description\n * Provides fine-grained control over when streaming should begin,\n * based on various conditions like visibility, idle state, or events.\n *\n * Deferral strategies:\n * - **Visibility**: Defer until element enters viewport\n * - **Idle**: Defer until browser is idle (requestIdleCallback)\n * - **Event**: Defer until a custom event is fired\n * - **Time-based**: Maximum defer duration before auto-triggering\n *\n * Features:\n * - Multiple deferral conditions (AND logic)\n * - Manual trigger override\n * - Maximum defer timeout\n * - Reason tracking for debugging\n * - Automatic cleanup\n *\n * @param options - Deferral configuration\n * @returns Deferral state and controls\n *\n * @example\n * ```tsx\n * // Defer until visible\n * const { isDeferred, ref } = useDeferredStream({\n *   deferUntilVisible: true,\n * });\n *\n * // Defer until browser is idle\n * const { isDeferred } = useDeferredStream({\n *   deferUntilIdle: true,\n * });\n *\n * // Defer until custom event\n * const { isDeferred } = useDeferredStream({\n *   deferUntilEvent: 'user-scrolled',\n * });\n *\n * // Combined conditions with timeout\n * const { isDeferred, ref, triggerNow, deferReason } = useDeferredStream({\n *   deferUntilVisible: true,\n *   deferUntilIdle: true,\n *   maxDeferMs: 3000,\n * });\n * ```\n */\nexport function useDeferredStream(options: UseDeferredStreamOptions = {}): UseDeferredStreamResult {\n  const {\n    deferUntilVisible = DEFAULT_OPTIONS.deferUntilVisible,\n    deferUntilIdle = DEFAULT_OPTIONS.deferUntilIdle,\n    deferUntilEvent = DEFAULT_OPTIONS.deferUntilEvent,\n    maxDeferMs = DEFAULT_OPTIONS.maxDeferMs,\n    visibilityThreshold = DEFAULT_OPTIONS.visibilityThreshold,\n  } = options;\n\n  const context = useOptionalStreamContext();\n\n  // State tracking\n  const [isVisible, setIsVisible] = useState(!deferUntilVisible);\n  const [isIdle, setIsIdle] = useState(!deferUntilIdle);\n  const [eventFired, setEventFired] = useState(!deferUntilEvent);\n  const [manuallyTriggered, setManuallyTriggered] = useState(false);\n  const [timedOut, setTimedOut] = useState(false);\n\n  // Refs\n  const elementRef = useRef<HTMLElement | null>(null);\n  const observerRef = useRef<IntersectionObserver | null>(null);\n  const idleCallbackRef = useRef<number | null>(null);\n  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n  const mountedRef = useRef(true);\n\n  // ==========================================================================\n  // Computed Deferral State\n  // ==========================================================================\n\n  const isDeferred = useMemo(() => {\n    // Manual trigger overrides all deferral\n    if (manuallyTriggered || timedOut) return false;\n\n    // Check all deferral conditions\n    const conditions = [\n      deferUntilVisible && !isVisible,\n      deferUntilIdle && !isIdle,\n      deferUntilEvent && !eventFired,\n    ];\n\n    // Deferred if any condition is still pending\n    return conditions.some(Boolean);\n  }, [\n    deferUntilVisible,\n    deferUntilIdle,\n    deferUntilEvent,\n    isVisible,\n    isIdle,\n    eventFired,\n    manuallyTriggered,\n    timedOut,\n  ]);\n\n  const deferReason = useMemo<DeferReason | null>(() => {\n    if (!isDeferred) return null;\n\n    if (deferUntilVisible && !isVisible) return DeferReason.NotVisible;\n    if (deferUntilIdle && !isIdle) return DeferReason.BrowserBusy;\n    if (deferUntilEvent && !eventFired) return DeferReason.WaitingForEvent;\n\n    return null;\n  }, [\n    isDeferred,\n    deferUntilVisible,\n    deferUntilIdle,\n    deferUntilEvent,\n    isVisible,\n    isIdle,\n    eventFired,\n  ]);\n\n  // ==========================================================================\n  // Manual Trigger\n  // ==========================================================================\n\n  const triggerNow = useCallback(() => {\n    setManuallyTriggered(true);\n  }, []);\n\n  // ==========================================================================\n  // Visibility Observer\n  // ==========================================================================\n\n  useEffect(() => {\n    if (!deferUntilVisible || typeof IntersectionObserver === 'undefined') {\n      return;\n    }\n\n    observerRef.current = new IntersectionObserver(\n      (entries) => {\n        for (const entry of entries) {\n          if (entry.isIntersecting && entry.intersectionRatio >= visibilityThreshold) {\n            if (mountedRef.current) {\n              setIsVisible(true);\n            }\n            // Stop observing once visible\n            observerRef.current?.disconnect();\n          }\n        }\n      },\n      {\n        threshold: visibilityThreshold,\n        rootMargin: '50px', // Start loading slightly before visible\n      }\n    );\n\n    // Observe element if available\n    if (elementRef.current) {\n      observerRef.current.observe(elementRef.current);\n    }\n\n    return () => {\n      observerRef.current?.disconnect();\n    };\n  }, [deferUntilVisible, visibilityThreshold]);\n\n  // Re-observe when element changes\n  const setRef = useCallback(\n    (element: HTMLElement | null) => {\n      elementRef.current = element;\n\n      if (element && observerRef.current && deferUntilVisible) {\n        observerRef.current.observe(element);\n      }\n    },\n    [deferUntilVisible]\n  );\n\n  // Create stable ref object\n  const refObject = useMemo(\n    () => ({\n      get current() {\n        return elementRef.current;\n      },\n      set current(value: HTMLElement | null) {\n        setRef(value);\n      },\n    }),\n    [setRef]\n  );\n\n  // ==========================================================================\n  // Idle Callback\n  // ==========================================================================\n\n  useEffect(() => {\n    if (!deferUntilIdle) {\n      return;\n    }\n\n    idleCallbackRef.current = requestIdleCallbackPolyfill(\n      () => {\n        if (mountedRef.current) {\n          setIsIdle(true);\n        }\n      },\n      { timeout: maxDeferMs }\n    );\n\n    return () => {\n      if (idleCallbackRef.current !== null) {\n        cancelIdleCallbackPolyfill(idleCallbackRef.current);\n      }\n    };\n  }, [deferUntilIdle, maxDeferMs]);\n\n  // ==========================================================================\n  // Event Listener\n  // ==========================================================================\n\n  useEffect(() => {\n    if (!deferUntilEvent) {\n      return;\n    }\n\n    const handleEvent = (): void => {\n      if (mountedRef.current) {\n        setEventFired(true);\n      }\n    };\n\n    // Listen for custom event on window\n    window.addEventListener(deferUntilEvent, handleEvent);\n\n    return () => {\n      window.removeEventListener(deferUntilEvent, handleEvent);\n    };\n  }, [deferUntilEvent]);\n\n  // ==========================================================================\n  // Maximum Defer Timeout\n  // ==========================================================================\n\n  useEffect(() => {\n    if (maxDeferMs <= 0 || !isDeferred) {\n      return;\n    }\n\n    timeoutRef.current = setTimeout(() => {\n      if (mountedRef.current) {\n        setTimedOut(true);\n      }\n    }, maxDeferMs);\n\n    return () => {\n      if (timeoutRef.current) {\n        clearTimeout(timeoutRef.current);\n      }\n    };\n  }, [maxDeferMs, isDeferred]);\n\n  // ==========================================================================\n  // Cleanup\n  // ==========================================================================\n\n  useEffect(() => {\n    mountedRef.current = true;\n\n    return () => {\n      mountedRef.current = false;\n    };\n  }, []);\n\n  // Return default if no context\n  if (!context) {\n    return DEFAULT_RESULT;\n  }\n\n  return {\n    isDeferred,\n    triggerNow,\n    ref: refObject as RefObject<HTMLElement>,\n    deferReason,\n  };\n}\n\n// ============================================================================\n// Specialized Deferral Hooks\n// ============================================================================\n\n/**\n * Extended result with additional controls.\n */\nexport interface UseExtendedDeferredStreamResult extends UseDeferredStreamResult {\n  /** Time remaining until max defer timeout */\n  timeRemaining: number | null;\n  /** Whether deferral is due to visibility */\n  isDeferredByVisibility: boolean;\n  /** Whether deferral is due to idle state */\n  isDeferredByIdle: boolean;\n  /** Whether deferral is due to event */\n  isDeferredByEvent: boolean;\n  /** Reset deferral state */\n  reset: () => void;\n}\n\n/**\n * Extended deferred stream hook with additional information.\n *\n * @example\n * ```tsx\n * function DetailedDeferred() {\n *   const {\n *     isDeferred,\n *     isDeferredByVisibility,\n *     isDeferredByIdle,\n *     timeRemaining,\n *     ref,\n *     reset,\n *   } = useExtendedDeferredStream({\n *     deferUntilVisible: true,\n *     deferUntilIdle: true,\n *     maxDeferMs: 5000,\n *   });\n *\n *   return (\n *     <div ref={ref}>\n *       {isDeferred && (\n *         <div>\n *           <p>Waiting: {isDeferredByVisibility ? 'visibility' : 'idle'}</p>\n *           <p>Time remaining: {timeRemaining}ms</p>\n *           <button onClick={reset}>Reset</button>\n *         </div>\n *       )}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useExtendedDeferredStream(\n  options: UseDeferredStreamOptions = {}\n): UseExtendedDeferredStreamResult {\n  const base = useDeferredStream(options);\n  const [startTime] = useState(() => Date.now());\n  const [timeRemaining, setTimeRemaining] = useState<number | null>(options.maxDeferMs ?? null);\n  const [resetCount, setResetCount] = useState(0);\n\n  useLayoutEffect(() => {\n    if (options.maxDeferMs == null || options.maxDeferMs === 0 || !base.isDeferred) {\n      // eslint-disable-next-line react-hooks/set-state-in-effect\n      setTimeRemaining(null);\n      return;\n    }\n\n    const interval = setInterval(() => {\n      const elapsed = Date.now() - startTime;\n      const remaining = Math.max(0, (options.maxDeferMs ?? 0) - elapsed);\n      setTimeRemaining(remaining);\n    }, 100);\n\n    return () => clearInterval(interval);\n  }, [options.maxDeferMs, base.isDeferred, startTime, resetCount]);\n\n  const isDeferredByVisibility = base.deferReason === DeferReason.NotVisible;\n  const isDeferredByIdle = base.deferReason === DeferReason.BrowserBusy;\n  const isDeferredByEvent = base.deferReason === DeferReason.WaitingForEvent;\n\n  const reset = useCallback(() => {\n    setResetCount((c) => c + 1);\n  }, []);\n\n  return {\n    ...base,\n    timeRemaining,\n    isDeferredByVisibility,\n    isDeferredByIdle,\n    isDeferredByEvent,\n    reset,\n  };\n}\n\n/**\n * Hook for deferring until element is visible.\n *\n * @description\n * Convenience hook for visibility-based deferral.\n *\n * @example\n * ```tsx\n * function LazyImage({ src }: { src: string }) {\n *   const { isDeferred, ref } = useDeferUntilVisible();\n *\n *   return (\n *     <div ref={ref}>\n *       {isDeferred ? <Skeleton /> : <img src={src} />}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useDeferUntilVisible(\n  options: Omit<UseDeferredStreamOptions, 'deferUntilVisible'> = {}\n): UseDeferredStreamResult {\n  return useDeferredStream({\n    ...options,\n    deferUntilVisible: true,\n  });\n}\n\n/**\n * Hook for deferring until browser is idle.\n *\n * @description\n * Convenience hook for idle-based deferral.\n *\n * @example\n * ```tsx\n * function NonCriticalWidget() {\n *   const { isDeferred } = useDeferUntilIdle();\n *\n *   if (isDeferred) return null;\n *\n *   return <ExpensiveWidget />;\n * }\n * ```\n */\nexport function useDeferUntilIdle(\n  options: Omit<UseDeferredStreamOptions, 'deferUntilIdle'> = {}\n): UseDeferredStreamResult {\n  return useDeferredStream({\n    ...options,\n    deferUntilIdle: true,\n  });\n}\n\n/**\n * Hook for deferring until a custom event.\n *\n * @description\n * Convenience hook for event-based deferral.\n *\n * @param eventName - Name of the event to wait for\n * @param options - Additional options\n *\n * @example\n * ```tsx\n * function AfterLoginContent() {\n *   const { isDeferred } = useDeferUntilEvent('user:logged-in');\n *\n *   if (isDeferred) return <LoginPrompt />;\n *\n *   return <AuthenticatedContent />;\n * }\n * ```\n */\nexport function useDeferUntilEvent(\n  eventName: string,\n  options: Omit<UseDeferredStreamOptions, 'deferUntilEvent'> = {}\n): UseDeferredStreamResult {\n  return useDeferredStream({\n    ...options,\n    deferUntilEvent: eventName,\n  });\n}\n"],"names":["DEFAULT_OPTIONS","DEFAULT_RESULT","requestIdleCallbackPolyfill","callback","options","timeout","start","cancelIdleCallbackPolyfill","handle","useDeferredStream","deferUntilVisible","deferUntilIdle","deferUntilEvent","maxDeferMs","visibilityThreshold","context","useOptionalStreamContext","isVisible","setIsVisible","useState","isIdle","setIsIdle","eventFired","setEventFired","manuallyTriggered","setManuallyTriggered","timedOut","setTimedOut","elementRef","useRef","observerRef","idleCallbackRef","timeoutRef","mountedRef","isDeferred","useMemo","deferReason","DeferReason","triggerNow","useCallback","useEffect","entries","entry","setRef","element","refObject","value","handleEvent","useExtendedDeferredStream","base","startTime","timeRemaining","setTimeRemaining","resetCount","setResetCount","useLayoutEffect","interval","elapsed","remaining","isDeferredByVisibility","isDeferredByIdle","isDeferredByEvent","reset","c","useDeferUntilVisible","useDeferUntilIdle","useDeferUntilEvent","eventName"],"mappings":"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"}