Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add fetch Instrumentation to Dedupe Fetches #25516

Merged
merged 3 commits into from
Oct 19, 2022

Conversation

sebmarkbage
Copy link
Collaborator

Dedupe GET and HEAD fetches while a React Cache is active.

Note that this doesn't say when this should happen nor the lifetime of these cache entries. Currently it's just during render and lives for the lifetime of the current Cache, but that will be expanded, in a limited form, in tasks outside of render. This PR isn't concerned about that yet. It's just saying which things will be deduped and that it's React doing it - when requiring "react".

Passing an explicit AbortSignal can be used to opt out of this behavior.

This doesn't instrument the Promises for sync resolution. It also yields new Responses every time and reading the body is still a macrotask operation so it's still better to have an outer cache() but this gives deduping at the network layer to avoid costly mistakes and to make the simple case simple.

Browsers do this kind of deduping anyway. It's really mostly for the cache: 'no-store' option and cache-control that we diverge slightly. So it's not a huge divergence in behavior.

Notably POST requests are not deduped so they have to be wrapped in cache() explicitly. This is unfortunate since those are often used for reads as well. E.g. GraphQL. We might want to expand the implicit caching of some of those as well by assuming that POST in render are idempotent since anything in render needs to be idempotent anyway. We'd have to be more careful about this when we expand to cache in unknown contexts though. Maybe a compromise is to only dedupe these on the server.

