Commit Graph

342 Commits

Author SHA1 Message Date
sebmarkbage 3ff23f9234 [Flight] Better error message if you pass a function as a child to a client component (#28367)
Similar to #28362 but if you pass it to a client component.

DiffTrain build for [2e84e16299](https://github.com/facebook/react/commit/2e84e1629924e6cb278638305fa92040f6ef6eb5)
2024-02-19 17:41:20 +00:00
sebmarkbage 94683ffb3d [Flight] Allow a Server Reference to be registered twice (#28343)
It's possible for the same function instance to appear more than once in
the same graph or even the same file.

Currently this errors on trying to reconfigure the property but it
really doesn't matter which one wins. First or last.

Regardless there will be an entry point generated that can get them.

DiffTrain build for [9444c51c7e](https://github.com/facebook/react/commit/9444c51c7e44936c24e1f44db905cfd45c51cff3)
2024-02-19 16:54:24 +00:00
sebmarkbage 43967e7833 Include the function name for context on invalid function child (#28362)
Also warn for symbols.

It's weird because for objects we throw a hard error but functions we do
a dev only check. Mainly because we have an object branch anyway.

In the object branch we have some built-ins that have bad errors like
forwardRef and memo but since they're going to become functions later, I
didn't bother updating those. Once they're functions those names will be
part of this.

DiffTrain build for [c1fd2a91b1](https://github.com/facebook/react/commit/c1fd2a91b1042c137d750be85e5998f699a54d2a)
2024-02-17 21:46:58 +00:00
jackpope 0db83ce329 Add useModernStrictMode as dynamic flag on www (#28346)
## Summary

Preparing modern strict mode rollout with dynamic feature flag

## How did you test this change?

![Screenshot 2024-02-15 at 10 09
49 AM](https://github.com/facebook/react/assets/8965173/9e90efc2-3578-4e63-ae2c-63d4a4e194b3)

DiffTrain build for [ef72271c2d](https://github.com/facebook/react/commit/ef72271c2d1234c9d1e1358f8083021089a50faa)
2024-02-16 20:22:50 +00:00
gaearon b19c9fedc2 Remove non-JSX propTypes checks (#28326)
Removes all `propTypes` validation called from outside the JSX
factories. Haven't touched JSX.

Tests that verify related behavior are stripped down to the
non-`propTypes` logic.

DiffTrain build for [fea900e454](https://github.com/facebook/react/commit/fea900e45447214ddd6ef69076ab7e38433b5ffd)
2024-02-16 00:40:11 +00:00
sebmarkbage edb6eccbe2 [Fizz] Align recoverable error serialization in dev mode (#28340)
Same as #28327 but for Fizz.

One thing that's weird about this recoverable error is that we don't
send the regular stack for it, just the component stack it seems. This
is missing some potential information and if we move toward integrated
since stacks it would be one thing.

DiffTrain build for [2e470a788e](https://github.com/facebook/react/commit/2e470a788e359e34feeadb422daaff046baf66cc)
2024-02-15 01:20:40 +00:00
rickhanlonii 7b5320203d Land enableAsyncActions enableFormActions in www (#28315)
DiffTrain build for [5d445b50a6](https://github.com/facebook/react/commit/5d445b50a670d6cdc52943ca4e5ab3422792c57c)
2024-02-13 16:53:52 +00:00
rickhanlonii 1985f4f852 Switch <Context> to mean <Context.Provider> (#28226)
Previously, `<Context>` was equivalent to `<Context.Consumer>`. However,
since the introduction of Hooks, the `<Context.Consumer>` API is rarely
used. The goal here is to make the common case cleaner:

```js
const ThemeContext = createContext('light')

function App() {
  return (
    <ThemeContext value="dark">
      ...
    </ThemeContext>
  )
}

function Button() {
  const theme = use(ThemeContext)
  // ...
}
```

This is technically a breaking change, but we've been warning about
rendering `<Context>` directly for several years by now, so it's
unlikely much code in the wild depends on the old behavior. [Proof that
it warns today (check
console).](https://codesandbox.io/p/sandbox/peaceful-nobel-pdxtfl)

---

**The relevant commit is 5696782b428a5ace96e66c1857e13249b6c07958.** It
switches `createContext` implementation so that `Context.Provider ===
Context`.

The main assumption that changed is that a Provider's fiber type is now
the context itself (rather than an intermediate object). Whereas a
Consumer's fiber type is now always an intermediate object (rather than
it being sometimes the context itself and sometimes an intermediate
object).

My methodology was to start with the relevant symbols, work tags, and
types, and work my way backwards to all usages.

This might break tooling that depends on inspecting React's internal
fields. I've added DevTools support in the second commit. This didn't
need explicit versioning—the structure tells us enough.

DiffTrain build for [14fd9630ee](https://github.com/facebook/react/commit/14fd9630ee04387f4361da289393234e2b7d93b6)
2024-02-13 15:10:06 +00:00
sebmarkbage 82dd48d0a1 Remove __self and __source location from elements (#28265)
Along with all the places using it like the `_debugSource` on Fiber.
This still lets them be passed into `createElement` (and JSX dev
runtime) since those can still be used in existing already compiled code
and we don't want that to start spreading to DOM attributes.

We used to have a DEV mode that compiles the source location of JSX into
the compiled output. This was nice because we could get the actual call
site of the JSX (instead of just somewhere in the component). It had a
bunch of issues though:

- It only works with JSX.
- The way this source location is compiled is different in all the
pipelines along the way. It relies on this transform being first and the
source location we want to extract but it doesn't get preserved along
source maps and don't have a way to be connected to the source hosted by
the source maps. Ideally it should just use the mechanism other source
maps use.
- Since it's expensive it only works in DEV so if it's used for
component stacks it would vary between dev and prod.
- It only captures the callsite of the JSX and not the stack between the
component and that callsite. In the happy case it's in the component but
not always.

Instead, we have another zero-cost trick to extract the call site of
each component lazily only if it's needed. This ensures that component
stacks are the same in DEV and PROD. At the cost of worse line number
information.

The better way to get the JSX call site would be to get it from `new
Error()` or `console.createTask()` inside the JSX runtime which can
capture the whole stack in a consistent way with other source mappings.
We might explore that in the future.

This removes source location info from React DevTools and React Native
Inspector. The "jump to source code" feature or inspection can be made
lazy instead by invoking the lazy component stack frame generation. That
way it can be made to work in prod too. The filtering based on file path
is a bit trickier.

When redesigned this UI should ideally also account for more than one
stack frame.

With this change the DEV only Babel transforms are effectively
deprecated since they're not necessary for anything.

DiffTrain build for [37d901e2b8](https://github.com/facebook/react/commit/37d901e2b81e12d40df7012c6f8681b8272d2555)
2024-02-07 21:42:46 +00:00
gaearon c178d6f4b1 [Flight] Delete Server Context (#28225)
Server Context was never documented, and has been deprecated in
https://github.com/facebook/react/pull/27424.

This PR removes it completely, including the implementation code.

Notably, `useContext` is removed from the shared subset, so importing it
from a React Server environment would now should be a build error in
environments that are able to enforce that.

DiffTrain build for [472854820b](https://github.com/facebook/react/commit/472854820bfd0058dfc85524051171c7b7c998c1)
2024-02-05 22:44:00 +00:00
gnoff 55b1962e67 add RSC entrypoint for jsx-runtime (#28217)
Adds a new entrypoint for the production jsx-runtime when using
react-server condition. Currently the entrypoints are the same but in
the future we will potentially change the implementation of the runtime
in ways that can only be optimized for react-server constraints and we
want to have the entrypoint already separated so environments using it
will be pulling in the right version

DiffTrain build for [00f9acb12c](https://github.com/facebook/react/commit/00f9acb12c036ef24a2b6d7957d75359c6280087)
2024-02-02 21:43:43 +00:00
gnoff 72343e632a [Fizz] Support aborting with Postpone (#28183)
Semantically if you make your reason for aborting a Postpone instance
the render should not hit the error pathways but should instead follow
the postpone pathways. It's awkward today to actually get your hands on
a Postpone instance because you have to catch the throw from postpone
and then pass that into `abort()` or `AbortController.abort()`
(depending on the renderer API you are using)

This change makes it so that in most circumstances if you abort with a
postpone the `onPostpone` handler will be called and the Suspense
boundaries still pending will be put into client render mode with the
appropriate postpone digest to avoid trigger recoverable error pathways
on the client.

Similar to postponing in the shell during a resume or render however if
you abort before the shell is complete in a resume or render we will
fatally error. The fatal error is contextualized by React to avoid
passing the postpone object itself to the `onError` and related options.

DiffTrain build for [1219d57fc9](https://github.com/facebook/react/commit/1219d57fc9fcbf44c873c0b10e5acbd31f613c15)
2024-02-01 15:18:52 +00:00
eps1lon 5f663581bc Restore old behavior for empty href props on anchor tags (#28124)
Treat `<a href="" />` the same with and without
`enableFilterEmptyStringAttributesDOM`

in https://github.com/facebook/react/pull/18513 we started to warn and
ignore for empty `href` and `src` props since it usually hinted at a
mistake. However, for anchor tags there's a valid use case since `<a
href=""></a>` will by spec render a link to the current page. It could
be used to reload the page without having to rely on browser
affordances.

The implementation for Fizz is in the spirit of
https://github.com/facebook/react/pull/21153. I gated the fork behind
the flag so that the fork is DCE'd when the flag is off.

DiffTrain build for [f3ce87ab65](https://github.com/facebook/react/commit/f3ce87ab650f07774e1df9bc3f8033e023973d10)
2024-01-30 23:48:54 +00:00
rickhanlonii 3cc608a8e7 Update www flags (#28150)
Adds an experiment for `enableFormActions` and hardcodes
`enableCustomElementPropertySupport` on www since this is shipped.

DiffTrain build for [417188314d](https://github.com/facebook/react/commit/417188314dd1d6df54efc8cd6a0c5d4830615888)
2024-01-30 19:29:43 +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
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
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
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 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
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
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
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
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
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
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
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 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 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
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
acdlite 0d03ff9eac [useFormState] Allow sync actions (#27571)
Updates useFormState to allow a sync function to be passed as an action.

A form action is almost always async, because it needs to talk to the
server. But since we support client-side actions, too, there's no reason
we can't allow sync actions, too.

I originally chose not to allow them to keep the implementation simpler
but it's not really that much more complicated because we already
support this for actions passed to startTransition. So now it's
consistent: anywhere an action is accepted, a sync client function is a
valid input.

DiffTrain build for [77c4ac2ce8](https://github.com/facebook/react/commit/77c4ac2ce88736bbdfe0b29008b5df931c2beb1e)
2023-11-01 03:38:26 +00:00
acdlite 9bdb530631 [Fizz] Pass task.childIndex in retryReplayTask (#27594)
This was missed that we track the child index on the task. The
equivalent in retryRenderTask already has this.

The effect is that a lazy node that suspends gets its child index reset
to -1 even though it should resume in the index it left off.

DiffTrain build for [8c8ee9ee61](https://github.com/facebook/react/commit/8c8ee9ee618eace9199b7c80f4cd2d6f20ecfb73)
2023-10-26 06:25:11 +00:00
kassens 242f985096 Revert "Build: use content hash for facebook-react-native build" (#27584)
Reverts facebook/react#27577.

We also sync React Native OSS bundles which means this didn't work as
hoped unless we abandon the commit hash in OSS which seems useful.

DiffTrain build for [97047a810c](https://github.com/facebook/react/commit/97047a810cb19e3041a3ec163f4fde85f495bdc1)
2023-10-25 19:12:26 +00:00
kassens 76600e478a Build: use content hash for facebook-react-native build (#27577)
Similar to #26734, this switches the RN builds for Meta to a content
hash instead of git commit number to make the builds reproducible and
avoid creating sync commits if the bundled content didn't change.

DiffTrain build for [51ffd3564f](https://github.com/facebook/react/commit/51ffd3564f97b58737df395d30628a27fa71a39d)
2023-10-25 13:55:20 +00:00
sebmarkbage 83b9e0144b [Fizz] Postponing in the shell (#27569)
When we postpone a prerender in the shell, we should just leave an empty
prelude and resume from the root. While preserving any options passed
in.

Since we haven't flushed anything we can't assume we've already emitted
html/body tags or any resources tracked in the resumable state. This
introduces a resetResumableState function to reset anything we didn't
flush.

This is a bit hacky. Ideally, we probably shouldn't have tracked it as
already happened until it flushed or something like that.

Basically, it's like restarting the prerender with the same options and
then immediately aborting. When we add the preload headers, we'd track
those as preload() being emitted after the reset and so they get readded
to the resumable state in that case.

DiffTrain build for [05fbd1aab0](https://github.com/facebook/react/commit/05fbd1aab036ecbd14469d6376024439bc931f68)
2023-10-23 19:59:15 +00:00
acdlite 857a68d62b useDeferredValue has higher priority than partial hydration (#27550)
By default, partial hydration is given the lowest possible priority,
because until a tree is updated, the server-rendered HTML is assumed to
match the final resolved HTML.

However, this isn't completely true because a component may choose to
"upgrade" itself upon hydration. The simplest example is a component
that calls setState in a useEffect to switch to a richer implementation
of the UI. Another example is a component that doesn't have a server-
rendered implementation, so it intentionally suspends to force a client-
only render.

useDeferredValue is an example, too: the server only renders the first
pass (the initialValue) argument, and relies on the client to upgrade to
the final value.

What we should really do in these cases is emit some information into
the Fizz stream so that Fiber knows to prioritize the hydration of
certain trees. We plan to add a mechanism for this in the future.

In the meantime, though, we can at least ensure that the priority of the
upgrade task is correct once it's "discovered" during hydration. In this
case, the priority of the task spawned by useDeferredValue should have
Transition priority, not Offscreen priority.

DiffTrain build for [779d59374e](https://github.com/facebook/react/commit/779d59374e8e852ce00728d895156a7574e1b456)
2023-10-23 17:54:55 +00:00
gnoff 5a422ba9bf [Fizz] Optimize end tags chunks (#27522)
Implements `endChunkForTag` to make writing end tags faster

DiffTrain build for [8c85b02996](https://github.com/facebook/react/commit/8c85b02996b940d63f961f835348a0dd0045d3b6)
2023-10-20 22:39:07 +00:00
gnoff 24721ffcba [Fizz][Float] Do not write after closing the stream (#27541)
Float methods can hang on to a reference to a Request after the request
is closed due to AsyncLocalStorage. If a Float method is called at this
point we do not want to attempt to flush anything. This change updates
the closing logic to also call `stopFlowing` which will ensure that any
checks against the destination properly reflect that we cannot do any
writes. In addition it updates the enqueueFlush logic to existence check
the destination inside the work function since it can change across the
work scheduling gap if it is async.

fixes: https://github.com/facebook/react/issues/27540

DiffTrain build for [601e5c3850](https://github.com/facebook/react/commit/601e5c38505ebc0ee099d8666b2f7a8b03159ac4)
2023-10-18 17:11:34 +00:00
acdlite 105044700e Prerendering support for useDeferredValue (#27512)
### Based on #27509

Revealing a prerendered tree (hidden -> visible) is considered the same
as mounting a brand new tree. So, when an initialValue argument is
passed to useDeferredValue, and it's prerendered inside a hidden tree,
we should first prerender the initial value.

After the initial value has been prerendered, we switch to prerendering
the final one. This is the same sequence that we use when mounting new
visible tree. Depending on how much prerendering work has been finished
by the time the tree is revealed, we may or may not be able to skip all
the way to the final value.

This means we get the benefits of both prerendering and preview states:
if we have enough resources to prerender the whole thing, we do that. If
we don't, we have a preview state to show for immediate feedback.

DiffTrain build for [75c1bd7ee7](https://github.com/facebook/react/commit/75c1bd7ee7e4a87a4dd0f560e157c57957ef823b)
2023-10-17 17:03:40 +00:00
acdlite 385a8f1519 useDeferredValue should skip initialValue if it suspends (#27509)
### Based on https://github.com/facebook/react/pull/27505

If a parent render spawns a deferred task with useDeferredValue, but the
parent render suspends, we should not wait for the parent render to
complete before attempting to render the final value.

The reason is that the initialValue argument to useDeferredValue is
meant to represent an immediate preview of the final UI. If we can't
render it "immediately", we might as well skip it and go straight to the
"real" value.

This is an improvement over how a userspace implementation of
useDeferredValue would work, because a userspace implementation would
have to wait for the parent task to commit (useEffect) before spawning
the deferred task, creating a waterfall.

DiffTrain build for [b2a68a65c8](https://github.com/facebook/react/commit/b2a68a65c84b63ac86930d88ae5c84380cbbdeb6)
2023-10-17 16:53:57 +00:00
hoxyq 1cb4186646 Fix: error messages (#27523)
<!--
  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
Changes `before before` to `before` in error messages.

<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
I want to improve error logs

## 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 [67cc9ba878](https://github.com/facebook/react/commit/67cc9ba8789335b9da0838a446137c1be62adbcd)
2023-10-16 14:10:35 +00:00
acdlite 40c111874f Track entangled lanes separately from update lane (#27505)
A small refactor to how the lane entanglement mechanism works. We can
now distinguish between the lane that "spawned" a render task (i.e. a
new update) versus the lanes that it's entangled with. Both the update
lane and the entangled lanes will be included while rendering, but by
keeping them separate, we don't lose the original priority.

In practical terms, this means we can now entangle a low priority update
with a higher priority lane while rendering at the lower priority.

To do this, lanes that are entangled at the root are now tracked using
the same variable that we use to track the "base lanes" when revealing a
previously hidden tree — conceptually, they are the same thing. I also
renamed this variable (from subtreeLanes to entangledRenderLanes) to
better reflect how it's used.

My primary motivation is related to useDeferredValue, which I'll address
in a later PR.

DiffTrain build for [309c8ad968](https://github.com/facebook/react/commit/309c8ad9688c491e5b17beb07ab01d65594914ce)
2023-10-15 16:34:39 +00:00