Commit Graph
727 Commits
Author SHA1 Message Date
sebmarkbage 3e92eb7fe1 [Flight] Eval Fake Server Component Functions to Recreate Native Stacks (#29632)
We have three kinds of stacks that we send in the RSC protocol:

- The stack trace where a replayed `console.log` was called on the
server.
- The JSX callsite that created a Server Component which then later
called another component.
- The JSX callsite that created a Host or Client Component.

These stack frames disappear in native stacks on the client since
they're executed on the server. This evals a fake file which only has
one call in it on the same line/column as the server. Then we call
through these fake modules to "replay" the callstack. We then replay the
`console.log` within this stack, or call `console.createTask` in this
stack to recreate the stack.

The main concern with this approach is the performance. It adds
significant cost to create all these eval:ed functions but it should
eventually balance out.

This doesn't yet apply source maps to these. With source maps it'll be
able to show the server source code when clicking the links.

I don't love how these appear.

- Because we haven't yet initialized the client module we don't have the
name of the client component we're about to render yet which leads to
the `<...>` task name.
- The `(async)` suffix Chrome adds is still a problem.
- The VMxxxx prefix is used to disambiguate which is noisy. Might be
helped by source maps.
- The continuation of the async stacks end up rooted somewhere in the
bootstrapping of the app. This might be ok when the bootstrapping ends
up ignore listed but it's kind of a problem that you can't clear the
async stack.

<img width="927" alt="Screenshot 2024-05-28 at 11 58 56 PM"
src="https://github.com/facebook/react/assets/63648/1c9d32ce-e671-47c8-9d18-9fab3bffabd0">

<img width="431" alt="Screenshot 2024-05-28 at 11 58 07 PM"
src="https://github.com/facebook/react/assets/63648/52f57518-bbed-400e-952d-6650835ac6b6">
<img width="327" alt="Screenshot 2024-05-28 at 11 58 31 PM"
src="https://github.com/facebook/react/assets/63648/d311a639-79a1-457f-9a46-4f3298d07e65">

<img width="817" alt="Screenshot 2024-05-28 at 11 59 12 PM"
src="https://github.com/facebook/react/assets/63648/3aefd356-acf4-4daa-bdbf-b8c8345f6d4b">

DiffTrain build for [9d4fba0788](https://github.com/facebook/react/commit/9d4fba078812de0363fe9514b943650fa479e8af)
2024-05-30 16:05:47 +00:00
hoxyq 3355e1829a fix[ReactDebugHooks/find-primitive-index]: remove some assumptions (#29652)
Partially reverts https://github.com/facebook/react/pull/28593.

While rolling out RDT 5.2.0, I've observed some issues on React Native
side: hooks inspection for some complex hook trees, like in
AnimatedView, were broken. After some debugging, I've noticed a
difference between what is in frame's source.

The difference is in the top-most frame, where with V8 it will correctly
pick up the `Type` as `Proxy` in `hookStack`, but for Hermes it will be
`Object`. This means that for React Native this top most frame is
skipped, since sources are identical.

Here I am reverting back to the previous logic, where we check each
frame if its a part of the wrapper, but also updated `isReactWrapper`
function to have an explicit case for `useFormStatus` support.

DiffTrain build for [fb61a1b515](https://github.com/facebook/react/commit/fb61a1b515c5ea0e31b0dac19184454a79c4baf1)
2024-05-30 15:16:51 +00:00
yungsters 0727c8aaf4 Revert Build Versions from Content Hash to Commit Hash (#29663)
https://github.com/facebook/react/pull/29236 caused issues for internal
syncs at Meta, because we were computing version numbers using file
hashes (to eliminate "no-op" internal sync commits). The problem is that
since version numbers may not be consistent across synced files (e.g. if
some files have not changed in recent commits), the newly introduced
version mismatch check fails.

There's some more work that needs to be done here to restore the
benefits of file-specific hashing, but for now this simply reverts the
content hash changes from the following PRs:

- https://github.com/facebook/react/pull/28633
(95319ab5af)
- https://github.com/facebook/react/pull/28590
(37676aba76)
- https://github.com/facebook/react/pull/28582
(cb076b593c)
- https://github.com/facebook/react/pull/26734
(5dd90c5623)
- https://github.com/facebook/react/pull/26331
(3cad3a54ed)

DiffTrain build for [5bd4031226](https://github.com/facebook/react/commit/5bd403122645ef0f0924ac5466f56e670a8f5b8d)
2024-05-30 14:31:14 +00:00
yungsters 4bebe8e206 Fix key Warning for Flattened Positional Children (#29662)
## Summary

https://github.com/facebook/react/pull/29088 introduced a regression
triggering this warning when rendering flattened positional children:

> Each child in a list should have a unique "key" prop.

The specific scenario that triggers this is when rendering multiple
positional children (which do not require unique `key` props) after
flattening them with one of the `React.Children` utilities (e.g.
`React.Children.toArray`).

The refactored logic in `React.Children` incorrectly drops the
`element._store.validated` property in `__DEV__`. This diff fixes the
bug and introduces a unit test to prevent future regressions.

## How did you test this change?

```
$ yarn test ReactChildren-test.js
```

DiffTrain build for [72644ef2f2](https://github.com/facebook/react/commit/72644ef2f2ec7a274f79f6b32320d62757521329)
2024-05-30 14:30:34 +00:00
sophiebits 431d10b3b0 Tweak error message for "Should have a queue" (#29626)
DiffTrain build for [38e3b23483](https://github.com/facebook/react/commit/38e3b23483bf7a612391cd617a8926aa1f3cf52e)
2024-05-29 15:45:51 +00:00
acdlite e5c63baf74 Fix: Use action implementation at time of dispatch (#29618)
Fixes the behavior of actions that are queued by useActionState to use
the action function that was current at the time it was dispatched, not
at the time it eventually executes.

The conceptual model is that the action is immediately dispatched, as if
it were sent to a remote server/worker. It's the remote worker that
maintains the queue, not the client.

This is another property of actions makes them more like event handlers
than like reducers.

DiffTrain build for [163122766b](https://github.com/facebook/react/commit/163122766b6008e992898b00f1fe3b104ed78737)
2024-05-28 19:15:52 +00:00
jackpope 0af082e4c9 Clean up disableDOMTestUtils (#29610)
`disableDOMTestUtils` and the FB build `ReactTestUtilsFB` allowed us to
finish migrating internal callsites off of ReactTestUtils. Now that
usage is cleaned up, we can remove the flag, build artifact, and test
coverage for the deprecated utility methods.

DiffTrain build for [2787eebe52](https://github.com/facebook/react/commit/2787eebe52864356252a280fd811cd9d52807a82)
2024-05-28 19:00:29 +00:00
acdlite 913577ed72 Throw if React and React DOM versions don't match (#29236)
Throw an error during module initialization if the version of the
"react-dom" package does not match the version of "react".

We used to be more relaxed about this, because the "react" package
changed so infrequently. However, we now have many more features that
rely on an internal protocol between the two packages, including Hooks,
Float, and the compiler runtime. So it's important that both packages
are versioned in lockstep.

Before this change, a version mismatch would often result in a cryptic
internal error with no indication of the root cause.

Instead, we will now compare the versions during module initialization
and immediately throw an error to catch mistakes as early as possible
and provide a clear error message.

DiffTrain build for [681a4aa810](https://github.com/facebook/react/commit/681a4aa81022d4053f990d905d6453c73d2ee644)
2024-05-28 18:12:28 +00:00
sebmarkbage d2a3772cd0 [Fiber] Enable Native console.createTask Stacks When Available (#29223)
Stacked on #29206 and #29221.

This disables appending owner stacks to console when
`console.createTask` is available in the environment. Instead we rely on
native "async" stacks that end up looking like this with source maps and
ignore list enabled.

<img width="673" alt="Screenshot 2024-05-22 at 4 00 27 PM"
src="https://github.com/facebook/react/assets/63648/5313ed53-b298-4386-8f76-8eb85bdfbbc7">

Unfortunately Chrome requires a string name for each async stack and,
worse, a suffix of `(async)` is automatically added which is very
confusing since it seems like it might be an async component or
something which it is not.

In this case it's not so bad because it's nice to refer to the host
component which otherwise doesn't have a stack frame since it's
internal. However, if there were more owners here there would also be a
`<Counter> (async)` which ends up being kind of duplicative.

If the Chrome DevTools is not open from the start of the app, then
`console.createTask` is disabled and so you lose the stack for those
errors (or those parents if the devtools is opened later). Unlike our
appended ones that are always added. That's unfortunate and likely to be
a bit of a DX issue but it's also nice that it saves on perf in DEV mode
for those cases. Framework dialogs can still surface the stack since we
also track it in user space in parallel.

This currently doesn't track Server Components yet. We need a more
clever hack for that part in a follow up.

I think I probably need to also add something to React DevTools to
disable its stacks for this case too. Since it looks for stacks in the
console.error and adds a stack otherwise. Since we don't add them
anymore from the runtime, the DevTools adds them instead.

DiffTrain build for [ea6e05912a](https://github.com/facebook/react/commit/ea6e05912aa43a0bbfbee381752caa1817a41a86)
2024-05-26 22:00:39 +00:00
sebmarkbage 6af8405359 [Fiber] Use Owner/JSX Stack When Appending Stacks to Console (#29206)
This one should be fully behind the `enableOwnerStacks` flag.

Instead of printing the parent Component stack all the way to the root,
this now prints the owner stack of every JSX callsite. It also includes
intermediate callsites between the Component and the JSX call so it has
potentially more frames. Mainly it provides the line number of the JSX
callsite. In terms of the number of components is a subset of the parent
component stack so it's less information in that regard. This is usually
better since it's more focused on components that might affect the
output but if it's contextual based on rendering it's still good to have
parent stack. Therefore, I still use the parent stack when printing DOM
nesting warnings but I plan on switching that format to a diff view
format instead (Next.js already reformats the parent stack like this).

__Follow ups__

- Server Components show up in the owner stack for client logs but logs
done by Server Components don't yet get their owner stack printed as
they're replayed. They're also not yet printed in the server logs of the
RSC server.

- Server Component stack frames are formatted as the server and added to
the end but this might be a different format than the browser. E.g. if
server is running V8 and browser is running JSC or vice versa. Ideally
we can reformat them in terms of the client formatting.

- This doesn't yet update Fizz or DevTools. Those will be follow ups.
Fizz still prints parent stacks in the server side logs. The stacks
added to user space `console.error` calls by DevTools still get the
parent stacks instead.

- It also doesn't yet expose these to user space so there's no way to
get them inside `onCaughtError` for example or inside a custom
`console.error` override.

- In another follow up I'll use `console.createTask` instead and
completely remove these stacks if it's available.

DiffTrain build for [d6cfa0f295](https://github.com/facebook/react/commit/d6cfa0f295f4c8b366af15fd20c84e27cdd1fab7)
2024-05-25 16:04:14 +00:00
acdlite 4374cb693d Fix async batching in React.startTransition (#29226)
Note: Despite the similar-sounding description, this fix is unrelated to
the issue where updates that occur after an `await` in an async action
must also be wrapped in their own `startTransition`, due to the absence
of an AsyncContext mechanism in browsers today.

---

Discovered a flaw in the current implementation of the isomorphic
startTransition implementation (React.startTransition), related to async
actions. It only creates an async scope if something calls setState
within the synchronous part of the action (i.e. before the first
`await`). I had thought this was fine because if there's no update
during this part, then there's nothing that needs to be entangled. I
didn't think this through, though — if there are multiple async updates
interleaved throughout the rest of the action, we need the async scope
to have already been created so that _those_ are batched together.

An even easier way to observe this is to schedule an optimistic update
after an `await` — the optimistic update should not be reverted until
the async action is complete.

To implement, during the reconciler's module initialization, we compose
its startTransition implementation with any previous reconciler's
startTransition that was already initialized. Then, the isomorphic
startTransition is the composition of every
reconciler's startTransition.

```js
function startTransition(fn) {
  return startTransitionDOM(() => {
    return startTransitionART(() => {
      return startTransitionThreeFiber(() => {
        // and so on...
        return fn();
      });
    });
  });
}
```

This is basically how flushSync is implemented, too.

DiffTrain build for [ee5c194930](https://github.com/facebook/react/commit/ee5c19493086fdeb32057e16d1e3414370242307)
2024-05-23 21:24:58 +00:00
gnoff fe342b1c85 [Fiber] clarify entry condition for suspensey commit recursion (#29222)
Previously Suspensey recursion would only trigger if the
ShouldSuspendCommit flag was true. However there is a dependence on the
Visibility flag embedded in this logic because these flags share a bit.
To make it clear that the semantics of Suspensey resources require
considering both flags I've added it to the condition even though this
extra or-ing is a noop when the bit is shared

DiffTrain build for [f55d172bcf](https://github.com/facebook/react/commit/f55d172bcf921d761733533395b798c5b3665e04)
2024-05-23 20:59:50 +00:00
sebmarkbage e574453c80 Move createElement/JSX Warnings into the Renderer (#29088)
This is necessary to simplify the component stack handling to make way
for owner stacks. It also solves some hacks that we used to have but
don't quite make sense. It also solves the problem where things like key
warnings get silenced in RSC because they get deduped. It also surfaces
areas where we were missing key warnings to begin with.

Almost every type of warning is issued from the renderer. React Elements
are really not anything special themselves. They're just lazily invoked
functions and its really the renderer that determines there semantics.

We have three types of warnings that previously fired in
JSX/createElement:

- Fragment props validation.
- Type validation.
- Key warning.

It's nice to be able to do some validation in the JSX/createElement
because it has a more specific stack frame at the callsite. However,
that's the case for every type of component and validation. That's the
whole point of enableOwnerStacks. It's also not sufficient to do it in
JSX/createElement so we also have validation in the renderers too. So
this validation is really just an eager validation but also happens
again later.

The problem with these is that we don't really know what types are valid
until we get to the renderer. Additionally, by placing it in the
isomorphic code it becomes harder to do deduping of warnings in a way
that makes sense for that renderer. It also means we can't reuse logic
for managing stacks etc.

Fragment props validation really should just be part of the renderer
like any other component type. This also matters once we add Fragment
refs and other fragment features. So I moved this into Fiber. However,
since some Fragments don't have Fibers, I do the validation in
ChildFiber instead of beginWork where it would normally happen.

For `type` validation we already do validation when rendering. By
leaving it to the renderer we don't have to hard code an extra list.
This list also varies by context. E.g. class components aren't allowed
in RSC but client references are but we don't have an isomorphic way to
identify client references because they're defined by the host config so
the current logic is flawed anyway. I kept the early validation for now
without the `enableOwnerStacks` since it does provide a nicer stack
frame but with that flag on it'll be handled with nice stacks anyway. I
normalized some of the errors to ensure tests pass.

For `key` validation it's the same principle. The mechanism for the
heuristic is still the same - if it passes statically through a parent
JSX/createElement call then it's considered validated. We already did
print the error later from the renderer so this also disables the early
log in the `enableOwnerStacks` flag.

I also added logging to Fizz so that key warnings can print in SSR logs.

Flight is a bit more complex. For elements that end up on the client we
just pass the `validated` flag along to the client and let the client
renderer print the error once rendered. For server components we log the
error from Flight with the server component as the owner on the stack
which will allow us to print the right stack for context. The factoring
of this is a little tricky because we only want to warn if it's in an
array parent but we want to log the error later to get the right debug
info.

Fiber/Fizz has a similar factoring problem that causes us to create a
fake Fiber for the owner which means the logs won't be associated with
the right place in DevTools.

DiffTrain build for [84239da896](https://github.com/facebook/react/commit/84239da896fd7395a667ab1e7ef1ef338a32de8f)
2024-05-23 16:54:10 +00:00
sebmarkbage 2de2c20e92 Set the current fiber to the source of the error during error reporting (#29044)
This lets us expose the component stack to the error reporting that
happens here as `console.error` patching. Now if you just call
`console.error` in the error handlers it'll get the component stack
added to the end by React DevTools.

However, unfortunately this happens a little too late so the Fiber will
be disconnected with its `.return` pointer set to null already. So it'll
be too late to extract a parent component stack from but you can at
least get the stack from source to error boundary. To work around this I
manually add the parent component stack in our default handlers when
owner stacks are off. We could potentially fix this but you can also
just include it yourself if you're calling `console.error` and it's not
a problem for owner stacks.

This is not a problem for owner stacks because we'll still have those
and so for those just calling `console.error` just works. However, the
main feature is that by letting React add them, we can switch to using
native error stacks when available.

DiffTrain build for [2e540e22b2](https://github.com/facebook/react/commit/2e540e22b2b4038a278b2875306976b016fb31a9)
2024-05-23 16:45:21 +00:00
sebmarkbageandSebastian Silbermann 89d5de9d7e Unify ReactFiberCurrentOwner and ReactCurrentFiber (#29038)
We previously had two slightly different concepts for "current fiber".

There's the "owner" which is set inside of class components in prod if
string refs are enabled, and sometimes inside function components in DEV
but not other contexts.

Then we have the "current fiber" which is only set in DEV for various
warnings but is enabled in a bunch of contexts.

This unifies them into a single "current fiber".

The concept of string refs shouldn't really exist so this should really
be a DEV only concept. In the meantime, this sets the current fiber
inside class render only in prod, however, in DEV it's now enabled in
more contexts which can affect the string refs. That was already the
case that a string ref in a Function component was only connecting to
the owner in prod. Any string ref associated with any non-class won't
work regardless so that's not an issue. The practical change here is
that an element with a string ref created inside a life-cycle associated
with a class will work in DEV but not in prod. Since we need the current
fiber to be available in more contexts in DEV for the debugging
purposes. That wouldn't affect any old code since it would have a broken
ref anyway. New code shouldn't use string refs anyway.

The other implication is that "owner" doesn't necessarily mean
"rendering" since we need the "owner" to track other debug information
like stacks - in other contexts like useEffect, life cycles, etc.
Internally we have a separate `isRendering` flag that actually means
we're rendering but even that is a very overloaded concept. So anything
that uses "owner" to imply rendering might be wrong with this change.

This is a first step to a larger refactor for tracking current rendering
information.

---------

Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>

DiffTrain build for [2e3e6a9b1c](https://github.com/facebook/react/commit/2e3e6a9b1cc97ec91248be74565e7ccbf6946067)
2024-05-23 16:30:25 +00:00
eps1lon b273ac49a1 Dim console calls on additional Effect invocations due to StrictMode (#29007)
DiffTrain build for [3ac551e855](https://github.com/facebook/react/commit/3ac551e855f9bec3161da2fc8787958aa62113db)
2024-05-22 09:45:58 +00:00
gnoff ca580d71d3 [Fiber] render boundary in fallback if it contains a new stylesheet during sync update (#28965)
Updates Suspensey instances and resources to preload even during urgent
updates and to potentially suspend.

The current implementation is unchanged for transitions but for sync
updates if there is a suspense boundary above the resource/instance it
will be rendered in fallback mode instead.

Note: This behavior is not what we want for images once we make them
suspense enabled. We will need to have forked behavior here to
distinguish between stylesheets which should never commit when not
loaded and images which should commit after a small delay

DiffTrain build for [217b2ccf16](https://github.com/facebook/react/commit/217b2ccf160d7594a926d276a75c7312b299be4d)
2024-05-21 23:08:46 +00:00
eps1lon bf983422b3 React DOM: Treat toggle and beforetoggle as discrete events (#29176)
DiffTrain build for [bf046e8653](https://github.com/facebook/react/commit/bf046e86531141d0eb9ffc1165f775a57ffb00f5)
2024-05-20 21:49:37 +00:00
eps1lon 7b19874613 React DOM: Add support for Popover API (#27981)
DiffTrain build for [6f90365128](https://github.com/facebook/react/commit/6f903651283861af4e5a8838b3b74d2a953a0acc)
2024-05-20 20:07:00 +00:00
sebmarkbage 0eecce3862 [Flight] Encode references to existing objects by property path (#28996)
Instead of forcing an object to be outlined to be able to refer to it
later we can refer to it by the property path inside another parent
object.

E.g. this encodes such a reference as `'$123:props:children:foo:bar'`.

That way we don't have to preemptively outline object and we can dedupe
after the first time we've found it.

There's no cost on the client if it's not used because we're not storing
any additional information preemptively.

This works mainly because we only have simple JSON objects from the root
reference. Complex objects like Map, FormData etc. are stored as their
entries array in the look up and not the complex object. Other complex
objects like TypedArrays or imports don't have deeply nested objects in
them that can be referenced.

This solves the problem that we only dedupe after the third instance.
This dedupes at the second instance. It also solves the problem where
all nested objects inside deduped instances also are outlined.

The property paths can get pretty large. This is why a test on payload
size increased. We could potentially outline the reference itself at the
first dupe. That way we get a shorter ID to refer to in the third
instance.

DiffTrain build for [7a78d03028](https://github.com/facebook/react/commit/7a78d030281f2f0e02e7cdbed5c1fc5c4a1a1823)
2024-05-09 23:21:00 +00:00
sebmarkbage 732aef73b0 Track Stack of JSX Calls (#29032)
This is the first step to experimenting with a new type of stack traces
behind the `enableOwnerStacks` flag - in DEV only.

The idea is to generate stacks that are more like if the JSX was a
direct call even though it's actually a lazy call. Not only can you see
which exact JSX call line number generated the erroring component but if
that's inside an abstraction function, which function called that
function and if it's a component, which component generated that
component. For this to make sense it really need to be the "owner" stack
rather than the parent stack like we do for other component stacks. On
one hand it has more precise information but on the other hand it also
loses context. For most types of problems the owner stack is the most
useful though since it tells you which component rendered this
component.

The problem with the platform in its current state is that there's two
ways to deal with stacks:

1) `new Error().stack`
2) `console.createTask()`

The nice thing about `new Error().stack` is that we can extract the
frames and piece them together in whatever way we want. That is great
for constructing custom UIs like error dialogs. Unfortunately, we can't
take custom stacks and set them in the native UIs like Chrome DevTools.

The nice thing about `console.createTask()` is that the resulting stacks
are natively integrated into the Chrome DevTools in the console and the
breakpoint debugger. They also automatically follow source mapping and
ignoreLists. The downside is that there's no way to extract the async
stack outside the native UI itself so this information cannot be used
for custom UIs like errors dialogs. It also means we can't collect this
on the server and then pass it to the client for server components.

The solution here is that we use both techniques and collect both an
`Error` object and a `Task` object for every JSX call.

The main concern about this approach is the performance so that's the
main thing to test. It's certainly too slow for production but it might
also be too slow even for DEV.

This first PR doesn't actually use the stacks yet. It just collects them
as the first step. The next step is to start utilizing this information
in error printing etc.

For RSC we pass the stack along across over the wire. This can be
concatenated on the client following the owner path to create an owner
stack leading back into the server. We'll later use this information to
restore fake frames on the client for native integration. Since this
information quickly gets pretty heavy if we include all frames, we strip
out the top frame. We also strip out everything below the functions that
call into user space in the Flight runtime. To do this we need to figure
out the frames that represents calling out into user space. The
resulting stack is typically just the one frame inside the owner
component's JSX callsite. I also eagerly strip out things we expect to
be ignoreList:ed anyway - such as `node_modules` and Node.js internals.

DiffTrain build for [151cce3740](https://github.com/facebook/react/commit/151cce37401dc2ff609701119d61a17d92fce4ab)
2024-05-09 16:28:08 +00:00
sebmarkbage 3229b97bb5 [Flight Reply] Resolve outlined models async in Reply just like in Flight Client (#28988)
This is the same change as #28780 but for the Flight Reply receiver.

While it's not possible to create an "async module" reference in this
case - resolving a server reference can still be async if loading it
requires loading chunks like in a new server instance.

Since extracting a typed array from a Blob is async, that's also a case
where a dependency can be async.

DiffTrain build for [ec15267a00](https://github.com/facebook/react/commit/ec15267a001086deb4ab5412d3f8b7e13573d6a5)
2024-05-08 02:24:56 +00:00
sebmarkbage e83564ae44 [Flight Reply] Encode binary streams as a single collapsed Blob (#28986)
Based on #28893.

For other streams we encode each chunk as a separate form field which is
a bit bloated. Especially for binary chunks since they also have an
indirection. We need some way to encode the chunks as separate anyway.
This way the streaming using busboy actually allows each chunk to stream
in over the network one at a time.

For binary streams the actual chunking is not important. The chunks can
be split and recombined in whatever size chunk makes sense.

Since we buffer the entire content anyway we can combine the chunks to
be consecutive. This PR does that with binary streams and also combine
them into a single Blob. That way there's no extra overhead when passing
through a binary stream.

Ideally, we'd be able to just use the stream from that one Blob but
Node.js doesn't return byob streams from Blob. Additionally, we don't
actually stream the content of Blobs due to the layering with busboy
atm. We could do that for binary streams in particular by replacing the
File layering with a stream and resolving each chunk as it comes in.
That could be a follow up.

If we stop buffering in the future, this set up still allows us to split
them and send other form fields in between while blocked since the
protocol is still the same.

DiffTrain build for [826bf4e51e](https://github.com/facebook/react/commit/826bf4e51ecf14904e936ed043392084553ebbaa)
2024-05-08 01:58:38 +00:00
sebmarkbage 86893d4831 [Fizz] Fallback to client replaying actions if we're trying to serialize a Blob (#28987)
This follows the same principle as in #28611.

We cannot serialize Blobs of a form data into HTML because you can't
initialize a file input to some value. However the serialization of
state in an Action can contain blobs. In this case we do error but
outside the try/catch that recovers to error to client replaying instead
of MPA mode. This errors earlier to ensure that this works.

Testing this is a bit annoying because JSDOM doesn't have any of the
Blob methods but the Blob needs to be compatible with FormData and the
FormData needs to be compatible with `<form>` nodes in these tests. So I
polyfilled those in JSDOM with some hacks.

A possible future enhancement would be to encode these blobs in a base64
mode instead and have some way to receive them on the server. It's just
a matter of layering this. I think the RSC layer's `FORM_DATA`
implementation can pass some flag to encode as base64 and then have
decodeAction include some way to parse them. That way this case would
work in MPA mode too.

DiffTrain build for [6bac4f2f31](https://github.com/facebook/react/commit/6bac4f2f31378cd58dffe6181e00639366a6081a)
2024-05-08 01:58:17 +00:00
jackpope 7e3000e052 Add FB build for ReactReconcilerConstants (#29003)
In order to integrate the `react-reconciler` build created in #28880
with third party libraries, we need to have matching
`react-reconciler/constants` to go with it.

DiffTrain build for [5d29478716](https://github.com/facebook/react/commit/5d29478716cefbf8290dfdd19129156c2ac75973)
2024-05-06 15:37:52 +00:00
kassens b76cf7b7a8 Bundle config: inline internal hook wrapper (#28978)
Bundle config: inline internal hook wrapper

Instead of reading this wrapper from 2 files for "start" and "end" and
then string modifying the templates, just inline them like the other
wrappers in this file.

DiffTrain build for [0a0a3af75a](https://github.com/facebook/react/commit/0a0a3af75a740d0920ebf7f4affaf8d1ce8c107f)
2024-05-03 18:13:10 +00:00
jackpope bc32edada7 Add flag to test fast jsx (#28816)
Following #28768, add a path to testing Fast JSX on www.

We want to measure the impact of Fast JSX and enable a path to testing
before string refs are completely removed in www (which is a work in
progress).

Without `disableStringRefs`, we need to copy any object with a `ref` key
so we can pass it through `coerceStringRef()` and copy it into the
object. This de-opt path is what is gated behind
`enableFastJSXWithStringRefs`.

The additional checks should have no perf impact in OSS as the flags
remain true there and the build output is not changed. For www, I've
benchmarked the addition of the boolean checks with values cached at
module scope. There is no significant change observed from our
benchmarks and any latency will apply to test and control branches
evenly. This added experiment complexity is temporary. We should be able
to clean it up, along with the flag checks for `enableRefAsProp` and
`disableStringRefs` shortly.

DiffTrain build for [1beb73de0f](https://github.com/facebook/react/commit/1beb73de0f7c3261a0de37620453b102caaa6236)
2024-05-03 14:52:18 +00:00
dmytrorykun a73bb0e53e Introduce a faster version of the addProperties function (#28969)
## Summary

This PR introduces a faster version of the `addProperties` function.
This new function is basically the `diffProperties` with `prevProps` set
to `null`, propagated constants, and all the unreachable code paths
collapsed.

## How did you test this change?

I've tested this change with [the benchmark
app](https://github.com/react-native-community/RNNewArchitectureApp/tree/new-architecture-benchmarks)
and got ~4.4% improvement in the view creation time.

DiffTrain build for [73bcdfbae5](https://github.com/facebook/react/commit/73bcdfbae57545aa8f88ecdf67426275610b5573)
2024-05-02 16:14:58 +00:00
gnoff cc2fb92581 [Tooling] Update critical artifact list (#28966)
When a React PR is opened CI will report large size changes. But for
critical packages like react-dom it reports always. In React 19 we moved
the build for react-dom the client reconciler from react-dom to
react-dom/client

This change adds react-dom-client artifacts for stable and oss channels
since that is originally what was being tracked. But since
react-dom/client always imports react-dom I left the original react-dom
packages as critical as well. They are small but it would be good to
keep an eye on them

DiffTrain build for [c7b1ae5a9e](https://github.com/facebook/react/commit/c7b1ae5a9ed58abece101d09c47ddd1e0b181fe2)
2024-05-02 14:45:16 +00:00
kassens 1b79911aba Move useMemoCache hook to react/compiler-runtime (#28954)
Move useMemoCache hook to react/compiler-runtime

For Meta-internal purposes, we keep the export on `react` itself to
reduce churn.

DiffTrain build for [4508873393](https://github.com/facebook/react/commit/4508873393058e86bed308b56e49ec883ece59d1)
2024-04-30 16:05:18 +00:00
gnoffandSebastian Markbage 9e2d7147a8 (Land #28798) Move Current Owner (and Cache) to an Async Dispatcher (#28912)
Rebasing and landing https://github.com/facebook/react/pull/28798

This PR was approved already but held back to give time for the sync.
Rebased and landing here without pushing to seb's remote to avoid
possibility of lost updates

---------

Co-authored-by: Sebastian Markbage <sebastian@calyptus.eu>

DiffTrain build for [94eed63c49](https://github.com/facebook/react/commit/94eed63c49d989861ae7cd62e111de6d717f0a10)
2024-04-25 17:45:24 +00:00
acdlite aef84c3f17 Update canary channel label to "beta" (#28905)
During the beta period, canaries will be published as
`19.0.0-beta-<COMMIT_SHA>-<DATE>`. They will also be tagged as `beta`
when published to npm.

DiffTrain build for [f8a8eac86b](https://github.com/facebook/react/commit/f8a8eac86bac406724f327325f804e65e594dd68)
2024-04-25 17:19:14 +00:00
acdlite 0433358c3b Go back to shared refs instance object (#28911)
It turns out we already made refs writable in #25696, which has been in
canary for over a year. The approach in that PR also has the benefit of
being slightly more perf sensitive because it still uses a shared object
until the fiber is mounted. So let's just go back to that.

DiffTrain build for [d285b3acba](https://github.com/facebook/react/commit/d285b3acbade77f9b17e6171dbda69ff4a033878)
2024-04-25 17:08:50 +00:00
kassens 22b1a6b5ec Support ref cleanup function for imperative handle refs (#28910)
Support ref cleanup function for imperative handle refs

DiffTrain build for [ed71a3ad29](https://github.com/facebook/react/commit/ed71a3ad2965617c27c6e7ca7577f15b8ca4152c)
2024-04-25 16:56:26 +00:00
gnoff 0c0e01783a [react-dom] move all client code to react-dom/client (#28271)
This PR reorganizes the `react-dom` entrypoint to only pull in code that
is environment agnostic. Previously if you required anything from this
entrypoint in any environment the entire client reconciler was loaded.
In a prior release we added a server rendering stub which you could
alias in server environments to omit this unecessary code. After landing
this change this entrypoint should not load any environment specific
code.

While a few APIs are truly client (browser) only such as createRoot and
hydrateRoot many of the APIs you import from this package are only
useful in the browser but could concievably be imported in shared code
(components running in Fizz or shared components as part of an RSC app).
To avoid making these require opting into the client bundle we are
keeping them in the `react-dom` entrypoint and changing their
implementation so that in environments where they are not particularly
useful they do something benign and expected.

#### Removed APIs
The following APIs are being removed in the next major. Largely they
have all been deprecated already and are part of legacy rendering modes
where concurrent features of React are not available
* `render`
* `hydrate`
* `findDOMNode`
* `unmountComponentAtNode`
* `unstable_createEventHandle`
* `unstable_renderSubtreeIntoContainer`
* `unstable_runWithPrioirty`

#### moved Client APIs
These APIs were available on both `react-dom` (with a warning) and
`react-dom/client`. After this change they are only available on
`react-dom/client`
* `createRoot`
* `hydrateRoot`

#### retained APIs
These APIs still exist on the `react-dom` entrypoint but have normalized
behavior depending on which renderers are currently in scope
* `flushSync`: will execute the function (if provided) inside the
flushSync implemention of FlightServer, Fizz, and Fiber DOM renderers.
* `unstable_batchedUpdates`: This is a noop in concurrent mode because
it is now the only supported behavior because there is no legacy
rendering mode
* `createPortal`: This just produces an object. It can be called from
anywhere but since you will probably not have a handle on a DOM node to
pass to it it will likely warn in environments other than the browser
* preloading APIS such as `preload`: These methods will execute the
preload across all renderers currently in scope. Since we resolve the
Request object on the server using AsyncLocalStorage or the current
function stack in practice only one renderer should act upon the
preload.

In addition to these changes the server rendering stub now just rexports
everything from `react-dom`. In a future minor we will add a warning
when using the stub and in the next major we will remove the stub
altogether

DiffTrain build for [cb151849e1](https://github.com/facebook/react/commit/cb151849e13f46ec64570519cb93d5939fb60cab)
2024-04-24 15:55:32 +00:00
kassens 21f1398e43 Unrevert "Support writing to this.refs from userspace" (#28879)
Reverts facebook/react#28877

We found the cause of the regression and should be able to land this
again.

DiffTrain build for [b039be627d](https://github.com/facebook/react/commit/b039be627dd7403d7d2f63a48c8d263d955ce456)
2024-04-24 14:08:29 +00:00
rickhanlonii fe8c683838 Create short link for jsx warning (#28899)
Short link created in https://github.com/reactjs/react.dev/pull/6772

DiffTrain build for [6f6e375fce](https://github.com/facebook/react/commit/6f6e375fce9d0700434f863f70f0e2e5ea180426)
2024-04-24 13:36:55 +00:00
eps1lon 3aec5d54db eslint-plugin-react-hooks: Add support for ESLint v9 (#28773)
DiffTrain build for [6f18664b82](https://github.com/facebook/react/commit/6f18664b82b61d34b30c794a151d7b032f8eabe0)
2024-04-23 21:34:41 +00:00
acdlite 802cec5a70 Remove automatic fetch cache instrumentation (#28896)
This removes the automatic patching of the global `fetch` function in
Server Components environments to dedupe requests using `React.cache`, a
behavior that some RSC framework maintainers have objected to.

We may revisit this decision in the future, but for now it's not worth
the controversy.

Frameworks that have already shipped this behavior, like Next.js, can
reimplement it in userspace.

I considered keeping the implementation in the codebase and disabling it
by setting `enableFetchInstrumentation` to `false` everywhere, but since
that also disables the tests, it doesn't seem worth it because without
test coverage the behavior is likely to drift regardless. We can just
revert this PR later if desired.

DiffTrain build for [a94838df1c](https://github.com/facebook/react/commit/a94838df1c598a3993316ff453c84f3688537a97)
2024-04-23 18:19:12 +00:00
sebmarkbage f007da754f [Fiber/Fizz] Support AsyncIterable as Children and AsyncGenerator Client Components (#28868)
Stacked on #28849, #28854, #28853. Behind a flag.

If you're following along from the side-lines. This is probably not what
you think it is.

It's NOT a way to get updates to a component over time. The
AsyncIterable works like an Iterable already works in React which is how
an Array works. I.e. it's a list of children - not the value of a child
over time.

It also doesn't actually render one component at a time. The way it
works is more like awaiting the entire list to become an array and then
it shows up. Before that it suspends the parent.

To actually get these to display one at a time, you have to opt-in with
`<SuspenseList>` to describe how they should appear. That's really the
interesting part and that not implemented yet.

Additionally, since these are effectively Async Functions and uncached
promises, they're not actually fully "supported" on the client yet for
the same reason rendering plain Promises and Async Functions aren't.
They warn. It's only really useful when paired with RSC that produces
instrumented versions of these. Ideally we'd published instrumented
helpers to help with map/filter style operations that yield new
instrumented AsyncIterables.

The way the implementation works basically just relies on unwrapThenable
and otherwise works like a plain Iterator.

There is one quirk with these that are different than just promises. We
ask for a new iterator each time we rerender. This means that upon retry
we kick off another iteration which itself might kick off new requests
that block iterating further. To solve this and make it actually
efficient enough to use on the client we'd need to stash something like
a buffer of the previous iteration and maybe iterator on the iterable so
that we can continue where we left off or synchronously iterate if we've
seen it before. Similar to our `.value` convention on Promises.

In Fizz, I had to do a special case because when we render an iterator
child we don't actually rerender the parent again like we do in Fiber.
However, it's more efficient to just continue on where we left off by
reusing the entries from the thenable state from before in that case.

DiffTrain build for [9f2eebd807](https://github.com/facebook/react/commit/9f2eebd807bf53b7d9901cf0b768762948224cae)
2024-04-22 17:30:04 +00:00
sebmarkbage d1d050887f Rename the react.element symbol to react.transitional.element (#28813)
We have changed the shape (and the runtime) of React Elements. To help
avoid precompiled or inlined JSX having subtle breakages or deopting
hidden classes, I renamed the symbol so that we can early error if
private implementation details are used or mismatching versions are
used.

Why "transitional"? Well, because this is not the last time we'll change
the shape. This is just a stepping stone to removing the `ref` field on
the elements in the next version so we'll likely have to do it again.

DiffTrain build for [3b551c8284](https://github.com/facebook/react/commit/3b551c82844bcfde51f0febb8e42c1a0d777df2c)
2024-04-22 16:45:16 +00:00
jackpope 5d6e662777 Remove warning for ref cleanup function (#28883)
Resources
- RFC: https://github.com/reactjs/rfcs/pull/205
- Warning implemented in https://github.com/facebook/react/pull/22313
- Warning enabled in https://github.com/facebook/react/pull/23145
- Feature added in https://github.com/facebook/react/pull/25686

We have warned to prevent the old behavior since 18.0.0.

The new feature has been on in canary for a while but still triggering
the warning. This PR cleans up the warning for 19

DiffTrain build for [db913d8e17](https://github.com/facebook/react/commit/db913d8e17db25045e0518f3621f1640f2390525)
2024-04-22 15:02:35 +00:00
sebmarkbage 3755ebbaca [Flight] Support (Async) Generator ServerComponent (#28849)
Stacked on #28853 and #28854.

React supports rendering `Iterable` and will soon support
`AsyncIterable`. As long as it's multi-shot since during an update we
may have to rerender with new inputs an loop over the iterable again.
Therefore the `Iterator` and `AsyncIterator` types are not supported
directly as a child of React - and really it shouldn't pass between
Hooks or components neither for this reason. For parity, that's also the
case when used in Server Components.

However, there is a special case when the component rendered itself is a
generator function. While it returns as a child an `Iterator`, the React
Element itself can act as an `Iterable` because we can re-evaluate the
function to create a new generator whenever we need to.

It's also very convenient to use generator functions over constructing
an `AsyncIterable`. So this is a proposal to special case the
`Generator`/`AsyncGenerator` returned by a (Async) Generator Function.

In Flight this means that when we render a Server Component we can
serialize this value as an `Iterable`/`AsyncIterable` since that's
effectively what rendering it on the server reduces down to. That way if
Fiber can receive the result in any position.

For SuspenseList this would also need another special case because the
children of SuspenseList represent "rows".

`<SuspenseList><Component /></SuspenseList>` currently is a single "row"
even if the component renders multiple children or is an iterator. This
is currently different if Component is a Server Component because it'll
reduce down to an array/AsyncIterable and therefore be treated as one
row per its child. This is different from `<SuspenseList><Component
/><Component /></SuspenseList>` since that has a wrapper array and so
this is always two rows.

It probably makes sense to special case a single-element child in
`SuspenseList` to represent a component that generates rows. That way
you can use an `AsyncGeneratorFunction` to do this.

DiffTrain build for [5b903cdaa9](https://github.com/facebook/react/commit/5b903cdaa94c78e8fabb985d8daca5bd7d266323)
2024-04-21 17:14:56 +00:00
sebmarkbage 91c2cfe814 Warn for Child Iterator of all types but allow Generator Components (#28853)
This doesn't change production behavior. We always render Iterables to
our best effort in prod even if they're Iterators.

But this does change the DEV warnings which indicates which are valid
patterns to use.

It's a footgun to use an Iterator as a prop when you pass between
components because if an intermediate component rerenders without its
parent, React won't be able to iterate it again to reconcile and any
mappers won't be able to re-apply. This is actually typically not a
problem when passed only to React host components but as a pattern it's
a problem for composability.

We used to warn only for Generators - i.e. Iterators returned from
Generator functions. This adds a warning for Iterators created by other
means too (e.g. Flight or the native Iterator utils). The heuristic is
to check whether the Iterator is the same as the Iterable because that
means it's not possible to get new iterators out of it. This case used
to just yield non-sense like empty sets in DEV but not in prod.

However, a new realization is that when the Component itself is a
Generator Function, it's not actually a problem. That's because the
React Element itself works as an Iterable since we can ask for new
generators by calling the function again. So this adds a special case to
allow the Generator returned from a Generator Function's direct child.
The principle is “don’t pass iterators around” but in this case there is
no iterator floating around because it’s between React and the JS VM.

Also see #28849 for context on AsyncIterables.

Related to this, but Hooks should ideally be banned in these for the
same reason they're banned in Async Functions.

DiffTrain build for [368202181e](https://github.com/facebook/react/commit/368202181e772d411b2445930aea1edd9428b09b)
2024-04-21 16:56:26 +00:00
acdlite 1c8380371c Don't minify symbols in production builds (#28881)
This disables symbol renaming in production builds. The original
variable and function names are preserved. All other forms of
compression applied by Closure (dead code elimination, inlining, etc)
are unchanged — the final program is identical to what we were producing
before, just in a more readable form.

The motivation is to make it easier to debug React issues that only
occur in production — the same reason we decided to start shipping
sourcemaps in #28827 and #28827.

However, because most apps run their own minification step on their npm
dependencies, it's not necessary for us to minify the symbols before
publishing — it'll be handled the app, if desired.

This is the same strategy Meta has used to ship React for years. The
React build itself has unminified symbols, but they get minified as part
of Meta's regular build pipeline.

Even if an app does not minify their npm dependencies, gzip covers most
of the cost of symbol renaming anyway.

This saves us from having to ship sourcemaps, which means even apps that
don't have sourcemaps configured will be able to debug the React build
as easily as they would any other npm dependency.

DiffTrain build for [857ee8cdf9](https://github.com/facebook/react/commit/857ee8cdf9af81bc94a7f04528fbda7fb2510eb4)
2024-04-20 15:29:32 +00:00
acdlite 2b01d44689 [Experiment] Reuse memo cache after interruption (#28878)
Adds an experimental feature flag to the implementation of useMemoCache,
the internal cache used by the React Compiler (Forget).

When enabled, instead of treating the cache as copy-on-write, like we do
with fibers, we share the same cache instance across all render
attempts, even if the component is interrupted before it commits.

If an update is interrupted, either because it suspended or because of
another update, we can reuse the memoized computations from the previous
attempt. We can do this because the React Compiler performs atomic
writes to the memo cache, i.e. it will not record the inputs to a
memoization without also recording its output.

This gives us a form of "resuming" within components and hooks.

This only works when updating a component that already mounted. It has
no impact during initial render, because the memo cache is stored on the
fiber, and since we have not implemented resuming for fibers, it's
always a fresh memo cache, anyway.

However, this alone is pretty useful — it happens whenever you update
the UI with fresh data after a mutation/action, which is extremely
common in a Suspense-driven (e.g. RSC or Relay) app.

So the impact of this feature is faster data mutations/actions (when the
React Compiler is used).

DiffTrain build for [ea26e38e33](https://github.com/facebook/react/commit/ea26e38e33bffeba1ecc42688d7e8cd7e0da1c02)
2024-04-19 23:35:03 +00:00
sebmarkbage a6449bdd92 Build react-reconciler for FB builds (#28880)
Meta uses various tools built on top of the "react-reconciler" package
but that package needs to match the version of the "react" package.

This means that it should be synced at the same time. However, more than
that the feature flags between the "react" package and the
"react-reconciler" package needs to line up. Since FB has custom feature
flags, it can't use the OSS version of react-reconciler.

DiffTrain build for [446aa9a632](https://github.com/facebook/react/commit/446aa9a632670eb9a373d897309452e24c10c55e)
2024-04-19 22:10:41 +00:00
acdlite 8309f584ec Run Closure on non-minified prod builds, too (#28827)
In #26446 we started publishing non-minified versions of our production
build artifacts, along with source maps, for easier debugging of React
when running in production mode.

The way it's currently set up is that these builds are generated
*before* Closure compiler has run. Which means it's missing many of the
optimizations that are in the final build, like dead code elimination.

This PR changes the build process to run Closure on the non-minified
production builds, too, by moving the sourcemap generation to later in
the pipeline.

The non-minified builds will still preserve the original symbol names,
and we'll use Prettier to add back whitespace. This is the exact same
approach we've been using for years to generate production builds for
Meta.

The idea is that the only difference between the minified and non-
minified builds is whitespace and symbol mangling. The semantic
structure of the program should be identical.

To implement this, I disabled symbol mangling when running Closure
compiler. Then, in a later step, the symbols are mangled by Terser. This
is when the source maps are generated.

DiffTrain build for [0e0b69321a](https://github.com/facebook/react/commit/0e0b69321a6fcfe8a3eaae3b1016beb110437b38)
2024-04-19 18:28:37 +00:00
kassens cf94a4aade Revert "Support writing to this.refs from userspace" (#28877)
Reverts facebook/react#28867

It broke some tests, reverting until we figure out why to avoid having
too much delay in the sync.

DiffTrain build for [f5ce642dee](https://github.com/facebook/react/commit/f5ce642deed7c74c5ae5df54ec4340a8d028eac9)
2024-04-19 16:40:08 +00:00
gnoff 627e1bebae Remove renderToStaticNodeStream (#28873)
Stacked on #28872

renderToStaticNodeStream was not originally deprecated when
renderToNodeStream was deprecated because it did not yet have a clear
analog in the modern streaming implementation for SSR. In React 19 we
have already removed renderToNodeStream. This change removes
renderToStaticNodeStream as well because you can replicate it's
semantics using renderToPipeableStream with onAllReady or
renderToReadableStream with await stream.allready.

DiffTrain build for [33a32441e9](https://github.com/facebook/react/commit/33a32441e991e126e5e874f831bd3afc237a3ecf)
2024-04-19 04:11:51 +00:00