mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-25 18:47:42 -06:00
Renders run in dedicated module Web Workers, each a second instance of the app's wasm module (index.html compiles it once and posts the WebAssembly.Module to worker.js). A job crosses as JSON (WireJob: source, settings, request); the worker reads originals and cached thumbnails from browser storage itself, keeps decoded sources and per-view stage caches, and transfers RGBA back. Jobs follow the worker that decoded the photo; the loupe waits for it. No wasm threads or SharedArrayBuffer needed; falls back to inline rendering if no worker starts (?workers=0). Thumbnail disk cache on the web: thumbs/<key>.jpg in OPFS/IndexedDB with an index on the main thread, pruned to the desktop budget (2 GB → 80 %, LRU). ui-egui: RenderOffload hook in the Renderer (queue/priorities/dedup stay in the UI). engine: RenderJob.origin + MediaCache::origin_ref; preview: encode_jpeg/decode_jpeg public. xtask web: copies worker.js; --serve sends COOP/COEP/CORP (documented in docs/web.md). Headless Chrome, cold load + grid scroll, 24 demo photos: main-thread busy 12.4 s → 0.7–1.1 s, long tasks 23 (max 1.1 s) → 0; grid filled in 6.3–8.4 s vs 13–16 s; slider job 4 ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
29 lines
1.3 KiB
Rust
29 lines
1.3 KiB
Rust
//! LightCraft in the browser: the same egui UI as the desktop app, compiled to WASM.
|
|
//!
|
|
//! Build with `cargo xtask web` (→ `target/web/`), then serve that folder over HTTP (see
|
|
//! `docs/web.md`). Differences from the desktop host:
|
|
//! - the library lives in browser storage (OPFS, or IndexedDB where OPFS can't be written from the
|
|
//! main thread): catalog journal, presets, view state and prefs are mirrored in memory and
|
|
//! flushed in the background ([`files`]); imported originals are stored by content hash
|
|
//! ([`store`]); a new library starts with the procedural demo photos;
|
|
//! - renders run in Web Workers, each a second instance of this module ([`wire`], `workers`), and
|
|
//! fall back to the main thread (one job per frame) if workers can't start;
|
|
//! - 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
|
|
//! persistence and `?workers=0` renders on the main thread.
|
|
#![forbid(unsafe_code)]
|
|
|
|
pub mod bench;
|
|
pub mod files;
|
|
pub mod store;
|
|
pub mod wire;
|
|
|
|
#[cfg(target_arch = "wasm32")]
|
|
mod backend;
|
|
#[cfg(target_arch = "wasm32")]
|
|
mod web;
|
|
#[cfg(target_arch = "wasm32")]
|
|
mod workers;
|