diff --git a/packages/blockstore-core/README.md b/packages/blockstore-core/README.md index 715e7c40..94943a86 100644 --- a/packages/blockstore-core/README.md +++ b/packages/blockstore-core/README.md @@ -74,6 +74,21 @@ const store = new TieredBlockstore([ ]) ``` +## Example - IdentityBlockstore + +An identity blockstore is one that deals exclusively in Identity CIDs - this is a special CID with the codec [0x00](https://github.com/multiformats/multicodec/blob/d06fc6194710e8909bac64273c43f16b56ca4c34/table.csv#L2) where the multihash digest is the data that makes up the block. + +```TypeScript +import { IdentityBlockstore } from 'blockstore-core/identity' +import { CID } from 'multiformats/cid' + +const blockstore = new IdentityBlockstore() + +blockstore.has(CID.parse('QmFoo')) // false + +blockstore.has(CID.parse('bafkqac3imvwgy3zao5xxe3de')) // true +``` + # Install ```console diff --git a/packages/blockstore-core/package.json b/packages/blockstore-core/package.json index 63f7757e..bbf25946 100644 --- a/packages/blockstore-core/package.json +++ b/packages/blockstore-core/package.json @@ -63,6 +63,10 @@ "types": "./dist/src/errors.d.ts", "import": "./dist/src/errors.js" }, + "./identity": { + "types": "./dist/src/identity.d.ts", + "import": "./dist/src/identity.js" + }, "./memory": { "types": "./dist/src/memory.d.ts", "import": "./dist/src/memory.js" diff --git a/packages/blockstore-core/src/base.ts b/packages/blockstore-core/src/base.ts index 1abcf540..87b1d966 100644 --- a/packages/blockstore-core/src/base.ts +++ b/packages/blockstore-core/src/base.ts @@ -31,8 +31,8 @@ export class BaseBlockstore implements Blockstore { } } - async delete (key: CID, options?: AbortOptions): Promise { - await Promise.reject(new Error('.delete is not implemented')) + delete (key: CID, options?: AbortOptions): Await { + return Promise.reject(new Error('.delete is not implemented')) } async * deleteMany (source: AwaitIterable, options?: AbortOptions): AwaitIterable { diff --git a/packages/blockstore-core/src/identity.ts b/packages/blockstore-core/src/identity.ts new file mode 100644 index 00000000..059902df --- /dev/null +++ b/packages/blockstore-core/src/identity.ts @@ -0,0 +1,34 @@ +import { BaseBlockstore } from './base.js' +import * as Errors from './errors.js' +import type { Pair } from 'interface-blockstore' +import type { Await, AwaitIterable } from 'interface-store' +import type { CID } from 'multiformats/cid' + +// https://github.com/multiformats/multicodec/blob/d06fc6194710e8909bac64273c43f16b56ca4c34/table.csv#L2 +const IDENTITY_CODEC = 0x00 + +export class IdentityBlockstore extends BaseBlockstore { + put (key: CID): CID { + return key + } + + get (key: CID): Await { + if (key.code === IDENTITY_CODEC) { + return key.multihash.digest + } + + throw Errors.notFoundError() + } + + has (key: CID): boolean { + return key.code === IDENTITY_CODEC + } + + delete (): void { + + } + + * getAll (): AwaitIterable { + + } +} diff --git a/packages/blockstore-core/src/index.ts b/packages/blockstore-core/src/index.ts index 3e4df1a4..0bab631f 100644 --- a/packages/blockstore-core/src/index.ts +++ b/packages/blockstore-core/src/index.ts @@ -65,6 +65,21 @@ * // ...etc * ]) * ``` + * + * @example IdentityBlockstore + * + * An identity blockstore is one that deals exclusively in Identity CIDs - this is a special CID with the codec [0x00](https://github.com/multiformats/multicodec/blob/d06fc6194710e8909bac64273c43f16b56ca4c34/table.csv#L2) where the multihash digest is the data that makes up the block. + * + * ```TypeScript + * import { IdentityBlockstore } from 'blockstore-core/identity' + * import { CID } from 'multiformats/cid' + * + * const blockstore = new IdentityBlockstore() + * + * blockstore.has(CID.parse('QmFoo')) // false + * + * blockstore.has(CID.parse('bafkqac3imvwgy3zao5xxe3de')) // true + * ``` */ import * as ErrorsImport from './errors.js' diff --git a/packages/blockstore-core/test/identity.spec.ts b/packages/blockstore-core/test/identity.spec.ts new file mode 100644 index 00000000..e0bfcdfc --- /dev/null +++ b/packages/blockstore-core/test/identity.spec.ts @@ -0,0 +1,59 @@ +/* eslint-env mocha */ + +import { expect } from 'aegir/chai' +import drain from 'it-drain' +import { CID } from 'multiformats/cid' +import * as raw from 'multiformats/codecs/raw' +import { identity } from 'multiformats/hashes/identity' +import { sha256 } from 'multiformats/hashes/sha2' +import { IdentityBlockstore } from '../src/identity.js' +import type { Blockstore } from 'interface-blockstore' + +describe('identity', () => { + let blockstore: Blockstore + + beforeEach(() => { + blockstore = new IdentityBlockstore() + }) + + it('has an identity CID', () => { + const block = Uint8Array.from([0, 1, 2, 3, 4]) + const multihash = identity.digest(block) + const cid = CID.createV1(identity.code, multihash) + + expect(blockstore.has(cid)).to.be.true() + expect(blockstore.get(cid)).to.equalBytes(block) + }) + + it('does not have a non-identity CID', async () => { + const block = Uint8Array.from([0, 1, 2, 3, 4]) + const multihash = await sha256.digest(block) + const cid = CID.createV1(raw.code, multihash) + + expect(blockstore.has(cid)).to.be.false() + + await blockstore.put(cid, block) + + expect(blockstore.has(cid)).to.be.false() + }) + + it('cannot delete an identity CID', async () => { + const block = Uint8Array.from([0, 1, 2, 3, 4]) + const multihash = identity.digest(block) + const cid = CID.createV1(identity.code, multihash) + + await blockstore.delete(cid) + + expect(blockstore.has(cid)).to.be.true() + }) + + it('cannot delete many identity CIDs', async () => { + const block = Uint8Array.from([0, 1, 2, 3, 4]) + const multihash = identity.digest(block) + const cid = CID.createV1(identity.code, multihash) + + await drain(blockstore.deleteMany([cid])) + + expect(blockstore.has(cid)).to.be.true() + }) +}) diff --git a/packages/blockstore-core/typedoc.json b/packages/blockstore-core/typedoc.json index 1015d65e..57c0b938 100644 --- a/packages/blockstore-core/typedoc.json +++ b/packages/blockstore-core/typedoc.json @@ -4,6 +4,7 @@ "./src/base.ts", "./src/black-hole.ts", "./src/errors.ts", + "./src/identity.ts", "./src/memory.ts", "./src/tiered.ts" ]