Skip to content

[pull] main from facebook:main #177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
43714eb
Do not notify Discord for draft pull requests (#33446)
unstubbable Jun 5, 2025
dddcae7
Enable the `enableEagerAlternateStateNodeCleanup` Feature Flag (#33447)
yungsters Jun 5, 2025
b175988
[Flight] Bypass caches in Flight fixture if requested (#33445)
unstubbable Jun 6, 2025
a3be682
[tests] remove pretest compiler script (#33452)
rickhanlonii Jun 6, 2025
22b9291
[Fizz] Suspensey Images for View Transition Reveals (#33433)
sebmarkbage Jun 6, 2025
d177272
[Fizz] Error and deopt from rel=expect for large documents without bo…
sebmarkbage Jun 6, 2025
e8d15fa
[Flight] Build node-webstreams version of bundled webpack server (#33…
sebmarkbage Jun 6, 2025
ab859e3
[Flight] Build Node.js Web Streams builds for Turbopack and Parcel (#…
sebmarkbage Jun 6, 2025
a374e0e
[ci] Fix missing permissions for stale job (#33466)
poteto Jun 6, 2025
6ccf328
[Fizz] Shorten throttle to hit a specific target metric (#33463)
sebmarkbage Jun 6, 2025
142aa07
[Fizz] Support deeply nested Suspense inside fallback (#33467)
gnoff Jun 6, 2025
82f3684
Revert Node Web Streams (#33472)
sebmarkbage Jun 6, 2025
280ff6f
[Flight] Add Web Stream support to the Flight Client in Node (#33473)
sebmarkbage Jun 6, 2025
b3d5e90
[Fizz] Include unit of threshold in rel=expect deopt error (#33476)
eps1lon Jun 7, 2025
65ec57d
[Fizz] Add Web Streams to Fizz Node entry point (#33475)
sebmarkbage Jun 7, 2025
9666605
[Flight] Add Web Stream support to the Flight Server in Node (#33474)
sebmarkbage Jun 7, 2025
b367b60
[Flight] Add "use ..." boundary after the change instead of before it…
sebmarkbage Jun 7, 2025
6c8bcda
[Flight] Clarify Semantics for Awaiting Cached Data (#33438)
sebmarkbage Jun 7, 2025
e4b88ae
[Flight] Add Web Streams APIs to unbundled Node entries for Webpack (…
unstubbable Jun 7, 2025
c0b5a0c
[Flight] Use Web Streams APIs for 3rd-party component in Flight fixtu…
unstubbable Jun 8, 2025
911dbd9
feat(ReactNative): prioritize attribute config `process` function to …
hannojg Jun 9, 2025
95bcf87
Format `ReactNativeAttributePayloadFabric.js` with Prettier (#33486)
unstubbable Jun 9, 2025
4df098c
[compiler] Don't include useEffectEvent values in autodeps (#33450)
jbrown215 Jun 9, 2025
428ab82
[Flight] Simulate fetch to third party in fixture (#33484)
sebmarkbage Jun 9, 2025
b6c0aa8
[compiler]: fix link compiler & 4 broken tests from path containing s…
wlemahieu Jun 9, 2025
80c03eb
refactor[devtools]: update css for settings and support css variables…
hoxyq Jun 9, 2025
c38e268
[Fiber] Fix hydration of useId in SuspenseList (#33491)
sebmarkbage Jun 9, 2025
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
1 change: 1 addition & 0 deletions .github/workflows/compiler_discord_notify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ permissions: {}

jobs:
check_access:
if: ${{ github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
outputs:
is_member_or_collaborator: ${{ steps.check_is_member_or_collaborator.outputs.is_member_or_collaborator }}
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/runtime_build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,35 @@ jobs:
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn test ${{ matrix.params }} --ci --shard=${{ matrix.shard }}

# Hardcoded to improve parallelism
test-linter:
name: Test eslint-plugin-react-hooks
needs: [runtime_compiler_node_modules_cache]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: yarn
cache-dependency-path: |
yarn.lock
compiler/yarn.lock
- name: Restore cached node_modules
uses: actions/cache@v4
id: node_modules
with:
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
restore-keys: |
runtime-and-compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-and-compiler-node_modules-v6-
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: ./scripts/react-compiler/build-compiler.sh && ./scripts/react-compiler/link-compiler.sh
- run: yarn workspace eslint-plugin-react-hooks test

# ----- BUILD -----
build_and_lint:
name: yarn build and lint
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/runtime_discord_notify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ permissions: {}

jobs:
check_access:
if: ${{ github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
outputs:
is_member_or_collaborator: ${{ steps.check_is_member_or_collaborator.outputs.is_member_or_collaborator }}
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/shared_stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ on:
- cron: '0 * * * *'
workflow_dispatch:

permissions: {}
permissions:
# https://github.com/actions/stale/tree/v9/?tab=readme-ov-file#recommended-permissions
issues: write
pull-requests: write

env:
TZ: /usr/share/zoneinfo/America/Los_Angeles
Expand Down
4 changes: 2 additions & 2 deletions compiler/apps/playground/scripts/link-compiler.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ set -eo pipefail

HERE=$(pwd)

cd ../../packages/react-compiler-runtime && yarn --silent link && cd $HERE
cd ../../packages/babel-plugin-react-compiler && yarn --silent link && cd $HERE
cd ../../packages/react-compiler-runtime && yarn --silent link && cd "$HERE"
cd ../../packages/babel-plugin-react-compiler && yarn --silent link && cd "$HERE"

yarn --silent link babel-plugin-react-compiler
yarn --silent link react-compiler-runtime
23 changes: 23 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
BuiltInSetId,
BuiltInUseActionStateId,
BuiltInUseContextHookId,
BuiltInUseEffectEventId,
BuiltInUseEffectHookId,
BuiltInUseInsertionEffectHookId,
BuiltInUseLayoutEffectHookId,
Expand All @@ -27,6 +28,7 @@ import {
BuiltInUseTransitionId,
BuiltInWeakMapId,
BuiltInWeakSetId,
BuiltinEffectEventId,
ReanimatedSharedValueId,
ShapeRegistry,
addFunction,
Expand Down Expand Up @@ -722,6 +724,27 @@ const REACT_APIS: Array<[string, BuiltInType]> = [
BuiltInFireId,
),
],
[
'useEffectEvent',
addHook(
DEFAULT_SHAPES,
{
positionalParams: [],
restParam: Effect.Freeze,
returnType: {
kind: 'Function',
return: {kind: 'Poly'},
shapeId: BuiltinEffectEventId,
isConstructor: false,
},
calleeEffect: Effect.Read,
hookKind: 'useEffectEvent',
// Frozen because it should not mutate any locally-bound values
returnValueKind: ValueKind.Frozen,
},
BuiltInUseEffectEventId,
),
],
];

TYPED_GLOBALS.push(
Expand Down
7 changes: 7 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1785,6 +1785,13 @@ export function isFireFunctionType(id: Identifier): boolean {
);
}

export function isEffectEventFunctionType(id: Identifier): boolean {
return (
id.type.kind === 'Function' &&
id.type.shapeId === 'BuiltInEffectEventFunction'
);
}

export function isStableType(id: Identifier): boolean {
return (
isSetStateType(id) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export type HookKind =
| 'useCallback'
| 'useTransition'
| 'useImperativeHandle'
| 'useEffectEvent'
| 'Custom';

/*
Expand Down Expand Up @@ -226,6 +227,8 @@ export const BuiltInUseTransitionId = 'BuiltInUseTransition';
export const BuiltInStartTransitionId = 'BuiltInStartTransition';
export const BuiltInFireId = 'BuiltInFire';
export const BuiltInFireFunctionId = 'BuiltInFireFunction';
export const BuiltInUseEffectEventId = 'BuiltInUseEffectEvent';
export const BuiltinEffectEventId = 'BuiltInEffectEventFunction';

// See getReanimatedModuleType() in Globals.ts — this is part of supporting Reanimated's ref-like types
export const ReanimatedSharedValueId = 'ReanimatedSharedValueId';
Expand Down Expand Up @@ -948,6 +951,19 @@ addObject(BUILTIN_SHAPES, BuiltInRefValueId, [
['*', {kind: 'Object', shapeId: BuiltInRefValueId}],
]);

addFunction(
BUILTIN_SHAPES,
[],
{
positionalParams: [],
restParam: Effect.ConditionallyMutate,
returnType: {kind: 'Poly'},
calleeEffect: Effect.ConditionallyMutate,
returnValueKind: ValueKind.Mutable,
},
BuiltinEffectEventId,
);

/**
* MixedReadOnly =
* | primitive
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
HIR,
BasicBlock,
BlockId,
isEffectEventFunctionType,
} from '../HIR';
import {collectHoistablePropertyLoadsInInnerFn} from '../HIR/CollectHoistablePropertyLoads';
import {collectOptionalChainSidemap} from '../HIR/CollectOptionalChainDependencies';
Expand Down Expand Up @@ -209,7 +210,8 @@ export function inferEffectDependencies(fn: HIRFunction): void {
((isUseRefType(maybeDep.identifier) ||
isSetStateType(maybeDep.identifier)) &&
!reactiveIds.has(maybeDep.identifier.id)) ||
isFireFunctionType(maybeDep.identifier)
isFireFunctionType(maybeDep.identifier) ||
isEffectEventFunctionType(maybeDep.identifier)
) {
// exclude non-reactive hook results, which will never be in a memo block
continue;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

## Input

```javascript
// @inferEffectDependencies
import {useEffect, useEffectEvent} from 'react';
import {print} from 'shared-runtime';

/**
* We do not include effect events in dep arrays.
*/
function NonReactiveEffectEvent() {
const fn = useEffectEvent(() => print('hello world'));
useEffect(() => fn());
}

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime"; // @inferEffectDependencies
import { useEffect, useEffectEvent } from "react";
import { print } from "shared-runtime";

/**
* We do not include effect events in dep arrays.
*/
function NonReactiveEffectEvent() {
const $ = _c(2);
const fn = useEffectEvent(_temp);
let t0;
if ($[0] !== fn) {
t0 = () => fn();
$[0] = fn;
$[1] = t0;
} else {
t0 = $[1];
}
useEffect(t0, []);
}
function _temp() {
return print("hello world");
}

```

### Eval output
(kind: exception) Fixture not implemented
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @inferEffectDependencies
import {useEffect, useEffectEvent} from 'react';
import {print} from 'shared-runtime';

/**
* We do not include effect events in dep arrays.
*/
function NonReactiveEffectEvent() {
const fn = useEffectEvent(() => print('hello world'));
useEffect(() => fn());
}
3 changes: 3 additions & 0 deletions fixtures/flight/server/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ async function renderApp(req, res, next) {
} else if (req.get('Content-type')) {
proxiedHeaders['Content-type'] = req.get('Content-type');
}
if (req.headers['cache-control']) {
proxiedHeaders['Cache-Control'] = req.get('cache-control');
}

const requestsPrerender = req.path === '/prerender';

Expand Down
21 changes: 12 additions & 9 deletions fixtures/flight/server/region.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const {readFile} = require('fs').promises;

const React = require('react');

async function renderApp(res, returnValue, formState) {
async function renderApp(res, returnValue, formState, noCache) {
const {renderToPipeableStream} = await import(
'react-server-dom-webpack/server'
);
Expand Down Expand Up @@ -97,15 +97,15 @@ async function renderApp(res, returnValue, formState) {
key: filename,
})
),
React.createElement(App)
React.createElement(App, {noCache})
);
// For client-invoked server actions we refresh the tree and return a return value.
const payload = {root, returnValue, formState};
const {pipe} = renderToPipeableStream(payload, moduleMap);
pipe(res);
}

async function prerenderApp(res, returnValue, formState) {
async function prerenderApp(res, returnValue, formState, noCache) {
const {unstable_prerenderToNodeStream: prerenderToNodeStream} = await import(
'react-server-dom-webpack/static'
);
Expand Down Expand Up @@ -152,7 +152,7 @@ async function prerenderApp(res, returnValue, formState) {
key: filename,
})
),
React.createElement(App, {prerender: true})
React.createElement(App, {prerender: true, noCache})
);
// For client-invoked server actions we refresh the tree and return a return value.
const payload = {root, returnValue, formState};
Expand All @@ -161,14 +161,17 @@ async function prerenderApp(res, returnValue, formState) {
}

app.get('/', async function (req, res) {
const noCache = req.get('cache-control') === 'no-cache';

if ('prerender' in req.query) {
await prerenderApp(res, null, null);
await prerenderApp(res, null, null, noCache);
} else {
await renderApp(res, null, null);
await renderApp(res, null, null, noCache);
}
});

app.post('/', bodyParser.text(), async function (req, res) {
const noCache = req.headers['cache-control'] === 'no-cache';
const {decodeReply, decodeReplyFromBusboy, decodeAction, decodeFormState} =
await import('react-server-dom-webpack/server');
const serverReference = req.get('rsc-action');
Expand Down Expand Up @@ -201,7 +204,7 @@ app.post('/', bodyParser.text(), async function (req, res) {
// We handle the error on the client
}
// Refresh the client and return the value
renderApp(res, result, null);
renderApp(res, result, null, noCache);
} else {
// This is the progressive enhancement case
const UndiciRequest = require('undici').Request;
Expand All @@ -217,11 +220,11 @@ app.post('/', bodyParser.text(), async function (req, res) {
// Wait for any mutations
const result = await action();
const formState = decodeFormState(result, formData);
renderApp(res, null, formState);
renderApp(res, null, formState, noCache);
} catch (x) {
const {setServerState} = await import('../src/ServerState.js');
setServerState('Error: ' + x.message);
renderApp(res, null, null);
renderApp(res, null, null, noCache);
}
}
});
Expand Down
Loading