use-fetch-smart
Version:
A smart React data-fetching hook with caching, retries, TTL, schema validation, and automatic token refresh.
1 lines • 46.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/useGetSmart.ts","../src/FetchSmartProvider.tsx","../src/smartAxios.ts","../src/cache/memoryCache.ts","../src/cache/indexedDBCache.ts","../src/cache/cacheDriver.ts","../src/utils/formatSchemaError.ts","../src/utils/validateWithSchema.ts","../src/prefetchSmart.ts","../src/utils/smartDedupe.ts","../src/usePostSmart.ts","../src/usePutSmart.ts","../src/useDeleteSmart.ts","../src/FetchSmartDevtools.tsx"],"sourcesContent":["// Hooks\r\nexport * from \"./useGetSmart\";\r\nexport * from \"./usePostSmart\";\r\nexport * from \"./usePutSmart\";\r\nexport * from \"./useDeleteSmart\";\r\n\r\n// Provider\r\nexport * from \"./FetchSmartProvider\";\r\n\r\n// Devtools\r\nexport * from \"./FetchSmartDevtools\";\r\n\r\n// Core utils\r\nexport * from \"./smartAxios\";\r\n\r\n// Types\r\nexport * from \"./types\"; \r\n","import { useEffect, useRef, useState } from \"react\";\r\nimport { useFetchSmartContext } from \"./FetchSmartProvider\";\r\nimport { cacheDriver } from \"./cache/cacheDriver\";\r\nimport { validateWithSchema } from \"./utils/validateWithSchema\";\r\nimport { SchemaMode, SchemaValidator } from \"./types\";\r\nimport { prefetchSmart } from \"./prefetchSmart\";\r\nimport { inFlightRequests } from \"./utils/smartDedupe\";\r\n\r\n\r\nexport function useGetSmart<T = any>(\r\n url: string,\r\n opts?: {\r\n cacheTimeMs?: number;\r\n persist?: boolean;\r\n swr?: boolean;\r\n schema?: SchemaValidator<T>;\r\n schemaMode?: SchemaMode;\r\n prefetchNext?: (\r\n data: T,\r\n ctx: { url: string }\r\n ) => Array<{\r\n url: string;\r\n schema?: SchemaValidator<any>;\r\n schemaMode?: SchemaMode;\r\n ttlMs?: number;\r\n persist?: boolean;\r\n }>;\r\n }\r\n) {\r\n const { axiosInstance: api } = useFetchSmartContext();\r\n\r\n const cacheKey = url;\r\n\r\n const ttlMs = opts?.cacheTimeMs ?? 0;\r\n\r\n const [data, setData] = useState<T | null>(null);\r\n const [loading, setLoading] = useState(!data);\r\n const [error, setError] = useState<any>(null);\r\n const swr = opts?.swr ?? false;\r\n const didRun = useRef(false);\r\n const abortRef = useRef<AbortController | null>(null);\r\n\r\n const mountedRef = useRef(true);\r\n\r\n useEffect(() => {\r\n return () => {\r\n mountedRef.current = false;\r\n abortRef.current?.abort();\r\n };\r\n }, []);\r\n\r\n useEffect(() => {\r\n fetchData();\r\n return () => abortRef.current?.abort();\r\n }, [url]);\r\n\r\n const fetchData = async () => {\r\n try {\r\n setLoading(true);\r\n setError(null);\r\n\r\n abortRef.current?.abort();\r\n const controller = new AbortController();\r\n abortRef.current = controller;\r\n\r\n let requestPromise: Promise<any>;\r\n\r\n\r\n if (inFlightRequests.has(url)) {\r\n\r\n requestPromise = inFlightRequests.get(url)!;\r\n } else {\r\n\r\n requestPromise = api.get(url, { signal: controller.signal });\r\n inFlightRequests.set(url, requestPromise);\r\n }\r\n\r\n const res = await requestPromise;\r\n\r\n\r\n if (inFlightRequests.get(url) === requestPromise) {\r\n inFlightRequests.delete(url);\r\n }\r\n\r\n const validated = validateWithSchema(res.data, opts?.schema, \"error\", url);\r\n setData(validated);\r\n await cacheDriver.set(cacheKey, validated);\r\n\r\n } catch (err) {\r\n inFlightRequests.delete(url);\r\n setError(err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n\r\n const revalidate = async () => {\r\n try {\r\n setLoading(true);\r\n abortRef.current?.abort();\r\n const controller = new AbortController();\r\n abortRef.current = controller;\r\n\r\n const signal = controller.signal;\r\n\r\n\r\n let requestPromise: Promise<any>\r\n\r\n if (inFlightRequests.has(url)) {\r\n requestPromise = inFlightRequests.get(url)!;\r\n } else {\r\n requestPromise = api.get<T>(url, { signal });\r\n inFlightRequests.set(url, requestPromise);\r\n }\r\n\r\n\r\n\r\n const res = await requestPromise;\r\n\r\n\r\n if (inFlightRequests.get(url) === requestPromise) {\r\n inFlightRequests.delete(url);\r\n }\r\n\r\n\r\n if (signal.aborted) return;\r\n\r\n\r\n\r\n const validated = validateWithSchema(\r\n res.data,\r\n opts?.schema,\r\n opts?.schemaMode ?? \"error\",\r\n url\r\n );\r\n\r\n setData(validated);\r\n\r\n\r\n await cacheDriver.set(cacheKey, validated, {\r\n ttlMs,\r\n persist: opts?.persist,\r\n });\r\n\r\n\r\n if (opts?.prefetchNext) {\r\n const predictions = opts.prefetchNext(validated, { url });\r\n\r\n predictions?.forEach((p) => {\r\n prefetchSmart<T>(p.url, api, {\r\n ttlMs: p.ttlMs ?? ttlMs,\r\n persist: p.persist ?? opts?.persist,\r\n schema: p.schema ?? opts?.schema,\r\n schemaMode: p.schemaMode ?? opts?.schemaMode,\r\n });\r\n });\r\n }\r\n\r\n\r\n } catch (err) {\r\n inFlightRequests.delete(url);\r\n setError(err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n return { data, loading, error, refetch: revalidate };\r\n}\r\n","import React, { createContext, useContext, useRef } from \"react\";\r\nimport { createSmartAxios, setGlobalToken } from \"./smartAxios\";\r\n\r\nexport interface FetchSmartConfig {\r\n baseURL?: string;\r\n token?: string;\r\n retryLimit?: number;\r\n refreshToken?: () => Promise<string | null>;\r\n}\r\n\r\ninterface FetchSmartContextValue {\r\n axiosInstance: ReturnType<typeof createSmartAxios>;\r\n}\r\n\r\nconst FetchSmartContext = createContext<FetchSmartContextValue | null>(null);\r\n\r\nexport const FetchSmartProvider = ({\r\n config,\r\n children,\r\n}: {\r\n config: FetchSmartConfig;\r\n children: React.ReactNode;\r\n}) => {\r\n\r\n if (config.token) {\r\n setGlobalToken(config.token);\r\n }\r\n\r\n\r\n const axiosRef = useRef(\r\n createSmartAxios(\r\n config.baseURL || \"\",\r\n config.refreshToken, // refresh function\r\n config.retryLimit // retry limit\r\n )\r\n );\r\n\r\n return (\r\n <FetchSmartContext.Provider value={{ axiosInstance: axiosRef.current }}>\r\n {children}\r\n </FetchSmartContext.Provider>\r\n );\r\n};\r\n\r\n\r\nexport const useFetchSmartContext = () => {\r\n const ctx = useContext(FetchSmartContext);\r\n if (!ctx) {\r\n throw new Error(\r\n \"useGetSmart / usePostSmart must be used inside <FetchSmartProvider>\"\r\n );\r\n }\r\n return ctx;\r\n};\r\n","import axios, { AxiosInstance } from \"axios\";\r\n\r\n\r\nlet refreshPromise: Promise<string | null> | null = null;\r\nlet latestToken: string | null = null;\r\n\r\n\r\nexport const setGlobalToken = (token: string | null) => {\r\n latestToken = token;\r\n};\r\n\r\nexport const createSmartAxios = (\r\n baseURL: string,\r\n refreshTokenFn?: () => Promise<string | null>,\r\n retryLimit: number = 3\r\n): AxiosInstance => {\r\n const api = axios.create({ baseURL });\r\n\r\n api.interceptors.request.use((config) => {\r\n if (latestToken) {\r\n config.headers = config.headers || {};\r\n\r\n if (typeof config.headers.set === \"function\") {\r\n config.headers.set(\"Authorization\", `Bearer ${latestToken}`);\r\n } else {\r\n (config.headers as any)[\"Authorization\"] =\r\n `Bearer ${latestToken}`;\r\n }\r\n }\r\n return config;\r\n });\r\n\r\n api.interceptors.response.use(\r\n (res) => res,\r\n async (error) => {\r\n const config = error.config;\r\n if (!config) return Promise.reject(error);\r\n\r\n if (error.response?.status === 401 &&\r\n latestToken\r\n && refreshTokenFn) {\r\n\r\n\r\n if (!refreshPromise) {\r\n refreshPromise = refreshTokenFn();\r\n }\r\n\r\n const newToken = await refreshPromise;\r\n refreshPromise = null;\r\n\r\n if (newToken) {\r\n setGlobalToken(newToken);\r\n\r\n config.headers.Authorization = `Bearer ${newToken}`;\r\n return api(config);\r\n }\r\n }\r\n\r\n config.__retry = config.__retry || 0;\r\n\r\n const shouldRetry =\r\n !error.response ||\r\n (error.response.status >= 500 && error.response.status < 600);\r\n\r\n if (shouldRetry && config.__retry < retryLimit) {\r\n config.__retry++;\r\n\r\n const delay = 500 * Math.pow(2, config.__retry - 1);\r\n await new Promise((resolve) => setTimeout(resolve, delay));\r\n\r\n return api(config);\r\n }\r\n\r\n return Promise.reject(error);\r\n }\r\n );\r\n\r\n return api;\r\n};\r\n","export interface CacheItem<T> {\r\n data: T;\r\n expiry: number | null; // timestamp (ms)\r\n}\r\n\r\nconst memoryStore = new Map<string, CacheItem<any>>();\r\n\r\nexport const memoryCache = {\r\n get<T>(key: string): T | null {\r\n const item = memoryStore.get(key);\r\n if (!item) return null;\r\n\r\n if (item.expiry && Date.now() > item.expiry) {\r\n memoryStore.delete(key);\r\n return null;\r\n }\r\n\r\n return item.data;\r\n },\r\n\r\n set<T>(key: string, data: T, ttlMs?: number) {\r\n const expiry = ttlMs ? Date.now() + ttlMs : null;\r\n memoryStore.set(key, { data, expiry });\r\n },\r\n\r\n delete(key: string) {\r\n memoryStore.delete(key);\r\n },\r\n\r\n clear() {\r\n memoryStore.clear();\r\n },\r\n keys() {\r\n return Array.from(memoryStore.keys());\r\n },\r\n\r\n\r\n dump() {\r\n return Array.from(memoryStore.entries()).map(([key, item]) => ({\r\n key,\r\n data: item.data,\r\n expiry: item.expiry,\r\n }));\r\n }\r\n};\r\n","import { get, set, del, keys, clear } from \"idb-keyval\";\r\n\r\nexport interface CacheItem<T> {\r\n data: T;\r\n expiry: number | null;\r\n}\r\nconst isDev = (() => {\r\n const env = (globalThis as any)?.process?.env?.NODE_ENV;\r\n return env !== \"production\";\r\n})();\r\n\r\nexport const indexedDBCache = {\r\n async get<T>(key: string): Promise<T | null> {\r\n try {\r\n const item = (await get(key)) as CacheItem<T> | undefined;\r\n if (!item) return null;\r\n\r\n if (item.expiry && Date.now() > item.expiry) {\r\n await del(key);\r\n return null;\r\n }\r\n\r\n return item.data;\r\n } catch (err) {\r\n if (isDev) console.error(\"IndexedDB get error\", err);\r\n return null;\r\n }\r\n },\r\n\r\n async set<T>(key: string, data: T, ttlMs?: number) {\r\n const expiry = ttlMs ? Date.now() + ttlMs : null;\r\n try {\r\n await set(key, { data, expiry } as CacheItem<T>);\r\n } catch (err) {\r\n if (isDev) console.error(\"IndexedDB set error\", err);\r\n }\r\n },\r\n\r\n async delete(key: string) {\r\n try {\r\n await del(key);\r\n } catch (err) {\r\n if (isDev) console.error(\"IndexedDB delete error\", err);\r\n }\r\n },\r\n\r\n\r\n async keys(): Promise<string[]> {\r\n try {\r\n return await keys();\r\n } catch (err) {\r\n if (isDev) console.error(\"IndexedDB keys error\", err);\r\n return [];\r\n }\r\n },\r\n\r\n async dump(): Promise<any[]> {\r\n try {\r\n const allKeys = await keys();\r\n const output: any[] = [];\r\n\r\n for (const k of allKeys) {\r\n const item = (await get(k)) as CacheItem<any>;\r\n if (!item) continue;\r\n\r\n output.push({\r\n key: k,\r\n data: item.data,\r\n expiry: item.expiry,\r\n });\r\n }\r\n\r\n return output;\r\n } catch (err) {\r\n if (isDev) console.error(\"IndexedDB dump error\", err);\r\n return [];\r\n }\r\n },\r\n clear: async () => {\r\n try {\r\n await clear();\r\n } catch (err) {\r\n if (isDev) console.error(\"IndexedDB clear error\", err);\r\n }\r\n },\r\n};\r\n","import { memoryCache } from \"./memoryCache\";\r\nimport { indexedDBCache } from \"./indexedDBCache\";\r\n\r\nexport type CacheMode = \"memory\" | \"indexeddb\";\r\n\r\nexport interface CacheOptions {\r\n ttlMs?: number;\r\n persist?: boolean;\r\n}\r\n\r\nexport const cacheDriver = {\r\n async get<T>(key: string, persist?: boolean): Promise<T | null> {\r\n if (persist) {\r\n\r\n const data = await indexedDBCache.get<T>(key);\r\n if (data !== null) return data;\r\n }\r\n\r\n return memoryCache.get<T>(key);\r\n },\r\n\r\n async set<T>(key: string, data: T, opts?: CacheOptions) {\r\n const ttlMs = opts?.ttlMs;\r\n\r\n memoryCache.set(key, data, ttlMs);\r\n\r\n if (opts?.persist) {\r\n await indexedDBCache.set(key, data, ttlMs);\r\n }\r\n },\r\n\r\n async delete(key: string) {\r\n memoryCache.delete(key);\r\n await indexedDBCache.delete(key);\r\n },\r\n\r\n async clear() {\r\n memoryCache.clear();\r\n\r\n },\r\n\r\n};\r\n","export function formatSchemaError(err: any, endpoint: string) {\r\n let msg = `Schema validation failed for response at \"${endpoint}\":\\n`;\r\n\r\n const issues = err?.issues || err?.errors || err?.inner;\r\n\r\n if (Array.isArray(issues)) {\r\n issues.forEach((issue: any) => {\r\n const pathArray = issue.path ?? [];\r\n const path =\r\n pathArray.length > 0\r\n ? \"[\" + pathArray.join(\"].\") + \"]\"\r\n : \"value\";\r\n msg += `- ${path}: ${issue.message}\\n`;\r\n });\r\n } else {\r\n msg += `- ${err?.message || \"Unknown schema validation error\"}`;\r\n }\r\n\r\n return msg.trim();\r\n}\r\n","import { formatSchemaError } from \"./formatSchemaError\";\r\nimport { SchemaValidator, SchemaMode } from \"../types\";\r\n\r\nexport function validateWithSchema<T>(\r\n data: any,\r\n schema?: SchemaValidator<T>,\r\n mode: SchemaMode = \"error\",\r\n endpoint: string = \"\"\r\n): T {\r\n if (!schema) return data;\r\n\r\n try {\r\n return schema.parse(data);\r\n } catch (err: any) {\r\n const formatted = formatSchemaError(err, endpoint);\r\n\r\n if (mode === \"warn\") {\r\n console.warn(\"[use-fetch-smart warn]\\n\" + formatted);\r\n return data;\r\n }\r\n\r\n err.message = formatted;\r\n throw err;\r\n }\r\n}\r\n\r\n","import { cacheDriver } from \"./cache/cacheDriver\";\r\nimport { validateWithSchema } from \"./utils/validateWithSchema\";\r\nimport { SchemaMode, SchemaValidator } from \"./types\";\r\n\r\n\r\nconst inFlightPrefetch = new Map<\r\n string,\r\n { controller: AbortController; promise: Promise<any> }\r\n>();\r\n\r\n\r\nconst prefetchQueue: Array<() => void> = [];\r\n\r\n\r\nconst MAX_PREFETCH_CONCURRENCY = 3;\r\n\r\n\r\nlet activePrefetches = 0;\r\n\r\n\r\nlet lastPrefetchTs = 0;\r\nconst PREFETCH_THROTTLE_MS = 200;\r\n\r\n\r\nconst isSlowNetwork = () => {\r\n const conn = (navigator as any)?.connection?.effectiveType;\r\n return conn === \"2g\" || conn === \"slow-2g\";\r\n};\r\n\r\ninterface PrefetchOptions<T = any> {\r\n ttlMs?: number;\r\n persist?: boolean;\r\n schema?: SchemaValidator<T>;\r\n schemaMode?: SchemaMode;\r\n}\r\n\r\n\r\nfunction schedulePrefetch(run: () => Promise<void>) {\r\n prefetchQueue.push(run);\r\n\r\n const tryRun = () => {\r\n if (activePrefetches >= MAX_PREFETCH_CONCURRENCY) return;\r\n if (prefetchQueue.length === 0) return;\r\n\r\n const task = prefetchQueue.shift();\r\n if (!task) return;\r\n\r\n activePrefetches++;\r\n\r\n task().finally(() => {\r\n activePrefetches--;\r\n tryRun();\r\n });\r\n };\r\n\r\n tryRun();\r\n}\r\n\r\n\r\nexport async function prefetchSmart<T = any>(\r\n url: string,\r\n api: any,\r\n opts?: PrefetchOptions<T>\r\n) {\r\n const cacheKey = url;\r\n\r\n\r\n if (typeof navigator !== \"undefined\" && !navigator.onLine) return;\r\n\r\n\r\n if (isSlowNetwork()) return;\r\n\r\n\r\n if (Date.now() - lastPrefetchTs < PREFETCH_THROTTLE_MS) return;\r\n lastPrefetchTs = Date.now();\r\n\r\n\r\n const existing = await cacheDriver.get<T>(cacheKey, opts?.persist);\r\n if (existing) return;\r\n\r\n\r\n if (inFlightPrefetch.has(cacheKey)) return;\r\n\r\n const controller = new AbortController();\r\n const signal = controller.signal;\r\n\r\n const runPrefetch = async () => {\r\n try {\r\n\r\n const promise = api.get<T>(url, { signal });\r\n inFlightPrefetch.set(cacheKey, { controller, promise });\r\n\r\n const res = await promise;\r\n\r\n const validated = validateWithSchema(\r\n res.data,\r\n opts?.schema,\r\n opts?.schemaMode ?? \"error\",\r\n url\r\n );\r\n\r\n // Save to cache\r\n await cacheDriver.set(cacheKey, validated, {\r\n ttlMs: opts?.ttlMs,\r\n persist: opts?.persist,\r\n });\r\n\r\n } catch (err) {\r\n\r\n } finally {\r\n\r\n inFlightPrefetch.delete(cacheKey);\r\n }\r\n };\r\n\r\n\r\n schedulePrefetch(runPrefetch);\r\n}\r\n\r\n\r\nexport function cancelAllPrefetches() {\r\n inFlightPrefetch.forEach(({ controller }) => controller.abort());\r\n inFlightPrefetch.clear();\r\n}\r\n","\r\nexport const inFlightRequests = new Map<string, Promise<any>>();\r\n\r\n\r\nexport const inFlightMutations = new Map<string, Promise<any>>();\r\n\r\n// Generate unique key for mutation types\r\nexport function mutationKey(method: string, url: string, body?: any) {\r\n const bodyKey = body ? JSON.stringify(body) : \"\";\r\n return `${method}:${url}:${bodyKey}`;\r\n}\r\n","import { useState } from \"react\";\r\nimport { useFetchSmartContext } from \"./FetchSmartProvider\";\r\nimport { SchemaMode, SchemaValidator } from \"./types\";\r\nimport { validateWithSchema } from \"./utils/validateWithSchema\";\r\nimport { inFlightMutations, mutationKey } from \"./utils/smartDedupe\";\r\n\r\nexport function usePostSmart<T = any, Body = any>(\r\n url: string,\r\n opts?: {\r\n schema?: SchemaValidator<T>,\r\n schemaMode?: SchemaMode\r\n }\r\n) {\r\n const { axiosInstance: api } = useFetchSmartContext();\r\n const [data, setData] = useState<T | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<any>(null);\r\n\r\n const mutate = async (body: Body) => {\r\n setLoading(true);\r\n setError(null);\r\n\r\n\r\n const key = mutationKey(\"POST\", url, body);\r\n\r\n if (inFlightMutations.has(key)) {\r\n return await inFlightMutations.get(key);\r\n }\r\n const promise = api.post<T>(url, body);\r\n\r\n\r\n inFlightMutations.set(key, promise);\r\n\r\n try {\r\n const res = await promise;\r\n\r\n if (inFlightMutations.get(key) === promise) {\r\n inFlightMutations.delete(key);\r\n }\r\n\r\n const validated = validateWithSchema(res.data, opts?.schema, \"error\", url);\r\n setData(validated);\r\n return validated;\r\n\r\n } catch (err) {\r\n inFlightMutations.delete(key);\r\n setError(err);\r\n return null;\r\n\r\n } finally {\r\n setLoading(false);\r\n }\r\n\r\n };\r\n\r\n return { mutate, data, loading, error };\r\n}\r\n","import { useState } from \"react\";\r\nimport { useFetchSmartContext } from \"./FetchSmartProvider\";\r\nimport { SchemaMode, SchemaValidator } from \"./types\";\r\nimport { validateWithSchema } from \"./utils/validateWithSchema\";\r\nimport { inFlightMutations, mutationKey } from \"./utils/smartDedupe\";\r\n\r\n\r\nexport function usePutSmart<T = any, Body = any>(\r\n url: string,\r\n opts?: {\r\n schema?: SchemaValidator<T>;\r\n schemaMode?: SchemaMode;\r\n }\r\n) {\r\n const { axiosInstance: api } = useFetchSmartContext();\r\n const [data, setData] = useState<T | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<any>(null);\r\n\r\n const mutate = async (body: Body) => {\r\n setLoading(true);\r\n setError(null);\r\n\r\n const key = mutationKey(\"PUT\", url, body);\r\n\r\n // DEDUPE\r\n if (inFlightMutations.has(key)) {\r\n return await inFlightMutations.get(key);\r\n }\r\n\r\n const promise = api.put<T>(url, body);\r\n inFlightMutations.set(key, promise);\r\n\r\n try {\r\n const res = await promise;\r\n\r\n if (inFlightMutations.get(key) === promise) {\r\n inFlightMutations.delete(key);\r\n }\r\n\r\n const validated = validateWithSchema(res.data, opts?.schema, \"error\", url);\r\n setData(validated);\r\n return validated;\r\n\r\n } catch (err) {\r\n inFlightMutations.delete(key);\r\n setError(err);\r\n return null;\r\n\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n\r\n return { mutate, data, loading, error };\r\n}\r\n","import { useState } from \"react\";\r\nimport { useFetchSmartContext } from \"./FetchSmartProvider\";\r\nimport { SchemaMode, SchemaValidator } from \"./types\";\r\nimport { validateWithSchema } from \"./utils/validateWithSchema\";\r\nimport { inFlightMutations, mutationKey } from \"./utils/smartDedupe\";\r\n\r\nexport function useDeleteSmart<T = any>(\r\n url: string,\r\n opts?: {\r\n schema?: SchemaValidator<T>;\r\n schemaMode?: SchemaMode;\r\n }\r\n) {\r\n const { axiosInstance: api } = useFetchSmartContext();\r\n const [data, setData] = useState<T | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<any>(null);\r\n\r\n const mutate = async () => {\r\n setLoading(true);\r\n setError(null);\r\n\r\n const key = mutationKey(\"DELETE\", url);\r\n\r\n\r\n if (inFlightMutations.has(key)) {\r\n return await inFlightMutations.get(key);\r\n }\r\n\r\n const promise = api.delete<T>(url);\r\n inFlightMutations.set(key, promise);\r\n\r\n try {\r\n const res = await promise;\r\n\r\n if (inFlightMutations.get(key) === promise) {\r\n inFlightMutations.delete(key);\r\n }\r\n\r\n const validated = validateWithSchema(res.data, opts?.schema, \"error\", url);\r\n setData(validated);\r\n return validated;\r\n\r\n } catch (err) {\r\n inFlightMutations.delete(key);\r\n setError(err);\r\n return null;\r\n\r\n } finally {\r\n setLoading(false);\r\n }\r\n };\r\n\r\n\r\n return { mutate, data, loading, error };\r\n}\r\n","import React, { useEffect, useState, useCallback } from \"react\";\r\nimport { memoryCache } from \"./cache/memoryCache\";\r\nimport { indexedDBCache } from \"./cache/indexedDBCache\";\r\nimport { inFlightRequests, inFlightMutations } from \"./utils/smartDedupe\";\r\n\r\nexport const FetchSmartDevtools = () => {\r\n const _proc: any = (globalThis as any).process;\r\n if (_proc?.env?.NODE_ENV === \"production\") return null;\r\n\r\n const [open, setOpen] = useState(false);\r\n\r\n const [state, setState] = useState({\r\n memDump: [] as any[],\r\n idbDump: [] as any[],\r\n combinedDump: [] as any[],\r\n memKeys: [] as string[],\r\n idbKeys: [] as string[],\r\n allKeys: [] as string[],\r\n inFlightGetKeys: [] as string[],\r\n inFlightMutationKeys: [] as string[],\r\n });\r\n\r\n /** -------------------------------\r\n * OPTIMIZED ASYNC REFRESH\r\n * ------------------------------- */\r\n const refresh = useCallback(async () => {\r\n const mem = memoryCache.dump?.() ?? [];\r\n const memKeys = mem.map((x) => x.key);\r\n\r\n // IndexedDB parallel read\r\n let idbKeys: string[] = [];\r\n let idbDump: any[] = [];\r\n\r\n if (indexedDBCache.keys) {\r\n idbKeys = await indexedDBCache.keys();\r\n const reads = await Promise.all(idbKeys.map((k) => indexedDBCache.get(k)));\r\n idbDump = idbKeys.map((k, i) => ({ key: k, data: reads[i] })).filter((x) => x.data !== null);\r\n }\r\n\r\n const allKeys = Array.from(new Set([...memKeys, ...idbKeys]));\r\n\r\n // Build combined result faster using maps\r\n const memMap = new Map(mem.map((x) => [x.key, x]));\r\n const idbMap = new Map(idbDump.map((x) => [x.key, x]));\r\n\r\n const combinedDump = allKeys.map((key) => {\r\n const m = memMap.get(key);\r\n const d = idbMap.get(key);\r\n\r\n return {\r\n key,\r\n source: m && d ? \"memory + indexeddb\" : m ? \"memory\" : \"indexeddb\",\r\n memoryData: m?.data ?? null,\r\n idbData: d?.data ?? null,\r\n memoryExpiry: m?.expiry ?? null,\r\n idbExpiry: d?.expiry ?? null,\r\n };\r\n });\r\n\r\n setState({\r\n memDump: mem,\r\n idbDump,\r\n combinedDump,\r\n memKeys,\r\n idbKeys,\r\n allKeys,\r\n inFlightGetKeys: Array.from(inFlightRequests.keys()),\r\n inFlightMutationKeys: Array.from(inFlightMutations.keys()),\r\n });\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (open) refresh();\r\n }, [open, refresh]);\r\n\r\n /** -------------------------------\r\n * CLEAN HELPERS\r\n * ------------------------------- */\r\n const clearMemory = () => {\r\n memoryCache.clear?.();\r\n refresh();\r\n };\r\n\r\n const clearIndexedDB = async () => {\r\n await indexedDBCache.clear?.();\r\n refresh();\r\n };\r\n\r\n const clearInFlight = () => {\r\n inFlightRequests.clear();\r\n inFlightMutations.clear();\r\n refresh();\r\n };\r\n\r\n /** -------------------------------\r\n * CLOSED STATE BUTTON\r\n * ------------------------------- */\r\n if (!open)\r\n return (\r\n <button\r\n onClick={() => setOpen(true)}\r\n style={FAB_STYLE}\r\n >\r\n FS Devtools\r\n </button>\r\n );\r\n\r\n /** -------------------------------\r\n * OPEN STATE PANEL\r\n * ------------------------------- */\r\n return (\r\n <div style={PANEL_STYLE}>\r\n <button onClick={() => setOpen(false)} style={BTN_STYLE}>\r\n Close\r\n </button>\r\n\r\n {/** ----------------------- */}\r\n {/** DEDUPE KEYS */}\r\n {/** ----------------------- */}\r\n <Section title=\"🔵 In-Flight GET Requests\">\r\n {state.inFlightGetKeys}\r\n </Section>\r\n\r\n <Section title=\"🔴 In-Flight Mutations\">\r\n {state.inFlightMutationKeys}\r\n </Section>\r\n\r\n {/** ----------------------- */}\r\n {/** CACHE KEYS */}\r\n {/** ----------------------- */}\r\n <Section title=\"Memory Keys\">{state.memKeys}</Section>\r\n <Section title=\"IndexedDB Keys\">{state.idbKeys}</Section>\r\n <Section title=\"All Cache Keys\">{state.allKeys}</Section>\r\n\r\n {/** ----------------------- */}\r\n {/** RAW DATA */}\r\n {/** ----------------------- */}\r\n <Section title=\"Memory Cache\">{state.memDump}</Section>\r\n <Section title=\"IndexedDB Cache\">{state.idbDump}</Section>\r\n <Section title=\"Combined Cache View\">{state.combinedDump}</Section>\r\n\r\n {/** ----------------------- */}\r\n {/** ACTION BTNS */}\r\n {/** ----------------------- */}\r\n <button style={BTN_STYLE} onClick={refresh}>Refresh</button>\r\n <button style={BTN_DANGER} onClick={clearMemory}>Clear Memory Cache</button>\r\n <button style={BTN_WARN} onClick={clearIndexedDB}>Clear IndexedDB</button>\r\n <button style={BTN_INFO} onClick={clearInFlight}>Clear In-Flight Requests</button>\r\n </div>\r\n );\r\n};\r\n\r\n/* -------------------------------\r\n SMALL UTIL COMPONENT\r\n--------------------------------*/\r\nconst Section = ({ title, children }: any) => (\r\n <>\r\n <h3>{title}</h3>\r\n <pre>{JSON.stringify(children, null, 2)}</pre>\r\n </>\r\n);\r\n\r\n/* -------------------------------\r\n UI STYLES\r\n--------------------------------*/\r\nconst FAB_STYLE: React.CSSProperties = {\r\n position: \"fixed\",\r\n bottom: 20,\r\n right: 20,\r\n padding: \"6px 10px\",\r\n background: \"#333\",\r\n color: \"white\",\r\n borderRadius: \"6px\",\r\n fontFamily: \"monospace\",\r\n zIndex: 99999,\r\n};\r\n\r\nconst PANEL_STYLE: React.CSSProperties = {\r\n position: \"fixed\",\r\n bottom: 20,\r\n right: 20,\r\n width: 480,\r\n maxHeight: \"80vh\",\r\n overflowY: \"auto\",\r\n background: \"#111\",\r\n padding: 16,\r\n borderRadius: 10,\r\n color: \"white\",\r\n fontFamily: \"monospace\",\r\n zIndex: 99999,\r\n};\r\n\r\nconst BTN_STYLE: React.CSSProperties = {\r\n background: \"#444\",\r\n padding: \"6px 8px\",\r\n borderRadius: 4,\r\n marginBottom: 10,\r\n width: \"100%\",\r\n};\r\n\r\nconst BTN_DANGER = {\r\n ...BTN_STYLE,\r\n background: \"#550000\",\r\n};\r\n\r\nconst BTN_WARN = {\r\n ...BTN_STYLE,\r\n background: \"#A36C00\",\r\n};\r\n\r\nconst BTN_INFO = {\r\n ...BTN_STYLE,\r\n background: \"#003355\",\r\n};\r\n"],"mappings":"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","names":["import_react","axios","import_react","import_react","import_react","import_react","import_jsx_runtime"]}