Skip to content

Commit

Permalink
feat: support decoding ArrayBuffers
Browse files Browse the repository at this point in the history
Expands supported input types to include `ArrayBuffer`s to make it
easiser for users to use modules like `fetch` that don't return
`Uint8Array`s.
  • Loading branch information
achingbrain committed Feb 15, 2024
1 parent 1e79739 commit d5f3923
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 4 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
},
"dependencies": {
"cborg": "^4.0.0",
"multiformats": "^13.0.0"
"multiformats": "^13.1.0"
},
"devDependencies": {
"@ipld/garbage": "^6.0.0",
Expand Down
24 changes: 21 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { base64 } from 'multiformats/bases/base64'
* @template T
* @typedef {import('multiformats/codecs/interface').ByteView<T>} ByteView
*/
/**
* @template T
* @typedef {import('multiformats/codecs/interface').ArrayBufferView<T>} ArrayBufferView
*/
/**
* @template T
* @typedef {import('multiformats').ToString<T>} ToString
Expand All @@ -16,6 +20,19 @@ import { base64 } from 'multiformats/bases/base64'
* @typedef {import('cborg/interface').DecodeTokenizer} DecodeTokenizer
*/

/**
* @template T
* @param {ByteView<T> | ArrayBufferView<T>} buf
* @returns {ByteView<T>}
*/
function toByteView (buf) {
if (buf instanceof ArrayBuffer) {
return new Uint8Array(buf, 0, buf.byteLength)
}

return buf
}

/**
* cidEncoder will receive all Objects during encode, it needs to filter out
* anything that's not a CID and return `null` for that so it's encoded as
Expand Down Expand Up @@ -246,13 +263,14 @@ export const encode = (node) => cborgJson.encode(node, encodeOptions)

/**
* @template T
* @param {ByteView<T>} data
* @param {ByteView<T> | ArrayBufferView<T>} data
* @returns {T}
*/
export const decode = (data) => {
const buf = toByteView(data)
// the tokenizer is stateful so we need a single instance of it
const options = Object.assign(decodeOptions, { tokenizer: new DagJsonTokenizer(data, decodeOptions) })
return cborgJson.decode(data, options)
const options = Object.assign(decodeOptions, { tokenizer: new DagJsonTokenizer(buf, decodeOptions) })
return cborgJson.decode(buf, options)
}

/**
Expand Down
9 changes: 9 additions & 0 deletions test/test-basics.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ describe('basic dag-json', () => {
same(bytes.toString(recode(byts)), expected)
})

it('encode decode with ArrayBuffer', () => {
const byts = encode({ hello: 'world' })
same(JSON.parse(bytes.toString(recode(byts))), { hello: 'world' })
const o = { link, byts: bytes.fromString('asdf'), n: null, o: {} }
const byts2 = encode(o)
same(decode(byts2), o)
same(bytes.isBinary(decode(byts2).byts.buffer), true)
})

describe('reserved space', () => {
it('allow alternative types', () => {
// wrong types
Expand Down
9 changes: 9 additions & 0 deletions test/ts-use/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ function useCodecFeature (codec: BlockCodec<297, any>) {
// use only as a BlockDecoder
useDecoder(codec)

// use with ArrayBuffer input type
useDecoderWithArrayBuffer(codec)

// use as a full BlockCodec which does both BlockEncoder & BlockDecoder
useBlockCodec(codec)
}
Expand All @@ -32,6 +35,12 @@ function useDecoder<Codec extends number> (decoder: BlockDecoder<Codec, Uint8Arr
console.log('[TS] ✓ { decoder: BlockDecoder }')
}

function useDecoderWithArrayBuffer<Codec extends number> (decoder: BlockDecoder<Codec, Uint8Array>) {
deepStrictEqual(decoder.code, 297)
deepStrictEqual(decoder.decode(Uint8Array.from([34, 98, 108, 105, 112, 34 ]).buffer), 'blip')
console.log('[TS] ✓ { decoder: BlockDecoder }')
}

function useBlockCodec<Codec extends number> (blockCodec: BlockCodec<Codec, string>) {
deepStrictEqual(blockCodec.code, 297)
deepStrictEqual(blockCodec.name, 'dag-json')
Expand Down

0 comments on commit d5f3923

Please sign in to comment.