diff --git a/src/block/interface.ts b/src/block/interface.ts index df583589..d595e89f 100644 --- a/src/block/interface.ts +++ b/src/block/interface.ts @@ -35,6 +35,22 @@ export interface Phantom { [Marker]?: T } +/** + * [Multicodec code] usually used to tag [multiformat]. It is simply an Integer that + * utilizes `Phantom` type to capture code name which typescript aware tools will + * surface providing info about the code withouth having to look it up in the table. + * + * Type also can be used to convey the fact that value must be a multicodec + * + * [multiformat]:https://multiformats.io/ + * [multicodec code]:https://github.com/multiformats/multicodec/blob/master/table.csv + */ +export type MulticodecCode< + Code extends number = number, + Name extends string = string +> = Code & Phantom + + /** * Represents an IPLD block (including its CID) that can be decoded to data of * type `T`. diff --git a/src/hashes/interface.ts b/src/hashes/interface.ts index b7e9edf6..29ab9d57 100644 --- a/src/hashes/interface.ts +++ b/src/hashes/interface.ts @@ -1,4 +1,5 @@ // # Multihash +import type { MulticodecCode } from '../block/interface.js' /** * Represents a multihash digest which carries information about the @@ -9,7 +10,7 @@ // a bunch of places that parse it to extract (code, digest, size). By creating // this first class representation we avoid reparsing and things generally fit // really nicely. -export interface MultihashDigest { +export interface MultihashDigest { /** * Code of the multihash */ @@ -23,7 +24,7 @@ export interface MultihashDigest { /** * byte length of the `this.digest` */ - size: number + size: Size /** * Binary representation of this multihash digest. @@ -35,7 +36,7 @@ export interface MultihashDigest { * Hasher represents a hashing algorithm implementation that produces as * `MultihashDigest`. */ -export interface MultihashHasher { +export interface MultihashHasher { /** * Takes binary `input` and returns it (multi) hash digest. Return value is * either promise of a digest or a digest. This way general use can `await` @@ -67,6 +68,76 @@ export interface MultihashHasher { * `SyncMultihashHasher` is useful in certain APIs where async hashing would be * impractical e.g. implementation of Hash Array Mapped Trie (HAMT). */ -export interface SyncMultihashHasher extends MultihashHasher { +export interface SyncMultihashHasher extends MultihashHasher { digest: (input: Uint8Array) => MultihashDigest } + +/** + * Incremental variant of the `MultihashHasher` that can be used to compute + * digest of the payloads that would be impractical or impossible to load all + * into a memory. + */ +export interface IncrementalMultihashHasher< + Code extends MulticodecCode, + Size extends number, + Digest = MultihashDigest +> { + /** + * Size of the digest this hasher produces. + */ + size: Size + + /** + * Code of the multihash + */ + code: Code + + /** + * Name of the multihash + */ + name: string + + /** + * Number of bytes that were consumed. + */ + count(): bigint + + /** + * Returns multihash digest of the bytes written so far. Should not have + * side-effects, meaning you should be able to write some more bytes and + * call `digest` again to get the digest for all the bytes written from + * creation (or from reset) + */ + digest(): Digest + + /** + * Encodes multihash of the bytes written so far (since creation or + * reset) into provided `target` at given `offset`. If `offset` not + * provided it is implicitly `0`. + * + * @param [offset=0] - Byte offset in the `target`. + */ + readDigest(target: Uint8Array, offset?: number): this + + /** + * Encodes raw digest (without multihash header) of the bytes written + * so far (since creation or reset) into provided `target` at given + * `offset`. If `offset` not provided it is implicitly `0`. + * + * @param [offset=0] - Byte offset in the `target`. + */ + read(target: Uint8Array, offset?: number): this + + /** + * Writes bytes to be digested. + */ + write(bytes: Uint8Array): this + + /** + * Resets this hasher to its initial state. Can be used to recycle this + * instance. It resets `count` and and discards all the bytes that were + * written prior. + */ + reset(): this +} +