Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e007924
Report Node.js 26.3.0 (V8 14.6.202.34, ABI 147)
Jarred-Sumner Jun 4, 2026
93fbd32
webstreams: settle pending BYOB reads when the reader is cancelled
Jarred-Sumner Jun 4, 2026
0e69614
node:stream, node:http: sync behavioral changes from Node 24.x to 26.x
Jarred-Sumner Jun 4, 2026
0393015
[autofix.ci] apply automated fixes
autofix-ci[bot] Jun 4, 2026
f6fd2e0
Bump bootstrap image versions for Node.js 26.3.0 [build images]
Jarred-Sumner Jun 4, 2026
0eb7699
Node 26: restore native upgrade pieces (V8 14.6 shim, ABI 147) [build…
Jarred-Sumner Jun 4, 2026
e18ae49
http, streams: review fixes for the Node 26 sync [build images]
Jarred-Sumner Jun 4, 2026
406f816
bootstrap: keep the xwin cache on the same filesystem as the splat ou…
Jarred-Sumner Jun 4, 2026
8561035
[autofix.ci] apply automated fixes
autofix-ci[bot] Jun 4, 2026
bc2e101
Rebuild CI images for the Node 26.3.0 toolchain [build images]
Jarred-Sumner Jun 4, 2026
a53ae4c
bootstrap: install musl Node.js from unofficial-builds.nodejs.org [bu…
Jarred-Sumner Jun 4, 2026
09f9406
Fix node-gyp on Windows and stale cipher stream tests for Node 26 [bu…
Jarred-Sumner Jun 5, 2026
6abf57e
streams: let destroyed-flagged readables still flush to piped destina…
Jarred-Sumner Jun 5, 2026
95d7107
next-pages tests: skip puppeteer browser download when it can't be us…
Jarred-Sumner Jun 5, 2026
7f3e8d3
Address review feedback: escape-slot lifetime, set-cookie consistency…
Jarred-Sumner Jun 5, 2026
b42f9b9
http2: destroy streams on socket close; never RST a never-started req…
Jarred-Sumner Jun 6, 2026
a00465f
v8: restore HandleScopeData when a Bun handle scope pops [build images]
Jarred-Sumner Jun 6, 2026
33e7483
http2: validate options.signal before the pre-aborted fast path
Jarred-Sumner Jun 6, 2026
ac7e1ce
packer: switch the windows-x64 bake VM to Standard_D4as_v7
Jarred-Sumner Jun 6, 2026
f38abb2
bootstrap: bump image versions past stale v35 tags [build images]
Jarred-Sumner Jun 6, 2026
44a873f
http2: send GOAWAY on graceful close(); run test node-gyp builds unde…
Jarred-Sumner Jun 6, 2026
f983083
v8 tests: run the node-side fixture build under bun too [build images]
Jarred-Sumner Jun 6, 2026
5f70d03
process.config: report clang=1 on macOS; surface exit codes in v8 har…
Jarred-Sumner Jun 6, 2026
6292587
complex-workspace test: skip lifecycle scripts on Windows [build images]
Jarred-Sumner Jun 6, 2026
7082a16
bootstrap: install Chrome on x64 apt images; recognize google-chrome …
Jarred-Sumner Jun 6, 2026
e8b24a3
symbols.def: export Value::IsArray/IsBigInt/IsInt32/IsMap [build images]
Jarred-Sumner Jun 6, 2026
38eadf7
v8 fixture: add stderr step markers to the tests that die on Windows …
Jarred-Sumner Jun 7, 2026
beaee52
v8: export the V8_INLINE members MSVC debug builds import [build images]
Jarred-Sumner Jun 7, 2026
6077779
http2: lastStreamId <= 0 in goaway means the actual last stream [buil…
Jarred-Sumner Jun 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/bootstrap.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Version: 19
# Version: 20
# A script that installs the dependencies needed to build and test Bun on Windows.
# Supports both x64 and ARM64 using Scoop for package management.
# Used by Azure [build images] pipeline.
Expand Down
2 changes: 1 addition & 1 deletion scripts/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh
# Version: 34
# Version: 35

# A script that installs the dependencies needed to build and test Bun.
# This should work on macOS and Linux with a POSIX shell.
Expand Down
21 changes: 18 additions & 3 deletions src/js/builtins/CompressionStream.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export function initializeCompressionStream(this, format) {
const zlib = require("node:zlib");
const stream = require("node:stream");
const {
newReadableWritablePairFromDuplex,
kValidateChunk,
kDestroyOnSyncError,
} = require("internal/webstreams_adapters");
const { isArrayBufferView, isSharedArrayBuffer } = require("node:util/types");

const builders = {
"deflate": zlib.createDeflate,
Expand All @@ -14,8 +19,18 @@ export function initializeCompressionStream(this, format) {
throw $ERR_INVALID_ARG_VALUE("format", format, "must be one of: " + Object.keys(builders).join(", "));

const handle = builders[format]();
$putByIdDirectPrivate(this, "readable", stream.Readable.toWeb(handle));
$putByIdDirectPrivate(this, "writable", stream.Writable.toWeb(handle));
const transform = newReadableWritablePairFromDuplex(handle, {
// Per the Compression Streams spec, chunks must be BufferSource
// (ArrayBuffer or ArrayBufferView not backed by SharedArrayBuffer).
[kValidateChunk]: function validateBufferSourceChunk(chunk) {
if (isSharedArrayBuffer(isArrayBufferView(chunk) ? chunk.buffer : chunk)) {
throw $ERR_INVALID_ARG_TYPE("chunk", ["ArrayBuffer", "Buffer", "TypedArray", "DataView"], chunk);
}
},
[kDestroyOnSyncError]: true,
});
$putByIdDirectPrivate(this, "readable", transform.readable);
$putByIdDirectPrivate(this, "writable", transform.writable);

return this;
}
Expand Down
21 changes: 18 additions & 3 deletions src/js/builtins/DecompressionStream.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export function initializeDecompressionStream(this, format) {
const zlib = require("node:zlib");
const stream = require("node:stream");
const {
newReadableWritablePairFromDuplex,
kValidateChunk,
kDestroyOnSyncError,
} = require("internal/webstreams_adapters");
const { isArrayBufferView, isSharedArrayBuffer } = require("node:util/types");

const builders = {
"deflate": zlib.createInflate,
Expand All @@ -14,8 +19,18 @@ export function initializeDecompressionStream(this, format) {
throw $ERR_INVALID_ARG_VALUE("format", format, "must be one of: " + Object.keys(builders).join(", "));

const handle = builders[format]();
$putByIdDirectPrivate(this, "readable", stream.Readable.toWeb(handle));
$putByIdDirectPrivate(this, "writable", stream.Writable.toWeb(handle));
const transform = newReadableWritablePairFromDuplex(handle, {
// Per the Compression Streams spec, chunks must be BufferSource
// (ArrayBuffer or ArrayBufferView not backed by SharedArrayBuffer).
[kValidateChunk]: function validateBufferSourceChunk(chunk) {
if (isSharedArrayBuffer(isArrayBufferView(chunk) ? chunk.buffer : chunk)) {
throw $ERR_INVALID_ARG_TYPE("chunk", ["ArrayBuffer", "Buffer", "TypedArray", "DataView"], chunk);
}
},
[kDestroyOnSyncError]: true,
});
$putByIdDirectPrivate(this, "readable", transform.readable);
$putByIdDirectPrivate(this, "writable", transform.writable);

return this;
}
Expand Down
13 changes: 13 additions & 0 deletions src/js/builtins/ReadableStreamInternals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,19 @@ export function readableStreamCancel(stream: ReadableStream, reason: any) {
if (state === $streamErrored) return Promise.$reject($getByIdDirectPrivate(stream, "storedError"));
$readableStreamClose(stream);

// https://streams.spec.whatwg.org/#readable-stream-cancel step 5: a BYOB
// reader's pending read requests are closed with undefined ($readableStreamClose
// only settles default-reader read requests; respond(0) is not coming after cancel).
const reader = $getByIdDirectPrivate(stream, "reader");
if (reader && $isReadableStreamBYOBReader(reader)) {
const requests = $getByIdDirectPrivate(reader, "readIntoRequests");
if (requests.isNotEmpty()) {
$putByIdDirectPrivate(reader, "readIntoRequests", $createFIFO());
for (var request = requests.shift(); request; request = requests.shift())
$fulfillPromise(request, { value: undefined, done: true });
}
}

const controller = $getByIdDirectPrivate(stream, "readableStreamController");
if (controller === null) return Promise.$resolve();

Expand Down
4 changes: 4 additions & 0 deletions src/js/internal/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ function emitErrorNt(msg, err, callback) {
const setMaxHTTPHeaderSize = $newZigFunction("node_http_binding.zig", "setMaxHTTPHeaderSize", 1);
const getMaxHTTPHeaderSize = $newZigFunction("node_http_binding.zig", "getMaxHTTPHeaderSize", 0);
const kOutHeaders = Symbol("kOutHeaders");
const kProxyConfig = Symbol("kProxyConfig");
const kWaitForProxyTunnel = Symbol("kWaitForProxyTunnel");

function ipToInt(ip) {
const octets = ip.split(".");
Expand Down Expand Up @@ -532,6 +534,7 @@ export {
kPendingCallbacks,
kPort,
kProtocol,
kProxyConfig,
kRealListen,
kRequest,
kRes,
Expand All @@ -542,6 +545,7 @@ export {
kTls,
kUpgradeOrConnect,
kUseDefaultPort,
kWaitForProxyTunnel,
noBodySymbol,
optionsSymbol,
parseProxyConfigFromEnv,
Expand Down
19 changes: 19 additions & 0 deletions src/js/internal/primordials.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,24 @@ const arrayToSafePromiseIterable = (promises, mapFn) =>
const PromiseAll = Promise.all;
const PromiseResolve = Promise.$resolve.bind(Promise);
const SafePromiseAll = (promises, mapFn) => PromiseAll(arrayToSafePromiseIterable(promises, mapFn));
const SafePromiseAllReturnVoid = (promises, mapFn) =>
new Promise((resolve, reject) => {
const { length } = promises;

if (length === 0) resolve();

let pendingPromises = length;
for (let i = 0; i < length; i++) {
const promise = mapFn != null ? mapFn(promises[i], i) : promises[i];
PromisePrototypeThen.$call(
PromiseResolve(promise),
() => {
if (--pendingPromises === 0) resolve();
},
reject,
);
}
});
const SafePromiseAllReturnArrayLike = (promises, mapFn) =>
new Promise((resolve, reject) => {
const { length } = promises;
Expand Down Expand Up @@ -136,6 +154,7 @@ export default {
),
SafePromiseAll,
SafePromiseAllReturnArrayLike,
SafePromiseAllReturnVoid,
SafeSet: makeSafe(
Set,
class SafeSet extends Set {
Expand Down
4 changes: 2 additions & 2 deletions src/js/internal/streams/duplex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ Duplex.fromWeb = function (pair, options) {
return lazyWebStreams().newStreamDuplexFromReadableWritablePair(pair, options);
};

Duplex.toWeb = function (duplex) {
return lazyWebStreams().newReadableWritablePairFromDuplex(duplex);
Duplex.toWeb = function (duplex, options) {
return lazyWebStreams().newReadableWritablePairFromDuplex(duplex, options);
};

let duplexify;
Expand Down
2 changes: 1 addition & 1 deletion src/js/internal/streams/duplexify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ function _duplexify(pair) {
eos(r, err => {
readable = false;
if (err) {
destroyer(r, err);
destroyer(w, err);
}
onfinished(err);
});
Expand Down
Loading
Loading