import Bitswap from 'ipfs-bitswap' import CID from 'cids' import { BlockStore, Block } from './blockstore' /** * BlockService is a content-addressable store for adding, deleting, and retrieving blocks of immutable data. * A block service is backed by a block store as its datastore for blocks, and uses an "exchange" (bitswap) to fetch * blocks from the network. This implementation is a simplified variant of the official IPFS block service, requiring * only a simple block store (not a full IPFS repo), and reference to a bitwap exchange. * * It satisfies the default IPFS block service interface: https://github.com/ipfs/js-ipfs-block-service. */ export class BlockService { /** * BlockService creates a new block service. * * @param {BlockStore} store The block store to use for local block storage. * @param {Bitswap} exchange Add a "bitswap" instance that communicates with the network to retrieve blocks that * are not in the local store. If the node is online, all requests for blocks first check locally and then ask * the network for the blocks. To 'go offline', simply set `exchange` to undefined or null. */ constructor(public store: BlockStore, public exchange?: Bitswap) {} /** * online returns whether the block service is online or not. i.e. does it have a valid exchange? */ online() { return this.exchange != null } /** * put adds a block to the underlying block store. * * @param {Block} block An immutable block of data. */ async put(block: Block) { if (this.exchange != null) { return this.exchange.put(block) } else { return this.store.put(block) } } /** * putMany adds multiple blocks to the underlying block store. * * @param {Iterable} blocks An iterable of immutable blocks of data. */ async putMany(blocks: Iterable) { if (this.exchange != null) { return this.exchange.putMany(blocks) } else { return this.store.putMany(blocks) } } /** * get returns a block by its content identifier. * If the block is not available locally and the exchange is online, it will request the block from the network. * * @param {CID} cid The content identifier for an immutable block of data. */ async get(cid: CID): Promise { if (this.exchange != null) { return this.exchange.get(cid) } else { return this.store.get(cid) } } /** * getMany returns multiple blocks from an iterable of content identifiers. * If any of the blocks are not available locally and the exchange is online, it will request the block(s) from the * exchange/network. * * @param {Iterable} cids Iterable of content identifiers for immutable blocks of data. */ async *getMany(cids: Iterable): AsyncIterableIterator { if (this.exchange != null) { return this.exchange.getMany(cids) } else { for (const cid of cids) { yield this.store.get(cid) } } } /** * delete removes a block from the local block store. * * @param {CID} cid The content identifier for an immutable block of data. */ async delete(cid: CID) { await this.store.delete(cid) return cid } }