Living Database (self-contained .html)

at1 page builds a single self-contained .html file that is its own searchable database. It fuses three things into one openable file: a WASM decoder (~84 KB), the .at1 archive (base64-embedded), and an in-browser query engine — full-text search, typed column filters, a sortable/paginated table, and CSV export. No server, no install, nothing uploaded; every search runs locally in the tab, and the original data is recoverable byte-for-byte from the HTML.

Build one

at1 page data.csv archive.html              # CSV/table -> one searchable .html
at1 page data.at1 archive.html              # wrap an existing queryable .at1
at1 page data.csv archive.html --title "Sales" --subtitle "Q1 2024"

The first argument is the source; the optional second is the output .html (it defaults from the source name). For a CSV/table the encoder sniffs the header row so the page shows named columns, infers per-column types, and compresses through the verification gate. Pass --title / --subtitle to brand the page.

Honest scope: the living-database build uses the queryable zstd profile (the embedded WASM decoder carries no lzma), so a non-.at1 input is recompressed with that profile on the way in. A typical page is the archive plus the ~84 KB decoder — small enough to email.

Searchable documents — PDFs, Word, bundles

at1 page makes documents full-text searchable without unpacking them. Point it at a file and it turns the text layer into a searchable table:

at1 page report.pdf report.html             # PDF -> searchable, one row per page
at1 page contract.docx contract.html        # Word .docx -> one row per paragraph
at1 page mybundle.at1 archive.html          # a bundle of PDFs/Word docs -> one combined table
  • PDF — per-page text extracted with pypdf; one row per page (columns page, text).
  • Word .docx — one row per paragraph (columns paragraph, text).
  • A bundle (an .at1 archive of many PDFs/Word docs) — one combined table across every document, with a file column so you can see which document each hit came from.

Text-layer documents only — a scanned/image-only PDF has no text and is reported as non-searchable (OCR is out of scope). The file still compresses byte-for-byte; it just isn't searchable. Use at1 decompress to get the original files back.

In the browser

Whoever opens the file double-clicks it and gets a branded search UI: a full-text search box across all text columns, advanced filters per named column (ranges and equality on numbers, contains/equals/starts-with on text, case-insensitive option), a sortable, paginated results table with expandable rows, and one-click Export CSV or Download .at1. A chip strip shows row/column counts, KB on disk, and a verified losslessmarker. It works offline and is mobile “Add to Home Screen”-friendly.

How it works

The query engine drives the same engine-agnostic core compiled to WebAssembly. It opens the embedded archive in an in-memory filesystem, reads the per-block zone maps, and on each query skips row-groups it can rule out before decoding only the surviving blocks — the same pushdown you get from the CLI, now running client-side. The count line even reports scanned N/M blocks, K skipped. Because the bytes embedded in the page are a normal .at1, the data is recoverable byte-for-byte and an embedded checksum proves it's unchanged.

Use cases

  • Share a queryable dataset by email, USB stick, or any static host — the recipient needs no account, no install, and no network.
  • Offline analysis — a single file that opens as a searchable database on any device, in any browser.
  • Searchable document archives — turn a report, contract, or a whole bundle of PDFs/Word docs into one offline, full-text-searchable file.

It's also available from the desktop app (one click to export a Living Database), and you can browse live demos before installing anything.