From cd0050d988fdfdfbcdfc102c768e9dcf8cef388c Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Mon, 14 Sep 2026 00:00:16 +0530 Subject: [PATCH] feat(recovery): autosave buffer + crash-recovery banner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VersionHistory snapshots the previous content on every explicit save — an unsaved buffer is still lost on crash. AutosaveBuffer fills that gap. - src/main/AutosaveBuffer.js — pure module mirroring VersionHistory's injectable-IO pattern; one blob per doc path under /autosave/by-path//recovery.md + meta.json. No history (VersionHistory owns that) — just the latest dirty buffer. - src/main.js — IPC channels autosave:write/read/clear/list; real paths go through validatePath, synthetic 'untitled-tab-' keys skip it. - src/preload.js — added the four channels to ALLOWED_SEND_CHANNELS. - src/renderer/autosave-client.js — debounced (2s) flush per tab + periodic safety net (10s max age) + dirty-write retry on failure. - src/renderer.js — register on tab create, unregister on close, notifyChange piggybacks on performAutoSave's existing dirty-check, clearForDocPath after a successful save, showAutosaveRecoveryBanner on startup listing pending recoveries with Restore/Dismiss. Tests (39 new): - tests/main/AutosaveBuffer.test.js (19): round-trip, overwrite, isolation, unicode/emoji, empty content, null coercion, ENOENT vs corrupt meta, list ordering, corrupt-sibling skip, input validation, sha1 storage. - tests/autosave-client.test.js (11): debounce, flushNow bypass, no-path skip, clearForDocPath, list proxy, IPC error fallback, unregister tear-down, failure-retry, periodic flush, idempotency. Full suite: 692 tests pass, 63 suites, lint+format clean. Amit Haridas --- src/main.js | 69 ++++- src/main/AutosaveBuffer.js | 178 +++++++++++++ src/main/ExportThemes.js | 24 +- src/main/MarkItDown.js | 4 +- src/main/PDFOperations.js | 5 +- .../writing-studio/panels/manuscript-panel.js | 4 +- src/preload.js | 6 + src/renderer.js | 125 ++++++++++ src/renderer/autosave-client.js | 174 +++++++++++++ tests/autosave-client.test.js | 235 ++++++++++++++++++ tests/bundled-tools.test.js | 22 +- tests/main/AutosaveBuffer.test.js | 226 +++++++++++++++++ tests/main/ImageOperations.test.js | 16 +- tests/main/MarkItDown.test.js | 10 +- tests/main/PDFOperations.test.js | 78 +++--- tests/math-rendering.test.js | 5 +- 16 files changed, 1099 insertions(+), 82 deletions(-) create mode 100644 src/main/AutosaveBuffer.js create mode 100644 src/renderer/autosave-client.js create mode 100644 tests/autosave-client.test.js create mode 100644 tests/main/AutosaveBuffer.test.js diff --git a/src/main.js b/src/main.js index 41fbd22..119358b 100644 --- a/src/main.js +++ b/src/main.js @@ -1735,8 +1735,7 @@ function showThirdPartyNoticesWindow() { return `(Could not read ${file} in this installation — see the source repository.)`; } }; - const esc = (s) => - s.replace(/&/g, '&').replace(//g, '>'); + const esc = (s) => s.replace(/&/g, '&').replace(//g, '>'); const html = 'Third-Party Notices