feat(history): add undo redo stack

This commit is contained in:
syntaxbullet
2026-07-03 17:30:31 +02:00
parent fedeaffa57
commit 0ffbc4f68b
12 changed files with 139 additions and 7 deletions

View File

@@ -1,5 +1,6 @@
import type { AppState } from "@editor/state";
import type { AppState, HistorySnapshot } from "@editor/state";
import type { CommandContext } from "./command";
import { commandIds } from "./ids";
import type { CommandId, CommandPayloads } from "./payloads";
import type { CommandRegistry } from "./registry";
@@ -21,10 +22,31 @@ export function createCommandDispatcher(options: {
throw new Error(`Unknown command: ${commandId}`);
}
const context: CommandContext = { state: options.getState() };
const nextState = command.execute(context, payload);
const currentState = options.getState();
const context: CommandContext = { state: currentState };
const executedState = command.execute(context, payload);
const nextState = shouldRecordHistory(commandId, currentState, executedState) ? recordHistory(currentState, executedState) : executedState;
options.setState(nextState);
return nextState;
},
};
}
function shouldRecordHistory(commandId: CommandId, currentState: AppState, nextState: AppState) {
if (commandId === commandIds.historyUndo || commandId === commandIds.historyRedo) return false;
return currentState.document !== nextState.document;
}
function recordHistory(currentState: AppState, nextState: AppState): AppState {
return {
...nextState,
history: {
past: [...currentState.history.past, snapshot(currentState)].slice(-100),
future: [],
},
};
}
function snapshot(state: AppState): HistorySnapshot {
return { document: state.document, editor: state.editor };
}