feat: implement Jetstream firehose subscription for atBB records
Implemented a complete firehose subscription system that connects to AT Proto Jetstream,
filters for space.atbb.* records, and indexes them into the PostgreSQL database.
Key Changes:
**Firehose Service** (packages/appview/src/lib/firehose.ts):
- Created FirehoseService class using @skyware/jetstream client
- Subscribes to space.atbb.post, space.atbb.forum, space.atbb.category,
space.atbb.membership, space.atbb.modAction, and space.atbb.reaction collections
- Implements connection lifecycle with automatic reconnection and exponential backoff
- Tracks cursor position in database for resume-from-last-position functionality
- Handles create, update, and delete events for all record types
**Record Indexer** (packages/appview/src/lib/indexer.ts):
- Implements database operations for all space.atbb.* record types
- Handles posts (topics and replies) with forum references and reply chains
- Creates users on-the-fly when new records are encountered
- Implements soft delete for posts (sets deleted flag)
- Parses AT Proto URIs to resolve foreign key references
- Handles forum, category, membership, and moderation action records
**Database Schema**:
- Added firehose_cursor table to track Jetstream event position
- Supports resuming from last known cursor after restarts
- Migration generated: drizzle/0001_daily_power_pack.sql
**Configuration**:
- Added JETSTREAM_URL environment variable
- Defaults to wss://jetstream2.us-east.bsky.network/subscribe
- Integrated firehose service with appview server startup
- Implements graceful shutdown to properly close WebSocket connections
**Dependencies**:
- Added @skyware/jetstream v0.2.5 to appview
- Added @atproto/api, @atproto/xrpc, @atproto/lexicon, multiformats to lexicon package
- Updated package exports to support direct type imports
**Integration**:
- Firehose starts automatically when appview server starts
- Handles SIGTERM and SIGINT for graceful shutdown
- Logs all record operations (create/update/delete) for debugging
Note: TypeScript build currently has issues with generated lexicon types missing .js
extensions. Runtime execution with tsx works correctly. This will be addressed in a
future update to the lexicon generation process.
Resolves ATB-9
https://claude.ai/code/session_01PaA43d9Q2ztwuRS8BRzJEL