Skip to content

Commit a04a8f6

Browse files
mikealGozala
authored andcommitted
pkg: drop period
1 parent b3580a6 commit a04a8f6

31 files changed

+1829
-828
lines changed

README.md

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,33 @@ This allows you to pass around an interface containing only the code you need
1313
which can greatly reduce dependencies and bundle size.
1414

1515
```js
16-
import { create } from 'multiformats'
17-
import sha2 from 'multiformats/hashes/sha2'
16+
import * as CID from 'multiformats/cid'
17+
import { sha256 } from 'multiformats/hashes/sha2'
1818
import dagcbor from '@ipld/dag-cbor'
19-
const { multihash, multicodec, CID } = create()
20-
multihash.add(sha2)
21-
multicodec.add(dagcbor)
19+
import { base32 } from 'multiformats/bases/base32'
20+
import { base58btc } from 'multiformats/bases/base58'
2221

23-
const buffer = multicodec.encode({ hello, 'world' }, 'dag-cbor')
24-
const hash = await multihash.hash(buffer, 'sha2-256')
22+
const bytes = dagcbor.encode({ hello: 'world' })
23+
24+
const hash = await sha256.digest(bytes)
2525
// raw codec is the only codec that is there by default
26-
const cid = new CID(1, 'raw', hash)
26+
const cid = CID.create(1, dagcbor.code, hash, {
27+
base: base32,
28+
base58btc
29+
})
2730
```
2831

2932
However, if you're doing this much you should probably use multiformats
3033
with the `Block` API.
3134

3235
```js
3336
// Import basics package with dep-free codecs, hashes, and base encodings
34-
import multiformats from 'multiformats/basics'
37+
import { block } from 'multiformats/basics'
3538
import dagcbor from '@ipld/dag-cbor'
36-
import { create } from '@ipld/block' // Yet to be released Block interface
37-
multiformats.multicodec.add(dagcbor)
38-
const Block = create(multiformats)
39-
const block = Block.encoder({ hello: world }, 'dag-cbor')
40-
const cid = await block.cid()
39+
40+
const encoder = block.encoder(dagcbor)
41+
const hello = encoder.encode({ hello: 'world' })
42+
const cid = await hello.cid()
4143
```
4244

4345
# Plugins
@@ -83,35 +85,17 @@ Returns a new multiformats interface.
8385

8486
Can optionally pass in a table of multiformat entries.
8587

86-
# multihash
87-
88-
## multihash.encode
89-
90-
## multihash.decode
91-
92-
## multihash.validate
93-
94-
## multihash.add
95-
96-
## multihash.hash
97-
98-
# multicodec
99-
100-
## multicodec.encode
101-
102-
## multicodec.decode
103-
104-
## multicodec.add
88+
## multiformats.configure
10589

106-
# multibase
90+
## multiformats.varint
10791

108-
## multibase.encode
92+
## multiformats.bytes
10993

110-
## multibase.decode
94+
## multiformats.digest
11195

112-
## multibase.add
96+
## multiformats.hasher
11397

114-
# CID
98+
# multiformats.CID
11599

