Compare commits

..

7 Commits

Author SHA1 Message Date
Sebastian Sebbie Silbermann
b910fc15e3 Version 19.2.2
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:08 +01:00
Sebastian Markbage
dd0519822a 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:08 +01:00
Sebastian "Sebbie" Silbermann
0eeded69c1 Run CI for backport releases (#35313) 2025-12-08 16:09:07 +01:00
Sebastian "Sebbie" Silbermann
a4d338a6c6 [test] Cleanup stack assertions in tests mixing React Server and Client (#35316) 2025-12-08 16:09:07 +01:00
Sebastian Sebbie Silbermann
053df4e856 Version 19.2.1 2025-12-03 15:33:44 +01:00
Sebastian Markbage
b180cb2b25 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:31:08 +01:00
Sebastian "Sebbie" Silbermann
581fdc550a [release] Allow building single release channel with processed versions (#35270) 2025-12-02 22:37:56 +01:00
343 changed files with 7378 additions and 6181 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

@@ -19,9 +19,6 @@ on:
tag_version:
required: false
type: string
dry_run:
required: false
type: boolean
secrets:
NPM_TOKEN:
required: true
@@ -58,13 +55,7 @@ jobs:
key: compiler-node_modules-v6-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('compiler/yarn.lock') }}
- run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
- if: inputs.dry_run == true
name: Publish packages to npm (dry run)
run: |
cp ./scripts/release/ci-npmrc ~/.npmrc
scripts/release/publish.js --frfr --debug --ci --versionName=${{ inputs.version_name }} --tag=${{ inputs.dist_tag }} ${{ inputs.tag_version && format('--tagVersion={0}', inputs.tag_version) || '' }}
- if: inputs.dry_run != true
name: Publish packages to npm
- name: Publish packages to npm
run: |
cp ./scripts/release/ci-npmrc ~/.npmrc
scripts/release/publish.js --frfr --ci --versionName=${{ inputs.version_name }} --tag=${{ inputs.dist_tag }} ${{ inputs.tag_version && format('--tagVersion={0}', inputs.tag_version) || '' }}

View File

@@ -17,9 +17,6 @@ on:
tag_version:
required: false
type: string
dry_run:
required: false
type: boolean
permissions: {}
@@ -36,6 +33,5 @@ jobs:
dist_tag: ${{ inputs.dist_tag }}
version_name: ${{ inputs.version_name }}
tag_version: ${{ inputs.tag_version }}
dry_run: ${{ inputs.dry_run }}
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -19,6 +19,5 @@ jobs:
release_channel: experimental
dist_tag: experimental
version_name: '0.0.0'
dry_run: false
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -3,6 +3,10 @@ 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/**
@@ -41,7 +45,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') }}
lookup-only: true
- uses: actions/setup-node@v4
if: steps.node_modules.outputs.cache-hit != 'true'
@@ -55,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
@@ -67,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
@@ -82,7 +84,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') }}
lookup-only: true
- uses: actions/setup-node@v4
if: steps.node_modules.outputs.cache-hit != 'true'
@@ -98,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
@@ -112,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:
@@ -154,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
@@ -184,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
@@ -216,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
@@ -274,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
@@ -306,7 +300,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') }}
- name: Install runtime dependencies
run: yarn install --frozen-lockfile
if: steps.node_modules.outputs.cache-hit != 'true'
@@ -349,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
@@ -440,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
@@ -483,10 +473,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
@@ -548,10 +536,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
@@ -588,10 +574,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
@@ -740,10 +724,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
@@ -802,10 +784,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

View File

@@ -82,6 +82,7 @@ jobs:
run: |
scripts/release/publish.js \
--ci \
--skipTests \
--tags=${{ inputs.dist_tag }} \
--onlyPackages=${{ inputs.only_packages }} ${{ (inputs.dry && '') || '\'}}
${{ inputs.dry && '--dry' || '' }}
@@ -90,10 +91,11 @@ jobs:
run: |
scripts/release/publish.js \
--ci \
--skipTests \
--tags=${{ inputs.dist_tag }} \
--skipPackages=${{ inputs.skip_packages }} ${{ (inputs.dry && '') || '\'}}
${{ inputs.dry && '--dry' || '' }}
- if: '${{ !inputs.skip_packages && !inputs.only_packages }}'
- if: '${{ !(inputs.skip_packages && inputs.only_packages) }}'
name: 'Publish all packages'
run: |
scripts/release/publish.js \

View File

@@ -7,18 +7,18 @@
//
// The @latest channel uses the version as-is, e.g.:
//
// 19.3.0
// 19.2.2
//
// The @canary channel appends additional information, with the scheme
// <version>-<label>-<commit_sha>, e.g.:
//
// 19.3.0-canary-a1c2d3e4
// 19.2.2-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.3.0';
const ReactVersion = '19.2.2';
// 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
@@ -33,8 +33,8 @@ const canaryChannelLabel = 'canary';
const rcNumber = 0;
const stablePackages = {
'eslint-plugin-react-hooks': '7.0.0',
'jest-react': '0.18.0',
'eslint-plugin-react-hooks': '6.1.0',
'jest-react': '0.17.0',
react: ReactVersion,
'react-art': ReactVersion,
'react-dom': ReactVersion,
@@ -42,12 +42,12 @@ const stablePackages = {
'react-server-dom-turbopack': ReactVersion,
'react-server-dom-parcel': ReactVersion,
'react-is': ReactVersion,
'react-reconciler': '0.34.0',
'react-refresh': '0.19.0',
'react-reconciler': '0.33.0',
'react-refresh': '0.18.0',
'react-test-renderer': ReactVersion,
'use-subscription': '1.13.0',
'use-sync-external-store': '1.7.0',
scheduler: '0.28.0',
'use-subscription': '1.12.0',
'use-sync-external-store': '1.6.0',
scheduler: '0.27.0',
};
// These packages do not exist in the @canary or @latest channel, only

View File

@@ -314,36 +314,6 @@ test('disableMemoizationForDebugging flag works as expected', async ({
expect(output).toMatchSnapshot('disableMemoizationForDebugging-output.txt');
});
test('error is displayed when source has syntax error', async ({page}) => {
const syntaxErrorSource = `function TestComponent(props) {
const oops = props.
return (
<>{oops}</>
);
}`;
const store: Store = {
source: syntaxErrorSource,
config: defaultConfig,
showInternals: false,
};
const hash = encodeStore(store);
await page.goto(`/#${hash}`);
await page.waitForFunction(isMonacoLoaded);
await expandConfigs(page);
await page.screenshot({
fullPage: true,
path: 'test-results/08-source-syntax-error.png',
});
const text =
(await page.locator('.monaco-editor-output').allInnerTexts()) ?? [];
const output = text.join('');
expect(output.replace(/\s+/g, ' ')).toContain(
'Expected identifier to be defined before being used',
);
});
TEST_CASE_INPUTS.forEach((t, idx) =>
test(`playground compiles: ${t.name}`, async ({page}) => {
const store: Store = {

View File

@@ -7,6 +7,7 @@
import {Resizable} from 're-resizable';
import React, {
useCallback,
useId,
unstable_ViewTransition as ViewTransition,
unstable_addTransitionType as addTransitionType,
@@ -55,14 +56,13 @@ function AccordionWindowItem({
tabsOpen: Set<string>;
setTabsOpen: (newTab: Set<string>) => void;
hasChanged: boolean;
isFailure: boolean;
}): React.ReactElement {
const id = useId();
const isShow = tabsOpen.has(name);
const transitionName = `accordion-window-item-${id}`;
const toggleTabs = (): void => {
const toggleTabs = () => {
startTransition(() => {
addTransitionType(EXPAND_ACCORDION_TRANSITION);
const nextState = new Set(tabsOpen);

View File

@@ -6,6 +6,7 @@
*/
import MonacoEditor, {loader, type Monaco} from '@monaco-editor/react';
import {PluginOptions} from 'babel-plugin-react-compiler';
import type {editor} from 'monaco-editor';
import * as monaco from 'monaco-editor';
import React, {
@@ -17,8 +18,9 @@ import React, {
} from 'react';
import {Resizable} from 're-resizable';
import {useStore, useStoreDispatch} from '../StoreContext';
import {monacoConfigOptions} from './monacoOptions';
import {monacoOptions} from './monacoOptions';
import {IconChevron} from '../Icons/IconChevron';
import prettyFormat from 'pretty-format';
import {CONFIG_PANEL_TRANSITION} from '../../lib/transitionTypes';
// @ts-expect-error - webpack asset/source loader handles .d.ts files as strings
@@ -27,9 +29,9 @@ import compilerTypeDefs from 'babel-plugin-react-compiler/dist/index.d.ts';
loader.config({monaco});
export default function ConfigEditor({
formattedAppliedConfig,
appliedOptions,
}: {
formattedAppliedConfig: string;
appliedOptions: PluginOptions | null;
}): React.ReactElement {
const [isExpanded, setIsExpanded] = useState(false);
@@ -47,7 +49,7 @@ export default function ConfigEditor({
setIsExpanded(false);
});
}}
formattedAppliedConfig={formattedAppliedConfig}
appliedOptions={appliedOptions}
/>
</div>
<div
@@ -69,10 +71,10 @@ export default function ConfigEditor({
function ExpandedEditor({
onToggle,
formattedAppliedConfig,
appliedOptions,
}: {
onToggle: (expanded: boolean) => void;
formattedAppliedConfig: string;
onToggle: () => void;
appliedOptions: PluginOptions | null;
}): React.ReactElement {
const store = useStore();
const dispatchStore = useStoreDispatch();
@@ -120,6 +122,13 @@ function ExpandedEditor({
});
};
const formattedAppliedOptions = appliedOptions
? prettyFormat(appliedOptions, {
printFunctionName: false,
printBasicPrototype: false,
})
: 'Invalid configs';
return (
<ViewTransition
update={{[CONFIG_PANEL_TRANSITION]: 'slide-in', default: 'none'}}>
@@ -149,7 +158,7 @@ function ExpandedEditor({
Config Overrides
</h2>
</div>
<div className="flex-1 border border-gray-300">
<div className="flex-1 rounded-lg overflow-hidden border border-gray-300">
<MonacoEditor
path={'config.ts'}
language={'typescript'}
@@ -158,7 +167,16 @@ function ExpandedEditor({
onChange={handleChange}
loading={''}
className="monaco-editor-config"
options={monacoConfigOptions}
options={{
...monacoOptions,
lineNumbers: 'off',
renderLineHighlight: 'none',
overviewRulerBorder: false,
overviewRulerLanes: 0,
fontSize: 12,
scrollBeyondLastLine: false,
glyphMargin: false,
}}
/>
</div>
</div>
@@ -168,16 +186,23 @@ function ExpandedEditor({
Applied Configs
</h2>
</div>
<div className="flex-1 border border-gray-300">
<div className="flex-1 rounded-lg overflow-hidden border border-gray-300">
<MonacoEditor
path={'applied-config.js'}
language={'javascript'}
value={formattedAppliedConfig}
value={formattedAppliedOptions}
loading={''}
className="monaco-editor-applied-config"
options={{
...monacoConfigOptions,
...monacoOptions,
lineNumbers: 'off',
renderLineHighlight: 'none',
overviewRulerBorder: false,
overviewRulerLanes: 0,
fontSize: 12,
scrollBeyondLastLine: false,
readOnly: true,
glyphMargin: false,
}}
/>
</div>

View File

@@ -5,17 +5,316 @@
* LICENSE file in the root directory of this source tree.
*/
import {
import {parse as babelParse, ParseResult} from '@babel/parser';
import * as HermesParser from 'hermes-parser';
import * as t from '@babel/types';
import BabelPluginReactCompiler, {
CompilerError,
CompilerErrorDetail,
CompilerDiagnostic,
Effect,
ErrorCategory,
parseConfigPragmaForTests,
ValueKind,
type Hook,
PluginOptions,
CompilerPipelineValue,
parsePluginOptions,
printReactiveFunctionWithOutlined,
printFunctionWithOutlined,
type LoggerEvent,
} from 'babel-plugin-react-compiler';
import {useDeferredValue, useMemo, useState} from 'react';
import {
useDeferredValue,
useMemo,
unstable_ViewTransition as ViewTransition,
} from 'react';
import {useStore} from '../StoreContext';
import ConfigEditor from './ConfigEditor';
import Input from './Input';
import {CompilerOutput, default as Output} from './Output';
import {compile} from '../../lib/compilation';
import prettyFormat from 'pretty-format';
import {
CompilerOutput,
CompilerTransformOutput,
default as Output,
PrintedCompilerPipelineValue,
} from './Output';
import {transformFromAstSync} from '@babel/core';
function parseInput(
input: string,
language: 'flow' | 'typescript',
): ParseResult<t.File> {
// Extract the first line to quickly check for custom test directives
if (language === 'flow') {
return HermesParser.parse(input, {
babel: true,
flow: 'all',
sourceType: 'module',
enableExperimentalComponentSyntax: true,
});
} else {
return babelParse(input, {
plugins: ['typescript', 'jsx'],
sourceType: 'module',
}) as ParseResult<t.File>;
}
}
function invokeCompiler(
source: string,
language: 'flow' | 'typescript',
options: PluginOptions,
): CompilerTransformOutput {
const ast = parseInput(source, language);
let result = transformFromAstSync(ast, source, {
filename: '_playgroundFile.js',
highlightCode: false,
retainLines: true,
plugins: [[BabelPluginReactCompiler, options]],
ast: true,
sourceType: 'module',
configFile: false,
sourceMaps: true,
babelrc: false,
});
if (result?.ast == null || result?.code == null || result?.map == null) {
throw new Error('Expected successful compilation');
}
return {
code: result.code,
sourceMaps: result.map,
language,
};
}
const COMMON_HOOKS: Array<[string, Hook]> = [
[
'useFragment',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'usePaginationFragment',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'useRefetchableFragment',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'useLazyLoadQuery',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'usePreloadedQuery',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
];
function parseOptions(
source: string,
mode: 'compiler' | 'linter',
configOverrides: string,
): PluginOptions {
// Extract the first line to quickly check for custom test directives
const pragma = source.substring(0, source.indexOf('\n'));
const parsedPragmaOptions = parseConfigPragmaForTests(pragma, {
compilationMode: 'infer',
environment:
mode === 'linter'
? {
// enabled in compiler
validateRefAccessDuringRender: false,
// enabled in linter
validateNoSetStateInRender: true,
validateNoSetStateInEffects: true,
validateNoJSXInTryStatements: true,
validateNoImpureFunctionsInRender: true,
validateStaticComponents: true,
validateNoFreezingKnownMutableFunctions: true,
validateNoVoidUseMemo: true,
}
: {
/* use defaults for compiler mode */
},
});
// Parse config overrides from config editor
let configOverrideOptions: any = {};
const configMatch = configOverrides.match(/^\s*import.*?\n\n\((.*)\)/s);
if (configOverrides.trim()) {
if (configMatch && configMatch[1]) {
const configString = configMatch[1].replace(/satisfies.*$/, '').trim();
configOverrideOptions = new Function(`return (${configString})`)();
} else {
throw new Error('Invalid override format');
}
}
const opts: PluginOptions = parsePluginOptions({
...parsedPragmaOptions,
...configOverrideOptions,
environment: {
...parsedPragmaOptions.environment,
...configOverrideOptions.environment,
customHooks: new Map([...COMMON_HOOKS]),
},
});
return opts;
}
function compile(
source: string,
mode: 'compiler' | 'linter',
configOverrides: string,
): [CompilerOutput, 'flow' | 'typescript', PluginOptions | null] {
const results = new Map<string, Array<PrintedCompilerPipelineValue>>();
const error = new CompilerError();
const otherErrors: Array<CompilerErrorDetail | CompilerDiagnostic> = [];
const upsert: (result: PrintedCompilerPipelineValue) => void = result => {
const entry = results.get(result.name);
if (Array.isArray(entry)) {
entry.push(result);
} else {
results.set(result.name, [result]);
}
};
let language: 'flow' | 'typescript';
if (source.match(/\@flow/)) {
language = 'flow';
} else {
language = 'typescript';
}
let transformOutput;
let baseOpts: PluginOptions | null = null;
try {
baseOpts = parseOptions(source, mode, configOverrides);
} catch (err) {
error.details.push(
new CompilerErrorDetail({
category: ErrorCategory.Config,
reason: `Unexpected failure when transforming configs! \n${err}`,
loc: null,
suggestions: null,
}),
);
}
if (baseOpts) {
try {
const logIR = (result: CompilerPipelineValue): void => {
switch (result.kind) {
case 'ast': {
break;
}
case 'hir': {
upsert({
kind: 'hir',
fnName: result.value.id,
name: result.name,
value: printFunctionWithOutlined(result.value),
});
break;
}
case 'reactive': {
upsert({
kind: 'reactive',
fnName: result.value.id,
name: result.name,
value: printReactiveFunctionWithOutlined(result.value),
});
break;
}
case 'debug': {
upsert({
kind: 'debug',
fnName: null,
name: result.name,
value: result.value,
});
break;
}
default: {
const _: never = result;
throw new Error(`Unhandled result ${result}`);
}
}
};
// Add logger options to the parsed options
const opts = {
...baseOpts,
logger: {
debugLogIRs: logIR,
logEvent: (_filename: string | null, event: LoggerEvent): void => {
if (event.kind === 'CompileError') {
otherErrors.push(event.detail);
}
},
},
};
transformOutput = invokeCompiler(source, language, opts);
} catch (err) {
/**
* error might be an invariant violation or other runtime error
* (i.e. object shape that is not CompilerError)
*/
if (err instanceof CompilerError && err.details.length > 0) {
error.merge(err);
} else {
/**
* Handle unexpected failures by logging (to get a stack trace)
* and reporting
*/
error.details.push(
new CompilerErrorDetail({
category: ErrorCategory.Invariant,
reason: `Unexpected failure when transforming input! \n${err}`,
loc: null,
suggestions: null,
}),
);
}
}
}
// Only include logger errors if there weren't other errors
if (!error.hasErrors() && otherErrors.length !== 0) {
otherErrors.forEach(e => error.details.push(e));
}
if (error.hasErrors()) {
return [{kind: 'err', results, error}, language, baseOpts];
}
return [
{kind: 'ok', results, transformOutput, errors: error.details},
language,
baseOpts,
];
}
export default function Editor(): JSX.Element {
const store = useStore();
@@ -28,7 +327,6 @@ export default function Editor(): JSX.Element {
() => compile(deferredStore.source, 'linter', deferredStore.config),
[deferredStore.source, deferredStore.config],
);
const [formattedAppliedConfig, setFormattedAppliedConfig] = useState('');
let mergedOutput: CompilerOutput;
let errors: Array<CompilerErrorDetail | CompilerDiagnostic>;
@@ -42,22 +340,11 @@ export default function Editor(): JSX.Element {
mergedOutput = compilerOutput;
errors = compilerOutput.error.details;
}
if (appliedOptions) {
const formatted = prettyFormat(appliedOptions, {
printFunctionName: false,
printBasicPrototype: false,
});
if (formatted !== formattedAppliedConfig) {
setFormattedAppliedConfig(formatted);
}
}
return (
<>
<div className="relative flex top-14">
<div className="flex-shrink-0">
<ConfigEditor formattedAppliedConfig={formattedAppliedConfig} />
<ConfigEditor appliedOptions={appliedOptions} />
</div>
<div className="flex flex-1 min-w-0">
<Input language={language} errors={errors} />

View File

@@ -27,8 +27,6 @@ import {
useState,
Suspense,
unstable_ViewTransition as ViewTransition,
unstable_addTransitionType as addTransitionType,
startTransition,
} from 'react';
import AccordionWindow from '../AccordionWindow';
import TabbedWindow from '../TabbedWindow';
@@ -37,7 +35,6 @@ import {BabelFileResult} from '@babel/core';
import {
CONFIG_PANEL_TRANSITION,
TOGGLE_INTERNALS_TRANSITION,
EXPAND_ACCORDION_TRANSITION,
} from '../../lib/transitionTypes';
import {LRUCache} from 'lru-cache';
@@ -271,19 +268,11 @@ function OutputContent({store, compilerOutput}: Props): JSX.Element {
const [previousOutputKind, setPreviousOutputKind] = useState(
compilerOutput.kind,
);
const isFailure = compilerOutput.kind !== 'ok';
if (compilerOutput.kind !== previousOutputKind) {
setPreviousOutputKind(compilerOutput.kind);
if (isFailure) {
startTransition(() => {
addTransitionType(EXPAND_ACCORDION_TRANSITION);
setTabsOpen(prev => new Set(prev).add('Output'));
setActiveTab('Output');
});
}
setTabsOpen(new Set(['Output']));
setActiveTab('Output');
}
const changedPasses: Set<string> = new Set(['Output', 'HIR']); // Initial and final passes should always be bold
let lastResult: string = '';
for (const [passName, results] of compilerOutput.results) {
@@ -386,18 +375,12 @@ function TextTabContent({
loading={''}
options={{
...monacoOptions,
scrollbar: {
vertical: 'hidden',
},
dimension: {
width: 0,
height: 0,
},
readOnly: true,
lineNumbers: 'off',
glyphMargin: false,
// Undocumented see https://github.com/Microsoft/vscode/issues/30795#issuecomment-410998882
overviewRulerLanes: 0,
lineDecorationsWidth: 0,
lineNumbersMinChars: 0,
}}
/>
) : (

View File

@@ -32,14 +32,3 @@ export const monacoOptions: Partial<EditorProps['options']> = {
tabSize: 2,
};
export const monacoConfigOptions: Partial<EditorProps['options']> = {
...monacoOptions,
lineNumbers: 'off',
renderLineHighlight: 'none',
overviewRulerBorder: false,
overviewRulerLanes: 0,
fontSize: 12,
scrollBeyondLastLine: false,
glyphMargin: false,
};

View File

@@ -49,8 +49,6 @@ export default function TabbedWindow({
{isActive && (
<ViewTransition
name={transitionName}
enter={{default: 'none'}}
exit={{default: 'none'}}
share={{
[TOGGLE_TAB_TRANSITION]: 'tab-highlight',
default: 'none',
@@ -60,8 +58,6 @@ export default function TabbedWindow({
</ViewTransition>
)}
<ViewTransition
enter={{default: 'none'}}
exit={{default: 'none'}}
update={{
[TOGGLE_TAB_TRANSITION]: 'tab-text',
default: 'none',

View File

@@ -1,308 +0,0 @@
/**
* 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.
*/
import {parse as babelParse, ParseResult} from '@babel/parser';
import * as HermesParser from 'hermes-parser';
import * as t from '@babel/types';
import BabelPluginReactCompiler, {
CompilerError,
CompilerErrorDetail,
CompilerDiagnostic,
Effect,
ErrorCategory,
parseConfigPragmaForTests,
ValueKind,
type Hook,
PluginOptions,
CompilerPipelineValue,
parsePluginOptions,
printReactiveFunctionWithOutlined,
printFunctionWithOutlined,
type LoggerEvent,
} from 'babel-plugin-react-compiler';
import {transformFromAstSync} from '@babel/core';
import type {
CompilerOutput,
CompilerTransformOutput,
PrintedCompilerPipelineValue,
} from '../components/Editor/Output';
function parseInput(
input: string,
language: 'flow' | 'typescript',
): ParseResult<t.File> {
// Extract the first line to quickly check for custom test directives
if (language === 'flow') {
return HermesParser.parse(input, {
babel: true,
flow: 'all',
sourceType: 'module',
enableExperimentalComponentSyntax: true,
});
} else {
return babelParse(input, {
plugins: ['typescript', 'jsx'],
sourceType: 'module',
}) as ParseResult<t.File>;
}
}
function invokeCompiler(
source: string,
language: 'flow' | 'typescript',
options: PluginOptions,
): CompilerTransformOutput {
const ast = parseInput(source, language);
let result = transformFromAstSync(ast, source, {
filename: '_playgroundFile.js',
highlightCode: false,
retainLines: true,
plugins: [[BabelPluginReactCompiler, options]],
ast: true,
sourceType: 'module',
configFile: false,
sourceMaps: true,
babelrc: false,
});
if (result?.ast == null || result?.code == null || result?.map == null) {
throw new Error('Expected successful compilation');
}
return {
code: result.code,
sourceMaps: result.map,
language,
};
}
const COMMON_HOOKS: Array<[string, Hook]> = [
[
'useFragment',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'usePaginationFragment',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'useRefetchableFragment',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'useLazyLoadQuery',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
[
'usePreloadedQuery',
{
valueKind: ValueKind.Frozen,
effectKind: Effect.Freeze,
noAlias: true,
transitiveMixedData: true,
},
],
];
function parseOptions(
source: string,
mode: 'compiler' | 'linter',
configOverrides: string,
): PluginOptions {
// Extract the first line to quickly check for custom test directives
const pragma = source.substring(0, source.indexOf('\n'));
const parsedPragmaOptions = parseConfigPragmaForTests(pragma, {
compilationMode: 'infer',
environment:
mode === 'linter'
? {
// enabled in compiler
validateRefAccessDuringRender: false,
// enabled in linter
validateNoSetStateInRender: true,
validateNoSetStateInEffects: true,
validateNoJSXInTryStatements: true,
validateNoImpureFunctionsInRender: true,
validateStaticComponents: true,
validateNoFreezingKnownMutableFunctions: true,
validateNoVoidUseMemo: true,
}
: {
/* use defaults for compiler mode */
},
});
// Parse config overrides from config editor
let configOverrideOptions: any = {};
const configMatch = configOverrides.match(/^\s*import.*?\n\n\((.*)\)/s);
if (configOverrides.trim()) {
if (configMatch && configMatch[1]) {
const configString = configMatch[1].replace(/satisfies.*$/, '').trim();
configOverrideOptions = new Function(`return (${configString})`)();
} else {
throw new Error('Invalid override format');
}
}
const opts: PluginOptions = parsePluginOptions({
...parsedPragmaOptions,
...configOverrideOptions,
environment: {
...parsedPragmaOptions.environment,
...configOverrideOptions.environment,
customHooks: new Map([...COMMON_HOOKS]),
},
});
return opts;
}
export function compile(
source: string,
mode: 'compiler' | 'linter',
configOverrides: string,
): [CompilerOutput, 'flow' | 'typescript', PluginOptions | null] {
const results = new Map<string, Array<PrintedCompilerPipelineValue>>();
const error = new CompilerError();
const otherErrors: Array<CompilerErrorDetail | CompilerDiagnostic> = [];
const upsert: (result: PrintedCompilerPipelineValue) => void = result => {
const entry = results.get(result.name);
if (Array.isArray(entry)) {
entry.push(result);
} else {
results.set(result.name, [result]);
}
};
let language: 'flow' | 'typescript';
if (source.match(/\@flow/)) {
language = 'flow';
} else {
language = 'typescript';
}
let transformOutput;
let baseOpts: PluginOptions | null = null;
try {
baseOpts = parseOptions(source, mode, configOverrides);
} catch (err) {
error.details.push(
new CompilerErrorDetail({
category: ErrorCategory.Config,
reason: `Unexpected failure when transforming configs! \n${err}`,
loc: null,
suggestions: null,
}),
);
}
if (baseOpts) {
try {
const logIR = (result: CompilerPipelineValue): void => {
switch (result.kind) {
case 'ast': {
break;
}
case 'hir': {
upsert({
kind: 'hir',
fnName: result.value.id,
name: result.name,
value: printFunctionWithOutlined(result.value),
});
break;
}
case 'reactive': {
upsert({
kind: 'reactive',
fnName: result.value.id,
name: result.name,
value: printReactiveFunctionWithOutlined(result.value),
});
break;
}
case 'debug': {
upsert({
kind: 'debug',
fnName: null,
name: result.name,
value: result.value,
});
break;
}
default: {
const _: never = result;
throw new Error(`Unhandled result ${result}`);
}
}
};
// Add logger options to the parsed options
const opts = {
...baseOpts,
logger: {
debugLogIRs: logIR,
logEvent: (_filename: string | null, event: LoggerEvent): void => {
if (event.kind === 'CompileError') {
otherErrors.push(event.detail);
}
},
},
};
transformOutput = invokeCompiler(source, language, opts);
} catch (err) {
/**
* error might be an invariant violation or other runtime error
* (i.e. object shape that is not CompilerError)
*/
if (err instanceof CompilerError && err.details.length > 0) {
error.merge(err);
} else {
/**
* Handle unexpected failures by logging (to get a stack trace)
* and reporting
*/
error.details.push(
new CompilerErrorDetail({
category: ErrorCategory.Invariant,
reason: `Unexpected failure when transforming input! \n${err}`,
loc: null,
suggestions: null,
}),
);
}
}
}
// Only include logger errors if there weren't other errors
if (!error.hasErrors() && otherErrors.length !== 0) {
otherErrors.forEach(e => error.details.push(e));
}
if (error.hasErrors() || !transformOutput) {
return [{kind: 'err', results, error}, language, baseOpts];
}
return [
{kind: 'ok', results, transformOutput, errors: error.details},
language,
baseOpts,
];
}

View File

@@ -124,11 +124,3 @@
::view-transition-group(.expand-accordion) {
overflow: clip;
}
/**
* For some reason, the original Monaco editor is still visible to the
* left of the DiffEditor. This is a workaround for better visual clarity.
*/
.monaco-diff-editor .editor.original{
visibility: hidden !important;
}

View File

@@ -52,8 +52,8 @@
"react-dom": "0.0.0-experimental-4beb1fd8-20241118",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.2",
"zod": "^3.22.4 || ^4.0.0",
"zod-validation-error": "^3.0.3 || ^4.0.0"
"zod": "^3.22.4",
"zod-validation-error": "^2.1.0"
},
"resolutions": {
"./**/@babel/parser": "7.7.4",

View File

@@ -536,8 +536,7 @@ function printErrorSummary(category: ErrorCategory, message: string): string {
case ErrorCategory.StaticComponents:
case ErrorCategory.Suppression:
case ErrorCategory.Syntax:
case ErrorCategory.UseMemo:
case ErrorCategory.VoidUseMemo: {
case ErrorCategory.UseMemo: {
heading = 'Error';
break;
}
@@ -583,10 +582,6 @@ export enum ErrorCategory {
* Checking for valid usage of manual memoization
*/
UseMemo = 'UseMemo',
/**
* Checking that useMemos always return a value
*/
VoidUseMemo = 'VoidUseMemo',
/**
* Checking for higher order functions acting as factories for components/hooks
*/
@@ -674,21 +669,6 @@ export enum ErrorCategory {
FBT = 'FBT',
}
export enum LintRulePreset {
/**
* Rules that are stable and included in the `recommended` preset.
*/
Recommended = 'recommended',
/**
* Rules that are more experimental and only included in the `recommended-latest` preset.
*/
RecommendedLatest = 'recommended-latest',
/**
* Rules that are disabled.
*/
Off = 'off',
}
export type LintRule = {
// Stores the category the rule corresponds to, used to filter errors when reporting
category: ErrorCategory;
@@ -709,14 +689,15 @@ export type LintRule = {
description: string;
/**
* Configures the preset in which the rule is enabled. If 'off', the rule will not be included in
* any preset.
* If true, this rule will automatically appear in the default, "recommended" ESLint
* rule set. Otherwise it will be part of an `allRules` export that developers can
* use to opt-in to showing output of all possible rules.
*
* NOTE: not all validations are enabled by default! Setting this flag only affects
* whether a given rule is part of the recommended set. The corresponding validation
* also should be enabled by default if you want the error to actually show up!
*/
preset: LintRulePreset;
recommended: boolean;
};
const RULE_NAME_PATTERN = /^[a-z]+(-[a-z]+)*$/;
@@ -739,7 +720,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'automatic-effect-dependencies',
description:
'Verifies that automatic effect dependencies are compiled if opted-in',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.CapitalizedCalls: {
@@ -749,7 +730,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'capitalized-calls',
description:
'Validates against calling capitalized functions/methods instead of using JSX',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.Config: {
@@ -758,7 +739,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Error,
name: 'config',
description: 'Validates the compiler configuration options',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.EffectDependencies: {
@@ -767,7 +748,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Error,
name: 'memoized-effect-dependencies',
description: 'Validates that effect dependencies are memoized',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.EffectDerivationsOfState: {
@@ -777,7 +758,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'no-deriving-state-in-effects',
description:
'Validates against deriving values from state in an effect',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.EffectSetState: {
@@ -787,7 +768,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'set-state-in-effect',
description:
'Validates against calling setState synchronously in an effect, which can lead to re-renders that degrade performance',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.ErrorBoundaries: {
@@ -797,7 +778,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'error-boundaries',
description:
'Validates usage of error boundaries instead of try/catch for errors in child components',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.Factories: {
@@ -808,7 +789,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
description:
'Validates against higher order functions defining nested components or hooks. ' +
'Components and hooks should be defined at the module level',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.FBT: {
@@ -817,7 +798,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Error,
name: 'fbt',
description: 'Validates usage of fbt',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.Fire: {
@@ -826,7 +807,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Error,
name: 'fire',
description: 'Validates usage of `fire`',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.Gating: {
@@ -836,7 +817,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'gating',
description:
'Validates configuration of [gating mode](https://react.dev/reference/react-compiler/gating)',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.Globals: {
@@ -847,7 +828,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
description:
'Validates against assignment/mutation of globals during render, part of ensuring that ' +
'[side effects must render outside of render](https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.Hooks: {
@@ -861,7 +842,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
* We need to dedeupe these (moving the remaining bits into the compiler) and then enable
* this rule.
*/
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.Immutability: {
@@ -871,7 +852,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'immutability',
description:
'Validates against mutating props, state, and other values that [are immutable](https://react.dev/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable)',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.Invariant: {
@@ -880,7 +861,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Error,
name: 'invariant',
description: 'Internal invariants',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.PreserveManualMemo: {
@@ -892,7 +873,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
'Validates that existing manual memoized is preserved by the compiler. ' +
'React Compiler will only compile components and hooks if its inference ' +
'[matches or exceeds the existing manual memoization](https://react.dev/learn/react-compiler/introduction#what-should-i-do-about-usememo-usecallback-and-reactmemo)',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.Purity: {
@@ -902,7 +883,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'purity',
description:
'Validates that [components/hooks are pure](https://react.dev/reference/rules/components-and-hooks-must-be-pure) by checking that they do not call known-impure functions',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.Refs: {
@@ -912,7 +893,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'refs',
description:
'Validates correct usage of refs, not reading/writing during render. See the "pitfalls" section in [`useRef()` usage](https://react.dev/reference/react/useRef#usage)',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.RenderSetState: {
@@ -922,7 +903,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'set-state-in-render',
description:
'Validates against setting state during render, which can trigger additional renders and potential infinite render loops',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.StaticComponents: {
@@ -932,7 +913,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'static-components',
description:
'Validates that components are static, not recreated every render. Components that are recreated dynamically can reset state and trigger excessive re-rendering',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.Suppression: {
@@ -941,7 +922,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Error,
name: 'rule-suppression',
description: 'Validates against suppression of other rules',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.Syntax: {
@@ -950,7 +931,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Error,
name: 'syntax',
description: 'Validates against invalid syntax',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.Todo: {
@@ -959,7 +940,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
severity: ErrorSeverity.Hint,
name: 'todo',
description: 'Unimplemented features',
preset: LintRulePreset.Off,
recommended: false,
};
}
case ErrorCategory.UnsupportedSyntax: {
@@ -969,7 +950,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'unsupported-syntax',
description:
'Validates against syntax that we do not plan to support in React Compiler',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
case ErrorCategory.UseMemo: {
@@ -979,17 +960,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'use-memo',
description:
'Validates usage of the useMemo() hook against common mistakes. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.',
preset: LintRulePreset.Recommended,
};
}
case ErrorCategory.VoidUseMemo: {
return {
category,
severity: ErrorSeverity.Error,
name: 'void-use-memo',
description:
'Validates that useMemos always return a value. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.',
preset: LintRulePreset.RecommendedLatest,
recommended: true,
};
}
case ErrorCategory.IncompatibleLibrary: {
@@ -999,7 +970,7 @@ function getRuleForCategoryImpl(category: ErrorCategory): LintRule {
name: 'incompatible-library',
description:
'Validates against usage of libraries which are incompatible with memoization (manual or automatic)',
preset: LintRulePreset.Recommended,
recommended: true,
};
}
default: {

View File

@@ -454,32 +454,6 @@ function collectNonNullsInBlocks(
assumedNonNullObjects.add(entry);
}
}
} else if (
fn.env.config.enablePreserveExistingMemoizationGuarantees &&
instr.value.kind === 'StartMemoize' &&
instr.value.deps != null
) {
for (const dep of instr.value.deps) {
if (dep.root.kind === 'NamedLocal') {
if (
!isImmutableAtInstr(dep.root.value.identifier, instr.id, context)
) {
continue;
}
for (let i = 0; i < dep.path.length; i++) {
const pathEntry = dep.path[i]!;
if (pathEntry.optional) {
break;
}
const depNode = context.registry.getOrCreateProperty({
identifier: dep.root.value.identifier,
path: dep.path.slice(0, i),
reactive: dep.root.value.reactive,
});
assumedNonNullObjects.add(depNode);
}
}
}
}
}

View File

@@ -159,7 +159,7 @@ export const EnvironmentConfigSchema = z.object({
* A function that, given the name of a module, can optionally return a description
* of that module's type signature.
*/
moduleTypeProvider: z.nullable(z.any()).default(null),
moduleTypeProvider: z.nullable(z.function().args(z.string())).default(null),
/**
* A list of functions which the application compiles as macros, where
@@ -210,7 +210,7 @@ export const EnvironmentConfigSchema = z.object({
* that if a useEffect or useCallback references a function value, that function value will be
* considered frozen, and in turn all of its referenced variables will be considered frozen as well.
*/
enablePreserveExistingMemoizationGuarantees: z.boolean().default(true),
enablePreserveExistingMemoizationGuarantees: z.boolean().default(false),
/**
* Validates that all useMemo/useCallback values are also memoized by Forget. This mode can be
@@ -249,7 +249,7 @@ export const EnvironmentConfigSchema = z.object({
* Allows specifying a function that can populate HIR with type information from
* Flow
*/
flowTypeProvider: z.nullable(z.any()).default(null),
flowTypeProvider: z.nullable(z.function().args(z.string())).default(null),
/**
* Enables inference of optional dependency chains. Without this flag
@@ -906,12 +906,6 @@ export class Environment {
if (moduleTypeProvider == null) {
return null;
}
if (typeof moduleTypeProvider !== 'function') {
CompilerError.throwInvalidConfig({
reason: `Expected a function for \`moduleTypeProvider\``,
loc,
});
}
const unparsedModuleConfig = moduleTypeProvider(moduleName);
if (unparsedModuleConfig != null) {
const parsedModuleConfig = TypeSchema.safeParse(unparsedModuleConfig);

View File

@@ -454,7 +454,7 @@ export function dropManualMemoization(
if (!hasNonVoidReturn(funcToCheck.loweredFunc.func)) {
errors.pushDiagnostic(
CompilerDiagnostic.create({
category: ErrorCategory.VoidUseMemo,
category: ErrorCategory.UseMemo,
reason: 'useMemo() callbacks must return a value',
description: `This ${
manualMemo.loadInstr.value.kind === 'PropertyLoad'

View File

@@ -393,7 +393,7 @@ function* generateInstructionTypes(
shapeId: BuiltInArrayId,
});
} else {
continue;
break;
}
}
} else {

View File

@@ -20,7 +20,7 @@ describe('parseConfigPragma()', () => {
validateHooksUsage: 1,
} as any);
}).toThrowErrorMatchingInlineSnapshot(
`"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: Invalid input: expected boolean, received number at "validateHooksUsage"."`,
`"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: Expected boolean, received number at "validateHooksUsage"."`,
);
});
@@ -38,7 +38,7 @@ describe('parseConfigPragma()', () => {
],
} as any);
}).toThrowErrorMatchingInlineSnapshot(
`"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: AutodepsIndex must be > 0 at "inferEffectDependencies[0].autodepsIndex"."`,
`"Error: Could not validate environment config. Update React Compiler config to fix the error. Validation error: autodepsIndex must be > 0 at "inferEffectDependencies[0].autodepsIndex"."`,
);
});

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
// bar(props.b) is an allocating expression that produces a primitive, which means
// that Forget should memoize it.
// Correctness:
@@ -17,8 +16,7 @@ function AllocatingPrimitiveAsDep(props) {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
// bar(props.b) is an allocating expression that produces a primitive, which means
import { c as _c } from "react/compiler-runtime"; // bar(props.b) is an allocating expression that produces a primitive, which means
// that Forget should memoize it.
// Correctness:
// - y depends on either bar(props.b) or bar(props.b) + 1

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
// bar(props.b) is an allocating expression that produces a primitive, which means
// that Forget should memoize it.
// Correctness:

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
const someGlobal = {value: 0};
@@ -33,7 +32,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
const someGlobal = { value: 0 };

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
const someGlobal = {value: 0};

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
function Component(props) {
let a = foo();
// freeze `a` so we know the next line cannot mutate it
@@ -18,7 +17,7 @@ function Component(props) {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
function Component(props) {
const $ = _c(2);
const a = foo();

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
function Component(props) {
let a = foo();
// freeze `a` so we know the next line cannot mutate it

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {Stringify, identity} from 'shared-runtime';
function foo() {
@@ -65,7 +64,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { Stringify, identity } from "shared-runtime";
function foo() {

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {Stringify, identity} from 'shared-runtime';
function foo() {

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {Stringify} from 'shared-runtime';
@@ -26,7 +25,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import { Stringify } from "shared-runtime";

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {Stringify} from 'shared-runtime';

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
function foo(props) {
let x, y;
({x, y} = {x: props.a, y: props.b});
@@ -22,7 +21,6 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
function foo(props) {
let x;
let y;

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
function foo(props) {
let x, y;
({x, y} = {x: props.a, y: props.b});

View File

@@ -1,41 +0,0 @@
## Input
```javascript
function Component(props) {
// Intentionally don't bind state, this repros a bug where we didn't
// infer the type of destructured properties after a hole in the array
let [, setState] = useState();
setState(1);
return props.foo;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: ['TodoAdd'],
isComponent: 'TodoAdd',
};
```
## Error
```
Found 1 error:
Error: Calling setState during render may trigger an infinite loop
Calling setState during render will trigger another render, and can lead to infinite loops. (https://react.dev/reference/react/useState).
error.invalid-setState-in-render-unbound-state.ts:5:2
3 | // infer the type of destructured properties after a hole in the array
4 | let [, setState] = useState();
> 5 | setState(1);
| ^^^^^^^^ Found setState() in render
6 | return props.foo;
7 | }
8 |
```

View File

@@ -1,13 +0,0 @@
function Component(props) {
// Intentionally don't bind state, this repros a bug where we didn't
// infer the type of destructured properties after a hole in the array
let [, setState] = useState();
setState(1);
return props.foo;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: ['TodoAdd'],
isComponent: 'TodoAdd',
};

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @flow @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @flow @enableNewMutationAliasingModel
/**
* This hook returns a function that when called with an input object,
* will return the result of mapping that input with the supplied map

View File

@@ -1,4 +1,4 @@
// @flow @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @flow @enableNewMutationAliasingModel
/**
* This hook returns a function that when called with an input object,
* will return the result of mapping that input with the supplied map

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
/**
* Repro from https://github.com/facebook/react/issues/34262

View File

@@ -1,4 +1,4 @@
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
/**
* Repro from https://github.com/facebook/react/issues/34262

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {identity, Stringify, useHook} from 'shared-runtime';

View File

@@ -1,4 +1,4 @@
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {identity, Stringify, useHook} from 'shared-runtime';

View File

@@ -1,91 +0,0 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x}) {
const object = useMemo(() => {
return identity({
callback: () => {
// This is a bug in our dependency inference: we stop capturing dependencies
// after x.a.b?.c. But what this dependency is telling us is that if `x.a.b`
// was non-nullish, then we can access `.c.d?.e`. Thus we should take the
// full property chain, exactly as-is with optionals/non-optionals, as a
// dependency
return identity(x.a.b?.c.d?.e);
},
});
}, [x.a.b?.c.d?.e]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <Inner x={x} result={result} />;
}
function Inner({x, result}) {
'use no memo';
return <ValidateMemoization inputs={[x.y.z]} output={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{x: {y: {z: 42}}}],
sequentialRenders: [
{x: {y: {z: 42}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
],
};
```
## Error
```
Found 1 error:
Compilation Skipped: Existing memoization could not be preserved
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `x.a.b?.c`, but the source dependencies were [x.a.b?.c.d?.e]. Inferred less specific property than source.
error.todo-preserve-memo-deps-mixed-optional-nonoptional-property-chain.ts:7:25
5 |
6 | function Component({x}) {
> 7 | const object = useMemo(() => {
| ^^^^^^^
> 8 | return identity({
| ^^^^^^^^^^^^^^^^^^^^^
> 9 | callback: () => {
| ^^^^^^^^^^^^^^^^^^^^^
> 10 | // This is a bug in our dependency inference: we stop capturing dependencies
| ^^^^^^^^^^^^^^^^^^^^^
> 11 | // after x.a.b?.c. But what this dependency is telling us is that if `x.a.b`
| ^^^^^^^^^^^^^^^^^^^^^
> 12 | // was non-nullish, then we can access `.c.d?.e`. Thus we should take the
| ^^^^^^^^^^^^^^^^^^^^^
> 13 | // full property chain, exactly as-is with optionals/non-optionals, as a
| ^^^^^^^^^^^^^^^^^^^^^
> 14 | // dependency
| ^^^^^^^^^^^^^^^^^^^^^
> 15 | return identity(x.a.b?.c.d?.e);
| ^^^^^^^^^^^^^^^^^^^^^
> 16 | },
| ^^^^^^^^^^^^^^^^^^^^^
> 17 | });
| ^^^^^^^^^^^^^^^^^^^^^
> 18 | }, [x.a.b?.c.d?.e]);
| ^^^^ Could not preserve existing manual memoization
19 | const result = useMemo(() => {
20 | return [object.callback()];
21 | }, [object]);
```

View File

@@ -1,41 +0,0 @@
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x}) {
const object = useMemo(() => {
return identity({
callback: () => {
// This is a bug in our dependency inference: we stop capturing dependencies
// after x.a.b?.c. But what this dependency is telling us is that if `x.a.b`
// was non-nullish, then we can access `.c.d?.e`. Thus we should take the
// full property chain, exactly as-is with optionals/non-optionals, as a
// dependency
return identity(x.a.b?.c.d?.e);
},
});
}, [x.a.b?.c.d?.e]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <Inner x={x} result={result} />;
}
function Inner({x, result}) {
'use no memo';
return <ValidateMemoization inputs={[x.y.z]} output={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{x: {y: {z: 42}}}],
sequentialRenders: [
{x: {y: {z: 42}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
],
};

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @flow @validatePreserveExistingMemoizationGuarantees
import {useMemo} from 'react';
import {logValue, useFragment, useHook, typedLog} from 'shared-runtime';

View File

@@ -1,4 +1,4 @@
// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @flow @validatePreserveExistingMemoizationGuarantees
import {useMemo} from 'react';
import {logValue, useFragment, useHook, typedLog} from 'shared-runtime';

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @flow @validatePreserveExistingMemoizationGuarantees
import {useFragment} from 'react-relay';
import LogEvent from 'LogEvent';
import {useCallback, useMemo} from 'react';

View File

@@ -1,4 +1,4 @@
// @flow @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @flow @validatePreserveExistingMemoizationGuarantees
import {useFragment} from 'react-relay';
import LogEvent from 'LogEvent';
import {useCallback, useMemo} from 'react';

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {useMemo} from 'react';
import {ValidateMemoization, useHook} from 'shared-runtime';

View File

@@ -1,4 +1,4 @@
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {useMemo} from 'react';
import {ValidateMemoization, useHook} from 'shared-runtime';

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {makeObject_Primitives, Stringify} from 'shared-runtime';
function Component(props) {

View File

@@ -1,4 +1,4 @@
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {makeObject_Primitives, Stringify} from 'shared-runtime';
function Component(props) {

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {makeObject_Primitives, Stringify} from 'shared-runtime';
function Component(props) {

View File

@@ -1,4 +1,4 @@
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {makeObject_Primitives, Stringify} from 'shared-runtime';
function Component(props) {

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo, useState} from 'react';
import {ValidateMemoization} from 'shared-runtime';
@@ -29,7 +28,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c2 } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c2 } from "react/compiler-runtime";
import { useMemo, useState } from "react";
import { ValidateMemoization } from "shared-runtime";

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo, useState} from 'react';
import {ValidateMemoization} from 'shared-runtime';

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import fbt from 'fbt';
/**
@@ -36,7 +35,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import fbt from "fbt";
/**

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import fbt from 'fbt';
/**

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
const {identity, mutate} = require('shared-runtime');
function Component(props) {
@@ -25,7 +24,6 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
const { identity, mutate } = require("shared-runtime");
function Component(props) {

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
const {identity, mutate} = require('shared-runtime');
function Component(props) {

View File

@@ -0,0 +1,35 @@
## Input
```javascript
function t(props) {
let [, setstate] = useState();
setstate(1);
return props.foo;
}
export const FIXTURE_ENTRYPOINT = {
fn: t,
params: ['TodoAdd'],
isComponent: 'TodoAdd',
};
```
## Code
```javascript
function t(props) {
const [, setstate] = useState();
setstate(1);
return props.foo;
}
export const FIXTURE_ENTRYPOINT = {
fn: t,
params: ["TodoAdd"],
isComponent: "TodoAdd",
};
```

View File

@@ -0,0 +1,11 @@
function t(props) {
let [, setstate] = useState();
setstate(1);
return props.foo;
}
export const FIXTURE_ENTRYPOINT = {
fn: t,
params: ['TodoAdd'],
isComponent: 'TodoAdd',
};

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @hookPattern:".*\b(use[^$]+)$" @enablePreserveExistingMemoizationGuarantees:false
// @hookPattern:".*\b(use[^$]+)$"
import * as React from 'react';
import {makeArray, useHook} from 'shared-runtime';
@@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @hookPattern:".*\b(use[^$]+)$" @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime"; // @hookPattern:".*\b(use[^$]+)$"
import * as React from "react";
import { makeArray, useHook } from "shared-runtime";

View File

@@ -1,4 +1,4 @@
// @hookPattern:".*\b(use[^$]+)$" @enablePreserveExistingMemoizationGuarantees:false
// @hookPattern:".*\b(use[^$]+)$"
import * as React from 'react';
import {makeArray, useHook} from 'shared-runtime';

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @debug @enablePreserveExistingMemoizationGuarantees:false
// @debug
function Component(props) {
const x = makeObject();
const y = delete x[props.value];
@@ -14,7 +14,7 @@ function Component(props) {
## Code
```javascript
// @debug @enablePreserveExistingMemoizationGuarantees:false
// @debug
function Component(props) {
const x = makeObject();
const y = delete x[props.value];

View File

@@ -1,4 +1,4 @@
// @debug @enablePreserveExistingMemoizationGuarantees:false
// @debug
function Component(props) {
const x = makeObject();
const y = delete x[props.value];

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
function Component(props) {
const x = makeObject();
const y = delete x.value;
@@ -14,7 +13,6 @@ function Component(props) {
## Code
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
function Component(props) {
const x = makeObject();
const y = delete x.value;

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
function Component(props) {
const x = makeObject();
const y = delete x.value;

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @validatePreserveExistingMemoizationGuarantees @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees @enableNewMutationAliasingModel
import {useCallback} from 'react';
import {makeArray} from 'shared-runtime';

View File

@@ -1,4 +1,4 @@
// @validatePreserveExistingMemoizationGuarantees @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees @enableNewMutationAliasingModel
import {useCallback} from 'react';
import {makeArray} from 'shared-runtime';

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
@@ -33,7 +32,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import { identity, ValidateMemoization } from "shared-runtime";

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
@@ -30,7 +29,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import { identity, ValidateMemoization } from "shared-runtime";

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
mutate,
@@ -50,7 +49,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import {
mutate,

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
mutate,

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,
@@ -42,7 +41,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import {
typedCapture,

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,
@@ -43,7 +42,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import {
typedCapture,

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,
@@ -41,7 +40,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import {
typedCapture,

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,
@@ -37,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import {
typedCapture,

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,

View File

@@ -2,7 +2,6 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,
@@ -41,7 +40,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime";
import { useMemo } from "react";
import {
typedCapture,

View File

@@ -1,4 +1,3 @@
// @enablePreserveExistingMemoizationGuarantees:false
import {useMemo} from 'react';
import {
typedCapture,

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @enableNewMutationAliasingModel
import {useCallback} from 'react';
import {Stringify} from 'shared-runtime';
@@ -36,7 +36,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel
import { useCallback } from "react";
import { Stringify } from "shared-runtime";

View File

@@ -1,4 +1,4 @@
// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @enableNewMutationAliasingModel
import {useCallback} from 'react';
import {Stringify} from 'shared-runtime';

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @enableNewMutationAliasingModel
import {useCallback} from 'react';
import {Stringify} from 'shared-runtime';
@@ -31,7 +31,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel
import { useCallback } from "react";
import { Stringify } from "shared-runtime";

View File

@@ -1,4 +1,4 @@
// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @enableNewMutationAliasingModel
import {useCallback} from 'react';
import {Stringify} from 'shared-runtime';

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @enableNewMutationAliasingModel
import {useMemo} from 'react';
function useFoo(arr1, arr2) {
@@ -27,7 +27,7 @@ export const FIXTURE_ENTRYPOINT = {
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel
import { useMemo } from "react";
function useFoo(arr1, arr2) {

View File

@@ -1,4 +1,4 @@
// @enableNewMutationAliasingModel @enablePreserveExistingMemoizationGuarantees:false
// @enableNewMutationAliasingModel
import {useMemo} from 'react';
function useFoo(arr1, arr2) {

View File

@@ -1,122 +0,0 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x}) {
const object = useMemo(() => {
return identity({
callback: () => {
return identity(x.y.z); // accesses more levels of properties than the manual memo
},
});
// x.y as a manual dep only tells us that x is non-nullable, not that x.y is non-nullable
// we can only take a dep on x.y, not x.y.z
}, [x.y]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <ValidateMemoization inputs={[x.y]} output={result} />;
}
const input1 = {x: {y: {z: 42}}};
const input1b = {x: {y: {z: 42}}};
const input2 = {x: {y: {z: 3.14}}};
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [input1],
sequentialRenders: [
input1,
input1,
input1b, // should reset even though .z didn't change
input1,
input2,
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import { useMemo } from "react";
import { identity, ValidateMemoization } from "shared-runtime";
function Component(t0) {
const $ = _c(11);
const { x } = t0;
let t1;
if ($[0] !== x.y) {
t1 = identity({ callback: () => identity(x.y.z) });
$[0] = x.y;
$[1] = t1;
} else {
t1 = $[1];
}
const object = t1;
let t2;
if ($[2] !== object) {
t2 = object.callback();
$[2] = object;
$[3] = t2;
} else {
t2 = $[3];
}
let t3;
if ($[4] !== t2) {
t3 = [t2];
$[4] = t2;
$[5] = t3;
} else {
t3 = $[5];
}
const result = t3;
let t4;
if ($[6] !== x.y) {
t4 = [x.y];
$[6] = x.y;
$[7] = t4;
} else {
t4 = $[7];
}
let t5;
if ($[8] !== result || $[9] !== t4) {
t5 = <ValidateMemoization inputs={t4} output={result} />;
$[8] = result;
$[9] = t4;
$[10] = t5;
} else {
t5 = $[10];
}
return t5;
}
const input1 = { x: { y: { z: 42 } } };
const input1b = { x: { y: { z: 42 } } };
const input2 = { x: { y: { z: 3.14 } } };
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [input1],
sequentialRenders: [
input1,
input1,
input1b, // should reset even though .z didn't change
input1,
input2,
],
};
```
### Eval output
(kind: ok) <div>{"inputs":[{"z":42}],"output":[42]}</div>
<div>{"inputs":[{"z":42}],"output":[42]}</div>
<div>{"inputs":[{"z":42}],"output":[42]}</div>
<div>{"inputs":[{"z":42}],"output":[42]}</div>
<div>{"inputs":[{"z":3.14}],"output":[3.14]}</div>

View File

@@ -1,35 +0,0 @@
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x}) {
const object = useMemo(() => {
return identity({
callback: () => {
return identity(x.y.z); // accesses more levels of properties than the manual memo
},
});
// x.y as a manual dep only tells us that x is non-nullable, not that x.y is non-nullable
// we can only take a dep on x.y, not x.y.z
}, [x.y]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <ValidateMemoization inputs={[x.y]} output={result} />;
}
const input1 = {x: {y: {z: 42}}};
const input1b = {x: {y: {z: 42}}};
const input2 = {x: {y: {z: 3.14}}};
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [input1],
sequentialRenders: [
input1,
input1,
input1b, // should reset even though .z didn't change
input1,
input2,
],
};

View File

@@ -1,117 +0,0 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x}) {
const object = useMemo(() => {
return identity({
callback: () => {
return identity(x.y.z);
},
});
}, [x.y.z]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <ValidateMemoization inputs={[x.y.z]} output={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{x: {y: {z: 42}}}],
sequentialRenders: [
{x: {y: {z: 42}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import { useMemo } from "react";
import { identity, ValidateMemoization } from "shared-runtime";
function Component(t0) {
const $ = _c(11);
const { x } = t0;
let t1;
if ($[0] !== x.y.z) {
t1 = identity({ callback: () => identity(x.y.z) });
$[0] = x.y.z;
$[1] = t1;
} else {
t1 = $[1];
}
const object = t1;
let t2;
if ($[2] !== object) {
t2 = object.callback();
$[2] = object;
$[3] = t2;
} else {
t2 = $[3];
}
let t3;
if ($[4] !== t2) {
t3 = [t2];
$[4] = t2;
$[5] = t3;
} else {
t3 = $[5];
}
const result = t3;
let t4;
if ($[6] !== x.y.z) {
t4 = [x.y.z];
$[6] = x.y.z;
$[7] = t4;
} else {
t4 = $[7];
}
let t5;
if ($[8] !== result || $[9] !== t4) {
t5 = <ValidateMemoization inputs={t4} output={result} />;
$[8] = result;
$[9] = t4;
$[10] = t5;
} else {
t5 = $[10];
}
return t5;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ x: { y: { z: 42 } } }],
sequentialRenders: [
{ x: { y: { z: 42 } } },
{ x: { y: { z: 42 } } },
{ x: { y: { z: 3.14 } } },
{ x: { y: { z: 42 } } },
{ x: { y: { z: 3.14 } } },
{ x: { y: { z: 42 } } },
],
};
```
### Eval output
(kind: ok) <div>{"inputs":[42],"output":[42]}</div>
<div>{"inputs":[42],"output":[42]}</div>
<div>{"inputs":[3.14],"output":[3.14]}</div>
<div>{"inputs":[42],"output":[42]}</div>
<div>{"inputs":[3.14],"output":[3.14]}</div>
<div>{"inputs":[42],"output":[42]}</div>

View File

@@ -1,31 +0,0 @@
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x}) {
const object = useMemo(() => {
return identity({
callback: () => {
return identity(x.y.z);
},
});
}, [x.y.z]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <ValidateMemoization inputs={[x.y.z]} output={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{x: {y: {z: 42}}}],
sequentialRenders: [
{x: {y: {z: 42}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
],
};

View File

@@ -1,125 +0,0 @@
## Input
```javascript
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x, y, z}) {
const object = useMemo(() => {
return identity({
callback: () => {
return identity(x?.y?.z, y.a?.b, z.a.b?.c);
},
});
}, [x?.y?.z, y.a?.b, z.a.b?.c]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <Inner x={x} result={result} />;
}
function Inner({x, result}) {
'use no memo';
return <ValidateMemoization inputs={[x.y.z]} output={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{x: {y: {z: 42}}}],
sequentialRenders: [
{x: {y: {z: 42}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime"; // @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import { useMemo } from "react";
import { identity, ValidateMemoization } from "shared-runtime";
function Component(t0) {
const $ = _c(11);
const { x, y, z } = t0;
x?.y?.z;
y.a?.b;
z.a.b?.c;
let t1;
if ($[0] !== x?.y?.z || $[1] !== y.a?.b || $[2] !== z.a.b?.c) {
t1 = identity({ callback: () => identity(x?.y?.z, y.a?.b, z.a.b?.c) });
$[0] = x?.y?.z;
$[1] = y.a?.b;
$[2] = z.a.b?.c;
$[3] = t1;
} else {
t1 = $[3];
}
const object = t1;
let t2;
if ($[4] !== object) {
t2 = object.callback();
$[4] = object;
$[5] = t2;
} else {
t2 = $[5];
}
let t3;
if ($[6] !== t2) {
t3 = [t2];
$[6] = t2;
$[7] = t3;
} else {
t3 = $[7];
}
const result = t3;
let t4;
if ($[8] !== result || $[9] !== x) {
t4 = <Inner x={x} result={result} />;
$[8] = result;
$[9] = x;
$[10] = t4;
} else {
t4 = $[10];
}
return t4;
}
function Inner({ x, result }) {
"use no memo";
return <ValidateMemoization inputs={[x.y.z]} output={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ x: { y: { z: 42 } } }],
sequentialRenders: [
{ x: { y: { z: 42 } } },
{ x: { y: { z: 42 } } },
{ x: { y: { z: 3.14 } } },
{ x: { y: { z: 42 } } },
{ x: { y: { z: 3.14 } } },
{ x: { y: { z: 42 } } },
],
};
```
### Eval output
(kind: ok) [[ (exception in render) TypeError: Cannot read properties of undefined (reading 'a') ]]
[[ (exception in render) TypeError: Cannot read properties of undefined (reading 'a') ]]
[[ (exception in render) TypeError: Cannot read properties of undefined (reading 'a') ]]
[[ (exception in render) TypeError: Cannot read properties of undefined (reading 'a') ]]
[[ (exception in render) TypeError: Cannot read properties of undefined (reading 'a') ]]
[[ (exception in render) TypeError: Cannot read properties of undefined (reading 'a') ]]

View File

@@ -1,36 +0,0 @@
// @enablePreserveExistingMemoizationGuarantees @validatePreserveExistingMemoizationGuarantees @enableOptionalDependencies @enableTreatFunctionDepsAsConditional:false
import {useMemo} from 'react';
import {identity, ValidateMemoization} from 'shared-runtime';
function Component({x, y, z}) {
const object = useMemo(() => {
return identity({
callback: () => {
return identity(x?.y?.z, y.a?.b, z.a.b?.c);
},
});
}, [x?.y?.z, y.a?.b, z.a.b?.c]);
const result = useMemo(() => {
return [object.callback()];
}, [object]);
return <Inner x={x} result={result} />;
}
function Inner({x, result}) {
'use no memo';
return <ValidateMemoization inputs={[x.y.z]} output={result} />;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{x: {y: {z: 42}}}],
sequentialRenders: [
{x: {y: {z: 42}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
{x: {y: {z: 3.14}}},
{x: {y: {z: 42}}},
],
};

View File

@@ -2,7 +2,7 @@
## Input
```javascript
// @validatePreserveExistingMemoizationGuarantees @enablePreserveExistingMemoizationGuarantees:false
// @validatePreserveExistingMemoizationGuarantees
import {useMemo} from 'react';
import {identity} from 'shared-runtime';

Some files were not shown because too many files have changed in this diff Show More