Jetstream was running backgrounded in the same container as the API server, so crashes went undetected and Docker never restarted it. Now each process runs as a separate docker-compose service with independent restart policies. Also adds cursor persistence to SQLite (saved every 5s) so restarts resume from where they left off, moves event destructuring inside try/catch blocks, and adds global unhandled error/rejection handlers for crash visibility.
55 lines
1.7 KiB
Markdown
55 lines
1.7 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with
|
|
code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
litenote-jetstream is the backend for Remanso, a blogging platform built on the
|
|
AT Protocol (Bluesky ecosystem). It has two processes:
|
|
|
|
1. **Jetstream listener** (`jetstream.ts`) — Subscribes to the AT Protocol
|
|
firehose via `@skyware/jetstream`, filtering for `space.remanso.note`
|
|
records. On create/update events, it upserts notes into a local SQLite
|
|
database.
|
|
2. **HTTP API server** (`server.ts`) — An Oak (Deno HTTP framework) server on
|
|
port 8080 that exposes read-only endpoints to query stored notes.
|
|
|
|
Both processes share the same SQLite database (`src/data/db.ts`).
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Run jetstream listener (dev, with watch)
|
|
deno task jetstream
|
|
|
|
# Run API server (dev, with watch)
|
|
deno task server
|
|
|
|
# Run both for production (as in Docker)
|
|
deno task jetstream:prod & deno task server:prod
|
|
|
|
# Run database migration
|
|
deno task migrate
|
|
|
|
# Lint
|
|
deno lint
|
|
|
|
# Format
|
|
deno fmt
|
|
```
|
|
|
|
## Architecture
|
|
|
|
- **Runtime**: Deno (not Bun, despite the README). Uses `deno.json` for task
|
|
definitions and import maps.
|
|
- **Database**: SQLite via `https://deno.land/x/sqlite/mod.ts`. DB path is
|
|
configurable via `SQLITE_PATH` env var, defaults to `notes.db`.
|
|
- **Note schema**: Defined as an AT Protocol lexicon in
|
|
`lexicons/space/remanso/note.json`. Notes have `title`, optional `images`
|
|
(blob refs), `publishedAt`, and `createdAt`. Primary key is `(did, rkey)`.
|
|
- **API endpoints**:
|
|
- `GET /notes?cursor=&limit=` — paginated notes (all users)
|
|
- `GET /:did/notes?cursor=&limit=` — paginated notes for a specific DID
|
|
- **Pagination**: cursor-based using `rkey`, descending order.
|