mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Fix failing tests for ReadableStream -> {text, arrayBuffer, blob}
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
# JavaScript Builtins
|
||||
|
||||
TLDR:
|
||||
|
||||
```bash
|
||||
# Delete the built files
|
||||
make clean-bindings generate-bindings && \
|
||||
# Compile all the C++ files which live in ../bindings
|
||||
make jsc-bindings-mac -j10 && \
|
||||
# Re-link the binary without compiling zig (so it's faster)
|
||||
make bun-link-lld-debug
|
||||
```
|
||||
|
||||
JavaScript files in [./js](./js) use JavaScriptCore's builtins syntax
|
||||
|
||||
```js
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
|
||||
#include "ByteLengthQueuingStrategyBuiltins.cpp"
|
||||
#include "CountQueuingStrategyBuiltins.cpp"
|
||||
#include "ImportMetaObjectBuiltins.cpp"
|
||||
#include "JSBufferConstructorBuiltins.cpp"
|
||||
#include "JSBufferPrototypeBuiltins.cpp"
|
||||
#include "JSZigGlobalObjectBuiltins.cpp"
|
||||
#include "ReadableByteStreamControllerBuiltins.cpp"
|
||||
#include "ReadableByteStreamInternalsBuiltins.cpp"
|
||||
#include "ReadableStreamBYOBReaderBuiltins.cpp"
|
||||
|
||||
@@ -104,53 +104,11 @@ function readableStreamToArray(stream) {
|
||||
|
||||
// this is a direct stream
|
||||
var underlyingSource = @getByIdDirectPrivate(stream, "underlyingSource");
|
||||
if (underlyingSource !== @undefined) {
|
||||
const promise = @initializeArrayStream.@call(stream, underlyingSource, @undefined);
|
||||
var reader = stream.getReader();
|
||||
return (async function() {
|
||||
while (@getByIdDirectPrivate(stream, "state") === @streamReadable) {
|
||||
var thisResult = await reader.read();
|
||||
if (thisResult.done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
reader.releaseLock();
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
return await promise;
|
||||
})();
|
||||
if (underlyingSource !== @undefined) {
|
||||
return @readableStreamToArrayDirect(stream, underlyingSource);
|
||||
}
|
||||
|
||||
var reader = stream.getReader();
|
||||
var manyResult = reader.readMany();
|
||||
|
||||
async function processManyResult(result) {
|
||||
|
||||
if (result.done) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var chunks = result.value || [];
|
||||
|
||||
while (true) {
|
||||
var thisResult = await reader.read();
|
||||
if (thisResult.done) {
|
||||
break;
|
||||
}
|
||||
chunks = chunks.concat(thisResult.value);
|
||||
}
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
if (manyResult && @isPromise(manyResult)) {
|
||||
return manyResult.@then(processManyResult);
|
||||
}
|
||||
|
||||
return processManyResult(manyResult);
|
||||
return @readableStreamIntoArray(stream);
|
||||
}
|
||||
|
||||
@globalPrivate
|
||||
@@ -160,73 +118,37 @@ function readableStreamToText(stream) {
|
||||
// this is a direct stream
|
||||
var underlyingSource = @getByIdDirectPrivate(stream, "underlyingSource");
|
||||
if (underlyingSource !== @undefined) {
|
||||
|
||||
const promise = @initializeTextStream.@call(stream, underlyingSource, @undefined);
|
||||
var reader = stream.getReader();
|
||||
return (async function() {
|
||||
while (@getByIdDirectPrivate(stream, "state") === @streamReadable) {
|
||||
var thisResult = await reader.read();
|
||||
if (thisResult.done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
reader.releaseLock();
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
return await promise;
|
||||
})();
|
||||
return @readableStreamToTextDirect(stream, underlyingSource);
|
||||
}
|
||||
|
||||
// TODO: optimize this to skip the extra ArrayBuffer
|
||||
var toArrayBuffer = globalThis.Bun.readableStreamToArrayBuffer(stream);
|
||||
if (toArrayBuffer && @isPromise(toArrayBuffer)) {
|
||||
return toArrayBuffer.@then(function(arrayBuffer) {
|
||||
return new globalThis.TextDecoder().decode(arrayBuffer);
|
||||
});
|
||||
return @readableStreamIntoText(stream);
|
||||
}
|
||||
|
||||
@globalPrivate
|
||||
function readableStreamToArrayBuffer(stream) {
|
||||
"use strict";
|
||||
|
||||
// this is a direct stream
|
||||
var underlyingSource = @getByIdDirectPrivate(stream, "underlyingSource");
|
||||
|
||||
if (underlyingSource !== @undefined) {
|
||||
return @readableStreamToArrayBufferDirect(stream, underlyingSource);
|
||||
}
|
||||
|
||||
return new globalThis.TextDecoder().decode(arrayBuffer);
|
||||
return globalThis.Bun.readableStreamToArray(stream).@then(globalThis.Bun.concatArrayBuffers);
|
||||
}
|
||||
|
||||
@globalPrivate
|
||||
function readableStreamToJSON(stream) {
|
||||
"use strict";
|
||||
|
||||
return @readableStreamToText(stream).@then(globalThis.JSON.parse);
|
||||
return globalThis.Bun.readableStreamToText(stream).@then(globalThis.JSON.parse);
|
||||
}
|
||||
|
||||
@globalPrivate
|
||||
function readableStreamToBlob(stream) {
|
||||
"use strict";
|
||||
|
||||
var underlyingSource = @getByIdDirectPrivate(stream, "underlyingSource");
|
||||
if (underlyingSource != @undefined) {
|
||||
var toArrayBuffer = globalThis.Bun.readableStreamToArrayBuffer(stream);
|
||||
if (toArrayBuffer && @isPromise(toArrayBuffer)) {
|
||||
return toArrayBuffer.@then(function(arrayBuffer) {
|
||||
return new globalThis.Blob([arrayBuffer]);
|
||||
});
|
||||
}
|
||||
|
||||
return new globalThis.Blob([toArrayBuffer]);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
});
|
||||
return @Promise.resolve(globalThis.Bun.readableStreamToArray(stream)).@then(array => new Blob(array));
|
||||
}
|
||||
|
||||
@globalPrivate
|
||||
@@ -459,7 +381,7 @@ function pipeTo(destination)
|
||||
|
||||
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=159869.
|
||||
// Built-in generator should be able to parse function signature to compute the function length correctly.
|
||||
let options = arguments[1];
|
||||
let options = @argument(1);
|
||||
|
||||
let preventClose = false;
|
||||
let preventAbort = false;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,6 +56,7 @@ pub const TextEncoder = struct {
|
||||
// unless it's huge
|
||||
// JSC will GC Uint8Array that occupy less than 512 bytes
|
||||
// so it's extra good for that case
|
||||
// this also means there won't be reallocations for small strings
|
||||
var buf: [2048]u8 = undefined;
|
||||
|
||||
var ctx = globalThis.ref();
|
||||
|
||||
@@ -1749,6 +1749,7 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
|
||||
return .{ .owned = @truncate(Blob.SizeType, written) };
|
||||
}
|
||||
|
||||
// In this case, it's always an error
|
||||
pub fn end(this: *@This(), err: ?JSC.Node.Syscall.Error) JSC.Node.Maybe(void) {
|
||||
log("end({s})", .{err});
|
||||
|
||||
@@ -1770,7 +1771,8 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
|
||||
if (readable.len == 0) {
|
||||
this.signal.close(err);
|
||||
this.done = true;
|
||||
this.res.endStream(false);
|
||||
// we do not close the stream here
|
||||
// this.res.endStream(false);
|
||||
this.finalize();
|
||||
return .{ .result = {} };
|
||||
}
|
||||
@@ -1778,6 +1780,10 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
|
||||
if (!this.hasBackpressure()) {
|
||||
if (this.send(readable)) {
|
||||
this.handleWrote(readable.len);
|
||||
this.signal.close(err);
|
||||
this.done = true;
|
||||
this.res.endStream(false);
|
||||
this.finalize();
|
||||
return .{ .result = {} };
|
||||
}
|
||||
|
||||
@@ -1852,6 +1858,8 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
|
||||
this.finalize();
|
||||
}
|
||||
|
||||
// This can be called _many_ times for the same instance
|
||||
// so it must zero out state instead of make it
|
||||
pub fn finalize(this: *@This()) void {
|
||||
log("finalize()", .{});
|
||||
|
||||
@@ -1866,7 +1874,7 @@ pub fn HTTPServerWritable(comptime ssl: bool) type {
|
||||
this.buffer = bun.ByteList.init("");
|
||||
this.pooled_buffer = null;
|
||||
pooled.release();
|
||||
} else if (!ByteListPool.full()) {
|
||||
} else if (this.buffer.cap == 0) {} else if (!ByteListPool.full()) {
|
||||
var entry = ByteListPool.get(this.allocator);
|
||||
entry.data = this.buffer;
|
||||
this.buffer = bun.ByteList.init("");
|
||||
|
||||
Reference in New Issue
Block a user