From f4a059a80a028fd7f129cda90522eb1660af774d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Louren=C3=A7o?= Date: Tue, 19 Sep 2023 22:56:32 -0300 Subject: [PATCH] lib: faster internal createBlob PR-URL: https://github.com/nodejs/node/pull/49730 Reviewed-By: Yagiz Nizipli Reviewed-By: Zeyu "Alex" Yang Reviewed-By: Matthew Aitken Reviewed-By: Benjamin Gruenbaum Reviewed-By: Rafael Gonzaga Reviewed-By: Stephen Belanger --- lib/internal/blob.js | 23 ++++++++++++++++------ test/parallel/test-blob-createobjecturl.js | 2 ++ test/parallel/test-blob.js | 7 +++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/internal/blob.js b/lib/internal/blob.js index b68037612ab8b3..a6801f3d7fba3b 100644 --- a/lib/internal/blob.js +++ b/lib/internal/blob.js @@ -6,6 +6,7 @@ const { MathMin, ObjectDefineProperties, ObjectDefineProperty, + ObjectSetPrototypeOf, PromiseReject, ReflectConstruct, RegExpPrototypeExec, @@ -403,13 +404,23 @@ function ClonedBlob() { } ClonedBlob.prototype[kDeserialize] = () => {}; +function TransferrableBlob(handle, length, type = '') { + markTransferMode(this, true, false); + this[kHandle] = handle; + this[kType] = type; + this[kLength] = length; +} + +ObjectSetPrototypeOf(TransferrableBlob.prototype, Blob.prototype); +ObjectSetPrototypeOf(TransferrableBlob, Blob); + function createBlob(handle, length, type = '') { - return ReflectConstruct(function() { - markTransferMode(this, true, false); - this[kHandle] = handle; - this[kType] = type; - this[kLength] = length; - }, [], Blob); + const transferredBlob = new TransferrableBlob(handle, length, type); + + // Fix issues like: https://github.com/nodejs/node/pull/49730#discussion_r1331720053 + transferredBlob.constructor = Blob; + + return transferredBlob; } ObjectDefineProperty(Blob.prototype, SymbolToStringTag, { diff --git a/test/parallel/test-blob-createobjecturl.js b/test/parallel/test-blob-createobjecturl.js index 70c64b138db1ac..614b8ae4a6aff0 100644 --- a/test/parallel/test-blob-createobjecturl.js +++ b/test/parallel/test-blob-createobjecturl.js @@ -24,6 +24,8 @@ const assert = require('assert'); const id = URL.createObjectURL(blob); assert.strictEqual(typeof id, 'string'); const otherBlob = resolveObjectURL(id); + assert.ok(otherBlob instanceof Blob); + assert.strictEqual(otherBlob.constructor, Blob); assert.strictEqual(otherBlob.size, 5); assert.strictEqual( Buffer.from(await otherBlob.arrayBuffer()).toString(), diff --git a/test/parallel/test-blob.js b/test/parallel/test-blob.js index e17824d2833682..04b0580202c171 100644 --- a/test/parallel/test-blob.js +++ b/test/parallel/test-blob.js @@ -473,3 +473,10 @@ assert.throws(() => new Blob({}), { await new Blob(chunks).arrayBuffer(); })().then(common.mustCall()); + +{ + const blob = new Blob(['hello']); + + assert.ok(blob.slice(0, 1).constructor === Blob); + assert.ok(blob.slice(0, 1) instanceof Blob); +}