Skip to content

Commit b739509

Browse files
authored
fix: support uint8arraylists (#149)
To make parsing streams more flexible, support uint8arraylists
1 parent fd0158f commit b739509

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

packages/it-ndjson/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,8 @@
5454
"aegir": "^45.0.8",
5555
"buffer": "^6.0.3",
5656
"it-all": "^3.0.0"
57+
},
58+
"dependencies": {
59+
"uint8arraylist": "^2.4.8"
5760
}
5861
}

packages/it-ndjson/src/parse.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { isUint8ArrayList } from 'uint8arraylist'
12
import { InvalidMessageLengthError } from './errors.js'
3+
import type { Uint8ArrayList } from 'uint8arraylist'
24

35
export interface ParseOptions {
46
/**
@@ -7,7 +9,7 @@ export interface ParseOptions {
79
maxMessageLength?: number
810
}
911

10-
export default async function * parse <T> (source: AsyncIterable<Uint8Array | string> | Iterable<Uint8Array | string>, opts: ParseOptions = {}): AsyncGenerator<T, void, undefined> {
12+
export default async function * parse <T> (source: AsyncIterable<Uint8Array | Uint8ArrayList | string> | Iterable<Uint8Array | Uint8ArrayList | string>, opts: ParseOptions = {}): AsyncGenerator<T, void, undefined> {
1113
const matcher = /\r?\n/
1214
const decoder = new TextDecoder('utf8')
1315
let buffer = ''
@@ -17,6 +19,10 @@ export default async function * parse <T> (source: AsyncIterable<Uint8Array | st
1719
chunk = new TextEncoder().encode(chunk)
1820
}
1921

22+
if (isUint8ArrayList(chunk)) {
23+
chunk = chunk.subarray()
24+
}
25+
2026
buffer += decoder.decode(chunk, { stream: true })
2127

2228
if (buffer.length > (opts?.maxMessageLength ?? buffer.length)) {

packages/it-ndjson/test/index.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Buffer } from 'buffer'
22
import { expect } from 'aegir/chai'
33
import all from 'it-all'
4+
import { Uint8ArrayList } from 'uint8arraylist'
45
import * as ndjson from '../src/index.js'
56

67
async function * toAsyncIterator <T> (array: T[]): AsyncIterable<T> {
@@ -74,6 +75,20 @@ describe('it-ndjson', () => {
7475
expect(results).to.deep.equal([{ id: 1 }, { id: 2 }, { id: 3 }])
7576
})
7677

78+
it('should split from Uint8ArrayLists', async () => {
79+
const source = toAsyncIterator([new Uint8ArrayList(toUint8Array('{ "id": 1 }\n{ "i')), new Uint8ArrayList(toUint8Array('d": 2 }')), new Uint8ArrayList(toUint8Array('\n{"id":3}'))])
80+
const results = await all(ndjson.parse(source))
81+
82+
expect(results).to.deep.equal([{ id: 1 }, { id: 2 }, { id: 3 }])
83+
})
84+
85+
it('should split from Uint8ArrayLists with multiple chunks', async () => {
86+
const source = toAsyncIterator([new Uint8ArrayList(toUint8Array('{ "id": 1 }\n{ "i'), toUint8Array('d": 2 }')), new Uint8ArrayList(toUint8Array('\n{"id":3}'))])
87+
const results = await all(ndjson.parse(source))
88+
89+
expect(results).to.deep.equal([{ id: 1 }, { id: 2 }, { id: 3 }])
90+
})
91+
7792
it('should round trip', async () => {
7893
const input = '{"id":1}\n{"id":2}\n{"id":3}\n'
7994
const source = toAsyncIterator([input])

0 commit comments

Comments
 (0)