export interface EditHistory { past: T[]; present: T; future: T[] } const LIMIT = 40; export function createEditHistory(present: T): EditHistory { return { past: [], present, future: [] }; } export function commitEdit(history: EditHistory, present: T): EditHistory { if (present === history.present) return history; return { past: [...history.past, history.present].slice(-LIMIT), present, future: [] }; } export function undoEdit(history: EditHistory): EditHistory { if (!history.past.length) return history; return { past: history.past.slice(0, -1), present: history.past.at(-1)!, future: [history.present, ...history.future] }; } export function redoEdit(history: EditHistory): EditHistory { if (!history.future.length) return history; return { past: [...history.past, history.present].slice(-LIMIT), present: history.future[0], future: history.future.slice(1) }; }