116100
Changes from `cids`:
117101

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "multiformats",
33
"version": "0.0.0-dev",
4-
"description": "Interface for multihash, multicodec, multibase and CID.",
4+
"description": "Interface for multihash, multicodec, multibase and CID",
55
"main": "index.js",
66
"type": "module",
77
"scripts": {

src/bases/base.js

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
// @ts-check
2+
3+
/**
4+
* @typedef {import('./interface').BaseEncoder} BaseEncoder
5+
* @typedef {import('./interface').BaseDecoder} BaseDecoder
6+
* @typedef {import('./interface').BaseCodec} BaseCodec
7+
*/
8+
9+
/**
10+
* @template T
11+
* @typedef {import('./interface').Multibase<T>} Multibase
12+
*/
13+
/**
14+
* @template T
15+
* @typedef {import('./interface').MultibaseEncoder<T>} MultibaseEncoder
16+
*/
17+
18+
/**
19+
* Class represents both BaseEncoder and MultibaseEncoder meaning it
20+
* can be used to encode to multibase or base encode without multibase
21+
* prefix.
22+
* @class
23+
* @template {string} Base
24+
* @template {string} Prefix
25+
* @implements {MultibaseEncoder<Prefix>}
26+
* @implements {BaseEncoder}
27+
*/
28+
class Encoder {
29+
/**
30+
* @param {Base} name
31+
* @param {Prefix} prefix
32+
* @param {(bytes:Uint8Array) => string} baseEncode
33+
*/
34+
constructor (name, prefix, baseEncode) {
35+
this.name = name
36+
this.prefix = prefix
37+
this.baseEncode = baseEncode
38+
}
39+
40+
/**
41+
* @param {Uint8Array} bytes
42+
* @returns {Multibase<Prefix>}
43+
*/
44+
encode (bytes) {
45+
// @ts-ignore
46+
return `${this.prefix}${this.baseEncode(bytes)}`
47+
}
48+
}
49+
50+
/**
51+
* @template T
52+
* @typedef {import('./interface').MultibaseDecoder<T>} MultibaseDecoder
53+
*/
54+
55+
/**
56+
* Class represents both BaseDecoder and MultibaseDecoder so it could be used
57+
* to decode multibases (with matching prefix) or just base decode strings
58+
* with corresponding base encoding.
59+
* @class
60+
* @template {string} Base
61+
* @template {string} Prefix
62+
* @implements {MultibaseDecoder<Prefix>}
63+
* @implements {BaseDecoder}
64+
*/
65+
class Decoder {
66+
/**
67+
* @param {Base} name
68+
* @param {Prefix} prefix
69+
* @param {(text:string) => Uint8Array} baseDecode
70+
*/
71+
constructor (name, prefix, baseDecode) {
72+
this.name = name
73+
this.prefix = prefix
74+
this.baseDecode = baseDecode
75+
}
76+
77+
/**
78+
* @param {string} text
79+
*/
80+
decode (text) {
81+
switch (text[0]) {
82+
case this.prefix: {
83+
return this.baseDecode(text.slice(1))
84+
}
85+
default: {
86+
throw Error(`${this.name} expects input starting with ${this.prefix} and can not decode "${text}"`)
87+
}
88+
}
89+
}
90+
}
91+
92+
/**
93+
* @template T
94+
* @typedef {import('./interface').MultibaseCodec<T>} MultibaseCodec
95+
*/
96+
97+
/**
98+
* @class
99+
* @template {string} Base
100+
* @template {string} Prefix
101+
* @implements {MultibaseCodec<Prefix>}
102+
* @implements {MultibaseEncoder<Prefix>}
103+
* @implements {MultibaseDecoder<Prefix>}
104+
* @implements {BaseCodec}
105+
* @implements {BaseEncoder}
106+
* @implements {BaseDecoder}
107+
*/
108+
export class Codec {
109+
/**
110+
* @param {Base} name
111+
* @param {Prefix} prefix
112+
* @param {(bytes:Uint8Array) => string} baseEncode
113+
* @param {(text:string) => Uint8Array} baseDecode
114+
*/
115+
constructor (name, prefix, baseEncode, baseDecode) {
116+
this.name = name
117+
this.prefix = prefix
118+
this.baseEncode = baseEncode
119+
this.baseDecode = baseDecode
120+
this.encoder = new Encoder(name, prefix, baseEncode)
121+
this.decoder = new Decoder(name, prefix, baseDecode)
122+
}
123+
124+
/**
125+
* @param {Uint8Array} input
126+
*/
127+
encode (input) {
128+
return this.encoder.encode(input)
129+
}
130+
131+
decode (input) {
132+
return this.decoder.decode(input)
133+
}
134+
}
135+
136+
/**
137+
* @template {string} Base
138+
* @template {string} Prefix
139+
* @param {Object} options
140+
* @param {Base} options.name
141+
* @param {Prefix} options.prefix
142+
* @param {string} options.alphabet
143+
* @param {(input:Uint8Array, alphabet:string) => string} options.encode
144+
* @param {(input:string, alphabet:string) => Uint8Array} options.decode
145+
*/
146+
export const withAlphabet = ({ name, prefix, encode, decode, alphabet }) =>
147+
from({
148+
name,
149+
prefix,
150+
encode: input => encode(input, alphabet),
151+
decode: input => {
152+
for (const char of input) {
153+
if (alphabet.indexOf(char) < 0) {
154+
throw new Error(`invalid ${name} character`)
155+
}
156+
}
157+
return decode(input, alphabet)
158+
}
159+
})
160+
161+
/**
162+
* @template {string} Base
163+
* @template {string} Prefix
164+
* @template Settings
165+
*
166+
* @param {Object} options
167+
* @param {Base} options.name
168+
* @param {Prefix} options.prefix
169+
* @param {Settings} options.settings
170+
* @param {(input:Uint8Array, settings:Settings) => string} options.encode
171+
* @param {(input:string, settings:Settings) => Uint8Array} options.decode
172+
*/
173+
174+
export const withSettings = ({ name, prefix, settings, encode, decode }) =>
175+
from({
176+
name,
177+
prefix,
178+
encode: (input) => encode(input, settings),
179+
decode: (input) => decode(input, settings)
180+
})
181+
182+
/**
183+
* @template {string} Base
184+
* @template {string} Prefix
185+
* @param {Object} options
186+
* @param {Base} options.name
187+
* @param {Prefix} options.prefix
188+
* @param {(bytes:Uint8Array) => string} options.encode
189+
* @param {(input:string) => Uint8Array} options.decode
190+
* @returns {Codec<Base, Prefix>}
191+
*/
192+
export const from = ({ name, prefix, encode, decode }) =>
193+
new Codec(name, prefix, encode, decode)
194+
195+
export const notImplemented = ({ name, prefix }) =>
196+
from({
197+
name,
198+
prefix,
199+
encode: _ => {
200+
throw Error(`No ${name} encoder implementation was provided`)
201+
},
202+
decode: _ => {
203+
throw Error(`No ${name} decoder implemnetation was provided`)
204+
}
205+
})

src/bases/base16.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
import { fromHex, toHex } from '../bytes.js'
1+
// @ts-check
22

3-
const create = function base16 (alphabet) {
4-
return {
5-
encode: input => toHex(input),
6-
decode (input) {
7-
for (const char of input) {
8-
if (alphabet.indexOf(char) < 0) {
9-
throw new Error('invalid base16 character')
10-
}
11-
}
12-
return fromHex(input)
13-
}
14-
}
15-
}
3+
import { fromHex, toHex } from '../bytes.js'
4+
import { withAlphabet } from './base.js'
165

17-
export default { prefix: 'f', name: 'base16', ...create('0123456789abcdef') }
6+
export const base16 = withAlphabet({
7+
prefix: 'f',
8+
name: 'base16',
9+
alphabet: '0123456789abcdef',
10+
encode: toHex,
11+
decode: fromHex
12+
})

0 commit comments

Comments
 (0)