Skip to content

Commit 3e18570

Browse files
committed
feat: add ArrayBuffer output support
1 parent dbf7398 commit 3e18570

17 files changed

+106
-46
lines changed

array.d.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,7 @@ export type Uint32ArrayBuffer = ReturnType<typeof Uint32Array.from>;
4545
/**
4646
* Output format for typed array conversions
4747
*/
48-
export type OutputFormat = 'uint8' | 'buffer';
49-
50-
/**
51-
* Output format for typed array copy conversions
52-
*/
53-
export type OutputCopyFormat = 'uint8' | 'arraybuffer' | 'buffer';
48+
export type OutputFormat = 'uint8' | 'arraybuffer' | 'buffer';
5449

5550
/**
5651
* Create a view of a TypedArray in the specified format (`'uint8'` or `'buffer'`)
@@ -68,7 +63,7 @@ export type OutputCopyFormat = 'uint8' | 'arraybuffer' | 'buffer';
6863
*/
6964
export function typedView(arr: ArrayBufferView, format: 'uint8'): Uint8Array;
7065
export function typedView(arr: ArrayBufferView, format: 'buffer'): Buffer;
71-
export function typedView(arr: ArrayBufferView, format: OutputFormat): Uint8Array | Buffer;
66+
export function typedView(arr: ArrayBufferView, format: 'uint8' | 'buffer'): Uint8Array | Buffer;
7267

7368
/**
7469
* Create a copy of TypedArray underlying bytes in the specified format (`'uint8'`, `'buffer'`, or `'arraybuffer'`)
@@ -91,4 +86,4 @@ export function typedView(arr: ArrayBufferView, format: OutputFormat): Uint8Arra
9186
export function typedCopyBytes(arr: ArrayBufferView, format: 'uint8'): Uint8Array;
9287
export function typedCopyBytes(arr: ArrayBufferView, format: 'arraybuffer'): ArrayBuffer;
9388
export function typedCopyBytes(arr: ArrayBufferView, format: 'buffer'): Buffer;
94-
export function typedCopyBytes(arr: ArrayBufferView, format: OutputCopyFormat): Uint8Array | ArrayBuffer | Buffer;
89+
export function typedCopyBytes(arr: ArrayBufferView, format: OutputFormat): Uint8Array | ArrayBuffer | Buffer;

base32.d.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ export function toBase32crockford(arr: Uint8Array, options?: ToBase32Options): s
7777
* @returns The decoded bytes
7878
*/
7979
export function fromBase32(string: string, options?: FromBase32Options & { format?: 'uint8' }): Uint8ArrayBuffer;
80+
export function fromBase32(string: string, options: FromBase32Options & { format: 'arraybuffer' }): ArrayBuffer;
8081
export function fromBase32(string: string, options: FromBase32Options & { format: 'buffer' }): Buffer;
81-
export function fromBase32(string: string, options?: FromBase32Options): Uint8ArrayBuffer | Buffer;
82+
export function fromBase32(string: string, options?: FromBase32Options): Uint8ArrayBuffer | ArrayBuffer | Buffer;
8283

8384
/**
8485
* Decode a base32hex string to bytes
@@ -90,8 +91,9 @@ export function fromBase32(string: string, options?: FromBase32Options): Uint8Ar
9091
* @returns The decoded bytes
9192
*/
9293
export function fromBase32hex(string: string, options?: FromBase32Options & { format?: 'uint8' }): Uint8ArrayBuffer;
94+
export function fromBase32hex(string: string, options: FromBase32Options & { format: 'arraybuffer' }): ArrayBuffer;
9395
export function fromBase32hex(string: string, options: FromBase32Options & { format: 'buffer' }): Buffer;
94-
export function fromBase32hex(string: string, options?: FromBase32Options): Uint8ArrayBuffer | Buffer;
96+
export function fromBase32hex(string: string, options?: FromBase32Options): Uint8ArrayBuffer | ArrayBuffer | Buffer;
9597

9698
/**
9799
* Decode a Crockford base32 string to bytes
@@ -105,5 +107,6 @@ export function fromBase32hex(string: string, options?: FromBase32Options): Uint
105107
* @returns The decoded bytes
106108
*/
107109
export function fromBase32crockford(string: string, options?: FromBase32Options & { format?: 'uint8' }): Uint8ArrayBuffer;
110+
export function fromBase32crockford(string: string, options: FromBase32Options & { format: 'arraybuffer' }): ArrayBuffer;
108111
export function fromBase32crockford(string: string, options: FromBase32Options & { format: 'buffer' }): Buffer;
109-
export function fromBase32crockford(string: string, options?: FromBase32Options): Uint8ArrayBuffer | Buffer;
112+
export function fromBase32crockford(string: string, options?: FromBase32Options): Uint8ArrayBuffer | ArrayBuffer | Buffer;

base58.d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ export function toBase58(arr: Uint8Array): string;
3535
* @returns The decoded bytes
3636
*/
3737
export function fromBase58(string: string, format?: 'uint8'): Uint8ArrayBuffer;
38+
export function fromBase58(string: string, format: 'arraybuffer'): ArrayBuffer;
3839
export function fromBase58(string: string, format: 'buffer'): Buffer;
39-
export function fromBase58(string: string, format?: OutputFormat): Uint8ArrayBuffer | Buffer;
40+
export function fromBase58(string: string, format?: OutputFormat): Uint8ArrayBuffer | ArrayBuffer | Buffer;
4041

4142
/**
4243
* Encode a `Uint8Array` to a base58 string using XRP alphabet
@@ -58,5 +59,6 @@ export function toBase58xrp(arr: Uint8Array): string;
5859
* @returns The decoded bytes
5960
*/
6061
export function fromBase58xrp(string: string, format?: 'uint8'): Uint8ArrayBuffer;
62+
export function fromBase58xrp(string: string, format: 'arraybuffer'): ArrayBuffer;
6163
export function fromBase58xrp(string: string, format: 'buffer'): Buffer;
62-
export function fromBase58xrp(string: string, format?: OutputFormat): Uint8ArrayBuffer | Buffer;
64+
export function fromBase58xrp(string: string, format?: OutputFormat): Uint8ArrayBuffer | ArrayBuffer | Buffer;

base58check.d.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ export interface Base58CheckAsync {
4646
* @returns A Promise that resolves to the decoded bytes
4747
*/
4848
decode(string: string, format?: 'uint8'): Promise<Uint8ArrayBuffer>;
49+
decode(string: string, format: 'arraybuffer'): Promise<ArrayBuffer>;
4950
decode(string: string, format: 'buffer'): Promise<Buffer>;
50-
decode(string: string, format?: OutputFormat): Promise<Uint8ArrayBuffer | Buffer>;
51+
decode(string: string, format?: OutputFormat): Promise<Uint8ArrayBuffer | ArrayBuffer | Buffer>;
5152
}
5253

5354
/**
@@ -70,8 +71,9 @@ export interface Base58CheckSync extends Base58CheckAsync {
7071
* @returns The decoded bytes
7172
*/
7273
decodeSync(string: string, format?: 'uint8'): Uint8ArrayBuffer;
74+
decodeSync(string: string, format: 'arraybuffer'): ArrayBuffer;
7375
decodeSync(string: string, format: 'buffer'): Buffer;
74-
decodeSync(string: string, format?: OutputFormat): Uint8ArrayBuffer | Buffer;
76+
decodeSync(string: string, format?: OutputFormat): Uint8ArrayBuffer | ArrayBuffer | Buffer;
7577
}
7678

7779
/**
@@ -104,8 +106,9 @@ export function toBase58check(arr: Uint8Array): Promise<string>;
104106
* @returns A Promise that resolves to the decoded bytes
105107
*/
106108
export function fromBase58check(string: string, format?: 'uint8'): Promise<Uint8ArrayBuffer>;
109+
export function fromBase58check(string: string, format: 'arraybuffer'): Promise<ArrayBuffer>;
107110
export function fromBase58check(string: string, format: 'buffer'): Promise<Buffer>;
108-
export function fromBase58check(string: string, format?: OutputFormat): Promise<Uint8ArrayBuffer | Buffer>;
111+
export function fromBase58check(string: string, format?: OutputFormat): Promise<Uint8ArrayBuffer | ArrayBuffer | Buffer>;
109112

110113
/**
111114
* Encode bytes to base58check string synchronously
@@ -127,5 +130,6 @@ export function toBase58checkSync(arr: Uint8Array): string;
127130
* @returns The decoded bytes
128131
*/
129132
export function fromBase58checkSync(string: string, format?: 'uint8'): Uint8ArrayBuffer;
133+
export function fromBase58checkSync(string: string, format: 'arraybuffer'): ArrayBuffer;
130134
export function fromBase58checkSync(string: string, format: 'buffer'): Buffer;
131-
export function fromBase58checkSync(string: string, format?: OutputFormat): Uint8ArrayBuffer | Buffer;
135+
export function fromBase58checkSync(string: string, format?: OutputFormat): Uint8ArrayBuffer | ArrayBuffer | Buffer;

base64.d.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ export function toBase64url(arr: Uint8Array, options?: ToBase64Options): string;
6969
* @returns The decoded bytes
7070
*/
7171
export function fromBase64(string: string, options?: FromBase64Options & { format?: 'uint8' }): Uint8ArrayBuffer;
72+
export function fromBase64(string: string, options: FromBase64Options & { format: 'arraybuffer' }): ArrayBuffer;
7273
export function fromBase64(string: string, options: FromBase64Options & { format: 'buffer' }): Buffer;
73-
export function fromBase64(string: string, options?: FromBase64Options): Uint8ArrayBuffer | Buffer;
74+
export function fromBase64(string: string, options?: FromBase64Options): Uint8ArrayBuffer | ArrayBuffer | Buffer;
7475

7576
/**
7677
* Decode a base64url string to bytes
@@ -82,8 +83,9 @@ export function fromBase64(string: string, options?: FromBase64Options): Uint8Ar
8283
* @returns The decoded bytes
8384
*/
8485
export function fromBase64url(string: string, options?: FromBase64Options & { format?: 'uint8' }): Uint8ArrayBuffer;
86+
export function fromBase64url(string: string, options: FromBase64Options & { format: 'arraybuffer' }): ArrayBuffer;
8587
export function fromBase64url(string: string, options: FromBase64Options & { format: 'buffer' }): Buffer;
86-
export function fromBase64url(string: string, options?: FromBase64Options): Uint8ArrayBuffer | Buffer;
88+
export function fromBase64url(string: string, options?: FromBase64Options): Uint8ArrayBuffer | ArrayBuffer | Buffer;
8789

8890
/**
8991
* Decode either base64 or base64url string to bytes
@@ -95,5 +97,6 @@ export function fromBase64url(string: string, options?: FromBase64Options): Uint
9597
* @returns The decoded bytes
9698
*/
9799
export function fromBase64any(string: string, options?: FromBase64Options & { format?: 'uint8' }): Uint8ArrayBuffer;
100+
export function fromBase64any(string: string, options: FromBase64Options & { format: 'arraybuffer' }): ArrayBuffer;
98101
export function fromBase64any(string: string, options: FromBase64Options & { format: 'buffer' }): Buffer;
99-
export function fromBase64url(string: string, options?: FromBase64Options): Uint8ArrayBuffer | Buffer;
102+
export function fromBase64url(string: string, options?: FromBase64Options): Uint8ArrayBuffer | ArrayBuffer | Buffer;

bigint.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ export interface FromBigIntOptions {
3434
* @returns The converted bytes in big-endian format
3535
*/
3636
export function fromBigInt(bigint: bigint, options: { length: number; format?: 'uint8' }): Uint8ArrayBuffer;
37+
export function fromBigInt(bigint: bigint, options: { length: number; format: 'arraybuffer' }): ArrayBuffer;
3738
export function fromBigInt(bigint: bigint, options: { length: number; format: 'buffer' }): Buffer;
38-
export function fromBigInt(bigint: bigint, options: FromBigIntOptions): Uint8ArrayBuffer | Buffer;
39+
export function fromBigInt(bigint: bigint, options: FromBigIntOptions): Uint8ArrayBuffer | ArrayBuffer | Buffer;
3940

4041
/**
4142
* Convert a Uint8Array or Buffer to a BigInt

fallback/_utils.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ export function fromUint8(arr, format) {
2525
case 'uint8':
2626
if (arr.constructor !== Uint8Array) throw new Error('Unexpected')
2727
return arr
28+
case 'arraybuffer':
29+
if (arr.byteLength !== arr.buffer.byteLength) throw new Error('Unexpected')
30+
return arr.buffer
2831
case 'buffer':
2932
if (arr.length <= 64) return Buffer.from(arr)
3033
return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength)
@@ -43,6 +46,8 @@ export function fromBuffer(arr, format) {
4346
}
4447

4548
return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength)
49+
case 'arraybuffer':
50+
return fromBuffer(arr, 'uint8').buffer
4651
case 'buffer':
4752
if (arr.constructor !== Buffer) throw new Error('Unexpected')
4853
return arr

hex.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ export function toHex(arr: Uint8Array): string;
3131
* @returns The decoded bytes
3232
*/
3333
export function fromHex(string: string, format?: 'uint8'): Uint8ArrayBuffer;
34+
export function fromHex(string: string, format: 'arraybuffer'): ArrayBuffer;
3435
export function fromHex(string: string, format: 'buffer'): Buffer;
35-
export function fromHex(string: string, format?: OutputFormat): Uint8ArrayBuffer | Buffer;
36+
export function fromHex(string: string, format?: OutputFormat): Uint8ArrayBuffer | ArrayBuffer | Buffer;

tests/base32.test.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ const pool = raw.map((uint8) => {
2323
const hex = buffer.toString('hex')
2424
const shared = new Uint8Array(new SharedArrayBuffer(uint8.length))
2525
shared.set(uint8)
26-
return { uint8, shared, buffer, hex, base32, base32padded, base32hex, base32hexPadded }
26+
const ab = uint8.buffer
27+
if (ab.byteLength !== uint8.byteLength) throw new Error('Unexpected pooled Uint8Array')
28+
return { uint8, ab, shared, buffer, hex, base32, base32padded, base32hex, base32hexPadded }
2729
})
2830

2931
describe('toBase32', () => {
@@ -110,7 +112,7 @@ describe('fromBase32', () => {
110112
t.assert.throws(() => fromBase32hex(input.toUpperCase()))
111113
t.assert.throws(() => fromBase32(input.toLowerCase()))
112114
t.assert.throws(() => fromBase32hex(input.toLowerCase()))
113-
for (const format of ['uint8', 'buffer', 'hex']) {
115+
for (const format of ['uint8', 'buffer', 'arraybuffer', 'hex']) {
114116
t.assert.throws(() => fromBase32(input, { format }))
115117
t.assert.throws(() => fromBase32hex(input, { format }))
116118
}
@@ -145,9 +147,18 @@ describe('fromBase32', () => {
145147
})
146148

147149
test('buffer', (t) => {
148-
for (const { base32, base32hex, buffer } of pool) {
150+
for (const { base32, base32padded, base32hex, buffer } of pool) {
149151
t.assert.deepStrictEqual(fromBase32(base32, { format: 'buffer' }), buffer)
152+
t.assert.deepStrictEqual(fromBase32(base32padded, { format: 'buffer' }), buffer)
150153
t.assert.deepStrictEqual(fromBase32hex(base32hex, { format: 'buffer' }), buffer)
151154
}
152155
})
156+
157+
test('arraybuffer', (t) => {
158+
for (const { base32, base32padded, base32hex, ab } of pool) {
159+
t.assert.deepStrictEqual(fromBase32(base32, { format: 'arraybuffer' }), ab)
160+
t.assert.deepStrictEqual(fromBase32(base32padded, { format: 'arraybuffer' }), ab)
161+
t.assert.deepStrictEqual(fromBase32hex(base32hex, { format: 'arraybuffer' }), ab)
162+
}
163+
})
153164
})

tests/base58.test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,22 @@ test('sizes roundtrip, static data + types', (t) => {
134134
const zerosBase58 = toBase58(zeros)
135135
t.assert.deepStrictEqual(fromBase58(zerosBase58), zeros, `[0] x${size}`)
136136
t.assert.deepStrictEqual(fromBase58(zerosBase58, 'buffer'), Buffer.from(zeros))
137+
t.assert.deepStrictEqual(fromBase58(zerosBase58, 'arraybuffer'), zeros.buffer)
137138
const ones = new Uint8Array(size).fill(1)
138139
const onesBase58 = toBase58(ones)
139140
t.assert.deepStrictEqual(fromBase58(onesBase58), ones, `[1] x${size}`)
140141
t.assert.deepStrictEqual(fromBase58(onesBase58, 'buffer'), Buffer.from(ones))
142+
t.assert.deepStrictEqual(fromBase58(onesBase58, 'arraybuffer'), ones.buffer)
141143
const mid = new Uint8Array(size).fill(42)
142144
const midBase58 = toBase58(mid)
143145
t.assert.deepStrictEqual(fromBase58(midBase58), mid, `[42] x${size}`)
144146
t.assert.deepStrictEqual(fromBase58(midBase58, 'buffer'), Buffer.from(mid))
147+
t.assert.deepStrictEqual(fromBase58(midBase58, 'arraybuffer'), mid.buffer)
145148
const max = new Uint8Array(size).fill(255)
146149
const maxBase58 = toBase58(max)
147150
t.assert.deepStrictEqual(fromBase58(maxBase58), max, `[255] x${size}`)
148151
t.assert.deepStrictEqual(fromBase58(maxBase58, 'buffer'), Buffer.from(max))
152+
t.assert.deepStrictEqual(fromBase58(maxBase58, 'arraybuffer'), max.buffer)
149153
}
150154
})
151155

@@ -191,7 +195,7 @@ test('fromBase58 returns non-pooled Uint8Array instances', (t) => {
191195
t.assert.ok(tracked.length > 1000)
192196

193197
for (const u8 of tracked) {
194-
if (Buffer.isBuffer(u8)) continue
198+
if (Buffer.isBuffer(u8) || u8 instanceof ArrayBuffer) continue
195199
t.assert.strictEqual(u8.byteLength, u8.buffer.byteLength)
196200
}
197201
})

0 commit comments

Comments
 (0)