From ac1799db38661e07a855653f86feb3e66081102e Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Mon, 2 Nov 2026 22:50:58 -0500 Subject: [PATCH] web: ?bench runs on demo photos in an unsaved library, never the stored one (#3646) A navigation link with ?bench opened the first photo of the library in browser storage and committed Exposure edits to it, finishing at 0 instead of the photo's own value. ?bench now implies ?store=memory and loads the generated demo photos, so the benchmark cannot edit stored photos. --- apps/lightcraft-web/src/bench.rs | 3 +++ apps/lightcraft-web/src/lib.rs | 3 ++- apps/lightcraft-web/src/web.rs | 11 +++++++++-- docs/web.md | 3 ++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/apps/lightcraft-web/src/bench.rs b/apps/lightcraft-web/src/bench.rs index 484c0041f6..4864834c75 100644 --- a/apps/lightcraft-web/src/bench.rs +++ b/apps/lightcraft-web/src/bench.rs @@ -2,6 +2,9 @@ //! control exactly like a slider drag (begin interaction → N `develop.set` → end) and time each //! step from the command to the moment the new loupe texture is ready. Results go to the log //! (the browser console on the web) as one `lightcraft-bench {…json…}` line. +//! +//! The web host runs it only on the generated demo photos in an unsaved library (`?bench` implies `?store=memory`): it +//! commits edits to the photo it opens, which must never be one in the user's stored library. use lightcraft_ui_egui::LightcraftApp; use lightcraft_ui_egui::render::Slot; diff --git a/apps/lightcraft-web/src/lib.rs b/apps/lightcraft-web/src/lib.rs index 5d3c011589..6a6b83b728 100644 --- a/apps/lightcraft-web/src/lib.rs +++ b/apps/lightcraft-web/src/lib.rs @@ -11,7 +11,8 @@ //! - export downloads the file through the browser. //! //! `?bench` in the URL runs a scripted first-paint / slider-latency measurement and logs it to the -//! console (see [`bench`]); `?store=idb` forces the IndexedDB backend, `?store=memory` disables +//! console (see [`bench`]) on the generated demo photos in an unsaved library (it implies `?store=memory`, so it never edits +//! the library in browser storage); `?store=idb` forces the IndexedDB backend, `?store=memory` disables //! persistence and `?workers=0` renders on the main thread. #![forbid(unsafe_code)] #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] diff --git a/apps/lightcraft-web/src/web.rs b/apps/lightcraft-web/src/web.rs index bd5215e4d4..da71c592a8 100644 --- a/apps/lightcraft-web/src/web.rs +++ b/apps/lightcraft-web/src/web.rs @@ -90,9 +90,12 @@ impl Options { }) .collect(); let get = |k: &str| params.iter().find(|(n, _)| n == k).map(|(_, v)| v.clone()); + let bench = get("bench").is_some(); Options { - bench: get("bench").is_some(), - store: get("store").filter(|s| s == "idb" || s == "memory").unwrap_or_else(|| "opfs".into()), + bench, + // the benchmark edits the first photo it finds: a link with `?bench` must never reach + // the library in browser storage, so it always runs on the demo photos in an unsaved library + store: if bench { "memory".into() } else { get("store").filter(|s| s == "idb" || s == "memory").unwrap_or_else(|| "opfs".into()) }, workers: get("workers").and_then(|v| v.parse().ok()), reset: get("reset").is_some(), } @@ -496,6 +499,10 @@ impl WebApp { }); } } + // `?bench` never has storage (see `Options::from_url`): it measures the generated demo photos + if opts.bench && backend.is_none() && session.catalog.len() == 0 { + lightcraft_engine::demo::load(&mut session); + } if backend.is_some() { notice( "LightCraft in the browser is experimental. Your library is kept in this browser's storage: keep your original photos \ diff --git a/docs/web.md b/docs/web.md index 76b84cd7c0..d8065dd766 100644 --- a/docs/web.md +++ b/docs/web.md @@ -188,7 +188,8 @@ are the same in every version, so serve them with `Cache-Control: no-cache` (not ## Measuring -Open `http://127.0.0.1:8080/?bench` to run a scripted measurement: +Open `http://127.0.0.1:8080/?bench` to run a scripted measurement. It always runs on the generated demo photos in an unsaved library +(`?bench` implies `?store=memory`), so it never edits the library kept in browser storage: 1. Wait for the grid thumbnails. 2. Open the first photo in Detail.