singularity-forge/packages/tui/src/undo-stack.ts
Mikael Hugo de77cf439f
Some checks failed
CI / detect-changes (push) Has been cancelled
CI / docs-check (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
CI / integration-tests (push) Has been cancelled
CI / windows-portability (push) Has been cancelled
CI / rtk-portability (linux, blacksmith-4vcpu-ubuntu-2404) (push) Has been cancelled
CI / rtk-portability (macos, macos-15) (push) Has been cancelled
CI / rtk-portability (windows, blacksmith-4vcpu-windows-2025) (push) Has been cancelled
fix(tui): error boundary in doRender, extract autonomousStatus, clean parseCellSize
- doRender() now catches render errors and emits a fallback line
- autonomousStatus ANSI formatting extracted to renderAutonomousStatus()
  with named color constants instead of raw escape strings
- parseCellSizeResponse extracted to pure function with proper validation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-10 12:41:47 +02:00

57 lines
1.4 KiB
TypeScript

/**
* Generic undo stack with clone-on-push semantics.
*
* Stores deep clones of state snapshots. Popped snapshots are returned
* directly (no re-cloning) since they are already detached.
*/
export class UndoStack<S> {
private stack: S[] = [];
private redoStack: S[] = [];
/** Push a deep clone of the given state onto the undo stack. Clears redo history. */
push(state: S): void {
this.stack.push(structuredClone(state));
this.redoStack.length = 0;
}
/** Pop and return the most recent undo snapshot, or undefined if empty. */
pop(): S | undefined {
return this.stack.pop();
}
/**
* Push a deep clone of the given state onto the redo stack.
* Called by the editor before applying an undo so the state can be redone.
*/
pushRedo(state: S): void {
this.redoStack.push(structuredClone(state));
}
/**
* Push a deep clone of the given state onto the undo stack without clearing
* the redo stack. Called by the editor before applying a redo so the state
* remains undoable.
*/
pushUndo(state: S): void {
this.stack.push(structuredClone(state));
}
/** Pop and return the most recent redo snapshot, or undefined if empty. */
redo(): S | undefined {
return this.redoStack.pop();
}
canRedo(): boolean {
return this.redoStack.length > 0;
}
/** Remove all snapshots from both undo and redo stacks. */
clear(): void {
this.stack.length = 0;
this.redoStack.length = 0;
}
get length(): number {
return this.stack.length;
}
}