mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-27 11:17:01 -06:00
M4.37: Data Recovery keeps copies of modified documents and offers them after a crash
- Every Preferences > File Handling > Data Recovery interval, modified documents
changed since their last copy are written to the recovery store in the
background (the same snapshot and encoder as Background Save; the status bar
shows it). Complex documents (over 20,000 objects) are skipped while Turn off
Data Recovery for complex documents is on.
- A copy goes when its document is saved, reverted, closed or undone back to its
saved state, and when the app quits with nothing unsaved.
- Each running app keeps its copies in an area of its own: a sub-folder whose
.lock file it keeps locked for its lifetime (File::try_lock), or on the web a
heartbeat refreshed every minute. Only areas nobody holds (lock free, or no
heartbeat for three intervals, at least three minutes) are offered, and an
area is held while it is restored or discarded, so a second running instance
never offers or deletes a live instance's copies. Empty leftover areas are
tidied away.
- The next launch after a crash asks with the Recover Documents dialog (Restore /
Discard / Cancel): restored documents open as "<name> [Recovered]", unsaved, and
Save asks where to save them, suggesting their original file; the copy moves
into the new app's area.
- Store: the recoveryFolder preference, else Data Recovery beside the desktop
app's preferences; browser storage on the web (Services::recovery_store);
tests use an in-memory store (with in-memory locks, or heartbeats).
- Engine: file.recovery.save, file.recovery.list, file.recovery.restore {file?},
file.recovery.discard {file?}; DocState.recovered and DocState.recovery.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
d8d1d472cf
commit
975067b44a
@@ -339,3 +339,10 @@ EPS Options: Export As… with the EPS format (`file.exportAs {format: "eps"}`,
|
||||
`cmykPostScript`, `compatibleGradients`, `level` (`2`, `3`), plus `path` and the artboard choice (`useArtboards`,
|
||||
`range`). `ui.dialog.confirm` checks them (a bad value or an unknown preset keeps the dialog open), remembers them for
|
||||
the next EPS Options and writes the file(s), asking for a path when there is none.
|
||||
|
||||
Data Recovery: at launch, copies left behind by a crash open the `recovery` dialog (never copies another running
|
||||
instance keeps, so instances started side by side for screenshots don't get it). Fields: `copies` (`[{file, title,
|
||||
saved}]`, from `file.recovery.list`) and `discard`. `ui.dialog.confirm` restores them all (`file.recovery.restore`
|
||||
each, opening "<name> [Recovered]" documents), `discard: true` then confirm deletes them, `ui.dialog.cancel` keeps them
|
||||
for the next launch. While copies are written in the background `ui.inspect` lists them under `background`
|
||||
("Saving recovery data for <name>").
|
||||
|
||||
+26
@@ -1265,3 +1265,29 @@ as they do for art larger than the imageable area and for overprints in composit
|
||||
{"name":"run_command","arguments":{"command":"print.preview","params":{"settings":{"output":{"mode":"separations"}}}}}
|
||||
{"name":"run_command","arguments":{"command":"file.print","params":{"path":"/tmp/job.pdf","settings":{"copies":2}}}}
|
||||
```
|
||||
|
||||
## Data Recovery
|
||||
|
||||
Modified documents get recovery copies (`file.recovery.save`; the app runs it every `autosaveInterval` minutes while
|
||||
`autosaveRecovery` is on, skipping documents of more than 20,000 objects while `recoveryOffForComplex` is on). A copy
|
||||
goes when its document is saved, reverted or closed, so copies still there after the app quits were left by a crash.
|
||||
The copies live in the `recoveryFolder` preference's folder (default: `Data Recovery` beside the app's preferences;
|
||||
none when the app runs with `VECTORCRAFT_NO_PREFS`) or, on the web, in browser storage.
|
||||
|
||||
Each running app (each browser tab) keeps its copies in an area of its own (`<area>/<name>`): a sub-folder whose
|
||||
`.lock` file it keeps locked while it runs, or on the web an area with a heartbeat it refreshes every minute. Only
|
||||
areas nobody holds are offered: their lock is free, or their heartbeat is older than three intervals (at least three
|
||||
minutes). Several apps running at once (agents' instances included) never see each other's copies as crash leftovers,
|
||||
and an area being restored or discarded is held, so two apps launched together never both take it.
|
||||
|
||||
`file.recovery.list` → `{copies: [{file, title, path, format, saved, open, running}], location}` (`open`: the copy of a
|
||||
document open here; `running`: kept by another VectorCraft that is running). `file.recovery.restore {file?}` opens
|
||||
copies left behind (default: all) as `"<name> [Recovered]"`: modified, and Save asks where to save them (suggesting
|
||||
their original file); the copy moves into this app's area. `file.recovery.discard {file?}` deletes them. Without a
|
||||
folder or browser storage the commands are disabled and say how to set one.
|
||||
|
||||
```json
|
||||
{"name":"run_command","arguments":{"command":"prefs.set","params":{"key":"recoveryFolder","value":"/tmp/vc-recovery"}}}
|
||||
{"name":"run_command","arguments":{"command":"file.recovery.save","params":{}}}
|
||||
{"name":"run_command","arguments":{"command":"file.recovery.restore","params":{"file":"1759650000-1/Poster-1"}}}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user