{"version":3,"file":"useApiCache.mjs","sources":["../../../../src/lib/api/hooks/useApiCache.ts"],"sourcesContent":["/**\n * @file useApiCache Hook\n * @description React hook for managing API response caching with utilities for\n * reading, updating, invalidating, and monitoring cache state.\n *\n * @example\n * ```typescript\n * import { useApiCache } from '@/lib/api';\n *\n * function CacheManager() {\n *   const {\n *     getData,\n *     setData,\n *     invalidate,\n *     invalidateAll,\n *     getStats,\n *   } = useApiCache();\n *\n *   // Get cached data\n *   const users = getData<User[]>(['users', 'list']);\n *\n *   // Update cache\n *   setData(['users', '123'], { ...user, name: 'Updated' });\n *\n *   // Invalidate specific queries\n *   await invalidate(['users']);\n *\n *   return <div>Cache entries: {getStats().queries}</div>;\n * }\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { type Query, type QueryKey, type QueryState, useQueryClient } from '@tanstack/react-query';\nimport type { CacheStats } from '../types';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Cache query filter options\n */\nexport interface CacheFilterOptions {\n  /** Match exact query key */\n  exact?: boolean;\n  /** Filter by query type */\n  type?: 'active' | 'inactive' | 'all';\n  /** Filter stale queries */\n  stale?: boolean;\n  /** Filter fetching queries */\n  fetching?: boolean;\n  /** Custom predicate */\n  predicate?: (query: Query) => boolean;\n}\n\n/**\n * Cache entry info for inspection\n */\nexport interface CacheEntryInfo<TData = unknown> {\n  queryKey: QueryKey;\n  data: TData | undefined;\n  state: QueryState<TData>;\n  isStale: boolean;\n  isFetching: boolean;\n  dataUpdatedAt: number;\n  errorUpdatedAt: number;\n  fetchStatus: 'fetching' | 'paused' | 'idle';\n}\n\n/**\n * Return type for useApiCache\n */\nexport interface UseApiCacheResult {\n  /** Get cached data for a query key */\n  getData: <TData = unknown>(queryKey: QueryKey) => TData | undefined;\n\n  /** Set cached data for a query key */\n  setData: <TData = unknown>(\n    queryKey: QueryKey,\n    updater: TData | ((old: TData | undefined) => TData)\n  ) => TData | undefined;\n\n  /** Remove cached data for a query key */\n  removeData: (queryKey: QueryKey) => void;\n\n  /** Invalidate queries matching the key */\n  invalidate: (queryKey: QueryKey, options?: { exact?: boolean }) => Promise<void>;\n\n  /** Invalidate all queries */\n  invalidateAll: () => Promise<void>;\n\n  /** Refetch queries matching the key */\n  refetch: (queryKey: QueryKey, options?: { exact?: boolean }) => Promise<void>;\n\n  /** Cancel in-flight queries */\n  cancel: (queryKey: QueryKey) => Promise<void>;\n\n  /** Reset queries to initial state */\n  reset: (queryKey: QueryKey) => Promise<void>;\n\n  /** Prefetch a query */\n  prefetch: <TData = unknown>(\n    queryKey: QueryKey,\n    queryFn: () => Promise<TData>,\n    options?: { staleTime?: number }\n  ) => Promise<void>;\n\n  /** Get cache statistics */\n  getStats: () => CacheStats;\n\n  /** Get cache entry info */\n  getEntry: <TData = unknown>(queryKey: QueryKey) => CacheEntryInfo<TData> | null;\n\n  /** Get all cache entries matching filter */\n  getEntries: <TData = unknown>(filter?: CacheFilterOptions) => CacheEntryInfo<TData>[];\n\n  /** Check if query exists in cache */\n  hasQuery: (queryKey: QueryKey) => boolean;\n\n  /** Check if query is stale */\n  isStale: (queryKey: QueryKey) => boolean;\n\n  /** Check if query is fetching */\n  isFetching: (queryKey: QueryKey) => boolean;\n\n  /** Clear entire cache */\n  clear: () => void;\n\n  /** Subscribe to cache changes */\n  subscribe: (callback: () => void) => () => void;\n}\n\n// =============================================================================\n// HOOK IMPLEMENTATION\n// =============================================================================\n\n/**\n * Hook for managing API response cache\n *\n * @returns Cache management utilities\n *\n * @example\n * ```typescript\n * function UserList() {\n *   const { getData, setData, invalidate } = useApiCache();\n *\n *   // Read from cache\n *   const cachedUsers = getData<User[]>(['users', 'list']);\n *\n *   // Optimistically update cache\n *   const handleOptimisticUpdate = (userId: string, updates: Partial<User>) => {\n *     setData<User[]>(['users', 'list'], (users) =>\n *       users?.map(u => u.id === userId ? { ...u, ...updates } : u) ?? []\n *     );\n *   };\n *\n *   // Invalidate after mutation\n *   const handleMutationSuccess = async () => {\n *     await invalidate(['users']);\n *   };\n *\n *   return <div>...</div>;\n * }\n * ```\n */\nexport function useApiCache(): UseApiCacheResult {\n  const queryClient = useQueryClient();\n\n  // Get cached data\n  const getData = useCallback(\n    <TData = unknown>(queryKey: QueryKey): TData | undefined => {\n      return queryClient.getQueryData<TData>(queryKey);\n    },\n    [queryClient]\n  );\n\n  // Set cached data\n  const setData = useCallback(\n    <TData = unknown>(\n      queryKey: QueryKey,\n      updater: TData | ((old: TData | undefined) => TData)\n    ): TData | undefined => {\n      return queryClient.setQueryData<TData>(queryKey, updater);\n    },\n    [queryClient]\n  );\n\n  // Remove cached data\n  const removeData = useCallback(\n    (queryKey: QueryKey): void => {\n      queryClient.removeQueries({ queryKey });\n    },\n    [queryClient]\n  );\n\n  // Invalidate queries\n  const invalidate = useCallback(\n    async (queryKey: QueryKey, options?: { exact?: boolean }): Promise<void> => {\n      await queryClient.invalidateQueries({\n        queryKey,\n        exact: options?.exact,\n      });\n    },\n    [queryClient]\n  );\n\n  // Invalidate all queries\n  const invalidateAll = useCallback(async (): Promise<void> => {\n    await queryClient.invalidateQueries();\n  }, [queryClient]);\n\n  // Refetch queries\n  const refetch = useCallback(\n    async (queryKey: QueryKey, options?: { exact?: boolean }): Promise<void> => {\n      await queryClient.refetchQueries({\n        queryKey,\n        exact: options?.exact,\n      });\n    },\n    [queryClient]\n  );\n\n  // Cancel queries\n  const cancel = useCallback(\n    async (queryKey: QueryKey): Promise<void> => {\n      await queryClient.cancelQueries({ queryKey });\n    },\n    [queryClient]\n  );\n\n  // Reset queries\n  const reset = useCallback(\n    async (queryKey: QueryKey): Promise<void> => {\n      await queryClient.resetQueries({ queryKey });\n    },\n    [queryClient]\n  );\n\n  // Prefetch query\n  const prefetch = useCallback(\n    async <TData = unknown>(\n      queryKey: QueryKey,\n      queryFn: () => Promise<TData>,\n      options?: { staleTime?: number }\n    ): Promise<void> => {\n      await queryClient.prefetchQuery({\n        queryKey,\n        queryFn,\n        staleTime: options?.staleTime,\n      });\n    },\n    [queryClient]\n  );\n\n  // Get cache statistics\n  const getStats = useCallback((): CacheStats => {\n    const cache = queryClient.getQueryCache();\n    const queries = cache.getAll();\n\n    let hits = 0;\n    let misses = 0;\n    let totalSize = 0;\n\n    for (const query of queries) {\n      const { state } = query;\n      if (state.data !== undefined) {\n        hits++;\n        // Estimate size (rough approximation)\n        try {\n          totalSize += JSON.stringify(state.data).length * 2; // UTF-16\n        } catch {\n          // Skip circular references\n        }\n      } else {\n        misses++;\n      }\n    }\n\n    return {\n      entries: queries.length,\n      size: totalSize,\n      hits,\n      misses,\n      hitRate: queries.length > 0 ? hits / queries.length : 0,\n      evictions: 0, // Not tracked by React Query\n    };\n  }, [queryClient]);\n\n  // Get cache entry info\n  const getEntry = useCallback(\n    <TData = unknown>(queryKey: QueryKey): CacheEntryInfo<TData> | null => {\n      const query = queryClient.getQueryCache().find({ queryKey });\n\n      if (!query) return null;\n\n      const state = query.state as QueryState<TData>;\n\n      return {\n        queryKey: query.queryKey,\n        data: state.data,\n        state,\n        isStale: query.isStale(),\n        isFetching: query.state.fetchStatus === 'fetching',\n        dataUpdatedAt: state.dataUpdatedAt,\n        errorUpdatedAt: state.errorUpdatedAt,\n        fetchStatus: state.fetchStatus,\n      };\n    },\n    [queryClient]\n  );\n\n  // Get all cache entries\n  const getEntries = useCallback(\n    <TData = unknown>(filter?: CacheFilterOptions): CacheEntryInfo<TData>[] => {\n      const cache = queryClient.getQueryCache();\n      let queries = cache.getAll();\n\n      // Apply filters\n      if (filter) {\n        if (filter.type === 'active') {\n          queries = queries.filter((q) => q.isActive());\n        } else if (filter.type === 'inactive') {\n          queries = queries.filter((q) => !q.isActive());\n        }\n\n        if (filter.stale !== undefined) {\n          queries = queries.filter((q) => q.isStale() === filter.stale);\n        }\n\n        if (filter.fetching !== undefined) {\n          queries = queries.filter((q) => (q.state.fetchStatus === 'fetching') === filter.fetching);\n        }\n\n        if (filter.predicate) {\n          queries = queries.filter(filter.predicate);\n        }\n      }\n\n      return queries.map((query) => {\n        const state = query.state as QueryState<TData>;\n        return {\n          queryKey: query.queryKey,\n          data: state.data,\n          state,\n          isStale: query.isStale(),\n          isFetching: query.state.fetchStatus === 'fetching',\n          dataUpdatedAt: state.dataUpdatedAt,\n          errorUpdatedAt: state.errorUpdatedAt,\n          fetchStatus: state.fetchStatus,\n        };\n      });\n    },\n    [queryClient]\n  );\n\n  // Check if query exists\n  const hasQuery = useCallback(\n    (queryKey: QueryKey): boolean => {\n      return queryClient.getQueryCache().find({ queryKey }) !== undefined;\n    },\n    [queryClient]\n  );\n\n  // Check if query is stale\n  const isStale = useCallback(\n    (queryKey: QueryKey): boolean => {\n      const query = queryClient.getQueryCache().find({ queryKey });\n      return query?.isStale() ?? true;\n    },\n    [queryClient]\n  );\n\n  // Check if query is fetching\n  const isFetching = useCallback(\n    (queryKey: QueryKey): boolean => {\n      return queryClient.isFetching({ queryKey }) > 0;\n    },\n    [queryClient]\n  );\n\n  // Clear cache\n  const clear = useCallback((): void => {\n    queryClient.clear();\n  }, [queryClient]);\n\n  // Subscribe to cache changes\n  const subscribe = useCallback(\n    (callback: () => void): (() => void) => {\n      return queryClient.getQueryCache().subscribe(callback);\n    },\n    [queryClient]\n  );\n\n  return useMemo(\n    () => ({\n      getData,\n      setData,\n      removeData,\n      invalidate,\n      invalidateAll,\n      refetch,\n      cancel,\n      reset,\n      prefetch,\n      getStats,\n      getEntry,\n      getEntries,\n      hasQuery,\n      isStale,\n      isFetching,\n      clear,\n      subscribe,\n    }),\n    [\n      getData,\n      setData,\n      removeData,\n      invalidate,\n      invalidateAll,\n      refetch,\n      cancel,\n      reset,\n      prefetch,\n      getStats,\n      getEntry,\n      getEntries,\n      hasQuery,\n      isStale,\n      isFetching,\n      clear,\n      subscribe,\n    ]\n  );\n}\n\n// =============================================================================\n// SPECIALIZED HOOKS\n// =============================================================================\n\n/**\n * Hook for monitoring cache statistics\n *\n * @example\n * ```typescript\n * function CacheMonitor() {\n *   const { stats, isMonitoring, startMonitoring, stopMonitoring } = useCacheMonitor({\n *     interval: 5000,\n *     autoStart: true,\n *   });\n *\n *   return (\n *     <div>\n *       <p>Entries: {stats.entries}</p>\n *       <p>Hit Rate: {(stats.hitRate * 100).toFixed(1)}%</p>\n *       <p>Size: {(stats.size / 1024).toFixed(1)} KB</p>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useCacheMonitor(options?: { interval?: number; autoStart?: boolean }): {\n  stats: CacheStats;\n  isMonitoring: boolean;\n  startMonitoring: () => void;\n  stopMonitoring: () => void;\n  refresh: () => void;\n} {\n  const { getStats, subscribe } = useApiCache();\n  const [stats, setStats] = useState<CacheStats>(getStats);\n  const [isMonitoring, setIsMonitoring] = useState(options?.autoStart ?? false);\n\n  const refresh = useCallback(() => {\n    setStats(getStats());\n  }, [getStats]);\n\n  const startMonitoring = useCallback(() => {\n    setIsMonitoring(true);\n  }, []);\n\n  const stopMonitoring = useCallback(() => {\n    setIsMonitoring(false);\n  }, []);\n\n  // Subscribe to cache changes\n  useEffect(() => {\n    if (isMonitoring) {\n      return subscribe(refresh);\n    }\n    return undefined;\n  }, [isMonitoring, subscribe, refresh]);\n\n  // Polling interval\n  useEffect(() => {\n    if (\n      isMonitoring &&\n      options?.interval !== undefined &&\n      options.interval !== null &&\n      options.interval > 0\n    ) {\n      const timer = setInterval(refresh, options.interval);\n      return () => clearInterval(timer);\n    }\n    return undefined;\n  }, [isMonitoring, options?.interval, refresh]);\n\n  return {\n    stats,\n    isMonitoring,\n    startMonitoring,\n    stopMonitoring,\n    refresh,\n  };\n}\n\n/**\n * Hook for watching specific cache entries\n *\n * @example\n * ```typescript\n * function UserCacheWatcher({ userId }: { userId: string }) {\n *   const { entry, isLoaded, isStale } = useCacheEntry<User>(['users', userId]);\n *\n *   if (!isLoaded) return <p>Not in cache</p>;\n *   if (isStale) return <p>Data is stale</p>;\n *\n *   return <p>User: {entry.data?.name}</p>;\n * }\n * ```\n */\nexport function useCacheEntry<TData = unknown>(\n  queryKey: QueryKey\n): {\n  entry: CacheEntryInfo<TData> | null;\n  isLoaded: boolean;\n  isStale: boolean;\n  isFetching: boolean;\n  refresh: () => void;\n} {\n  const { getEntry, subscribe } = useApiCache();\n  const [entry, setEntry] = useState<CacheEntryInfo<TData> | null>(() => getEntry<TData>(queryKey));\n\n  const refresh = useCallback(() => {\n    setEntry(getEntry<TData>(queryKey));\n  }, [getEntry, queryKey]);\n\n  // Subscribe to changes\n  useEffect(() => {\n    return subscribe(refresh);\n  }, [subscribe, refresh]);\n\n  // Update when query key changes\n  const serializedKey = JSON.stringify(queryKey);\n  useEffect(() => {\n    // Refresh is intentionally called here to update cache entry when query key changes\n    // eslint-disable-next-line react-hooks/set-state-in-effect\n    refresh();\n  }, [refresh, serializedKey]);\n\n  return {\n    entry,\n    isLoaded: entry?.data !== undefined,\n    isStale: entry?.isStale ?? true,\n    isFetching: entry?.isFetching ?? false,\n    refresh,\n  };\n}\n\n/**\n * Hook for bulk cache operations\n *\n * @example\n * ```typescript\n * function BulkCacheOperations() {\n *   const { invalidateByTag, removeByPredicate } = useBulkCacheOperations();\n *\n *   const handleLogout = async () => {\n *     // Invalidate all user-related queries\n *     await invalidateByTag('user');\n *   };\n *\n *   const handleClearStale = () => {\n *     removeByPredicate((query) => query.isStale());\n *   };\n *\n *   return <div>...</div>;\n * }\n * ```\n */\nexport function useBulkCacheOperations(): {\n  invalidateByTag: (tag: string) => Promise<void>;\n  invalidateByPrefix: (prefix: string) => Promise<void>;\n  removeByPredicate: (predicate: (query: Query) => boolean) => void;\n  refetchActive: () => Promise<void>;\n  refetchStale: () => Promise<void>;\n} {\n  const queryClient = useQueryClient();\n\n  const invalidateByTag = useCallback(\n    async (tag: string): Promise<void> => {\n      await queryClient.invalidateQueries({\n        predicate: (query) => {\n          const { meta } = query;\n          const tags = meta?.tags as string[] | undefined;\n          return Boolean(meta?.tag === tag || tags?.includes(tag));\n        },\n      });\n    },\n    [queryClient]\n  );\n\n  const invalidateByPrefix = useCallback(\n    async (prefix: string): Promise<void> => {\n      await queryClient.invalidateQueries({\n        predicate: (query) => {\n          const [firstKey] = query.queryKey;\n          return typeof firstKey === 'string' && firstKey.startsWith(prefix);\n        },\n      });\n    },\n    [queryClient]\n  );\n\n  const removeByPredicate = useCallback(\n    (predicate: (query: Query) => boolean): void => {\n      queryClient.removeQueries({ predicate });\n    },\n    [queryClient]\n  );\n\n  const refetchActive = useCallback(async (): Promise<void> => {\n    await queryClient.refetchQueries({ type: 'active' });\n  }, [queryClient]);\n\n  const refetchStale = useCallback(async (): Promise<void> => {\n    await queryClient.refetchQueries({ stale: true });\n  }, [queryClient]);\n\n  return {\n    invalidateByTag,\n    invalidateByPrefix,\n    removeByPredicate,\n    refetchActive,\n    refetchStale,\n  };\n}\n"],"names":["useApiCache","queryClient","useQueryClient","getData","useCallback","queryKey","setData","updater","removeData","invalidate","options","invalidateAll","refetch","cancel","reset","prefetch","queryFn","getStats","queries","hits","misses","totalSize","query","state","getEntry","getEntries","filter","q","hasQuery","isStale","isFetching","clear","subscribe","callback","useMemo","useCacheMonitor","stats","setStats","useState","isMonitoring","setIsMonitoring","refresh","startMonitoring","stopMonitoring","useEffect","timer","useCacheEntry","entry","setEntry","serializedKey","useBulkCacheOperations","invalidateByTag","tag","meta","tags","invalidateByPrefix","prefix","firstKey","removeByPredicate","predicate","refetchActive","refetchStale"],"mappings":"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"}