diff options
author | 2023-06-02 22:03:16 -0400 | |
---|---|---|
committer | 2023-06-02 19:03:16 -0700 | |
commit | f798a0cfe8372e7df62d9514e6785e6f16549d25 (patch) | |
tree | 81204276db9636ae4b10ae9de859900da6b6b437 | |
parent | 51846d0277aa58a69557668cb930448bd62de0bf (diff) | |
download | bun-f798a0cfe8372e7df62d9514e6785e6f16549d25.tar.gz bun-f798a0cfe8372e7df62d9514e6785e6f16549d25.tar.zst bun-f798a0cfe8372e7df62d9514e6785e6f16549d25.zip |
fix readableStreamToArrayBuffer (#3181)
* fix discord.js again
* remove one of the async hooks warnings
* clarify hardcoded modules docs
-rw-r--r-- | docs/project/development.md | 12 | ||||
-rw-r--r-- | packages/bun-types/bun.d.ts | 2 | ||||
-rw-r--r-- | src/js/builtins/ReadableStream.ts | 10 | ||||
-rw-r--r-- | src/js/node/async_hooks.js | 17 | ||||
-rw-r--r-- | src/js/out/WebCoreJSBuiltins.cpp | 4 | ||||
-rw-r--r-- | test/js/bun/util/readablestreamtoarraybuffer.test.ts | 29 |
6 files changed, 51 insertions, 23 deletions
diff --git a/docs/project/development.md b/docs/project/development.md index 8d90aabac..878838429 100644 --- a/docs/project/development.md +++ b/docs/project/development.md @@ -148,11 +148,17 @@ $ make generate-sink You probably won't need to run that one much. -## Modifying ESM core modules +## Modifying ESM hardcoded modules -Certain modules like `node:fs`, `node:path`, `node:stream`, and `bun:sqlite` are implemented in JavaScript. These live in `src/bun.js/*.exports.js` files. +Certain modules like `node:fs`, `node:stream`, `bun:sqlite`, and `ws` are implemented in JavaScript. These live in `src/js/{node,bun,thirdparty}` files and are pre-bundled using Bun. The bundled code is committed so CI builds can run without needing a copy of Bun. -While Bun is in beta, you can modify them at runtime in release builds via the environment variable `BUN_OVERRIDE_MODULE_PATH`. When set, Bun will look in the override directory for `<name>.exports.js` before checking the files from `src/bun.js` (which are now baked in to the binary). This lets you test changes to the ESM modules without needing to re-compile Bun. +When these are changed, run: + +``` +$ make hardcoded +``` + +In debug builds, Bun automatically loads these from the filesystem, wherever it was compiled, so no need to re-run `make dev`. In release builds, this same behavior can be done via the environment variable `BUN_OVERRIDE_MODULE_PATH`. When set to the repository root, Bun will read from the bundled modules in the repository instead of the ones baked into the binary. ## Release build diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index 1bbc89028..27b01433c 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -281,7 +281,7 @@ declare module "bun" { * @returns A promise that resolves with the concatenated chunks or the concatenated chunks as an `ArrayBuffer`. */ export function readableStreamToArrayBuffer( - stream: ReadableStream<ArrayBuffer>, + stream: ReadableStream<ArrayBufferView | ArrayBufferLike>, ): Promise<ArrayBuffer> | ArrayBuffer; /** diff --git a/src/js/builtins/ReadableStream.ts b/src/js/builtins/ReadableStream.ts index 613f869e5..26b85fb6b 100644 --- a/src/js/builtins/ReadableStream.ts +++ b/src/js/builtins/ReadableStream.ts @@ -132,12 +132,14 @@ export function readableStreamToArrayBuffer(stream: ReadableStream<ArrayBuffer>) return $readableStreamToArrayBufferDirect(stream, underlyingSource); } - var array = Bun.readableStreamToArray(stream); - if ($isPromise(array)) { - return array.$then(Bun.concatArrayBuffers); + var result = Bun.readableStreamToArray(stream); + if ($isPromise(result)) { + // `result` is an InternalPromise, which doesn't have a `.$then` method + // but `.then` isn't user-overridable, so we can use it safely. + return result.then(Bun.concatArrayBuffers); } - return Bun.concatArrayBuffers(array); + return Bun.concatArrayBuffers(result); } $linkTimeConstant; diff --git a/src/js/node/async_hooks.js b/src/js/node/async_hooks.js index c5b0c8fe5..c68a15dbe 100644 --- a/src/js/node/async_hooks.js +++ b/src/js/node/async_hooks.js @@ -5,7 +5,9 @@ var drainMicrotasks = () => { }; var notImplemented = () => { - console.warn("[bun]: async_hooks has not been implemented yet. See https://github.com/oven-sh/bun/issues/1832"); + console.warn( + "[bun] Warning: async_hooks has not been implemented yet. See https://github.com/oven-sh/bun/issues/1832", + ); notImplemented = () => {}; }; @@ -146,19 +148,11 @@ class AsyncResource { constructor(type, triggerAsyncId) { this.type = type; this.triggerAsyncId = triggerAsyncId; - - if (AsyncResource.allowedRunInAsyncScope.has(type)) { - this.runInAsyncScope = this.#runInAsyncScope; - } } type; triggerAsyncId; - // We probably will not fully support AsyncResource - // But some packages in the wild do depend on it - static allowedRunInAsyncScope = new Set(["prisma-client-request"]); - emitBefore() { return true; } @@ -169,10 +163,7 @@ class AsyncResource { emitDestroy() {} - runInAsyncScope; - - #runInAsyncScope(fn, ...args) { - notImplemented(); + runInAsyncScope(fn, ...args) { var result, err; process.nextTick(fn => { try { diff --git a/src/js/out/WebCoreJSBuiltins.cpp b/src/js/out/WebCoreJSBuiltins.cpp index f0df6a9e4..b57e346b5 100644 --- a/src/js/out/WebCoreJSBuiltins.cpp +++ b/src/js/out/WebCoreJSBuiltins.cpp @@ -2420,9 +2420,9 @@ const char* const s_readableStreamReadableStreamToTextCode = "(function (p){\"us const JSC::ConstructAbility s_readableStreamReadableStreamToArrayBufferCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; const JSC::ConstructorKind s_readableStreamReadableStreamToArrayBufferCodeConstructorKind = JSC::ConstructorKind::None; const JSC::ImplementationVisibility s_readableStreamReadableStreamToArrayBufferCodeImplementationVisibility = JSC::ImplementationVisibility::Private; -const int s_readableStreamReadableStreamToArrayBufferCodeLength = 271; +const int s_readableStreamReadableStreamToArrayBufferCodeLength = 270; static const JSC::Intrinsic s_readableStreamReadableStreamToArrayBufferCodeIntrinsic = JSC::NoIntrinsic; -const char* const s_readableStreamReadableStreamToArrayBufferCode = "(function (_){\"use strict\";var b=@getByIdDirectPrivate(_,\"underlyingSource\");if(b!==@undefined)return @readableStreamToArrayBufferDirect(_,b);var p=@Bun.readableStreamToArray(_);if(@isPromise(p))return p.@then(@Bun.concatArrayBuffers);return @Bun.concatArrayBuffers(p)})\n"; +const char* const s_readableStreamReadableStreamToArrayBufferCode = "(function (_){\"use strict\";var b=@getByIdDirectPrivate(_,\"underlyingSource\");if(b!==@undefined)return @readableStreamToArrayBufferDirect(_,b);var p=@Bun.readableStreamToArray(_);if(@isPromise(p))return p.then(@Bun.concatArrayBuffers);return @Bun.concatArrayBuffers(p)})\n"; // readableStreamToJSON const JSC::ConstructAbility s_readableStreamReadableStreamToJSONCodeConstructAbility = JSC::ConstructAbility::CannotConstruct; diff --git a/test/js/bun/util/readablestreamtoarraybuffer.test.ts b/test/js/bun/util/readablestreamtoarraybuffer.test.ts new file mode 100644 index 000000000..132e5f18a --- /dev/null +++ b/test/js/bun/util/readablestreamtoarraybuffer.test.ts @@ -0,0 +1,29 @@ +import { test, expect } from "bun:test"; + +test("readableStreamToArrayBuffer works", async () => { + // the test calls InternalPromise.then. this test ensures that such function is not user-overridable. + let _then = Promise.prototype.then; + let counter = 0; + // @ts-ignore + Promise.prototype.then = (...args) => { + counter++; + return _then.apply(this, args); + }; + try { + const result = await Bun.readableStreamToArrayBuffer( + new ReadableStream({ + async start(controller) { + controller.enqueue(new TextEncoder().encode("bun is")); + controller.enqueue(new TextEncoder().encode(" awesome!")); + controller.close(); + }, + }), + ); + expect(counter).toBe(0); + expect(new TextDecoder().decode(result)).toBe("bun is awesome!"); + } catch (error) { + throw error; + } finally { + Promise.prototype.then = _then; + } +}); |