web #
The client: TypeScript and React, bundled by Vite, run with Bun. Deployed to Cloudflare Pages from the repo on commit.
just serve-client # the dev server, hot reloading
just ts # what CI runs: biome, tsc, bun test, vite build
The catalog comes from the other origin, so just serve has to be running
too: it exports the artifact from the cache and sends the
Access-Control-Allow-Origin the bucket has to send in production.
src/config.ts holds the two origins.
src/catalog/ reads it — load.ts fetches, store.ts keeps the bytes in
IndexedDB under their content-addressed names, rows.ts finds the row
boundaries in them, columns.ts and strings.ts hold what it reads out,
index.ts answers questions of the pair, search.ts scans names and
query.ts parses the search syntax. Only load.ts touches the network or
IndexedDB, which is what leaves the format and the ranking testable under
bun test.
public/oauth/client-metadata.json is the OAuth client metadata document.
Vite copies public/ into dist/ verbatim, which is what serves it at
/oauth/client-metadata.json — the URL its client_id has to equal. The
client imports the same file for the scopes it requests.
Editing it is a protocol change, not a config change:
docs/atproto.md says what it has to keep saying, and
bun run check in tools/lexicon-check enforces it.