UNPKG

@atproto/repo

Version:

atproto repo and MST implementation

65 lines (58 loc) 1.88 kB
import { CID } from 'multiformats/cid' import { writeCarStream } from '../car' import { CidSet } from '../cid-set' import { MissingBlocksError } from '../error' import { MST } from '../mst' import { ReadableBlockstore, RepoStorage } from '../storage' import { RecordPath, def } from '../types' import * as util from '../util' // Full Repo // ------------- export const getFullRepo = ( storage: RepoStorage, commitCid: CID, ): AsyncIterable<Uint8Array> => { return writeCarStream(commitCid, iterateFullRepo(storage, commitCid)) } async function* iterateFullRepo(storage: RepoStorage, commitCid: CID) { const commit = await storage.readObjAndBytes(commitCid, def.commit) yield { cid: commitCid, bytes: commit.bytes } const mst = MST.load(storage, commit.obj.data) for await (const block of mst.carBlockStream()) { yield block } } // Narrow slices // ------------- export const getRecords = ( storage: ReadableBlockstore, commitCid: CID, paths: RecordPath[], ): AsyncIterable<Uint8Array> => { return writeCarStream( commitCid, iterateRecordBlocks(storage, commitCid, paths), ) } async function* iterateRecordBlocks( storage: ReadableBlockstore, commitCid: CID, paths: RecordPath[], ) { const commit = await storage.readObjAndBytes(commitCid, def.commit) yield { cid: commitCid, bytes: commit.bytes } const mst = MST.load(storage, commit.obj.data) const cidsForPaths = await Promise.all( paths.map((p) => mst.cidsForPath(util.formatDataKey(p.collection, p.rkey))), ) const allCids = cidsForPaths.reduce((acc, cur) => { return acc.addSet(new CidSet(cur)) }, new CidSet()) const found = await storage.getBlocks(allCids.toList()) if (found.missing.length > 0) { throw new MissingBlocksError('writeRecordsToCarStream', found.missing) } for (const block of found.blocks.entries()) { yield block } }