diff options
-rw-r--r-- | src/bun.js/builtins/cpp/ReadableStreamInternalsBuiltins.cpp | 8 | ||||
-rw-r--r-- | src/bun.js/builtins/js/ReadableStreamInternals.js | 6 | ||||
-rw-r--r-- | test/bun.js/streams.test.js | 49 |
3 files changed, 61 insertions, 2 deletions
diff --git a/src/bun.js/builtins/cpp/ReadableStreamInternalsBuiltins.cpp b/src/bun.js/builtins/cpp/ReadableStreamInternalsBuiltins.cpp index 8f3caa3a2..a2b13e770 100644 --- a/src/bun.js/builtins/cpp/ReadableStreamInternalsBuiltins.cpp +++ b/src/bun.js/builtins/cpp/ReadableStreamInternalsBuiltins.cpp @@ -751,7 +751,7 @@ const char* const s_readableStreamInternalsPipeToFinalizeCode = const JSC::ConstructAbility s_readableStreamInternalsReadableStreamTeeCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamInternalsReadableStreamTeeCodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_readableStreamInternalsReadableStreamTeeCodeImplementationVisibility = JSC::ImplementationVisibility::Public; -const int s_readableStreamInternalsReadableStreamTeeCodeLength = 1689; +const int s_readableStreamInternalsReadableStreamTeeCodeLength = 1839; static const JSC::Intrinsic s_readableStreamInternalsReadableStreamTeeCodeIntrinsic = JSC::NoIntrinsic; const char* const s_readableStreamInternalsReadableStreamTeeCode = "(function (stream, shouldClone) {\n" \ @@ -760,6 +760,12 @@ const char* const s_readableStreamInternalsReadableStreamTeeCode = " @assert(@isReadableStream(stream));\n" \ " @assert(typeof shouldClone === \"boolean\");\n" \ "\n" \ + " var start_ = @getByIdDirectPrivate(stream, \"start\");\n" \ + " if (start_) {\n" \ + " @putByIdDirectPrivate(stream, \"start\", @undefined);\n" \ + " start_();\n" \ + " }\n" \ + "\n" \ " const reader = new @ReadableStreamDefaultReader(stream);\n" \ "\n" \ " const teeState = {\n" \ diff --git a/src/bun.js/builtins/js/ReadableStreamInternals.js b/src/bun.js/builtins/js/ReadableStreamInternals.js index e59372d24..ca1edaee8 100644 --- a/src/bun.js/builtins/js/ReadableStreamInternals.js +++ b/src/bun.js/builtins/js/ReadableStreamInternals.js @@ -609,6 +609,12 @@ function readableStreamTee(stream, shouldClone) { @assert(@isReadableStream(stream)); @assert(typeof shouldClone === "boolean"); + var start_ = @getByIdDirectPrivate(stream, "start"); + if (start_) { + @putByIdDirectPrivate(stream, "start", @undefined); + start_(); + } + const reader = new @ReadableStreamDefaultReader(stream); const teeState = { diff --git a/test/bun.js/streams.test.js b/test/bun.js/streams.test.js index 8ca424495..6488eb37f 100644 --- a/test/bun.js/streams.test.js +++ b/test/bun.js/streams.test.js @@ -4,7 +4,7 @@ import { readableStreamToArray, readableStreamToText, } from "bun"; -import { expect, it, beforeEach, afterEach } from "bun:test"; +import { expect, it, beforeEach, afterEach, describe } from "bun:test"; import { mkfifo } from "mkfifo"; import { unlinkSync, writeFileSync } from "node:fs"; import { join } from "node:path"; @@ -14,6 +14,53 @@ new Uint8Array(); beforeEach(() => gc()); afterEach(() => gc()); +describe("ReadableStream.prototype.tee", async () => { + it("class", () => { + const [a, b] = new ReadableStream().tee(); + expect(a instanceof ReadableStream).toBe(true); + expect(b instanceof ReadableStream).toBe(true); + }); + + describe("default stream", () => { + it("works", async () => { + var [a, b] = new ReadableStream({ + start(controller) { + controller.enqueue("a"); + controller.enqueue("b"); + controller.enqueue("c"); + controller.close(); + }, + }).tee(); + + expect(await readableStreamToText(a)).toBe("abc"); + expect(await readableStreamToText(b)).toBe("abc"); + }); + }); + + describe("direct stream", () => { + it("works", async () => { + try { + var [a, b] = new ReadableStream({ + pull(controller) { + controller.write("a"); + controller.write("b"); + controller.write("c"); + controller.close(); + }, + type: "direct", + }).tee(); + + expect(await readableStreamToText(a)).toBe("abc"); + expect(await readableStreamToText(b)).toBe("abc"); + } catch (e) { + console.log(e.message); + console.log(e.stack); + throw e; + } + }); + }); +}); + it("ReadableStream.prototype[Symbol.asyncIterator]", async () => { const stream = new ReadableStream({ start(controller) { |