Skip to content

Commit 87e13bc

Browse files
committed
allow stream ponyfill as ReadableStream
1 parent 11a76c4 commit 87e13bc

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"ts-node": "^8.2.0",
8888
"tsconfig-paths": "^3.8.0",
8989
"typescript": "^3.5.1",
90+
"web-streams-polyfill": "^2.0.3",
9091
"webpack": "^4.30.0",
9192
"webpack-cli": "^3.3.1"
9293
},

src/utils/stream.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// utility for whatwg streams
22

3+
// The living standard of whatwg streams says
4+
// ReadableStream is also AsyncIterable, but
5+
// as of June 2019, no browser implements it.
6+
// See https://streams.spec.whatwg.org/ for details
37
export type ReadableStreamLike<T> = AsyncIterable<T> | ReadableStream<T>;
48

5-
export function isReadableStream<T>(object: unknown): object is ReadableStream<T> {
6-
return typeof ReadableStream !== "undefined" && object instanceof ReadableStream;
9+
export function isAsyncIterable<T>(object: object): object is AsyncIterable<T> {
10+
return (object as any)[Symbol.asyncIterator] != null;
711
}
812

913
export async function* asyncIterableFromStream<T>(stream: ReadableStream<T>): AsyncIterable<T> {
@@ -23,9 +27,9 @@ export async function* asyncIterableFromStream<T>(stream: ReadableStream<T>): As
2327
}
2428

2529
export function ensureAsyncIterabe<T>(streamLike: ReadableStreamLike<T>): AsyncIterable<T> {
26-
if (isReadableStream(streamLike)) {
27-
return asyncIterableFromStream(streamLike);
28-
} else {
30+
if (isAsyncIterable(streamLike)) {
2931
return streamLike;
32+
} else {
33+
return asyncIterableFromStream(streamLike);
3034
}
3135
}

test/whatwg-streams.test.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { deepStrictEqual } from "assert";
22
import { decodeAsync, encode, decodeArrayStream } from "@msgpack/msgpack";
3-
3+
import { ReadableStream as PonyReadableStream } from "web-streams-polyfill/ponyfill";
44
const isReadableStreamConstructorAvailable: boolean = (() => {
55
try {
66
// Edge <= 18 has ReadableStream but its constructor is not available
@@ -13,24 +13,28 @@ const isReadableStreamConstructorAvailable: boolean = (() => {
1313
}
1414
})();
1515

16-
describe("whatwg streams", () => {
17-
before(function() {
18-
if (!isReadableStreamConstructorAvailable) {
19-
this.skip();
20-
}
21-
});
16+
const MyReadableStream: typeof ReadableStream = isReadableStreamConstructorAvailable
17+
? ReadableStream
18+
: PonyReadableStream;
2219

23-
it("decodeAsync", async () => {
20+
// Downgrade stream not to implement AsycIterable<T>
21+
function downgradeReadableStream(stream: ReadableStream) {
22+
(stream as any)[Symbol.asyncIterator] = undefined;
23+
}
24+
25+
describe("whatwg streams", () => {
26+
it("decodeArrayStream", async () => {
2427
const data = [1, 2, 3];
2528
const encoded = encode(data);
26-
const stream = new ReadableStream({
29+
const stream = new MyReadableStream({
2730
start(controller) {
2831
for (const byte of encoded) {
2932
controller.enqueue([byte]);
3033
}
3134
controller.close();
3235
},
3336
});
37+
downgradeReadableStream(stream);
3438

3539
const items: Array<unknown> = [];
3640
for await (const item of decodeArrayStream(stream)) {
@@ -39,17 +43,18 @@ describe("whatwg streams", () => {
3943
deepStrictEqual(items, data);
4044
});
4145

42-
it("reads from stream", async () => {
46+
it("decodeAsync", async () => {
4347
const data = [1, 2, 3];
4448
const encoded = encode(data);
45-
const stream = new ReadableStream({
49+
const stream = new MyReadableStream({
4650
start(controller) {
4751
for (const byte of encoded) {
4852
controller.enqueue([byte]);
4953
}
5054
controller.close();
5155
},
5256
});
57+
downgradeReadableStream(stream);
5358

5459
deepStrictEqual(await decodeAsync(stream), data);
5560
});

0 commit comments

Comments
 (0)