Data viewer: read-only db.inspect() + a /viewer route over the demo store#25
Merged
Conversation
…tore Adds db.inspect(version?) to the core surface (Design §13): a read-only, format-agnostic projection of the otherwise-private manifest — version, committedAt, formatVersion, and per-table chunks with row counts and primary-key/partition zone-map min/max. Deliberately a derived shape, not the raw Manifest, so on-store format evolution can't break the contract. Reads manifest metadata only (lighter than export()), returns no blob URLs, and resolves any retained past version exactly as asOf does. Builds the read-only web UI from the §14 roadmap in the test-lab app: - app/api/inspect + app/api/viewer-rows (paged rows with asOf time travel and pruned-vs-scanned stats; table/sort identifiers whitelisted against the code-first schema, so no user values reach the SQL string) - app/viewer: table browser (paged, click-to-sort), a version scrubber (time travel), and a chunk/zone-map internals panel; linked from the home header Verified: tsc clean, lint clean, next build green, api-smoke 35/35 against the real Blob store (5 new inspect assertions), and the routes exercised live against the demo store incl. past-version time travel and the injection guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…keletons Fetch the viewer's data with @tanstack/react-query (provider scoped to the /viewer route via a route layout). Both queries use placeholderData: keepPreviousData so the table never collapses during a fetch. The table structure is now always on screen: /api/inspect returns each table's schema (columns/types/pk/partition, via a shared app/lib/viewer helper), so the client draws headers and tabs from the schema before any row loads. Row cells and chunk rows fall back to skeleton loaders while the page/version/table they belong to is in flight — pagination keeps the previous page (keepPreviousData), while a table or version switch shows skeletons under the correct new headers (guarded by matching table+version, so stale rows never paint under new columns). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 2.6.0 is already on npm; the new public API needs a minor bump or the main-push publish job fails on the duplicate version - api.mdx: inspect() in the surface block + its own section (incl. the tier-A visibility note: durable-but-unfolded appends appear at fold, like any cross-instance reader) - test-lab.mdx: the /viewer walkthrough - CLAUDE.md: inspect added to the §13 surface invariant Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds the read-only web UI from the §14 roadmap ("non-engineers love to see their data"), and adds the one core primitive it needs.
Core:
db.inspect(version?)(Design §13)A read-only, format-agnostic projection of the otherwise-private manifest —
version,committedAt,formatVersion, and per-table chunks with row counts and primary-key / partition zone-map min/max. Deliberately a derived shape, not the rawManifest, so on-store format evolution can't break the contract.export()(which also reads every chunk).asOfdoes (throwsVERSION_NOT_FOUNDif pruned).export()is), and §14.Viewer (test-lab app)
app/api/inspect+app/api/viewer-rows— paged rows withasOftime travel and pruned-vs-scanned stats. Table and sort identifiers are whitelisted against the code-first schema and page bounds coerced to ints, so no user values reach the SQL string (and the parser rejects statement stacking regardless).app/viewer— table browser (paged, click-to-sort), a version scrubber (time travel, commits on release so it doesn't hammer Blob), and a chunk/zone-map internals panel. Linked from the home header.Scrubbing the demo store is itself a demo of the architecture: at an early version
customersis a single 6-row chunk on format 3; at the live head it's 3 chunks on format 4 — copy-on-write and format evolution, made visible.Verification
bunx tsc --noEmit— cleanbun run lint— cleanbunx next build— green (all three routes registered)bun scripts/api-smoke.ts— 35/35 against the real Blob store, including 5 newinspect()assertions (current + past-version time travel, zone-map presence, loud failure on an unretained version)inspect,viewer-rowswith real zone maps and pruning stats, unknown-table guard → 400, pruned version → 404Rebased onto
main(2.6.0 secondary indexes) — no conflicts;inspect()coexists with the new index code.🤖 Generated with Claude Code