Copies the existing circleci workflow for flow into GitHub actions. I
didn't remove the circleci job for now just to check for parity.
ghstack-source-id: 59104902e4
Pull Request resolved: https://github.com/facebook/react/pull/30025
Copies the existing circleci workflow for linting into GitHub actions. I
didn't remove the circleci for now just to check for parity.
ghstack-source-id: a3754dcc3b
Pull Request resolved: https://github.com/facebook/react/pull/30023
Merges the existing config to the root one so we can have a single
configuration file. I've tried to keep the compiler config as much as
possible in this PR so that no formatting changes occur.
ghstack-source-id: 8bbfc9f269
Pull Request resolved: https://github.com/facebook/react/pull/30021
This PR extends the previous logic added in #29141 to also account for
other kinds of non-ascii characters such as `\n`. Because these control
characters are individual special characters (and not 2 characters `\`
and `n`) we match based on unicode which was already being checked for
non-Latin characters.
This allows control characters to continue to be compiled equivalently
to its original source if it was provided in a JsxExpressionContainer.
However note that this PR does not convert JSX attributes that are
StringLiterals to JsxExpressionContainer, to preserve the original
source code as it was written.
Alternatively we could always emit a JsxExpressionContainer if it was
used in the source and not try to down level it to some other node
kind. But since we already do this I opted to keep this behavior.
Partially addresses #29648.
ghstack-source-id: ecc61c9f0b
Pull Request resolved: https://github.com/facebook/react/pull/29997
Need to tighten up this a bit.
react-dom isomorphic currently depends on react-reconciler which is
mostly DCE but it's pulled in which makes it hard to make other bundling
changes.
ReactFlightServer can have a hard dependency on the module that imports
its internals since even if other internals are aliased it still always
needs the server one.
Now that the compiler directory has its own prettier config, we can
remove the prettierignore entry for compiler/ so it still runs in your
editor if you open the root directory
ghstack-source-id: 5e3bd597cf
Pull Request resolved: https://github.com/facebook/react/pull/29993
## Summary
Fix bundle type filtering logic to correctly handle array input in
argv.type and use some with includes for accurate filtering. This
addresses a TypeError encountered during yarn build-for-devtools-prod
and yarn build-for-devtools-dev commands.
## Motivation
The current implementation of the `shouldSkipBundle` function in
`scripts/rollup/build.js` has two issues:
1. **Incorrect array handling in
`parseRequestedNames`([#29613](https://github.com/facebook/react/issues/29613)):**
The function incorrectly wraps the `argv.type` value in an additional
array when it's already an array. This leads to a `TypeError:
names[i].split is not a function` when `parseRequestedNames` attempts to
split the nested array, as seen in this error message:
```
C:\Users\Administrator\Documents\새 폴더\react\scripts\rollup\build.js:76
let splitNames = names[i].split(',');
^
TypeError: names[i].split is not a function
```
This PR fixes this by correctly handling both string and array inputs in
`argv.type`:
```diff
- const requestedBundleTypes = argv.type
- ? parseRequestedNames([argv.type], 'uppercase')
+ const argvType = Array.isArray(argv.type) ? argv.type : [argv.type];
+ const requestedBundleTypes = argv.type
+ ? parseRequestedNames(argvType, 'uppercase')
```
2. **Inaccurate filtering logic in
`shouldSkipBundle`([#29614](https://github.com/facebook/react/issues/29614)):**
The function uses `Array.prototype.every` with `indexOf` to check if
**all** requested bundle types are missing in the current bundle type.
However, when multiple bundle types are requested (e.g., `['NODE',
'NODE_DEV']`), the function should skip a bundle only if **none** of the
requested types are present. The current implementation incorrectly
allows bundles that match any of the requested types.
To illustrate, consider the following example output:
```
requestedBundleTypes [ 'NODE', 'NODE_DEV' ]
bundleType NODE_DEV
isAskingForDifferentType false
requestedBundleTypes [ 'NODE', 'NODE_DEV' ]
bundleType NODE_PROD
isAskingForDifferentType false // Incorrect behavior
```
In this case, even though the bundle type is `NODE_PROD` and doesn't
include `NODE_DEV`, the bundle is not skipped due to the incorrect
logic.
This PR fixes this by replacing `every` with `some` and using `includes`
for a more accurate check:
```diff
- const isAskingForDifferentType = requestedBundleTypes.every(
- requestedType => bundleType.indexOf(requestedType) === -1
- );
+ const isAskingForDifferentType = requestedBundleTypes.some(
+ requestedType => !bundleType.includes(requestedType)
+ );
```
This ensures that the bundle is skipped only if **none** of the
requested types are found in the `bundleType`.
This PR addresses both of these issues to ensure correct bundle type
filtering in various build scenarios.
## How did you test this change?
1. **Verification of `requestedBundleTypes` usage in
`shouldSkipBundle`:**
* I manually tested the following scenarios:
* `yarn build`: Verified that `requestedBundleTypes` remains an empty
array, as expected.
* `yarn build-for-devtools`: Confirmed that `requestedBundleTypes` is
correctly set to `['NODE']`, as in the original implementation.
* `yarn build-for-devtools-dev`: This previously failed due to the
error. After the fix, I confirmed that `requestedBundleTypes` is now
correctly passed as `['NODE', 'NODE_DEV']`.
2. **Debugging of filtering logic in `shouldSkipBundle`:**
* I added the following logging statements to the `shouldSkipBundle`
function to observe its behavior during the build process:
```javascript
console.log('requestedBundleTypes', requestedBundleTypes);
console.log('bundleType', bundleType);
console.log('isAskingForDifferentType', isAskingForDifferentType);
```
* By analyzing the log output, I confirmed that the filtering logic now
correctly identifies when a bundle should be skipped based on the
requested types. This allowed me to verify that the fix enables building
specific target bundles as intended.
<!--
Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.
Before submitting a pull request, please make sure the following is
done:
1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
10. If you haven't already, complete the CLA.
Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->
## Summary
<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
I have fixed an issue where the display of the HIR diff in the React
Compiler Playground was incorrect. The HIR diff is supposed to show the
pre-change state as the source, but currently, it is showing
EnvironmentConfig as the pre-change state. This PR corrects this by
setting the pre-change state to source instead of EnvironmentConfig.
## 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.
-->
before:

after:

Somehow missed this while working on
https://github.com/facebook/react/pull/29869.
With these changes, manual inspection of the
`react_devtools_backend_compact.js` doesn't have any occurences of
`__IS_FIREFOX__` flag.
Only with the enableOwnerStacks flag (which is not on in www).
This is a new DEV-only API to be able to implement what we do for
console.error in user space.
This API does not actually include the current stack that you'd get from
`new Error().stack`. That you'd have to add yourself.
This adds the ability to have conditional development exports because we
plan on eventually having separate ESM builds that use the "development"
or "production" export conditions.
NOTE: This removes the export of `act` from `react` in prod (as opposed
to a function that throws) - inline with what we do with other
conditional exports.
## Summary
This is the pre-requisite for
https://github.com/facebook/react/pull/29231.
Current implementation of profiling hooks is only using
`performance.mark` and then makes `performance.clearMarks` call right
after it to free the memory. We've been relying on this assumption in
the tests that every mark is cleared by the time we check something.
https://github.com/facebook/react/pull/29231 adds `performance.measure`
calls and the `start` mark is not cleared until the corresponding `stop`
one is registered, and then they are cleared together.
## How did you test this change?
To test against React from source:
```
yarn test --build --project=devtools -r=experimental --ci
```
To test against React 18:
```
./scripts/circleci/download_devtools_regression_build.js 18.0 --replaceBuild
node ./scripts/jest/jest-cli.js --build --project devtools --release-channel=experimental --reactVersion 18.0 --ci
```
If a component uses the `useRef` hook directly then we type it's return
value as a ref. But if it's wrapped in a custom hook then we lose out on
this type information as the compiler doesn't look at the hook
definition. This has resulted in some false positives in our analysis
like the ones reported in #29160 and #29196.
This PR will treat objects named as `ref` or if their names end with the
substring `Ref`, and contain a property named `current`, as React refs.
```
const ref = useMyRef();
const myRef = useMyRef2();
useEffect(() => {
ref.current = ...;
myRef.current = ...;
})
```
In the above example, `ref` and `myRef` will be treated as React refs.
Updated version of #29758 removing `useFormState` since that was the
previous name for `useActionState`.
---------
Co-authored-by: Hieu Do <hieudn.uh@gmail.com>
Stacked on https://github.com/facebook/react/pull/29869.
## Summary
When using ANSI escape sequences, we construct a message in the
following way: `console.<method>('\x1b...%s\x1b[0m',
userspaceArgument1?, userspaceArgument2?, userspaceArgument3?, ...)`.
This won't dim all arguments, if user had something like `console.log(1,
2, 3)`, we would only apply it to `1`, since this is the first
arguments, so we need to:
- inline everything whats possible into a single string, while
preserving console substitutions defined by the user
- omit css and object substitutions, since we can't really inline them
and will delegate in to the environment
## How did you test this change?
Added some tests, manually inspected that it works well for web and
native cases.
Adds fixtures for `macro.namespace(...)` style invocations which we use internally in some cases instead of just `macro(...)`. I tried every example i could think of that could possibly break it (including basing one off of another fixture where we hit an invariant related due to a temporary being emitted for a method call), and they all worked. I just had to fix an existing bug where we early return in some cases instead of continuing, which is a holdover from when this pass was originally written as a ReactiveFunction visitor.
ghstack-source-id: c01f45b3ef
Pull Request resolved: https://github.com/facebook/react/pull/29899
## Summary
Removes the usage of `consoleManagedByDevToolsDuringStrictMode` flag
from React DevTools backend, this is the only place in RDT where this
flag was used. The only remaining part is
[`ReactFiberDevToolsHook`](https://github.com/facebook/react/blob/67081159377b438b48e3c2f2278af8e5f56b9f64/packages/react-reconciler/src/ReactFiberDevToolsHook.js#L203),
so React renderers can start notifying DevTools when `render` runs in a
Strict Mode.
> TL;DR: it is broken, and we already incorrectly apply dimming, when
RDT frontend is not opened. Fixing in the next few changes, see next
steps.
Before explaining why I am removing this, some context is required. The
way RDT works is slightly different, based on the fact if RDT frontend
and RDT backend are actually connected:
1. For browser extension case, the Backend is a script, which is
injected by the extension when page is loaded and before React is
loaded. RDT Frontend is loaded together with the RDT panel in browser
DevTools, so ONLY when user actually opens the RDT panel.
2. For native case, RDT backend is shipped together with `react-native`
for DEV bundles. It is always injected before React is loaded. RDT
frontend is loaded only when user starts a standalone RDT app via `npx
react-devtools` or by opening React Native DevTools and then selecting
React DevTools panel.
When Frontend is not connected to the Backend, the only thing we have is
the `__REACT_DEVTOOLS_GLOBAL_HOOK__` — this thing inlines some APIs in
itself, so that it can work similarly when RDT Frontend is not even
opened. This is especially important for console logs, since they are
cached and stored, then later displayed to the user once the Console
panel is opened, but from RDT side, you want to modify these console
logs when they are emitted.
In order to do so, we [inline the console patching logic into the
hook](https://github.com/facebook/react/blob/3ac551e855f9bec3161da2fc8787958aa62113db/packages/react-devtools-shared/src/hook.js#L222-L319).
This implementation doesn't use the
`consoleManagedByDevToolsDuringStrictMode`. This means that if we enable
`consoleManagedByDevToolsDuringStrictMode` for Native right now, users
would see broken dimming in LogBox / Metro logs when RDT Frontend is not
opened.
Next steps:
1. Align this console patching implementation with the one in `hook.js`.
2. Make LogBox compatible with console stylings: both css and ASCII
escape symbols.
3. Ship new version of RDT with these changes.
4. Remove `consoleManagedByDevToolsDuringStrictMode` from
`ReactFiberDevToolsHook`, so this is rolled out for all renderers.
This adds few changes:
1. We are going to ship source maps only for 2 artifacts:
`installHook.js` and `react_devtools_backend_compact.js`, because it is
only these modules that can patch console and be visible to the user via
stack traces in console. We need to ship source maps to be able to use
`ignoreList` feature in source maps, so we can actually hide these from
stack traces.
| Before | After |
|--------|--------|
| 
| 
|
2. The `"sources"` field in source map will have relative urls listed,
instead of absolute with `webpack://` protocol. This will move the
sources to the `React Developer Tools` frame in `Sources` panel, instead
of `webpack://`.
| Before | After |
|--------|--------|
| 
| 
|
> [!NOTE]
> I still have 1 unresolved issue with shipping source maps in extension
build, and it is related to Firefox, which can't find them in the
extension bundle and returns 404, even though urls are relative and I
can actually open them via unique address like
`moz-extension://<extension-id>/build/intallHook.js.map` ¯\\\_(ツ)\_/¯
## Summary
Configures the React Native open source feature flags in preparation for
React Native 0.75, which will be upgraded to React 19.
## How did you test this change?
```
$ yarn test
$ yarn flow fabric
```
Adds a pass just after DCE to reorder safely reorderable instructions (jsx, primitives, globals) closer to where they are used, to allow other optimization passes to be more effective. Notably, the reordering allows scope merging to be more effective, since that pass relies on two scopes not having intervening instructions — in many cases we can now reorder such instructions out of the way and unlock merging, as demonstrated in the changed fixtures.
The algorithm itself is described in the docblock.
note: This is a cleaned up version of #29579 that is ready for review.
ghstack-source-id: c54a806cad
Pull Request resolved: https://github.com/facebook/react/pull/29863
Updates our scope merging pass to allow more types of instructions to intervene btw scopes. This includes all the non-allocating kinds of nodes that are considered reorderable in #29863. It's already safe to merge scopes with these instructions — we only merge if the lvalue is not used past the next scope. Additionally, without changing this pass reordering isn't very effective, since we would reorder to add these types of intervening instructions and then not be able to merge scopes.
Sequencing this first helps to see the win just from reordering alone.
ghstack-source-id: 79263576d8
Pull Request resolved: https://github.com/facebook/react/pull/29881
<!--
Thanks for submitting a pull request!
We appreciate you spending the time to work on these changes. Please
provide enough information so that others can review your pull request.
The three fields below are mandatory.
Before submitting a pull request, please make sure the following is
done:
1. Fork [the repository](https://github.com/facebook/react) and create
your branch from `main`.
2. Run `yarn` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch
TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It
supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`,
open `chrome://inspect`, and press "Inspect".
7. Format your code with
[prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only
check changed files.
9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).
10. If you haven't already, complete the CLA.
Learn more about contributing:
https://reactjs.org/docs/how-to-contribute.html
-->
## Summary
<!--
Explain the **motivation** for making this change. What existing problem
does the pull request solve?
-->
In the Fabric renderer in React Native, we only use the HostContext to
issue soft errors in __DEV__ bundles when attempting to add a raw text
child to a node that may not support them. Moving the logic to set this
context to __DEV__ bundles only unblocks more expensive methods for
resolving whether a parent context supports raw text children, like
resolving this information from `getViewConfigForType`.
## How did you test this change?
<!--
Demonstrate the code is solid. Example: The exact commands you ran and
their output, screenshots / videos if the pull request changes the user
interface.
How exactly did you verify that your PR solves the issue you wanted to
solve?
If you leave this empty, your PR will very likely be closed.
-->
yarn test (--prod)
sanitize javascript: urls for <object> tags
React 19 added sanitization for `javascript:` URLs for `href` properties
on various tags. This PR also adds that sanitization for `<object>` tags
as well that Firefox otherwise executes.
Summary: The change detection mode was unavailable in the playground because the pragma was not a boolean. This fixes that by special casing it in pragma parsing, similar to validateNoCapitalizedCalls
ghstack-source-id: 4a8c17d21a
Pull Request resolved: https://github.com/facebook/react/pull/29889
### Summary
Similarly to what has been done on the `react-native` repo in
https://github.com/facebook/react-native/pull/43851, this PR adds a
`react.code-workspace` workspace file when using VSCode.
This disables the built-in TypeScript Language Service for `.js`, `.ts`,
and `.json` files, recommends extensions, enables `formatOnSave`,
excludes certain files in search, and configures Flow language support.
### Motivation
This is a DevX benefit for **React contributors** using open source VS
Code. Without this, it takes quite a long time to set up the environment
in vscode to work well.
For me the following two points took around an hour each to figure out,
but for others it may take even more (screenshots can be found below):
* Search with "files to include" was searching in ignored files
(compiled/generated)
* Configure language validation and prettier both in "packages" that use
flow and in the "compiler" folder that uses typescript.
### Recommended extensions
NOTE: The recommended extensions list is currently minimal — happy to
extend this now or in future, but let's aim to keep these conservative
at the moment.
* Flow — language support
* EditorConfig — formatting based on `.editorconfig`, all file types
* Prettier — formatting for JS* files
* ESLint — linter for JS* files
### Why `react.code-workspace`?
`.code-workspace` files have slight extra behaviours over a `.vscode/`
directory:
* Allows user to opt-in or skip.
* Allows double-click launching from file managers.
* Allows base folder (and any subfolders in future) to be opened with
local file tree scope (useful in fbsource!)
* (Minor point) Single config file over multiple files.
https://code.visualstudio.com/docs/editor/workspaces
### Test plan
Against a new un-configured copy of Visual Studio Code Insiders.
**Without workspace config**
❌ .js files raise errors by default (built-in TypeScript language
service)
❌ When using the Flow VS Code extension, the wrong version (global) of
Flow is used.
<img width="978" alt="Screenshot 2024-06-10 at 16 03 59"
src="https://github.com/facebook/react/assets/5188459/17e19ba4-bac2-48ea-9b35-6b4b6242bcc1">
❌ Searching in excluded files when the "include" field is specified
<img width="502" alt="Screenshot 2024-06-10 at 15 41 24"
src="https://github.com/facebook/react/assets/5188459/00248755-7905-41bc-b303-498ddba82108">
**With workspace config**
✅ Built-in TypeScript Language Service is disabled for .js files, but
still enabled for .ts[x] files

✅ Flow language support is configured correctly against flow version in
package.json
<img width="993" alt="Screenshot 2024-06-10 at 16 03 44"
src="https://github.com/facebook/react/assets/5188459/b54e143c-a013-4e73-8995-3af7b5a03e36">
✅ Does not search in excluded files when the "include" field is
specified
<img width="555" alt="Screenshot 2024-06-10 at 15 39 18"
src="https://github.com/facebook/react/assets/5188459/dd3e5344-84fb-4b5d-8689-4c8bd28168e0">
✅ Workspace config is suggested when folder is opened in VS Code

✅ Dialog is shown on workspace launch with recommended VS Code
extensions
<img width="580" alt="Screenshot 2024-06-10 at 15 40 52"
src="https://github.com/facebook/react/assets/5188459/c6406fb6-92a0-47f1-8497-4ffe899bb6a9">
Our passes aren't sequenced such that we could observe this bug, but this retains the proper terminal kind for pruned-scopes in mapTerminalSuccessors.
ghstack-source-id: 1a03b40e45
Pull Request resolved: https://github.com/facebook/react/pull/29884
Summary: Minor change inspired by #29863: the BuildHIR pass ensures that Binary and UnaryOperator nodes only use a limited set of the operators that babel's operator types represent, which that pr relies on for safe reorderability, but the type of those HIR nodes admits the other operators. For example, even though you can't build an HIR UnaryOperator with `delete` as the operator, it is a valid HIR node--and if we made a mistaken change that let you build such a node, it would be unsafe to reorder.
This pr makes the typing of operators stricter to prevent that.
ghstack-source-id: 9bf3b1a37e
Pull Request resolved: https://github.com/facebook/react/pull/29880
The export maps for react packages have to choose an order of
preference. Many runtimes use multiple conditions, for instance when
building for edge webpack also uses the browser condition which makes
sense given most edge runtimes have a web-standards based set of APIs.
However React is building the browser builds primarily for actual
browsers and sometimes have builds intended for servers that might be
browser compat. This change updates the order of conditions to
preference specific named runtimes > node > generic edge runtimes >
browser > default
Fixes a bug found by mofeiZ in #29878. When we merge queued states, if the new state does not introduce changes relative to the queued state we should use the queued state, not the new state.
ghstack-source-id: c59f69de15
Pull Request resolved: https://github.com/facebook/react/pull/29879
That way we get owner stacks (native or otherwise) for `console.error`
or `console.warn` inside of them.
Since the `reportError` is also called within this context, we also get
them for errors thrown within event listeners. You'll also be able to
observe this in in the `error` event. Similar to how `onUncaughtError`
is in the scope of the instance that errored - even though
`onUncaughtError` doesn't kick in for event listeners.
Chrome (from console.createTask):
<img width="306" alt="Screenshot 2024-06-12 at 2 08 19 PM"
src="https://github.com/facebook/react/assets/63648/34cd9d57-0df4-44df-a470-e89a5dd1b07d">
<img width="302" alt="Screenshot 2024-06-12 at 2 03 32 PM"
src="https://github.com/facebook/react/assets/63648/678117b1-e03a-47d4-9989-8350212c8135">
Firefox (from React DevTools):
<img width="493" alt="Screenshot 2024-06-12 at 2 05 01 PM"
src="https://github.com/facebook/react/assets/63648/94ca224d-354a-4ec8-a886-5740bcb418e5">
(This is the parent stack since React DevTools doesn't just yet print
owner stack.)
(Firefox doesn't print the component stack for uncaught since we don't
add component stacks for "error" events from React DevTools - just
console.error. Perhaps an oversight.)
If we didn't have the synthetic event system this would kind of just
work natively in Chrome because we have this task active when we attach
the event listeners to the DOM node and async stacks just follow along
that way. In fact, if you attach a manual listener in useEffect you get
this same effect. It's just because we use event delegation that this
doesn't work.
However, if we did get rid of the synthetic event system we'd likely
still want to add a wrapper on the DOM node to set our internal current
owner so that the non-native part of the system still can observe the
active instance. That wouldn't work with manually attached listeners
though.
This lets the environment name vary within a request by the context a
component, log or error being executed in.
A potentially different API would be something like
`setEnvironmentName()` but we'd have to extend the `ReadableStream` or
something to do that like we do for `.allReady`. As a function though it
has some expansion possibilities, e.g. we could potentially also pass
some information to it for context about what is being asked for.
If it changes before completing a task, we also emit the change so that
we have the debug info for what the environment was before entering a
component and what it was after completing it.
Stacked on #29807.
This lets the nearest Suspense/Error Boundary handle it even if that
boundary is defined by the model itself.
It also ensures that when we have an error during serialization of
properties, those can be associated with the nearest JSX element and
since we have a stack/owner for that element we can use it to point to
the source code of that line. We can't track the source of any nested
arbitrary objects deeper inside since objects don’t track their stacks
but close enough. Ideally we have the property path but we don’t have
that right now. We have a partial in the message itself.
<img width="813" alt="Screenshot 2024-06-09 at 10 08 27 PM"
src="https://github.com/facebook/react/assets/63648/917fbe0c-053c-4204-93db-d68a66e3e874">
Note: The component name (Counter) is lost in the first message because
we don't print it in the Task. We use `"use client"` instead because we
expect the next stack frame to have the name. We also don't include it
in the actual error message because the Server doesn't know the
component name yet. Ideally Client References should be able to have a
name. If the nearest is a Host Component then we do use the name though.
However, it's not actually inside that Component that the error happens
it's in App and that points to the right line number.
An interesting case is that if something that's actually going to be
consumed by the props to a Suspense/Error Boundary or the Client
Component that wraps them fails, then it can't be handled by the
boundary. However, a counter intuitive case might be when that's on the
`children` props. E.g.
`<ErrorBoundary>{clientReferenceOrInvalidSerialization}</ErrorBoundary>`.
This value can be inspected by the boundary so it's not safe to pass it
so if it's errored it is not caught.
## Implementation
The first insight is that this is best solved on the Client rather than
in the Server because that way it also covers Client References that end
up erroring.
The key insight is that while we don't have a true stack when using
`JSON.parse` and therefore no begin/complete we can still infer these
phases for Elements because the first child of an Element is always
`'$'` which is also a leaf. In depth first that's our begin phase. When
the Element itself completes, we have the complete phase. Anything in
between is within the Element.
Using this idea I was able to refactor the blocking tracking mechanism
to stash the blocked information on `initializingHandler` and then on
the way up do we let whatever is nearest handle it - whether that's an
Element or the root Chunk. It's kind of like an Algebraic Effect.
cc @unstubbable This is something you might want to deep dive into to
find more edge cases. I'm sure I've missed something.
---------
Co-authored-by: eps1lon <sebastian.silbermann@vercel.com>