OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-proto-peer commits / 57620fa

0.3.123: get-record — read one record back over the UDS
get-state lists {collection, rkey} and no values, so a client can see THAT a record exists and never what it says. That makes "is what I would write already there?" unanswerable, and leaves a projector only a local fingerprint — state that drifts from the repo it claims to describe. Read-only, UDS-gated like the diagnostics beside it, and returns null rather than throwing for an absent record: "not written yet" is an ordinary state for a caller deciding whether to write. Added for favela-bridge, which needs to reconcile a projected bsky profile against the one actually in the repo rather than against its own belief about it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
57620fa22a5ffeb65cd565d993883dfa051459ab
by plankatron <fleeky@gmail.com> · 2026-09-09T22:55:28.000Z

Changed files (2) +12 -1

lib/serve-device-uds.js +11 -0
……@@ -64,6 +64,17 @@ export async function serveDeviceUds (device, { uds, blobs = null, onRelease = n
6464 // into a fresh line). Public (UDS is filesystem-owner-gated). Bytes as hex, matching get-blob.
6565 svc.handle('get-repo-car', async () => { const r = await device.exportCar(); return { car: b4a.toString(r.carBytes, 'hex'), commitCid: r.commitCid, dataCid: r.dataCid, rev: r.rev, recordCount: r.recordCount } })
6666 svc.handle('apply-write', async (ctx, op) => device.applyWrite(op))
67 // get-record: read ONE record back. get-state lists {collection, rkey} and no values, so a client
68 // could see THAT a record exists and never what it says — which makes "is what I would write
69 // already there?" unanswerable, and the only alternative is a local fingerprint that drifts from
70 // the repo. A projector reconciling desired-against-actual needs the actual.
71 //
72 // Read-only and UDS-gated like the diagnostics beside it. Returns null rather than throwing for an
73 // absent record: "not written yet" is an ordinary state for a caller deciding whether to write.
74 svc.handle('get-record', async (ctx, { collection, rkey } = {}) => {
75 if (!collection || !rkey) throw new Error('get-record: collection and rkey required')
76 try { return (await device.repo.getRecord(collection, rkey)) || null } catch { return null }
77 })
6778 // reconcile-bytes: ATTEMPT to pull the authoritative bytes for every converged pointer this node
6879 // cannot resolve. The daemon already runs this on a loop; exposing it gives an operator a way to
6980 // demand one NOW and read the result, which is what makes "is this record recoverable?" answerable.
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "hyper-proto-peer",
3 "version": "0.3.122",
3 "version": "0.3.123",
44 "description": "Self-custody, P2P-native atproto peer \u2014 holds the user's key + content as Hypercores and authors+signs its own repo. The source of truth in the peer/bridge split (Model B); atproto-bridge projects it to bsky.",
55 "type": "module",
66 "main": "lib/peer.js",