let entry: AbortSignal | void = (currentCache.get(createSignal): any);
if (entry === undefined) {
entry = createSignal();
// $FlowFixMe[incompatible-use] found when upgrading Flow
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I don't get why a FlowFixMe is necessary here. Is it because the createSignal call resets the type refinement? Would a const binding above fix it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it was added during a codemod to getCacheForType below, and then you copy pasted. Guessing it's easy to fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just temporary until I add the lifetime to Flight next, and getCacheForType will be replaced by cache().

// Notably we currently don't consider non-standard (or future) options.
// This might not be safe. TODO: warn for non-standard extensions differing.
// IF YOU CHANGE THIS UPDATE THE simpleCacheKey ABOVE.
return JSON.stringify([
Copy link
Collaborator Author

@sebmarkbage sebmarkbage Oct 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this isn't actually used as a key in a map we could just make it an explicit comparison of two Request objects.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intuitively that seems like it would be faster to me. But if you're not confident either way, seems fine to leave as is and benchmark later.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH this is less code

@sizebot
Copy link

sizebot commented Oct 19, 2022

Comparing: 8e2bde6...c94f72d

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name +/- Base Current +/- gzip Base gzip Current gzip
oss-stable/react-dom/cjs/react-dom.production.min.js = 135.99 kB 135.99 kB = 43.54 kB 43.54 kB
oss-experimental/react-dom/cjs/react-dom.production.min.js +0.02% 151.46 kB 151.49 kB +0.02% 48.23 kB 48.24 kB
facebook-www/ReactDOM-prod.classic.js +0.03% 493.51 kB 493.66 kB +0.03% 87.83 kB 87.86 kB
facebook-www/ReactDOM-prod.modern.js +0.03% 478.77 kB 478.92 kB +0.04% 85.64 kB 85.67 kB
facebook-www/ReactDOMForked-prod.classic.js +0.03% 493.51 kB 493.66 kB +0.03% 87.83 kB 87.86 kB
oss-experimental/react/cjs/react.shared-subset.production.min.js +12.29% 7.39 kB 8.30 kB +13.41% 3.00 kB 3.40 kB
oss-experimental/react/cjs/react.production.min.js +9.99% 9.09 kB 10.00 kB +12.00% 3.38 kB 3.79 kB
oss-experimental/react/umd/react.profiling.min.js +7.08% 12.86 kB 13.77 kB +7.83% 4.96 kB 5.34 kB
oss-experimental/react/umd/react.production.min.js +7.08% 12.86 kB 13.77 kB +7.85% 4.95 kB 5.34 kB
oss-experimental/react/cjs/react.shared-subset.development.js +5.73% 80.16 kB 84.75 kB +6.36% 22.04 kB 23.44 kB
oss-experimental/react/cjs/react.development.js +4.78% 96.09 kB 100.68 kB +5.48% 25.84 kB 27.25 kB
oss-experimental/react/umd/react.development.js +3.98% 119.93 kB 124.70 kB +4.95% 30.72 kB 32.24 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name +/- Base Current +/- gzip Base gzip Current gzip
oss-experimental/react/cjs/react.shared-subset.production.min.js +12.29% 7.39 kB 8.30 kB +13.41% 3.00 kB 3.40 kB
oss-experimental/react/cjs/react.production.min.js +9.99% 9.09 kB 10.00 kB +12.00% 3.38 kB 3.79 kB
oss-experimental/react/umd/react.profiling.min.js +7.08% 12.86 kB 13.77 kB +7.83% 4.96 kB 5.34 kB
oss-experimental/react/umd/react.production.min.js +7.08% 12.86 kB 13.77 kB +7.85% 4.95 kB 5.34 kB
oss-experimental/react/cjs/react.shared-subset.development.js +5.73% 80.16 kB 84.75 kB +6.36% 22.04 kB 23.44 kB
oss-experimental/react/cjs/react.development.js +4.78% 96.09 kB 100.68 kB +5.48% 25.84 kB 27.25 kB
oss-experimental/react/umd/react.development.js +3.98% 119.93 kB 124.70 kB +4.95% 30.72 kB 32.24 kB
oss-experimental/react-server/cjs/react-server-flight.production.min.js +1.44% 12.74 kB 12.93 kB +0.96% 4.69 kB 4.73 kB
facebook-www/ReactFlightDOMRelayServer-prod.classic.js +1.29% 33.19 kB 33.62 kB +0.67% 8.40 kB 8.46 kB
facebook-www/ReactFlightDOMRelayServer-prod.modern.js +1.29% 33.27 kB 33.70 kB +0.68% 8.43 kB 8.49 kB
oss-stable-semver/react-server/cjs/react-server-flight.production.min.js +1.21% 12.19 kB 12.33 kB +0.53% 4.55 kB 4.58 kB
oss-stable/react-server/cjs/react-server-flight.production.min.js +1.21% 12.19 kB 12.33 kB +0.53% 4.55 kB 4.58 kB
facebook-relay/flight/ReactFlightNativeRelayServer-prod.js +1.15% 26.15 kB 26.45 kB +0.46% 6.30 kB 6.33 kB
oss-experimental/react-server/cjs/react-server-flight.development.js +1.10% 57.83 kB 58.46 kB +0.77% 14.18 kB 14.29 kB
facebook-www/ReactFlightDOMRelayServer-dev.classic.js +0.88% 71.30 kB 71.93 kB +0.60% 17.70 kB 17.81 kB
facebook-www/ReactFlightDOMRelayServer-dev.modern.js +0.88% 71.36 kB 71.98 kB +0.60% 17.72 kB 17.83 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js +0.86% 21.48 kB 21.66 kB +0.46% 7.58 kB 7.61 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js +0.84% 21.90 kB 22.08 kB +0.56% 7.66 kB 7.70 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js +0.84% 21.67 kB 21.86 kB +0.62% 7.64 kB 7.69 kB
oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js +0.79% 84.64 kB 85.31 kB +0.56% 20.48 kB 20.60 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +0.79% 80.55 kB 81.19 kB +0.56% 20.23 kB 20.35 kB
oss-experimental/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +0.77% 81.98 kB 82.62 kB +0.55% 20.35 kB 20.46 kB
facebook-relay/flight/ReactFlightNativeRelayServer-dev.js +0.73% 51.43 kB 51.80 kB +0.33% 12.83 kB 12.88 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js +0.71% 20.88 kB 21.02 kB +0.39% 7.41 kB 7.44 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.min.js +0.71% 20.88 kB 21.02 kB +0.39% 7.41 kB 7.44 kB
oss-stable-semver/react-server/cjs/react-server-flight.development.js +0.70% 53.92 kB 54.30 kB +0.31% 13.22 kB 13.26 kB
oss-stable/react-server/cjs/react-server-flight.development.js +0.70% 53.92 kB 54.30 kB +0.31% 13.22 kB 13.26 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js +0.70% 21.09 kB 21.23 kB +0.51% 7.47 kB 7.51 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.production.min.js +0.70% 21.09 kB 21.23 kB +0.51% 7.47 kB 7.51 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js +0.69% 21.30 kB 21.45 kB +0.35% 7.50 kB 7.52 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.min.js +0.69% 21.30 kB 21.45 kB +0.35% 7.50 kB 7.52 kB
oss-stable-semver/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js +0.50% 80.48 kB 80.88 kB +0.17% 19.50 kB 19.53 kB
oss-stable/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js +0.50% 80.48 kB 80.88 kB +0.17% 19.50 kB 19.53 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +0.49% 76.59 kB 76.97 kB +0.21% 19.23 kB 19.27 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +0.49% 76.59 kB 76.97 kB +0.21% 19.23 kB 19.27 kB
oss-stable-semver/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +0.48% 78.02 kB 78.40 kB +0.21% 19.34 kB 19.38 kB
oss-stable/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +0.48% 78.02 kB 78.40 kB +0.21% 19.34 kB 19.38 kB

Generated by 🚫 dangerJS against c94f72d

let url: string;
let cacheKey: string;
if (typeof resource === 'string' && !options) {
// Fast path.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clever

const request = new Request(resource, options);
if (
(request.method !== 'GET' && request.method !== 'HEAD') ||
// $FlowFixMe: keepalive is real
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆

export const DefaultCacheDispatcher: CacheDispatcher = {
getCacheSignal(): AbortSignal {
throw new Error('Not implemented.');
if (!currentCache) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why unroll this? Does this really help?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just that I don't want to call the Dispatcher and create a dependency on the object wrapper. But this is going away soon anyway as we need a proper lifetime for it.

return originalFetch(resource, options);
}
// Normalize the Request
let url: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to normalize url if it's a relative path string? In case history.push gets called while the cache is alive.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for the fast path. Good catch. Originally I didn't have the fast path.

const value = cacheEntries[i + 1];
if (key === cacheKey) {
match = value;
// I would've preferred a labelled break but lint says no.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change the lint config? labeled break is fine IMO

match = originalFetch(resource, options);
cache.set(url, [cacheKey, match]);
} else {
// We use an array as the inner data structure since it's lighter and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lighter than both {} and Map? I know those use arrays internally for small sizes right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't benchmark yet but maybe yea.

// eslint-disable-next-line react-internal/no-production-logging
console.warn(
'React was unable to patch the fetch() function in this environment. ' +
'Suspensey APIs might not work correctly as a result.',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the first time we've used "Suspensey" in public facing messages? I think I dig it

@sebmarkbage
Copy link
Collaborator Author

Btw, I did not enable this in www so the tests don't run in yarn test.

…gnore

In the final passes, we ignore the newly generated Promises and use
the previous ones. This ensures that if those generate errors, that we
intentionally ignore those.
@sebmarkbage sebmarkbage merged commit 65e32e5 into facebook:main Oct 19, 2022
facebook-github-bot pushed a commit to facebook/react-native that referenced this pull request Nov 1, 2022
Summary:
This sync includes the following changes:
- **[ab075a232](facebook/react@ab075a232 )**: Do not unmount layout effects on initial Offscreen mount ([#25592](facebook/react#25592)) //<Samuel Susla>//
- **[765805bf8](facebook/react@765805bf8 )**: Fix type check for null ([#25595](facebook/react#25595)) //<Sebastian Markbåge>//
- **[2ac77aab9](facebook/react@2ac77aab9 )**: Clean up vestige of useOpaqueIdentifier ([#25587](facebook/react#25587)) //<Andrew Clark>//
- **[bdd3d0807](facebook/react@bdd3d0807 )**: Extract logic for detecting bad fallback to helper //<Andrew Clark>//
- **[952dfff3f](facebook/react@952dfff3f )**: Split suspended work loop logic into separate functions //<Andrew Clark>//
- **[d2c0ab10d](facebook/react@d2c0ab10d )**: In work loop, add enum of reasons for suspending //<Andrew Clark>//
- **[5450dd409](facebook/react@5450dd409 )**: Strict Mode: Reuse memoized result from first pass ([#25583](facebook/react#25583)) //<Andrew Clark>//
- **[d2a0176a1](facebook/react@d2a0176a1 )**: Detect and warn if use(promise) is wrapped with try/catch block ([#25543](facebook/react#25543)) //<Andrew Clark>//
- **[cf3932be5](facebook/react@cf3932be5 )**: Remove old react-fetch, react-fs and react-pg libraries ([#25577](facebook/react#25577)) //<Sebastian Markbåge>//
- **[28a574ea8](facebook/react@28a574ea8 )**: Try assigning fetch to globalThis if global assignment fails ([#25571](facebook/react#25571)) //<Sebastian Markbåge>//
- **[09def5990](facebook/react@09def5990 )**: [Float] handle noscript context for Resources ([#25559](facebook/react#25559)) //<Josh Story>//
- **[17204056d](facebook/react@17204056d )**: [Float] fix coordination of resource identity and hydration ([#25569](facebook/react#25569)) //<Josh Story>//
- **[d925a8d0b](facebook/react@d925a8d0b )**: Flight client error stack ([#25560](facebook/react#25560)) //<Josh Story>//
- **[996b00b78](facebook/react@996b00b78 )**: [Tiny] Fixed incorrect import in `react-server-dom-webpack` ([#25554](facebook/react#25554)) //<Leo Lamprecht>//
- **[e7c5af45c](facebook/react@e7c5af45c )**: Update cache() and use() to the canary aka next channel ([#25502](facebook/react#25502)) //<Sebastian Markbåge>//
- **[fa77f52e7](facebook/react@fa77f52e7 )**: Unify promise switch statements //<Andrew Clark>//
- **[7572e4931](facebook/react@7572e4931 )**: Track thenable state in work loop //<Andrew Clark>//
- **[7fc3eefd8](facebook/react@7fc3eefd8 )**: Revert yieldy behavior for non-use Suspense (in Flight, too) //<Andrew Clark>//
- **[61f9b5e97](facebook/react@61f9b5e97 )**: [Float] support <base> as Resource ([#25546](facebook/react#25546)) //<Josh Story>//
- **[1d3fc9c9c](facebook/react@1d3fc9c9c )**: Bug fix when resolving cache ([#25545](facebook/react#25545)) //<Sebastian Markbåge>//
- **[cce18e350](facebook/react@cce18e350 )**: [Flight] Use AsyncLocalStorage to extend the scope of the cache to micro tasks ([#25542](facebook/react#25542)) //<Sebastian Markbåge>//
- **[caa84c8da](facebook/react@caa84c8da )**: Revert fetch instrumentation to only RSC ([#25540](facebook/react#25540)) //<Sebastian Markbåge>//
- **[0c11baa6a](facebook/react@0c11baa6a )**: add warnings for non-resources rendered outside body or head ([#25532](facebook/react#25532)) //<Josh Story>//
- **[9236abdb5](facebook/react@9236abdb5 )**: when float is enabled only push title and script as a single unit ([#25536](facebook/react#25536)) //<Josh Story>//
- **[dd5c20825](facebook/react@dd5c20825 )**: Revert yieldy behavior for non-use Suspense ([#25537](facebook/react#25537)) //<Andrew Clark>//
- **[934177598](facebook/react@934177598 )**: fix transposed escape functions ([#25534](facebook/react#25534)) //<Josh Story>//
- **[d1ced9fd5](facebook/react@d1ced9fd5 )**: [Float] support all links as Resources ([#25515](facebook/react#25515)) //<Josh Story>//
- **[973b90bdf](facebook/react@973b90bdf )**: [Float] support meta tags as Resources ([#25514](facebook/react#25514)) //<Josh Story>//
- **[79c582981](facebook/react@79c582981 )**: Let ReactDOM initialize in RSC ([#25503](facebook/react#25503)) //<Sebastian Markbåge>//
- **[1f7a2f577](facebook/react@1f7a2f577 )**: [Float] support title tags as Resources ([#25508](facebook/react#25508)) //<Josh Story>//
- **[c63580787](facebook/react@c63580787 )**: Support `use` in `act` testing API ([#25523](facebook/react#25523)) //<Andrew Clark>//
- **[65e32e58b](facebook/react@65e32e58b )**: Add fetch Instrumentation to Dedupe Fetches ([#25516](facebook/react#25516)) //<Sebastian Markbåge>//
- **[9336e29d9](facebook/react@9336e29d9 )**: [useEvent] Lint for presence of useEvent functions in dependency lists ([#25512](facebook/react#25512)) //<lauren>//
- **[3cc792bfb](facebook/react@3cc792bfb )**: [useEvent] Non-stable function identity ([#25473](facebook/react#25473)) //<lauren>//
- **[987292815](facebook/react@987292815 )**: Remove feature flag enableStrictEffects ([#25387](facebook/react#25387)) //<Samuel Susla>//
- **[8e2bde6f2](facebook/react@8e2bde6f2 )**: Add cache() API ([#25506](facebook/react#25506)) //<Sebastian Markbåge>//
- **[9cdf8a99e](facebook/react@9cdf8a99e )**: [Codemod] Update copyright header to Meta ([#25315](facebook/react#25315)) //<Andrew Clark>//
- **[e54015e26](facebook/react@e54015e26 )**: Refactor: fill in the flow missing type ([#25496](facebook/react#25496)) //<c0dedance>//
- **[3b1fd5767](facebook/react@3b1fd5767 )**: refactor: Flow: typing of Scheduler ([#25485](facebook/react#25485)) //<bubucuo>//
- **[14072ce64](facebook/react@14072ce64 )**: Add detach to Offscreen component ([#25265](facebook/react#25265)) //<Samuel Susla>//
- **[3bb71dfd4](facebook/react@3bb71dfd4 )**: Rename react-server-dom-webpack entry points to /client and /server ([#25504](facebook/react#25504)) //<Sebastian Markbåge>//
- **[71f2c8cf1](facebook/react@71f2c8cf1 )**: move resource acquisition to mutation phase ([#25500](facebook/react#25500)) //<Josh Story>//
- **[500bea532](facebook/react@500bea532 )**: Add option to load Fizz runtime from external file ([#25499](facebook/react#25499)) //<Andrew Clark>//
- **[4494f2a86](facebook/react@4494f2a86 )**: [Float] add support for scripts and other enhancements ([#25480](facebook/react#25480)) //<Josh Story>//
- **[9ecf84ed7](facebook/react@9ecf84ed7 )**: Bugfix: Suspending in shell during discrete update ([#25495](facebook/react#25495)) //<Andrew Clark>//

Changelog:
[General][Changed] - React Native sync for revisions 54f297a...ab075a2

jest_e2e[run_all_tests]

Reviewed By: kassens

Differential Revision: D40897093

fbshipit-source-id: 6a040315834dea5c0ab994ea94d91f5605b9d6b0
rickhanlonii pushed a commit that referenced this pull request Dec 3, 2022
* Add fetch instrumentation in cached contexts

* Avoid unhandled rejection errors for Promises that we intentionally ignore

In the final passes, we ignore the newly generated Promises and use
the previous ones. This ensures that if those generate errors, that we
intentionally ignore those.

* Add extra fetch properties if there were any
@igorkamyshev
Copy link

Have you considered finding another way but money patching (yeah, you called it instrumentation, but let's be frank — it's monkey patching)? I assume everyone there knows its pitfalls, but let me remind — https://en.wikipedia.org/wiki/Monkey_patch#Pitfalls.

OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this pull request May 22, 2023
Summary:
This sync includes the following changes:
- **[ab075a232](facebook/react@ab075a232 )**: Do not unmount layout effects on initial Offscreen mount ([facebook#25592](facebook/react#25592)) //<Samuel Susla>//
- **[765805bf8](facebook/react@765805bf8 )**: Fix type check for null ([facebook#25595](facebook/react#25595)) //<Sebastian Markbåge>//
- **[2ac77aab9](facebook/react@2ac77aab9 )**: Clean up vestige of useOpaqueIdentifier ([facebook#25587](facebook/react#25587)) //<Andrew Clark>//
- **[bdd3d0807](facebook/react@bdd3d0807 )**: Extract logic for detecting bad fallback to helper //<Andrew Clark>//
- **[952dfff3f](facebook/react@952dfff3f )**: Split suspended work loop logic into separate functions //<Andrew Clark>//
- **[d2c0ab10d](facebook/react@d2c0ab10d )**: In work loop, add enum of reasons for suspending //<Andrew Clark>//
- **[5450dd409](facebook/react@5450dd409 )**: Strict Mode: Reuse memoized result from first pass ([facebook#25583](facebook/react#25583)) //<Andrew Clark>//
- **[d2a0176a1](facebook/react@d2a0176a1 )**: Detect and warn if use(promise) is wrapped with try/catch block ([facebook#25543](facebook/react#25543)) //<Andrew Clark>//
- **[cf3932be5](facebook/react@cf3932be5 )**: Remove old react-fetch, react-fs and react-pg libraries ([facebook#25577](facebook/react#25577)) //<Sebastian Markbåge>//
- **[28a574ea8](facebook/react@28a574ea8 )**: Try assigning fetch to globalThis if global assignment fails ([facebook#25571](facebook/react#25571)) //<Sebastian Markbåge>//
- **[09def5990](facebook/react@09def5990 )**: [Float] handle noscript context for Resources ([facebook#25559](facebook/react#25559)) //<Josh Story>//
- **[17204056d](facebook/react@17204056d )**: [Float] fix coordination of resource identity and hydration ([facebook#25569](facebook/react#25569)) //<Josh Story>//
- **[d925a8d0b](facebook/react@d925a8d0b )**: Flight client error stack ([facebook#25560](facebook/react#25560)) //<Josh Story>//
- **[996b00b78](facebook/react@996b00b78 )**: [Tiny] Fixed incorrect import in `react-server-dom-webpack` ([facebook#25554](facebook/react#25554)) //<Leo Lamprecht>//
- **[e7c5af45c](facebook/react@e7c5af45c )**: Update cache() and use() to the canary aka next channel ([facebook#25502](facebook/react#25502)) //<Sebastian Markbåge>//
- **[fa77f52e7](facebook/react@fa77f52e7 )**: Unify promise switch statements //<Andrew Clark>//
- **[7572e4931](facebook/react@7572e4931 )**: Track thenable state in work loop //<Andrew Clark>//
- **[7fc3eefd8](facebook/react@7fc3eefd8 )**: Revert yieldy behavior for non-use Suspense (in Flight, too) //<Andrew Clark>//
- **[61f9b5e97](facebook/react@61f9b5e97 )**: [Float] support <base> as Resource ([facebook#25546](facebook/react#25546)) //<Josh Story>//
- **[1d3fc9c9c](facebook/react@1d3fc9c9c )**: Bug fix when resolving cache ([facebook#25545](facebook/react#25545)) //<Sebastian Markbåge>//
- **[cce18e350](facebook/react@cce18e350 )**: [Flight] Use AsyncLocalStorage to extend the scope of the cache to micro tasks ([facebook#25542](facebook/react#25542)) //<Sebastian Markbåge>//
- **[caa84c8da](facebook/react@caa84c8da )**: Revert fetch instrumentation to only RSC ([facebook#25540](facebook/react#25540)) //<Sebastian Markbåge>//
- **[0c11baa6a](facebook/react@0c11baa6a )**: add warnings for non-resources rendered outside body or head ([facebook#25532](facebook/react#25532)) //<Josh Story>//
- **[9236abdb5](facebook/react@9236abdb5 )**: when float is enabled only push title and script as a single unit ([facebook#25536](facebook/react#25536)) //<Josh Story>//
- **[dd5c20825](facebook/react@dd5c20825 )**: Revert yieldy behavior for non-use Suspense ([facebook#25537](facebook/react#25537)) //<Andrew Clark>//
- **[934177598](facebook/react@934177598 )**: fix transposed escape functions ([facebook#25534](facebook/react#25534)) //<Josh Story>//
- **[d1ced9fd5](facebook/react@d1ced9fd5 )**: [Float] support all links as Resources ([facebook#25515](facebook/react#25515)) //<Josh Story>//
- **[973b90bdf](facebook/react@973b90bdf )**: [Float] support meta tags as Resources ([facebook#25514](facebook/react#25514)) //<Josh Story>//
- **[79c582981](facebook/react@79c582981 )**: Let ReactDOM initialize in RSC ([facebook#25503](facebook/react#25503)) //<Sebastian Markbåge>//
- **[1f7a2f577](facebook/react@1f7a2f577 )**: [Float] support title tags as Resources ([facebook#25508](facebook/react#25508)) //<Josh Story>//
- **[c63580787](facebook/react@c63580787 )**: Support `use` in `act` testing API ([facebook#25523](facebook/react#25523)) //<Andrew Clark>//
- **[65e32e58b](facebook/react@65e32e58b )**: Add fetch Instrumentation to Dedupe Fetches ([facebook#25516](facebook/react#25516)) //<Sebastian Markbåge>//
- **[9336e29d9](facebook/react@9336e29d9 )**: [useEvent] Lint for presence of useEvent functions in dependency lists ([facebook#25512](facebook/react#25512)) //<lauren>//
- **[3cc792bfb](facebook/react@3cc792bfb )**: [useEvent] Non-stable function identity ([facebook#25473](facebook/react#25473)) //<lauren>//
- **[987292815](facebook/react@987292815 )**: Remove feature flag enableStrictEffects ([facebook#25387](facebook/react#25387)) //<Samuel Susla>//
- **[8e2bde6f2](facebook/react@8e2bde6f2 )**: Add cache() API ([facebook#25506](facebook/react#25506)) //<Sebastian Markbåge>//
- **[9cdf8a99e](facebook/react@9cdf8a99e )**: [Codemod] Update copyright header to Meta ([facebook#25315](facebook/react#25315)) //<Andrew Clark>//
- **[e54015e26](facebook/react@e54015e26 )**: Refactor: fill in the flow missing type ([facebook#25496](facebook/react#25496)) //<c0dedance>//
- **[3b1fd5767](facebook/react@3b1fd5767 )**: refactor: Flow: typing of Scheduler ([facebook#25485](facebook/react#25485)) //<bubucuo>//
- **[14072ce64](facebook/react@14072ce64 )**: Add detach to Offscreen component ([facebook#25265](facebook/react#25265)) //<Samuel Susla>//
- **[3bb71dfd4](facebook/react@3bb71dfd4 )**: Rename react-server-dom-webpack entry points to /client and /server ([facebook#25504](facebook/react#25504)) //<Sebastian Markbåge>//
- **[71f2c8cf1](facebook/react@71f2c8cf1 )**: move resource acquisition to mutation phase ([facebook#25500](facebook/react#25500)) //<Josh Story>//
- **[500bea532](facebook/react@500bea532 )**: Add option to load Fizz runtime from external file ([facebook#25499](facebook/react#25499)) //<Andrew Clark>//
- **[4494f2a86](facebook/react@4494f2a86 )**: [Float] add support for scripts and other enhancements ([facebook#25480](facebook/react#25480)) //<Josh Story>//
- **[9ecf84ed7](facebook/react@9ecf84ed7 )**: Bugfix: Suspending in shell during discrete update ([facebook#25495](facebook/react#25495)) //<Andrew Clark>//

Changelog:
[General][Changed] - React Native sync for revisions 54f297a...ab075a2

jest_e2e[run_all_tests]

Reviewed By: kassens

Differential Revision: D40897093

fbshipit-source-id: 6a040315834dea5c0ab994ea94d91f5605b9d6b0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants