Skip to content

Commit

Permalink
feat: support decoding ArrayBuffers (#114)
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.

---------

Co-authored-by: Rod Vagg <rod@vagg.org>
  • Loading branch information
achingbrain and rvagg committed Feb 16, 2024
1 parent d6d1def commit a10269d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 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
22 changes: 20 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ const CID_CBOR_TAG = 42
* @typedef {import('multiformats/codecs/interface').ByteView<T>} ByteView
*/

/**
* @template T
* @typedef {import('multiformats/codecs/interface').ArrayBufferView<T>} ArrayBufferView
*/

/**
* @template T
* @param {ByteView<T> | ArrayBufferView<T>} buf
* @returns {ByteView<T>}
*/
export 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 @@ -123,7 +141,7 @@ export const encode = (node) => cborg.encode(node, _encodeOptions)

/**
* @template T
* @param {ByteView<T>} data
* @param {ByteView<T> | ArrayBufferView<T>} data
* @returns {T}
*/
export const decode = (data) => cborg.decode(data, _decodeOptions)
export const decode = (data) => cborg.decode(toByteView(data), _decodeOptions)
14 changes: 14 additions & 0 deletions test/test-basics.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ describe('dag-cbor', () => {
same(deserializedObj, obj)
})

test('.serialize and .deserialize with ArrayBuffer', () => {
same(bytes.isBinary(serializedObj), true)

// Check for the tag 42
// d8 = tag, 2a = 42
same(bytes.toHex(serializedObj).match(/d82a/g)?.length, 4)

const deserializedObj = decode(serializedObj.buffer.slice(
serializedObj.byteOffset,
serializedObj.byteOffset + serializedObj.byteLength)
)
same(deserializedObj, obj)
})

test('.serialize and .deserialize large objects', () => {
// larger than the default borc heap size, should auto-grow the heap
const dataSize = 128 * 1024
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<0x71, 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, 0x70)
deepStrictEqual(decoder.decode(Uint8Array.from([100, 98, 108, 105, 112]).buffer), 'blip')
console.log('[TS] ✓ { decoder: BlockDecoder }')
}

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

0 comments on commit a10269d

Please sign in to comment.