@@ -3,6 +3,16 @@ import createCID from 'multiformats/cid.js'
3
3
import * as bytes from 'multiformats/bytes.js'
4
4
5
5
const cache = new Map ( )
6
+
7
+ /**
8
+ * @typedef {Object } Varint
9
+ * @property {function(Uint8Array):[number, number] } decode
10
+ * @property {function(number):Uint8Array } encode
11
+ */
12
+
13
+ /**
14
+ * @type {Varint }
15
+ */
6
16
const varint = {
7
17
decode : data => {
8
18
const code = varints . decode ( data )
@@ -16,15 +26,50 @@ const varint = {
16
26
}
17
27
}
18
28
19
- const createMultihash = multiformats => {
20
- const { get, has, parse, add } = multiformats
29
+ /**
30
+ * @template Raw,Encoded
31
+ * @typedef {(value:Raw) => Encoded } Encode
32
+ */
33
+
34
+ /**
35
+ * @template Raw,Encoded
36
+ * @typedef {Object } Codec
37
+ * @property {string } name
38
+ * @property {number } code
39
+ * @property {Encode<Raw, Encoded> } encode
40
+ * @property {Encode<Encoded, Raw> } decode
41
+ */
42
+
43
+ /**
44
+ * @typedef {Codec<Uint8Array, Uint8Array> } MultihashCodec
45
+ * @typedef {(bytes:Uint8Array) => {name:string, code:number, length:number, digest:Uint8Array} } Multihash$decode
46
+ * @typedef {(byte:Uint8Array, base:string|name) => Uint8Array } Multihash$encode
47
+ * @typedef {(bytes:Uint8Array, key:string) => Promise<Uint8Array> } Multihash$hash
48
+ * @typedef {Object } Multihash
49
+ * @property {Multihash$encode } encode
50
+ * @property {Multihash$decode } decode
51
+ * @property {Multihash$hash } hash
52
+ * @property {function(number|string):boolean } has
53
+ * @property {function(number|string):void|MultihashCodec } get
54
+ * @property {function(MultihashCodec):void } add
55
+ * @property {function(Uint8Array, Uint8Array):Promise<true> } validate
56
+ */
57
+
58
+ /**
59
+ * @param {MultiformatsUtil & Multicodec } multiformats
60
+ * @returns {Multihash }
61
+ */
62
+ const createMultihash = ( { get, has, parse, add } ) => {
63
+ /** @type {Multihash$decode } */
21
64
const decode = digest => {
22
65
const [ info , len ] = parse ( digest )
23
66
digest = digest . slice ( len )
24
67
const [ length , len2 ] = varint . decode ( digest )
25
68
digest = digest . slice ( len2 )
26
69
return { code : info . code , name : info . name , length, digest }
27
70
}
71
+
72
+ /** @type {Multihash$encode } */
28
73
const encode = ( digest , id ) => {
29
74
let info
30
75
if ( typeof id === 'number' ) {
@@ -36,6 +81,8 @@ const createMultihash = multiformats => {
36
81
const length = varint . encode ( digest . length )
37
82
return Uint8Array . from ( [ ...code , ...length , ...digest ] )
38
83
}
84
+
85
+ /** @type {Multihash$hash } */
39
86
const hash = async ( buff , key ) => {
40
87
buff = bytes . coerce ( buff )
41
88
const info = get ( key )
@@ -44,6 +91,12 @@ const createMultihash = multiformats => {
44
91
/* c8 ignore next */
45
92
return encode ( await info . encode ( buff ) , key )
46
93
}
94
+
95
+ /**
96
+ * @param {Uint8Array } _hash
97
+ * @param {Uint8Array } buff
98
+ * @returns {Promise<true> }
99
+ */
47
100
const validate = async ( _hash , buff ) => {
48
101
_hash = bytes . coerce ( _hash )
49
102
const { length, digest, code } = decode ( _hash )
@@ -57,9 +110,29 @@ const createMultihash = multiformats => {
57
110
/* c8 ignore next */
58
111
return true
59
112
}
113
+
60
114
return { encode, has, decode, hash, validate, add, get }
61
115
}
62
116
117
+ /**
118
+ * @typedef {Encode<string, Uint8Array> } MultibaseDecode
119
+ * @typedef {Encode<Uint8Array, string> } MultibaseEncode
120
+ * @typedef {Object } MultibaseCodec
121
+ * @property {string } prefix
122
+ * @property {string } name
123
+ * @property {MultibaseEncode } encode
124
+ * @property {MultibaseDecode } decode
125
+ * @typedef {Object } Multibase
126
+ * @property {(codec:MultibaseCodec|MultibaseCodec[]) => void } add
127
+ * @property {(prefex:string) => MultibaseCodec } get
128
+ * @property {(prefex:string) => boolean } has
129
+ * @property {(bytes:Uint8Array, prefix:string) => string } encode
130
+ * @property {MultibaseDecode } decode
131
+ * @property {(text:string) => MultibaseCodec } encoding
132
+ *
133
+ *
134
+ * @returns {Multibase }
135
+ */
63
136
const createMultibase = ( ) => {
64
137
const prefixMap = new Map ( )
65
138
const nameMap = new Map ( )
@@ -75,6 +148,11 @@ const createMultibase = () => {
75
148
_add ( prefix , name , encode , decode )
76
149
}
77
150
}
151
+
152
+ /**
153
+ * @param {string } id
154
+ * @returns {MultibaseCodec }
155
+ */
78
156
const get = id => {
79
157
if ( id . length === 1 ) {
80
158
if ( ! prefixMap . has ( id ) ) throw new Error ( `Missing multibase implementation for "${ id } "` )
@@ -105,11 +183,37 @@ const createMultibase = () => {
105
183
const { decode } = get ( prefix )
106
184
return Uint8Array . from ( decode ( string ) )
107
185
}
186
+ /**
187
+ * @param {string } string
188
+ * @returns {MultibaseCodec }
189
+ */
108
190
const encoding = string => get ( string [ 0 ] )
109
191
return { add, has, get, encode, decode, encoding }
110
192
}
111
193
194
+ /**
195
+ * @typedef {Object } MultiformatsUtil
196
+ * @property {Varint } varint
197
+ * @property {function(Uint8Array):[MultihashCodec, number] } parse
198
+ *
199
+ * @typedef {Object } Multicodec
200
+ * @property {function(MultihashCodec):void } add
201
+ * @property {function(string|number|Uint8Array):MultihashCodec } get
202
+ * @property {function(string):boolean } has
203
+ *
204
+ * @typedef {Object } MultiformatsExt
205
+ * @property {Multicodec } multicodec
206
+ * @property {Multibase } multibase
207
+ * @property {Multihash } multihash
208
+ *
209
+ * @typedef {MultiformatsUtil & Multicodec & MultiformatsExt } Multiformats
210
+
211
+ * @param {Array<[number, string, Function, Function]> } [table]
212
+ * @returns {Multiformats }
213
+ */
112
214
const create = ( table = [ ] ) => {
215
+ /** @type {Map<number, [string, Encode<Uint8Array, Uint8Array>, Encode<Uint8Array, Uint8Array>]> }
216
+ */
113
217
const intMap = new Map ( )
114
218
const nameMap = new Map ( )
115
219
const _add = ( code , name , encode , decode ) => {
@@ -131,6 +235,12 @@ const create = (table = []) => {
131
235
for ( const [ code , name , encode , decode ] of table ) {
132
236
_add ( code , name , encode , decode )
133
237
}
238
+
239
+ /**
240
+ *
241
+ * @param {Uint8Array } buff
242
+ * @returns {[MultihashCodec, number] }
243
+ */
134
244
const parse = buff => {
135
245
buff = bytes . coerce ( buff )
136
246
const [ code , len ] = varint . decode ( buff )
@@ -140,6 +250,7 @@ const create = (table = []) => {
140
250
}
141
251
return [ { code, name, encode, decode } , len ]
142
252
}
253
+
143
254
const get = obj => {
144
255
if ( typeof obj === 'string' ) {
145
256
if ( nameMap . has ( obj ) ) {
@@ -190,10 +301,12 @@ const create = (table = []) => {
190
301
}
191
302
192
303
const multiformats = { parse, add, get, has, encode, decode, varint, bytes }
304
+ /** @type {Multicodec } */
193
305
multiformats . multicodec = { add, get, has, encode, decode }
194
306
multiformats . multibase = createMultibase ( )
195
307
multiformats . multihash = createMultihash ( multiformats )
196
308
multiformats . CID = createCID ( multiformats )
309
+
197
310
return multiformats
198
311
}
199
312
export { create , bytes , varint }
0 commit comments