The forking for `shared/ReactFeatureFlags` doesn't work in the console
patches. Since they're already forked, we can import the internal
ReactFeatureFlags files directly.
Would have caught this in testing a PR sync, but the PR syncs are broken
right now.
This will provide the opt-in for using [View
Transitions](https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API)
in React.
View Transitions only trigger for async updates like `startTransition`,
`useDeferredValue`, Actions or `<Suspense>` revealing from fallback to
content. Synchronous updates provide an opt-out but also guarantee that
they commit immediately which View Transitions can't.
There's no need to opt-in to View Transitions at the "cause" side like
event handlers or actions. They don't know what UI will change and
whether that has an animated transition described.
Conceptually the `<ViewTransition>` component is like a DOM fragment
that transitions its children in its own isolate/snapshot. The API works
by wrapping a DOM node or inner component:
```js
import {ViewTransition} from 'react';
<ViewTransition><Component /></ViewTransition>
```
The default is `name="auto"` which will automatically assign a
`view-transition-name` to the inner DOM node. That way you can add a
View Transition to a Component without controlling its DOM nodes styling
otherwise.
A difference between this and the browser's built-in
`view-transition-name: auto` is that switching the DOM nodes within the
`<ViewTransition>` component preserves the same name so this example
cross-fades between the DOM nodes instead of causing an exit and enter:
```js
<ViewTransition>{condition ? <ComponentA /> : <ComponentB />}</ViewTransition>
```
This becomes especially useful with `<Suspense>` as this example
cross-fades between Skeleton and Content:
```js
<ViewTransition>
<Suspense fallback={<Skeleton />}>
<Content />
</Suspense>
</ViewTransition>
```
Where as this example triggers an exit of the Skeleton and an enter of
the Content:
```js
<Suspense fallback={<ViewTransition><Skeleton /></ViewTransition>}>
<ViewTransition><Content /></ViewTransition>
</Suspense>
```
Managing instances and keys becomes extra important.
You can also specify an explicit `name` property for example for
animating the same conceptual item from one page onto another. However,
best practices is to property namespace these since they can easily
collide. It's also useful to add an `id` to it if available.
```js
<ViewTransition name="my-shared-view">
```
The model in general is the same as plain `view-transition-name` except
React manages a set of heuristics for when to apply it. A problem with
the naive View Transitions model is that it overly opts in every
boundary that *might* transition into transitioning. This is leads to
unfortunate effects like things floating around when unrelated updates
happen. This leads the whole document to animate which means that
nothing is clickable in the meantime. It makes it not useful for smaller
and more local transitions. Best practice is to add
`view-transition-name` only right before you're about to need to animate
the thing. This is tricky to manage globally on complex apps and is not
compositional. Instead we let React manage when a `<ViewTransition>`
"activates" and add/remove the `view-transition-name`. This is also when
React calls `startViewTransition` behind the scenes while it mutates the
DOM.
I've come up with a number of heuristics that I think will make a lot
easier to coordinate this. The principle is that only if something that
updates that particular boundary do we activate it. I hope that one day
maybe browsers will have something like these built-in and we can remove
our implementation.
A `<ViewTransition>` only activates if:
- If a mounted Component renders a `<ViewTransition>` within it outside
the first DOM node, and it is within the viewport, then that
ViewTransition activates as an "enter" animation. This avoids inner
"enter" animations trigger when the parent mounts.
- If an unmounted Component had a `<ViewTransition>` within it outside
the first DOM node, and it was within the viewport, then that
ViewTransition activates as an "exit" animation. This avoids inner
"exit" animations triggering when the parent unmounts.
- If an explicitly named `<ViewTransition name="...">` is deep within an
unmounted tree and one with the same name appears in a mounted tree at
the same time, then both are activated as a pair, but only if they're
both in the viewport. This avoids these triggering "enter" or "exit"
animations when going between parents that don't have a pair.
- If an already mounted `<ViewTransition>` is visible and a DOM
mutation, that might affect how it's painted, happens within its
children but outside any nested `<ViewTransition>`. This allows it to
"cross-fade" between its updates.
- If an already mounted `<ViewTransition>` resizes or moves as the
result of direct DOM nodes siblings changing or moving around. This
allows insertion, deletion and reorders into a list to animate all
children. It is only within one DOM node though, to avoid unrelated
changes in the parent to trigger this. If an item is outside the
viewport before and after, then it's skipped to avoid things flying
across the screen.
- If a `<ViewTransition>` boundary changes size, due to a DOM mutation
within it, then the parent activates (or the root document if there are
no more parents). This ensures that the container can cross-fade to
avoid abrupt relayout. This can be avoided by using absolutely
positioned children. When this can avoid bubbling to the root document,
whatever is not animating is still responsive to clicks during the
transition.
Conceptually each DOM node has its own default that activates the parent
`<ViewTransition>` or no transition if the parent is the root. That
means that if you add a DOM node like `<div><ViewTransition><Component
/></ViewTransition></div>` this won't trigger an "enter" animation since
it was the div that was added, not the ViewTransition. Instead, it might
cause a cross-fade of the parent ViewTransition or no transition if it
had no parent. This ensures that only explicit boundaries perform coarse
animations instead of every single node which is really the benefit of
the View Transitions model. This ends up working out well for simple
cases like switching between two pages immediately while transitioning
one floating item that appears on both pages. Because only the floating
item transitions by default.
Note that it's possible to add manual `view-transition-name` with CSS or
`style={{ viewTransitionName: 'auto' }}` that always transitions as long
as something else has a `<ViewTransition>` that activates. For example a
`<ViewTransition>` can wrap a whole page for a cross-fade but inside of
it an explicit name can be added to something to ensure it animates as a
move when something relates else changes its layout. Instead of just
cross-fading it along with the Page which would be the default.
There's more PRs coming with some optimizations, fixes and expanded
APIs. This first PR explores the above core heuristic.
---------
Co-authored-by: Sebastian "Sebbie" Silbermann <silbermann.sebastian@gmail.com>
Followup to #31725
This implements `prepareDestinationForModule` in the Parcel Flight
client. On the Parcel side, the `<Resources>` component now only inserts
`<link>` elements for stylesheets (along with a bootstrap script when
needed), and React is responsible for inserting scripts. This ensures
that components that are conditionally dynamic imported during render
are also preloaded.
CSS must be added to the RSC tree using `<Resources>` to avoid FOUC.
This must be manually rendered in both the top-level page, and in any
component that is dynamic imported. It would be nice if there was a way
for React to automatically insert CSS as well, but unfortunately
`prepareDestinationForModule` only knows about client components and not
CSS for server components. Perhaps there could be a way we could
annotate components at code splitting boundaries with the resources they
need? More thoughts in this thread:
https://github.com/facebook/react/pull/31725#discussion_r1884867607
We already have handling and retry logic for in-flight workflows in
`downloadArtifactsFromGitHub`, so there's no need to exit early if we
find a workflow for a given commit but it hasn't finished yet.
#31787 introduces an experimental scheduler flag:
`enableAlwaysYieldScheduler`, which is turned off for www. There wasn't
a SchedulerFeatureFlags fork for native-fb, so the experimental change
was enabled in the Scheduler-dev build there which causes test failures
and is blocking the sync.
#31805 introduces another scheduler flag `enableRequestPaint`, which is
set as a `__VARIANT__` on www. I've set this to `true` here to preserve
the existing behavior. We can follow up with dynamic flags for native-fb
after unblocking the sync.
We introduced the `unstable_useContextWithBailout` API to run compiler
based experiments. This API was designed to be an experiment proxy for
alternative approaches which would be heavier to implement. The
experiment turned out to be inconclusive. Since most of our performance
critical usage is already optimized, we weren't able to find a clear win
with this approach.
Since we don't have further plans for this API, let's clean it up.
Follow up to #31725.
I diffed against the Turbopack one to find any unexpected discrepancies.
Some parts are forked enough that it's hard to diff but I think I got
most of it.
This adds a new `react-server-dom-parcel-package`, which is an RSC
integration for the Parcel bundler. It is mostly copied from the
existing webpack/turbopack integrations, with some changes to utilize
Parcel runtime APIs for loading and executing bundles/modules.
See https://github.com/parcel-bundler/parcel/pull/10043 for the Parcel
side of this, which includes the plugin needed to generate client and
server references. https://github.com/parcel-bundler/rsc-examples also
includes examples of various ways to use RSCs with Parcel.
Differences from other integrations:
* Client and server modules are all part of the same graph, and we use
Parcel's
[environments](https://parceljs.org/plugin-system/transformer/#the-environment)
to distinguish them. The server is the Parcel build entry point, and it
imports and renders server components in route handlers. When a `"use
client"` directive is seen, the environment changes and Parcel creates a
new client bundle for the page, combining all client modules together.
CSS from both client and server components are also combined
automatically.
* There is no separate manifest file that needs to be passed around by
the user. A [Runtime](https://parceljs.org/plugin-system/runtime/)
plugin injects client and server references as needed into the relevant
bundles, and registers server action ids using `react-server-dom-parcel`
automatically.
* A special `<Resources>` component is also generated by Parcel to
render the `<script>` and `<link rel="stylesheet">` elements needed for
a page, using the relevant info from the bundle graph.
Note: I've already published a 0.0.x version of this package to npm for
testing purposes but happy to add whoever needs access to it as well.
### Questions
* How to test this in the React repo. I'll have integration tests in
Parcel, but setting up all the different mocks and environments to
simulate that here seems challenging. I could try to copy how
Webpack/Turbopack do it but it's a bit different.
* Where to put TypeScript types. Right now I have some ambient types in
my [example
repo](https://github.com/parcel-bundler/rsc-examples/blob/main/types.d.ts)
but it would be nice for users not to copy and paste these. Can I
include them in the package or do they need to maintained separately in
definitelytyped? I would really prefer not to have to maintain code in
three different repos ideally.
---------
Co-authored-by: Sebastian Markbage <sebastian@calyptus.eu>
When streaming SSR while hydrating React will wait for Suspense
boundaries to be revealed by the SSR stream before attempting to hydrate
them. The rationale here is that the Server render is likely further
ahead of whatever the client would produce so waiting to let the server
stream in the UI is preferable to retrying on the client and possibly
delaying how quickly the primary content becomes available. However If
the connection closes early (user hits stop for instance) or there is a
server error which prevents additional HTML from being delivered to the
client this can put React into a broken state where the boundary never
resolves nor errors and the hydration never retries that boundary
freezing it in it's fallback state.
Once the document has fully loaded we know there is not way any
additional Suspense boundaries can arrive. This update changes react-dom
on the client to schedule client renders for any unfinished Suspense
boundaries upon document loading.
The technique for client rendering a fallback is pretty straight
forward. When hydrating a Suspense boundary if the Document is in
'complete' readyState we interpret pending boundaries as fallback
boundaries. If the readyState is not 'complete' we register an event to
retry the boundary when the DOMContentLoaded event fires.
To test this I needed JSDOM to model readyState. We previously had a
temporary implementation of readyState for SSR streaming but I ended up
implementing this as a mock of JSDOM that implements a fake readyState
that is mutable. It starts off in 'loading' readyState and you can
advance it by mutating document.readyState. You can also reset it to
'loading'. It fires events when changing states.
This seems like the least invasive way to get closer-to-real-browser
behavior in a way that won't require remembering this subtle detail
every time you create a test that asserts Suspense resolution order.
## Overview
Changes the error message to say "Server Functions" instead of "Server
Actions" since this error can fire in cases like:
```
<button onClick={serverFunction} />
```
Which is calling a server function, not a server action.
Fixes a bug with the experimental `useResourceEffect` hook where we
would compare the wrong deps when there happened to be another kind of
effect preceding the ResourceEffect. To do this correctly we need to add
a pointer to the ResourceEffect's identity on the update.
I also unified the previously separate push effect impls for resource
effects since they are always pushed together as a unit.
This lets us track separately if something was suspended on an Action
using useActionState rather than suspended on Data.
This approach feels quite bloated and it seems like we'd eventually
might want to read more information about the Promise that suspended and
the context it suspended in. As a more general reason for suspending.
The way useActionState works in combination with the prewarming is quite
unfortunate because 1) it renders blocking to update the isPending flag
whether you use it or not 2) it prewarms and suspends the useActionState
3) then it does another third render to get back into the useActionState
position again.
## Summary
I'm working to get the main `react-native` package parsable by modern
Flow tooling (both `flow-bundler`, `flow-api-translator`), and one
blocker is legacy `module.exports` syntax. This diff updates files which
are [synced to
`react-native`](https://github.com/facebook/react-native/tree/main/packages/react-native/Libraries/Renderer/shims)
from this repo.
## How did you test this change?
Files were pasted into `react-native-github` under fbsource, where Flow
validates ✅.
Backs out the 2 related commits:
-
f8f6e1a21a
-
6c0f37f94b
Since I only realized when syncing that we need the version of `react`
and the legacy renderer to match.
While I investigate if there's anything we can do to work around that
while preserving the legacy renderer, this unblocks the sync.
We don't actually want the source mapped version of `.stack` from errors
because that would cause us to not be able to associate it with a source
map in the UIs that need it. The strategy in browsers is more correct
where the display is responsible for source maps.
That's why we disable any custom `prepareStackTrace` like the ones added
by `source-map`. We reset it to `undefined`.
However, when running node with `--enable-source-maps` the default for
`prepareStackTrace` which is a V8 feature (but may exist elsewhere too
like Bun) is a source mapped version of the stack. In those environments
we need to reset it to a default implementation that doesn't apply
source maps.
We already did this in Flight using the `ReactFlightStackConfigV8.js`
config. However, we need this more generally in the
`shared/ReactComponentStackFrame` implementation.
We could always set it to the default implementation instead of
`undefined` but that's unnecessary code in browser builds and it might
lead to slightly different results. For safety and code size, this PR
does it with a fork instead.
All builds specific to `node` or `edge` (or `markup` which is a server
feature) gets the default implementation where as everything else (e.g.
browsers) get `undefined` since it's expected that this is not source
mapped. We don't have to do anything about the equivalent in React
DevTools since React DevTools doesn't run on the server.
Adds tests for Compiler integration.
This includes:
- Tests against Compiler from source.
- Versioned (18.2 - <19) tests against Compiler from npm.
For tests against React 18.2, I had to download `react-compiler-runtime`
from npm and put it to `react/compiler-runtime.js`.
Discovered yesterday while was publishing a new release.
NPM `10.x.x` changed the text for 404 errors, so this check was failing.
Instead of handling 404 as a signal, I think its better to just parse
the whole list of versions and check if the new one is already there.
This has been broken since the migration to GitHub actions.
Previously, we've been using `buildId` as an identifier from CircleCI.
I've decided to use a commit hash as an identifier, because I don't know
if there is a better option, and
`scripts/release/download_build_artifacts.js` allows us to download them
for a specific commit.
Bumps [ws](https://github.com/websockets/ws) from 6.2.2 to 6.2.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/websockets/ws/releases">ws's
releases</a>.</em></p>
<blockquote>
<h2>6.2.3</h2>
<h1>Bug fixes</h1>
<ul>
<li>Backported e55e5106 to the 6.x release line (eeb76d31).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="d87f3b6d3a"><code>d87f3b6</code></a>
[dist] 6.2.3</li>
<li><a
href="eeb76d313e"><code>eeb76d3</code></a>
[security] Fix crash when the Upgrade header cannot be read (<a
href="https://redirect.github.com/websockets/ws/issues/2231">#2231</a>)</li>
<li>See full diff in <a
href="https://github.com/websockets/ws/compare/6.2.2...6.2.3">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
You can trigger a rebase of this PR by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/facebook/react/network/alerts).
</details>
> **Note**
> Automatic rebases have been disabled on this pull request as it has
been open for over 30 days.
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Summary
Builds `react-dom` for React Native so that it also populates the
`builds/facebook-fbsource` branch.
**NOTE:** For Meta employees, D61354219 is the internal integration.
## How did you test this change?
```
$ yarn build
…
$ ls build/facebook-react-native/react-dom/cjs
ReactDOM-dev.js ReactDOM-prod.js ReactDOM-profiling.js
```
## Summary
When a view config can not be found, it currently errors with
`TypeError: Cannot read property 'bubblingEventTypes' of null`. Instead
invariant at the correct location and prevent further processing of the
null viewConfig to improve the error logged.
## How did you test this change?
Build and run RN playground app referencing an invalid native view
through `requireNativeComponent`.
## Summary
This PR bumps Flow all the way to the latest 0.245.2.
Most of the suppressions comes from Flow v0.239.0's change to include
undefined in the return of `Array.pop`.
I also enabled `react.custom_jsx_typing=true` and added custom jsx
typing to match the old behavior that `React.createElement` is
effectively any typed. This is necessary since various builtin
components like `React.Fragment` is actually symbol in the React repo
instead of `React.AbstractComponent<...>`. It can be made more accurate
by customizing the `React$CustomJSXFactory` type, but I will leave it to
the React team to decide.
## How did you test this change?
`yarn flow` for all the renderers
### Based on
- #30761
- #30759
---
`use` has an optimization where in some cases it can suspend the work
loop during the render phase until the data has resolved, rather than
unwind the stack and lose context. However, the current implementation
is not compatible with sibling prerendering. So I've temporarily
disabled it until the sibling prerendering has been refactored. We will
add it back in a later step.
The unbundled form is just a way to show case a prototype for how an
unbundled version of RSC can work. It's not really intended for every
bundler combination to provide such a configuration.
There's no configuration of Turbopack that supports this mode atm and
possibly never will be since it's more of an integrated server/client
experience.
This removes the unbundled form and node register/loaders from the
turbopack build.
Follow up to #30741.
This is just for the reference Webpack implementation.
If there is a source map associated with a Node ESM loader, we generate
new source map entries for every `registerServerReference` call.
To avoid messing too much with it, this doesn't rewrite the original
mappings. It just reads them while finding each of the exports in the
original mappings. We need to read all since whatever we append at the
end is relative. Then we just generate new appended entries at the end.
For the location I picked the location of the local name identifier.
Since that's the name of the function and that gives us a source map
name index. It means it jumps to the name rather than the beginning of
the function declaration. It could be made more clever like finding a
local function definition if it is reexported. We could also point to
the line/column of the function declaration rather than the identifier
but point to the name index of the identifier name.
Now jumping to definition works in the fixture.
<img width="574" alt="Screenshot 2024-08-20 at 2 49 07 PM"
src="https://github.com/user-attachments/assets/7710f0e6-2cee-4aad-8d4c-ae985f8289eb">
Unfortunately this technique doesn't seem to work in Firefox nor Safari.
They don't apply the source map for jumping to the definition.
Shortcut for the common case where only a single flag is checked. Same
as `gate(flags => flags.enableFeatureFlag)`.
Normally I don't care about these types of conveniences but I'm about to
add a lot more inline flag checks these all over our tests and it gets
noisy. This helps a bit.
Noticed this from #30707. This was vestigial from from circleci and now
that we're on GH actions I think we should be able to remove this option
altogether.
ghstack-source-id: 78e8b0243b
Pull Request resolved: https://github.com/facebook/react/pull/30753
Prerendering in flight is similar to prerendering in Fizz. Instead of
receiving a result (the stream) immediately a promise is returned which
resolves to the stream when the prerender is complete. The promise will
reject if the flight render fatally errors otherwise it will resolve
when the render is completed or is aborted.
This commit updates the file locations and bulid configurations for
flight in preparation for new static entrypoints. This follows a
structure similar to Fizz which has a unified build but exports methods
from different top level entrypoints. This PR doesn't actually add the
new top level entrypoints however, that will arrive in a later update.
<!--
Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.
Before submitting a pull request, please make sure the following is
done:
1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
10. If you haven't already, complete the CLA.
Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->
## Summary
Just fixing some copy-paste typos.
## How did you test this change?
Untested.
Adding `__IS_NATIVE__` global, which will be used for forking backend
implementation. Will only be set to `true` for `react-devtools-core`
package, which is used by `react-native`.
Ideally, we should name it `react-devtools-native`, and keep
`react-devtools-core` as host-agnostic.
With this change, the next release of `react-devtools-core` should
append component stack as Error object, not as string, and should add
`(<anonymous>)` suffix to component stack frames.
Several CI workflows depend on the runtime_build_and_test.yml workflow
to complete before it can successfully download the build artifact.
However it is possible to encounter a race condition where the build
hasn't completed when the new workflow is started.
This PR adds a simple polling mechanism that waits up to 10 minutes for
the build for that revision to complete.
ghstack-source-id: 6a954638a800fbea8081e6fba35ee4b4437731c5
Pull Request resolved: https://github.com/facebook/react/pull/30515
Added instructions on the new workflow. Let's keep this short around for
now as it may be used again due to muscle memory and emit a helpful
message instead.
ghstack-source-id: 3f840a3d4319309d31cefeae028f97d280b0c09a
Pull Request resolved: https://github.com/facebook/react/pull/30510