interface BlockStore { put: (block: { cid: any; bytes: Uint8Array }) => Promise get: (cid: any) => Promise } interface MemoryBlockStore extends BlockStore { content: () => Set diff: (otherStore: BlockStore) => { missingLocal: Set missingOther: Set intersection: Set } push: (otherStore: BlockStore) => Promise countReads: () => number resetReads: () => void size: () => number } const memoryBlockStoreFactory = (): MemoryBlockStore => { const blocks = {} let readCounter = 0 const put = async (block: { cid: any bytes: Uint8Array }): Promise => { blocks[block.cid.toString()] = block.bytes } const get = async (cid: any): Promise => { const bytes = blocks[cid.toString()] if (bytes === undefined) throw new Error('Block Not found for ' + cid.toString()) readCounter++ return bytes } const push = async (otherStore: BlockStore): Promise => { const cids = Object.keys(blocks) for (const cid of cids) { const bytes = blocks[cid] await otherStore.put({ cid, bytes }) } } const diff = ( otherStore: MemoryBlockStore ): { missingLocal: Set missingOther: Set intersection: Set } => { const missingLocal = new Set() const missingOther = new Set() const intersection = new Set() const localCids = content() const otherCids = otherStore.content() for (const cid of localCids) { if (otherCids.has(cid)) { intersection.add(cid) } else { missingOther.add(cid) } } for (const cid of otherCids) { if (!localCids.has(cid)) { missingLocal.add(cid) } } return { missingLocal, missingOther, intersection } } const content = (): Set => { const out = new Set() for (const cid of Object.keys(blocks)) { out.add(cid.toString()) } return out } const countReads = () => readCounter const resetReads = () => (readCounter = 0) const size = () => Object.keys(blocks).length return { get, put, push, countReads, resetReads, size, diff, content } } export { BlockStore, MemoryBlockStore, memoryBlockStoreFactory }