UNPKG

@atcute/car

Version:

lightweight DASL CAR and atproto repository decoder for AT Protocol.

58 lines 2.18 kB
import * as CBOR from '@atcute/cbor'; import * as CID from '@atcute/cid'; import { decodeUtf8From } from '@atcute/uint8array'; import * as CarReader from '../car-reader/index.js'; import { assert } from '../utils.js'; import { isMstNode } from './mst.js'; /** * collects entries from a CAR archive into a mapping of CID string -> actual bytes * @param iterator a generator that yields objects with a `cid` and `bytes` property * @returns a mapping of CID string -> actual bytes */ export const collectBlock = (iterator) => { const blockmap = new Map(); for (const entry of iterator) { blockmap.set(CID.toString(entry.cid), entry); } return blockmap; }; /** * reads a block from the blockmap and validates it against the provided validation function * @param map a mapping of CID string -> actual bytes * @param link a CID link to read * @param validate a validation function to validate the decoded data * @returns the decoded and validated data */ export const readBlock = (map, link, validate) => { const cid = link.$link; const entry = map.get(cid); assert(entry != null, `cid not found in blockmap; cid=${cid}`); const data = CBOR.decode(entry.bytes); assert(validate(data), `validation failed for cid=${cid}`); return data; }; /** * walks the entries of a Merkle Sorted Tree (MST) in a depth-first manner * @param map a mapping of CID string -> actual bytes * @param pointer a CID link to the root of the MST * @returns a generator that yields the entries of the MST */ export function* walkMstEntries(map, pointer) { const data = readBlock(map, pointer, isMstNode); const entries = data.e; let lastKey = ''; if (data.l !== null) { yield* walkMstEntries(map, data.l); } for (let i = 0, il = entries.length; i < il; i++) { const entry = entries[i]; const key_str = decodeUtf8From(CBOR.fromBytes(entry.k)); const key = lastKey.slice(0, entry.p) + key_str; lastKey = key; yield { key: key, cid: entry.v }; if (entry.t !== null) { yield* walkMstEntries(map, entry.t); } } } //# sourceMappingURL=sync-blockmap.js.map