Skip to content

fix(recents): merge the recent-files list instead of overwriting it - #404

Closed
PathGao wants to merge 1 commit into
sftwrdotdev:masterfrom
PathGao:fix/recent-files-across-windows
Closed

fix(recents): merge the recent-files list instead of overwriting it#404
PathGao wants to merge 1 commit into
sftwrdotdev:masterfrom
PathGao:fix/recent-files-across-windows

Conversation

@PathGao

@PathGao PathGao commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

First of a five-PR chain over MarkdownViewer.svelte. Each is independently reviewable; they are chained because they share that file. Merge order 1 → 5.

The defect

Three call sites — saveRecentFile, deleteRecentFile, and the rename sync — each did JSON.stringify(recentFiles) from the window's own in-memory copy. No re-read, no storage listener. With two windows open, the last one to touch the list silently discarded whatever the other had recorded.

The fix reuses #370 rather than inventing a second mechanism

This is the same shape #370 already solved for settings, so:

No change to settings.svelte.ts was neededwriteStoredSetting was already exported.

Tests

scripts/recentFilesMultiWindow.test.ts — the concurrency tests drive two simulated windows against one shared localStorage and run the real merge, rather than asserting on source text.

Module absent (true master state) suite fails to load
Module present, viewer wiring reverted 3 red / 9 green
Final 12 / 12
npm run check   0 errors
npm test        433 / 433
cargo test      131 / 131   (untouched)

Not covered

  • Two windows writing in the same tick. localStorage is synchronous per document, so writes are serialised per webview; not tested.
  • Paths differing only by case are treated as distinct entries.

🤖 Generated with Claude Code

Three call sites serialised the window's own copy of the list back to
localStorage with no re-read and no `storage` listener, so with two
windows open the last one to touch the list discarded whatever the other
had recorded.

#370 already solved this shape for settings, so the fix reuses it rather
than inventing a second mechanism: a new `recentFiles.ts` holds the pure
list transforms plus `updateStoredRecentFiles(mutate)`, which re-reads,
applies, and writes through #370's `writeStoredSetting`. That write is
compare-and-set, so a no-op fires no `storage` event and the propagation
loop terminates after one hop - #370's argument for why an
`isApplyingRemote` flag cannot work applies here unchanged. A `storage`
listener in the viewer folds in what sibling windows record.

No change to settings.svelte.ts was needed; `writeStoredSetting` was
already exported.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@PathGao

PathGao commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator Author

Reopening from an in-repo branch so the five-part chain can be a real stack — GitHub cannot use a fork branch as a base ref. Same commit, no content change.

@PathGao PathGao closed this Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant