import { useRef, useCallback } from 'react'; // Guards async handlers against double-fire (e.g. a rapid double-click that triggers // both onClick callbacks before React re-renders the now-disabled button). Disabled // buttons alone don't prevent this because the disable only takes effect after a render. // // Usage: // const guard = useActionLock(); // const handleSubmit = guard('submit', async () => { ... }); // // Each `key` locks independently, so unrelated buttons don't block each other. While a // run is in-flight the same key is a no-op until it settles (resolve or throw). export function useActionLock() { const locks = useRef(new Set()); return useCallback((key, fn) => async (...args) => { if (locks.current.has(key)) return undefined; locks.current.add(key); try { return await fn(...args); } finally { locks.current.delete(key); } }, []); }