Skip to content

feat(catalog): Frontend companion to the preview/lambda feature PR #4936#4937

Closed
Austin-s-h wants to merge 23 commits into
feat/preview-lambda-featuresfrom
feat/preview-frontend
Closed

feat(catalog): Frontend companion to the preview/lambda feature PR #4936#4937
Austin-s-h wants to merge 23 commits into
feat/preview-lambda-featuresfrom
feat/preview-frontend

Conversation

@Austin-s-h

@Austin-s-h Austin-s-h commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Description

Frontend companion to the preview/lambda feature PR (#4936). Adds catalog
rendering for the new preview-lambda capabilities, hardens preview error
handling, and isolates preview crashes so one bad file can no longer blank an
entire page. Also includes the CI-unblocking fixes that landed on this branch.

Stacked PR: base is feat/preview-lambda-features (#4936); this branch is the
base for feat/local-catalog (#4938).

Preview rendering features

  • FCS — render a Vega-Lite scatter chart when the preview lambda emits a
    vegaLite spec (loaders/Fcs.js, renderers/Fcs.jsx, types.js).
  • Video/transcode — request video/webm transcoding for video previews
    (loaders/Video.tsx).
  • PDF/PPTX — pre-sign the URL via useMemoEq, raise preview resolution to
    w2048h1536, and fix an infinite re-render loop in the renderer by holding
    sign/firstPageBlob in refs (loaders/Pdf.js, renderers/Pdf.jsx,
    loaders/utils.js).
  • TextFallback — new always-on fallback loader/renderer: any file not
    claimed by a type-specific loader is previewed as text via the preview
    lambda, with a binary-sniff fallback that shows a clean
    "Binary file — no text preview available" message instead of dumping bytes
    (loaders/TextFallback.tsx, registered in load.jsx immediately before the
    generic fallback).
  • Perspective/h5ad — surface error and matrix_preview/
    matrix_preview_error fields; render an explicit PreviewError instead of a
    blank Perspective panel when the tabular_preview lambda returns an error
    envelope (loaders/Tabular.tsx, renderers/Perspective/Metadata.tsx).

Error handling & crash isolation

  • PDF retry — re-throw the raw error from the loader instead of
    pre-building PreviewError.Unexpected with retry: null, so useErrorHandling
    attaches data.fetch and transient failures (timeouts, temporary 5xx) keep
    their retry button (loaders/Pdf.js).
  • Text null-envelope guards — throw a clean PreviewError when the lambda
    returns { info: null } or a payload missing info.data, instead of a raw
    TypeError (loaders/Text.js, loaders/TextFallback.tsx).
  • Unsupported messagePreviewError.Unsupported now carries an optional
    message rendered by PreviewDisplay (types.js, Display.jsx).
  • Error boundaries — wrap the File-page preview (File.jsx) and each
    Summarize file preview (Summarize.tsx) in error boundaries that reset on
    handle change, so a single failing preview no longer crashes the whole view.

CI / build fixes on this branch

  • Pdf.spec.ts — correct a TypeScript-incompatible useErrorHandling
    mock return value ({ tag: 'Handled' }{ value, options } shape) that
    failed npm run build with TS2345.
  • File/ErrorBoundary and Summarize.ErrorBoundary spec helpers annotated
    : never so the production build (ForkTsCheckerWebpackPlugin type-checks spec
    files) accepts the throwing JSX child.
  • De-flake the useQueryRun empty-database test by polling with waitFor
    instead of waitForValueToChange.
  • Routes.tsfromBucketPathParams helper to keep the path-params schema
    types consistent across routes.
  • Prettier 3.4.2 formatting applied where CI's prettier --check flagged it.

TODO

  • Unit tests
  • Security: Confirm that this change meets security best practices and does not violate the security model
  • Open and Embed: Confirm that this change doesn't break Open variant and Embed widget
  • Documentation
    • run optipng on any new PNGs (none added)
    • Python: Run build.py for new docstrings (no Python docstring changes)
    • JavaScript: basic explanation of new features (see Description)
    • Markdown in docs (docs/Catalog/Preview.md: FCS scatter + binary-file fallback; linked from SUMMARY.md)
    • Markdown docs for developers (inline module docs in TextFallback.tsx, Tabular.tsx)
  • Changelog entry (new Catalog section under unreleased)

Frontend companion to the preview/lambda feature PR.

* FCS: render Vega-Lite scatter when the preview emits a vegaLite spec
  (loaders/Fcs, renderers/Fcs) + specs.
* Video/transcode: request webm transcode for video previews
  (loaders/Video).
* PDF: pre-sign the URL, raise preview resolution, wrap errors in
  PreviewError, fix an infinite re-render loop (loaders/Pdf,
  renderers/Pdf) + specs.
* TextFallback: new loader/renderer with a binary-sniff text fallback
  (loaders/Text, loaders/TextFallback) + specs.
* Perspective/h5ad: surface error / matrix_preview fields
  (renderers/Perspective, types.js).
* Crash isolation: error boundaries around the file preview view and
  Summarize (File.jsx, Summarize.tsx) + specs.
* usePreview/Pdf: pre-compute the signed URL with useMemoEq instead of
  signing inside the loader (loaders/utils.js).

Verified: prettier + eslint clean; vitest 84 passed across the changed
and new spec files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.96078% with 49 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.74%. Comparing base (c5ce526) to head (e45fe1e).

Files with missing lines Patch % Lines
catalog/app/containers/Bucket/Summarize.tsx 13.33% 10 Missing and 3 partials ⚠️
catalog/app/components/Preview/loaders/Tabular.tsx 0.00% 8 Missing and 1 partial ⚠️
catalog/app/components/Preview/renderers/Pdf.jsx 0.00% 7 Missing and 1 partial ⚠️
...atalog/app/components/Preview/loaders/Notebook.tsx 0.00% 3 Missing and 1 partial ⚠️
catalog/app/components/Preview/loaders/utils.js 20.00% 4 Missing ⚠️
catalog/app/containers/Bucket/File/File.jsx 0.00% 4 Missing ⚠️
catalog/app/components/DataGrid.tsx 0.00% 1 Missing ⚠️
catalog/app/components/Filters/NumbersRange.tsx 0.00% 1 Missing ⚠️
catalog/app/components/JsonEditor/PreviewValue.tsx 0.00% 1 Missing ⚠️
catalog/app/components/Preview/loaders/Audio.tsx 0.00% 1 Missing ⚠️
... and 3 more
Additional details and impacted files
@@                       Coverage Diff                        @@
##           feat/preview-lambda-features    #4937      +/-   ##
================================================================
+ Coverage                         46.95%   47.74%   +0.79%     
================================================================
  Files                               833      819      -14     
  Lines                             34383    34123     -260     
  Branches                           5834     5780      -54     
================================================================
+ Hits                              16145    16293     +148     
+ Misses                            16239    15859     -380     
+ Partials                           1999     1971      -28     
Flag Coverage Δ
api-python 93.15% <ø> (ø)
catalog 22.47% <51.96%> (+0.92%) ⬆️
lambda 96.94% <ø> (ø)
py-shared 98.02% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread catalog/app/components/Preview/loaders/Pdf.js Outdated
Comment thread catalog/app/components/Preview/loaders/Text.js
Austin Hovland and others added 3 commits June 1, 2026 21:57
…ting

- Pdf.js: re-throw the raw error instead of pre-building
  PreviewError.Unexpected with retry: null. The pre-built error passed through
  useErrorHandling's R.unless(PreviewError.is, …) unchanged, so transient
  failures (timeouts, temporary 5xx) lost their retry button. Re-throwing lets
  useErrorHandling attach data.fetch as the retry handler (original behavior).
- Text.js: throw PreviewError.Unexpected when info is null/undefined before
  destructuring it, so a { info: null } envelope shows the clean custom message
  instead of a raw TypeError caught by R.tryCatch.
- Apply prettier 3.4.2 formatting to Perspective.tsx and Search/Table/Table.tsx
  (flagged by CI's prettier --check), unblocking test-catalog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The File/ErrorBoundary test helper threw without a return annotation, so TS
inferred `void` and the production build (ForkTsCheckerWebpackPlugin, which
type-checks spec files too) rejected it with TS2786 "cannot be used as a JSX
component". Annotate it `: never`, matching the working sibling helper in
Summarize.ErrorBoundary.spec.tsx.

(The requests.spec.ts CI failure was a transient flake — the test passes
reliably under CI-matched deps; no change needed there.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The test waited with waitForValueToChange(() => result.current), which only
resolves on a reference change. The tuple ref could update while
result.current[0] was still undefined, so the immediate toBeNull() assertion
raced and failed intermittently in CI ("expected undefined to be null").
Poll with waitFor(() => expect(result.current[0]).toBeNull()) instead, which
settles deterministically regardless of timing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Austin-s-h Austin-s-h added enhancement javascript Pull requests that update Javascript code labels Jun 2, 2026
@Austin-s-h
Austin-s-h force-pushed the feat/preview-lambda-features branch from 0c1aab6 to 7362800 Compare June 2, 2026 17:41
Austin Hovland and others added 2 commits June 2, 2026 14:47
preview.py was migrated from fcsparser to flowio for FCS parsing, but the
`preview` optional-dependency in lambdas/shared/pyproject.toml still pinned
`fcsparser~=0.2.1`. CI installs deps from the lockfiles, so `import flowio`
raised ModuleNotFoundError and every FCS code path fell through to the
"Unable to parse data or metadata" fallback — failing test_fcs in the
shared, indexer, and preview lambda suites.

Swap the extra to `flowio~=1.4` and regenerate the workspace + preview locks
(shared and indexer resolve flowio transitively via t4-lambda-shared[preview]).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Austin-s-h
Austin-s-h force-pushed the feat/preview-lambda-features branch from 3552c62 to 49aad46 Compare June 2, 2026 19:14
@Austin-s-h

Copy link
Copy Markdown
Collaborator Author

@greptile re-review

Comment thread catalog/app/components/Preview/loaders/TextFallback.tsx Outdated
Copilot AI changed the title feat(catalog): preview rendering features and crash isolation fix(catalog): resolve test-catalog build failure in Pdf.spec.ts Jun 7, 2026
@Austin-s-h Austin-s-h changed the title fix(catalog): resolve test-catalog build failure in Pdf.spec.ts feat(catalog): Frontend companion to the preview/lambda feature PR #4936 Jun 7, 2026
@Austin-s-h

Copy link
Copy Markdown
Collaborator Author

Closing in favor of smaller, independently-reviewable PRs harvested from this work and rebased cleanly onto master (this branch was stacked on the uv-workspace base, which is being set aside per discussion with the Quilt team).

The preview frontend work is superseded by:

Closing to keep the review queue clean; happy to reopen if any of the split PRs miss something.

@Austin-s-h Austin-s-h closed this Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants