new Response(stream).arrayBuffer() + 3 more

- `new Response(stream).arrayBuffer()`
- `new Response(stream).json()`
- `new Response(stream).text()`
- `new Response(stream).blob()`
This commit is contained in:
Jarred Sumner
2022-06-09 21:29:57 -07:00
parent b8eea5cc4a
commit 5ccf606107
16 changed files with 478 additions and 39 deletions

View File

@@ -366,7 +366,7 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerPullC
const JSC::ConstructAbility s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeConstructorKind = JSC::ConstructorKind::None;
const int s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeLength = 872;
const int s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeLength = 873;
static const JSC::Intrinsic s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableByteStreamInternalsReadableByteStreamControllerShouldCallPullCode =
"(function (controller)\n" \
@@ -381,7 +381,8 @@ const char* const s_readableByteStreamInternalsReadableByteStreamControllerShoul
" return false;\n" \
" if (!@getByIdDirectPrivate(controller, \"started\"))\n" \
" return false;\n" \
" const reader = @getByIdDirectPrivate(stream, \"reader\");\n" \
" const reader = @getByIdDirectPrivate(stream, \"reader\");\n" \
" \n" \
" if (reader && (@getByIdDirectPrivate(reader, \"readRequests\")?.isNotEmpty() || !!@getByIdDirectPrivate(reader, \"bunNativePtr\")))\n" \
" return true;\n" \
" if (@readableStreamHasBYOBReader(stream) && @getByIdDirectPrivate(@getByIdDirectPrivate(stream, \"reader\"), \"readIntoRequests\")?.isNotEmpty())\n" \

View File

@@ -119,7 +119,7 @@ const char* const s_readableStreamInitializeReadableStreamCode =
const JSC::ConstructAbility s_readableStreamReadableStreamToArrayCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamReadableStreamToArrayCodeConstructorKind = JSC::ConstructorKind::None;
const int s_readableStreamReadableStreamToArrayCodeLength = 884;
const int s_readableStreamReadableStreamToArrayCodeLength = 883;
static const JSC::Intrinsic s_readableStreamReadableStreamToArrayCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamReadableStreamToArrayCode =
"(function (stream) {\n" \
@@ -129,7 +129,6 @@ const char* const s_readableStreamReadableStreamToArrayCode =
" return null;\n" \
" }\n" \
" var reader = stream.getReader();\n" \
"\n" \
" var manyResult = reader.readMany();\n" \
" \n" \
" async function processManyResult(result) {\n" \
@@ -166,6 +165,60 @@ const char* const s_readableStreamReadableStreamToArrayCode =
"})\n" \
;
const JSC::ConstructAbility s_readableStreamReadableStreamToTextCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamReadableStreamToTextCodeConstructorKind = JSC::ConstructorKind::None;
const int s_readableStreamReadableStreamToTextCodeLength = 215;
static const JSC::Intrinsic s_readableStreamReadableStreamToTextCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamReadableStreamToTextCode =
"(function (stream) {\n" \
" \"use strict\";\n" \
"\n" \
" //\n" \
" return globalThis.Bun.readableStreamToArrayBuffer(stream).@then(function(arrayBuffer) {\n" \
" return new globalThis.TextDecoder().decode(arrayBuffer);\n" \
" });\n" \
"})\n" \
;
const JSC::ConstructAbility s_readableStreamReadableStreamToJSONCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamReadableStreamToJSONCodeConstructorKind = JSC::ConstructorKind::None;
const int s_readableStreamReadableStreamToJSONCodeLength = 238;
static const JSC::Intrinsic s_readableStreamReadableStreamToJSONCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamReadableStreamToJSONCode =
"(function (stream) {\n" \
" \"use strict\";\n" \
"\n" \
" //\n" \
" return globalThis.Bun.readableStreamToArrayBuffer(stream).@then(function(arrayBuffer) {\n" \
" return globalThis.JSON.parse(new globalThis.TextDecoder().decode(arrayBuffer));\n" \
" });\n" \
"})\n" \
;
const JSC::ConstructAbility s_readableStreamReadableStreamToBlobCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamReadableStreamToBlobCodeConstructorKind = JSC::ConstructorKind::None;
const int s_readableStreamReadableStreamToBlobCodeLength = 367;
static const JSC::Intrinsic s_readableStreamReadableStreamToBlobCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamReadableStreamToBlobCode =
"(function (stream) {\n" \
" \"use strict\";\n" \
"\n" \
" \n" \
" const array = @readableStreamToArray(stream);\n" \
" if (array === null) {\n" \
" return new globalThis.Blob();\n" \
" }\n" \
"\n" \
" return array.@then(function(chunks) {\n" \
" if (chunks === null || chunks.length === 0) {\n" \
" return new globalThis.Blob();\n" \
" }\n" \
"\n" \
" return new globalThis.Blob(chunks);\n" \
" });\n" \
"})\n" \
;
const JSC::ConstructAbility s_readableStreamReadableStreamToArrayPublicCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamReadableStreamToArrayPublicCodeConstructorKind = JSC::ConstructorKind::None;
const int s_readableStreamReadableStreamToArrayPublicCodeLength = 841;

