{"version":3,"file":"useErrorRecovery.mjs","sources":["../../../src/lib/hooks/useErrorRecovery.ts"],"sourcesContent":["/**\n * @file Error Recovery Hooks\n * @description React hooks for error handling and recovery patterns\n *\n * These hooks provide consistent patterns for:\n * - Async operations with automatic retry\n * - Network-aware operations\n * - Optimistic updates with rollback\n * - Safe callbacks with error boundaries\n * - Error toast management\n */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { type AppError, isRetryableError, normalizeError } from '../monitoring/errorTypes';\nimport { ErrorReporter } from '../monitoring/ErrorReporter';\nimport { networkMonitor } from '../utils/networkStatus';\nimport { useIsMounted } from './shared/useIsMounted';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Async operation state\n */\nexport interface AsyncState<T> {\n  /** Operation result data */\n  data: T | null;\n  /** Error if operation failed */\n  error: AppError | null;\n  /** Whether operation is in progress */\n  isLoading: boolean;\n  /** Whether operation has errored */\n  isError: boolean;\n  /** Whether operation completed successfully */\n  isSuccess: boolean;\n  /** Number of retry attempts made */\n  retryCount: number;\n}\n\n/**\n * Recovery options for async operations\n */\nexport interface RecoveryOptions {\n  /** Maximum retry attempts */\n  maxRetries?: number;\n  /** Initial retry delay in ms */\n  retryDelay?: number;\n  /** Whether to auto-retry on failure */\n  autoRetry?: boolean;\n  /** Whether to execute on mount */\n  executeOnMount?: boolean;\n  /** Callback on error */\n  onError?: (error: AppError) => void;\n  /** Callback on success */\n  onSuccess?: <T>(data: T) => void;\n  /** Callback on each retry */\n  onRetry?: (attempt: number) => void;\n}\n\n/**\n * Async operation with recovery controls\n */\nexport interface AsyncWithRecovery<T> extends AsyncState<T> {\n  /** Execute the async operation */\n  execute: () => Promise<T | null>;\n  /** Retry the operation */\n  retry: () => Promise<T | null>;\n  /** Reset state */\n  reset: () => void;\n}\n\n// ============================================================================\n// useAsyncWithRecovery\n// ============================================================================\n\n/**\n * Hook for async operations with automatic error recovery\n *\n * @example\n * ```tsx\n * function UserProfile({ userId }: { userId: string }) {\n *   const {\n *     data: user,\n *     isLoading,\n *     isError,\n *     error,\n *     execute,\n *     retry\n *   } = useAsyncWithRecovery(\n *     () => fetchUser(userId),\n *     {\n *       executeOnMount: true,\n *       maxRetries: 3,\n *       autoRetry: true,\n *       onError: (err) => toast.error(err.message)\n *     }\n *   );\n *\n *   if (isLoading) return <Skeleton />;\n *   if (isError) return <ErrorState onRetry={retry} />;\n *   return <UserCard user={user} />;\n * }\n * ```\n */\nexport function useAsyncWithRecovery<T>(\n  asyncFn: () => Promise<T>,\n  options: RecoveryOptions = {}\n): AsyncWithRecovery<T> {\n  const {\n    maxRetries = 3,\n    retryDelay = 1000,\n    autoRetry = false,\n    executeOnMount = false,\n    onError,\n    onSuccess,\n    onRetry,\n  } = options;\n\n  const [state, setState] = useState<AsyncState<T>>({\n    data: null,\n    error: null,\n    isLoading: false,\n    isError: false,\n    isSuccess: false,\n    retryCount: 0,\n  });\n\n  const isMounted = useIsMounted();\n  const retryTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n  const retryCountRef = useRef(0);\n\n  // Define execute before using it in the effect\n  const executeRef = useRef<(() => Promise<T | null>) | null>(null);\n\n  useEffect(() => {\n    return () => {\n      if (retryTimeoutRef.current) {\n        clearTimeout(retryTimeoutRef.current);\n      }\n    };\n  }, []);\n\n  const execute = useCallback(async (): Promise<T | null> => {\n    if (!isMounted()) return null;\n\n    setState((prev) => ({\n      ...prev,\n      isLoading: true,\n      isError: false,\n      error: null,\n    }));\n\n    try {\n      const result = await asyncFn();\n\n      if (isMounted()) {\n        setState({\n          data: result,\n          error: null,\n          isLoading: false,\n          isError: false,\n          isSuccess: true,\n          retryCount: 0,\n        });\n        retryCountRef.current = 0;\n        onSuccess?.(result);\n      }\n\n      return result;\n    } catch (err) {\n      const appError = normalizeError(err);\n\n      if (isMounted()) {\n        const newRetryCount = retryCountRef.current;\n\n        setState((prev) => ({\n          ...prev,\n          error: appError,\n          isLoading: false,\n          isError: true,\n          isSuccess: false,\n          retryCount: newRetryCount,\n        }));\n\n        onError?.(appError);\n\n        // Auto-retry if enabled and error is retryable\n        if (autoRetry && isRetryableError(appError) && newRetryCount < maxRetries) {\n          const delay = retryDelay * Math.pow(2, newRetryCount);\n          retryTimeoutRef.current = setTimeout(() => {\n            if (isMounted() && executeRef.current != null) {\n              retryCountRef.current++;\n              onRetry?.(retryCountRef.current);\n              void executeRef.current();\n            }\n          }, delay);\n        }\n      }\n\n      return null;\n    }\n  }, [asyncFn, autoRetry, isMounted, maxRetries, onError, onRetry, onSuccess, retryDelay]);\n\n  // Store execute in ref for use in timeout\n  // eslint-disable-next-line react-hooks/refs\n  executeRef.current = execute;\n\n  const retry = useCallback(async (): Promise<T | null> => {\n    if (!isMounted()) return null;\n\n    retryCountRef.current++;\n    setState((prev) => ({\n      ...prev,\n      retryCount: retryCountRef.current,\n    }));\n\n    onRetry?.(retryCountRef.current);\n    return execute();\n  }, [execute, isMounted, onRetry]);\n\n  const reset = useCallback(() => {\n    if (retryTimeoutRef.current) {\n      clearTimeout(retryTimeoutRef.current);\n    }\n    retryCountRef.current = 0;\n    setState({\n      data: null,\n      error: null,\n      isLoading: false,\n      isError: false,\n      isSuccess: false,\n      retryCount: 0,\n    });\n  }, []);\n\n  // Execute on mount if requested\n  useEffect(() => {\n    if (executeOnMount) {\n      void execute();\n    }\n  }, [executeOnMount, execute]);\n\n  return {\n    ...state,\n    execute,\n    retry,\n    reset,\n  };\n}\n\n// ============================================================================\n// useNetworkAwareOperation\n// ============================================================================\n\n/**\n * Result of network-aware operation hook\n */\nexport interface NetworkAwareOperationResult<T> {\n  /** Execute the operation */\n  execute: () => Promise<T | null>;\n  /** Current online status */\n  isOnline: boolean;\n  /** Whether waiting for network */\n  isWaiting: boolean;\n  /** Error if any */\n  error: AppError | null;\n}\n\n/**\n * Hook for network-aware operations that wait for connectivity\n *\n * @example\n * ```tsx\n * function SyncButton() {\n *   const { execute, isOnline, isWaiting } = useNetworkAwareOperation(\n *     () => syncData(),\n *     { requiresNetwork: true, waitForOnline: true }\n *   );\n *\n *   return (\n *     <button onClick={execute} disabled={isWaiting}>\n *       {isWaiting ? 'Waiting for connection...' : 'Sync'}\n *     </button>\n *   );\n * }\n * ```\n */\nexport function useNetworkAwareOperation<T>(\n  operation: () => Promise<T>,\n  options: {\n    /** Whether operation requires network */\n    requiresNetwork?: boolean;\n    /** Whether to wait for online status */\n    waitForOnline?: boolean;\n    /** Timeout for waiting (ms) */\n    onlineTimeout?: number;\n  } = {}\n): NetworkAwareOperationResult<T> {\n  const { requiresNetwork = true, waitForOnline = true, onlineTimeout = 30000 } = options;\n\n  const [isOnline, setIsOnline] = useState(() => networkMonitor.isOnline());\n  const [isWaiting, setIsWaiting] = useState(false);\n  const [error, setError] = useState<AppError | null>(null);\n\n  useEffect(() => {\n    return networkMonitor.onStatusChange((status) => {\n      setIsOnline(status.online);\n    });\n  }, []);\n\n  const execute = useCallback(async (): Promise<T | null> => {\n    setError(null);\n\n    if (requiresNetwork && !networkMonitor.isOnline()) {\n      if (waitForOnline) {\n        setIsWaiting(true);\n        const online = await networkMonitor.waitForOnline(onlineTimeout);\n        setIsWaiting(false);\n\n        if (!online) {\n          const offlineError = normalizeError(new Error('Network unavailable'));\n          setError(offlineError);\n          return null;\n        }\n      } else {\n        const offlineError = normalizeError(new Error('Network unavailable'));\n        setError(offlineError);\n        return null;\n      }\n    }\n\n    try {\n      return await operation();\n    } catch (err) {\n      const appError = normalizeError(err);\n      setError(appError);\n      return null;\n    }\n  }, [operation, requiresNetwork, waitForOnline, onlineTimeout]);\n\n  return {\n    execute,\n    isOnline,\n    isWaiting,\n    error,\n  };\n}\n\n// ============================================================================\n// useOptimisticUpdate\n// ============================================================================\n\n/**\n * Result of optimistic update hook\n */\nexport interface OptimisticUpdateResult<T, U> {\n  /** Current value (optimistic or confirmed) */\n  value: T;\n  /** Perform optimistic update */\n  update: (optimisticValue: T, updateData: U) => Promise<void>;\n  /** Whether update is pending */\n  isPending: boolean;\n  /** Error if update failed */\n  error: AppError | null;\n}\n\n/**\n * Hook for optimistic updates with automatic rollback on failure\n *\n * @example\n * ```tsx\n * function LikeButton({ post }: { post: Post }) {\n *   const { value: likes, update, isPending } = useOptimisticUpdate(\n *     post.likes,\n *     (newLikes) => updatePostLikes(post.id, newLikes),\n *     { onRollback: () => toast.error('Failed to like') }\n *   );\n *\n *   const handleLike = () => {\n *     update(likes + 1, likes + 1);\n *   };\n *\n *   return (\n *     <button onClick={handleLike} disabled={isPending}>\n *       {likes} likes\n *     </button>\n *   );\n * }\n * ```\n */\nexport function useOptimisticUpdate<T, U>(\n  currentValue: T,\n  updateFn: (update: U) => Promise<T>,\n  options: {\n    /** Callback when rollback occurs */\n    onRollback?: (original: T, error: AppError) => void;\n    /** Callback on successful update */\n    onSuccess?: (newValue: T) => void;\n  } = {}\n): OptimisticUpdateResult<T, U> {\n  const [value, setValue] = useState<T>(currentValue);\n  const [isPending, setIsPending] = useState(false);\n  const [error, setError] = useState<AppError | null>(null);\n  const originalValueRef = useRef<T>(currentValue);\n\n  // Sync with external value\n  useEffect(() => {\n    setValue(currentValue);\n    originalValueRef.current = currentValue;\n  }, [currentValue]);\n\n  const update = useCallback(\n    async (optimisticValue: T, updateData: U): Promise<void> => {\n      const original = originalValueRef.current;\n\n      // Apply optimistic update\n      setValue(optimisticValue);\n      setIsPending(true);\n      setError(null);\n\n      try {\n        const result = await updateFn(updateData);\n        setValue(result);\n        originalValueRef.current = result;\n        options.onSuccess?.(result);\n      } catch (err) {\n        const appError = normalizeError(err);\n\n        // Rollback to original\n        setValue(original);\n        setError(appError);\n        options.onRollback?.(original, appError);\n\n        ErrorReporter.reportError(err, {\n          action: 'optimistic_update_rollback',\n        });\n      } finally {\n        setIsPending(false);\n      }\n    },\n    [updateFn, options]\n  );\n\n  return {\n    value,\n    update,\n    isPending,\n    error,\n  };\n}\n\n// ============================================================================\n// useSafeCallback\n// ============================================================================\n\n/**\n * Result of safe callback hook\n */\nexport interface SafeCallbackResult<Args extends unknown[], Return> {\n  /** Execute callback with error handling */\n  execute: (...args: Args) => Promise<Return | undefined>;\n  /** Error if callback failed */\n  error: AppError | null;\n  /** Clear error state */\n  clearError: () => void;\n}\n\n/**\n * Hook that wraps a callback with error handling\n *\n * @example\n * ```tsx\n * function DeleteButton({ onDelete }: { onDelete: () => Promise<void> }) {\n *   const { execute, error, clearError } = useSafeCallback(onDelete, {\n *     onError: (err) => console.error('Delete failed:', err),\n *     reportError: true\n *   });\n *\n *   return (\n *     <>\n *       <button onClick={execute}>Delete</button>\n *       {error && <p>Error: {error.message}</p>}\n *     </>\n *   );\n * }\n * ```\n */\nexport function useSafeCallback<Args extends unknown[], Return>(\n  callback: (...args: Args) => Return | Promise<Return>,\n  options: {\n    /** Callback on error */\n    onError?: (error: AppError) => void;\n    /** Fallback return value on error */\n    fallbackValue?: Return;\n    /** Whether to report errors */\n    reportError?: boolean;\n  } = {}\n): SafeCallbackResult<Args, Return> {\n  const { onError, fallbackValue, reportError = true } = options;\n  const [error, setError] = useState<AppError | null>(null);\n\n  const execute = useCallback(\n    async (...args: Args): Promise<Return | undefined> => {\n      setError(null);\n\n      try {\n\n        return await callback(...args);\n      } catch (err) {\n        const appError = normalizeError(err);\n        setError(appError);\n        onError?.(appError);\n\n        if (reportError) {\n          ErrorReporter.reportError(err, {\n            action: 'safe_callback_error',\n          });\n        }\n\n        return fallbackValue;\n      }\n    },\n    [callback, onError, fallbackValue, reportError]\n  );\n\n  const clearError = useCallback(() => setError(null), []);\n\n  return {\n    execute,\n    error,\n    clearError,\n  };\n}\n\n// ============================================================================\n// useErrorToast\n// ============================================================================\n\n/**\n * Toast error entry\n */\nexport interface ToastEntry {\n  id: string;\n  error: AppError;\n}\n\n/**\n * Result of error toast hook\n */\nexport interface ErrorToastResult {\n  /** Current toast entries */\n  toasts: ToastEntry[];\n  /** Show error toast */\n  showError: (error: unknown) => void;\n  /** Dismiss specific toast */\n  dismissToast: (id: string) => void;\n  /** Clear all toasts */\n  clearAll: () => void;\n}\n\n/**\n * Hook for managing error toasts with auto-dismiss\n *\n * @example\n * ```tsx\n * function App() {\n *   const { toasts, showError, dismissToast } = useErrorToast({\n *     duration: 5000,\n *     maxToasts: 3\n *   });\n *\n *   return (\n *     <>\n *       <ErrorToastContainer>\n *         {toasts.map(t => (\n *           <Toast key={t.id} error={t.error} onDismiss={() => dismissToast(t.id)} />\n *         ))}\n *       </ErrorToastContainer>\n *       {// Pass showError to child components //}\n *     </>\n *   );\n * }\n * ```\n */\nexport function useErrorToast(\n  options: {\n    /** Auto-dismiss duration in ms */\n    duration?: number;\n    /** Maximum toasts to show */\n    maxToasts?: number;\n  } = {}\n): ErrorToastResult {\n  const { duration = 5000, maxToasts = 3 } = options;\n  const [toasts, setToasts] = useState<ToastEntry[]>([]);\n\n  const showError = useCallback(\n    (error: unknown) => {\n      const appError = normalizeError(error);\n      const id = `toast_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n\n      setToasts((prev) => {\n        const newToasts = [...prev, { id, error: appError }];\n        // Limit to maxToasts\n        return newToasts.slice(-maxToasts);\n      });\n\n      // Auto-dismiss\n      setTimeout(() => {\n        setToasts((prev) => prev.filter((t) => t.id !== id));\n      }, duration);\n    },\n    [duration, maxToasts]\n  );\n\n  const dismissToast = useCallback((id: string) => {\n    setToasts((prev) => prev.filter((t) => t.id !== id));\n  }, []);\n\n  const clearAll = useCallback(() => {\n    setToasts([]);\n  }, []);\n\n  return {\n    toasts,\n    showError,\n    dismissToast,\n    clearAll,\n  };\n}\n\n// ============================================================================\n// useRecoveryState\n// ============================================================================\n\n/**\n * Recovery state for component error handling\n */\nexport interface RecoveryState {\n  /** Current error if any */\n  error: AppError | null;\n  /** Number of recovery attempts */\n  recoveryAttempts: number;\n  /** Whether currently recovering */\n  isRecovering: boolean;\n  /** Set error state */\n  setError: (error: unknown) => void;\n  /** Clear error state */\n  clearError: () => void;\n  /** Attempt recovery */\n  attemptRecovery: (recoveryFn: () => Promise<void>) => Promise<boolean>;\n  /** Reset all state */\n  reset: () => void;\n}\n\n/**\n * Hook for managing component-level error recovery state\n *\n * @example\n * ```tsx\n * function DataFetcher() {\n *   const recovery = useRecoveryState({ maxAttempts: 3 });\n *\n *   useEffect(() => {\n *     fetchData().catch(recovery.setError);\n *   }, []);\n *\n *   if (recovery.error) {\n *     return (\n *       <ErrorDisplay\n *         error={recovery.error}\n *         onRetry={() => recovery.attemptRecovery(() => fetchData())}\n *         isRetrying={recovery.isRecovering}\n *       />\n *     );\n *   }\n *\n *   return <DataDisplay />;\n * }\n * ```\n */\nexport function useRecoveryState(\n  options: {\n    /** Maximum recovery attempts */\n    maxAttempts?: number;\n    /** Callback when max attempts reached */\n    onMaxAttemptsReached?: (error: AppError) => void;\n  } = {}\n): RecoveryState {\n  const { maxAttempts = 3, onMaxAttemptsReached } = options;\n\n  const [error, setErrorState] = useState<AppError | null>(null);\n  const [recoveryAttempts, setRecoveryAttempts] = useState(0);\n  const [isRecovering, setIsRecovering] = useState(false);\n\n  const setError = useCallback((err: unknown) => {\n    setErrorState(normalizeError(err));\n  }, []);\n\n  const clearError = useCallback(() => {\n    setErrorState(null);\n  }, []);\n\n  const attemptRecovery = useCallback(\n    async (recoveryFn: () => Promise<void>): Promise<boolean> => {\n      if (recoveryAttempts >= maxAttempts) {\n        if (error) {\n          onMaxAttemptsReached?.(error);\n        }\n        return false;\n      }\n\n      setIsRecovering(true);\n      setRecoveryAttempts((prev) => prev + 1);\n\n      try {\n        await recoveryFn();\n        setErrorState(null);\n        setRecoveryAttempts(0);\n        return true;\n      } catch (err) {\n        const appError = normalizeError(err);\n        setErrorState(appError);\n\n        if (recoveryAttempts + 1 >= maxAttempts) {\n          onMaxAttemptsReached?.(appError);\n        }\n\n        return false;\n      } finally {\n        setIsRecovering(false);\n      }\n    },\n    [error, recoveryAttempts, maxAttempts, onMaxAttemptsReached]\n  );\n\n  const reset = useCallback(() => {\n    setErrorState(null);\n    setRecoveryAttempts(0);\n    setIsRecovering(false);\n  }, []);\n\n  return {\n    error,\n    recoveryAttempts,\n    isRecovering,\n    setError,\n    clearError,\n    attemptRecovery,\n    reset,\n  };\n}\n\n// ============================================================================\n// useErrorContext\n// ============================================================================\n\n/**\n * Contextual error information for better UX\n */\nexport interface ErrorContext {\n  /** User action that triggered the error */\n  action: string;\n  /** Resource being accessed */\n  resource?: string;\n  /** Feature name */\n  feature?: string;\n}\n\n/**\n * Hook for managing contextual error information\n *\n * @example\n * ```tsx\n * function UserEditor() {\n *   const errorContext = useErrorContext({\n *     action: 'update profile',\n *     resource: 'user settings',\n *     feature: 'Profile'\n *   });\n *\n *   const handleSave = async () => {\n *     try {\n *       await saveProfile();\n *     } catch (err) {\n *       // Error will have context attached\n *       errorContext.reportError(err);\n *     }\n *   };\n *\n *   return <Form onSubmit={handleSave} />;\n * }\n * ```\n */\nexport function useErrorContext(context: ErrorContext): {\n  context: ErrorContext;\n  reportError: (error: unknown) => void;\n  createContextualError: (error: unknown) => AppError;\n} {\n  const contextRef = useRef(context);\n  // eslint-disable-next-line react-hooks/refs\n  contextRef.current = context;\n\n  const reportError = useCallback((error: unknown) => {\n    ErrorReporter.reportError(error, {\n      action: contextRef.current.action,\n      metadata: {\n        resource: contextRef.current.resource,\n        feature: contextRef.current.feature,\n      },\n    });\n  }, []);\n\n  const createContextualError = useCallback((error: unknown): AppError => {\n    const appError = normalizeError(error);\n    return {\n      ...appError,\n      context: {\n        ...contextRef.current,\n      },\n    } as AppError;\n  }, []);\n\n  return {\n    context,\n    reportError,\n    createContextualError,\n  };\n}\n"],"names":["useAsyncWithRecovery","asyncFn","options","maxRetries","retryDelay","autoRetry","executeOnMount","onError","onSuccess","onRetry","state","setState","useState","isMounted","useIsMounted","retryTimeoutRef","useRef","retryCountRef","executeRef","useEffect","execute","useCallback","prev","result","err","appError","normalizeError","newRetryCount","isRetryableError","delay","retry","reset","useNetworkAwareOperation","operation","requiresNetwork","waitForOnline","onlineTimeout","isOnline","setIsOnline","networkMonitor","isWaiting","setIsWaiting","error","setError","status","online","offlineError","useOptimisticUpdate","currentValue","updateFn","value","setValue","isPending","setIsPending","originalValueRef","update","optimisticValue","updateData","original","ErrorReporter","useSafeCallback","callback","fallbackValue","reportError","args","clearError","useErrorToast","duration","maxToasts","toasts","setToasts","showError","id","t","dismissToast","clearAll","useRecoveryState","maxAttempts","onMaxAttemptsReached","setErrorState","recoveryAttempts","setRecoveryAttempts","isRecovering","setIsRecovering","attemptRecovery","recoveryFn","useErrorContext","context","contextRef","createContextualError"],"mappings":"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"}