evbogue/dovepds
APDS-based personal data server for anproto
{ "createdAt": "2025-11-14T21:08:19Z", "defaultBranch": "main", "description": "APDS-based personal data server for anproto", "fullName": "evbogue/dovepds", "homepage": null, "language": "JavaScript", "name": "dovepds", "pushedAt": "2025-11-14T22:14:17Z", "stargazersCount": 1, "topics": [], "updatedAt": "2025-11-14T23:42:05Z", "url": "https://github.com/evbogue/dovepds"}dovepds — Dove Personal Data Server
Section titled “dovepds — Dove Personal Data Server”This project runs an APDS/anproto‑based personal data server (dovepds) using Deno. It discovers and syncs messages and blobs from APDS peers, serves them to browser clients over WebSockets, and gossips missing items aggressively with per‑peer backoff.
Usage
- Start:
deno run -A main.js <appname> [--port=48080] [--log|-v] - Or via task:
deno task start(defaults toapds) - Permissions: uses
-A(APIs: timers, env, Web Cache API)
Commands
- Manage pubs:
- Add:
deno run -A main.js addpub wss://pub.wiredove.net - Remove:
deno run -A main.js rmpub wss://pub.wiredove.net
- Add:
- Manage follows:
- Follow:
deno run -A main.js follow <pubkey> [more...] - Unfollow:
deno run -A main.js unfollow <pubkey> [more...]
- Follow:
- View log:
deno run -A main.js log [appname](pretty JSON of opened log)
- Get by key or author pubkey:
deno run -A main.js <appname> get <hash>- If
<hash>is a blob key and present, prints blob - If
<hash>is a 44‑char author pubkey and present, prints latest signature
- If
Flags
--port=<n>(default48080) — WebSocket server port for browser clients--logor-v— verbose logging (connections, asks/fulfilled, payload info)
WebSocket Server
- Listens on
ws://localhost:<port>(default 48080) - Browser client can:
- Send a key; server responds with the blob if
apds.get(key)returns data - Send a 44‑char author pubkey; server responds with
latest.sigif known - Send a signed message or blob; server ingests it and discovers links
- Send a key; server responds with the blob if
- If a browser requests a 44‑char key we don’t have, it’s enqueued for gossip immediately.
Config
dovepub.jsonis created on first run with:pubs: WebSocket pub peers (seeded withwss://pub.wiredove.net)follows: author pubkeys to gossip for
- File is reloaded every 10s; pub connections update live; follows merge in.
Gossip Strategy
- Discovery
- Periodically scans
apds.query()to find missing hashes:- From
opened: takesopened.substring(13, 57)and enqueues if missing - Parses YAML message bodies to find
previous,reply, andreplyTo- Enqueues missing
previous/reply - Adds
replyToauthors tofollows
- Enqueues missing
- Also scans
imageandbodyfor boundary‑aware 44‑char hashlinks - Always skips
sig(signatures are not gossiped)
- From
- On inbound messages (from pubs or browser), stores blobs, parses YAML, and enqueues discovered links with provenance.
- Periodically scans
- Asking
- A 1ms ticker asks peers for items:
- Prioritizes
gossipMissing(missing hashes), then followed authors - Targets both pub peers and browser clients
- Tracks per‑hash, per‑peer exponential backoff (up to 5m w/ jitter) to avoid hammering the same server for the same hash
- Verbose logs include source provenance (opened, yaml.previous, pub.request, ws.request, etc.)
- Prioritizes
- A 1ms ticker asks peers for items:
- Pruning
- Every 10s checks
gossipMissingagainstapds.get()and removes fulfilled hashes
- Every 10s checks
Protocol
- dovepds speaks APDS on top of anproto (AN). APDS handles hashing/signing/opening of messages using anproto primitives; dovepds orchestrates discovery, gossip, and serving over WebSockets.
Further Reading
- anproto: https://anproto.com
Distribution
- Pub peers and browser clients can request:
- A blob key → server replies with the blob if present
- An author pubkey (44 chars) → server replies with the latest signature if known
- Otherwise, the 44‑char request is queued for gossip
Progress Bar
- Shows in place every 5s (quiet mode):
[##########----------] <have>/<total> missing <n> | db <count>have= opened log entriesmissing=gossipMissing.sizedb= have + blobs from pub peers + blobs from browser clients
Notes
- APDS uses the Web Cache API for storage.
- The server maintains persistent WebSocket connections to
pubswith exponential backoff. - Verbose mode (
--log/-v) prints detailed gossip activity and payload headers.
MIT