import { useCallback, useRef } from "react"; export interface CanvasHistorySnapshot { textNodes: unknown[]; imageNodes: unknown[]; videoNodes: unknown[]; manualLinks: unknown[]; nodePackages: unknown[]; } interface CanvasHistoryState { past: CanvasHistorySnapshot[]; future: CanvasHistorySnapshot[]; } const MAX_HISTORY = 50; export function useCanvasHistory() { const historyRef = useRef({ past: [], future: [] }); const lastPushRef = useRef(0); const pushSnapshot = useCallback((snapshot: CanvasHistorySnapshot) => { const now = Date.now(); // Debounce: skip if pushed within 300ms (e.g. rapid drag moves) if (now - lastPushRef.current < 300) return; lastPushRef.current = now; const history = historyRef.current; history.past = [...history.past.slice(-(MAX_HISTORY - 1)), snapshot]; history.future = []; }, []); const undo = useCallback( (currentSnapshot: CanvasHistorySnapshot): CanvasHistorySnapshot | null => { const history = historyRef.current; if (!history.past.length) return null; const previous = history.past[history.past.length - 1]; history.past = history.past.slice(0, -1); history.future = [...history.future, currentSnapshot]; return previous; }, [] ); const redo = useCallback( (currentSnapshot: CanvasHistorySnapshot): CanvasHistorySnapshot | null => { const history = historyRef.current; if (!history.future.length) return null; const next = history.future[history.future.length - 1]; history.future = history.future.slice(0, -1); history.past = [...history.past, currentSnapshot]; return next; }, [] ); const canUndo = useCallback(() => historyRef.current.past.length > 0, []); const canRedo = useCallback(() => historyRef.current.future.length > 0, []); const clear = useCallback(() => { historyRef.current = { past: [], future: [] }; }, []); return { pushSnapshot, undo, redo, canUndo, canRedo, clear }; }