import CID from 'cids' ; import multibase from 'multibase' ; import varint from 'varint' ; import dagCBOR from 'ipld-dag-cbor' ; import uint8ArrayConcat from 'uint8arrays/concat' ; import uint8ArrayToString from 'uint8arrays/to-string' ; import { DEFAULT_BASE , STREAMID_CODEC } from './constants' ; import { readCid , readCidNoThrow , readVarint } from './reading-bytes' ; import { Memoize } from 'typescript-memoize' ; import { CommitID } from './commit-id' ; import { StreamRef } from './stream-ref' ; import { StreamType } from './stream-type' ; param bytes throws see function fromBytes ( bytes ) { const result = fromBytesNoThrow ( bytes ) ; if ( result instanceof Error ) { throw result ; } return result ; } param bytes function fromBytesNoThrow ( bytes ) { const [ streamCodec , streamCodecRemainder ] = readVarint ( bytes ) ; if ( streamCodec !== STREAMID_CODEC ) return new Error ( 'fromBytes: invalid streamid, does not include streamid codec' ) ; const [ type , streamTypeRemainder ] = readVarint ( streamCodecRemainder ) ; const cidResult = readCidNoThrow ( streamTypeRemainder ) ; if ( cidResult instanceof Error ) { return cidResult ; } const [ cid , cidRemainder ] = cidResult ; if ( cidRemainder . length > 0 ) { return new Error ( `Invalid StreamID: contains commit` ) ; } return new StreamID ( type , cid ) ; } param input see see function fromString ( input ) { const result = fromStringNoThrow ( input ) ; if ( result instanceof Error ) { throw result ; } return result ; } param input function fromStringNoThrow ( input ) { const protocolFree = input . replace ( 'ceramic://' , '' ) . replace ( '/ceramic/' , '' ) ; const commitFree = protocolFree . includes ( 'commit' ) ? protocolFree . split ( '?' ) [ 0 ] : protocolFree ; const bytes = multibase . decode ( commitFree ) ; return fromBytesNoThrow ( bytes ) ; } const TAG = Symbol . for ( '@ceramicnetwork/streamid/StreamID' ) ; /**
 * Stream identifier, no commit information included.
 *
 * Contains stream type and CID of genesis commit.
 *
 * Encoded as `<multibase-prefix><multicodec-streamid><type><genesis-cid-bytes>`.
 *
 * String representation is base36-encoding of the bytes above.
 */ export class StreamID implements StreamRef { protected readonly _tag = TAG ; readonly #type : number ; readonly #cid : CID ; static fromBytes = fromBytes ; static fromBytesNoThrow = fromBytesNoThrow ; static fromString = fromString ; static fromStringNoThrow = fromStringNoThrow ; static isInstance ( instance ) { return typeof instance === 'object' && '_tag' in instance && instance . _tag === TAG ; } param { string | number } type param { CID | string } cid example constructor ( type , cid ) { if ( ! ( type || type === 0 ) ) throw new Error ( 'constructor: type required' ) ; if ( ! cid ) throw new Error ( 'constructor: cid required' ) ; this . #type = typeof type === 'string' ? StreamType . codeByName ( type ) : type ; this . #cid = typeof cid === 'string' ? new CID ( cid ) : cid ; } param param { string | number } type param { Record < string , any > } genesis example static async fromGenesis ( type , genesis ) { const cid = await dagCBOR . util . cid ( new Uint8Array ( dagCBOR . util . serialize ( genesis ) ) ) ; return new StreamID ( type , cid ) ; } /**
     * Stream type code
     */ get type ( ) : number { return this . #type ; } /**
     * Stream type name
     */ @ Memoize ( ) get typeName ( ) : string { return StreamType . nameByCode ( this . #type ) ; } /**
     * Genesis commits CID
     */ get cid ( ) : CID { return this . #cid ; } /**
     * Bytes representation of StreamID.
     */ @ Memoize ( ) get bytes ( ) : Uint8Array { const codec = varint . encode ( STREAMID_CODEC ) ; const type = varint . encode ( this . type ) ; return uint8ArrayConcat ( [ codec , type , this . cid . bytes ] ) ; } readonly @ Memoize ( ) get baseID ( ) : StreamID { return new StreamID ( this . #type , this . #cid ) ; } /**
     * Construct new CommitID for the same stream, but a new `commit` CID.
     */ atCommit ( commit ) { return new CommitID ( this . #type , this . #cid , commit ) ; } /**
     * Compare equality with another StreamID.
     */ equals ( other ) { if ( StreamID . isInstance ( other ) ) { return this . type === other . type && this . cid . equals ( other . cid ) ; } else { return false ; } } /**
     * Encode the StreamID into a string.
     */ @ Memoize ( ) toString ( ) { return uint8ArrayToString ( multibase . encode ( DEFAULT_BASE , this . bytes ) ) ; } /**
     * Encode the StreamID into a base36 url.
     */ @ Memoize ( ) toUrl ( ) { return `ceramic://${ this . toString ( ) }` ; } /**
     * StreamId(k3y52l7mkcvtg023bt9txegccxe1bah8os3naw5asin3baf3l3t54atn0cuy98yws)
     */ [ Symbol . for ( 'nodejs.util.inspect.custom' ) ] ( ) { return `StreamID(${ this . toString ( ) })` ; } /**
     * String representation of StreamID.
     */ [ Symbol . toPrimitive ] ( ) { return this . toString ( ) ; } }