View File

@@ -55,6 +55,18 @@ extern const char* const s_readableStreamReadableStreamToArrayCode;
extern const int s_readableStreamReadableStreamToArrayCodeLength;
extern const JSC::ConstructAbility s_readableStreamReadableStreamToArrayCodeConstructAbility;
extern const JSC::ConstructorKind s_readableStreamReadableStreamToArrayCodeConstructorKind;
extern const char* const s_readableStreamReadableStreamToTextCode;
extern const int s_readableStreamReadableStreamToTextCodeLength;
extern const JSC::ConstructAbility s_readableStreamReadableStreamToTextCodeConstructAbility;
extern const JSC::ConstructorKind s_readableStreamReadableStreamToTextCodeConstructorKind;
extern const char* const s_readableStreamReadableStreamToJSONCode;
extern const int s_readableStreamReadableStreamToJSONCodeLength;
extern const JSC::ConstructAbility s_readableStreamReadableStreamToJSONCodeConstructAbility;
extern const JSC::ConstructorKind s_readableStreamReadableStreamToJSONCodeConstructorKind;
extern const char* const s_readableStreamReadableStreamToBlobCode;
extern const int s_readableStreamReadableStreamToBlobCodeLength;
extern const JSC::ConstructAbility s_readableStreamReadableStreamToBlobCodeConstructAbility;
extern const JSC::ConstructorKind s_readableStreamReadableStreamToBlobCodeConstructorKind;
extern const char* const s_readableStreamReadableStreamToArrayPublicCode;
extern const int s_readableStreamReadableStreamToArrayPublicCodeLength;
extern const JSC::ConstructAbility s_readableStreamReadableStreamToArrayPublicCodeConstructAbility;
@@ -99,6 +111,9 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind;
#define WEBCORE_FOREACH_READABLESTREAM_BUILTIN_DATA(macro) \
macro(initializeReadableStream, readableStreamInitializeReadableStream, 2) \
macro(readableStreamToArray, readableStreamReadableStreamToArray, 1) \
macro(readableStreamToText, readableStreamReadableStreamToText, 1) \
macro(readableStreamToJSON, readableStreamReadableStreamToJSON, 1) \
macro(readableStreamToBlob, readableStreamReadableStreamToBlob, 1) \
macro(readableStreamToArrayPublic, readableStreamReadableStreamToArrayPublic, 1) \
macro(consumeReadableStream, readableStreamConsumeReadableStream, 3) \
macro(createEmptyReadableStream, readableStreamCreateEmptyReadableStream, 0) \
@@ -112,6 +127,9 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind;
#define WEBCORE_BUILTIN_READABLESTREAM_INITIALIZEREADABLESTREAM 1
#define WEBCORE_BUILTIN_READABLESTREAM_READABLESTREAMTOARRAY 1
#define WEBCORE_BUILTIN_READABLESTREAM_READABLESTREAMTOTEXT 1
#define WEBCORE_BUILTIN_READABLESTREAM_READABLESTREAMTOJSON 1
#define WEBCORE_BUILTIN_READABLESTREAM_READABLESTREAMTOBLOB 1
#define WEBCORE_BUILTIN_READABLESTREAM_READABLESTREAMTOARRAYPUBLIC 1
#define WEBCORE_BUILTIN_READABLESTREAM_CONSUMEREADABLESTREAM 1
#define WEBCORE_BUILTIN_READABLESTREAM_CREATEEMPTYREADABLESTREAM 1
@@ -126,6 +144,9 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind;
#define WEBCORE_FOREACH_READABLESTREAM_BUILTIN_CODE(macro) \
macro(readableStreamInitializeReadableStreamCode, initializeReadableStream, ASCIILiteral(), s_readableStreamInitializeReadableStreamCodeLength) \
macro(readableStreamReadableStreamToArrayCode, readableStreamToArray, ASCIILiteral(), s_readableStreamReadableStreamToArrayCodeLength) \
macro(readableStreamReadableStreamToTextCode, readableStreamToText, ASCIILiteral(), s_readableStreamReadableStreamToTextCodeLength) \
macro(readableStreamReadableStreamToJSONCode, readableStreamToJSON, ASCIILiteral(), s_readableStreamReadableStreamToJSONCodeLength) \
macro(readableStreamReadableStreamToBlobCode, readableStreamToBlob, ASCIILiteral(), s_readableStreamReadableStreamToBlobCodeLength) \
macro(readableStreamReadableStreamToArrayPublicCode, readableStreamToArrayPublic, ASCIILiteral(), s_readableStreamReadableStreamToArrayPublicCodeLength) \
macro(readableStreamConsumeReadableStreamCode, consumeReadableStream, ASCIILiteral(), s_readableStreamConsumeReadableStreamCodeLength) \
macro(readableStreamCreateEmptyReadableStreamCode, createEmptyReadableStream, ASCIILiteral(), s_readableStreamCreateEmptyReadableStreamCodeLength) \
@@ -149,6 +170,9 @@ extern const JSC::ConstructorKind s_readableStreamLockedCodeConstructorKind;
macro(pipeTo) \
macro(readableStreamToArray) \
macro(readableStreamToArrayPublic) \
macro(readableStreamToBlob) \
macro(readableStreamToJSON) \
macro(readableStreamToText) \
macro(tee) \
#define DECLARE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \

View File

@@ -89,7 +89,7 @@ const char* const s_readableStreamDefaultReaderCancelCode =
const JSC::ConstructAbility s_readableStreamDefaultReaderReadManyCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_readableStreamDefaultReaderReadManyCodeConstructorKind = JSC::ConstructorKind::None;
const int s_readableStreamDefaultReaderReadManyCodeLength = 2683;
const int s_readableStreamDefaultReaderReadManyCodeLength = 3235;
static const JSC::Intrinsic s_readableStreamDefaultReaderReadManyCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_readableStreamDefaultReaderReadManyCode =
"(function ()\n" \
@@ -121,6 +121,12 @@ const char* const s_readableStreamDefaultReaderReadManyCode =
" \n" \
"\n" \
" if (length > 0) {\n" \
" for (var i = 0; i < values.length; i++) {\n" \
" const buf = values[i];\n" \
" if (!(@ArrayBuffer.@isView(buf) || buf instanceof @ArrayBuffer)) {\n" \
" values[i] = new @Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n" \
" }\n" \
" }\n" \
" \n" \
" @resetQueue(@getByIdDirectPrivate(controller, \"queue\"));\n" \
"\n" \
@@ -143,6 +149,13 @@ const char* const s_readableStreamDefaultReaderReadManyCode =
" \n" \
" var queue = @getByIdDirectPrivate(controller, \"queue\");\n" \
" var value = [result.value].concat(queue.content.toArray(false));\n" \
" for (var i = 0; i < value.length; i++) {\n" \
" const buf = value[i];\n" \
" if (!(@ArrayBuffer.@isView(buf) || buf instanceof @ArrayBuffer)) {\n" \
" value[i] = new @Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n" \
" }\n" \
" }\n" \
"\n" \
" var size = queue.size;\n" \
" @resetQueue(queue);\n" \
"\n" \

View File

@@ -886,6 +886,19 @@ static JSC_DEFINE_HOST_FUNCTION(functionReportError,
return JSC::JSValue::encode(JSC::jsUndefined());
}
extern "C" JSC__JSValue Bun__createUninitializedArrayBuffer(JSC::JSGlobalObject* globalObject, const void* ptr, size_t len)
{
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
auto arrayBuffer = JSC::ArrayBuffer::tryCreateUninitialized(len, 1);
if (UNLIKELY(!arrayBuffer)) {
JSC::throwOutOfMemoryError(globalObject, scope);
return JSC::JSValue::encode(JSC::JSValue {});
}
RELEASE_AND_RETURN(scope, JSValue::encode(JSC::JSArrayBuffer::create(globalObject->vm(), globalObject->arrayBufferStructure(JSC::ArrayBufferSharingMode::Default), WTFMove(arrayBuffer))));
}
JSC_DECLARE_HOST_FUNCTION(functionCreateUninitializedArrayBuffer);
JSC_DEFINE_HOST_FUNCTION(functionCreateUninitializedArrayBuffer,
(JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
@@ -1273,12 +1286,9 @@ extern "C" int32_t ReadableStreamTag__tagged(Zig::GlobalObject* globalObject, JS
auto* readableStream = jsCast<JSReadableStream*>(object);
auto& vm = globalObject->vm();
auto& builtinNames = WebCore::clientData(vm)->builtinNames();
JSValue numberValue = readableStream->getDirect(vm, builtinNames.bunNativeTypePrivateName());
int32_t num = numberValue.toInt32(globalObject);
if (numberValue.isUndefined() || num == 0) {
*ptr = JSC::JSValue();
return 0;
int32_t num = 0;
if (JSValue numberValue = readableStream->getDirect(vm, builtinNames.bunNativeTypePrivateName())) {
num = numberValue.toInt32(globalObject);
}
// If this type is outside the expected range, it means something is wrong.
@@ -1533,6 +1543,78 @@ extern "C" JSC__JSValue ZigGlobalObject__readableStreamToArrayBuffer(Zig::Global
return ZigGlobalObject__readableStreamToArrayBufferBody(reinterpret_cast<Zig::GlobalObject*>(globalObject), readableStreamValue);
}
extern "C" JSC__JSValue ZigGlobalObject__readableStreamToText(Zig::GlobalObject* globalObject, JSC__JSValue readableStreamValue);
extern "C" JSC__JSValue ZigGlobalObject__readableStreamToText(Zig::GlobalObject* globalObject, JSC__JSValue readableStreamValue)
{
auto& vm = globalObject->vm();
auto clientData = WebCore::clientData(vm);
auto& builtinNames = WebCore::builtinNames(vm);
JSC::JSFunction* function = nullptr;
if (auto readableStreamToText = globalObject->m_readableStreamToText.get()) {
function = readableStreamToText;
} else {
function = JSFunction::create(vm, static_cast<JSC::FunctionExecutable*>(readableStreamReadableStreamToTextCodeGenerator(vm)), globalObject);
globalObject->m_readableStreamToText.set(vm, globalObject, function);
}
JSC::MarkedArgumentBuffer arguments = JSC::MarkedArgumentBuffer();
arguments.append(JSValue::decode(readableStreamValue));
auto callData = JSC::getCallData(function);
return JSC::JSValue::encode(call(globalObject, function, callData, JSC::jsUndefined(), arguments));
}
extern "C" JSC__JSValue ZigGlobalObject__readableStreamToJSON(Zig::GlobalObject* globalObject, JSC__JSValue readableStreamValue);
extern "C" JSC__JSValue ZigGlobalObject__readableStreamToJSON(Zig::GlobalObject* globalObject, JSC__JSValue readableStreamValue)
{
auto& vm = globalObject->vm();
auto clientData = WebCore::clientData(vm);
auto& builtinNames = WebCore::builtinNames(vm);
JSC::JSFunction* function = nullptr;
if (auto readableStreamToJSON = globalObject->m_readableStreamToJSON.get()) {
function = readableStreamToJSON;
} else {
function = JSFunction::create(vm, static_cast<JSC::FunctionExecutable*>(readableStreamReadableStreamToJSONCodeGenerator(vm)), globalObject);
globalObject->m_readableStreamToJSON.set(vm, globalObject, function);
}
JSC::MarkedArgumentBuffer arguments = JSC::MarkedArgumentBuffer();
arguments.append(JSValue::decode(readableStreamValue));
auto callData = JSC::getCallData(function);
return JSC::JSValue::encode(call(globalObject, function, callData, JSC::jsUndefined(), arguments));
}
extern "C" JSC__JSValue ZigGlobalObject__readableStreamToBlob(Zig::GlobalObject* globalObject, JSC__JSValue readableStreamValue);
extern "C" JSC__JSValue ZigGlobalObject__readableStreamToBlob(Zig::GlobalObject* globalObject, JSC__JSValue readableStreamValue)
{
auto& vm = globalObject->vm();
auto clientData = WebCore::clientData(vm);
auto& builtinNames = WebCore::builtinNames(vm);
JSC::JSFunction* function = nullptr;
if (auto readableStreamToBlob = globalObject->m_readableStreamToBlob.get()) {
function = readableStreamToBlob;
} else {
function = JSFunction::create(vm, static_cast<JSC::FunctionExecutable*>(readableStreamReadableStreamToBlobCodeGenerator(vm)), globalObject);
globalObject->m_readableStreamToBlob.set(vm, globalObject, function);
}
JSC::MarkedArgumentBuffer arguments = JSC::MarkedArgumentBuffer();
arguments.append(JSValue::decode(readableStreamValue));
auto callData = JSC::getCallData(function);
return JSC::JSValue::encode(call(globalObject, function, callData, JSC::jsUndefined(), arguments));
}
JSC_DECLARE_HOST_FUNCTION(functionReadableStreamToArrayBuffer);
JSC_DEFINE_HOST_FUNCTION(functionReadableStreamToArrayBuffer, (JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
{
@@ -1771,6 +1853,24 @@ void GlobalObject::installAPIGlobals(JSClassRef* globals, int count, JSC::VM& vm
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
}
{
JSC::Identifier identifier = JSC::Identifier::fromString(vm, "readableStreamToText"_s);
object->putDirectBuiltinFunction(vm, this, identifier, readableStreamReadableStreamToTextCodeGenerator(vm),
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
}
{
JSC::Identifier identifier = JSC::Identifier::fromString(vm, "readableStreamToBlob"_s);
object->putDirectBuiltinFunction(vm, this, identifier, readableStreamReadableStreamToBlobCodeGenerator(vm),
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
}
{
JSC::Identifier identifier = JSC::Identifier::fromString(vm, "readableStreamToJSON"_s);
object->putDirectBuiltinFunction(vm, this, identifier, readableStreamReadableStreamToJSONCodeGenerator(vm),
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0);
}
{
JSC::Identifier identifier = JSC::Identifier::fromString(vm, "concatArrayBuffers"_s);
object->putDirectNativeFunction(vm, this, identifier, 1, functionConcatTypedArrays, NoIntrinsic,
@@ -1871,7 +1971,9 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_builtinInternalFunctions.visit(visitor);
thisObject->m_JSFFIFunctionStructure.visit(visitor);
visitor.append(thisObject->m_readableStreamToArrayBufferResolve);
visitor.append(thisObject->m_readableStreamToTextResolve);
visitor.append(thisObject->m_readableStreamToText);
visitor.append(thisObject->m_readableStreamToJSON);
visitor.append(thisObject->m_readableStreamToBlob);
ScriptExecutionContext* context = thisObject->scriptExecutionContext();
visitor.addOpaqueRoot(context);
}

View File

@@ -153,7 +153,9 @@ public:
bool isThreadLocalDefaultGlobalObject = false;
mutable WriteBarrier<JSFunction> m_readableStreamToArrayBufferResolve;
mutable WriteBarrier<JSFunction> m_readableStreamToTextResolve;
mutable WriteBarrier<JSFunction> m_readableStreamToText;
mutable WriteBarrier<JSFunction> m_readableStreamToBlob;
mutable WriteBarrier<JSFunction> m_readableStreamToJSON;
private:
void addBuiltinGlobals(JSC::VM&);

View File

@@ -1620,12 +1620,30 @@ pub const JSGlobalObject = extern struct {
}
extern fn ZigGlobalObject__readableStreamToArrayBuffer(*JSGlobalObject, JSValue) JSValue;
extern fn ZigGlobalObject__readableStreamToText(*JSGlobalObject, JSValue) JSValue;
extern fn ZigGlobalObject__readableStreamToJSON(*JSGlobalObject, JSValue) JSValue;
extern fn ZigGlobalObject__readableStreamToBlob(*JSGlobalObject, JSValue) JSValue;
pub fn readableStreamToArrayBuffer(this: *JSGlobalObject, value: JSValue) JSValue {
if (comptime is_bindgen) unreachable;
return ZigGlobalObject__readableStreamToArrayBuffer(this, value);
}
pub fn readableStreamToText(this: *JSGlobalObject, value: JSValue) JSValue {
if (comptime is_bindgen) unreachable;
return ZigGlobalObject__readableStreamToText(this, value);
}
pub fn readableStreamToJSON(this: *JSGlobalObject, value: JSValue) JSValue {
if (comptime is_bindgen) unreachable;
return ZigGlobalObject__readableStreamToJSON(this, value);
}
pub fn readableStreamToBlob(this: *JSGlobalObject, value: JSValue) JSValue {
if (comptime is_bindgen) unreachable;
return ZigGlobalObject__readableStreamToBlob(this, value);
}
pub const Extern = [_][]const u8{
"bunVM",
"putCachedObject",

View File

@@ -96,7 +96,6 @@ function readableStreamToArray(stream) {
return null;
}
var reader = stream.getReader();
var manyResult = reader.readMany();
async function processManyResult(result) {
@@ -132,6 +131,45 @@ function readableStreamToArray(stream) {
return processManyResult(manyResult);
}
@globalPrivate
function readableStreamToText(stream) {
"use strict";
// TODO: optimize this to skip the extra ArrayBuffer
return globalThis.Bun.readableStreamToArrayBuffer(stream).@then(function(arrayBuffer) {
return new globalThis.TextDecoder().decode(arrayBuffer);
});
}
@globalPrivate
function readableStreamToJSON(stream) {
"use strict";
// TODO: optimize this to skip the extra ArrayBuffer
return globalThis.Bun.readableStreamToArrayBuffer(stream).@then(function(arrayBuffer) {
return globalThis.JSON.parse(new globalThis.TextDecoder().decode(arrayBuffer));
});
}
@globalPrivate
function readableStreamToBlob(stream) {
"use strict";
const array = @readableStreamToArray(stream);
if (array === null) {
return new globalThis.Blob();
}
return array.@then(function(chunks) {
if (chunks === null || chunks.length === 0) {
return new globalThis.Blob();
}
return new globalThis.Blob(chunks);
});
}
@globalPrivate
function readableStreamToArrayPublic(stream) {
"use strict";

View File

@@ -80,6 +80,12 @@ function readMany()
if (length > 0) {
for (var i = 0; i < values.length; i++) {
const buf = values[i];
if (!(@ArrayBuffer.@isView(buf) || buf instanceof @ArrayBuffer)) {
values[i] = new @Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
}
}
@resetQueue(@getByIdDirectPrivate(controller, "queue"));
@@ -102,6 +108,13 @@ function readMany()
var queue = @getByIdDirectPrivate(controller, "queue");
var value = [result.value].concat(queue.content.toArray(false));
for (var i = 0; i < value.length; i++) {
const buf = value[i];
if (!(@ArrayBuffer.@isView(buf) || buf instanceof @ArrayBuffer)) {
value[i] = new @Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
}
}
var size = queue.size;
@resetQueue(queue);

View File

@@ -3811,7 +3811,7 @@ pub const Body = struct {
pub const PendingValue = struct {
promise: ?JSValue = null,
readable: JSValue = JSValue.zero,
stream: ?JSC.WebCore.ReadableStream = null,
global: *JSGlobalObject,
task: ?*anyopaque = null,
@@ -3825,14 +3825,47 @@ pub const Body = struct {
pub fn setPromise(value: *PendingValue, globalThis: *JSC.JSGlobalObject, action: Action) JSValue {
value.action = action;
var promise = JSC.JSPromise.create(globalThis);
const promise_value = promise.asValue(globalThis);
value.promise = promise_value;
if (value.onPull) |onPull| {
value.onPull = null;
onPull(value.task.?);
if (value.stream) |*stream| {
// switch (stream.ptr) {
// .JavaScript
// }
switch (action) {
.getText, .getJSON, .getBlob, .getArrayBuffer => {
switch (stream.ptr) {
.Blob => unreachable,
else => {},
}
value.promise = switch (action) {
.getJSON => globalThis.readableStreamToJSON(stream.value),
.getArrayBuffer => globalThis.readableStreamToArrayBuffer(stream.value),
.getText => globalThis.readableStreamToText(stream.value),
.getBlob => globalThis.readableStreamToBlob(stream.value),
else => unreachable,
};
value.promise.?.ensureStillAlive();
stream.value.unprotect();
// js now owns the memory
value.stream = null;
return value.promise.?;
},
.none => {},
}
}
{
var promise = JSC.JSPromise.create(globalThis);
const promise_value = promise.asValue(globalThis);
value.promise = promise_value;
if (value.onPull) |onPull| {
value.onPull = null;
onPull(value.task.?);
}
return promise_value;
}
return promise_value;
}
pub const Action = enum {
@@ -3861,9 +3894,28 @@ pub const Body = struct {
pub const empty = Value{ .Empty = .{} };
pub fn fromReadableStream(stream: JSC.WebCore.ReadableStream, globalThis: *JSGlobalObject) Value {
if (stream.isLocked(globalThis)) {
return .{ .Error = ZigString.init("Cannot use a locked ReadableStream").toErrorInstance(globalThis) };
}
stream.value.protect();
return .{
.Locked = .{
.stream = stream,
.global = globalThis,
},
};
}
pub fn resolve(this: *Value, new: *Value, global: *JSGlobalObject) void {
if (this.* == .Locked) {
var locked = this.Locked;
var locked = &this.Locked;
if (locked.stream) |stream| {
stream.done();
locked.stream = null;
}
if (locked.callback) |callback| {
locked.callback = null;
callback(locked.task.?, new);
@@ -3936,6 +3988,11 @@ pub const Body = struct {
locked.promise = null;
}
if (locked.stream) |stream| {
stream.done();
locked.stream = null;
}
this.* = .{ .Error = error_instance };
if (locked.callback) |callback| {
locked.callback = null;
@@ -3967,6 +4024,10 @@ pub const Body = struct {
pub fn deinit(this: *Value) void {
const tag = @as(Tag, this.*);
if (tag == .Locked) {
if (this.Locked.stream) |*stream| {
stream.done();
}
this.Locked.deinit = true;
return;
}
@@ -4051,10 +4112,28 @@ pub const Body = struct {
} else |_| {}
}
// if (value.as(JSC.WebCore.ReadableStream)) |readable| {
// body.value = Body.Value.fromReadableStream(ctx, readable);
// return body;
// }
if (JSC.WebCore.ReadableStream.fromJS(value, ctx)) |readable| {
switch (readable.ptr) {
.Blob => |blob| {
body.value = .{
.Blob = Blob.initWithStore(blob.store, ctx),
};
blob.store.ref();
readable.done();
if (!blob.done) {
blob.done = true;
blob.deinit();
}
return body;
},
else => {},
}
body.value = Body.Value.fromReadableStream(readable, ctx);
return body;
}
body.value = .{
.Blob = Blob.fromJS(ctx.ptr(), value, true, false) catch |err| {
@@ -4451,7 +4530,7 @@ fn BlobInterface(comptime Type: type) type {
_: []const js.JSValueRef,
_: js.ExceptionRef,
) js.JSValueRef {
var value = this.getBodyValue();
var value: *Body.Value = this.getBodyValue();
if (value.* == .Locked) {
return value.Locked.setPromise(ctx.ptr(), .getText).asObjectRef();
}
@@ -4468,7 +4547,7 @@ fn BlobInterface(comptime Type: type) type {
_: []const js.JSValueRef,
exception: js.ExceptionRef,
) js.JSValueRef {
var value = this.getBodyValue();
var value: *Body.Value = this.getBodyValue();
if (value.* == .Locked) {
return value.Locked.setPromise(ctx.ptr(), .getJSON).asObjectRef();
}
@@ -4484,7 +4563,7 @@ fn BlobInterface(comptime Type: type) type {
_: []const js.JSValueRef,
_: js.ExceptionRef,
) js.JSValueRef {
var value = this.getBodyValue();
var value: *Body.Value = this.getBodyValue();
if (value.* == .Locked) {
return value.Locked.setPromise(ctx.ptr(), .getArrayBuffer).asObjectRef();
@@ -4502,7 +4581,8 @@ fn BlobInterface(comptime Type: type) type {
_: []const js.JSValueRef,
_: js.ExceptionRef,
) js.JSValueRef {
var value = this.getBodyValue();
var value: *Body.Value = this.getBodyValue();
if (value.* == .Locked) {
return value.Locked.setPromise(ctx.ptr(), .getBlob).asObjectRef();
}

View File

@@ -51,6 +51,10 @@ pub const ReadableStream = struct {
value: JSValue,
ptr: Handle,
pub fn done(this: *const ReadableStream) void {
this.value.unprotect();
}
pub const Tag = enum(i32) {
Invalid = -1,