Tests can't override values captured at module load because ES imports hoist before any Deno.env.set call. Reading env on each helper invocation makes the module trivially testable and has no production cost (env doesn't change at runtime).
litenote-jetstream
Backend for Remanso, a blogging platform on the AT
Protocol. Listens to the Jetstream firehose for space.remanso.note records and
serves them via a REST API.
Prerequisites
Setup
# Initialize the SQLite database
deno task migrate
Development
# Run the Jetstream listener (with watch)
deno task jetstream
# Run the API server (with watch)
deno task server
Production
# Run both processes
deno task jetstream:prod & deno task server:prod
Docker
docker build -t litenote-jetstream .
docker run -p 8080:8080 -v litenote-data:/data litenote-jetstream
API
| Endpoint | Description |
|---|---|
GET /notes?cursor=&limit= |
Paginated notes from all users (discoverable only) |
GET /:did/notes?cursor=&limit= |
Paginated notes for a specific DID (discoverable only) |
GET /search?q=&cursor=&limit= |
Full-text fuzzy search across discoverable notes. Returns { results, cursor? } |
GET /:did/search?q=&cursor=&limit= |
Owner-scoped search incl. non-discoverable. Requires Authorization: Bearer <jwt> for that DID |
Search hits include { did, rkey, title, snippet, score, publishedAt }. The
snippet is a sentence-bounded fragment from the matching content with the
query terms wrapped in <em> tags. Queries use OpenSearch multi_match with
fuzziness: AUTO, so small typos still match.
Environment Variables
| Variable | Default | Description |
|---|---|---|
SQLITE_PATH |
notes.db |
Path to the SQLite database file |
OPENSEARCH_URL |
(unset) | OpenSearch base URL (e.g. http://opensearch:9200). When unset, indexing and search degrade to no-ops |
OPENSEARCH_USERNAME |
(unset) | Optional basic-auth user |
OPENSEARCH_PASSWORD |
(unset) | Optional basic-auth password |
OPENSEARCH_INDEX |
notes |
Index name to read/write |
ADMIN_DIDS |
(empty) | Comma-separated DIDs allowed to hit /admin/* |
OpenSearch backfill
Note content arrives via the jetstream firehose only for new and updated records. To populate the index with pre-existing notes, run:
OPENSEARCH_URL=http://localhost:9200 deno task backfill:search
The script reads every DID in the local SQLite database, resolves each one's
PDS, and reindexes their notes via com.atproto.repo.listRecords. Safe to
re-run; document IDs are deterministic (<did>:<rkey>).