Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 5 additions & 2 deletions .github/workflows/runtime_commit_artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,13 @@ jobs:
mv build/facebook-react-native/react-is/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react-is/
mv build/facebook-react-native/react-test-renderer/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react-test-renderer/

# Delete OSS renderer. OSS renderer is synced through internal script.
# Delete the OSS renderers, these are sync'd to RN separately.
RENDERER_FOLDER=$BASE_FOLDER/react-native-github/Libraries/Renderer/implementations/
rm $RENDERER_FOLDER/ReactFabric-{dev,prod,profiling}.js
rm $RENDERER_FOLDER/ReactNativeRenderer-{dev,prod,profiling}.js

# Delete the legacy renderer shim, this is not sync'd and will get deleted in the future.
SHIM_FOLDER=$BASE_FOLDER/react-native-github/Libraries/Renderer/shims/
rm $SHIM_FOLDER/ReactNative.js

# Copy eslint-plugin-react-hooks
# NOTE: This is different from www, here we include the full package
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"download-build-in-codesandbox-ci": "yarn build --type=node react/index react.react-server react-dom/index react-dom/client react-dom/src/server react-dom/test-utils react-dom.react-server scheduler/index react/jsx-runtime react/jsx-dev-runtime react-server-dom-webpack",
"check-release-dependencies": "node ./scripts/release/check-release-dependencies",
"generate-inline-fizz-runtime": "node ./scripts/rollup/generate-inline-fizz-runtime.js",
"generate-changelog": "node ./scripts/tasks/generate-changelog/index.js",
"flags": "node ./scripts/flags/flags.js"
},
"resolutions": {
Expand Down
16 changes: 16 additions & 0 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,22 @@ function wakeChunkIfInitialized<T>(
rejectListeners.splice(rejectionIdx, 1);
}
}
// The status might have changed after fulfilling the reference.
switch ((chunk: SomeChunk<T>).status) {
case INITIALIZED:
const initializedChunk: InitializedChunk<T> = (chunk: any);
wakeChunk(
resolveListeners,
initializedChunk.value,
initializedChunk,
);
return;
case ERRORED:
if (rejectListeners !== null) {
rejectChunk(rejectListeners, chunk.reason);
}
return;
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/react-dom/npm/server.bun.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
14 changes: 14 additions & 0 deletions packages/react-dom/server.bun.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
}
11 changes: 11 additions & 0 deletions packages/react-dom/src/server/react-dom-server.bun.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,14 @@
*/

export * from './ReactDOMFizzServerBun.js';
export {
renderToPipeableStream,
resumeToPipeableStream,
resume,
} from './ReactDOMFizzServerNode.js';
export {
prerenderToNodeStream,
prerender,
resumeAndPrerenderToNodeStream,
resumeAndPrerender,
} from './ReactDOMFizzStaticNode.js';
11 changes: 11 additions & 0 deletions packages/react-dom/src/server/react-dom-server.bun.stable.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
1 change: 1 addition & 0 deletions packages/react-native-renderer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ import * as ReactNative from './src/ReactNativeRenderer';
// Assert that the exports line up with the type we're going to expose.
(ReactNative: ReactNativeType);

// TODO: Delete the legacy renderer, only Fabric is used now.
export * from './src/ReactNativeRenderer';
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('created with ReactFabric called with ReactNative', () => {
require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNativeTagFromPublicInstance;
});

