From b4455a6ee6450fae830ae0b6e53e77f7a147bc27 Mon Sep 17 00:00:00 2001 From: Michael H Date: Tue, 28 Oct 2025 09:06:45 +1100 Subject: [PATCH] [react-dom] Include all Node.js APIs in Bun entrypoint for `/server` (#34193) --- packages/react-dom/npm/server.bun.js | 2 ++ packages/react-dom/server.bun.js | 14 ++++++++++ .../src/server/react-dom-server.bun.js | 11 ++++++++ .../src/server/react-dom-server.bun.stable.js | 11 ++++++++ .../src/ReactServerStreamConfigBun.js | 27 ++++++++++++++++--- scripts/rollup/bundles.js | 2 +- scripts/shared/inlinedHostConfigs.js | 2 ++ 7 files changed, 65 insertions(+), 4 deletions(-) diff --git a/packages/react-dom/npm/server.bun.js b/packages/react-dom/npm/server.bun.js index bb44b38ec3..ec94e0f0bc 100644 --- a/packages/react-dom/npm/server.bun.js +++ b/packages/react-dom/npm/server.bun.js @@ -12,6 +12,8 @@ if (process.env.NODE_ENV === 'production') { exports.version = b.version; exports.renderToReadableStream = b.renderToReadableStream; +exports.renderToPipeableStream = b.renderToPipeableStream; +exports.resumeToPipeableStream = b.resumeToPipeableStream; exports.resume = b.resume; exports.renderToString = l.renderToString; exports.renderToStaticMarkup = l.renderToStaticMarkup; diff --git a/packages/react-dom/server.bun.js b/packages/react-dom/server.bun.js index 7d054e5534..13e312e559 100644 --- a/packages/react-dom/server.bun.js +++ b/packages/react-dom/server.bun.js @@ -38,3 +38,17 @@ export function resume() { arguments, ); } + +export function renderToPipeableStream() { + return require('./src/server/react-dom-server.bun').renderToPipeableStream.apply( + this, + arguments, + ); +} + +export function resumeToPipeableStream() { + return require('./src/server/react-dom-server.bun').resumeToPipeableStream.apply( + this, + arguments, + ); +} diff --git a/packages/react-dom/src/server/react-dom-server.bun.js b/packages/react-dom/src/server/react-dom-server.bun.js index 5ca420c230..17c9c1f465 100644 --- a/packages/react-dom/src/server/react-dom-server.bun.js +++ b/packages/react-dom/src/server/react-dom-server.bun.js @@ -8,3 +8,14 @@ */ export * from './ReactDOMFizzServerBun.js'; +export { + renderToPipeableStream, + resumeToPipeableStream, + resume, +} from './ReactDOMFizzServerNode.js'; +export { + prerenderToNodeStream, + prerender, + resumeAndPrerenderToNodeStream, + resumeAndPrerender, +} from './ReactDOMFizzStaticNode.js'; diff --git a/packages/react-dom/src/server/react-dom-server.bun.stable.js b/packages/react-dom/src/server/react-dom-server.bun.stable.js index 4d17773002..50c83508ba 100644 --- a/packages/react-dom/src/server/react-dom-server.bun.stable.js +++ b/packages/react-dom/src/server/react-dom-server.bun.stable.js @@ -8,3 +8,14 @@ */ export {renderToReadableStream, version} from './ReactDOMFizzServerBun.js'; +export { + renderToPipeableStream, + resume, + resumeToPipeableStream, +} from './ReactDOMFizzServerNode.js'; +export { + prerenderToNodeStream, + prerender, + resumeAndPrerenderToNodeStream, + resumeAndPrerender, +} from './ReactDOMFizzStaticNode.js'; diff --git a/packages/react-server/src/ReactServerStreamConfigBun.js b/packages/react-server/src/ReactServerStreamConfigBun.js index ef53ca9623..a9079bee43 100644 --- a/packages/react-server/src/ReactServerStreamConfigBun.js +++ b/packages/react-server/src/ReactServerStreamConfigBun.js @@ -9,13 +9,22 @@ /* global Bun */ +import type {Writable} from 'stream'; + type BunReadableStreamController = ReadableStreamController & { end(): mixed, write(data: Chunk | BinaryChunk): void, error(error: Error): void, flush?: () => void, }; -export type Destination = BunReadableStreamController; + +interface MightBeFlushable { + flush?: () => void; +} + +export type Destination = + | BunReadableStreamController + | (Writable & MightBeFlushable); export type PrecomputedChunk = string; export opaque type Chunk = string; @@ -46,6 +55,7 @@ export function writeChunk( return; } + // $FlowFixMe[incompatible-call]: write() is compatible with both types in Bun destination.write(chunk); } @@ -53,6 +63,7 @@ export function writeChunkAndReturn( destination: Destination, chunk: PrecomputedChunk | Chunk | BinaryChunk, ): boolean { + // $FlowFixMe[incompatible-call]: write() is compatible with both types in Bun return !!destination.write(chunk); } @@ -86,11 +97,21 @@ export function byteLengthOfBinaryChunk(chunk: BinaryChunk): number { } export function closeWithError(destination: Destination, error: mixed): void { + // $FlowFixMe[incompatible-use] // $FlowFixMe[method-unbinding] if (typeof destination.error === 'function') { // $FlowFixMe[incompatible-call]: This is an Error object or the destination accepts other types. destination.error(error); - } else { + + // $FlowFixMe[incompatible-use] + // $FlowFixMe[method-unbinding] + } else if (typeof destination.destroy === 'function') { + // $FlowFixMe[incompatible-call]: This is an Error object or the destination accepts other types. + destination.destroy(error); + + // $FlowFixMe[incompatible-use] + // $FlowFixMe[method-unbinding] + } else if (typeof destination.close === 'function') { // Earlier implementations doesn't support this method. In that environment you're // supposed to throw from a promise returned but we don't return a promise in our // approach. We could fork this implementation but this is environment is an edge @@ -101,7 +122,7 @@ export function closeWithError(destination: Destination, error: mixed): void { } } -export function createFastHash(input: string): string | number { +export function createFastHash(input: string): number { return Bun.hash(input); } diff --git a/scripts/rollup/bundles.js b/scripts/rollup/bundles.js index 69d0b534fc..c4176099b7 100644 --- a/scripts/rollup/bundles.js +++ b/scripts/rollup/bundles.js @@ -405,7 +405,7 @@ const bundles = [ global: 'ReactDOMServer', minifyWithProdErrorCodes: false, wrapWithModuleBoundaries: false, - externals: ['react', 'react-dom'], + externals: ['react', 'react-dom', 'crypto', 'stream', 'util'], }, /******* React DOM Fizz Server External Runtime *******/ diff --git a/scripts/shared/inlinedHostConfigs.js b/scripts/shared/inlinedHostConfigs.js index 801060c4c5..ebdbf6cf52 100644 --- a/scripts/shared/inlinedHostConfigs.js +++ b/scripts/shared/inlinedHostConfigs.js @@ -250,6 +250,8 @@ module.exports = [ 'react-dom/server.bun', 'react-dom/src/server/react-dom-server.bun', 'react-dom/src/server/ReactDOMFizzServerBun.js', + 'react-dom/src/server/ReactDOMFizzServerNode.js', + 'react-dom/src/server/ReactDOMFizzStaticNode.js', 'react-dom-bindings', 'react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js', 'react-dom-bindings/src/server/ReactFlightServerConfigDOM.js',