mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-14 19:26:56 -04:00
A heartbeat alone can't tell a crashed tab from one whose timers stopped in the background, so another tab could discard (or restore) the copies of a still-live document once its heartbeat went stale. - Recovery stores without locks can now announce an area for as long as the app runs (RecoveryStore::announce/announced). The web shell implements it with the browser's Web Locks (navigator.locks through js_sys::Reflect): a tab holds a lock named after its area, which the browser releases only when the tab is gone. Lock snapshots are refreshed every 10 s (once before the first frame); a snapshot over a minute old counts every area as held. - An area is gone only when no announcement holds it and its heartbeat is stale. Where the store can't tell (no Web Locks), the owner repairs: each heartbeat (also its first frame after a pause) and each recovery save write again the copies missing from its area, and a heartbeat newer than the one another tab wrote when taking the area over marks it running again. - MemoryStore::announcing models Web Locks in tests; engine and UI tests cover the issue's sequence. Native folder locks are unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>