import { useEffect, useMemo, useRef } from "react"; function fingerprint(f: File) { return `${f.name}::${f.size}::${f.lastModified}`; } export function useObjectUrlCache(files: File[]) { const cacheRef = useRef>(new Map()); const keys = useMemo(() => { return files.map((f) => fingerprint(f)); }, [files]); // revoke removed keys useEffect(() => { const need = new Set(keys); for (const [key, url] of cacheRef.current.entries()) { if (!need.has(key)) { try { URL.revokeObjectURL(url); } catch {} cacheRef.current.delete(key); } } }, [keys]); // unmount: revoke all useEffect(() => { return () => { for (const url of cacheRef.current.values()) { try { URL.revokeObjectURL(url); } catch {} } cacheRef.current.clear(); }; }, []); const getOrCreate = (file: File) => { const key = fingerprint(file); const existed = cacheRef.current.get(key); if (existed) return existed; const url = URL.createObjectURL(file); cacheRef.current.set(key, url); return url; }; return { getOrCreate }; }