Skip to main content

Crate feather_reader

Crate feather_reader 

Source
Expand description

FeatherReader — a minimalist, atproto-native RSS/Atom feed reader.

Your feed subscriptions live in your own atproto PDS (via the open community.lexicon.rss.* community lexicon), so your reading list follows you across any compatible reader — you own your data, not the app. Minimalist by design.

This crate ships as a single server binary (featherreader) plus this small library, which declares the module tree and the shared types the binary and its subsystems build on. The heavy lifting lives in sibling modules:

  • config — env-driven runtime configuration (FEATHERREADER_*).
  • lexicon — the community.lexicon.rss.* record schemas (subscription, folder, saved, readState) as serde types.
  • store — the per-DID SQLite cache + read-state working copy (sqlx, runtime queries).
  • feed — polite fetching (conditional GET, backoff), feed-rs parsing, and ammonia sanitization.
  • atproto — the atproto identity + PDS record layer (subscriptions, folders, saved, batched read-state sync), including the Node sidecar’s client (atproto::SidecarClient).
  • oauth — the Rust-native atproto OAuth client (the rust repo backend, which production runs).
  • repo — the one dispatcher every com.atproto.repo.* call goes through, choosing the sidecar or the Rust client by FEATHERREADER_REPO_BACKEND.
  • standard_site — reading standard.site publications from their authors’ repos.
  • network — read-only queries against the public atproto network (the relay adoption probe). A projection, never a source of truth, and never on a reader path.
  • web — the axum router + askama server-rendered views.
  • sanitized_html — the reader’s article body, re-sanitized at render so the template never emits a stored string unescaped.

Status: experimental / pre-1.0. See https://feather-reader.com.

Modules§

atproto
The atproto identity + PDS record layer.
config
Runtime configuration for the FeatherReader server.
feed
Feed fetch → parse → sanitize → store pipeline.
lexicon
Serde types for the community.lexicon.rss.* atproto record schemas.
metrics
Side-by-side latency for the two repo backends.
net
Hardened outbound HTTP for untrusted, user-supplied feed URLs.
network
Read-only queries against the public atproto network.
oauth
Rust-native atproto OAuth — the replacement for the Node sidecar.
readstate
Read-state flushing — turning dirty local cursors into readState records in the user’s own PDS.
repo
The one place the two repo backends are chosen between, and timed.
runtime_health
What the background loops are actually doing, readable from a request.
safe_link
The href type.
sanitized_html
The reader view’s article body.
standard_site
Reading standard.site publications as feeds.
store
SQLite persistence layer (via sqlx, runtime queries).
vetted
Record types that cannot exist unvetted.
web
The axum web layer — server-rendered HTML + a dash of htmx, no SPA.

Structs§

AppState
Shared application state handed to every axum handler.
Session
One logged-in identity, resolved from the OAuth sidecar and keyed by DID.
SessionRegistry
In-memory session registry: opaque random session-id → Session.

Constants§

USER_AGENT
The User-Agent FeatherReader identifies itself with when fetching feeds.
VERSION
The crate version — surfaced for the server’s --version / health output.

Functions§

block_on_then_shutdown
Run future on a new multi-thread runtime — what #[tokio::main] builds — then shut that runtime down waiting at most shutdown for work still on its blocking pool, where dropping it would wait without limit. The server’s main runs on this; see its RUNTIME_SHUTDOWN_TIMEOUT for why (#226: an abandoned ingest sanitize cannot be cancelled).
build_http_client
The shared HTTP client AppState carries, also used by the binary’s maintenance commands (--revoke-all-sessions) so they reach the network exactly as the serving app does.