// @gate !disableLegacyMode
it('find Fabric instances with the RN renderer', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {title: true},
Expand All @@ -60,6 +61,7 @@ describe('created with ReactFabric called with ReactNative', () => {
expect(getNativeTagFromPublicInstance(instance)).toBe(2);
});

// @gate !disableLegacyMode
it('find Fabric nodes with the RN renderer', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {title: true},
Expand All @@ -80,6 +82,7 @@ describe('created with ReactFabric called with ReactNative', () => {
expect(handle).toBe(2);
});

// @gate !disableLegacyMode
it('dispatches commands on Fabric nodes with the RN renderer', () => {
nativeFabricUIManager.dispatchCommand.mockClear();
const View = createReactNativeComponentClass('RCTView', () => ({
Expand All @@ -101,6 +104,7 @@ describe('created with ReactFabric called with ReactNative', () => {
expect(UIManager.dispatchViewManagerCommand).not.toBeCalled();
});

// @gate !disableLegacyMode
it('dispatches sendAccessibilityEvent on Fabric nodes with the RN renderer', () => {
nativeFabricUIManager.sendAccessibilityEvent.mockClear();
const View = createReactNativeComponentClass('RCTView', () => ({
Expand Down Expand Up @@ -143,6 +147,7 @@ describe('created with ReactNative called with ReactFabric', () => {
.ReactNativeViewConfigRegistry.register;
});

// @gate !disableLegacyMode
it('find Paper instances with the Fabric renderer', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {title: true},
Expand All @@ -163,6 +168,7 @@ describe('created with ReactNative called with ReactFabric', () => {
expect(instance._nativeTag).toBe(3);
});

// @gate !disableLegacyMode
it('find Paper nodes with the Fabric renderer', () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {title: true},
Expand All @@ -183,6 +189,7 @@ describe('created with ReactNative called with ReactFabric', () => {
expect(handle).toBe(3);
});

// @gate !disableLegacyMode
it('dispatches commands on Paper nodes with the Fabric renderer', () => {
UIManager.dispatchViewManagerCommand.mockReset();
const View = createReactNativeComponentClass('RCTView', () => ({
Expand All @@ -205,6 +212,7 @@ describe('created with ReactNative called with ReactFabric', () => {
expect(nativeFabricUIManager.dispatchCommand).not.toBeCalled();
});

// @gate !disableLegacyMode
it('dispatches sendAccessibilityEvent on Paper nodes with the Fabric renderer', () => {
ReactNativePrivateInterface.legacySendAccessibilityEvent.mockReset();
const View = createReactNativeComponentClass('RCTView', () => ({
Expand Down
2 changes: 1 addition & 1 deletion packages/react-reconciler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ The examples in the React repository are declared a bit differently than a third

* [React ART](https://github.com/facebook/react/blob/main/packages/react-art/src/ReactART.js) and its [host config](https://github.com/facebook/react/blob/main/packages/react-art/src/ReactFiberConfigART.js)
* [React DOM](https://github.com/facebook/react/blob/main/packages/react-dom/src/client/ReactDOM.js) and its [host config](https://github.com/facebook/react/blob/main/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js)
* [React Native](https://github.com/facebook/react/blob/main/packages/react-native-renderer/src/ReactNativeRenderer.js) and its [host config](https://github.com/facebook/react/blob/main/packages/react-native-renderer/src/ReactFiberConfigNative.js)
* [React Native](https://github.com/facebook/react/blob/main/packages/react-native-renderer/src/ReactFabric.js) and its [host config](https://github.com/facebook/react/blob/main/packages/react-native-renderer/src/ReactFiberConfigFabric.js)

If these links break please file an issue and we’ll fix them. They intentionally link to the latest versions since the API is still evolving. If you have more questions please file an issue and we’ll try to help!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2196,4 +2196,29 @@ describe('ReactFlightDOMEdge', () => {
'Switched to client rendering because the server rendering errored:\n\nssr-throw',
);
});

it('should properly resolve with deduped objects', async () => {
const obj = {foo: 'hi'};

function Test(props) {
return props.obj.foo;
}

const root = {
obj: obj,
node: <Test obj={obj} />,
};

const stream = ReactServerDOMServer.renderToReadableStream(root);

const response = ReactServerDOMClient.createFromReadableStream(stream, {
serverConsumerManifest: {
moduleMap: null,
moduleLoading: null,
},
});

const result = await response;
expect(result).toEqual({obj: obj, node: 'hi'});
});
});
27 changes: 24 additions & 3 deletions packages/react-server/src/ReactServerStreamConfigBun.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -46,13 +55,15 @@ export function writeChunk(
return;
}

// $FlowFixMe[incompatible-call]: write() is compatible with both types in Bun
destination.write(chunk);
}

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);
}

Expand Down Expand Up @@ -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
Expand All @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/shared/forks/ReactFeatureFlags.native-fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const disableCommentsAsDOMContainers: boolean = true;
export const disableInputAttributeSyncing: boolean = false;
export const disableLegacyContext: boolean = false;
export const disableLegacyContextForFunctionComponents: boolean = false;
export const disableLegacyMode: boolean = false;
export const disableLegacyMode: boolean = true;
export const disableSchedulerTimeoutInWorkLoop: boolean = false;
export const disableTextareaChildren: boolean = false;
export const enableAsyncDebugInfo: boolean = false;
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/forks/ReactFeatureFlags.native-oss.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const disableCommentsAsDOMContainers: boolean = true;
export const disableInputAttributeSyncing: boolean = false;
export const disableLegacyContext: boolean = true;
export const disableLegacyContextForFunctionComponents: boolean = true;
export const disableLegacyMode: boolean = false;
export const disableLegacyMode: boolean = true;
export const disableSchedulerTimeoutInWorkLoop: boolean = false;
export const disableTextareaChildren: boolean = false;
export const enableAsyncDebugInfo: boolean = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const disableCommentsAsDOMContainers = true;
export const disableInputAttributeSyncing = false;
export const disableLegacyContext = false;
export const disableLegacyContextForFunctionComponents = false;
export const disableLegacyMode = false;
export const disableLegacyMode = true;
export const disableSchedulerTimeoutInWorkLoop = false;
export const disableTextareaChildren = false;
export const enableAsyncDebugInfo = false;
Expand Down
38 changes: 1 addition & 37 deletions scripts/rollup/bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 *******/
Expand Down Expand Up @@ -819,42 +819,6 @@ const bundles = [
}),
},

/******* React Native *******/
{
bundleTypes: __EXPERIMENTAL__
? []
: [RN_FB_DEV, RN_FB_PROD, RN_FB_PROFILING],
moduleType: RENDERER,
entry: 'react-native-renderer',
global: 'ReactNativeRenderer',
externals: ['react-native', 'ReactNativeInternalFeatureFlags'],
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: true,
babel: opts =>
Object.assign({}, opts, {
plugins: opts.plugins.concat([
[require.resolve('@babel/plugin-transform-classes'), {loose: true}],
]),
}),
},
{
bundleTypes: [RN_OSS_DEV, RN_OSS_PROD, RN_OSS_PROFILING],
moduleType: RENDERER,
entry: 'react-native-renderer',
global: 'ReactNativeRenderer',
// ReactNativeInternalFeatureFlags temporary until we land enableRemoveConsolePatches.
// Needs to be done before the next RN OSS release.
externals: ['react-native', 'ReactNativeInternalFeatureFlags'],
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: true,
babel: opts =>
Object.assign({}, opts, {
plugins: opts.plugins.concat([
[require.resolve('@babel/plugin-transform-classes'), {loose: true}],
]),
}),
},

/******* React Native Fabric *******/
{
bundleTypes: __EXPERIMENTAL__
Expand Down
1 change: 1 addition & 0 deletions scripts/rollup/shims/react-native/ReactNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {ReactNativeType} from './ReactNativeTypes';

let ReactNative: ReactNativeType;

// TODO: Delete the legacy renderer. Only ReactFabric is used now.
if (__DEV__) {
ReactNative = require('../implementations/ReactNativeRenderer-dev');
} else {
Expand Down
2 changes: 2 additions & 0 deletions scripts/shared/inlinedHostConfigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Loading
Loading