Commit Graph

15860 Commits

Author SHA1 Message Date
acdlite ec00d40eaa Always warn if client component suspends with an uncached promise (#28159)
Previously we only warned during a synchronous update, because we
eventually want to support async client components in controlled
scenarios, like during navigations. However, we're going to warn in all
cases for now until we figure out how that should work.

DiffTrain build for [178f435194](https://github.com/facebook/react/commit/178f4351947a842ff0b56700e9115b25ae8f20d0)
2024-01-30 19:28:23 +00:00
gnoff fa09a710fb [Fizz] improve Hoistable handling for Elements and Resources inside Suspense Boundaries (#28069)
Updates Fizz to handle Hoistables (Resources and Elements) in a way that
better aligns with Suspense fallbacks

1. Hoistable Elements inside a fallback (regardless of how deep and how
many additional boundaries are intermediate) will be ignored. The
reasoning is fallbacks are transient and since there is not good way to
clean up hoistables because they escape their Suspense container its
better to not emit them in the first place. SSR fallbacks are already
not full fidelity because they never hydrate so this aligns with that
somewhat.
2. Hoistable stylesheets in fallbacks will only block the reveal of a
parent suspense boundary if the fallback is going to flush with that
completed parent suspense boundary. Previously if you rendered a
stylesheet Resource inside a fallback any parent suspense boundaries
that completed after the shell flushed would include that resource in
the set required to resolve before the boundary reveal happens on the
client. This is not a semantic change, just a performance optimization
3. preconnect and preload hoistable queues are gone, if you want to
optimize resource loading you shoudl use `ReactDOM.preconnect` and
`ReactDOM.preload`. `viewport` meta tags get their own queue because
they need to go before any preloads since they affect the media state.

In addition to those functional changes this PR also refactors the
boundary resource tracking by moving it to the task rather than using
function calls at the start of each render and flush. Tasks also now
track whether they are a fallback task

supercedes prior work here: https://github.com/facebook/react/pull/27534

DiffTrain build for [554fc49f41](https://github.com/facebook/react/commit/554fc49f41465d914b15dc8eb2ec094f37824f7e)
2024-01-30 18:20:40 +00:00
gnoff bc0fa9ecd7 [Fiber] Use a safer strategy to track the last precedence (#28110)
Uses a safer strategy to track the last precedence to avoid the need to
consistently remember to preprend `'p'` to the precedence value

DiffTrain build for [1c958aa4ab](https://github.com/facebook/react/commit/1c958aa4abf9e6b638489b1d73cdb1b6dc7c3ab6)
2024-01-30 18:15:00 +00:00
rickhanlonii 52a1078a24 Remove outdated enableSchedulerDebugging flag (#28101)
This flag was moved to the scheduler feature flags, so these flags don't
do anything.

DiffTrain build for [766eac46bb](https://github.com/facebook/react/commit/766eac46bb52bda28f87c11740214a4444ca881b)
2024-01-26 21:57:53 +00:00
acdlite c6f9c3abf5 Capture React.startTransition errors and pass to reportError (#28111)
To make React.startTransition more consistent with the hook form of
startTransition, we capture errors thrown by the scope function and pass
them to the global reportError function. (This is also what we do as a
default for onRecoverableError.)

This is a breaking change because it means that errors inside of
startTransition will no longer bubble up to the caller. You can still
catch the error by putting a try/catch block inside of the scope
function itself.

We do the same for async actions to prevent "unhandled promise
rejection" warnings.

The motivation is to avoid a refactor hazard when changing from a sync
to an async action, or from useTransition to startTransition.

DiffTrain build for [60f190a559](https://github.com/facebook/react/commit/60f190a55948a7512d4e2a336f03b45fd38d6a80)
2024-01-26 17:15:15 +00:00
gnoff c53cad6bbe fix incorrect insertion order of stylesheets (#28108)
## Summary

In the precendences Map every key is prefixed with `p`. This fixes one
case where this is missing.

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->

DiffTrain build for [763612647c](https://github.com/facebook/react/commit/763612647ceb66d95f728af896ca5e18a8181db8)
2024-01-26 16:00:50 +00:00
acdlite bd16b96a44 Async action support for React.startTransition (#28097)
This adds support for async actions to the "isomorphic" version of
startTransition (i.e. the one exported by the "react" package).
Previously, async actions were only supported by the startTransition
that is returned from the useTransition hook.

The interesting part about the isomorphic startTransition is that it's
not associated with any particular root. It must work with updates to
arbitrary roots, or even arbitrary React renderers in the same app. (For
example, both React DOM and React Three Fiber.)

The idea is that React.startTransition should behave as if every root
had an implicit useTransition hook, and you composed together all the
startTransitions provided by those hooks. Multiple updates to the same
root will be batched together. However, updates to one root will not be
batched with updates to other roots.

Features like useOptimistic work the same as with the hook version.

There is one difference from from the hook version of startTransition:
an error triggered inside an async action cannot be captured by an error
boundary, because it's not associated with any particular part of the
tree. You should handle errors the same way you would in a regular
event, e.g. with a global error event handler, or with a local
`try/catch`.

DiffTrain build for [85b296e9b6](https://github.com/facebook/react/commit/85b296e9b6ded4accd9ec3389297f95091fb1ac0)
2024-01-26 02:59:47 +00:00
sebmarkbage b9b97d9ac8 [Flight/Fizz] Reset ThenableState Only in Branches Where It's Added (#28068)
Before, we used to reset the thenable state and extract the previous
state very early so that it's only the retried task that can possibly
consume it. This is nice because we can't accidentally consume that
state for any other node.

However, it does add a lot of branches of code that has to pass this
around. It also adds extra bytes on the stack per node. Even though it's
mostly just null.

This changes it so that where ever we can create a thenable state (e.g.
entering a component with hooks) we first extract this from the task.
The principle is that whatever could've created the thenable state in
the first place, must always be rerendered so it'll take the same code
paths to get there and so we'll always consume it.

DiffTrain build for [382190c595](https://github.com/facebook/react/commit/382190c595126837ee7e43b4fa953f4edd30e01c)
2024-01-26 00:58:02 +00:00
sebmarkbage 68cd468ecd [Flight] Refactor the Render Loop to Behave More Like Fizz (#28065)
This refactors the Flight render loop to behave more like Fizz with
similar naming conventions. So it's easier to apply similar techniques
across both. This is not necessarily better/faster - at least not yet.

This doesn't yet implement serialization by writing segments to chunks
but we probably should do that since the built-in parts that
`JSON.stringify` gets us isn't really much anymore (except serializing
strings). When we switch to that it probably makes sense for the whole
thing to be recursive.

Right now it's not technically fully recursive because each recursive
render returns the next JSON value to encode. So it's kind of like a
trampoline. This means we can't have many contextual things on the
stack. It needs to use the Server Context `__POP` trick. However, it
does work for things that are contextual only for one sequence of server
component abstractions in a row. Since those are now recursive.

An interesting observation here is that `renderModel` means that
anything can suspend while still serializing the outer siblings.
Typically only Lazy or Components would suspend but in principle a Proxy
can suspend/postpone too and now that is left serialized by reference to
a future value. It's only if the thing that we rendered was something
that can reduce to Lazy e.g. an Element that we can serialize it as a
lazy.

Similarly to how Suspense boundaries in Fizz can catch errors, anything
that can be reduced to Lazy can also catch an error rather than bubbling
it. It only errors when the Lazy resolves. Unlike Suspense boundaries
though, those things don't render anything so they're otherwise going to
use the destructive form. To ensure that throwing in an Element can
reuse the current task, this must be handled by `renderModel`, not for
example `renderElement`.

DiffTrain build for [b123b9c4f0](https://github.com/facebook/react/commit/b123b9c4f054a7def7ed84e350ccd46cc86672a6)
2024-01-25 17:14:06 +00:00
acdlite 69fea0b202 Batch async actions even if useTransition is unmounted (#28078)
If there are multiple updates inside an async action, they should all be
rendered in the same batch, even if they are separate by an async
operation (`await`). We currently implement this by suspending in the
`useTransition` hook to block the update from committing until all
possible updates have been scheduled by the action. The reason we did it
this way is so you can "cancel" an action by navigating away from the UI
that triggered it.

The problem with that approach, though, is that even if you navigate
away from the `useTransition` hook, the action may have updated shared
parts of the UI that are still in the tree. So we may need to continue
suspending even after the `useTransition` hook is deleted.

In other words, the lifetime of an async action scope is longer than the
lifetime of a particular `useTransition` hook.

The solution is to suspend whenever _any_ update that is part of the
async action scope is unwrapped during render. So, inside useState and
useReducer.

This fixes a related issue where an optimistic update is reverted before
the async action has finished, because we were relying on the
`useTransition` hook to prevent the optimistic update from finishing.

This also prepares us to support async actions being passed to the
non-hook form of `startTransition` (though this isn't implemented yet).

DiffTrain build for [11c9fd0c53](https://github.com/facebook/react/commit/11c9fd0c53133f24f5270d36591b65b8fc2ebd25)
2024-01-25 04:59:52 +00:00
rickhanlonii 605ae6d45e Convert ReactDOMTestSelectors-test.js to createRoot (#27993)
Straightforward adding createRoot and act

DiffTrain build for [4217d324ae](https://github.com/facebook/react/commit/4217d324ae5766b3201e682bb4d67b8855652694)
2024-01-24 04:06:34 +00:00
rickhanlonii d703a879f2 Update error decoder URL (#27240)
Updates the error decoder to the URL for the new docs site.

- Switches the domain from reactjs.org to react.dev
- Switches to put the error code in the URL for SSG
- All params are still in the query

Example without args:

- Before: `https://reactjs.org/docs/error-decoder.html?invariant=200`
- After: ` https://react.dev/errors/200`

Example with args:
- Before:
`https://reactjs.org/docs/error-decoder.html?invariant=124?args[]=foo&args[]=bar
`
- After: ` https://react.dev/errors/124?args[]=foo&args[]=bar`

Requires: https://github.com/reactjs/react.dev/pull/6214

---------

Co-authored-by: Jan Kassens <jkassens@meta.com>

DiffTrain build for [b300304710](https://github.com/facebook/react/commit/b3003047101b4c7a643788a8faf576f7e370fb45)
2024-01-18 02:45:49 +00:00
acdlite a2531fa8a8 Remove client caching from cache() API (#27977)
We haven't yet decided how we want `cache` to work on the client. The
lifetime of the cache is more complex than on the server, where it only
has to live as long as a single request.

Since it's more important to ship this on the server, we're removing the
existing behavior from the client for now. On the client (i.e. not a
Server Components environment) `cache` will have not have any caching
behavior. `cache(fn)` will return the function as-is.

We intend to implement client caching in a future major release. In the
meantime, it's only exposed as an API so that Shared Components can use
per-request caching on the server without breaking on the client.

DiffTrain build for [5c607369ce](https://github.com/facebook/react/commit/5c607369ceebe56d85175df84b7b6ad58dd25e1f)
2024-01-17 01:31:57 +00:00
acdlite 0cd227f5e2 Refactor React Server entrypoint to not depend on the client one (#27940)
This refactors the Server Components entrypoint for the `react` package
(ReactServer.js) so that it doesn't depend on the client entrypoint
(React.js). I also renamed React.js to ReactClient.js to make the
separation clearer.

This structure will make it easier to add client-only and server-only
features.

DiffTrain build for [f16344ea6d](https://github.com/facebook/react/commit/f16344ea6db5bcc108de80dbc39a41ec28e8210d)
2024-01-17 01:23:48 +00:00
acdlite 5832ad09fd Rename "shared subset" to "server" (#27939)
The internal file ReactSharedSubset is what the `react` module resolves
to when imported from a Server Component environment. We gave it this
name because, originally, the idea was that Server Components can access
a subset of the APIs available on the client.

However, since then, we've also added APIs that can _only_ by accessed
on the server and not the client. In other words, it's no longer a
subset, it's a slightly different overlapping set.

So this commit renames ReactSharedSubet to ReactServer and updates all
the references. This does not affect the public API, only our internal
implementation.

DiffTrain build for [5d1b15a4f0](https://github.com/facebook/react/commit/5d1b15a4f06fa93e76cd89f37ea5bfd62cc66183)
2024-01-17 01:02:57 +00:00
acdlite f10aaf1267 Fix: useOptimistic should return passthrough value when there are no updates pending (#27936)
This fixes a bug that happened when the canonical value passed to
useOptimistic without an accompanying call to setOptimistic. In this
scenario, useOptimistic should pass through the new canonical value.

I had written tests for the more complicated scenario, where a new value
is passed while there are still pending optimistic updates, but not this
simpler one.

DiffTrain build for [60a927d04a](https://github.com/facebook/react/commit/60a927d04ad3888facebcdf7da620aa1cfc9528f)
2024-01-14 02:42:16 +00:00
sebmarkbage 990d5cc255 Use getComponentNameFromType for debug info for the key warning (#27930)
If this is a client reference we shouldn't dot into it, which would
throw in the proxy.

Interestingly our client references don't really have a `name`
associated with them for debug information so a component type doesn't
show up in error logs even though it seems like it should.

DiffTrain build for [0ac3ea471f](https://github.com/facebook/react/commit/0ac3ea471fbcb7d79bc7d36179e960c72c779e76)
2024-01-11 22:29:18 +00:00
noahlemen 827e912776 re-add dynamic feature flags for isInputPending (#27919)
## Summary

these were removed in https://github.com/facebook/react/pull/26617. adds
them back so we can conduct another experiment.

## How did you test this change?
`yarn test-www`

DiffTrain build for [c81f4e02ba](https://github.com/facebook/react/commit/c81f4e02bab9d03e1583047d041fdb5e4eb19415)
2024-01-09 22:25:42 +00:00
sebmarkbage 3d4df0a7de [Fizz] Fix Client Render after Postpone (#27905)
If we end up client rendering a boundary due to an error after we have
already injected a postponed hole in that boundary we'll end up trying
to target a missing segment. Since we never insert segments for an
already errored boundary into the HTML. Normally an errored prerender
wouldn't be used but if it is, such as if it was an intentional client
error it triggers this case. Those should really be replaced with
postpones though.

This is a bit annoying since we eagerly build up the postponed path. I
took the easy route here and just cleared out the suspense boundary
itself from having any postponed slots. However, this still creates an
unnecessary replay path along the way to the boundary. We could probably
walk the path and remove any empty parent nodes.

What is worse is that if this is the only thing that postponed, we'd
still generate a postponed state even though there's actually nothing to
resume. Since this is a bit of an edge case already maybe it's fine.

In my test I added a check for the `error` event on `window` since this
error only surfaces by throwing an ignored error. We should really do
that globally for all tests. Our tests should fail by default if there's
an error logged to the window.

DiffTrain build for [f9dddcbbb1](https://github.com/facebook/react/commit/f9dddcbbb1c0b73f974e78b9488927b778630682)
2024-01-09 04:57:25 +00:00
acdlite f748f7366c Fix: useDeferredValue initialValue suspends forever without switching to final (#27888)
Fixes a bug in the experimental `initialValue` option for
`useDeferredValue` (added in #27500).

If rendering the `initialValue` causes the tree to suspend, React should
skip it and switch to rendering the final value instead. It should not
wait for `initialValue` to resolve.

This is not just an optimization, because in some cases the initial
value may _never_ resolve — intentionally. For example, if the
application does not provide an instant fallback state. This capability
is, in fact, the primary motivation for the `initialValue` API.

I mostly implemented this correctly in the original PR, but I missed
some cases where it wasn't working:

- If there's no Suspense boundary between the `useDeferredValue` hook
and the component that suspends, and we're not in the shell of the
transition (i.e. there's a parent Suspense boundary wrapping the
`useDeferredValue` hook), the deferred task would get incorrectly
dropped.
- Similarly, if there's no Suspense boundary between the
`useDeferredValue` hook and the component that suspends, and we're
rendering a synchronous update, the deferred task would get incorrectly
dropped.

What these cases have in common is that it causes the `useDeferredValue`
hook itself to be replaced by a Suspense fallback. The fix was the same
for both. (It already worked in cases where there's no Suspense fallback
at all, because those are handled differently, at the root.)

The way I discovered this was when investigating a particular bug in
Next.js that would happen during a 'popstate' transition (back/forward),
but not during a regular navigation. That's because we render popstate
transitions synchronously to preserve browser's scroll position — which
in this case triggered the second scenario above.

DiffTrain build for [f1039be4a4](https://github.com/facebook/react/commit/f1039be4a48384e7e4b0a87d4d92c48e900053b9)
2024-01-08 04:22:01 +00:00
sebmarkbage f2094eebbf [Fizz] Only compute component stacks in DEV and prerenders (#27850)
If you have a lot of intentional throws (or postpones) from client-only
rendering then computing the stack is too much.

DiffTrain build for [c5b9375767](https://github.com/facebook/react/commit/c5b9375767e2c4102d7e5559d383523736f1c902)
2023-12-19 23:08:55 +00:00
alunyov beb4a4d2d1 [RSC @ Meta] Simplify implementation of isClientReference, getClientReferenceKey, resolveClientReferenceMetadata (#27839)
For clientReferences we can just check the instance of the
`clientReference`.
The implementation of `isClientReference` is provided via configuration.
The class for ClientReference has to implement an interface that has
`getModuleId() method.

DiffTrain build for [cb2439624f](https://github.com/facebook/react/commit/cb2439624f43c510007f65aea5c50a8bb97917e4)
2023-12-19 14:22:53 +00:00
gnoff 7fb394d17d [Fizz] Add Component Stacks to onError and onPostpone when in dev mode or during prerenders in prod mode (#27761)
Historically React would produce component stacks for dev builds only.
There is a cost to tracking component stacks and given the prod builds
try to optimize runtime performance these stacks were left out. More
recently React added production component stacks to Fiber in because it
can be immensely helpful in tracking down hard to debug production
issues. Fizz was not updated to have a similar behavior.

With the advent of prerendering however stacks for production in Fizz
are more relevant because prerendering is not really a dev-time task. If
you want the ability to reason about errors or postpones that happen
during a prerender having component stacks to interrogate is helpful and
these component stacks need to be available in production otherwise you
are really never going to see them. (it is possible that you could do
dev-mode prerenders but we don't expect this to be a common dev mode
workflow)

To better support the prerender use case and to make error logging in
Fizz more useful the following changes have been made

1. `onPostpone` now accepts a second `postponeInfo` argument which will
contain a componentStack. Postpones always originate from a component
render so the stack should be consistently available. The type however
will indicate the stack is optional so we can remove them in the future
if we decide the overhead is the wrong tradeoff in certain cases
2. `onError` now accepts a second `errorInfo` argument which may contain
a componentStack. If an error originated from a component a stack will
be included in the following cases.

This change entails tracking the component hierarchy in prod builds now.
While this isn't cost free it is implemented in a relatively lean
manner. Deferring the most expensive work (reifying the stack) until we
are actually in an error pathway.

In the course of implementing this change a number of simplifications
were made to the code which should make the stack tracking more
resilient. We no longer use a module global to curry the stack up to
some handler. This was delicate because you needed to always reset it
properly. We now curry the stack on the task itself.

Another change made was to track the component stack on SuspenseBoundary
instances so that we can provide the stack when aborting suspense
boundaries to help you determine which ones were affected by an abort.

DiffTrain build for [63310df2b2](https://github.com/facebook/react/commit/63310df2b243b6c3b2f01e8b121e7d115e839cfb)
2023-12-16 02:10:31 +00:00
kassens 9996001938 Add feature flags for expiration times (#27821)
It seems worthwhile to me to run a test to experiment with different
expiration times. This moves the expiration times for scheduler and
reconciler into FeatureFlags for the facebook build. Non-facebook should
not be affected by these changes.

DiffTrain build for [0cdfef19b9](https://github.com/facebook/react/commit/0cdfef19b96cc6202d48e0812b5069c286d12b04)
2023-12-11 15:03:05 +00:00
kassens da417b29bb Remove WARNINGS file from FB (#27820)
The test was migrated to the generated JS file that allows Jest to track
the dependencies, we can now remove this file generation.

DiffTrain build for [40f653d13c](https://github.com/facebook/react/commit/40f653d13c363c6f81b13de67ce391991fb1f870)
2023-12-08 21:26:02 +00:00
gnoff 7d8a8d9c3f [Flight] Support postponing through a serialized promise (#27818)
Postponing in a promise that is being serialized to the client from the
server should be possible however prior to this change Flight treated
this case like an error rather than a postpone. This fix adds support
for postponing in this position and adds a test asserting you can
successfully prerender the root if you unwrap this promise inside a
suspense boundary.

DiffTrain build for [5bcade5fcf](https://github.com/facebook/react/commit/5bcade5fcf5610e82e7cda05cc6de574bdace0c7)
2023-12-08 19:10:45 +00:00
kassens a1635091f2 Add header to ReactAllWarnings Meta-only file (#27819)
Adds missing headers to the generated file.

DiffTrain build for [8ff2c236a2](https://github.com/facebook/react/commit/8ff2c236a233a78c18d6f524dd74baec9153fd37)
2023-12-08 18:49:06 +00:00
kassens 235d6d7ad4 [ci] try to fix commit_artifacts step (#27817)
Tries to fix the failure from
https://github.com/facebook/react/actions/runs/7142005723/job/19450371514

I think it failed because we cannot `mv` into a folder with existing
files or folders.

DiffTrain build for [d3ed07bce0](https://github.com/facebook/react/commit/d3ed07bce036df61fbce52151f1531a5762ba6d6)
2023-12-08 17:43:31 +00:00
jackpope 0f81c6bf79 Add stable concurrent option to react-test-renderer (#27804)
## Summary

Concurrent rendering has been the default since React 18 release.
ReactTestRenderer requires passing `{unstable_isConcurrent: true}` to
match this behavior, which means by default tests written with RTR use a
different rendering method than the code they test.

Eventually, RTR should only use ConcurrentRoot. As a first step, let's
add a version of the concurrent option that isn't marked unstable. Next
we will follow up with removing the unstable option when it is safe to
merge.

## How did you test this change?

`yarn test
packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js`

DiffTrain build for [b36ae8d7aa](https://github.com/facebook/react/commit/b36ae8d7aab94dae285d9d6a1c5f004e6fc19fc9)
2023-12-07 15:31:34 +00:00
kassens 7adeb4a8ef [lint] treat React.use() the same as use() (#27769)
We should probably treat `React.use()` the same as `use()` to allow it
within loops and conditionals.

Ideally this would implement a test that `React` is imported or required
from `'react'`, but we don't otherwise implement such a test.

DiffTrain build for [640ccebb7d](https://github.com/facebook/react/commit/640ccebb7d9669f1efbd20e86f6f84086c3d698d)
2023-12-01 20:05:58 +00:00
hoxyq c35082fd80 fix: select console error to not suggest to set readonly to true (#27740)
fix #27657

added test in the `ReactDOMSELECT-test.js` to not allow regession to
happen in future.

After changes this is what the error message looks like

https://github.com/facebook/react/assets/72331432/53dcbe2a-70d2-43d2-a52d-a4fc389fdfbf

DiffTrain build for [5dd35968be](https://github.com/facebook/react/commit/5dd35968bef791ccc5948c657fabf191a77fff3f)
2023-12-01 16:00:15 +00:00
kassens bb600b3dda [lint] move use lint to non-experimental (#27768)
`use` is being stabilized, so let's make sure the lint is updated for
the next release.

DiffTrain build for [b8be034f07](https://github.com/facebook/react/commit/b8be034f07e1abc59863742063f5baeff20e33fe)
2023-11-30 22:44:18 +00:00
alunyov 2f391b032a FB-specific builds of Flight Server, Flight Client, and React Shared Subset (#27579)
This PR adds a new FB-specific configuration of Flight. We also need to
bundle a version of ReactSharedSubset that will be used for running
Flight on the server.

This initial implementation does not support server actions yet.

The FB-Flight still uses the text protocol on the server (the flag
`enableBinaryFlight` is set to false). It looks like we need some
changes in Hermes to properly support this binary format.

DiffTrain build for [c17a27ef49](https://github.com/facebook/react/commit/c17a27ef492d9812351aecdfb017488e8e8404ce)
2023-11-27 23:40:03 +00:00
kassens 62b9d0a15f [cleanup] remove enableHostSingletons feature flag (#27583)
The flag is enabled everywhere, I think we can remove it now.

DiffTrain build for [1a65d036ef](https://github.com/facebook/react/commit/1a65d036ef057b07a6b15f5604e399f91bc5ed73)
2023-11-16 22:47:06 +00:00
gnoff cecbf4f081 [Fizz] handle errors in onHeaders (#27712)
`onHeaders` can throw however for now we can assume that headers are
optimistic values since the only things we produce for them are preload
links. This is a pragmatic decision because React could concievably have
headers in the future which were not optimistic and thus non-optional
however it is hard to imagine what these headers might be in practice.
If we need to change this behavior to be fatal in the future it would be
a breaking change.

This commit adds error logging when `onHeaders` throws and ensures the
request can continue to render successfully.

DiffTrain build for [ee68446ff1](https://github.com/facebook/react/commit/ee68446ff198755bd38202ac9139275b657968b0)
2023-11-15 20:58:39 +00:00
kassens 9e50f2a78b Add a feature flag to enable expiration of retry lanes (#27694)
An attempt to see if we can bring back expiration of retry lanes to
avoid cases resolving Suspense can be starved by frequent updates.

In the past, this caused increase browser crashes, but a lot of time has
passed since then. Just trying if we can re-enable this.

Old PR that reverted adding the timeout:
https://github.com/facebook/react/pull/21300

DiffTrain build for [593ecee66a](https://github.com/facebook/react/commit/593ecee66a609d4a4c2b36b39b1e5e23b2456dd1)
2023-11-14 15:20:17 +00:00
kassens ea781fb710 Upgrade Flow to 0.221.0 (#27689)
Upgrades Flow and dependencies
```
yarn add -W flow-bin flow-remove-types hermes-parser hermes-eslint
```

DiffTrain build for [432b9f1d97](https://github.com/facebook/react/commit/432b9f1d9729aaea010730d546bda89b9842eaa1)
2023-11-10 19:20:43 +00:00
mofeiZ 8b8cf95503 [FeatureFlags] Enable useMemoCache for ReactTestRenderer (#27677)
## Summary
Forget compiled code currently cannot be tested with ReactTestRender as
`useMemoCache` is not being set on the dispatcher. This PR ensures that
projects can execute unit tests with Forget compilation in the test
build pipeline.

```js
// source code
function Component(props) {
  // ...
}

// transformed code, which also should be evaluated in unit tests
function Component(props) {
  const $ = useMemoCache(...);
  // ...
}
```

This PR enables the `enableUseMemoCacheHook` feature flag for all bundle
variations of ReactTestRenderer. Forget *should* be the only caller of
useMemoCache, so this should be a reversible change (in the event we
need to change the implementation or api of the hook).

## How did you test this change?
* Check that generated ReactTestRenderer bundles contain `useMemoCache`.
* Synced to Meta and checked that unit tests that use Forget +
@testing-library/react pass.

I did not add new tests to check that useMemoCache can be called when
using the test renderer as `useMemoCache` is not yet stable. Happy to
add a test case here if that would be helpful to reviewers though (I'm
guessing that would go in
`packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js` )

DiffTrain build for [6a7f3aa858](https://github.com/facebook/react/commit/6a7f3aa858b3a8670d6a4861e30f248b335e55bd)
2023-11-10 15:36:24 +00:00
kassens 6bab074fd2 Small cleanup in ReactFiberCompleteWork (#27681)
These are all functionally equivalent changes.

- remove double negation and more explicit naming of
`hadNoMutationsEffects`
- use docblock syntax that's consumed by Flow
- remove useless cast

DiffTrain build for [c4c87e049b](https://github.com/facebook/react/commit/c4c87e049b891ebc38a7a14b8c93285c877e90af)
2023-11-10 15:25:47 +00:00
sebmarkbage c9079646c0 [Fizz] Fix for failing id overwrites for postpone (#27684)
When we postpone during a render we inject a new segment synchronously
which we postpone. That gets assigned an ID so we can refer to it
immediately in the postponed state.

When we do that, the parent segment may complete later even though it's
also synchronous. If that ends up not having any content in it, it'll
inline into the child and that will override the child's segment id
which is not correct since it was already assigned one.

To fix this, we simply opt-out of the optimization in that case which is
unfortunate because we'll generate many more unnecessary empty segments.
So we should come up with a new strategy for segment id assignment but
this fixes the bug.

Co-authored-by: Josh Story <story@hey.com>

DiffTrain build for [0e352ea01c](https://github.com/facebook/react/commit/0e352ea01c0209b6c5e23f0e857af4e01c783024)
2023-11-10 03:57:35 +00:00
hoxyq 69de556cc2 refactor[ci/build]: dont generate sourcemaps for BROWSER_SCRIPT bundles (#27665)
Instead of https://github.com/facebook/react/pull/27664, we can just
exclude `unstable_server-external-runtime.js` from having sourcemaps for
now.

We should consider removing manual copying of this artifact in
https://github.com/facebook/react/blob/52d542ad6d410008c495084f511247f43387055f/.github/workflows/commit_artifacts.yml#L136-L138

As described in https://github.com/facebook/react/pull/27664, this
artifact doesn't have any effect on the `hash`, which is used for
generating React version identifier.

DiffTrain build for [78c71bc545](https://github.com/facebook/react/commit/78c71bc545bf5c0fdeedc023b69fafe05d988067)
2023-11-09 16:17:04 +00:00
hoxyq c65ae2687c refactor[ci/build]: preserve header format in artifacts (#27671)
In order to make Haste work with React's artifacts, It is important to
keep headers in this format:
```
/**
* ...
...
* ...
*/
```

For optimization purposes, Closure compiler will actually modify these
headers by removing * prefixes, which is expected.
We should pass sources to the compiler without license headers, with
these changes the current flow will be:
1. Apply top-level definitions. For UMD-bundles, for example, or
DEV-only bundles (e. g. `if (__DEV__) { ...`)
2. Apply licence headers for artifacts with sourcemaps: oss-production
and oss-profiling bundles, they don't need to preserve the header format
to comply with Haste. We need to apply these headers before passing
sources to Closure, so it can build correct mappings for sourcemaps.
3. Pass these sources to closure compiler for minification and
sourcemaps building.
4. Apply licence headers for artifacts without sourcemaps: dev bundles,
fb bundles. This way the header style will be preserved and not changed
by Closure.

DiffTrain build for [c47c306a7a](https://github.com/facebook/react/commit/c47c306a7a23d3c796b148d303764e2832da480c)
2023-11-09 16:05:29 +00:00
gnoff 9c7330855c [Static][Fizz] bootstrap scripts should only emit once (#27674)
I introduced a bug in a recent change to how bootstrap scripts are
handled. Rather than clearing out the bootstrap script state from
ResumableState on completion of the prerender I did it during the
flushing phase which comes later after the postponed state has likely
been serialized. We should freeze these objects in dev so this is not
possible to do easily in test (nor in actual code in real systems).

This fixes the bug by eliminating the bootstrap config during
getPostponedState which is before the state can be serialized.

DiffTrain build for [7468903294](https://github.com/facebook/react/commit/746890329452cbec8685eb3466847c5f17d9dc77)
2023-11-09 01:56:32 +00:00
gnoff 6e10ef7619 [Static][Fizz] Carry forward bootstrap config to resume if postponing in the shell (#27672)
Previously it was possible to postpone in the shell during a prerender
and then during a resume the bootstrap scripts would not be emitted
leading to no hydration on the client. This change moves the bootstrap
configuration to `ResumableState` where it can be serialized after
postponing if it wasn't flushed as part of the static shell.

DiffTrain build for [7508dcd5cc](https://github.com/facebook/react/commit/7508dcd5cc245e376860d65402972e418199264d)
2023-11-08 18:48:33 +00:00
mofeiZ 0367178d64 Update stack diffing algorithm in describeNativeComponentFrame (#27132)
## Summary

There's a bug with the existing stack comparison algorithm in
`describeNativeComponentFrame` — specifically how it attempts to find a
common root frame between the control and sample stacks. This PR
attempts to fix that bug by injecting a frame that can have a guaranteed
string in it for us to search for in both stacks to find a common root.

## Brief Background/How it works now

Right now `describeNativeComponentFrame` does the following to leverage
native browser/VM stack frames to get details (e.g. script path, row and
col #s) for a single component:
1. Throwing and catching a control error in the function
2. Calling the component which should eventually throw an error (most of
the time), that we'll catch as our sample error.
3. Diffing the stacks in the control and sample errors to find the line
which should represent our component call.

## What's broken

To account for potential stack trace truncation, the stack diffing
algorithm first attempts to find a common "root" frame by inspecting the
earliest frame of the sample stack and searching for an identical frame
in the control stack starting from the bottom. However, there are a
couple of scenarios which I've hit that cause the above approach to not
work correctly.

First, it's possible that for render passes of extremely large component
trees to have a lot of repeating internal react function calls, which
can result in an incorrect common or "root" frame found. Here's a small
example from a stack trace using React Fizz for SSR.
Our control frame can look like this:
```
Error:
    at Fake (...)
    at construct (native)
    at describeNativeComponentFrame (...)
    at describeClassComponentFrame (...)
    at getStackByComponentStackNode (...)
    at getCurrentStackInDEV (...)
    at renderNodeDestructive (...)
    at renderElement (...)
    at renderNodeDestructiveImpl (...) // <-- Actual common root frame with the sample stack
    at renderNodeDestructive (...)
    at renderElement (...)
    at renderNodeDestructiveImpl (...) // <-- Incorrectly chosen common root frame
    at renderNodeDestructive (...)
```

And our sample stack can look like this:
```
Error:
    at set (...)
    at PureComponent (...)
    at call (native)
    at apply (native)
    at ErrorBoundary (...)
    at construct (native)
    at describeNativeComponentFrame (...)
    at describeClassComponentFrame (...)
    at getStackByComponentStackNode (...)
    at getCurrentStackInDEV (...)
    at renderNodeDestructive (...)
    at renderElement (...)
    at renderNodeDestructiveImpl (...) // <-- Root frame that's common in the control stack
```

Here you can see that the earliest trace in the sample stack, the
`renderNodeDestructiveImpl` call, can exactly match with multiple
`renderNodeDestructiveImpl` calls in the control stack (including file
path and line + col #s). Currently the algorithm will chose the
earliest/last frame with the `renderNodeDestructiveImpl` call (which is
the second last frame in our control stack), which is incorrect. The
actual matching frame in the control stack is the latest or first frame
(when traversing from the top) with the `renderNodeDestructiveImpl`
call. This leads to the rest of the stack diffing associating an
incorrect frame (`at getStackByComponentStackNode (...)`) for the
component.

Another issue with this approach is that it assumes all VMs will
truncate stack traces at the *bottom*, [which isn't the case for the
Hermes
VM](https://github.com/facebook/hermes/blob/df07cf713a84a4434c83c08cede38ba438dc6aca/lib/VM/JSError.cpp#L688-L699)
which **truncates stack traces in the middle**, placing a

```
    at renderNodeDestructiveImpl (...)
    ... skipping {n} frames
    at renderNodeDestructive (...)
```

line in the middle of the stack trace for all stacks that contain more
than 100 traces. This causes stack traces for React Native apps using
the Hermes VM to potentially break for large component trees. Although
for this specific case with Hermes, it's possible to account for this by
either manually grepping and removing the `... skipping` line and
everything below it (see draft PR: #26999), or by implementing the
non-standard `prepareStackTrace` API which Hermes also supports to
manually generate a stack trace that truncates from the bottom ([example
implementation](https://github.com/facebook/react/compare/main...KarimP:react:component-stack-hermes-fix)).

## The Fix

I found different ways to go about fixing this. The first was to search
for a common stack frame starting from the top/latest frame. It's a
relatively small change ([see
implementation](https://github.com/facebook/react/compare/main...KarimP:react:component-stack-fix-2)),
although it is less performant by being n^2 (albeit with `n`
realistically being <= 5 here). It's also a bit more buggy for class
components given that different VMs insert a different amount of
additional lines for new/construct calls...

Another fix would be to actually implement a [longest common
substring](https://en.wikipedia.org/wiki/Longest_common_substring)
algorithm, which can also be roughly n^2 time (assuming the longest
common substring between control and sample will be most of the sample
frame).

The fix I ended up going with was have the lines that throw the control
error and the lines that call/instantiate the component be inside a
distinct method under an object property
(`"DescribeNativeComponentFrameRoot"`). All major VMs (Safari's
JavaScriptCore, Firefox's SpiderMonkey, V8, Hermes, and Bun) should
display the object property name their stack trace. I've also set the
`name` and `displayName` properties for method as well to account for
minification, any advanced optimizations (e.g. key crushing), and VM
inconsistencies (both Bun and Safari seem to exclusively use the value
under `displayName` and not `name` in traces for methods defined under
an object's own property...).

We can then find this "common" frame by simply finding the line that has
our special method name (`"DescribeNativeComponentFrameRoot"`), and the
rest of the code to determine the actual component line works as
expected. If by any chance we don't find a frame with our special method
name in either control or sample stack traces, we then revert back to
the existing approach mentioned above by searching for the last line of
the sample frame in the control frame.

## How did you test this change?

1. There are bunch of existing tests that ensure a properly formatted
component trace is logged for certain scenarios, so I ensured the
existing full test suite passed
2. I threw an error in a component that's deep in the component
hierarchy of a large React app (facebook) to ensure there's stack trace
truncation, and ensured the correct component stack trace was logged for
Chrome, Safari, and Firefox, and with and without minification.
3. Ran a large React app (facebook) on the Hermes VM, threw an error in
a component that's deep in the component hierarchy, and ensured that
component frames are generated despite stack traces being truncated in
the middle.

DiffTrain build for [88b00dec47](https://github.com/facebook/react/commit/88b00dec4778ffa230cceca81af3328f49e1efd9)
2023-11-08 16:50:30 +00:00
tyao1 91537cd6e5 Enable enableUnifiedSyncLane (#27646)
<!--
  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

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
The flag has been tested internally on WWW, should be good to set to
true for OSS. Added a dynamic flag for fb RN.

## How did you test this change?

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->
yarn test

DiffTrain build for [52d542ad6d](https://github.com/facebook/react/commit/52d542ad6d410008c495084f511247f43387055f)
2023-11-08 00:50:36 +00:00
hoxyq c7e4e4f3fb Generate sourcemaps for production build artifacts (#26446)
<!--
  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

This PR updates the Rollup build pipeline to generate sourcemaps for
production build artifacts like `react-dom.production.min.js`.

It requires the Rollup v3 changes that were just merged in #26442 .

Sourcemaps are currently _only_ generated for build artifacts that are
_truly_ "production" - no sourcemaps will be generated for development,
profiling, UMD, or `shouldStayReadable` artifacts.

The generated sourcemaps contain the bundled source contents right
before that chunk was minified by Closure, and _not_ the original source
files like `react-reconciler/src/*`. This better reflects the actual
code that is running as part of the bundle, with all the feature flags
and transformations that were applied to the source files to generate
that bundle. The sourcemaps _do_ still show comments and original
function names, thus improving debuggability for production usage.

Fixes #20186 .

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->

This allows React users to actually debug a readable version of the
React bundle in production scenarios. It also allows other tools like
[Replay](https://replay.io) to do a better job inspecting the React
source when stepping through.

## How did you test this change?

- Generated numerous sourcemaps with various combinations of the React
bundle selections
- Viewed those sourcemaps in
https://evanw.github.io/source-map-visualization/ and confirmed via the
visualization that the generated mappings appear to be correct

I've attached a set of production files + their sourcemaps here:

[react-sourcemap-examples.zip](https://github.com/facebook/react/files/11023466/react-sourcemap-examples.zip)

You can drag JS+sourcemap file pairs into
https://evanw.github.io/source-map-visualization/ for viewing.

Examples:

- `react.production.min.js`:

![image](https://user-images.githubusercontent.com/1128784/226478247-e5cbdee0-83fd-4a19-bcf1-09961d3c7da4.png)

- `react-dom.production.min.js`:

![image](https://user-images.githubusercontent.com/1128784/226478433-b5ccbf0f-8f68-42fe-9db9-9ecb97770d46.png)

- `use-sync-external-store/with-selector.production.min.js`:

![image](https://user-images.githubusercontent.com/1128784/226478565-bc74699d-db14-4c39-9e2d-b775f8755561.png)

<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
  If you leave this empty, your PR will very likely be closed.
-->

DiffTrain build for [2c8a139a59](https://github.com/facebook/react/commit/2c8a139a593e0294c3a6953d74b451bd05fdcfca)
2023-11-07 19:06:24 +00:00
gnoff 8645888c94 [Fizz] implement onHeaders and headersLengthHint options (#27641)
Adds a new option to `react-dom/server` entrypoints.

`onHeaders: (headers: Headers) => void` (non node envs)
`onHeaders: (headers: { Link?: string }) => void` (node envs)

When any `renderTo...` or `prerender...` function is called and this
option is provided the supplied function will be called sometime on or
before completion of the render with some preload link headers.

When provided during a `renderTo...` the callback will usually be called
after the first pass at work. The idea here is we want to get a set of
headers to start the browser loading well before the shell is ready. We
don't wait for the shell because if we did we may as well send the
preloads as tags in the HTML.

When provided during a `prerender...` the callback will be called after
the entire prerender is complete. The idea here is we are not responding
to a live request and it is preferable to capture as much as possible
for preloading as Headers in case the prerender was unable to finish the
shell.

Currently the following resources are always preloaded as headers when
the option is provided
1. prefetchDNS and preconnects
2. font preloads
3. high priority image preloads

Additionally if we are providing headers when the shell is incomplete
(regardless of whether it is render or prerender) we will also include
any stylesheet Resources (ones with a precedence prop)

There is a second option `maxHeadersLength?: number` which allows you to
specify the maximum length of the header content in unicode code units.
This is what you get when you read the length property of a string in
javascript. It's improtant to note that this is not the same as the
utf-8 byte length when these headers are serialized in a Response. The
utf8 representation may be the same size, or larger but it will never be
smaller.

If you do not supply a `maxHeadersLength` we defaul to `2000`. This was
chosen as half the value of the max headers length supported by commonly
known web servers and CDNs. many browser and web server can support
significantly more headers than this so you can use this option to
increase the headers limit. You can also of course use it to be even
more conservative. Again it is important to keep in mind there is no
direct translation between the max length and the bytelength and so if
you want to stay under a certain byte length you need to be potentially
more aggressive in the maxHeadersLength you choose.

Conceptually `onHeaders` could be called more than once as new headers
are discovered however if we haven't started flushing yet but since most
APIs for the server including the web standard Response only allow you
to set headers once the current implementation will only call it one
time

DiffTrain build for [2983249dd2](https://github.com/facebook/react/commit/2983249dd2bb1a295f27939e36ab0de9e4bfab76)
2023-11-07 18:21:25 +00:00
kassens c7102d3558 [activity] rename unstable_Offscreen to unstable_Activity (#27640)
`Activity` is the current candidate name. This PR starts the rename work
by renaming the exported unstable component name.

NOTE: downstream consumers need to rename the import when updating to
this commit.

DiffTrain build for [ce2bc58a9f](https://github.com/facebook/react/commit/ce2bc58a9f6f3b0bfc8c738a0d8e2a5f3a332ff5)
2023-11-02 20:18:15 +00:00
noahlemen 63e0697e97 SchedulerPostTask: Reuse original TaskController (#27595)
## Summary

It's not clear to me why we currently create a new TaskController in
`runTask` – ultimately, we use the same signal and priority from the
original created in `unstable_scheduleCallback`

## How did you test this change?
```
yarn test SchedulerPostTask
```

DiffTrain build for [a17467e7e2](https://github.com/facebook/react/commit/a17467e7e2cd8947c595d1834889b5d184459f12)
2023-11-02 15:08:54 +00:00