From 453f5052569dafb52e82e875a8976cf348ed16d4 Mon Sep 17 00:00:00 2001 From: Szymon Chmal Date: Tue, 14 Jan 2025 21:23:42 +0100 Subject: [PATCH 1/4] [DevTools] Prevent crash when starting consecutive profiling sessions (#32066) ## Summary This pull request resolves an issue where consecutive profiling sessions would cause Dev Tools to freeze due to an infinite loop of state updates. The problem occurs when the startProfiling function triggers a call to [`selectCommitIndex(0)` in SnapshotSelector](https://github.com/facebook/react/blob/b3a95caf61bc716fb618997e6e9f3a0c8c9c8374/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotSelector.js#L77-L85) as previous profiling data is available, which causes a re-render. Then, [ProfilerContextProvider calls `selectCommitIndex(null)`](https://github.com/facebook/react/blob/b3a95caf61bc716fb618997e6e9f3a0c8c9c8374/packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js#L231-L241) to clear the view while profiling is in progress, leading to another re-render and creating an infinite loop. This behavior was prevented by clearing the existing profiling data before starting a new session. Closes #31977 Closes #31679 ## How did you test this change? I ran the Dev Tools locally following [the contributing guideline](https://github.com/facebook/react/blob/b3a95caf61bc716fb618997e6e9f3a0c8c9c8374/packages/react-devtools/CONTRIBUTING.md). I observed the freeze at the start of the second profiling session. Then, I modified the code to clear the store when starting a new session and ran the Dev Tools again. This time, no freeze was observed. Before: https://github.com/user-attachments/assets/9d790f84-f6d0-4951-8202-e599cf8d225b After: https://github.com/user-attachments/assets/af097019-0b8f-49dd-8afc-0f6cd72af787 --- packages/react-devtools-shared/src/devtools/ProfilerStore.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/react-devtools-shared/src/devtools/ProfilerStore.js b/packages/react-devtools-shared/src/devtools/ProfilerStore.js index b9bbdb11df5..33240bd77f3 100644 --- a/packages/react-devtools-shared/src/devtools/ProfilerStore.js +++ b/packages/react-devtools-shared/src/devtools/ProfilerStore.js @@ -191,6 +191,8 @@ export default class ProfilerStore extends EventEmitter<{ } startProfiling(): void { + this.clear(); + this._bridge.send('startProfiling', { recordChangeDescriptions: this._store.recordChangeDescriptions, recordTimeline: this._store.supportsTimeline, From f9f17f6c8d1e747a3e242b36aa35feae31c55f75 Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Tue, 14 Jan 2025 22:59:52 +0100 Subject: [PATCH 2/4] [Fizz] Restore `useMemoCache` in renderers with support for Client APIs (#32067) --- packages/react-reconciler/src/ReactInternalTypes.js | 2 +- packages/react-server/src/ReactFizzHooks.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/ReactInternalTypes.js b/packages/react-reconciler/src/ReactInternalTypes.js index 859da37cadf..7a6766f5c92 100644 --- a/packages/react-reconciler/src/ReactInternalTypes.js +++ b/packages/react-reconciler/src/ReactInternalTypes.js @@ -430,7 +430,7 @@ export type Dispatcher = { ): T, useId(): string, useCacheRefresh?: () => (?() => T, ?T) => void, - useMemoCache?: (size: number) => Array, + useMemoCache: (size: number) => Array, useHostTransitionStatus: () => TransitionStatus, useOptimistic: ( passthrough: S, diff --git a/packages/react-server/src/ReactFizzHooks.js b/packages/react-server/src/ReactFizzHooks.js index 83f51c6fb24..d346bdff0c5 100644 --- a/packages/react-server/src/ReactFizzHooks.js +++ b/packages/react-server/src/ReactFizzHooks.js @@ -834,6 +834,7 @@ export const HooksDispatcher: Dispatcher = supportsClientAPIs useActionState, useFormState: useActionState, useHostTransitionStatus, + useMemoCache, } : { readContext, From f0edf41e3ee00fbc97873b72b66d62d0f26185b1 Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Wed, 15 Jan 2025 00:29:37 +0100 Subject: [PATCH 3/4] Fix Flight fixture CI (#32070) --- fixtures/flight/package.json | 2 +- fixtures/flight/yarn.lock | 75 ++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/fixtures/flight/package.json b/fixtures/flight/package.json index f9b8a752d4f..62910097cca 100644 --- a/fixtures/flight/package.json +++ b/fixtures/flight/package.json @@ -65,7 +65,7 @@ "webpack-manifest-plugin": "^4.0.2" }, "devDependencies": { - "@playwright/test": "^1.41.2" + "@playwright/test": "^1.49.1" }, "scripts": { "predev": "cp -r ../../build/oss-experimental/* ./node_modules/", diff --git a/fixtures/flight/yarn.lock b/fixtures/flight/yarn.lock index 36e16f18a99..e1e39cce27b 100644 --- a/fixtures/flight/yarn.lock +++ b/fixtures/flight/yarn.lock @@ -2748,12 +2748,12 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@playwright/test@^1.41.2": - version "1.41.2" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.41.2.tgz#bd9db40177f8fd442e16e14e0389d23751cdfc54" - integrity sha512-qQB9h7KbibJzrDpkXkYvsmiDJK14FULCCZgEcoe2AvFAS64oCirWTwzTlAYEbKaRxWs5TFesE1Na6izMv3HfGg== +"@playwright/test@^1.49.1": + version "1.49.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.49.1.tgz#55fa360658b3187bfb6371e2f8a64f50ef80c827" + integrity sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g== dependencies: - playwright "1.41.2" + playwright "1.49.1" "@pmmmwh/react-refresh-webpack-plugin@0.5.15": version "0.5.15" @@ -7178,17 +7178,17 @@ pkg-up@^3.1.0: dependencies: find-up "^3.0.0" -playwright-core@1.41.2: - version "1.41.2" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.41.2.tgz#db22372c708926c697acc261f0ef8406606802d9" - integrity sha512-VaTvwCA4Y8kxEe+kfm2+uUUw5Lubf38RxF7FpBxLPmGe5sdNkSg5e3ChEigaGrX7qdqT3pt2m/98LiyvU2x6CA== +playwright-core@1.49.1: + version "1.49.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.49.1.tgz#32c62f046e950f586ff9e35ed490a424f2248015" + integrity sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg== -playwright@1.41.2: - version "1.41.2" - resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.41.2.tgz#4e760b1c79f33d9129a8c65cc27953be6dd35042" - integrity sha512-v0bOa6H2GJChDL8pAeLa/LZC4feoAMbSQm1/jF/ySsWWoaNItvrMP7GEkvEEFyCTUYKMxjQKaTSg5up7nR6/8A== +playwright@1.49.1: + version "1.49.1" + resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.49.1.tgz#830266dbca3008022afa7b4783565db9944ded7c" + integrity sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA== dependencies: - playwright-core "1.41.2" + playwright-core "1.49.1" optionalDependencies: fsevents "2.3.2" @@ -7946,18 +7946,18 @@ react-refresh@^0.11.0: integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== react-server-dom-webpack@experimental: - version "0.0.0-experimental-6ebfd5b0-20240818" - resolved "https://registry.yarnpkg.com/react-server-dom-webpack/-/react-server-dom-webpack-0.0.0-experimental-6ebfd5b0-20240818.tgz#56df6a7a406a033897f9bdd33b649e6e956adcef" - integrity sha512-kDPLVKaSKwDpuxGKxWS4w0VEY1O0IUJVksfA39H7nENjmFCuHybZ6rvi+hlXgJcwV3TvVeISLSmf27yvZWUriQ== + version "0.0.0-experimental-b3a95caf-20250113" + resolved "https://registry.yarnpkg.com/react-server-dom-webpack/-/react-server-dom-webpack-0.0.0-experimental-b3a95caf-20250113.tgz#a2175829be7395acc4d25e0befbd92b233a764c6" + integrity sha512-/6/IP8sP/I1CKIBsXvuF3mQEO0Vw/Nu85QyNliCx+K6WT7plTbjpFlEnbJKWoZdh/9uQkG17IZZiGlOgExmjbA== dependencies: acorn-loose "^8.3.0" neo-async "^2.6.1" - webpack-sources "^3.2.3" + webpack-sources "^3.2.0" react@experimental: - version "0.0.0-experimental-6ebfd5b0-20240818" - resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-6ebfd5b0-20240818.tgz#80ed47abae164ace0006ef5e5931383ddb8964ae" - integrity sha512-Wkw/YNSnolRlb4q2IF738W9zDLATEDe0TLnFZJBFgb3bXLQomxChEqFG1Z2upuh0nhdnlJylCN2Q8ammQsbQLg== + version "0.0.0-experimental-b3a95caf-20250113" + resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-b3a95caf-20250113.tgz#3603103432922765869f3a95c31ff5ebcf68a2cb" + integrity sha512-Sx4o/oQ4+cxn9fFgfvrknlR0QSXl3sNztFM8P+4aazqXtLc6JM2zcQh5EBeJN9rZMPS3cPX/2gnDCD+bgwHSYw== read-cache@^1.0.0: version "1.0.0" @@ -8485,7 +8485,16 @@ string-length@^5.0.1: char-regex "^2.0.0" strip-ansi "^7.0.1" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -8549,7 +8558,14 @@ string.prototype.trimstart@^1.0.3, string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -9134,7 +9150,7 @@ webpack-sources@^2.2.0: source-list-map "^2.0.1" source-map "^0.6.1" -webpack-sources@^3.2.3: +webpack-sources@^3.2.0, webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== @@ -9231,7 +9247,16 @@ wordwrap@~1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== From 886c5ad936428f168e50e077bd37fe9472ff8d3e Mon Sep 17 00:00:00 2001 From: "Sebastian \"Sebbie\" Silbermann" Date: Wed, 15 Jan 2025 00:40:54 +0100 Subject: [PATCH 4/4] Reduce risk of leaving shipped Hooks as nullable on Dispatcher (#32068) --- packages/react-reconciler/src/ReactInternalTypes.js | 4 +++- packages/react-server/src/ReactFizzHooks.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/react-reconciler/src/ReactInternalTypes.js b/packages/react-reconciler/src/ReactInternalTypes.js index 7a6766f5c92..0c5504cab46 100644 --- a/packages/react-reconciler/src/ReactInternalTypes.js +++ b/packages/react-reconciler/src/ReactInternalTypes.js @@ -394,7 +394,9 @@ export type Dispatcher = { create: () => (() => void) | void, deps: Array | void | null, ): void, + // TODO: Non-nullable once `enableUseEffectEventHook` is on everywhere. useEffectEvent?: ) => mixed>(callback: F) => F, + // TODO: Non-nullable once `enableUseResourceEffectHook` is on everywhere. useResourceEffect?: ( create: () => mixed, createDeps: Array | void | null, @@ -429,7 +431,7 @@ export type Dispatcher = { getServerSnapshot?: () => T, ): T, useId(): string, - useCacheRefresh?: () => (?() => T, ?T) => void, + useCacheRefresh: () => (?() => T, ?T) => void, useMemoCache: (size: number) => Array, useHostTransitionStatus: () => TransitionStatus, useOptimistic: ( diff --git a/packages/react-server/src/ReactFizzHooks.js b/packages/react-server/src/ReactFizzHooks.js index d346bdff0c5..0db0b00b3bd 100644 --- a/packages/react-server/src/ReactFizzHooks.js +++ b/packages/react-server/src/ReactFizzHooks.js @@ -835,6 +835,7 @@ export const HooksDispatcher: Dispatcher = supportsClientAPIs useFormState: useActionState, useHostTransitionStatus, useMemoCache, + useCacheRefresh, } : { readContext,