Skip to content

Add session-authorized Storage images for React - #518

Merged
kvz merged 5 commits into
mainfrom
viewer-react
Sep 25, 2026
Merged

kvz merged 5 commits into
mainfrom
viewer-react

Conversation

@kvz

@kvz kvz commented Sep 25, 2026 •

Copy link
Copy Markdown
Member

Why

Dynamic albums need to pass canonical Storage receipts to React while checking current application permissions on every image and download request. This adds @transloadit/viewer/react and a Web-standard @transloadit/viewer/server route, without proxying image bytes through the application or making Viewer own gallery/auth state.

Contract

  • One receipt-returning authorization callback checks each request. Preview, original and download permissions are separate; delivery pins the retained asset/version and enforces finite server-owned renditions, crops and rotating CDN lifetimes.
  • Application redirects are private/no-store. Previously issued CDN URLs remain usable until their signed expiry/cache policy permits; this is not instant CDN revocation.
  • React reuses the existing image model and picture renderer. Optional placeholder="blur" uses the receipt's ThumbHash through a bounded decoder shared with Next. No native dependencies, new runtime dependencies or load handlers. Transparent and letterboxed images stay empty; crop placeholders preserve proportions.
  • Returning a private hash reveals preview pixels: the data query must authorize that metadata first. Next's request-authorized private path continues to omit inline preview pixels. Mirror stylesheet object-fit through the explicit objectFit prop for SSR safety.
  • Strict Assembly receipt extraction lives in narrow Zod v3/v4 entries and is reused by Node. Failed Assemblies, including ok: null, retain their failure code. Utils stays dependency-free.
  • Viewer remains alpha. The README distinguishes published static Next usage from these upcoming dynamic React entries, explains the integration-path chooser, and states extraction cost and rendering boundaries.

Validation

Target: e521c0010618cbe3379a2af78b97dbc2dbc5044a.

  • Local yarn check and verify:full pass: 456 Viewer tests and 863 Node tests (one existing skip), plus Zod v3/v4 and the other workspace/script checks.
  • The packed Next fixture passes 146 Chromium/WebKit checks: 68 with Cache Components, 68 without, and ten development checks, plus 15 packed CLI tests. No retries or skips. Includes delayed blur, alpha/letterboxing/crops, withheld private hashes, request authorization, expired grants and exact-byte downloads.
  • Council findings were reproduced red-first and fixed, including cropped blur proportions and nullable failed-Assembly status. Evidence-bound Claude UX/security review found no authorization regression. Its stylesheet-fit and native error-UI limitations are documented rather than hidden behind new client state.
  • Independent local desktop/mobile exploratory checks passed with no console errors or failed requests. These use real synthetic image bytes on a fake CDN, not a new production canary.
  • Bundle/install-footprint, worker/browser export boundaries and SDK Supabase Edge checks are retained. The complete React entry measured 17,880 bytes minified / 6,443 Brotli excluding React before the final one-line cover adjustment; the decoder adds about 1.3 KB Brotli. The Web handler remains decoder-free.
  • Exact-head CI is green, including the packed Next fixture, Edge, E2E, Node 20/22/24, full verification and release dry run. Earlier final-artifact Content rendering comparisons and production/Convex ingestion/session proofs are recorded in the contract; those are prior-head evidence, not a fresh production proof for this follow-up.

Release and follow-up

Released through Changesets #519: Viewer 0.0.3 (alpha), Node/Types/Zod/legacy 5.0.1, MCP 0.4.1. The release workflow and release-commit CI are green. npm's alpha tag points to Viewer 0.0.3; its legacy latest tag remains 0.0.1, and the GitHub release is explicitly a prerelease.

A clean npm-registry consumer passes five additional smoke tests for blur, current authorization, exact-version delivery and Zod v3/v4 extraction, without Next or Sharp installed. Publication needed one same-commit retry after npm accepted but temporarily hid staged versions; no version bump or tag workaround was used. Convex #33 now switches to exact registry versions and removes its preview tarballs/overrides.

The finish checklist records ownership and evidence. No production deployment, new Storage canary or credential changes are included. API2 #9253 remains a separate deferred follow-up.

@kvz kvz self-assigned this Sep 25, 2026
@kvz
kvz merged commit dc7d42d into main Sep 25, 2026
14 checks passed
@kvz
kvz deleted the viewer-react branch September 25, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant