Skip to content

Commit 6ccc5a1

Browse files
committed
Add support for Uint8Array in iterables
Fixes #21
1 parent 4082f72 commit 6ccc5a1

File tree

4 files changed

+51
-16
lines changed

4 files changed

+51
-16
lines changed

index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ export type Input =
66
| NodeJS.TypedArray
77
| ArrayBuffer
88
| string
9-
| Iterable<Buffer | string>
10-
| AsyncIterable<Buffer | string>;
9+
| Iterable<Buffer | string | NodeJS.TypedArray>
10+
| AsyncIterable<Buffer | string | NodeJS.TypedArray>;
1111

1212
/* eslint-disable @typescript-eslint/ban-types */
1313
export type ObjectInput =

index.js

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,40 @@ function baseIntoStream(isObjectMode, input) {
1717
value = [...value];
1818
}
1919

20-
if (
21-
!isObjectMode
22-
&& (
23-
value instanceof ArrayBuffer
24-
|| (ArrayBuffer.isView(value) && !Buffer.isBuffer(value))
25-
)
26-
) {
20+
// Convert ArrayBuffer/TypedArray to Buffer
21+
if (!isObjectMode && (value instanceof ArrayBuffer || (ArrayBuffer.isView(value) && !Buffer.isBuffer(value)))) {
2722
value = Buffer.from(value);
2823
}
2924

30-
// We don't iterate on strings and buffers since yielding them is ~7x faster.
25+
const convertElement = element => {
26+
if (isObjectMode) {
27+
return element;
28+
}
29+
30+
if (ArrayBuffer.isView(element) && !Buffer.isBuffer(element)) {
31+
return Buffer.from(element);
32+
}
33+
34+
if (typeof element === 'number') {
35+
return Buffer.from([element]);
36+
}
37+
38+
return element;
39+
};
40+
41+
// Handle iterables
3142
if (typeof value !== 'string' && !Buffer.isBuffer(value) && value?.[Symbol.iterator]) {
3243
for (const element of value) {
33-
yield element;
44+
yield convertElement(element);
3445
}
3546

3647
return;
3748
}
3849

50+
// Handle async iterables
3951
if (value?.[Symbol.asyncIterator]) {
4052
for await (const element of value) {
41-
yield await element;
53+
yield convertElement(await element);
4254
}
4355

4456
return;

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ intoStream('unicorn').pipe(process.stdout);
2323

2424
### intoStream(input)
2525

26-
Type: `Buffer | TypedArray | ArrayBuffer | string | Iterable<Buffer | string> | AsyncIterable<Buffer | string> | Promise`\
26+
Type: `Buffer | TypedArray | ArrayBuffer | string | Iterable<Buffer | string | TypedArray> | AsyncIterable<Buffer | string | TypedArray> | Promise`\
2727
Returns: [Readable stream](https://nodejs.org/api/stream.html#class-streamreadable)
2828

2929
### intoStream.object(input)

test.js

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,13 @@ test('async iterable', async t => {
9090
t.is(await getStream(intoStream(iterable)), fixture);
9191
});
9292

93-
test.failing('async iterable - Uint8Array', async t => {
94-
const fixture = new Uint8Array([21, 31]);
93+
test('async iterable - Uint8Array elements iterate as numbers', async t => {
94+
// When iterating over a Uint8Array directly, it yields numbers, not Uint8Array chunks
95+
// This test documents that behavior - individual numbers get converted to single-byte buffers
96+
const fixture = new Uint8Array([65, 66]); // 'A', 'B' in ASCII
9597
const iterable = asyncIterableFrom(fixture);
96-
t.is(await getStream(intoStream(iterable)), fixture);
98+
const result = await getStream(intoStream(iterable));
99+
t.is(result, 'AB');
97100
});
98101

99102
test('async generator', async t => {
@@ -197,3 +200,23 @@ test('pushes chunk on next tick', async t => {
197200

198201
t.true(flag);
199202
});
203+
204+
test('Uint8Array in iterables', async t => {
205+
// Sync iterable
206+
function * syncGen() {
207+
yield new Uint8Array([72, 101]); // "He"
208+
yield new Uint8Array([108, 108, 111]); // "llo"
209+
}
210+
211+
// Async iterable
212+
async function * asyncGen() {
213+
yield new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
214+
yield new Uint8Array([32, 87, 111, 114, 108, 100]); // " World"
215+
}
216+
217+
const syncResult = await getStream.buffer(intoStream(syncGen()));
218+
const asyncResult = await getStream.buffer(intoStream(asyncGen()));
219+
220+
t.is(syncResult.toString(), 'Hello');
221+
t.is(asyncResult.toString(), 'Hello World');
222+
});

0 commit comments

Comments
 (0)