Commit Graph

16669 Commits

Author SHA1 Message Date
Josh Story ba1a9797ee Remove flight-browser fixture (#28828)
The flight-browser fixtures doesn't make sense. It also uses UMD builds
which are being removed so we'd have to make it use esm.sh or something
and really it just won't work because it needs to be built by webpack to
not error. We could potentially shim the webpack globals but really the
right thing is to publish the esm version of react-server and use esm.sh
to load a browser only esm demo of react-server. This change removes the
flight-browser fixture
2024-04-12 09:48:40 -07:00
Ruslan Lesiutin 7625f0d501 feat[devtools-fusebox]: support theme option (#28832)
Support propagating theme from Chrome DevTools frontend, the field is
optional.

Next step, which is out of scope of this project and general improvement
for React DevTools: teach RDT to listen to theme changes and if the
theme preference is set to `auto` in settings, update the theme
accordingly with the browser devtools.
2024-04-12 17:26:37 +01:00
Ruslan Lesiutin 96c5846610 feat[devtools]: add package for fusebox integration (#28553)
## Summary

Stacked on https://github.com/facebook/react/pull/28552. Review only the
[last commit at the
top](https://github.com/facebook/react/pull/28553/commits/c69952f1bf6e23252d47e0f7eb98efbbb2cc2c55).

These changes add new package `react-devtools-fusebox`, which is the
entrypoint for the RDT Frontend, which will be used in Chrome DevTools
panel. The main differences from other frontend shells (extension,
standalone) are:
1. This package builds scripts in ESM format, this is required by Chrome
DevTools, see webpack config:

https://github.com/facebook/react/blob/c69952f1bf6e23252d47e0f7eb98efbbb2cc2c55/packages/react-devtools-fusebox/webpack.config.frontend.js#L50-L52
2. The build includes styles in a separate `.css` file, which is
required for Chrome DevTools: styles are loaded lazily once panel is
mounted.
2024-04-12 15:29:35 +01:00
Ruslan Lesiutin d012a32f84 feat[devtools]: add method for connecting backend with custom messaging protocol (#28552)
## Summary

RDT backend will now expose method `connectWithCustomMessagingProtocol`,
which will be similar to the classic `connectToDevTools` one, but with
few differences:
1. It delegates the communication management between frontend and
backend to the owner (whos injecting RDT backend). Unlike the
`connectToDevTools`, which is relying on websocket connection and
receives host and port as an arguments.
2. It returns a callback, which can be used for unsubscribing the
current backend instance from the global DevTools hook.


This is a prerequisite for any non-browser RDT integration, which is not
designed to be based on websocket.
2024-04-12 15:17:07 +01:00
Josh Story c8a035036d [Fizz] hoistables should never flush before the preamble (#28802)
Hoistables should never flush before the preamble however there is a
surprisingly easy way to trigger this to happen by suspending in the
shell of the app. This change modifies the flushing behavior to not emit
any hoistables before the preamble has written. It accomplishes this by
aborting the flush early if there are any pending root tasks remaining.
It's unfortunate we need this extra condition but it's essential that we
don't emit anything before the preamble and at the moment I don't see a
way to do that without introducing a new condition.

There is a test that began to fail with this update. It turns out that
in node the root can be blocked during a resume even for a component
inside a Suspense boundary if that boundary was part of the prerender.
This means that with the current heuristic in this PR boundaries cannot
be flushed during resume until the root is unblocked. This is not ideal
but this is already how Edge works because the root blocks the stream in
that case. This just makes Node deopt in a similar way to edge. We
should improve this but we ought to do so in a way that works for edge
too and it needs to be more comprehensive.
2024-04-11 15:13:04 -07:00
Sebastian Silbermann 4f5c812a3c DevTools: Rely on sourcemaps to compute hook name of built-in hooks in newer versions (#28593) 2024-04-11 22:00:54 +02:00
Jack Pope 4354159623 Backwards compatibility for string refs on WWW (#28826)
Seeing errors with undefined string ref values when trying to sync
https://github.com/facebook/react/pull/28473

Added a test that reproduces the failing pattern.

@acdlite pushed
https://github.com/facebook/react/pull/28826/commits/a786481ae5702f1966ecdb62f3667f3d72966e78
with fix

---------

Co-authored-by: Jack Pope <jackpope@meta.com>
Co-authored-by: Andrew Clark <git@andrewclark.io>
2024-04-11 15:30:37 -04:00
Sebastian Silbermann adb7173938 Fix nightly release job for real (#28825) 2024-04-11 18:28:10 +02:00
Sebastian Silbermann a2582074b8 Fix nightly release job (#28824) 2024-04-11 18:08:13 +02:00
Ricky 608edcc90a [tests] add assertConsole<method>Dev helpers (#28732)
## Overview
**Internal React repo tests only**

Depends on https://github.com/facebook/react/pull/28710

Adds three new assertions:
- `assertConsoleLogDev`
- `assertConsoleWarnDev`
- `assertConsoleErrorDev`

These will replace this pattern:

```js
await expect(async () => {
  await expect(async () => {
    await act(() => {
      root.render(<Fail />)
    });
  }).toThrow();
}).toWarnDev('Warning');
```

With this:

```js
await expect(async () => {
  await act(() => {
    root.render(<Fail />)
  });
}).toThrow();

assertConsoleWarnDev('Warning');
```

It works similar to our other `assertLog` matchers which clear the log
and assert on it, failing the tests if the log is not asserted before
the test ends.

## Diffs

There are a few improvements I also added including better log diffs and
more logging.

When there's a failure, the output will look something like:

<img width="655" alt="Screenshot 2024-04-03 at 11 50 08 AM"
src="https://github.com/facebook/react/assets/2440089/0c4bf1b2-5f63-4204-8af3-09e0c2d752ad">


Check out the test suite for snapshots of all the failures we may log.
2024-04-11 08:19:46 -04:00
Andrew Clark da69b6af96 ReactDOM.requestFormReset (#28809)
Based on:

- #28808
- #28804 

---

This adds a React DOM method called requestFormReset that schedules a
form reset to occur when the current transition completes.

Internally, it's the same method that's called automatically whenever a
form action is submitted. It only affects uncontrolled form inputs. See
https://github.com/facebook/react/pull/28804 for details.

The reason for the public API is so UI libraries can implement their own
action-based APIs and maintain the form-resetting behavior, something
like this:

```js
function onSubmit(event) {
  // Disable default form submission behavior
  event.preventDefault();
  const form = event.target;
  startTransition(async () => {
    // Request the form to reset once the action
    // has completed
    requestFormReset(form);

    // Call the user-provided action prop
    await action(new FormData(form));
  })
}
```
2024-04-10 16:56:55 -04:00
Andrew Clark 374b5d26c2 Scaffolding for requestFormReset API (#28808)
Based on:

- #28804 

---

This sets adds a new ReactDOM export called requestFormReset, including
setting up the export and creating a method on the internal ReactDOM
dispatcher. It does not yet add any implementation.

Doing this in its own commit for review purposes.

The API itself will be explained in the next PR.
2024-04-10 16:55:15 -04:00
Andrew Clark 41950d14a5 Automatically reset forms after action finishes (#28804)
This updates the behavior of form actions to automatically reset the
form's uncontrolled inputs after the action finishes.

This is a frequent feature request for people using actions and it
aligns the behavior of client-side form submissions more closely with
MPA form submissions.

It has no impact on controlled form inputs. It's the same as if you
called `form.reset()` manually, except React handles the timing of when
the reset happens, which is tricky/impossible to get exactly right in
userspace.

The reset shouldn't happen until the UI has updated with the result of
the action. So, resetting inside the action is too early.

Resetting in `useEffect` is better, but it's later than ideal because
any effects that run before it will observe the state of the form before
it's been reset.

It needs to happen in the mutation phase of the transition. More
specifically, after all the DOM mutations caused by the transition have
been applied. That way the `defaultValue` of the inputs are updated
before the values are reset. The idea is that the `defaultValue`
represents the current, canonical value sent by the server.

Note: this change has no effect on form submissions that aren't
triggered by an action.
2024-04-10 16:54:24 -04:00
Josh Story dc6a7e01e1 [Float] Don't preload images inside <noscript> (#28815)
`<noscript>` scopes should be considered inert from the perspective of
Fizz since we assume they'll only be used in rare and adverse
circumstances. When we added preload support for img tags we did not
include the noscript scope check in the opt-out for preloading. This
change adds it in

fixes: #27910
2024-04-10 12:15:04 -07:00
Ricky 3f947b1b46 [tests] Assert scheduler log empty in internalAct (#28737)
We should force `assertLog` to be called before each `act` block to
ensure the queue is empty.

Requires fixing tests:
- https://github.com/facebook/react/pull/28745
- https://github.com/facebook/react/pull/28758
- https://github.com/facebook/react/pull/28759
- https://github.com/facebook/react/pull/28760
- https://github.com/facebook/react/pull/28761
- https://github.com/facebook/react/pull/28762
- https://github.com/facebook/react/pull/28763
- https://github.com/facebook/react/pull/28812
2024-04-10 14:13:46 -04:00
Ricky 870e4045ab [tests] add assertLog for legacy mode tests (#28814)
A few more tests for https://github.com/facebook/react/pull/28737
2024-04-10 14:01:59 -04:00
Josh Story a8a83f7a59 Removes the react-interactions project which is unused (#28799)
Removes the react-interactions project which is unused

This project uses `unstable_createEventHandle` which is being removed
from React in version 19
2024-04-10 09:18:33 -07:00
Ricky bf09089f64 Remove Scheduler.log from ReactSuspenseFuzz-test (#28812)
These test don't `assertLog` or `waitFor` so we don't need to
`Scheduler.log`. Ideally we would, but since they're fuzzers it's a bit
difficult to know what the expected log is from the helper.

Since this doesn't regress current test behavior, we can improve them
after this to unblock https://github.com/facebook/react/pull/28737
2024-04-10 11:40:22 -04:00
Ricky 84cb3b4cb2 Hardcode disableIEWorkarounds for www (#28811)
This has landed and is true everywhere, but let's keep the flag until it
lands in the stable release.
2024-04-10 11:14:33 -04:00
Ricky 2243b40aba [tests] assertLog before act in useEffectEvent (#28763)
Fixes tests blocking https://github.com/facebook/react/pull/28737
2024-04-10 10:34:34 -04:00
Ricky dfc64c6e31 [tests] assertLog before act in ReactUse (#28762)
Fixes tests blocking https://github.com/facebook/react/pull/28737
2024-04-10 10:34:27 -04:00
Ricky b02199d322 [tests] assertLog before act in ReactErrorBoundaries (#28761)
Fixes tests blocking https://github.com/facebook/react/pull/28737
2024-04-10 10:34:19 -04:00
Ricky 6e1e2f2198 [tests] assertLog before act in ReactUpdates (#28760)
Fixes tests blocking https://github.com/facebook/react/pull/28737
2024-04-10 10:34:11 -04:00
Ricky 88df5242d6 [tests] assertLog before act in ReactDOMServerSelectiveHydration (#28759)
Fixes tests blocking https://github.com/facebook/react/pull/28737
2024-04-10 10:34:02 -04:00
Ricky e36ee763fa [tests] assertLog before act in ReactCompositeComponentState (#28758)
Fixes tests blocking https://github.com/facebook/react/pull/28737
2024-04-10 10:33:51 -04:00
Ricky 42eff4bc78 [tests] Fix assertions not flushed before act (#28745)
Fixes some easy cases blocking
https://github.com/facebook/react/pull/28737, I'll follow up with more
complex/interesting cases in other PRs.
2024-04-10 10:33:41 -04:00
Andrew Clark ed3c65caf0 Warn if outdated JSX transform is detected (#28781)
We want to warn if we detect that an app is using an outdated JSX
transform. We can't just warn if `createElement` is called because we
still support `createElement` when it's called manually. We only want to
warn if `createElement` is output by the compiler.

The heuristic is to check for a `__self` prop, which is an optional,
internal prop that older transforms used to pass to `createElement` for
better debugging in development mode.

If `__self` is present, we `console.warn` once with advice to upgrade to
the modern JSX transform. Subsequent elements will not warn.

There's a special case we have to account for: when a static "key" prop
is defined _after_ a spread, the modern JSX transform outputs
`createElement` instead of `jsx`. (This is because with `jsx`, a spread
key always takes precedence over a static key, regardless of the order,
whereas `createElement` respects the order.) To avoid a false positive
warning, we skip the warning whenever a `key` prop is present.
2024-04-09 17:13:19 -04:00
Andrew Clark 3f9e237a2f Fix: Suspend while recovering from hydration error (#28800)
Fixes a bug that happens when an error occurs during hydration, React
switches to client rendering, and then the client render suspends. It
works correctly if there's a Suspense boundary on the stack, but not if
it happens in the shell of the app.

Prior to this fix, the app would crash with an "Unknown root exit
status" error.

I left a TODO comment for how we might refactor this code to be less
confusing in the future.
2024-04-09 17:11:46 -04:00
Joseph Savona 64c8d2d45d Attempt to fix diff syncing for Meta (#28801)
#28796 broke Meta's PR syncing tool, hoping this fixes it
2024-04-09 14:05:18 -07:00
Joseph Savona 7f5d25e23e Fix cloneElement using string ref w no owner (#28797)
Fix for an issue introduced in #28473 where cloneElement() with a string
ref fails due to lack of an owner. We should use the current owner in
this case.

---------

Co-authored-by: Rick Hanlon <rickhanlonii@fb.com>
2024-04-09 13:43:49 -07:00
Josh Story bf40b02442 [Fizz] Stop publishing external-runtime to stable channel (#28796)
The external runtime is not vetted for stability yet. We should stop
publishing it with our stable build
2024-04-09 11:57:58 -07:00
Josh Story 67ff96e12d [Tests][Fizz] Test script runtime even when external runtime is available (#28794)
Previously if the external runtime was enabled Fizz tests would use it
exclusively. However now that this flag is enabled for OSS and Meta
builds this means we were no longer testing the inline script runtime.
This changes the test flags to produce some runs where we test the
inline script runtime and others where we test the external runtime

the external runtime will be tested if the flag is enabled and
* Meta Builds: variant is true
* OSS Builds: experiemental is true

this gives us decent coverage. long term we should probably bring
variant to OSS builds since we will eventually want to test both modes
even when the external runtime is stable.
2024-04-09 11:50:02 -07:00
Josh Story 7f93cb41c8 [DOM] Infer react-server entries bundles if not explicitly configured (#28795)
When packaging we want to infer that a bundle exists for a
`react-server` file even if it isn't explicitly configured. This is
useful in particular for the react-server entrypoints that error on
import that were recently added to `react-dom`

This change also cleans up a wayward comment left behind in a prior PR
2024-04-09 10:39:25 -07:00
Sebastian Markbåge f613165357 Rename SECRET INTERNALS to __CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE (#28789)
Follow up to #28783 and #28786.

Since we've changed the implementations of these we can rename them to
something a bit more descriptive while we're at it, since anyone
depending on them will need to upgrade their code anyway.

"react" with no condition:
`__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
"react" with "react-server" condition:
`__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
"react-dom":
`__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE`
2024-04-09 12:20:22 -04:00
Sebastian Silbermann 50895bc161 CI: Run with Node.js 18.20 (#28774) 2024-04-09 16:02:22 +02:00
Jan Kassens cffbcac8e3 Run stale job hourly (#28769) 2024-04-09 09:21:20 -04:00
Ricky 9644d206e8 Soften useFormState warning (#28788)
It's not deprecated, it's really just renamed. Let's make the warning
less scary.
2024-04-08 23:22:17 -04:00
Sebastian Markbåge c771016e19 Rename The Secret Export of Server Internals (#28786)
We have a different set of dispatchers that Flight uses. This also
includes the `jsx-runtime` which must also be aliased to use the right
version.

To ensure the right versions are used together we rename the export of
the SharedInternals from 'react' and alias it in relevant bundles.
2024-04-08 22:34:59 -04:00
Sebastian Markbåge d50323eb84 Flatten ReactSharedInternals (#28783)
This is similar to #28771 but for isomorphic. We need a make over for
these dispatchers anyway so this is the first step. Also helps flush out
some internals usage that will break anyway.

It flattens the inner mutable objects onto the ReactSharedInternals.
2024-04-08 19:23:23 -04:00
Josh Story acef2f8111 [DOM] Fix package.json files for #28784 (#28785)
Missed some files for the react-server disallow client change in #28784
2024-04-08 15:49:18 -07:00
Josh Story 556a087de3 [DOM] disallow client entrypoints with react-server condition (#28784)
`react-server` precludes loading code that expects to be run in a client
context. This includes react-dom/client react-dom/server
react-dom/unstable_testing react-dom/profiling and react-dom/static

This update makes importing any of these client only entrypoints an
error
2024-04-08 15:37:06 -07:00
Josh Story f62cf8c620 [Float] treat props.async in Float consistent with the rest of react-dom (#26760)
Treat async (boolean prop) consistently with Float. Previously float
checked if `props.async === true` (or not true) but the rest of
react-dom considers anything truthy that isn't a function or symbol as
`true`. This PR normalizes the Float behavior.
2024-04-08 14:26:58 -07:00
Hugo Sales dfd3d5af83 Add support for transition{run,start,cancel} events (#27345) 2024-04-08 23:23:04 +02:00
Josh Story 1f8327f834 [Fiber] Use real event priority for hydration scheduling (#28765)
Stacked on #28751 

Historically explicit hydration scheduling used the reconciler's update
priority to schedule the hydration. There was a lingering todo to switch
to using event priority in the absence of an explicit update priority.
This change updates the hydration priority by referring to the event
priority if no update priority is set
2024-04-08 14:05:17 -07:00
Josh Story 97c90ed883 [DOM] Shrink ReactDOMCurrentDispatcher method names (#28770)
Stacked on #28771 

ReactDOMCurrentDispatcher has longer property names for various methods.
These methods are only ever called internally and don't need to be
represented with as many characters. This change shortens the names and
aligns them with the hint codes we use in Flight. This alignment is
passive since not all dispatcher methods will exist as flight
instructions but where they can line up it seems reasonable to make them
do so
2024-04-08 13:54:30 -07:00
Josh Story 9007fdc8f1 [DOM] Shrink ReactDOMSharedInternals source representation (#28771)
Stacked on #28751 

ReactDOMSharedInternals uses properties of considerable length to model
mutuable state. These properties are not mangled during minification and
contribute a not insigificant amount to the uncompressed bundle size and
to a lesser degree compressed bundle size.

This change rewrites the DOMInternals in a way that shortens property
names so we can have smaller builds.
It also treats the entire object as a mutable container rather than
having different mutable sub objects.

The same treatment should be given to ReactSharedInternals
2024-04-08 13:39:39 -07:00
Sebastian Markbåge 14f50ad155 [Flight] Allow lazily resolving outlined models (#28780)
We used to assume that outlined models are emitted before the reference
(which was true before Blobs). However, it still wasn't safe to assume
that all the data will be available because an "import" (client
reference) can be async and therefore if it's directly a child of an
outlined model, it won't be able to update in place.

This is a similar problem as the one hit by @unstubbable in #28669 with
elements, but a little different since these don't follow the same way
of wrapping.

I don't love the structuring of this code which now needs to pass a
first class mapper instead of just being known code. It also shares the
host path which is just an identity function. It wouldn't necessarily
pass my own review but I don't have a better one for now. I'd really
prefer if this was done at a "row" level but that ends up creating even
more code.

Add test for Blob in FormData and async modules in Maps.
2024-04-08 15:40:11 -04:00
Josh Story 01bb3c5632 [TestUtils] Build limited test-utils (#28782)
We landed a flag to disable test utils in many builds but we need to
fork the entrypoint to make it work with tests properly. This also
removes test-utils implementations from builds that do not support it.
Currently in OSS builds the only thing in test-utils is a reexport of
`act`
2024-04-08 12:27:20 -07:00
Ruslan Lesiutin 6de7733e73 feat[devtools]: ship source maps for content scripts and ignore list installHook script (#28730)
## Summary

1. RDT browser extension's content scripts will now ship source maps
(without source in prod, to save some bundle size).
2. `installHook` content script will be ignore listed via `ignoreList`
field in the corresponding source map.
3. Previously, source map for backend file used `x_google_ignoreList`
naming, now `ignoreList`.

## How did you test this change?

1. `ignoreList-test.js`
2. Tested manually that I don't see `installHook` in stack traces when
`console.error` is called.
2024-04-08 18:10:09 +01:00
Josh Story 4c12339ce3 [DOM] move flushSync out of the reconciler (#28500)
This PR moves `flushSync` out of the reconciler. there is still an
internal implementation that is used when these semantics are needed for
React methods such as `unmount` on roots.

This new isomorphic `flushSync` is only used in builds that no longer
support legacy mode.

Additionally all the internal uses of flushSync in the reconciler have
been replaced with more direct methods. There is a new
`updateContainerSync` method which updates a container but forces it to
the Sync lane and flushes passive effects if necessary. This combined
with flushSyncWork can be used to replace flushSync for all instances of
internal usage.

We still maintain the original flushSync implementation as
`flushSyncFromReconciler` because it will be used as the flushSync
implementation for FB builds. This is because it has special legacy mode
handling that the new isomorphic implementation does not need to
consider. It will be removed from production OSS builds by closure
though
2024-04-08 09:03:20 -07:00