atproto user agency toolkit for individuals and groups
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 71 lines 2.0 kB view raw
1/** 2 * Recovery export functions for replicated atproto account data. 3 * 4 * Provides CAR file export (for repo import to a new PDS) and blob 5 * export for disaster recovery scenarios. 6 */ 7 8import { BlockMap, blocksToCarFile } from "@atproto/repo"; 9import { CID } from "@atproto/lex-data"; 10import type { SyncStorage } from "./sync-storage.js"; 11import type { BlockStore } from "../ipfs.js"; 12 13/** 14 * Assemble a CAR v1 file from all replicated blocks for a DID. 15 * 16 * Uses @atproto/repo's blocksToCarFile which produces spec-compliant 17 * CAR v1 with the commit root as the single root CID. 18 * 19 * Returns null if the DID has no sync state or root CID. 20 */ 21export async function exportRepoAsCar( 22 did: string, 23 syncStorage: SyncStorage, 24 blockStore: BlockStore, 25): Promise<{ car: Uint8Array; rootCid: string; blockCount: number } | null> { 26 const state = syncStorage.getState(did); 27 if (!state?.rootCid) return null; 28 29 const blockCids = syncStorage.getBlockCids(did); 30 const blocks = new BlockMap(); 31 let blockCount = 0; 32 33 for (const cidStr of blockCids) { 34 const bytes = await blockStore.getBlock(cidStr); 35 if (bytes) { 36 blocks.set(CID.parse(cidStr), bytes); 37 blockCount++; 38 } 39 } 40 41 if (blockCount === 0) return null; 42 43 const root = CID.parse(state.rootCid); 44 const car = await blocksToCarFile(root, blocks); 45 46 return { car, rootCid: state.rootCid, blockCount }; 47} 48 49/** 50 * Export all blob bytes for a DID. 51 * 52 * Returns an array of { cid, bytes } for every tracked blob CID 53 * that has data in the blockstore. Blobs without data are skipped. 54 */ 55export async function exportBlobs( 56 did: string, 57 syncStorage: SyncStorage, 58 blockStore: BlockStore, 59): Promise<Array<{ cid: string; bytes: Uint8Array }>> { 60 const blobCids = syncStorage.getBlobCids(did); 61 const results: Array<{ cid: string; bytes: Uint8Array }> = []; 62 63 for (const cid of blobCids) { 64 const bytes = await blockStore.getBlock(cid); 65 if (bytes) { 66 results.push({ cid, bytes }); 67 } 68 } 69 70 return results; 71}