Created
June 30, 2021 13:08
-
-
Save olizilla/bb27a08e32fbdd544788ec0514a16d5c to your computer and use it in GitHub Desktop.
CarReaderIdb - A CarReader impl that decodes blocks directly to idb via idb-keyval
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as idb from 'idb-keyval' | |
import { CID } from 'multiformats' | |
import { BytesReader } from '@ipld/car/lib/coding' | |
import { createDecoder, asyncIterableReader } from '@ipld/car/lib/decoder.js' | |
export class CarReaderIdb { | |
_version: number; | |
_roots: Array<CID>; | |
constructor (version: number, roots: Array<CID>) { | |
this._version = version | |
this._roots = roots | |
} | |
get version () { | |
return this._version | |
} | |
/** | |
* Get the list of roots defined by the CAR referenced by this reader. May be | |
* zero or more `CID`s. | |
*/ | |
async getRoots () { | |
return this._roots | |
} | |
/** | |
* Check whether a given `CID` exists within the CAR referenced by this | |
* reader. | |
*/ | |
async has (key: CID) { | |
const val = await idb.get(key.toString()) | |
return !!val | |
} | |
/** | |
* Fetch a `Block` (a `{ cid:CID, bytes:Uint8Array }` pair) from the CAR | |
* referenced by this reader matching the provided `CID`. In the case where | |
* the provided `CID` doesn't exist within the CAR, `undefined` will be | |
* returned. | |
*/ | |
async get (key: CID) { | |
return idb.get(key.toString()) | |
} | |
/** | |
* Returns a `BlockIterator` (`AsyncIterable<Block>`) that iterates over all | |
* of the `Block`s (`{ cid:CID, bytes:Uint8Array }` pairs) contained within | |
* the CAR referenced by this reader. | |
*/ | |
async * blocks () { | |
const keys = await idb.keys() | |
for (const key of keys) { | |
yield idb.get(key) | |
} | |
} | |
/** | |
* Returns a `CIDIterator` (`AsyncIterable<CID>`) that iterates over all of | |
* the `CID`s contained within the CAR referenced by this reader. | |
*/ | |
async * cids () { | |
for await (const block of this.blocks()) { | |
yield block.cid | |
} | |
} | |
/** | |
* Instantiate a {@link CarReaderIdb} from a `AsyncIterable<Uint8Array>`, such as | |
* a [modern Node.js stream](https://nodejs.org/api/stream.html#stream_streams_compatibility_with_async_generators_and_async_iterators). | |
*/ | |
static async fromIterable (asyncIterable: AsyncIterable<Uint8Array>) { | |
if (!asyncIterable || !(typeof asyncIterable[Symbol.asyncIterator] === 'function')) { | |
throw new TypeError('fromIterable() requires an async iterable') | |
} | |
return decodeReaderComplete(asyncIterableReader(asyncIterable)) | |
} | |
} | |
async function decodeReaderComplete (reader: BytesReader) { | |
const decoder = createDecoder(reader) | |
const { version, roots } = await decoder.header() | |
for await (const block of decoder.blocks()) { | |
idb.set(block.cid.toString(), block) | |
} | |
return new CarReaderIdb(version, roots) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment