forked from 1b-agent/opencadstudio-upstream
web: harden drop-open and autosave after adversarial review
Review of the drop-open and autosave commits surfaced one blocker and
five majors; all are fixed here, and two claims in the autosave commit
message are corrected by this one: tab close does NOT clear a snapshot
(matches native .sv$ semantics — saving, restoring, discarding, exit,
and the capped boot scan do), and serialization runs on the main
thread between awaits, not off the paint path.
- The restore prompt can no longer appear with no entries (empty
"Recover Drawing" modal on every boot once the autosave dir exists).
- Restore no longer consumes the snapshot before the open succeeds:
the recovered drawing goes through the guarded drop queue, and the
snapshot is deleted only after the tab opens; cancel or parse
failure keeps the only copy.
- Saving during an autosave round defers its snapshot cleanup until
the round finishes, so a stale round can no longer resurrect a
snapshot newer than the save.
- The boot scan no longer deletes snapshots by mtime comparison
(re-opening a drawing refreshes the recent copy's mtime, which
silently destroyed wanted snapshots); GC is now a 16-entry cap with
oldest-first eviction.
- OPFS write failures abort the writable stream (a leaked lock could
stall the same-key writer and disable autosave for the session), and
DOMException errors now carry their name/message.
- Empty (crash-window) snapshots are never offered; an unreadable one
warns and stays discardable instead of looping forever.
- Drop-open polish: reads start inside the handler and complete in
drop order (legacy WebKit safety, deterministic multi-file order),
dragenter is canceled too, the install guard only latches on
success, non-drawing drops don't steal propagation, a lock-poison
panic can't cross into JS, and re-dropping an open drawing no
longer risks clobbering an in-flight open (it re-queues).
- The model-space sheet floor is per-axis (a thin 8x400 mm profile
keeps its length) and centers content on the enlarged page.
(cherry picked from commit 3edbc5b7c8)
This commit is contained in:
1 parent
12fd04790f
commit
3023cefea4
7 files changed
+360
-96
No files matched your search
+16
-2
@@ -927,6 +927,16 @@ pub(super) struct OpenCADStudio {
|
||||
/// prompt still has to offer, one at a time.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
web_autosave_pending: Vec<crate::io::web_autosave::WebAutosaveEntry>,
|
||||
/// The snapshot whose recovered open is queued: `(autosave key,
|
||||
/// open name)`. The OPFS copy is the only one, so it is deleted only
|
||||
/// once an open with exactly that name succeeds.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
web_autosave_consumed: Option<(String, String)>,
|
||||
/// Autosave keys a web save wanted to remove while a snapshot round was
|
||||
/// still writing (the round's late write would resurrect the snapshot
|
||||
/// with a fresh mtime); the removes run when the round finishes.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
web_autosave_clear_after: Vec<String>,
|
||||
// ── Floating panel windows ────────────────────────────────────────────
|
||||
/// Active `iced_aw` colour picker: destination plus its initial colour.
|
||||
color_pick_target: Option<(ColorPickTarget, AcadColor)>,
|
||||
@@ -2324,8 +2334,8 @@ pub enum Message {
|
||||
/// Web: delete the offered autosave snapshot (and offer the next, if any).
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
WebAutosaveDiscard,
|
||||
/// Web: the offered snapshot's bytes are in (and the OPFS copy consumed);
|
||||
/// open them as `name`.
|
||||
/// Web: the offered snapshot's bytes are in; queue them for the guarded
|
||||
/// open poll. The OPFS copy is consumed only once that open succeeds.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
WebAutosaveBytes(String, Result<Vec<u8>, String>),
|
||||
/// Web: one autosave round finished for all dirty tabs (serially).
|
||||
@@ -4410,6 +4420,10 @@ impl OpenCADStudio {
|
||||
web_autosave_warned: false,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
web_autosave_pending: Vec::new(),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
web_autosave_consumed: None,
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
web_autosave_clear_after: Vec::new(),
|
||||
color_pick_target: None,
|
||||
color_picker_tab: ColorPickerTab::Index,
|
||||
recent_colors: Vec::new(),
|
||||
|
||||
Reference in new issue
Block a user