| … | … | @@ -34,6 +34,14 @@ export class DualBlobStore { |
| 34 | 34 | // ── operator repair (pass-through to the overlay side; the legacy bee needs neither) ────────────── |
| 35 | 35 | // Re-register the blob FILES so peers can fetch them by oid. The legacy Hyperbee store keeps its bytes |
| 36 | 36 | // as bee values, which replicate as core blocks — it has no oid index to repair. |
| 37 | // Inventory for listBlobs. Delegates to the overlay/pointer store only: the LEGACY store predates | |
| 38 | // pointers entirely, so it has no published set to enumerate and including it would report blobs the | |
| 39 | // rest of the network cannot fetch. | |
| 40 | async list (opts) { | |
| 41 | if (typeof this._new.list !== 'function') return { cids: [], cursor: null, skipped: 'not-supported' } | |
| 42 | return this._new.list(opts) | |
| 43 | } | |
| 44 | ||
| 37 | 45 | async reindexOverlay () { |
| 38 | 46 | if (typeof this._new.reindexOverlay !== 'function') return { skipped: 'not-supported' } |
| 39 | 47 | return this._new.reindexOverlay() |
| … | … | @@ -140,6 +140,10 @@ export async function serveDeviceUds (device, { uds, blobs = null, onRelease = n |
| 140 | 140 | // get-blob: local read counterpart to upload-blob — the co-located client (favela-web) renders images it |
| 141 | 141 | // uploaded. The UDS had upload-blob but no read path, so locally-stored blobs were unreadable. Public (a |
| 142 | 142 | // UDS connection is already filesystem-owner-gated). Returns { mimeType, size, bytes(hex) } or null. |
| 143 | svc.handle('list-blobs', async (ctx, { limit, cursor } = {}) => { | |
| 144 | if (!blobs || typeof blobs.list !== 'function') return { cids: [], cursor: null, skipped: 'not-supported' } | |
| 145 | return blobs.list({ limit, cursor }) | |
| 146 | }) | |
| 143 | 147 | svc.handle('get-blob', async (ctx, { cid } = {}) => { |
| 144 | 148 | if (!cid) throw new Error('get-blob: cid required') |
| 145 | 149 | const blob = await blobs.get(String(cid)) |
| … | … | @@ -50,6 +50,14 @@ export function serveDevice (device, swarm, { canWrite = null, blobs = null, ses |
| 50 | 50 | // bsky; server-bare.js expects { mimeType, bytes(hex) } or null (→ 404). This responder was MISSING: |
| 51 | 51 | // blobs could be uploaded but never read back, so every getBlob 404'd regardless of who held the bytes. |
| 52 | 52 | if (blobs) { |
| 53 | // list-blobs: the DID's published blob inventory. READ-ONLY and ungated like get-blob — it returns | |
| 54 | // content addresses the peer already serves by CID, so it grants no access that get-blob does not. | |
| 55 | // This is what makes ORPHAN detection possible: a blob referenced by no record cannot be found by | |
| 56 | // walking records, only by asking the authority what it has (spec/convergence.md §6). | |
| 57 | rpc.respond('list-blobs', async ({ limit, cursor } = {}) => { | |
| 58 | if (typeof blobs.list !== 'function') return { cids: [], cursor: null, skipped: 'not-supported' } | |
| 59 | return blobs.list({ limit, cursor }) | |
| 60 | }) | |
| 53 | 61 | rpc.respond('get-blob', async ({ cid } = {}) => { |
| 54 | 62 | if (!cid) throw new Error('get-blob: cid required') |
| 55 | 63 | const blob = await blobs.get(String(cid)) |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "hyper-proto-peer", |
| 3 | "version": "0.3.107", | |
| 3 | "version": "0.3.108", | |
| 4 | 4 | "description": "Self-custody, P2P-native atproto peer — 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.", |
| 5 | 5 | "type": "module", |
| 6 | 6 | "main": "lib/peer.js", |