What's wrong
SaveBoundaryManager.CreateSaveBoundary always appends a new SaveBoundary, even when one already exists at the same position. docs/getting-started.md shows a Save button that calls MarkAsSaved on every click, and autosave timers do the same. Each save without an edit in between adds another identical boundary. Nothing removes them until the stack branches or is trimmed past that position.
Repro
var s = new UndoRedoService(new StackManager(), new SaveBoundaryManager(), new CommandMerger());
s.SetSerializer(new JsonUndoRedoSerializer());
s.Execute(new DelegateCommand("Type", () => { }, () => { }));
Console.WriteLine($"before saving: {s.SaveBoundaries.Count} boundaries, {(await s.SaveStateAsync()).Length} bytes");
for (int i = 0; i < 1000; i++) s.MarkAsSaved("Saved");
Console.WriteLine($"after 1000 saves: {s.SaveBoundaries.Count} boundaries at position(s) " +
$"{string.Join(",", s.SaveBoundaries.Select(b => b.Position).Distinct())}, state {(await s.SaveStateAsync()).Length} bytes");
Observed:
before saving: 0 boundaries, 368 bytes
after 1000 saves: 1000 boundaries at position(s) 0, state 85250 bytes
Why it matters
- The serialized history grows by about 85 bytes for every save that changes nothing.
HasUnsavedChanges, GetChangeVisualizations and IsAtSaveBoundary run on every Execute, and each one scans the boundary list.
- A history UI that lists
SaveBoundaries shows the same save point hundreds of times.
Suggested fix / acceptance criteria
What's wrong
SaveBoundaryManager.CreateSaveBoundaryalways appends a newSaveBoundary, even when one already exists at the same position.docs/getting-started.mdshows a Save button that callsMarkAsSavedon every click, and autosave timers do the same. Each save without an edit in between adds another identical boundary. Nothing removes them until the stack branches or is trimmed past that position.Repro
Observed:
Why it matters
HasUnsavedChanges,GetChangeVisualizationsandIsAtSaveBoundaryrun on everyExecute, and each one scans the boundary list.SaveBoundariesshows the same save point hundreds of times.Suggested fix / acceptance criteria
position,MarkAsSaved/CreateSaveBoundaryupdates that boundary (new timestamp and description) instead of appending another.SaveBoundaryCreatedstill fires.MarkAsSavedthree times,SaveBoundaries.Count == 1.