feat(review): downscale desktop Visual-preview thumbnails in self-host mode - #6347
Conversation
…t mode Closes #6324 shot.ts captures full-page, native-resolution PNGs (up to 1440px wide for the desktop viewport, taller still for a long page's full-page height), stored and embedded verbatim at <img width="360"> -- every viewer's browser previously downloaded the full-resolution capture just to render a 360px-wide thumbnail. New downscaleForDisplay/isDisplayDownscaleAvailable in image-downscale.ts (Worker no-op) + src/selfhost/stubs/image-downscale.ts (real sharp-based implementation, 720px width cap -- 2x the display width for a sharp retina render, still a real reduction from 1440px) mirror the existing downscaleForVision seam's own hosted-no-op/self-host-real architecture exactly. Desktop-only: shot.ts's mobile viewport (390px) is already close enough to the table's 360px display width that a third resized copy wouldn't meaningfully help. capturePage stores the downscaled copy at a SIBLING R2 key on a fresh render (only when it genuinely shrinks the bytes, and only once the write is CONFIRMED to succeed -- caught a real bug in my own first pass here, where thumbUrl was set even when the write silently failed), and re-verifies the sibling's existence on a cache hit rather than assuming it from the original's own presence. The ORIGINAL full-resolution object at the existing key is completely unchanged: pixel-diff (compareCapturedScreenshots) always compares the true originals on both a fresh render and a cache hit, and the "click to open full-size" link keeps resolving to it. unified-comment-bridge.ts's cell() embeds the thumbnail for <img src> when present, falling back to the full-resolution URL otherwise (hosted mode, mobile rows, or a resize that didn't actually shrink anything) -- the href always points at the full-resolution original either way. Course-correction from #6324's original text, which proposed working in both hosted and self-host modes: hosted mode has no image-resizing primitive available in the Workers runtime (confirmed by downscaleForVision's own pre-existing header comment), so this mirrors that seam's own honest hosted-no-op / self-host-real split rather than inventing new Worker-side infrastructure to force parity.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-16 04:27:38 UTC
Review summary Nits — 5 non-blocking
Concerns raised — review before merging
📋 Copy for AI agents — paste into your coding agentDecision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://gittensory.aethereal.dev/docs/loopover-commands 🧪 Experimental — new and may change. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6347 +/- ##
==========================================
- Coverage 95.60% 95.59% -0.01%
==========================================
Files 597 597
Lines 47191 47203 +12
Branches 15019 15026 +7
==========================================
+ Hits 45117 45126 +9
Misses 1290 1290
- Partials 784 787 +3
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Summary
shot.tscaptures full-page, native-resolution PNGs (up to 1440px wide for the desktop viewport, taller still for a long page's full-page height), stored and embedded verbatim at<img width="360">— every viewer's browser previously downloaded the full-resolution capture just to render a 360px-wide thumbnail.downscaleForDisplay/isDisplayDownscaleAvailableinimage-downscale.ts(Worker no-op) +src/selfhost/stubs/image-downscale.ts(realsharp-based implementation, 720px width cap — 2x the display width for a sharp retina render, still a real reduction from 1440px) mirror the existingdownscaleForVisionseam's own hosted-no-op/self-host-real architecture exactly. Desktop-only:shot.ts's mobile viewport (390px) is already close enough to the table's 360px display width that a third resized copy wouldn't meaningfully help.capturePagestores the downscaled copy at a sibling R2 key on a fresh render (only when it genuinely shrinks the bytes, and only once the write is confirmed to succeed — caught a real bug in my own first pass here, wherethumbUrlwas set even when the write silently failed via a bare.catch(() => undefined)), and re-verifies the sibling's existence on a cache hit rather than assuming it from the original's own presence.compareCapturedScreenshots) always compares the true originals on both a fresh render and a cache hit, and "click to open full-size" keeps resolving to it.unified-comment-bridge.ts'scell()embeds the thumbnail for<img src>when present, falling back to the full-resolution URL otherwise (hosted mode, mobile rows, or a resize that didn't actually shrink anything) — thehrefalways points at the full-resolution original either way.Course-correction from #6324's original text, which proposed working in both hosted and self-host modes: hosted mode has no image-resizing primitive available in the Workers runtime (confirmed by
downscaleForVision's own pre-existing header comment: "a native image-resizing binding that can't run on the Cloudflare Workers runtime"), so this mirrors that seam's own honest hosted-no-op / self-host-real split rather than inventing new Worker-side infrastructure to force parity.Closes #6324 (together with #6341, already merged, which added the visible caption line)
Test plan
test/unit/image-downscale.test.ts+test/unit/selfhost-image-downscale-stub.test.tsextended: the Worker no-op, and the realsharpresize against actual PNG fixtures (including the exact 1440×2397 dimensions observed live on fix(ui): apply the pre-2000 placeholder rule in normalizeFreshnessSources metagraphed#6036) — 100% coverage on both filestest/unit/visual-capture.test.tsextended (11 new tests): thumbnail generation/storage, the desktop-only gate, the skip-when-nothing-shrunk optimization, decode-failure degradation, cache-hit re-verification (including the bug I found and fixed), S3-direct-bucket-URL linking, and — the most important correctness check — that pixel-diff always receives the ORIGINAL bytes, never the downscaled copy, even in the same capture pass that generated a thumbnailtest/unit/visual-collapsible.test.tsextended:<img src>prefers the thumb URL while<a href>always uses the full-resolution URL; falls back correctly when no thumb is presentnpm run typecheckcleannpm run test:cigate green, twice (before and after resolving a rebase conflict with feat(review): add a visible caption under each Visual/Scroll preview thumbnail #6341's merged caption change)