OverviewFilesCommitsIssuesDocsReleasesPeers

atproto-bridge commits / 27ff2c2

0.9.38: pass listRecords paging params through
The lexicon's limit/reverse/cursor were parsed by nobody: they arrived at the membrane and were dropped before reaching read-view, which also ignored them. Both ends are fixed (atproto-store 0.0.20, atproto-did-peer 0.2.10); this threads the query params through and returns { records, cursor } verbatim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
27ff2c2780f0a82597095b9f46b54a5dd4e35e87
by plankatron <fleeky@gmail.com> · 2026-08-01T00:57:01.000Z

Changed files (5) +20 -6

package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "atproto-bridge",
3 "version": "0.9.37",
3 "version": "0.9.38",
44 "description": "Stateless keyless atproto MEMBRANE \u2014 fronts self-custody hyper-proto-peers to bluesky over HTTP/WS, holds no keys and never signs. Bare-runnable. Deploy root / flat closure over the identity+repo+store+pds packages.",
55 "type": "module",
66 "main": "index.js",
pds/lib/server-bare.js +8 -1
……@@ -216,7 +216,14 @@ export function createPdsServer ({ peers = null, serverDid = null, availableUser
216216 case 'com.atproto.repo.listRecords': {
217217 const front = await frontIfPeer(q.get('repo') || q.get('did') || undefined)
218218 if (!front) return sendErr(res, 404, 'RepoNotFound', 'repo not fronted here')
219 return sendJson(res, 200, { records: await front.listRecords(q.get('collection')) })
219 // The lexicon's params were parsed by nobody: limit/reverse/cursor arrived here and were
220 // dropped, so a paging client looped on a cursor that never advanced. `records` and
221 // `cursor` are spread through verbatim — cursor absent means "last page".
222 return sendJson(res, 200, await front.listRecords(q.get('collection'), {
223 limit: q.get('limit') ? Number(q.get('limit')) : 50,
224 reverse: q.get('reverse') === 'true',
225 cursor: q.get('cursor') || null
226 }))
220227 }
221228 case 'com.atproto.repo.describeRepo': {
222229 const front = await frontIfPeer(q.get('repo') || q.get('did') || undefined)
pds/lib/server.js +8 -1
……@@ -136,7 +136,14 @@ export function createPdsServer ({ peers = null, serverDid = null, availableUser
136136 case 'com.atproto.repo.listRecords': {
137137 const front = await frontIfPeer(q.get('repo') || q.get('did') || undefined)
138138 if (!front) return sendErr(res, 404, 'RepoNotFound', 'repo not fronted here')
139 return sendJson(res, 200, { records: await front.listRecords(q.get('collection')) })
139 // The lexicon's params were parsed by nobody: limit/reverse/cursor arrived here and were
140 // dropped, so a paging client looped on a cursor that never advanced. `records` and
141 // `cursor` are spread through verbatim — cursor absent means "last page".
142 return sendJson(res, 200, await front.listRecords(q.get('collection'), {
143 limit: q.get('limit') ? Number(q.get('limit')) : 50,
144 reverse: q.get('reverse') === 'true',
145 cursor: q.get('cursor') || null
146 }))
140147 }
141148 case 'com.atproto.repo.describeRepo': {
142149 const front = await frontIfPeer(q.get('repo') || q.get('did') || undefined)
pds/test/peer-front.test.js +1 -1
……@@ -98,7 +98,7 @@ test('bridge PeerFront serves a remote peer getRepo + subscribeRepos — KEYLESS
9898 // keyless read surface (from the replicated repo/firehose)
9999 const rec = await front.getRecord('app.bsky.feed.post', '3a')
100100 t.is(rec && rec.value.text, 'fronted', 'getRecord returns the peer record')
101 const list = await front.listRecords('app.bsky.feed.post')
101 const { records: list } = await front.listRecords('app.bsky.feed.post')
102102 t.ok(list.some(r => r.value.text === 'fronted'), 'listRecords includes the record')
103103 const latest = await front.getLatestCommit()
104104 t.ok(latest && latest.cid && latest.rev, 'getLatestCommit returns { cid, rev }')
pds/test/peer-restart-durability.test.js +2 -2
……@@ -61,7 +61,7 @@ test('peer RESTART (same keys) — front self-heals, new commit replicates witho
6161 // corestore.replicate re-attaches them to a FRESH connection after a flaky-link drop (direction-free).
6262 t.ok(front.seq.core.replicator && front.seq.core.replicator.downloading, 'FIX: firehose core is downloading (standing download)')
6363 t.ok(front.repo.core.replicator && front.repo.core.replicator.downloading, 'FIX: repo core is downloading (standing download)')
64 const r1 = await front.listRecords('app.bsky.feed.post')
64 const { records: r1 } = await front.listRecords('app.bsky.feed.post')
6565 t.is(r1.length, 1, 'baseline: front serves the pre-restart post')
6666
6767 // --- RESTART the peer: swarm dies (process restart), recreate SAME keypair + SAME storage, rejoin ---
……@@ -78,7 +78,7 @@ test('peer RESTART (same keys) — front self-heals, new commit replicates witho
7878 // ASSERT: the front replicates the new commit within ~12s, WITHOUT re-creating the router.
7979 let got = 0
8080 for (let i = 0; i < 60; i++) {
81 const recs = await front.listRecords('app.bsky.feed.post').catch(() => [])
81 const recs = (await front.listRecords('app.bsky.feed.post').catch(() => ({ records: [] }))).records
8282 got = recs.length
8383 if (got >= 2) break
8484 await new Promise(r => setTimeout(r, 200))