Compare commits

...

19 Commits

Author SHA1 Message Date
Sebastian Sebbie Silbermann
e3145b1f37 Version 19.1.4
Some checks failed
(Runtime) Build and Test / Cache Runtime node_modules (push) Has been cancelled
(Runtime) Build and Test / Cache Runtime, Compiler node_modules (push) Has been cancelled
(Runtime) Build and Test / Discover flow inline configs (push) Has been cancelled
(Runtime) Build and Test / Flow check ${{ matrix.flow_inline_config_shortname }} (push) Has been cancelled
(Runtime) Build and Test / Confirm generated inline Fizz runtime is up to date (push) Has been cancelled
(Runtime) Build and Test / Check flags (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / Test eslint-plugin-react-hooks (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / Process artifacts combined (push) Has been cancelled
(Runtime) Build and Test / Search build artifacts for unminified errors (push) Has been cancelled
(Runtime) Build and Test / Check release dependencies (push) Has been cancelled
(Runtime) Build and Test / Check fixtures DOM (stable) (push) Has been cancelled
(Runtime) Build and Test / Run fixtures Flight tests (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (chrome) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (edge) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (firefox) (push) Has been cancelled
(Runtime) Build and Test / Merge DevTools artifacts (push) Has been cancelled
(Runtime) Build and Test / Run DevTools e2e tests (push) Has been cancelled
(Runtime) Build and Test / Run sizebot (push) Has been cancelled
2025-12-11 23:35:18 +01:00
Sebastian Markbage
72f436d0ef Add extra protection 2025-12-11 23:25:11 +01:00
Sebastian Sebbie Silbermann
cff62b6370 Version 19.1.3
Some checks failed
(Runtime) Build and Test / Cache Runtime node_modules (push) Has been cancelled
(Runtime) Build and Test / Cache Runtime, Compiler node_modules (push) Has been cancelled
(Runtime) Build and Test / Discover flow inline configs (push) Has been cancelled
(Runtime) Build and Test / Flow check ${{ matrix.flow_inline_config_shortname }} (push) Has been cancelled
(Runtime) Build and Test / Confirm generated inline Fizz runtime is up to date (push) Has been cancelled
(Runtime) Build and Test / Check flags (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=experimental --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development --persistent (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=development (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=stable --env=production (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-classic --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=www-modern --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=development --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=false (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 1/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 2/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 3/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 4/5) (push) Has been cancelled
(Runtime) Build and Test / yarn test -r=xplat --env=production --variant=true (Shard 5/5) (push) Has been cancelled
(Runtime) Build and Test / Test eslint-plugin-react-hooks (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (experimental, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 0) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 1) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 10) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 11) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 12) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 13) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 14) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 15) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 16) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 17) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 18) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 19) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 2) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 20) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 21) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 22) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 23) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 24) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 3) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 4) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 5) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 6) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 7) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 8) (push) Has been cancelled
(Runtime) Build and Test / yarn build and lint (stable, 9) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (1/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (10/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (2/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (3/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (4/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (5/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (6/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (7/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (8/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, --project=devtools -r=experimental) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=experimental --env=production) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=development) (push) Has been cancelled
(Runtime) Build and Test / yarn test-build (9/10, -r=stable --env=production) (push) Has been cancelled
(Runtime) Build and Test / Process artifacts combined (push) Has been cancelled
(Runtime) Build and Test / Search build artifacts for unminified errors (push) Has been cancelled
(Runtime) Build and Test / Check release dependencies (push) Has been cancelled
(Runtime) Build and Test / Check fixtures DOM (stable) (push) Has been cancelled
(Runtime) Build and Test / Run fixtures Flight tests (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (chrome) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (edge) (push) Has been cancelled
(Runtime) Build and Test / Build DevTools and process artifacts (firefox) (push) Has been cancelled
(Runtime) Build and Test / Merge DevTools artifacts (push) Has been cancelled
(Runtime) Build and Test / Run DevTools e2e tests (push) Has been cancelled
(Runtime) Build and Test / Run sizebot (push) Has been cancelled
2025-12-11 19:03:44 +01:00
Sebastian Markbåge
6568bd00f9 Patch Promise cycles and toString on Server Functions
[Flight] Move `react-server-dom-webpack/*.unbundled` to private `react-server-dom-unbundled` (#35290)

Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>
2025-12-11 19:03:44 +01:00
Sebastian "Sebbie" Silbermann
7adca9e3b9 Run CI for backport releases (#35313) 2025-12-08 16:09:26 +01:00
Sebastian Sebbie Silbermann
ede3840137 Version 19.1.2 2025-12-03 15:33:20 +01:00
Sebastian Markbage
0e2ae74309 Bring ReactFlightClient fixes to FlightReplyServer
We did a bunch of refactors to ReactFlightClient in PRs like #29823 and #33664.

This brings a bunch of those related refactors to the equivalent FlightReplyServer. Such as deep resolution of cycles and deferred error handling.
2025-12-03 15:32:26 +01:00
Sebastian "Sebbie" Silbermann
6e79ecf60b [release] Allow building single release channel with processed versions (#35270) 2025-12-03 01:38:04 +01:00
Jack Pope
02ef495809 Reset packages we are not releasing to currently published versions 2025-07-24 16:35:10 -04:00
Riccardo Cipolleschi
3f178f55fc [Release] Update build script to properly set React Native's renderers version (#33972) 2025-07-24 16:49:56 +01:00
Jack Pope
87e33ca2b7 Set release versions to 19.1.1 2025-07-16 13:05:36 -04:00
lauren
52cf381c72 [eprh] Bump stable version (#32978)
https://www.npmjs.com/package/eslint-plugin-react-hooks/v/6.0.0 was just
released, so we can bump this now.
2025-07-16 12:55:41 -04:00
lauren
b793948e15 Bump next prerelease version numbers (#32782)
Updates the version numbers in the prerelease channels.
2025-07-16 12:55:24 -04:00
Jack Pope
73e4ba42cd Allow runtime_build_and_test action to trigger manually (#33796) 2025-07-16 12:52:44 -04:00
Ruslan Lesiutin
5a1eb6f61a fix: rename bottom stack frame (#33680)
`react-stack-bottom-frame` -> `react_stack_bottom_frame`.

This survives `@babel/plugin-transform-function-name`, but now frames
will be displayed as `at Object.react_stack_bottom_frame (...)` in V8.
Checks that were relying on exact function name match were updated to
use either `.indexOf()` or `.includes()`

For backwards compatibility, both React DevTools and Flight Client will
look for both options. I am not so sure about the latter and if React
version is locked.
2025-07-16 11:53:56 -04:00
Sebastian Markbåge
01eae200bf [DevTools] Get source location from structured callsites in prepareStackTrace (#33143)
When we get the source location for "View source for this element" we
should be using the enclosing function of the callsite of the child. So
that we don't just point to some random line within the component.

This is similar to the technique in #33136.

This technique is now really better than the fake throw technique, when
available. So I now favor the owner technique. The only problem it's
only available in DEV and only if it has a child that's owned (and not
filtered).

We could implement this same technique for the error that's thrown in
the fake throwing solution. However, we really shouldn't need that at
all because for client components we should be able to call
`inspect(fn)` at least in Chrome which is even better.
2025-07-16 11:11:51 -04:00
Timothy Yung
0e6781a06b Enable the enableEagerAlternateStateNodeCleanup Feature Flag (#33447)
Enables the `enableEagerAlternateStateNodeCleanup` feature flag for all
variants, while maintaining the `__VARIANT__` for the internal React
Native flavor for backtesting reasons.

```
$ yarn test
```
2025-07-15 15:29:02 -04:00
Samuel Susla
2cd3c424ea Add eager alternate.stateNode cleanup (#33161)
This is a fix for a problem where React retains shadow nodes longer than
it needs to. The behaviour is shown in React Native test:
https://github.com/facebook/react-native/blob/main/packages/react-native/src/private/__tests__/utilities/__tests__/ShadowNodeReferenceCounter-itest.js#L169

When React commits a new shadow tree, old shadow nodes are stored inside
`fiber.alternate.stateNode`. This is not cleared up until React clones
the node again. This may be problematic if mutation deletes a subtree,
in that case `fiber.alternate.stateNode` will retain entire subtree
until next update. In case of image nodes, this means retaining entire
images.

So when React goes from revision A: `<View><View /></View>` to revision
B: `<View />`, `fiber.alternate.stateNode` will be pointing to Shadow
Node that represents revision A..

![image](https://github.com/user-attachments/assets/076b677e-d152-4763-8c9d-4f923212b424)

To fix this, this PR adds a new feature flag
`enableEagerAlternateStateNodeCleanup`. When enabled,
`alternate.stateNode` is proactively pointed towards finishedWork's
stateNode, releasing resources sooner.

I have verified this fixes the issue [demonstrated by React Native
tests](https://github.com/facebook/react-native/blob/main/packages/react-native/src/private/__tests__/utilities/__tests__/ShadowNodeReferenceCounter-itest.js#L169).
All existing React tests pass when the flag is enabled.
2025-07-15 15:24:50 -04:00
Jack Pope
a24654e65b Ship enableFabricCompleteRootInCommitPhase (#33064)
This was shipped internally. Cleaning up the flag.
2025-07-15 15:16:15 -04:00
99 changed files with 3619 additions and 609 deletions

View File

@@ -331,6 +331,7 @@ module.exports = {
'packages/react-server-dom-turbopack/**/*.js',
'packages/react-server-dom-parcel/**/*.js',
'packages/react-server-dom-fb/**/*.js',
'packages/react-server-dom-unbundled/**/*.js',
'packages/react-test-renderer/**/*.js',
'packages/react-debug-tools/**/*.js',
'packages/react-devtools-extensions/**/*.js',

View File

@@ -3,9 +3,19 @@ name: (Runtime) Build and Test
on:
push:
branches: [main]
tags:
# To get CI for backport releases.
# This will duplicate CI for releases from main which is acceptable
- "v*"
pull_request:
paths-ignore:
- compiler/**
workflow_dispatch:
inputs:
commit_sha:
required: false
type: string
default: ''
permissions: {}
@@ -28,14 +38,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- name: Check cache hit
uses: actions/cache/restore@v4
id: node_modules
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
lookup-only: true
- uses: actions/setup-node@v4
if: steps.node_modules.outputs.cache-hit != 'true'
@@ -49,10 +59,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Save cache
@@ -61,7 +69,7 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
runtime_compiler_node_modules_cache:
name: Cache Runtime, Compiler node_modules
@@ -69,14 +77,14 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- name: Check cache hit
uses: actions/cache/restore@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') }}
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
lookup-only: true
- uses: actions/setup-node@v4
if: steps.node_modules.outputs.cache-hit != 'true'
@@ -92,10 +100,8 @@ jobs:
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-
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- run: yarn --cwd compiler install --frozen-lockfile
@@ -106,7 +112,7 @@ jobs:
with:
path: |
**/node_modules
key: runtime-and-compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# ----- FLOW -----
discover_flow_inline_configs:
@@ -117,7 +123,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/github-script@v7
id: set-matrix
with:
@@ -136,7 +142,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -148,10 +154,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -166,7 +170,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -178,10 +182,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -198,7 +200,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -210,7 +212,7 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -254,7 +256,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -268,10 +270,8 @@ jobs:
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-
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -280,6 +280,37 @@ 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-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
- name: Install runtime dependencies
run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- name: Install compiler dependencies
run: yarn install --frozen-lockfile
working-directory: compiler
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
@@ -294,7 +325,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -312,10 +343,8 @@ jobs:
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-
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -389,7 +418,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -403,10 +432,8 @@ jobs:
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-
key: runtime-and-compiler-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock', 'compiler/yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -430,7 +457,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -442,10 +469,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -458,7 +483,7 @@ jobs:
merge-multiple: true
- name: Display structure of build
run: ls -R build
- run: echo ${{ github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
- run: echo ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
- name: Scrape warning messages
run: |
mkdir -p ./build/__test_utils__
@@ -483,7 +508,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -495,10 +520,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -523,7 +546,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -535,10 +558,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -560,7 +581,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -601,7 +622,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -675,7 +696,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -687,10 +708,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -732,7 +751,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -744,10 +763,8 @@ jobs:
with:
path: |
**/node_modules
key: runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
restore-keys: |
runtime-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-
runtime-node_modules-v6-
key: runtime-node_modules-v7-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
# Don't use restore-keys here. Otherwise the cache grows indefinitely.
- name: Ensure clean build directory
run: rm -rf build
- run: yarn install --frozen-lockfile
@@ -777,7 +794,7 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
ref: ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }}
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
@@ -822,7 +839,7 @@ jobs:
node ./scripts/print-warnings/print-warnings.js > build/__test_utils__/ReactAllWarnings.js
- name: Display structure of build for PR
run: ls -R build
- run: echo ${{ github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
- run: echo ${{ github.event.inputs.commit_sha != '' && github.event.inputs.commit_sha || github.event.pull_request.head.sha || github.sha }} >> build/COMMIT_SHA
- run: node ./scripts/tasks/danger
- name: Archive sizebot results
uses: actions/upload-artifact@v4

View File

@@ -7,18 +7,18 @@
//
// The @latest channel uses the version as-is, e.g.:
//
// 19.1.0
// 19.1.4
//
// The @canary channel appends additional information, with the scheme
// <version>-<label>-<commit_sha>, e.g.:
//
// 19.1.0-canary-a1c2d3e4
// 19.1.4-canary-a1c2d3e4
//
// The @experimental channel doesn't include a version, only a date and a sha, e.g.:
//
// 0.0.0-experimental-241c4467e-20200129
const ReactVersion = '19.1.0';
const ReactVersion = '19.1.4';
// The label used by the @canary channel. Represents the upcoming release's
// stability. Most of the time, this will be "canary", but we may temporarily
@@ -34,7 +34,7 @@ const rcNumber = 0;
const stablePackages = {
'eslint-plugin-react-hooks': '5.2.0',
'jest-react': '0.17.0',
'jest-react': '0.16.0',
react: ReactVersion,
'react-art': ReactVersion,
'react-dom': ReactVersion,

View File

@@ -3,7 +3,7 @@ import {
load as reactLoad,
getSource as getSourceImpl,
transformSource as reactTransformSource,
} from 'react-server-dom-webpack/node-loader';
} from 'react-server-dom-unbundled/node-loader';
export {resolve};

View File

@@ -36,7 +36,7 @@ const http = require('http');
const React = require('react');
const {renderToPipeableStream} = require('react-dom/server');
const {createFromNodeStream} = require('react-server-dom-webpack/client');
const {createFromNodeStream} = require('react-server-dom-unbundled/client');
const {PassThrough} = require('stream');
const app = express();

View File

@@ -5,7 +5,8 @@
const path = require('path');
const url = require('url');
const register = require('react-server-dom-webpack/node-register');
const register = require('react-server-dom-unbundled/node-register');
// TODO: This seems to have no effect anymore. Remove?
register();
const babelRegister = require('@babel/register');
@@ -52,7 +53,7 @@ const React = require('react');
async function renderApp(res, returnValue, formState) {
const {renderToPipeableStream} = await import(
'react-server-dom-webpack/server'
'react-server-dom-unbundled/server'
);
// const m = require('../src/App.js');
const m = await import('../src/App.js');
@@ -107,7 +108,7 @@ async function renderApp(res, returnValue, formState) {
async function prerenderApp(res, returnValue, formState) {
const {unstable_prerenderToNodeStream: prerenderToNodeStream} = await import(
'react-server-dom-webpack/static'
'react-server-dom-unbundled/static'
);
// const m = require('../src/App.js');
const m = await import('../src/App.js');
@@ -170,7 +171,7 @@ app.get('/', async function (req, res) {
app.post('/', bodyParser.text(), async function (req, res) {
const {decodeReply, decodeReplyFromBusboy, decodeAction, decodeFormState} =
await import('react-server-dom-webpack/server');
await import('react-server-dom-unbundled/server');
const serverReference = req.get('rsc-action');
if (serverReference) {
// This is the client-side case

View File

@@ -120,10 +120,10 @@
"scripts": {
"prebuild": "./scripts/react-compiler/link-compiler.sh",
"build": "node ./scripts/rollup/build-all-release-channels.js",
"build-for-devtools": "cross-env RELEASE_CHANNEL=experimental yarn build react/index,react/jsx,react/compiler-runtime,react-dom/index,react-dom/client,react-dom/unstable_testing,react-dom/test-utils,react-is,react-debug-tools,scheduler,react-test-renderer,react-refresh,react-art --type=NODE",
"build-for-devtools": "cross-env yarn build react/index,react/jsx,react/compiler-runtime,react-dom/index,react-dom/client,react-dom/unstable_testing,react-dom/test-utils,react-is,react-debug-tools,scheduler,react-test-renderer,react-refresh,react-art --type=NODE --release-channel=experimental",
"build-for-devtools-dev": "yarn build-for-devtools --type=NODE_DEV",
"build-for-devtools-prod": "yarn build-for-devtools --type=NODE_PROD",
"build-for-flight-dev": "cross-env RELEASE_CHANNEL=experimental node ./scripts/rollup/build.js react/index,react/jsx,react.react-server,react-dom/index,react-dom/client,react-dom/server,react-dom.react-server,react-dom-server.node,react-dom-server-legacy.node,scheduler,react-server-dom-webpack/ --type=NODE_DEV,ESM_PROD,NODE_ES2015 && mv ./build/node_modules ./build/oss-experimental",
"build-for-flight-dev": "cross-env RELEASE_CHANNEL=experimental node ./scripts/rollup/build.js react/index,react/jsx,react.react-server,react-dom/index,react-dom/client,react-dom/server,react-dom.react-server,react-dom-server.node,react-dom-server-legacy.node,scheduler,react-server-dom-webpack/,react-server-dom-unbundled/ --type=NODE_DEV,ESM_PROD,NODE_ES2015 && mv ./build/node_modules ./build/oss-experimental",
"build-for-vt-dev": "cross-env RELEASE_CHANNEL=experimental node ./scripts/rollup/build.js react/index,react/jsx,react-dom/index,react-dom/client,react-dom/server,react-dom-server.node,react-dom-server-legacy.node,scheduler --type=NODE_DEV && mv ./build/node_modules ./build/oss-experimental",
"linc": "node ./scripts/tasks/linc.js",
"lint": "node ./scripts/tasks/eslint.js",

View File

@@ -20,8 +20,8 @@
"homepage": "https://react.dev/",
"peerDependencies": {
"jest": "^23.0.1 || ^24.0.0 || ^25.1.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0",
"react": "^19.0.0",
"react-test-renderer": "^19.0.0"
"react": "^19.1.4",
"react-test-renderer": "^19.1.4"
},
"files": [
"LICENSE",

View File

@@ -1,7 +1,7 @@
{
"name": "react-art",
"description": "React ART is a JavaScript library for drawing vector graphics using React. It provides declarative and reactive bindings to the ART library. Using the same declarative API you can render the output to either Canvas, SVG or VML (IE8).",
"version": "19.1.0",
"version": "19.1.4",
"main": "index.js",
"repository": {
"type": "git",
@@ -24,10 +24,10 @@
"dependencies": {
"art": "^0.10.1",
"create-react-class": "^15.6.2",
"scheduler": "^0.25.0"
"scheduler": "^0.26.0"
},
"peerDependencies": {
"react": "^19.0.0"
"react": "^19.1.4"
},
"files": [
"LICENSE",
@@ -38,4 +38,4 @@
"Rectangle.js",
"Wedge.js"
]
}
}

View File

@@ -555,6 +555,7 @@ function resolveModuleChunk<T>(
const resolvedChunk: ResolvedModuleChunk<T> = (chunk: any);
resolvedChunk.status = RESOLVED_MODULE;
resolvedChunk.value = value;
resolvedChunk.reason = null;
if (resolveListeners !== null) {
initializeModuleChunk(resolvedChunk);
wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
@@ -616,6 +617,7 @@ function initializeModelChunk<T>(chunk: ResolvedModelChunk<T>): void {
const initializedChunk: InitializedChunk<T> = (chunk: any);
initializedChunk.status = INITIALIZED;
initializedChunk.value = value;
initializedChunk.reason = null;
} catch (error) {
const erroredChunk: ErroredChunk<T> = (chunk: any);
erroredChunk.status = ERRORED;
@@ -634,6 +636,7 @@ function initializeModuleChunk<T>(chunk: ResolvedModuleChunk<T>): void {
const initializedChunk: InitializedChunk<T> = (chunk: any);
initializedChunk.status = INITIALIZED;
initializedChunk.value = value;
initializedChunk.reason = null;
} catch (error) {
const erroredChunk: ErroredChunk<T> = (chunk: any);
erroredChunk.status = ERRORED;
@@ -652,6 +655,8 @@ export function reportGlobalError(response: Response, error: Error): void {
// because we won't be getting any new data to resolve it.
if (chunk.status === PENDING) {
triggerErrorOnChunk(chunk, error);
} else if (chunk.status === INITIALIZED && chunk.reason !== null) {
chunk.reason.error(error);
}
});
if (enableProfilerTimer && enableComponentPerformanceTrack) {
@@ -1008,6 +1013,7 @@ function waitForReference<T>(
const initializedChunk: InitializedChunk<T> = (chunk: any);
initializedChunk.status = INITIALIZED;
initializedChunk.value = handler.value;
initializedChunk.reason = null;
if (resolveListeners !== null) {
wakeChunk(resolveListeners, handler.value);
}
@@ -1186,6 +1192,7 @@ function loadServerReference<A: Iterable<any>, T>(
const initializedChunk: InitializedChunk<T> = (chunk: any);
initializedChunk.status = INITIALIZED;
initializedChunk.value = handler.value;
initializedChunk.reason = null;
if (resolveListeners !== null) {
wakeChunk(resolveListeners, handler.value);
}
@@ -1443,7 +1450,7 @@ function parseModelString(
// Symbol
return Symbol.for(value.slice(2));
}
case 'F': {
case 'h': {
// Server Reference
const ref = value.slice(2);
return getOutlinedModel(
@@ -1854,6 +1861,7 @@ function startReadableStream<T>(
type: void | 'bytes',
): void {
let controller: ReadableStreamController = (null: any);
let closed = false;
const stream = new ReadableStream({
type: type,
start(c) {
@@ -1911,6 +1919,10 @@ function startReadableStream<T>(
}
},
close(json: UninitializedModel): void {
if (closed) {
return;
}
closed = true;
if (previousBlockedChunk === null) {
controller.close();
} else {
@@ -1921,6 +1933,10 @@ function startReadableStream<T>(
}
},
error(error: mixed): void {
if (closed) {
return;
}
closed = true;
if (previousBlockedChunk === null) {
// $FlowFixMe[incompatible-call]
controller.error(error);
@@ -1980,6 +1996,7 @@ function startAsyncIterable<T>(
(chunk: any);
initializedChunk.status = INITIALIZED;
initializedChunk.value = {done: false, value: value};
initializedChunk.reason = null;
if (resolveListeners !== null) {
wakeChunkIfInitialized(chunk, resolveListeners, rejectListeners);
}
@@ -1999,6 +2016,9 @@ function startAsyncIterable<T>(
nextWriteIndex++;
},
close(value: UninitializedModel): void {
if (closed) {
return;
}
closed = true;
if (nextWriteIndex === buffer.length) {
buffer[nextWriteIndex] = createResolvedIteratorResultChunk(
@@ -2020,6 +2040,9 @@ function startAsyncIterable<T>(
}
},
error(error: Error): void {
if (closed) {
return;
}
closed = true;
if (nextWriteIndex === buffer.length) {
buffer[nextWriteIndex] =
@@ -2438,7 +2461,7 @@ function buildFakeTask(
}
const createFakeJSXCallStack = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
response: Response,
stack: ReactStackTrace,
environmentName: string,
@@ -2459,7 +2482,7 @@ const createFakeJSXCallStackInDEV: (
environmentName: string,
) => Error = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(createFakeJSXCallStack['react-stack-bottom-frame'].bind(
(createFakeJSXCallStack.react_stack_bottom_frame.bind(
createFakeJSXCallStack,
): any)
: (null: any);
@@ -2563,7 +2586,7 @@ function getCurrentStackInDEV(): string {
}
const replayConsoleWithCallStack = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
response: Response,
methodName: string,
stackTrace: ReactStackTrace,
@@ -2614,7 +2637,7 @@ const replayConsoleWithCallStackInDEV: (
args: Array<mixed>,
) => void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(replayConsoleWithCallStack['react-stack-bottom-frame'].bind(
(replayConsoleWithCallStack.react_stack_bottom_frame.bind(
replayConsoleWithCallStack,
): any)
: (null: any);

View File

@@ -107,7 +107,7 @@ function serializePromiseID(id: number): string {
}
function serializeServerReferenceID(id: number): string {
return '$F' + id.toString(16);
return '$h' + id.toString(16);
}
function serializeTemporaryReferenceMarker(): string {
@@ -115,7 +115,6 @@ function serializeTemporaryReferenceMarker(): string {
}
function serializeFormDataReference(id: number): string {
// Why K? F is "Function". D is "Date". What else?
return '$K' + id.toString(16);
}
@@ -477,8 +476,22 @@ export function processReply(
}
}
const existingReference = writtenObjects.get(value);
// $FlowFixMe[method-unbinding]
if (typeof value.then === 'function') {
if (existingReference !== undefined) {
if (modelRoot === value) {
// This is the ID we're currently emitting so we need to write it
// once but if we discover it again, we refer to it by id.
modelRoot = null;
} else {
// We've already emitted this as an outlined object, so we can
// just refer to that by its existing ID.
return existingReference;
}
}
// We assume that any object with a .then property is a "Thenable" type,
// or a Promise type. Either of which can be represented by a Promise.
if (formData === null) {
@@ -487,11 +500,19 @@ export function processReply(
}
pendingParts++;
const promiseId = nextPartId++;
const promiseReference = serializePromiseID(promiseId);
writtenObjects.set(value, promiseReference);
const thenable: Thenable<any> = (value: any);
thenable.then(
partValue => {
try {
const partJSON = serializeModel(partValue, promiseId);
const previousReference = writtenObjects.get(partValue);
let partJSON;
if (previousReference !== undefined) {
partJSON = JSON.stringify(previousReference);
} else {
partJSON = serializeModel(partValue, promiseId);
}
// $FlowFixMe[incompatible-type] We know it's not null because we assigned it above.
const data: FormData = formData;
data.append(formFieldPrefix + promiseId, partJSON);
@@ -507,10 +528,9 @@ export function processReply(
// that throws on the server instead.
reject,
);
return serializePromiseID(promiseId);
return promiseReference;
}
const existingReference = writtenObjects.get(value);
if (existingReference !== undefined) {
if (modelRoot === value) {
// This is the ID we're currently emitting so we need to write it

View File

@@ -6,13 +6,13 @@
*
* @flow
*/
export {default as rendererVersion} from 'shared/ReactVersion';
export const rendererPackageName = 'react-server-dom-webpack';
export const rendererPackageName = 'react-server-dom-unbundled';
export * from 'react-client/src/ReactFlightClientStreamConfigNode';
export * from 'react-client/src/ReactClientConsoleConfigServer';
export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack';
export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer';
export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigTargetWebpackServer';
export * from 'react-server-dom-unbundled/src/client/ReactFlightClientConfigBundlerNode';
export * from 'react-server-dom-unbundled/src/client/ReactFlightClientConfigTargetNodeServer';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;

View File

@@ -6,13 +6,13 @@
*
* @flow
*/
export {default as rendererVersion} from 'shared/ReactVersion';
export const rendererPackageName = 'react-server-dom-webpack';
export * from 'react-client/src/ReactFlightClientStreamConfigNode';
export * from 'react-client/src/ReactClientConsoleConfigServer';
export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerNode';
export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack';
export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer';
export * from 'react-server-dom-webpack/src/client/ReactFlightClientConfigTargetWebpackServer';
export * from 'react-dom-bindings/src/shared/ReactFlightClientConfigDOM';
export const usedWithSSR = true;

View File

@@ -50,6 +50,7 @@ import {
gt,
gte,
parseSourceFromComponentStack,
parseSourceFromOwnerStack,
serializeToString,
} from 'react-devtools-shared/src/backend/utils';
import {
@@ -5758,15 +5759,13 @@ export function attach(
function getSourceForFiberInstance(
fiberInstance: FiberInstance,
): Source | null {
const unresolvedSource = fiberInstance.source;
if (
unresolvedSource !== null &&
typeof unresolvedSource === 'object' &&
!isError(unresolvedSource)
) {
// $FlowFixMe: isError should have refined it.
return unresolvedSource;
// Favor the owner source if we have one.
const ownerSource = getSourceForInstance(fiberInstance);
if (ownerSource !== null) {
return ownerSource;
}
// Otherwise fallback to the throwing trick.
const dispatcherRef = getDispatcherRef(renderer);
const stackFrame =
dispatcherRef == null
@@ -5777,10 +5776,7 @@ export function attach(
dispatcherRef,
);
if (stackFrame === null) {
// If we don't find a source location by throwing, try to get one
// from an owned child if possible. This is the same branch as
// for virtual instances.
return getSourceForInstance(fiberInstance);
return null;
}
const source = parseSourceFromComponentStack(stackFrame);
fiberInstance.source = source;
@@ -5788,7 +5784,7 @@ export function attach(
}
function getSourceForInstance(instance: DevToolsInstance): Source | null {
let unresolvedSource = instance.source;
const unresolvedSource = instance.source;
if (unresolvedSource === null) {
// We don't have any source yet. We can try again later in case an owned child mounts later.
// TODO: We won't have any information here if the child is filtered.
@@ -5801,7 +5797,9 @@ export function attach(
// any intermediate utility functions. This won't point to the top of the component function
// but it's at least somewhere within it.
if (isError(unresolvedSource)) {
unresolvedSource = formatOwnerStack((unresolvedSource: any));
return (instance.source = parseSourceFromOwnerStack(
(unresolvedSource: any),
));
}
if (typeof unresolvedSource === 'string') {
const idx = unresolvedSource.lastIndexOf('\n');

View File

@@ -13,8 +13,12 @@ export function formatOwnerStack(error: Error): string {
const prevPrepareStackTrace = Error.prepareStackTrace;
// $FlowFixMe[incompatible-type] It does accept undefined.
Error.prepareStackTrace = undefined;
let stack = error.stack;
const stack = error.stack;
Error.prepareStackTrace = prevPrepareStackTrace;
return formatOwnerStackString(stack);
}
export function formatOwnerStackString(stack: string): string {
if (stack.startsWith('Error: react-stack-top-frame\n')) {
// V8's default formatting prefixes with the error message which we
// don't want/need.
@@ -25,7 +29,10 @@ export function formatOwnerStack(error: Error): string {
// Pop the JSX frame.
stack = stack.slice(idx + 1);
}
idx = stack.indexOf('react-stack-bottom-frame');
idx = stack.indexOf('react_stack_bottom_frame');
if (idx === -1) {
idx = stack.indexOf('react-stack-bottom-frame');
}
if (idx !== -1) {
idx = stack.lastIndexOf('\n', idx);
}

View File

@@ -18,6 +18,8 @@ import type {DehydratedData} from 'react-devtools-shared/src/frontend/types';
export {default as formatWithStyles} from './formatWithStyles';
export {default as formatConsoleArguments} from './formatConsoleArguments';
import {formatOwnerStackString} from '../shared/DevToolsOwnerStack';
// TODO: update this to the first React version that has a corresponding DevTools backend
const FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER = '999.9.9';
export function hasAssignedBackend(version?: string): boolean {
@@ -345,6 +347,81 @@ export function parseSourceFromComponentStack(
return parseSourceFromFirefoxStack(componentStack);
}
let collectedLocation: Source | null = null;
function collectStackTrace(
error: Error,
structuredStackTrace: CallSite[],
): string {
let result: null | Source = null;
// Collect structured stack traces from the callsites.
// We mirror how V8 serializes stack frames and how we later parse them.
for (let i = 0; i < structuredStackTrace.length; i++) {
const callSite = structuredStackTrace[i];
const name = callSite.getFunctionName();
if (
name.includes('react_stack_bottom_frame') ||
name.includes('react-stack-bottom-frame')
) {
// We pick the last frame that matches before the bottom frame since
// that will be immediately inside the component as opposed to some helper.
// If we don't find a bottom frame then we bail to string parsing.
collectedLocation = result;
// Skip everything after the bottom frame since it'll be internals.
break;
} else {
const sourceURL = callSite.getScriptNameOrSourceURL();
const line =
// $FlowFixMe[prop-missing]
typeof callSite.getEnclosingLineNumber === 'function'
? (callSite: any).getEnclosingLineNumber()
: callSite.getLineNumber();
const col =
// $FlowFixMe[prop-missing]
typeof callSite.getEnclosingColumnNumber === 'function'
? (callSite: any).getEnclosingColumnNumber()
: callSite.getLineNumber();
if (!sourceURL || !line || !col) {
// Skip eval etc. without source url. They don't have location.
continue;
}
result = {
sourceURL,
line: line,
column: col,
};
}
}
// At the same time we generate a string stack trace just in case someone
// else reads it.
const name = error.name || 'Error';
const message = error.message || '';
let stack = name + ': ' + message;
for (let i = 0; i < structuredStackTrace.length; i++) {
stack += '\n at ' + structuredStackTrace[i].toString();
}
return stack;
}
export function parseSourceFromOwnerStack(error: Error): Source | null {
// First attempt to collected the structured data using prepareStackTrace.
collectedLocation = null;
const previousPrepare = Error.prepareStackTrace;
Error.prepareStackTrace = collectStackTrace;
let stack;
try {
stack = error.stack;
} finally {
Error.prepareStackTrace = previousPrepare;
}
if (collectedLocation !== null) {
return collectedLocation;
}
// Fallback to parsing the string form.
const componentStack = formatOwnerStackString(stack);
return parseSourceFromComponentStack(componentStack);
}
// 0.123456789 => 0.123
// Expects high-resolution timestamp in milliseconds, like from performance.now()
// Mainly used for optimizing the size of serialized profiling payload

View File

@@ -1,7 +1,7 @@
{
"name": "react-dom-bindings",
"description": "React implementation details for react-dom.",
"version": "19.1.0",
"version": "19.1.4",
"private": true,
"main": "index.js",
"repository": {
@@ -18,6 +18,6 @@
},
"homepage": "https://react.dev/",
"peerDependencies": {
"react": "^19.0.0"
"react": "^19.1.4"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "react-dom",
"version": "19.1.0",
"version": "19.1.4",
"description": "React package for working with the DOM.",
"main": "index.js",
"repository": {
@@ -17,10 +17,10 @@
},
"homepage": "https://react.dev/",
"dependencies": {
"scheduler": "^0.25.0"
"scheduler": "^0.26.0"
},
"peerDependencies": {
"react": "^19.0.0"
"react": "^19.1.4"
},
"files": [
"LICENSE",
@@ -123,4 +123,4 @@
"./server.js": "./server.browser.js",
"./static.js": "./static.browser.js"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "react-is",
"version": "19.1.0",
"version": "19.1.4",
"description": "Brand checking of React Elements.",
"main": "index.js",
"sideEffects": false,

View File

@@ -1,6 +1,6 @@
{
"name": "react-markup",
"version": "19.1.0",
"version": "19.1.4",
"description": "React package generating embedded markup such as e-mails with support for Server Components.",
"main": "index.js",
"repository": {
@@ -17,7 +17,7 @@
},
"homepage": "https://react.dev/",
"peerDependencies": {
"react": "^19.0.0"
"react": "^19.1.4"
},
"files": [
"LICENSE",

View File

@@ -8,9 +8,9 @@
"directory": "packages/react-native-renderer"
},
"dependencies": {
"scheduler": "^0.25.0"
"scheduler": "^0.26.0"
},
"peerDependencies": {
"react": "^18.0.0"
}
}
}

View File

@@ -58,7 +58,6 @@ import {
} from './ReactNativeFiberInspector';
import {
enableFabricCompleteRootInCommitPhase,
passChildrenWhenCloningPersistedNodes,
enableLazyPublicInstanceInFabric,
} from 'shared/ReactFeatureFlags';
@@ -534,19 +533,14 @@ export function finalizeContainerChildren(
container: Container,
newChildren: ChildSet,
): void {
if (!enableFabricCompleteRootInCommitPhase) {
completeRoot(container.containerTag, newChildren);
}
// Noop - children will be replaced in replaceContainerChildren
}
export function replaceContainerChildren(
container: Container,
newChildren: ChildSet,
): void {
// Noop - children will be replaced in finalizeContainerChildren
if (enableFabricCompleteRootInCommitPhase) {
completeRoot(container.containerTag, newChildren);
}
completeRoot(container.containerTag, newChildren);
}
export {getClosestInstanceFromNode as getInstanceFromNode};

View File

@@ -1,7 +1,7 @@
{
"name": "react-reconciler",
"description": "React package for creating custom renderers.",
"version": "0.32.0",
"version": "0.32.1",
"keywords": [
"react"
],
@@ -26,9 +26,9 @@
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^19.0.0"
"react": "^19.1.4"
},
"dependencies": {
"scheduler": "^0.25.0"
"scheduler": "^0.26.0"
}
}
}

View File

@@ -24,7 +24,7 @@ import {enableUseEffectCRUDOverload} from 'shared/ReactFeatureFlags';
// TODO: Consider marking the whole bundle instead of these boundaries.
const callComponent = {
'react-stack-bottom-frame': function <Props, Arg, R>(
react_stack_bottom_frame: function <Props, Arg, R>(
Component: (p: Props, arg: Arg) => R,
props: Props,
secondArg: Arg,
@@ -46,7 +46,7 @@ export const callComponentInDEV: <Props, Arg, R>(
secondArg: Arg,
) => R = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callComponent['react-stack-bottom-frame'].bind(callComponent): any)
(callComponent.react_stack_bottom_frame.bind(callComponent): any)
: (null: any);
interface ClassInstance<R> {
@@ -62,7 +62,7 @@ interface ClassInstance<R> {
}
const callRender = {
'react-stack-bottom-frame': function <R>(instance: ClassInstance<R>): R {
react_stack_bottom_frame: function <R>(instance: ClassInstance<R>): R {
const wasRendering = isRendering;
setIsRendering(true);
try {
@@ -77,11 +77,11 @@ const callRender = {
export const callRenderInDEV: <R>(instance: ClassInstance<R>) => R => R =
__DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callRender['react-stack-bottom-frame'].bind(callRender): any)
(callRender.react_stack_bottom_frame.bind(callRender): any)
: (null: any);
const callComponentDidMount = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
finishedWork: Fiber,
instance: ClassInstance<any>,
): void {
@@ -98,13 +98,13 @@ export const callComponentDidMountInDEV: (
instance: ClassInstance<any>,
) => void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callComponentDidMount['react-stack-bottom-frame'].bind(
(callComponentDidMount.react_stack_bottom_frame.bind(
callComponentDidMount,
): any)
: (null: any);
const callComponentDidUpdate = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
finishedWork: Fiber,
instance: ClassInstance<any>,
prevProps: Object,
@@ -127,13 +127,13 @@ export const callComponentDidUpdateInDEV: (
snaphot: Object,
) => void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callComponentDidUpdate['react-stack-bottom-frame'].bind(
(callComponentDidUpdate.react_stack_bottom_frame.bind(
callComponentDidUpdate,
): any)
: (null: any);
const callComponentDidCatch = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
instance: ClassInstance<any>,
errorInfo: CapturedValue<mixed>,
): void {
@@ -150,13 +150,13 @@ export const callComponentDidCatchInDEV: (
errorInfo: CapturedValue<mixed>,
) => void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callComponentDidCatch['react-stack-bottom-frame'].bind(
(callComponentDidCatch.react_stack_bottom_frame.bind(
callComponentDidCatch,
): any)
: (null: any);
const callComponentWillUnmount = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
current: Fiber,
nearestMountedAncestor: Fiber | null,
instance: ClassInstance<any>,
@@ -175,13 +175,13 @@ export const callComponentWillUnmountInDEV: (
instance: ClassInstance<any>,
) => void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callComponentWillUnmount['react-stack-bottom-frame'].bind(
(callComponentWillUnmount.react_stack_bottom_frame.bind(
callComponentWillUnmount,
): any)
: (null: any);
const callCreate = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
effect: Effect,
): (() => void) | {...} | void | null {
if (!enableUseEffectCRUDOverload) {
@@ -234,11 +234,11 @@ const callCreate = {
export const callCreateInDEV: (effect: Effect) => (() => void) | void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callCreate['react-stack-bottom-frame'].bind(callCreate): any)
(callCreate.react_stack_bottom_frame.bind(callCreate): any)
: (null: any);
const callDestroy = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
current: Fiber,
nearestMountedAncestor: Fiber | null,
destroy: () => void,
@@ -257,11 +257,11 @@ export const callDestroyInDEV: (
destroy: (() => void) | (({...}) => void),
) => void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callDestroy['react-stack-bottom-frame'].bind(callDestroy): any)
(callDestroy.react_stack_bottom_frame.bind(callDestroy): any)
: (null: any);
const callLazyInit = {
'react-stack-bottom-frame': function (lazy: LazyComponent<any, any>): any {
react_stack_bottom_frame: function (lazy: LazyComponent<any, any>): any {
const payload = lazy._payload;
const init = lazy._init;
return init(payload);
@@ -270,5 +270,5 @@ const callLazyInit = {
export const callLazyInitInDEV: (lazy: LazyComponent<any, any>) => any = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callLazyInit['react-stack-bottom-frame'].bind(callLazyInit): any)
(callLazyInit.react_stack_bottom_frame.bind(callLazyInit): any)
: (null: any);

View File

@@ -57,6 +57,7 @@ import {
enableComponentPerformanceTrack,
enableViewTransition,
enableFragmentRefs,
enableEagerAlternateStateNodeCleanup,
} from 'shared/ReactFeatureFlags';
import {
FunctionComponent,
@@ -1947,6 +1948,20 @@ function commitMutationEffectsOnFiber(
}
}
}
} else {
if (enableEagerAlternateStateNodeCleanup) {
if (supportsPersistence) {
if (finishedWork.alternate !== null) {
// `finishedWork.alternate.stateNode` is pointing to a stale shadow
// node at this point, retaining it and its subtree. To reclaim
// memory, point `alternate.stateNode` to new shadow node. This
// prevents shadow node from staying in memory longer than it
// needs to. The correct behaviour of this is checked by test in
// React Native: ShadowNodeReferenceCounter-itest.js#L150
finishedWork.alternate.stateNode = finishedWork.stateNode;
}
}
}
}
break;
}

View File

@@ -1,7 +1,7 @@
{
"name": "react-server-dom-esm",
"description": "React Server Components bindings for DOM using ESM. This is intended to be integrated into meta-frameworks. It is not intended to be imported directly.",
"version": "19.1.0",
"version": "19.1.4",
"keywords": [
"react"
],
@@ -46,16 +46,16 @@
},
"main": "index.js",
"repository": {
"type" : "git",
"url" : "https://github.com/facebook/react.git",
"type": "git",
"url": "https://github.com/facebook/react.git",
"directory": "packages/react-server-dom-esm"
},
"engines": {
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react": "^19.1.4",
"react-dom": "^19.1.4"
},
"dependencies": {
"acorn-loose": "^8.3.0",

View File

@@ -88,6 +88,12 @@ function bind(this: ServerReference<any>): any {
return newFn;
}
const serverReferenceToString = {
value: () => 'function () { [omitted code] }',
configurable: true,
writable: true,
};
export function registerServerReference<T: Function>(
reference: T,
id: string,
@@ -111,12 +117,14 @@ export function registerServerReference<T: Function>(
configurable: true,
},
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
}
: {
$$typeof,
$$id,
$$bound,
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
},
);
}

View File

@@ -222,16 +222,23 @@ function decodeReplyFromBusboy<T>(
// we queue any fields we receive until the previous file is done.
queuedFields.push(name, value);
} else {
resolveField(response, name, value);
try {
resolveField(response, name, value);
} catch (error) {
busboyStream.destroy(error);
}
}
});
busboyStream.on('file', (name, value, {filename, encoding, mimeType}) => {
if (encoding.toLowerCase() === 'base64') {
throw new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
busboyStream.destroy(
new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
),
);
return;
}
pendingFiles++;
const file = resolveFileInfo(response, name, filename, mimeType);
@@ -239,14 +246,18 @@ function decodeReplyFromBusboy<T>(
resolveFileChunk(response, file, chunk);
});
value.on('end', () => {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
try {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
}
queuedFields.length = 0;
}
queuedFields.length = 0;
} catch (error) {
busboyStream.destroy(error);
}
});
});

View File

@@ -8,10 +8,10 @@
"directory": "packages/react-server-dom-fb"
},
"dependencies": {
"scheduler": "^0.25.0"
"scheduler": "^0.26.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "react-server-dom-parcel",
"description": "React Server Components bindings for DOM using Parcel. This is intended to be integrated into meta-frameworks. It is not intended to be imported directly.",
"version": "19.0.0",
"version": "19.1.4",
"keywords": [
"react"
],
@@ -71,15 +71,15 @@
},
"main": "index.js",
"repository": {
"type" : "git",
"url" : "https://github.com/facebook/react.git",
"type": "git",
"url": "https://github.com/facebook/react.git",
"directory": "packages/react-server-dom-parcel"
},
"engines": {
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react": "^19.1.4",
"react-dom": "^19.1.4"
}
}

View File

@@ -95,6 +95,12 @@ function bind(this: ServerReference<any>): any {
return newFn;
}
const serverReferenceToString = {
value: () => 'function () { [omitted code] }',
configurable: true,
writable: true,
};
export function registerServerReference<T>(
reference: ServerReference<T>,
id: string,
@@ -118,12 +124,14 @@ export function registerServerReference<T>(
configurable: true,
},
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
}
: {
$$typeof,
$$id,
$$bound,
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
},
);
}

View File

@@ -19,6 +19,8 @@ import {
} from '../shared/ReactFlightImportMetadata';
import {prepareDestinationWithChunks} from 'react-client/src/ReactFlightClientConfig';
import hasOwnProperty from 'shared/hasOwnProperty';
export type ServerManifest = {
[string]: Array<string>,
};
@@ -78,5 +80,8 @@ export function preloadModule<T>(
export function requireModule<T>(metadata: ClientReference<T>): T {
const moduleExports = parcelRequire(metadata[ID]);
return moduleExports[metadata[NAME]];
if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
return moduleExports[metadata[NAME]];
}
return (undefined: any);
}

View File

@@ -231,16 +231,23 @@ export function decodeReplyFromBusboy<T>(
// we queue any fields we receive until the previous file is done.
queuedFields.push(name, value);
} else {
resolveField(response, name, value);
try {
resolveField(response, name, value);
} catch (error) {
busboyStream.destroy(error);
}
}
});
busboyStream.on('file', (name, value, {filename, encoding, mimeType}) => {
if (encoding.toLowerCase() === 'base64') {
throw new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
busboyStream.destroy(
new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
),
);
return;
}
pendingFiles++;
const file = resolveFileInfo(response, name, filename, mimeType);
@@ -248,14 +255,18 @@ export function decodeReplyFromBusboy<T>(
resolveFileChunk(response, file, chunk);
});
value.on('end', () => {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
try {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
}
queuedFields.length = 0;
}
queuedFields.length = 0;
} catch (error) {
busboyStream.destroy(error);
}
});
});

View File

@@ -1,7 +1,7 @@
{
"name": "react-server-dom-turbopack",
"description": "React Server Components bindings for DOM using Turbopack. This is intended to be integrated into meta-frameworks. It is not intended to be imported directly.",
"version": "19.1.0",
"version": "19.1.4",
"keywords": [
"react"
],
@@ -79,8 +79,8 @@
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react": "^19.1.4",
"react-dom": "^19.1.4"
},
"dependencies": {
"acorn-loose": "^8.3.0",

View File

@@ -102,6 +102,12 @@ function bind(this: ServerReference<any>): any {
return newFn;
}
const serverReferenceToString = {
value: () => 'function () { [omitted code] }',
configurable: true,
writable: true,
};
export function registerServerReference<T: Function>(
reference: T,
id: string,
@@ -125,12 +131,14 @@ export function registerServerReference<T: Function>(
configurable: true,
},
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
}
: {
$$typeof,
$$id,
$$bound,
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
},
);
}

View File

@@ -30,6 +30,8 @@ import {prepareDestinationWithChunks} from 'react-client/src/ReactFlightClientCo
import {loadChunk} from 'react-client/src/ReactFlightClientConfig';
import hasOwnProperty from 'shared/hasOwnProperty';
export type ServerConsumerModuleMap = null | {
[clientId: string]: {
[clientExportName: string]: ClientReferenceManifestEntry,
@@ -228,5 +230,8 @@ export function requireModule<T>(metadata: ClientReference<T>): T {
// default property of this if it was an ESM interop module.
return moduleExports.__esModule ? moduleExports.default : moduleExports;
}
return moduleExports[metadata[NAME]];
if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
return moduleExports[metadata[NAME]];
}
return (undefined: any);
}

View File

@@ -224,16 +224,23 @@ function decodeReplyFromBusboy<T>(
// we queue any fields we receive until the previous file is done.
queuedFields.push(name, value);
} else {
resolveField(response, name, value);
try {
resolveField(response, name, value);
} catch (error) {
busboyStream.destroy(error);
}
}
});
busboyStream.on('file', (name, value, {filename, encoding, mimeType}) => {
if (encoding.toLowerCase() === 'base64') {
throw new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
busboyStream.destroy(
new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
),
);
return;
}
pendingFiles++;
const file = resolveFileInfo(response, name, filename, mimeType);
@@ -241,14 +248,18 @@ function decodeReplyFromBusboy<T>(
resolveFileChunk(response, file, chunk);
});
value.on('end', () => {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
try {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
}
queuedFields.length = 0;
}
queuedFields.length = 0;
} catch (error) {
busboyStream.destroy(error);
}
});
});

View File

@@ -0,0 +1,5 @@
# react-server-dom-unbundled
Test-only React Flight bindings for DOM using Node.js.
This only exists for internal testing.

View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
export * from '../src/ReactFlightUnbundledNodeLoader.js';

View File

@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
throw new Error('Use react-server-dom-webpack/client instead.');

View File

@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
module.exports = require('./src/ReactFlightUnbundledNodeRegister');

View File

@@ -0,0 +1,7 @@
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react-server-dom-unbundled-client.production.js');
} else {
module.exports = require('./cjs/react-server-dom-unbundled-client.development.js');
}

View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@@ -0,0 +1,12 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
'use strict';
throw new Error('Use react-server-dom-unbundled/client instead.');

View File

@@ -0,0 +1,3 @@
'use strict';
module.exports = require('./cjs/react-server-dom-unbundled-node-register.js');

View File

@@ -0,0 +1,6 @@
'use strict';
throw new Error(
'The React Server Writer cannot be used outside a react-server environment. ' +
'You must configure Node.js using the `--conditions react-server` flag.'
);

View File

@@ -0,0 +1,20 @@
'use strict';
var s;
if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-unbundled-server.node.production.js');
} else {
s = require('./cjs/react-server-dom-unbundled-server.node.development.js');
}
exports.renderToReadableStream = s.renderToReadableStream;
exports.renderToPipeableStream = s.renderToPipeableStream;
exports.decodeReply = s.decodeReply;
exports.decodeReplyFromBusboy = s.decodeReplyFromBusboy;
exports.decodeReplyFromAsyncIterable = s.decodeReplyFromAsyncIterable;
exports.decodeAction = s.decodeAction;
exports.decodeFormState = s.decodeFormState;
exports.registerServerReference = s.registerServerReference;
exports.registerClientReference = s.registerClientReference;
exports.createClientModuleProxy = s.createClientModuleProxy;
exports.createTemporaryReferenceSet = s.createTemporaryReferenceSet;

View File

@@ -0,0 +1,6 @@
'use strict';
throw new Error(
'The React Server Writer cannot be used outside a react-server environment. ' +
'You must configure Node.js using the `--conditions react-server` flag.'
);

View File

@@ -0,0 +1,11 @@
'use strict';
var s;
if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-unbundled-server.node.production.js');
} else {
s = require('./cjs/react-server-dom-unbundled-server.node.development.js');
}
exports.prerender = s.prerender;
exports.prerenderToNodeStream = s.prerenderToNodeStream;

View File

@@ -0,0 +1,46 @@
{
"name": "react-server-dom-unbundled",
"description": "React Server Components bindings for DOM using Node.js. This only exists for internal testing.",
"version": "0.0.0",
"private": true,
"files": [
"LICENSE",
"README.md",
"index.js",
"client.js",
"server.js",
"server.node.js",
"static.js",
"static.node.js",
"node-register.js",
"cjs/",
"esm/"
],
"exports": {
".": "./index.js",
"./client": "./client.js",
"./server": {
"react-server": "./server.node.js",
"default": "./server.js"
},
"./server.node": "./server.node.js",
"./static": {
"react-server": "./static.node.js",
"default": "./static.js"
},
"./static.node": "./static.node.js",
"./node-loader": "./esm/react-server-dom-unbundled-node-loader.production.js",
"./node-register": "./node-register.js",
"./src/*": "./src/*.js",
"./package.json": "./package.json"
},
"main": "index.js",
"peerDependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"dependencies": {
"acorn-loose": "^8.3.0",
"webpack-sources": "^3.2.0"
}
}

View File

@@ -0,0 +1,13 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
throw new Error(
'The React Server cannot be used outside a react-server environment. ' +
'You must configure Node.js using the `--conditions react-server` flag.',
);

View File

@@ -17,4 +17,4 @@ export {
registerClientReference,
createClientModuleProxy,
createTemporaryReferenceSet,
} from './src/server/react-flight-dom-server.node.unbundled';
} from './src/server/react-flight-dom-server.node';

View File

@@ -0,0 +1,804 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import * as acorn from 'acorn-loose';
import readMappings from 'webpack-sources/lib/helpers/readMappings.js';
import createMappingsSerializer from 'webpack-sources/lib/helpers/createMappingsSerializer.js';
type ResolveContext = {
conditions: Array<string>,
parentURL: string | void,
};
type ResolveFunction = (
string,
ResolveContext,
ResolveFunction,
) => {url: string} | Promise<{url: string}>;
type GetSourceContext = {
format: string,
};
type GetSourceFunction = (
string,
GetSourceContext,
GetSourceFunction,
) => Promise<{source: Source}>;
type TransformSourceContext = {
format: string,
url: string,
};
type TransformSourceFunction = (
Source,
TransformSourceContext,
TransformSourceFunction,
) => Promise<{source: Source}>;
type LoadContext = {
conditions: Array<string>,
format: string | null | void,
importAssertions: Object,
};
type LoadFunction = (
string,
LoadContext,
LoadFunction,
) => Promise<{format: string, shortCircuit?: boolean, source: Source}>;
type Source = string | ArrayBuffer | Uint8Array;
let warnedAboutConditionsFlag = false;
let stashedGetSource: null | GetSourceFunction = null;
let stashedResolve: null | ResolveFunction = null;
export async function resolve(
specifier: string,
context: ResolveContext,
defaultResolve: ResolveFunction,
): Promise<{url: string}> {
// We stash this in case we end up needing to resolve export * statements later.
stashedResolve = defaultResolve;
if (!context.conditions.includes('react-server')) {
context = {
...context,
conditions: [...context.conditions, 'react-server'],
};
if (!warnedAboutConditionsFlag) {
warnedAboutConditionsFlag = true;
// eslint-disable-next-line react-internal/no-production-logging
console.warn(
'You did not run Node.js with the `--conditions react-server` flag. ' +
'Any "react-server" override will only work with ESM imports.',
);
}
}
return await defaultResolve(specifier, context, defaultResolve);
}
export async function getSource(
url: string,
context: GetSourceContext,
defaultGetSource: GetSourceFunction,
): Promise<{source: Source}> {
// We stash this in case we end up needing to resolve export * statements later.
stashedGetSource = defaultGetSource;
return defaultGetSource(url, context, defaultGetSource);
}
type ExportedEntry = {
localName: string,
exportedName: string,
type: null | string,
loc: {
start: {line: number, column: number},
end: {line: number, column: number},
},
originalLine: number,
originalColumn: number,
originalSource: number,
nameIndex: number,
};
function addExportedEntry(
exportedEntries: Array<ExportedEntry>,
localNames: Set<string>,
localName: string,
exportedName: string,
type: null | 'function',
loc: {
start: {line: number, column: number},
end: {line: number, column: number},
},
) {
if (localNames.has(localName)) {
// If the same local name is exported more than once, we only need one of the names.
return;
}
exportedEntries.push({
localName,
exportedName,
type,
loc,
originalLine: -1,
originalColumn: -1,
originalSource: -1,
nameIndex: -1,
});
}
function addLocalExportedNames(
exportedEntries: Array<ExportedEntry>,
localNames: Set<string>,
node: any,
) {
switch (node.type) {
case 'Identifier':
addExportedEntry(
exportedEntries,
localNames,
node.name,
node.name,
null,
node.loc,
);
return;
case 'ObjectPattern':
for (let i = 0; i < node.properties.length; i++)
addLocalExportedNames(exportedEntries, localNames, node.properties[i]);
return;
case 'ArrayPattern':
for (let i = 0; i < node.elements.length; i++) {
const element = node.elements[i];
if (element)
addLocalExportedNames(exportedEntries, localNames, element);
}
return;
case 'Property':
addLocalExportedNames(exportedEntries, localNames, node.value);
return;
case 'AssignmentPattern':
addLocalExportedNames(exportedEntries, localNames, node.left);
return;
case 'RestElement':
addLocalExportedNames(exportedEntries, localNames, node.argument);
return;
case 'ParenthesizedExpression':
addLocalExportedNames(exportedEntries, localNames, node.expression);
return;
}
}
function transformServerModule(
source: string,
program: any,
url: string,
sourceMap: any,
loader: LoadFunction,
): string {
const body = program.body;
// This entry list needs to be in source location order.
const exportedEntries: Array<ExportedEntry> = [];
// Dedupe set.
const localNames: Set<string> = new Set();
for (let i = 0; i < body.length; i++) {
const node = body[i];
switch (node.type) {
case 'ExportAllDeclaration':
// If export * is used, the other file needs to explicitly opt into "use server" too.
break;
case 'ExportDefaultDeclaration':
if (node.declaration.type === 'Identifier') {
addExportedEntry(
exportedEntries,
localNames,
node.declaration.name,
'default',
null,
node.declaration.loc,
);
} else if (node.declaration.type === 'FunctionDeclaration') {
if (node.declaration.id) {
addExportedEntry(
exportedEntries,
localNames,
node.declaration.id.name,
'default',
'function',
node.declaration.id.loc,
);
} else {
// TODO: This needs to be rewritten inline because it doesn't have a local name.
}
}
continue;
case 'ExportNamedDeclaration':
if (node.declaration) {
if (node.declaration.type === 'VariableDeclaration') {
const declarations = node.declaration.declarations;
for (let j = 0; j < declarations.length; j++) {
addLocalExportedNames(
exportedEntries,
localNames,
declarations[j].id,
);
}
} else {
const name = node.declaration.id.name;
addExportedEntry(
exportedEntries,
localNames,
name,
name,
node.declaration.type === 'FunctionDeclaration'
? 'function'
: null,
node.declaration.id.loc,
);
}
}
if (node.specifiers) {
const specifiers = node.specifiers;
for (let j = 0; j < specifiers.length; j++) {
const specifier = specifiers[j];
addExportedEntry(
exportedEntries,
localNames,
specifier.local.name,
specifier.exported.name,
null,
specifier.local.loc,
);
}
}
continue;
}
}
let mappings =
sourceMap && typeof sourceMap.mappings === 'string'
? sourceMap.mappings
: '';
let newSrc = source;
if (exportedEntries.length > 0) {
let lastSourceIndex = 0;
let lastOriginalLine = 0;
let lastOriginalColumn = 0;
let lastNameIndex = 0;
let sourceLineCount = 0;
let lastMappedLine = 0;
if (sourceMap) {
// We iterate source mapping entries and our matched exports in parallel to source map
// them to their original location.
let nextEntryIdx = 0;
let nextEntryLine = exportedEntries[nextEntryIdx].loc.start.line;
let nextEntryColumn = exportedEntries[nextEntryIdx].loc.start.column;
readMappings(
mappings,
(
generatedLine: number,
generatedColumn: number,
sourceIndex: number,
originalLine: number,
originalColumn: number,
nameIndex: number,
) => {
if (
generatedLine > nextEntryLine ||
(generatedLine === nextEntryLine &&
generatedColumn > nextEntryColumn)
) {
// We're past the entry which means that the best match we have is the previous entry.
if (lastMappedLine === nextEntryLine) {
// Match
exportedEntries[nextEntryIdx].originalLine = lastOriginalLine;
exportedEntries[nextEntryIdx].originalColumn = lastOriginalColumn;
exportedEntries[nextEntryIdx].originalSource = lastSourceIndex;
exportedEntries[nextEntryIdx].nameIndex = lastNameIndex;
} else {
// Skip if we didn't have any mappings on the exported line.
}
nextEntryIdx++;
if (nextEntryIdx < exportedEntries.length) {
nextEntryLine = exportedEntries[nextEntryIdx].loc.start.line;
nextEntryColumn = exportedEntries[nextEntryIdx].loc.start.column;
} else {
nextEntryLine = -1;
nextEntryColumn = -1;
}
}
lastMappedLine = generatedLine;
if (sourceIndex > -1) {
lastSourceIndex = sourceIndex;
}
if (originalLine > -1) {
lastOriginalLine = originalLine;
}
if (originalColumn > -1) {
lastOriginalColumn = originalColumn;
}
if (nameIndex > -1) {
lastNameIndex = nameIndex;
}
},
);
if (nextEntryIdx < exportedEntries.length) {
if (lastMappedLine === nextEntryLine) {
// Match
exportedEntries[nextEntryIdx].originalLine = lastOriginalLine;
exportedEntries[nextEntryIdx].originalColumn = lastOriginalColumn;
exportedEntries[nextEntryIdx].originalSource = lastSourceIndex;
exportedEntries[nextEntryIdx].nameIndex = lastNameIndex;
}
}
for (
let lastIdx = mappings.length - 1;
lastIdx >= 0 && mappings[lastIdx] === ';';
lastIdx--
) {
// If the last mapped lines don't contain any segments, we don't get a callback from readMappings
// so we need to pad the number of mapped lines, with one for each empty line.
lastMappedLine++;
}
sourceLineCount = program.loc.end.line;
if (sourceLineCount < lastMappedLine) {
throw new Error(
'The source map has more mappings than there are lines.',
);
}
// If the original source string had more lines than there are mappings in the source map.
// Add some extra padding of unmapped lines so that any lines that we add line up.
for (
let extraLines = sourceLineCount - lastMappedLine;
extraLines > 0;
extraLines--
) {
mappings += ';';
}
} else {
// If a file doesn't have a source map then we generate a blank source map that just
// contains the original content and segments pointing to the original lines.
sourceLineCount = 1;
let idx = -1;
while ((idx = source.indexOf('\n', idx + 1)) !== -1) {
sourceLineCount++;
}
mappings = 'AAAA' + ';AACA'.repeat(sourceLineCount - 1);
sourceMap = {
version: 3,
sources: [url],
sourcesContent: [source],
mappings: mappings,
sourceRoot: '',
};
lastSourceIndex = 0;
lastOriginalLine = sourceLineCount;
lastOriginalColumn = 0;
lastNameIndex = -1;
lastMappedLine = sourceLineCount;
for (let i = 0; i < exportedEntries.length; i++) {
// Point each entry to original location.
const entry = exportedEntries[i];
entry.originalSource = 0;
entry.originalLine = entry.loc.start.line;
// We use column zero since we do the short-hand line-only source maps above.
entry.originalColumn = 0; // entry.loc.start.column;
}
}
newSrc += '\n\n;';
newSrc +=
'import {registerServerReference} from "react-server-dom-webpack/server";\n';
if (mappings) {
mappings += ';;';
}
const createMapping = createMappingsSerializer();
// Create an empty mapping pointing to where we last left off to reset the counters.
let generatedLine = 1;
createMapping(
generatedLine,
0,
lastSourceIndex,
lastOriginalLine,
lastOriginalColumn,
lastNameIndex,
);
for (let i = 0; i < exportedEntries.length; i++) {
const entry = exportedEntries[i];
generatedLine++;
if (entry.type !== 'function') {
// We first check if the export is a function and if so annotate it.
newSrc += 'if (typeof ' + entry.localName + ' === "function") ';
}
newSrc += 'registerServerReference(' + entry.localName + ',';
newSrc += JSON.stringify(url) + ',';
newSrc += JSON.stringify(entry.exportedName) + ');\n';
mappings += createMapping(
generatedLine,
0,
entry.originalSource,
entry.originalLine,
entry.originalColumn,
entry.nameIndex,
);
}
}
if (sourceMap) {
// Override with an new mappings and serialize an inline source map.
sourceMap.mappings = mappings;
newSrc +=
'//# sourceMappingURL=data:application/json;charset=utf-8;base64,' +
Buffer.from(JSON.stringify(sourceMap)).toString('base64');
}
return newSrc;
}
function addExportNames(names: Array<string>, node: any) {
switch (node.type) {
case 'Identifier':
names.push(node.name);
return;
case 'ObjectPattern':
for (let i = 0; i < node.properties.length; i++)
addExportNames(names, node.properties[i]);
return;
case 'ArrayPattern':
for (let i = 0; i < node.elements.length; i++) {
const element = node.elements[i];
if (element) addExportNames(names, element);
}
return;
case 'Property':
addExportNames(names, node.value);
return;
case 'AssignmentPattern':
addExportNames(names, node.left);
return;
case 'RestElement':
addExportNames(names, node.argument);
return;
case 'ParenthesizedExpression':
addExportNames(names, node.expression);
return;
}
}
function resolveClientImport(
specifier: string,
parentURL: string,
): {url: string} | Promise<{url: string}> {
// Resolve an import specifier as if it was loaded by the client. This doesn't use
// the overrides that this loader does but instead reverts to the default.
// This resolution algorithm will not necessarily have the same configuration
// as the actual client loader. It should mostly work and if it doesn't you can
// always convert to explicit exported names instead.
const conditions = ['node', 'import'];
if (stashedResolve === null) {
throw new Error(
'Expected resolve to have been called before transformSource',
);
}
return stashedResolve(specifier, {conditions, parentURL}, stashedResolve);
}
async function parseExportNamesInto(
body: any,
names: Array<string>,
parentURL: string,
loader: LoadFunction,
): Promise<void> {
for (let i = 0; i < body.length; i++) {
const node = body[i];
switch (node.type) {
case 'ExportAllDeclaration':
if (node.exported) {
addExportNames(names, node.exported);
continue;
} else {
const {url} = await resolveClientImport(node.source.value, parentURL);
const {source} = await loader(
url,
{format: 'module', conditions: [], importAssertions: {}},
loader,
);
if (typeof source !== 'string') {
throw new Error('Expected the transformed source to be a string.');
}
let childBody;
try {
childBody = acorn.parse(source, {
ecmaVersion: '2024',
sourceType: 'module',
}).body;
} catch (x) {
// eslint-disable-next-line react-internal/no-production-logging
console.error('Error parsing %s %s', url, x.message);
continue;
}
await parseExportNamesInto(childBody, names, url, loader);
continue;
}
case 'ExportDefaultDeclaration':
names.push('default');
continue;
case 'ExportNamedDeclaration':
if (node.declaration) {
if (node.declaration.type === 'VariableDeclaration') {
const declarations = node.declaration.declarations;
for (let j = 0; j < declarations.length; j++) {
addExportNames(names, declarations[j].id);
}
} else {
addExportNames(names, node.declaration.id);
}
}
if (node.specifiers) {
const specifiers = node.specifiers;
for (let j = 0; j < specifiers.length; j++) {
addExportNames(names, specifiers[j].exported);
}
}
continue;
}
}
}
async function transformClientModule(
program: any,
url: string,
sourceMap: any,
loader: LoadFunction,
): Promise<string> {
const body = program.body;
const names: Array<string> = [];
await parseExportNamesInto(body, names, url, loader);
if (names.length === 0) {
return '';
}
let newSrc =
'import {registerClientReference} from "react-server-dom-webpack/server";\n';
for (let i = 0; i < names.length; i++) {
const name = names[i];
if (name === 'default') {
newSrc += 'export default ';
newSrc += 'registerClientReference(function() {';
newSrc +=
'throw new Error(' +
JSON.stringify(
`Attempted to call the default export of ${url} from the server ` +
`but it's on the client. It's not possible to invoke a client function from ` +
`the server, it can only be rendered as a Component or passed to props of a ` +
`Client Component.`,
) +
');';
} else {
newSrc += 'export const ' + name + ' = ';
newSrc += 'registerClientReference(function() {';
newSrc +=
'throw new Error(' +
JSON.stringify(
`Attempted to call ${name}() from the server but ${name} is on the client. ` +
`It's not possible to invoke a client function from the server, it can ` +
`only be rendered as a Component or passed to props of a Client Component.`,
) +
');';
}
newSrc += '},';
newSrc += JSON.stringify(url) + ',';
newSrc += JSON.stringify(name) + ');\n';
}
// TODO: Generate source maps for Client Reference functions so they can point to their
// original locations.
return newSrc;
}
async function loadClientImport(
url: string,
defaultTransformSource: TransformSourceFunction,
): Promise<{format: string, shortCircuit?: boolean, source: Source}> {
if (stashedGetSource === null) {
throw new Error(
'Expected getSource to have been called before transformSource',
);
}
// TODO: Validate that this is another module by calling getFormat.
const {source} = await stashedGetSource(
url,
{format: 'module'},
stashedGetSource,
);
const result = await defaultTransformSource(
source,
{format: 'module', url},
defaultTransformSource,
);
return {format: 'module', source: result.source};
}
async function transformModuleIfNeeded(
source: string,
url: string,
loader: LoadFunction,
): Promise<string> {
// Do a quick check for the exact string. If it doesn't exist, don't
// bother parsing.
if (
source.indexOf('use client') === -1 &&
source.indexOf('use server') === -1
) {
return source;
}
let sourceMappingURL = null;
let sourceMappingStart = 0;
let sourceMappingEnd = 0;
let sourceMappingLines = 0;
let program;
try {
program = acorn.parse(source, {
ecmaVersion: '2024',
sourceType: 'module',
locations: true,
onComment(
block: boolean,
text: string,
start: number,
end: number,
startLoc: {line: number, column: number},
endLoc: {line: number, column: number},
) {
if (
text.startsWith('# sourceMappingURL=') ||
text.startsWith('@ sourceMappingURL=')
) {
sourceMappingURL = text.slice(19);
sourceMappingStart = start;
sourceMappingEnd = end;
sourceMappingLines = endLoc.line - startLoc.line;
}
},
});
} catch (x) {
// eslint-disable-next-line react-internal/no-production-logging
console.error('Error parsing %s %s', url, x.message);
return source;
}
let useClient = false;
let useServer = false;
const body = program.body;
for (let i = 0; i < body.length; i++) {
const node = body[i];
if (node.type !== 'ExpressionStatement' || !node.directive) {
break;
}
if (node.directive === 'use client') {
useClient = true;
}
if (node.directive === 'use server') {
useServer = true;
}
}
if (!useClient && !useServer) {
return source;
}
if (useClient && useServer) {
throw new Error(
'Cannot have both "use client" and "use server" directives in the same file.',
);
}
let sourceMap = null;
if (sourceMappingURL) {
const sourceMapResult = await loader(
sourceMappingURL,
// $FlowFixMe
{
format: 'json',
conditions: [],
importAssertions: {type: 'json'},
importAttributes: {type: 'json'},
},
loader,
);
const sourceMapString =
typeof sourceMapResult.source === 'string'
? sourceMapResult.source
: // $FlowFixMe
sourceMapResult.source.toString('utf8');
sourceMap = JSON.parse(sourceMapString);
// Strip the source mapping comment. We'll re-add it below if needed.
source =
source.slice(0, sourceMappingStart) +
'\n'.repeat(sourceMappingLines) +
source.slice(sourceMappingEnd);
}
if (useClient) {
return transformClientModule(program, url, sourceMap, loader);
}
return transformServerModule(source, program, url, sourceMap, loader);
}
export async function transformSource(
source: Source,
context: TransformSourceContext,
defaultTransformSource: TransformSourceFunction,
): Promise<{source: Source}> {
const transformed = await defaultTransformSource(
source,
context,
defaultTransformSource,
);
if (context.format === 'module') {
const transformedSource = transformed.source;
if (typeof transformedSource !== 'string') {
throw new Error('Expected source to have been transformed to a string.');
}
const newSrc = await transformModuleIfNeeded(
transformedSource,
context.url,
(url: string, ctx: LoadContext, defaultLoad: LoadFunction) => {
return loadClientImport(url, defaultTransformSource);
},
);
return {source: newSrc};
}
return transformed;
}
export async function load(
url: string,
context: LoadContext,
defaultLoad: LoadFunction,
): Promise<{format: string, shortCircuit?: boolean, source: Source}> {
const result = await defaultLoad(url, context, defaultLoad);
if (result.format === 'module') {
if (typeof result.source !== 'string') {
throw new Error('Expected source to have been loaded into a string.');
}
const newSrc = await transformModuleIfNeeded(
result.source,
url,
defaultLoad,
);
return {format: 'module', source: newSrc};
}
return result;
}

View File

@@ -0,0 +1,109 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
const acorn = require('acorn-loose');
const url = require('url');
const Module = require('module');
module.exports = function register() {
const Server: any = require('react-server-dom-unbundled/server');
const registerServerReference = Server.registerServerReference;
const createClientModuleProxy = Server.createClientModuleProxy;
// $FlowFixMe[prop-missing] found when upgrading Flow
const originalCompile = Module.prototype._compile;
// $FlowFixMe[prop-missing] found when upgrading Flow
Module.prototype._compile = function (
this: any,
content: string,
filename: string,
): void {
// Do a quick check for the exact string. If it doesn't exist, don't
// bother parsing.
if (
content.indexOf('use client') === -1 &&
content.indexOf('use server') === -1
) {
return originalCompile.apply(this, arguments);
}
let body;
try {
body = acorn.parse(content, {
ecmaVersion: '2024',
sourceType: 'source',
}).body;
} catch (x) {
console['error']('Error parsing %s %s', url, x.message);
return originalCompile.apply(this, arguments);
}
let useClient = false;
let useServer = false;
for (let i = 0; i < body.length; i++) {
const node = body[i];
if (node.type !== 'ExpressionStatement' || !node.directive) {
break;
}
if (node.directive === 'use client') {
useClient = true;
}
if (node.directive === 'use server') {
useServer = true;
}
}
if (!useClient && !useServer) {
return originalCompile.apply(this, arguments);
}
if (useClient && useServer) {
throw new Error(
'Cannot have both "use client" and "use server" directives in the same file.',
);
}
if (useClient) {
const moduleId: string = (url.pathToFileURL(filename).href: any);
this.exports = createClientModuleProxy(moduleId);
}
if (useServer) {
originalCompile.apply(this, arguments);
const moduleId: string = (url.pathToFileURL(filename).href: any);
const exports = this.exports;
// This module is imported server to server, but opts in to exposing functions by
// reference. If there are any functions in the export.
if (typeof exports === 'function') {
// The module exports a function directly,
registerServerReference(
(exports: any),
moduleId,
// Represents the whole Module object instead of a particular import.
null,
);
} else {
const keys = Object.keys(exports);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const value = exports[keys[i]];
if (typeof value === 'function') {
registerServerReference((value: any), moduleId, key);
}
}
}
}
};
};

View File

@@ -0,0 +1,360 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {ReactClientValue} from 'react-server/src/ReactFlightServer';
export type ServerReference<T: Function> = T & {
$$typeof: symbol,
$$id: string,
$$bound: null | Array<ReactClientValue>,
$$location?: Error,
};
// eslint-disable-next-line no-unused-vars
export type ClientReference<T> = {
$$typeof: symbol,
$$id: string,
$$async: boolean,
};
const CLIENT_REFERENCE_TAG = Symbol.for('react.client.reference');
const SERVER_REFERENCE_TAG = Symbol.for('react.server.reference');
export function isClientReference(reference: Object): boolean {
return reference.$$typeof === CLIENT_REFERENCE_TAG;
}
export function isServerReference(reference: Object): boolean {
return reference.$$typeof === SERVER_REFERENCE_TAG;
}
export function registerClientReference<T>(
proxyImplementation: any,
id: string,
exportName: string,
): ClientReference<T> {
return registerClientReferenceImpl(
proxyImplementation,
id + '#' + exportName,
false,
);
}
function registerClientReferenceImpl<T>(
proxyImplementation: any,
id: string,
async: boolean,
): ClientReference<T> {
return Object.defineProperties(proxyImplementation, {
$$typeof: {value: CLIENT_REFERENCE_TAG},
$$id: {value: id},
$$async: {value: async},
});
}
// $FlowFixMe[method-unbinding]
const FunctionBind = Function.prototype.bind;
// $FlowFixMe[method-unbinding]
const ArraySlice = Array.prototype.slice;
function bind(this: ServerReference<any>): any {
// $FlowFixMe[incompatible-call]
const newFn = FunctionBind.apply(this, arguments);
if (this.$$typeof === SERVER_REFERENCE_TAG) {
if (__DEV__) {
const thisBind = arguments[0];
if (thisBind != null) {
console.error(
'Cannot bind "this" of a Server Action. Pass null or undefined as the first argument to .bind().',
);
}
}
const args = ArraySlice.call(arguments, 1);
const $$typeof = {value: SERVER_REFERENCE_TAG};
const $$id = {value: this.$$id};
const $$bound = {value: this.$$bound ? this.$$bound.concat(args) : args};
return Object.defineProperties(
(newFn: any),
__DEV__
? {
$$typeof,
$$id,
$$bound,
$$location: {
value: this.$$location,
configurable: true,
},
bind: {value: bind, configurable: true},
}
: {
$$typeof,
$$id,
$$bound,
bind: {value: bind, configurable: true},
},
);
}
return newFn;
}
const serverReferenceToString = {
value: () => 'function () { [omitted code] }',
configurable: true,
writable: true,
};
export function registerServerReference<T: Function>(
reference: T,
id: string,
exportName: null | string,
): ServerReference<T> {
const $$typeof = {value: SERVER_REFERENCE_TAG};
const $$id = {
value: exportName === null ? id : id + '#' + exportName,
configurable: true,
};
const $$bound = {value: null, configurable: true};
return Object.defineProperties(
(reference: any),
__DEV__
? {
$$typeof,
$$id,
$$bound,
$$location: {
value: Error('react-stack-top-frame'),
configurable: true,
},
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
}
: {
$$typeof,
$$id,
$$bound,
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
},
);
}
const PROMISE_PROTOTYPE = Promise.prototype;
const deepProxyHandlers = {
get: function (
target: Function,
name: string | symbol,
receiver: Proxy<Function>,
) {
switch (name) {
// These names are read by the Flight runtime if you end up using the exports object.
case '$$typeof':
// These names are a little too common. We should probably have a way to
// have the Flight runtime extract the inner target instead.
return target.$$typeof;
case '$$id':
return target.$$id;
case '$$async':
return target.$$async;
case 'name':
return target.name;
case 'displayName':
return undefined;
// We need to special case this because createElement reads it if we pass this
// reference.
case 'defaultProps':
return undefined;
// React looks for debugInfo on thenables.
case '_debugInfo':
return undefined;
// Avoid this attempting to be serialized.
case 'toJSON':
return undefined;
case Symbol.toPrimitive:
// $FlowFixMe[prop-missing]
return Object.prototype[Symbol.toPrimitive];
case Symbol.toStringTag:
// $FlowFixMe[prop-missing]
return Object.prototype[Symbol.toStringTag];
case 'Provider':
throw new Error(
`Cannot render a Client Context Provider on the Server. ` +
`Instead, you can export a Client Component wrapper ` +
`that itself renders a Client Context Provider.`,
);
case 'then':
throw new Error(
`Cannot await or return from a thenable. ` +
`You cannot await a client module from a server component.`,
);
}
// eslint-disable-next-line react-internal/safe-string-coercion
const expression = String(target.name) + '.' + String(name);
throw new Error(
`Cannot access ${expression} on the server. ` +
'You cannot dot into a client module from a server component. ' +
'You can only pass the imported name through.',
);
},
set: function () {
throw new Error('Cannot assign to a client module from a server module.');
},
};
function getReference(target: Function, name: string | symbol): $FlowFixMe {
switch (name) {
// These names are read by the Flight runtime if you end up using the exports object.
case '$$typeof':
return target.$$typeof;
case '$$id':
return target.$$id;
case '$$async':
return target.$$async;
case 'name':
return target.name;
// We need to special case this because createElement reads it if we pass this
// reference.
case 'defaultProps':
return undefined;
// React looks for debugInfo on thenables.
case '_debugInfo':
return undefined;
// Avoid this attempting to be serialized.
case 'toJSON':
return undefined;
case Symbol.toPrimitive:
// $FlowFixMe[prop-missing]
return Object.prototype[Symbol.toPrimitive];
case Symbol.toStringTag:
// $FlowFixMe[prop-missing]
return Object.prototype[Symbol.toStringTag];
case '__esModule':
// Something is conditionally checking which export to use. We'll pretend to be
// an ESM compat module but then we'll check again on the client.
const moduleId = target.$$id;
target.default = registerClientReferenceImpl(
(function () {
throw new Error(
`Attempted to call the default export of ${moduleId} from the server ` +
`but it's on the client. It's not possible to invoke a client function from ` +
`the server, it can only be rendered as a Component or passed to props of a ` +
`Client Component.`,
);
}: any),
target.$$id + '#',
target.$$async,
);
return true;
case 'then':
if (target.then) {
// Use a cached value
return target.then;
}
if (!target.$$async) {
// If this module is expected to return a Promise (such as an AsyncModule) then
// we should resolve that with a client reference that unwraps the Promise on
// the client.
const clientReference: ClientReference<any> =
registerClientReferenceImpl(({}: any), target.$$id, true);
const proxy = new Proxy(clientReference, proxyHandlers);
// Treat this as a resolved Promise for React's use()
target.status = 'fulfilled';
target.value = proxy;
const then = (target.then = registerClientReferenceImpl(
(function then(resolve, reject: any) {
// Expose to React.
return Promise.resolve(resolve(proxy));
}: any),
// If this is not used as a Promise but is treated as a reference to a `.then`
// export then we should treat it as a reference to that name.
target.$$id + '#then',
false,
));
return then;
} else {
// Since typeof .then === 'function' is a feature test we'd continue recursing
// indefinitely if we return a function. Instead, we return an object reference
// if we check further.
return undefined;
}
}
if (typeof name === 'symbol') {
throw new Error(
'Cannot read Symbol exports. Only named exports are supported on a client module ' +
'imported on the server.',
);
}
let cachedReference = target[name];
if (!cachedReference) {
const reference: ClientReference<any> = registerClientReferenceImpl(
(function () {
throw new Error(
// eslint-disable-next-line react-internal/safe-string-coercion
`Attempted to call ${String(name)}() from the server but ${String(
name,
)} is on the client. ` +
`It's not possible to invoke a client function from the server, it can ` +
`only be rendered as a Component or passed to props of a Client Component.`,
);
}: any),
target.$$id + '#' + name,
target.$$async,
);
Object.defineProperty((reference: any), 'name', {value: name});
cachedReference = target[name] = new Proxy(reference, deepProxyHandlers);
}
return cachedReference;
}
const proxyHandlers = {
get: function (
target: Function,
name: string | symbol,
receiver: Proxy<Function>,
): $FlowFixMe {
return getReference(target, name);
},
getOwnPropertyDescriptor: function (
target: Function,
name: string | symbol,
): $FlowFixMe {
let descriptor = Object.getOwnPropertyDescriptor(target, name);
if (!descriptor) {
descriptor = {
value: getReference(target, name),
writable: false,
configurable: false,
enumerable: false,
};
Object.defineProperty(target, name, descriptor);
}
return descriptor;
},
getPrototypeOf(target: Function): Object {
// Pretend to be a Promise in case anyone asks.
return PROMISE_PROTOTYPE;
},
set: function (): empty {
throw new Error('Cannot assign to a client module from a server module.');
},
};
export function createClientModuleProxy<T>(
moduleId: string,
): ClientReference<T> {
const clientReference: ClientReference<T> = registerClientReferenceImpl(
({}: any),
// Represents the whole Module object instead of a particular import.
moduleId,
false,
);
return new Proxy(clientReference, proxyHandlers);
}

View File

@@ -24,6 +24,8 @@ import {
} from '../shared/ReactFlightImportMetadata';
import {prepareDestinationWithChunks} from 'react-client/src/ReactFlightClientConfig';
import hasOwnProperty from 'shared/hasOwnProperty';
export type ServerConsumerModuleMap = {
[clientId: string]: {
[clientExportName: string]: ClientReference<any>,
@@ -158,5 +160,8 @@ export function requireModule<T>(metadata: ClientReference<T>): T {
// default property of this if it was an ESM interop module.
return moduleExports.default;
}
return moduleExports[metadata.name];
if (hasOwnProperty.call(moduleExports, metadata.name)) {
return moduleExports[metadata.name];
}
return (undefined: any);
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import {preinitScriptForSSR} from 'react-client/src/ReactFlightClientConfig';
export type ModuleLoading = null | {
prefix: string,
crossOrigin?: 'use-credentials' | '',
};
export function prepareDestinationWithChunks(
moduleLoading: ModuleLoading,
// Chunks are double-indexed [..., idx, filenamex, idy, filenamey, ...]
chunks: Array<string>,
nonce: ?string,
) {
if (moduleLoading !== null) {
for (let i = 1; i < chunks.length; i += 2) {
preinitScriptForSSR(
moduleLoading.prefix + chunks[i],
nonce,
moduleLoading.crossOrigin,
);
}
}
}

View File

@@ -0,0 +1,186 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {Thenable, ReactCustomFormAction} from 'shared/ReactTypes.js';
import type {
Response as FlightResponse,
FindSourceMapURLCallback,
} from 'react-client/src/ReactFlightClient';
import type {ReactServerValue} from 'react-client/src/ReactFlightReplyClient';
import type {
ServerConsumerModuleMap,
ModuleLoading,
ServerManifest,
} from 'react-client/src/ReactFlightClientConfig';
type ServerConsumerManifest = {
moduleMap: ServerConsumerModuleMap,
moduleLoading: ModuleLoading,
serverModuleMap: null | ServerManifest,
};
import {
createResponse,
getRoot,
reportGlobalError,
processBinaryChunk,
close,
} from 'react-client/src/ReactFlightClient';
import {
processReply,
createServerReference as createServerReferenceImpl,
} from 'react-client/src/ReactFlightReplyClient';
export {registerServerReference} from 'react-client/src/ReactFlightReplyClient';
import type {TemporaryReferenceSet} from 'react-client/src/ReactFlightTemporaryReferences';
export {createTemporaryReferenceSet} from 'react-client/src/ReactFlightTemporaryReferences';
export type {TemporaryReferenceSet};
function noServerCall() {
throw new Error(
'Server Functions cannot be called during initial render. ' +
'This would create a fetch waterfall. Try to use a Server Component ' +
'to pass data to Client Components instead.',
);
}
export function createServerReference<A: Iterable<any>, T>(
id: any,
callServer: any,
): (...A) => Promise<T> {
return createServerReferenceImpl(id, noServerCall);
}
type EncodeFormActionCallback = <A>(
id: any,
args: Promise<A>,
) => ReactCustomFormAction;
export type Options = {
serverConsumerManifest: ServerConsumerManifest,
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
temporaryReferences?: TemporaryReferenceSet,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
};
function createResponseFromOptions(options: Options) {
return createResponse(
options.serverConsumerManifest.moduleMap,
options.serverConsumerManifest.serverModuleMap,
options.serverConsumerManifest.moduleLoading,
noServerCall,
options.encodeFormAction,
typeof options.nonce === 'string' ? options.nonce : undefined,
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
);
}
function startReadingFromStream(
response: FlightResponse,
stream: ReadableStream,
): void {
const reader = stream.getReader();
function progress({
done,
value,
}: {
done: boolean,
value: ?any,
...
}): void | Promise<void> {
if (done) {
close(response);
return;
}
const buffer: Uint8Array = (value: any);
processBinaryChunk(response, buffer);
return reader.read().then(progress).catch(error);
}
function error(e: any) {
reportGlobalError(response, e);
}
reader.read().then(progress).catch(error);
}
function createFromReadableStream<T>(
stream: ReadableStream,
options: Options,
): Thenable<T> {
const response: FlightResponse = createResponseFromOptions(options);
startReadingFromStream(response, stream);
return getRoot(response);
}
function createFromFetch<T>(
promiseForResponse: Promise<Response>,
options: Options,
): Thenable<T> {
const response: FlightResponse = createResponseFromOptions(options);
promiseForResponse.then(
function (r) {
startReadingFromStream(response, (r.body: any));
},
function (e) {
reportGlobalError(response, e);
},
);
return getRoot(response);
}
function encodeReply(
value: ReactServerValue,
options?: {temporaryReferences?: TemporaryReferenceSet, signal?: AbortSignal},
): Promise<
string | URLSearchParams | FormData,
> /* We don't use URLSearchParams yet but maybe */ {
return new Promise((resolve, reject) => {
const abort = processReply(
value,
'',
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
resolve,
reject,
);
if (options && options.signal) {
const signal = options.signal;
if (signal.aborted) {
abort((signal: any).reason);
} else {
const listener = () => {
abort((signal: any).reason);
signal.removeEventListener('abort', listener);
};
signal.addEventListener('abort', listener);
}
}
});
}
export {createFromFetch, createFromReadableStream, encodeReply};

View File

@@ -0,0 +1,107 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {Thenable, ReactCustomFormAction} from 'shared/ReactTypes.js';
import type {
Response,
FindSourceMapURLCallback,
} from 'react-client/src/ReactFlightClient';
import type {
ServerConsumerModuleMap,
ModuleLoading,
ServerManifest,
} from 'react-client/src/ReactFlightClientConfig';
type ServerConsumerManifest = {
moduleMap: ServerConsumerModuleMap,
moduleLoading: ModuleLoading,
serverModuleMap: null | ServerManifest,
};
import type {Readable} from 'stream';
import {
createResponse,
getRoot,
reportGlobalError,
processStringChunk,
processBinaryChunk,
close,
} from 'react-client/src/ReactFlightClient';
import {createServerReference as createServerReferenceImpl} from 'react-client/src/ReactFlightReplyClient';
export {registerServerReference} from 'react-client/src/ReactFlightReplyClient';
function noServerCall() {
throw new Error(
'Server Functions cannot be called during initial render. ' +
'This would create a fetch waterfall. Try to use a Server Component ' +
'to pass data to Client Components instead.',
);
}
export function createServerReference<A: Iterable<any>, T>(
id: any,
callServer: any,
): (...A) => Promise<T> {
return createServerReferenceImpl(id, noServerCall);
}
type EncodeFormActionCallback = <A>(
id: any,
args: Promise<A>,
) => ReactCustomFormAction;
export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
};
function createFromNodeStream<T>(
stream: Readable,
serverConsumerManifest: ServerConsumerManifest,
options?: Options,
): Thenable<T> {
const response: Response = createResponse(
serverConsumerManifest.moduleMap,
serverConsumerManifest.serverModuleMap,
serverConsumerManifest.moduleLoading,
noServerCall,
options ? options.encodeFormAction : undefined,
options && typeof options.nonce === 'string' ? options.nonce : undefined,
undefined, // TODO: If encodeReply is supported, this should support temporaryReferences
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
);
stream.on('data', chunk => {
if (typeof chunk === 'string') {
processStringChunk(response, chunk);
} else {
processBinaryChunk(response, chunk);
}
});
stream.on('error', error => {
reportGlobalError(response, error);
});
stream.on('end', () => close(response));
return getRoot(response);
}
export {createFromNodeStream};

View File

@@ -0,0 +1,307 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {
Request,
ReactClientValue,
} from 'react-server/src/ReactFlightServer';
import type {Destination} from 'react-server/src/ReactServerStreamConfigNode';
import type {ClientManifest} from './ReactFlightServerConfigUnbundledBundler';
import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig';
import type {Busboy} from 'busboy';
import type {Writable} from 'stream';
import type {Thenable} from 'shared/ReactTypes';
import {Readable} from 'stream';
import {
createRequest,
createPrerenderRequest,
startWork,
startFlowing,
stopFlowing,
abort,
} from 'react-server/src/ReactFlightServer';
import {
createResponse,
reportGlobalError,
close,
resolveField,
resolveFileInfo,
resolveFileChunk,
resolveFileComplete,
getRoot,
} from 'react-server/src/ReactFlightReplyServer';
import {
decodeAction,
decodeFormState,
} from 'react-server/src/ReactFlightActionServer';
export {
registerServerReference,
registerClientReference,
createClientModuleProxy,
} from '../ReactFlightUnbundledReferences';
import type {TemporaryReferenceSet} from 'react-server/src/ReactFlightServerTemporaryReferences';
export {createTemporaryReferenceSet} from 'react-server/src/ReactFlightServerTemporaryReferences';
export type {TemporaryReferenceSet};
function createDrainHandler(destination: Destination, request: Request) {
return () => startFlowing(request, destination);
}
function createCancelHandler(request: Request, reason: string) {
return () => {
stopFlowing(request);
abort(request, new Error(reason));
};
}
type Options = {
environmentName?: string | (() => string),
filterStackFrame?: (url: string, functionName: string) => boolean,
onError?: (error: mixed) => void,
onPostpone?: (reason: string) => void,
identifierPrefix?: string,
temporaryReferences?: TemporaryReferenceSet,
};
type PipeableStream = {
abort(reason: mixed): void,
pipe<T: Writable>(destination: T): T,
};
function renderToPipeableStream(
model: ReactClientValue,
webpackMap: ClientManifest,
options?: Options,
): PipeableStream {
const request = createRequest(
model,
webpackMap,
options ? options.onError : undefined,
options ? options.identifierPrefix : undefined,
options ? options.onPostpone : undefined,
options ? options.temporaryReferences : undefined,
__DEV__ && options ? options.environmentName : undefined,
__DEV__ && options ? options.filterStackFrame : undefined,
);
let hasStartedFlowing = false;
startWork(request);
return {
pipe<T: Writable>(destination: T): T {
if (hasStartedFlowing) {
throw new Error(
'React currently only supports piping to one writable stream.',
);
}
hasStartedFlowing = true;
startFlowing(request, destination);
destination.on('drain', createDrainHandler(destination, request));
destination.on(
'error',
createCancelHandler(
request,
'The destination stream errored while writing data.',
),
);
destination.on(
'close',
createCancelHandler(request, 'The destination stream closed early.'),
);
return destination;
},
abort(reason: mixed) {
abort(request, reason);
},
};
}
function createFakeWritable(readable: any): Writable {
// The current host config expects a Writable so we create
// a fake writable for now to push into the Readable.
return ({
write(chunk) {
return readable.push(chunk);
},
end() {
readable.push(null);
},
destroy(error) {
readable.destroy(error);
},
}: any);
}
type PrerenderOptions = {
environmentName?: string | (() => string),
filterStackFrame?: (url: string, functionName: string) => boolean,
onError?: (error: mixed) => void,
onPostpone?: (reason: string) => void,
identifierPrefix?: string,
temporaryReferences?: TemporaryReferenceSet,
signal?: AbortSignal,
};
type StaticResult = {
prelude: Readable,
};
function prerenderToNodeStream(
model: ReactClientValue,
webpackMap: ClientManifest,
options?: PrerenderOptions,
): Promise<StaticResult> {
return new Promise((resolve, reject) => {
const onFatalError = reject;
function onAllReady() {
const readable: Readable = new Readable({
read() {
startFlowing(request, writable);
},
});
const writable = createFakeWritable(readable);
resolve({prelude: readable});
}
const request = createPrerenderRequest(
model,
webpackMap,
onAllReady,
onFatalError,
options ? options.onError : undefined,
options ? options.identifierPrefix : undefined,
options ? options.onPostpone : undefined,
options ? options.temporaryReferences : undefined,
__DEV__ && options ? options.environmentName : undefined,
__DEV__ && options ? options.filterStackFrame : undefined,
);
if (options && options.signal) {
const signal = options.signal;
if (signal.aborted) {
const reason = (signal: any).reason;
abort(request, reason);
} else {
const listener = () => {
const reason = (signal: any).reason;
abort(request, reason);
signal.removeEventListener('abort', listener);
};
signal.addEventListener('abort', listener);
}
}
startWork(request);
});
}
function decodeReplyFromBusboy<T>(
busboyStream: Busboy,
webpackMap: ServerManifest,
options?: {temporaryReferences?: TemporaryReferenceSet},
): Thenable<T> {
const response = createResponse(
webpackMap,
'',
options ? options.temporaryReferences : undefined,
);
let pendingFiles = 0;
const queuedFields: Array<string> = [];
busboyStream.on('field', (name, value) => {
if (pendingFiles > 0) {
// Because the 'end' event fires two microtasks after the next 'field'
// we would resolve files and fields out of order. To handle this properly
// we queue any fields we receive until the previous file is done.
queuedFields.push(name, value);
} else {
try {
resolveField(response, name, value);
} catch (error) {
busboyStream.destroy(error);
}
}
});
busboyStream.on('file', (name, value, {filename, encoding, mimeType}) => {
if (encoding.toLowerCase() === 'base64') {
busboyStream.destroy(
new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
),
);
return;
}
pendingFiles++;
const file = resolveFileInfo(response, name, filename, mimeType);
value.on('data', chunk => {
resolveFileChunk(response, file, chunk);
});
value.on('end', () => {
try {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
}
queuedFields.length = 0;
}
} catch (error) {
busboyStream.destroy(error);
}
});
});
busboyStream.on('finish', () => {
close(response);
});
busboyStream.on('error', err => {
reportGlobalError(
response,
// $FlowFixMe[incompatible-call] types Error and mixed are incompatible
err,
);
});
return getRoot(response);
}
function decodeReply<T>(
body: string | FormData,
webpackMap: ServerManifest,
options?: {temporaryReferences?: TemporaryReferenceSet},
): Thenable<T> {
if (typeof body === 'string') {
const form = new FormData();
form.append('0', body);
body = form;
}
const response = createResponse(
webpackMap,
'',
options ? options.temporaryReferences : undefined,
body,
);
const root = getRoot<T>(response);
close(response);
return root;
}
export {
renderToPipeableStream,
prerenderToNodeStream,
decodeReplyFromBusboy,
decodeReply,
decodeAction,
decodeFormState,
};

View File

@@ -0,0 +1,108 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {ReactClientValue} from 'react-server/src/ReactFlightServer';
import type {
ImportMetadata,
ImportManifestEntry,
} from '../shared/ReactFlightImportMetadata';
import type {
ClientReference,
ServerReference,
} from '../ReactFlightUnbundledReferences';
export type {ClientReference, ServerReference};
export type ClientManifest = {
[id: string]: ClientReferenceManifestEntry,
};
export type ServerReferenceId = string;
export type ClientReferenceMetadata = ImportMetadata;
export opaque type ClientReferenceManifestEntry = ImportManifestEntry;
export type ClientReferenceKey = string;
export {
isClientReference,
isServerReference,
} from '../ReactFlightUnbundledReferences';
export function getClientReferenceKey(
reference: ClientReference<any>,
): ClientReferenceKey {
return reference.$$async ? reference.$$id + '#async' : reference.$$id;
}
export function resolveClientReferenceMetadata<T>(
config: ClientManifest,
clientReference: ClientReference<T>,
): ClientReferenceMetadata {
const modulePath = clientReference.$$id;
let name = '';
let resolvedModuleData = config[modulePath];
if (resolvedModuleData) {
// The potentially aliased name.
name = resolvedModuleData.name;
} else {
// We didn't find this specific export name but we might have the * export
// which contains this name as well.
// TODO: It's unfortunate that we now have to parse this string. We should
// probably go back to encoding path and name separately on the client reference.
const idx = modulePath.lastIndexOf('#');
if (idx !== -1) {
name = modulePath.slice(idx + 1);
resolvedModuleData = config[modulePath.slice(0, idx)];
}
if (!resolvedModuleData) {
throw new Error(
'Could not find the module "' +
modulePath +
'" in the React Client Manifest. ' +
'This is probably a bug in the React Server Components bundler.',
);
}
}
if (resolvedModuleData.async === true && clientReference.$$async === true) {
throw new Error(
'The module "' +
modulePath +
'" is marked as an async ESM module but was loaded as a CJS proxy. ' +
'This is probably a bug in the React Server Components bundler.',
);
}
if (resolvedModuleData.async === true || clientReference.$$async === true) {
return [resolvedModuleData.id, resolvedModuleData.chunks, name, 1];
} else {
return [resolvedModuleData.id, resolvedModuleData.chunks, name];
}
}
export function getServerReferenceId<T>(
config: ClientManifest,
serverReference: ServerReference<T>,
): ServerReferenceId {
return serverReference.$$id;
}
export function getServerReferenceBoundArguments<T>(
config: ClientManifest,
serverReference: ServerReference<T>,
): null | Array<ReactClientValue> {
return serverReference.$$bound;
}
export function getServerReferenceLocation<T>(
config: ClientManifest,
serverReference: ServerReference<T>,
): void | Error {
return serverReference.$$location;
}

View File

@@ -0,0 +1,44 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
export type ImportManifestEntry = {
id: string,
// chunks is a double indexed array of chunkId / chunkFilename pairs
chunks: Array<string>,
name: string,
async?: boolean,
};
// This is the parsed shape of the wire format which is why it is
// condensed to only the essentialy information
export type ImportMetadata =
| [
/* id */ string,
/* chunks id/filename pairs, double indexed */ Array<string>,
/* name */ string,
/* async */ 1,
]
| [
/* id */ string,
/* chunks id/filename pairs, double indexed */ Array<string>,
/* name */ string,
];
export const ID = 0;
export const CHUNKS = 1;
export const NAME = 2;
// export const ASYNC = 3;
// This logic is correct because currently only include the 4th tuple member
// when the module is async. If that changes we will need to actually assert
// the value is true. We don't index into the 4th slot because flow does not
// like the potential out of bounds access
export function isAsyncImport(metadata: ImportMetadata): boolean {
return metadata.length === 4;
}

View File

@@ -0,0 +1,13 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
throw new Error(
'The React Server cannot be used outside a react-server environment. ' +
'You must configure Node.js using the `--conditions react-server` flag.',
);

View File

@@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerenderToNodeStream} from './src/server/react-flight-dom-server.node.unbundled';
export {unstable_prerenderToNodeStream} from './src/server/react-flight-dom-server.node';

View File

@@ -1,7 +1,7 @@
{
"name": "react-server-dom-webpack",
"description": "React Server Components bindings for DOM using Webpack. This is intended to be integrated into meta-frameworks. It is not intended to be imported directly.",
"version": "19.1.0",
"version": "19.1.4",
"keywords": [
"react"
],
@@ -17,17 +17,14 @@
"client.browser.js",
"client.edge.js",
"client.node.js",
"client.node.unbundled.js",
"server.js",
"server.browser.js",
"server.edge.js",
"server.node.js",
"server.node.unbundled.js",
"static.js",
"static.browser.js",
"static.edge.js",
"static.node.js",
"static.node.unbundled.js",
"node-register.js",
"cjs/",
"esm/"
@@ -39,10 +36,7 @@
"workerd": "./client.edge.js",
"deno": "./client.edge.js",
"worker": "./client.edge.js",
"node": {
"webpack": "./client.node.js",
"default": "./client.node.unbundled.js"
},
"node": "./client.node.js",
"edge-light": "./client.edge.js",
"browser": "./client.browser.js",
"default": "./client.browser.js"
@@ -50,15 +44,11 @@
"./client.browser": "./client.browser.js",
"./client.edge": "./client.edge.js",
"./client.node": "./client.node.js",
"./client.node.unbundled": "./client.node.unbundled.js",
"./server": {
"react-server": {
"workerd": "./server.edge.js",
"deno": "./server.browser.js",
"node": {
"webpack": "./server.node.js",
"default": "./server.node.unbundled.js"
},
"node": "./server.node.js",
"edge-light": "./server.edge.js",
"browser": "./server.browser.js"
},
@@ -67,15 +57,11 @@
"./server.browser": "./server.browser.js",
"./server.edge": "./server.edge.js",
"./server.node": "./server.node.js",
"./server.node.unbundled": "./server.node.unbundled.js",
"./static": {
"react-server": {
"workerd": "./static.edge.js",
"deno": "./static.browser.js",
"node": {
"webpack": "./static.node.js",
"default": "./static.node.unbundled.js"
},
"node": "./static.node.js",
"edge-light": "./static.edge.js",
"browser": "./static.browser.js"
},
@@ -84,7 +70,6 @@
"./static.browser": "./static.browser.js",
"./static.edge": "./static.edge.js",
"./static.node": "./static.node.js",
"./static.node.unbundled": "./static.node.unbundled.js",
"./node-loader": "./esm/react-server-dom-webpack-node-loader.production.js",
"./node-register": "./node-register.js",
"./src/*": "./src/*.js",
@@ -100,8 +85,8 @@
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react": "^19.1.4",
"react-dom": "^19.1.4",
"webpack": "^5.59.0"
},
"dependencies": {

View File

@@ -103,6 +103,12 @@ function bind(this: ServerReference<any>): any {
return newFn;
}
const serverReferenceToString = {
value: () => 'function () { [omitted code] }',
configurable: true,
writable: true,
};
export function registerServerReference<T: Function>(
reference: T,
id: string,
@@ -126,12 +132,14 @@ export function registerServerReference<T: Function>(
configurable: true,
},
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
}
: {
$$typeof,
$$id,
$$bound,
bind: {value: bind, configurable: true},
toString: serverReferenceToString,
},
);
}

View File

@@ -60,11 +60,11 @@ describe('ReactFlightDOM', () => {
FlightReactDOM = require('react-dom');
jest.mock('react-server-dom-webpack/server', () =>
require('react-server-dom-webpack/server.node.unbundled'),
require('react-server-dom-unbundled/server.node'),
);
if (__EXPERIMENTAL__) {
jest.mock('react-server-dom-webpack/static', () =>
require('react-server-dom-webpack/static.node.unbundled'),
require('react-server-dom-unbundled/static.node'),
);
}
const WebpackMock = require('./utils/WebpackMock');
@@ -172,6 +172,23 @@ describe('ReactFlightDOM', () => {
};
}
function createUnclosingStream(
stream: ReadableStream<Uint8Array>,
): ReadableStream<Uint8Array> {
const reader = stream.getReader();
const s = new ReadableStream({
async pull(controller) {
const {done, value} = await reader.read();
if (!done) {
controller.enqueue(value);
}
},
});
return s;
}
const theInfinitePromise = new Promise(() => {});
function InfiniteSuspend() {
throw theInfinitePromise;
@@ -2949,7 +2966,7 @@ describe('ReactFlightDOM', () => {
const {prelude} = await pendingResult;
const result = await ReactServerDOMClient.createFromReadableStream(
Readable.toWeb(prelude),
createUnclosingStream(Readable.toWeb(prelude)),
);
const iterator = result.multiShotIterable[Symbol.asyncIterator]();

View File

@@ -45,13 +45,13 @@ describe('ReactFlightDOMNode', () => {
// Simulate the condition resolution
jest.mock('react', () => require('react/react.react-server'));
jest.mock('react-server-dom-webpack/server', () =>
require('react-server-dom-webpack/server.node'),
jest.requireActual('react-server-dom-webpack/server.node'),
);
ReactServer = require('react');
ReactServerDOMServer = require('react-server-dom-webpack/server');
if (__EXPERIMENTAL__) {
jest.mock('react-server-dom-webpack/static', () =>
require('react-server-dom-webpack/static.node'),
jest.requireActual('react-server-dom-webpack/static.node'),
);
ReactServerDOMStaticServer = require('react-server-dom-webpack/static');
}
@@ -66,7 +66,7 @@ describe('ReactFlightDOMNode', () => {
__unmockReact();
jest.unmock('react-server-dom-webpack/server');
jest.mock('react-server-dom-webpack/client', () =>
require('react-server-dom-webpack/client.node'),
jest.requireActual('react-server-dom-webpack/client.node'),
);
React = require('react');

View File

@@ -147,7 +147,7 @@ describe('ReactFlightDOMReplyEdge', () => {
expect(await resultBlob.arrayBuffer()).toEqual(await blob.arrayBuffer());
});
it('should supports ReadableStreams with typed arrays', async () => {
it('should support ReadableStreams with typed arrays', async () => {
const buffer = new Uint8Array([
123, 4, 10, 5, 100, 255, 244, 45, 56, 67, 43, 124, 67, 89, 100, 20,
]).buffer;
@@ -246,6 +246,53 @@ describe('ReactFlightDOMReplyEdge', () => {
);
});
it('should cancel the transported ReadableStream when we are cancelled', async () => {
const s = new ReadableStream({
start(controller) {
controller.enqueue('hi');
controller.close();
},
});
const body = await ReactServerDOMClient.encodeReply(s);
const iterable = {
async *[Symbol.asyncIterator]() {
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
for (const entry of body) {
if (entry[1] === 'C') {
// Return before finishing the stream.
return;
}
yield entry;
}
},
};
const result = await ReactServerDOMServer.decodeReplyFromAsyncIterable(
iterable,
webpackServerMap,
);
const reader = result.getReader();
// We should be able to read the part we already emitted before the abort
expect(await reader.read()).toEqual({
value: 'hi',
done: false,
});
let error = null;
try {
await reader.read();
} catch (x) {
error = x;
}
expect(error).not.toBe(null);
expect(error.message).toBe('Connection closed.');
});
it('should abort when parsing an incomplete payload', async () => {
const infinitePromise = new Promise(() => {});
const controller = new AbortController();

View File

@@ -30,6 +30,8 @@ import {prepareDestinationWithChunks} from 'react-client/src/ReactFlightClientCo
import {loadChunk} from 'react-client/src/ReactFlightClientConfig';
import hasOwnProperty from 'shared/hasOwnProperty';
export type ServerConsumerModuleMap = null | {
[clientId: string]: {
[clientExportName: string]: ClientReferenceManifestEntry,
@@ -249,5 +251,8 @@ export function requireModule<T>(metadata: ClientReference<T>): T {
// default property of this if it was an ESM interop module.
return moduleExports.__esModule ? moduleExports.default : moduleExports;
}
return moduleExports[metadata[NAME]];
if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
return moduleExports[metadata[NAME]];
}
return (undefined: any);
}

View File

@@ -224,16 +224,23 @@ function decodeReplyFromBusboy<T>(
// we queue any fields we receive until the previous file is done.
queuedFields.push(name, value);
} else {
resolveField(response, name, value);
try {
resolveField(response, name, value);
} catch (error) {
busboyStream.destroy(error);
}
}
});
busboyStream.on('file', (name, value, {filename, encoding, mimeType}) => {
if (encoding.toLowerCase() === 'base64') {
throw new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
busboyStream.destroy(
new Error(
"React doesn't accept base64 encoded file uploads because we don't expect " +
"form data passed from a browser to ever encode data that way. If that's " +
'the wrong assumption, we can easily fix it.',
),
);
return;
}
pendingFiles++;
const file = resolveFileInfo(response, name, filename, mimeType);
@@ -241,14 +248,18 @@ function decodeReplyFromBusboy<T>(
resolveFileChunk(response, file, chunk);
});
value.on('end', () => {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
try {
resolveFileComplete(response, name, file);
pendingFiles--;
if (pendingFiles === 0) {
// Release any queued fields
for (let i = 0; i < queuedFields.length; i += 2) {
resolveField(response, queuedFields[i], queuedFields[i + 1]);
}
queuedFields.length = 0;
}
queuedFields.length = 0;
} catch (error) {
busboyStream.destroy(error);
}
});
});

View File

@@ -13,7 +13,7 @@ import type {LazyComponent} from 'react/src/ReactLazy';
// TODO: Consider marking the whole bundle instead of these boundaries.
const callComponent = {
'react-stack-bottom-frame': function <Props, Arg, R>(
react_stack_bottom_frame: function <Props, Arg, R>(
Component: (p: Props, arg: Arg) => R,
props: Props,
secondArg: Arg,
@@ -28,7 +28,7 @@ export const callComponentInDEV: <Props, Arg, R>(
secondArg: Arg,
) => R = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callComponent['react-stack-bottom-frame'].bind(callComponent): any)
(callComponent.react_stack_bottom_frame.bind(callComponent): any)
: (null: any);
interface ClassInstance<R> {
@@ -36,7 +36,7 @@ interface ClassInstance<R> {
}
const callRender = {
'react-stack-bottom-frame': function <R>(instance: ClassInstance<R>): R {
react_stack_bottom_frame: function <R>(instance: ClassInstance<R>): R {
return instance.render();
},
};
@@ -44,11 +44,11 @@ const callRender = {
export const callRenderInDEV: <R>(instance: ClassInstance<R>) => R => R =
__DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callRender['react-stack-bottom-frame'].bind(callRender): any)
(callRender.react_stack_bottom_frame.bind(callRender): any)
: (null: any);
const callLazyInit = {
'react-stack-bottom-frame': function (lazy: LazyComponent<any, any>): any {
react_stack_bottom_frame: function (lazy: LazyComponent<any, any>): any {
const payload = lazy._payload;
const init = lazy._init;
return init(payload);
@@ -57,5 +57,5 @@ const callLazyInit = {
export const callLazyInitInDEV: (lazy: LazyComponent<any, any>) => any = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callLazyInit['react-stack-bottom-frame'].bind(callLazyInit): any)
(callLazyInit.react_stack_bottom_frame.bind(callLazyInit): any)
: (null: any);

View File

@@ -19,7 +19,7 @@ import {setCurrentOwner} from './flight/ReactFlightCurrentOwner';
// TODO: Consider marking the whole bundle instead of these boundaries.
const callComponent = {
'react-stack-bottom-frame': function <Props, R>(
react_stack_bottom_frame: function <Props, R>(
Component: (p: Props, arg: void) => R,
props: Props,
componentDebugInfo: ReactComponentInfo,
@@ -41,11 +41,11 @@ export const callComponentInDEV: <Props, R>(
componentDebugInfo: ReactComponentInfo,
) => R = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callComponent['react-stack-bottom-frame'].bind(callComponent): any)
(callComponent.react_stack_bottom_frame.bind(callComponent): any)
: (null: any);
const callLazyInit = {
'react-stack-bottom-frame': function (lazy: LazyComponent<any, any>): any {
react_stack_bottom_frame: function (lazy: LazyComponent<any, any>): any {
const payload = lazy._payload;
const init = lazy._init;
return init(payload);
@@ -54,11 +54,11 @@ const callLazyInit = {
export const callLazyInitInDEV: (lazy: LazyComponent<any, any>) => any = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callLazyInit['react-stack-bottom-frame'].bind(callLazyInit): any)
(callLazyInit.react_stack_bottom_frame.bind(callLazyInit): any)
: (null: any);
const callIterator = {
'react-stack-bottom-frame': function (
react_stack_bottom_frame: function (
iterator: $AsyncIterator<ReactClientValue, ReactClientValue, void>,
progress: (
entry:
@@ -81,5 +81,5 @@ export const callIteratorInDEV: (
error: (reason: mixed) => void,
) => void = __DEV__
? // We use this technique to trick minifiers to preserve the function name.
(callIterator['react-stack-bottom-frame'].bind(callIterator): any)
(callIterator.react_stack_bottom_frame.bind(callIterator): any)
: (null: any);

File diff suppressed because it is too large Load Diff

View File

@@ -1904,7 +1904,7 @@ function serializePromiseID(id: number): string {
}
function serializeServerReferenceID(id: number): string {
return '$F' + id.toString(16);
return '$h' + id.toString(16);
}
function serializeSymbolReference(name: string): string {

View File

@@ -45,7 +45,7 @@ export function parseStackTrace(
// don't want/need.
stack = stack.slice(29);
}
let idx = stack.indexOf('react-stack-bottom-frame');
let idx = stack.indexOf('react_stack_bottom_frame');
if (idx !== -1) {
idx = stack.lastIndexOf('\n', idx);
}

View File

@@ -0,0 +1,30 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import {AsyncLocalStorage} from 'async_hooks';
import type {Request} from 'react-server/src/ReactFlightServer';
import type {ReactComponentInfo} from 'shared/ReactTypes';
export * from 'react-server-dom-unbundled/src/server/ReactFlightServerConfigUnbundledBundler';
export * from 'react-dom-bindings/src/server/ReactFlightServerConfigDOM';
export const supportsRequestStorage = true;
export const requestStorage: AsyncLocalStorage<Request | void> =
new AsyncLocalStorage();
export const supportsComponentStorage = __DEV__;
export const componentStorage: AsyncLocalStorage<ReactComponentInfo | void> =
supportsComponentStorage ? new AsyncLocalStorage() : (null: any);
export {createHook as createAsyncHook, executionAsyncId} from 'async_hooks';
export * from '../ReactFlightServerConfigDebugNode';
export * from '../ReactFlightStackConfigV8';

View File

@@ -1,6 +1,6 @@
{
"name": "react-test-renderer",
"version": "19.1.0",
"version": "19.1.4",
"description": "React package for snapshot testing.",
"main": "index.js",
"repository": {
@@ -19,11 +19,11 @@
},
"homepage": "https://react.dev/",
"dependencies": {
"react-is": "^19.0.0",
"scheduler": "^0.25.0"
"react-is": "^19.1.4",
"scheduler": "^0.26.0"
},
"peerDependencies": {
"react": "^19.0.0"
"react": "^19.1.4"
},
"files": [
"LICENSE",
@@ -32,4 +32,4 @@
"shallow.js",
"cjs/"
]
}
}

View File

@@ -4,7 +4,7 @@
"keywords": [
"react"
],
"version": "19.1.0",
"version": "19.1.4",
"homepage": "https://react.dev/",
"bugs": "https://github.com/facebook/react/issues",
"license": "MIT",

View File

@@ -66,7 +66,7 @@ function UnknownOwner() {
return (() => Error('react-stack-top-frame'))();
}
const createFakeCallStack = {
'react-stack-bottom-frame': function (callStackForError) {
react_stack_bottom_frame: function (callStackForError) {
return callStackForError();
},
};
@@ -81,7 +81,7 @@ if (__DEV__) {
didWarnAboutElementRef = {};
// We use this technique to trick minifiers to preserve the function name.
unknownOwnerDebugStack = createFakeCallStack['react-stack-bottom-frame'].bind(
unknownOwnerDebugStack = createFakeCallStack.react_stack_bottom_frame.bind(
createFakeCallStack,
UnknownOwner,
)();

View File

@@ -1,6 +1,6 @@
{
"name": "scheduler",
"version": "0.25.0",
"version": "0.26.0",
"description": "Cooperative scheduler for the browser environment.",
"repository": {
"type": "git",
@@ -24,4 +24,4 @@
"unstable_post_task.js",
"cjs/"
]
}
}

View File

@@ -96,11 +96,6 @@ export const enableSwipeTransition = __EXPERIMENTAL__;
export const enableScrollEndPolyfill = __EXPERIMENTAL__;
/**
* Switches the Fabric API from doing layout in commit work instead of complete work.
*/
export const enableFabricCompleteRootInCommitPhase = false;
/**
* Switches Fiber creation to a simple object instead of a constructor.
*/
@@ -140,6 +135,8 @@ export const enableShallowPropDiffing = false;
export const enableSiblingPrerendering = true;
export const enableEagerAlternateStateNodeCleanup = true;
/**
* Enables an expiration time for retry lanes to avoid starvation.
*/

View File

@@ -24,7 +24,7 @@ export function formatOwnerStack(error: Error): string {
// Pop the JSX frame.
stack = stack.slice(idx + 1);
}
idx = stack.indexOf('react-stack-bottom-frame');
idx = stack.indexOf('react_stack_bottom_frame');
if (idx !== -1) {
idx = stack.lastIndexOf('\n', idx);
}

View File

@@ -12,4 +12,4 @@
// TODO: This module is used both by the release scripts and to expose a version
// at runtime. We should instead inject the version number as part of the build
// process, and use the ReactVersions.js module as the single source of truth.
export default '19.1.0';
export default '19.1.4';

View File

@@ -22,8 +22,8 @@ export const enableObjectFiber = __VARIANT__;
export const enableHiddenSubtreeInsertionEffectCleanup = __VARIANT__;
export const enablePersistedModeClonedFlag = __VARIANT__;
export const enableShallowPropDiffing = __VARIANT__;
export const enableEagerAlternateStateNodeCleanup = __VARIANT__;
export const passChildrenWhenCloningPersistedNodes = __VARIANT__;
export const enableFabricCompleteRootInCommitPhase = __VARIANT__;
export const enableSiblingPrerendering = __VARIANT__;
export const enableUseEffectCRUDOverload = __VARIANT__;
export const enableFastAddPropertiesInDiffing = __VARIANT__;

View File

@@ -20,12 +20,12 @@ const dynamicFlags: DynamicExportsType = (dynamicFlagsUntyped: any);
// the exports object every time a flag is read.
export const {
alwaysThrottleRetries,
enableFabricCompleteRootInCommitPhase,
enableHiddenSubtreeInsertionEffectCleanup,
enableObjectFiber,
enablePersistedModeClonedFlag,
enableShallowPropDiffing,
enableUseEffectCRUDOverload,
enableEagerAlternateStateNodeCleanup,
passChildrenWhenCloningPersistedNodes,
enableSiblingPrerendering,
enableFastAddPropertiesInDiffing,

View File

@@ -30,7 +30,6 @@ export const enableAsyncIterableChildren = false;
export const enableCPUSuspense = false;
export const enableCreateEventHandleAPI = false;
export const enableDO_NOT_USE_disableStrictPassiveEffect = false;
export const enableFabricCompleteRootInCommitPhase = false;
export const enableMoveBefore = true;
export const enableFizzExternalRuntime = true;
export const enableHalt = false;
@@ -50,6 +49,7 @@ export const enableSchedulingProfiler = __PROFILE__;
export const enableComponentPerformanceTrack = false;
export const enableScopeAPI = false;
export const enableShallowPropDiffing = false;
export const enableEagerAlternateStateNodeCleanup = true;
export const enableSuspenseAvoidThisFallback = false;
export const enableSuspenseCallback = false;
export const enableTaint = true;

View File

@@ -36,7 +36,6 @@ export const enableUseEffectEventHook = false;
export const favorSafetyOverHydrationPerf = true;
export const enableLegacyFBSupport = false;
export const enableMoveBefore = false;
export const enableFabricCompleteRootInCommitPhase = false;
export const enableHiddenSubtreeInsertionEffectCleanup = false;
export const enableHydrationLaneScheduling = true;
@@ -66,6 +65,7 @@ export const enableShallowPropDiffing = false;
export const enableSiblingPrerendering = true;
export const enableUseEffectCRUDOverload = false;
export const enableEagerAlternateStateNodeCleanup = true;
export const enableYieldingBeforePassive = true;

View File

@@ -47,6 +47,7 @@ export const enableSchedulingProfiler = __PROFILE__;
export const enableComponentPerformanceTrack = false;
export const enableScopeAPI = false;
export const enableShallowPropDiffing = false;
export const enableEagerAlternateStateNodeCleanup = true;
export const enableSuspenseAvoidThisFallback = false;
export const enableSuspenseCallback = false;
export const enableTaint = true;
@@ -60,7 +61,6 @@ export const renameElementSymbol = false;
export const retryLaneExpirationMs = 5000;
export const syncLaneExpirationMs = 250;
export const transitionLaneExpirationMs = 5000;
export const enableFabricCompleteRootInCommitPhase = false;
export const enableSiblingPrerendering = true;
export const enableUseEffectCRUDOverload = true;
export const enableHydrationLaneScheduling = true;

View File

@@ -39,7 +39,6 @@ export const favorSafetyOverHydrationPerf = true;
export const enableLegacyFBSupport = false;
export const enableMoveBefore = false;
export const enableRenderableContext = false;
export const enableFabricCompleteRootInCommitPhase = false;
export const enableHiddenSubtreeInsertionEffectCleanup = true;
export const enableRetryLaneExpiration = false;
@@ -75,6 +74,7 @@ export const enableShallowPropDiffing = false;
export const enableSiblingPrerendering = true;
export const enableUseEffectCRUDOverload = false;
export const enableEagerAlternateStateNodeCleanup = true;
export const enableHydrationLaneScheduling = true;

View File

@@ -50,7 +50,6 @@ export const enableProfilerTimer = __PROFILE__;
export const enableProfilerCommitHooks = __PROFILE__;
export const enableProfilerNestedUpdatePhase = __PROFILE__;
export const enableUpdaterTracking = __PROFILE__;
export const enableFabricCompleteRootInCommitPhase = false;
export const enableSuspenseAvoidThisFallback = true;
@@ -111,6 +110,8 @@ export const disableLegacyMode = true;
export const enableShallowPropDiffing = false;
export const enableEagerAlternateStateNodeCleanup = true;
export const enableLazyPublicInstanceInFabric = false;
export const enableSwipeTransition = false;

View File

@@ -21,6 +21,6 @@
"rxjs": "^5.5.6"
},
"dependencies": {
"use-sync-external-store": "^1.4.0"
"use-sync-external-store": "^1.5.0"
}
}

View File

@@ -537,5 +537,9 @@
"549": "Cannot start a gesture with a disconnected AnimationTimeline.",
"550": "useSwipeTransition is not yet supported in react-art.",
"551": "useSwipeTransition is not yet supported in React Native.",
"552": "Cannot use a useSwipeTransition() in a detached root."
"552": "Cannot use a useSwipeTransition() in a detached root.",
"567": "Already initialized stream.",
"568": "Already initialized typed array.",
"569": "Cannot have cyclic thenables.",
"570": "Invalid reference."
}

View File

@@ -124,25 +124,34 @@ async function main() {
throw new Error(`Unknown release channel ${argv.releaseChannel}`);
}
} else {
// Running locally, no concurrency. Move each channel's build artifacts into
// a temporary directory so that they don't conflict.
buildForChannel('stable', '', '');
const stableDir = tmp.dirSync().name;
crossDeviceRenameSync('./build', stableDir);
processStable(stableDir);
buildForChannel('experimental', '', '');
const experimentalDir = tmp.dirSync().name;
crossDeviceRenameSync('./build', experimentalDir);
processExperimental(experimentalDir);
const releaseChannel = argv.releaseChannel;
if (releaseChannel === 'stable') {
buildForChannel('stable', '', '');
processStable('./build');
} else if (releaseChannel === 'experimental') {
buildForChannel('experimental', '', '');
processExperimental('./build');
} else {
// Running locally, no concurrency. Move each channel's build artifacts into
// a temporary directory so that they don't conflict.
buildForChannel('stable', '', '');
const stableDir = tmp.dirSync().name;
crossDeviceRenameSync('./build', stableDir);
processStable(stableDir);
buildForChannel('experimental', '', '');
const experimentalDir = tmp.dirSync().name;
crossDeviceRenameSync('./build', experimentalDir);
processExperimental(experimentalDir);
// Then merge the experimental folder into the stable one. processExperimental
// will have already removed conflicting files.
//
// In CI, merging is handled by the GitHub Download Artifacts plugin.
mergeDirsSync(experimentalDir + '/', stableDir + '/');
// Then merge the experimental folder into the stable one. processExperimental
// will have already removed conflicting files.
//
// In CI, merging is handled by the GitHub Download Artifacts plugin.
mergeDirsSync(experimentalDir + '/', stableDir + '/');
// Now restore the combined directory back to its original name
crossDeviceRenameSync(stableDir, './build');
// Now restore the combined directory back to its original name
crossDeviceRenameSync(stableDir, './build');
}
}
}
@@ -231,9 +240,16 @@ function processStable(buildDir) {
}
if (fs.existsSync(buildDir + '/react-native')) {
updatePlaceholderReactVersionInCompiledArtifactsFb(
updatePlaceholderReactVersionInCompiledArtifacts(
buildDir + '/react-native',
rnVersionString
rnVersionString,
filename => filename.endsWith('.fb.js')
);
updatePlaceholderReactVersionInCompiledArtifacts(
buildDir + '/react-native',
ReactVersion,
filename => !filename.endsWith('.fb.js') && filename.endsWith('.js')
);
}
@@ -340,9 +356,16 @@ function processExperimental(buildDir, version) {
}
if (fs.existsSync(buildDir + '/react-native')) {
updatePlaceholderReactVersionInCompiledArtifactsFb(
updatePlaceholderReactVersionInCompiledArtifacts(
buildDir + '/react-native',
rnVersionString
rnVersionString,
filename => filename.endsWith('.fb.js')
);
updatePlaceholderReactVersionInCompiledArtifacts(
buildDir + '/react-native',
ReactVersion,
filename => !filename.endsWith('.fb.js') && filename.endsWith('.js')
);
}
@@ -437,38 +460,15 @@ function updatePackageVersions(
function updatePlaceholderReactVersionInCompiledArtifacts(
artifactsDirectory,
newVersion
newVersion,
filteringClosure
) {
// Update the version of React in the compiled artifacts by searching for
// the placeholder string and replacing it with a new one.
const artifactFilenames = String(
spawnSync('grep', [
'-lr',
PLACEHOLDER_REACT_VERSION,
'--',
artifactsDirectory,
]).stdout
)
.trim()
.split('\n')
.filter(filename => filename.endsWith('.js'));
for (const artifactFilename of artifactFilenames) {
const originalText = fs.readFileSync(artifactFilename, 'utf8');
const replacedText = originalText.replaceAll(
PLACEHOLDER_REACT_VERSION,
newVersion
);
fs.writeFileSync(artifactFilename, replacedText);
if (filteringClosure == null) {
filteringClosure = filename => filename.endsWith('.js');
}
}
function updatePlaceholderReactVersionInCompiledArtifactsFb(
artifactsDirectory,
newVersion
) {
// Update the version of React in the compiled artifacts by searching for
// the placeholder string and replacing it with a new one.
const artifactFilenames = String(
spawnSync('grep', [
'-lr',
@@ -479,7 +479,7 @@ function updatePlaceholderReactVersionInCompiledArtifactsFb(
)
.trim()
.split('\n')
.filter(filename => filename.endsWith('.fb.js'));
.filter(filteringClosure);
for (const artifactFilename of artifactFilenames) {
const originalText = fs.readFileSync(artifactFilename, 'utf8');

View File

@@ -462,18 +462,6 @@ const bundles = [
wrapWithModuleBoundaries: false,
externals: ['react', 'util', 'crypto', 'async_hooks', 'react-dom'],
},
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: RENDERER,
entry:
'react-server-dom-webpack/src/server/react-flight-dom-server.node.unbundled',
name: 'react-server-dom-webpack-server.node.unbundled',
condition: 'react-server',
global: 'ReactServerDOMServer',
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: false,
externals: ['react', 'util', 'crypto', 'async_hooks', 'react-dom'],
},
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: RENDERER,
@@ -505,15 +493,6 @@ const bundles = [
wrapWithModuleBoundaries: false,
externals: ['react', 'react-dom', 'util', 'crypto'],
},
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: RENDERER,
entry: 'react-server-dom-webpack/client.node.unbundled',
global: 'ReactServerDOMClient',
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: false,
externals: ['react', 'react-dom', 'util', 'crypto'],
},
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: RENDERER,
@@ -731,6 +710,61 @@ const bundles = [
externals: ['acorn'],
},
/******* React Server DOM Unbundled Server *******/
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: RENDERER,
entry: 'react-server-dom-unbundled/server.node',
condition: 'react-server',
global: 'ReactServerDOMServer',
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: false,
externals: [
'react',
'react-dom',
'async_hooks',
'crypto',
'stream',
'util',
],
},
/******* React Server DOM Unbundled Client *******/
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: RENDERER,
entry: 'react-server-dom-unbundled/client',
global: 'ReactServerDOMClient',
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: false,
externals: ['react', 'react-dom', 'util', 'crypto'],
},
/******* React Server DOM Unbundled Node.js Loader *******/
{
bundleTypes: [ESM_PROD],
moduleType: RENDERER_UTILS,
entry: 'react-server-dom-unbundled/node-loader',
condition: 'react-server',
global: 'ReactServerUnbundledNodeLoader',
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: false,
externals: ['acorn'],
},
/******* React Server DOM Unbundled Node.js CommonJS Loader *******/
{
bundleTypes: [NODE_ES2015],
moduleType: RENDERER_UTILS,
entry: 'react-server-dom-unbundled/src/ReactFlightUnbundledNodeRegister',
name: 'react-server-dom-unbundled-node-register',
condition: 'react-server',
global: 'ReactFlightUnbundledNodeRegister',
minifyWithProdErrorCodes: false,
wrapWithModuleBoundaries: false,
externals: ['url', 'module', 'react-server-dom-unbundled/server'],
},
/******* React Suspense Test Utils *******/
{
bundleTypes: [NODE_ES2015],

View File

@@ -62,8 +62,6 @@ module.exports = [
'react-dom/static.node',
'react-dom/test-utils',
'react-dom/unstable_server-external-runtime',
'react-server-dom-webpack/client.node.unbundled',
'react-server-dom-webpack/src/server/react-flight-dom-server.node.unbundled',
],
paths: [
'react-dom',
@@ -83,18 +81,13 @@ module.exports = [
'react-dom-bindings/src/server/ReactFlightServerConfigDOM.js',
'react-dom-bindings/src/shared/ReactFlightClientConfigDOM.js',
'react-server-dom-webpack',
'react-server-dom-webpack/client.node.unbundled',
'react-server-dom-webpack/server',
'react-server-dom-webpack/server.node.unbundled',
'react-server-dom-webpack/static',
'react-server-dom-webpack/static.node.unbundled',
'react-server-dom-webpack/src/client/ReactFlightDOMClientEdge.js', // react-server-dom-webpack/client.node
'react-server-dom-webpack/src/client/ReactFlightDOMClientNode.js', // react-server-dom-webpack/client.node
'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerNode.js',
'react-server-dom-webpack/src/server/react-flight-dom-server.node.unbundled',
'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack.js',
'react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer.js',
'react-server-dom-webpack/src/server/ReactFlightDOMServerNode.js', // react-server-dom-webpack/src/server/react-flight-dom-server.node
'react-devtools',
'react-devtools-core',
'react-devtools-shell',
'react-devtools-shared',
'shared/ReactDOMSharedInternals',
'react-server/src/ReactFlightServerConfigDebugNode.js',
@@ -232,6 +225,49 @@ module.exports = [
isFlowTyped: true,
isServerSupported: true,
},
{
shortName: 'dom-node-unbundled',
entryPoints: [
'react-server-dom-unbundled/client',
'react-server-dom-unbundled/server.node',
],
paths: [
'react-dom',
'react-dom-bindings',
'react-dom/client',
'react-dom/profiling',
'react-dom/server',
'react-dom/server.node',
'react-dom/static',
'react-dom/static.node',
'react-dom/src/server/react-dom-server.node',
'react-dom/src/server/ReactDOMFizzServerNode.js', // react-dom/server.node
'react-dom/src/server/ReactDOMFizzStaticNode.js',
'react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js',
'react-dom-bindings/src/server/ReactFlightServerConfigDOM.js',
'react-dom-bindings/src/shared/ReactFlightClientConfigDOM.js',
'react-server-dom-unbundled',
'react-server-dom-unbundled/client',
'react-server-dom-unbundled/server',
'react-server-dom-unbundled/server.node',
'react-server-dom-unbundled/static',
'react-server-dom-unbundled/static.node',
'react-server-dom-unbundled/src/client/ReactFlightDOMClientEdge.js', // react-server-dom-unbundled/client.node
'react-server-dom-unbundled/src/client/ReactFlightDOMClientNode.js', // react-server-dom-unbundled/client.node
'react-server-dom-unbundled/src/client/ReactFlightClientConfigBundlerNode.js',
'react-server-dom-unbundled/src/client/react-flight-dom-client.node',
'react-server-dom-unbundled/src/server/react-flight-dom-server.node',
'react-server-dom-unbundled/src/server/ReactFlightDOMServerNode.js', // react-server-dom-unbundled/src/server/react-flight-dom-server.node
'react-devtools',
'react-devtools-core',
'react-devtools-shell',
'react-devtools-shared',
'shared/ReactDOMSharedInternals',
'react-server/src/ReactFlightServerConfigDebugNode.js',
],
isFlowTyped: true,
isServerSupported: true,
},
{
shortName: 'dom-bun',
entryPoints: ['react-dom/src/server/react-dom-server.bun.js'],