forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 0
Mirror of upstream PR #35051 #548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kushxg
wants to merge
780
commits into
main
Choose a base branch
from
upstream-pr-35051
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Stacked on facebook#34509. View Transitions introduces a bunch of new types of gaps in the commit phase which needs to be logged differently in the performance track. One thing that can happen is that a `flushSync` update forces the View Transition to abort before it has started if it happens in the gap before the transition is ready. In that case we log "Interrupted View Transition". Otherwise, when we're done in `startViewTransition` there's some work to finalize the animations before the `ready` calllback. This is logged as "Starting Animation". Then there's a gap before the passive effects fire which we log as "Animating". This can be long unless they're forced to flush early e.g. due to another lane updating. The "Animating" track should then pick up which doesn't do yet. This one is tricky because this is after the actual commit phase and needs to be interrupted by new renders which themselves can be suspended on the animation finshing. This PR is just a subset of all the cases. Will need a lot more work. <img width="679" height="161" alt="Screenshot 2025-09-16 at 10 19 06 PM" src="https://github.com/user-attachments/assets/0407372d-aaed-41f5-a262-059b2686ae87" />
…type (facebook#34521) Some components accept a union of a ref callback function or ref object. In this case we may infer the type as a function due to the presence of invoking the ref callback function. In that case, we currently report a "Hint: name `fooRef` as "ref" or with a "-Ref" suffix..." even though the variable is already named appropriately — the problem is that we inferred a non-ref type. So here we check the type and don't report this hint if we inferred another type.
…le in build hir (facebook#34488) <!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. Before submitting a pull request, please make sure the following is done: 1. Fork [the repository](https://github.com/facebook/react) and create your branch from `main`. 2. Run `yarn` in the repository root. 3. If you've fixed a bug or added code that should be tested, add tests! 4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development. 5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`. 6. If you need a debugger, run `yarn test --debug --watch TestName`, open `chrome://inspect`, and press "Inspect". 7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`). 8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files. 9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`). 10. If you haven't already, complete the CLA. Learn more about contributing: https://reactjs.org/docs/how-to-contribute.html --> ## Summary <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> The React Compiler rejected a default parameter that contains a TSInstantiationExpression with the todo message that the expression cannot be safely reordered. This change teaches the reorder check in BuildHIR.ts to treat TSInstantiationExpression as reorderable. This is safe because TypeScript instantiation only affects types and is erased at runtime, so it has no side effects and does not change semantics. ## How did you test this change? ``` Set-Content testfilter.txt 'ts-instantiation-default-param' yarn test --filter --update yarn test --filter ``` <!-- 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. --> I added a fixture: > compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ts-instantiation-default-param.js
Stacked on facebook#34510. The "Commit" phase for a View Transition starts before the snapshot phase (before mutation) and then stretches into the async gap of `startViewTransition`, encompasses the mutation phase inside of its update callback and finally the layout phase. However, between the mutation phase and the layout phase we may suspend the start of the view transition on fonts and/or images. In that case we now split the Commit phase into first one before we suspend and then we log "Waiting for Images and/or Fonts" and then another Commit phase around the layout effects. <img width="897" height="119" alt="Screenshot 2025-09-16 at 11 37 26 PM" src="https://github.com/user-attachments/assets/0fe21388-bb48-4456-a594-62227d12d9b7" />
…book#34523) In an upstack PR, I need `getDebugInfo` in another test file, so I'm moving it to `internal-test-utils` so it can be shared.
<!-- 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 Made many small changes to the compiler playground to improve user experience. Removed any "Loading" indicators that would flash in before a component would finish loading in. Additionally, before users would see the "Show Internals" button toggling from false to true if they had set it at true previously. I was able to refactor the URL/local storage loading so that the `Store` would be fully initialized before the components would load in. Attempted to integrate `<Activity>` into showing/hiding these different editors, but the current state of [monaco editors](https://github.com/suren-atoyan/monaco-react) does not allow for this. I created an issue for them to address: suren-atoyan/monaco-react#753 Added a debounce to the config editor so every key type wouldn't cause the output panel to respond instantly. Users can type for 500 ms before an error is thrown at them. <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> ## How did you test this change? Here is what loading the page would look like before (not sure why its so blurry): https://github.com/user-attachments/assets/58f4281a-cc02-4141-b9b5-f70d6ace12a2 Here is how it looks now: https://github.com/user-attachments/assets/40535165-fc7c-44fb-9282-9c7fa76e7d53 Here is the debouncing: https://github.com/user-attachments/assets/e4ab29e4-1afd-4249-beca-671fb6542f5e <!-- 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. -->
…ok#34531) Seems like this was missed in facebook#31313
If we don't handle Lazy types specifically in `renderDebugModel`, all of their properties will be emitted using `renderDebugModel` as well. This also includes its `_debugInfo` property, if the Lazy comes from the Flight client. That array might contain objects that are deduped, and resolving those references in the client can cause runtime errors, e.g.: ``` TypeError: Cannot read properties of undefined (reading '$$typeof') ``` This happened specifically when an "RSC stream" debug info entry, coming from the Flight client through IO tracking, was emitted and its `debugTask` property was deduped, which couldn't be resolved in the client. To avoid actually initializing a lazy causing a side-effect, we make some assumptions about the structure of its payload, and only emit resolved or rejected values, otherwise we emit a halted chunk.
If we are referencing a lazy value that isn't explicitly lazy ($L...) it's because we added it around an element that was blocked to be able to defer things inside. However, once that is unblocked we can start unwrap it and just use the inner element instead for any future reference. The race condition is still there since it's a race condition whether we added the wrapper in the first place. This just makes it consistent with unwrapping of the rest of the path.
…acebook#34537) Triggering the "(Runtime) Publish Prereleases Manual" workflow with a short git sha doesn't work. It needs the full sha. We might be able to make it work with the short sha as well, but for now we can at least document the restriction.
Stacked on facebook#34511. We currently log all Suspended Commit as "Suspended on Images or CSS" but it can really be other reasons too now. Like waiting on the previous View Transition. This allows the host config configure this reason. Now when one animation starts before another one finishes we log that as "Waiting for the previous Animation". <img width="592" height="257" alt="Screenshot 2025-09-17 at 11 53 45 PM" src="https://github.com/user-attachments/assets/817af8b5-37ae-46d8-bfd1-cd3fc637f3f3" />
) Stacked on facebook#34522. <img width="1025" height="200" alt="Screenshot 2025-09-19 at 6 37 28 PM" src="https://github.com/user-attachments/assets/f25900f6-6503-48b1-876d-bd6697a29c6f" /> We already cover the time between "Starting Animation" and "Remaining Effects" as "Animating". However, if the effects are forced then we can still be animating after that. This fills in that gap. This also fills in the gap if another render starts before the animation finishes on the same track. It'll mark the blank space between the previous render finishing and the next render starting as "Animating". This should correspond roughly to the native "Animations" track.
…races (facebook#34539) Stacked on facebook#34538. Track the Task of the first ViewTransition that we detected as animating. Use this as the Task as "Starting Animation", "Animating" etc. That way you can see which ViewTransition spawned the Animation. Although it's likely to be multiple. <img width="757" height="393" alt="Screenshot 2025-09-19 at 10 19 18 PM" src="https://github.com/user-attachments/assets/a6cdcb89-bd02-40ec-b3c3-11121c29e892" />
<!-- 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? --> Added more tests for the compiler playground with the addition of the new config editor and "Show Internals" button. Added testing to check for incomplete store params in the URL, toggle functionality, and correct errors showing for syntax/validation errors in the config overrides.
…ook#34533) The root instance doesn't have a canonical property so we were not returning a public instance that we can call compareDocumentPosition on when a Fragment had no other host parent in Fabric. In this case we need to get the ReactNativeElement from the ReactNativeDocument. I've also added test coverage for this case in DOM for consistency, though it was already working there because we use DOM elements as root. This same test will be copied to RN using Fantom.
…book#34566) If there is a large owner stack, we could potentially spam multiple fetch requests for the same source map. This adds a simple deduplication logic, based on URL. Also, this adds a timeout of 60 seconds to all fetch requests initiated by fileFetcher content script.
…facebook#34492) --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34492). * facebook#34497 * __->__ facebook#34492
[sourcemap-codec](https://www.npmjs.com/package/sourcemap-codec) (deprecated) -> [@jridgewell/sourcemap-codec](https://www.npmjs.com/package/@jridgewell/sourcemap-codec) Validated that symbolication still works.
This helper weirdly doesn't include the sync lane. Everywhere we use it we have to check the sync lane separately. We can simplify things by simply including the sync lane. This fixes a lack of optimization because we should not check the store consistency for a `flushSync` render. https://github.com/facebook/react/blob/d91d28c8ba6fe7c96e651f82fc47c9d5481bf5f9/packages/react-reconciler/src/ReactFiberHooks.js#L1691-L1693
…ing (facebook#34548) Stacked on facebook#34546. Same as facebook#34538 but for gestures. Includes various fixes. This shows how it ends with a Transition when you release in the committed state. Note how the Animation of the Gesture continues until the Transition is done so that the handoff is seamless. <img width="853" height="134" alt="Screenshot 2025-09-20 at 7 37 29 PM" src="https://github.com/user-attachments/assets/6192a033-4bec-43b9-884b-77e3a6f00da6" />
…facebook#34580) Summary: Change error and update snapshots The error now mentions what values are causing the issue which should provide better context on how to fix the issue --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34580). * __->__ facebook#34580 * facebook#34579 * facebook#34578 * facebook#34577 * facebook#34575 * facebook#34574
…ook#34963) When a longer function or expression is identified as the source of an error, we currently print the entire expression in our error message. This is because we delegate to a Babel helper to print codeframes. Here, we add some checking and abbreviate the result if it spans too many lines.
Some vulnerabilities were detected in older versions of Playwright, upgrading for the playground.
(disclaimer: I used codex to write this script) Adds a new `yarn generate-changelog` script to simplify the process of writing changelogs. You can use it as follows: ``` $ yarn generate-changelog --help Usage: yarn generate-changelog [--codex|--claude] [--debug] [<pkg@version> ...] Options: --codex Use Codex for commit summarization. [boolean] --claude Use Claude for commit summarization. [boolean] --debug Enable verbose debug logging. [boolean] [default: false] -h, --help Show help [boolean] Examples: generate-changelog --codex Generate changelog for a single [email protected] package using Codex. generate-changelog --claude [email protected] Generate changelog entries for [email protected] multiple packages using Claude. generate-changelog --codex Generate changelog for all stable packages using recorded versions. ``` For example, if no args are passed, the script will print find all the relevant commits affecting packages (defaults to `stablePackages` in `ReactVersions.js`) and format them as a simple markdown list. ``` $ yarn generate-changelog ## [email protected] * [compiler] improve zod v3 backwards compat (facebook#34877) ([facebook#34877](facebook#34877) by [@henryqdineen](https://github.com/henryqdineen)) * [ESLint] Disallow passing effect event down when inlined as a prop (facebook#34820) ([facebook#34820](facebook#34820) by [@jf-eirinha](https://github.com/jf-eirinha)) * Switch to `export =` to fix eslint-plugin-react-hooks types (facebook#34949) ([facebook#34949](facebook#34949) by [@karlhorky](https://github.com/karlhorky)) * [eprh] Type `configs.flat` more strictly (facebook#34950) ([facebook#34950](facebook#34950) by [@poteto](https://github.com/poteto)) * Add hint for Node.js cjs-module-lexer for eslint-plugin-react-hook types (facebook#34951) ([facebook#34951](facebook#34951) by [@karlhorky](https://github.com/karlhorky)) * Add hint for Node.js cjs-module-lexer for eslint-plugin-react-hook types (facebook#34953) ([facebook#34953](facebook#34953) by [@karlhorky](https://github.com/karlhorky)) // etc etc... ``` If `--codex` or `--claude` is passed, the script will attempt to use them to summarize the commit(s) in the same style as our existing CHANGELOG.md. And finally, for debugging the script you can add `--debug` to see what's going on.
Now that RN is only on the New Architecture, we can stop stop syncing the legacy React Native renderers. In this diff, I just stop syncing them. In a follow up I'll delete the code for them so only Fabric is left. This will also allow us to remove the `enableLegacyMode` feature flag.
Stacked on facebook#34946 This should be a noop, now that the legacy renderers are not being sync'd.
Adds a new `--format` option which can be `text` (default), `csv`, or `json`. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34992). * facebook#34993 * __->__ facebook#34992
Just a light reorganization.
500 tests failed from not using async act. Will fix the tests and then re-land this.
…acebook#35003) IO tasks can execute more than once. E.g. a connection may fire each time a new message or chunk comes in or a setInterval every time it executes. We used to treat these all as one I/O node and just updated the end time as we go. Most of the time this was fine because typically you would have a Promise instance whose end time is really the one that gets used as the I/O anyway. However, in a pattern like this it could be problematic: ```js setTimeout(() => { function App() { return Promise.resolve(123); } renderToReadableStream(<App />); }); ``` Because the I/O's end time is before the render started so it should be excluded from being considered I/O as part of the render. It happened outside of render. But because the `Promise.resolve()` is inside render its end time is after the render start so the promise is considered part of the render. This is usually not a problem because the end time of the I/O is still before the start of the render so even though the Promise is valid it has no I/O source so it's properly excluded. However, if the I/O's end time updates before we observe this then the I/O can be considered part of the render. E.g. if this was a setInterval it would be clearly wrong. But it turns out that even setTimeout can sometimes execute more than once in the async_hooks because each run of "process.nextTick" and microtasks respectively are ran in their own before/after. When a micro task executes after this main body it'll update the end time which can then turn the whole I/O as being inside the render. To solve this properly I create a new I/O node each time before() is invoked so that each one gets to observe a different end time. This has a potential CPU and memory allocation cost when there's a lot of them like in a quick stream.
… times along different paths (facebook#35005) We avoid visiting the same async node twice but if we see it again we returned "null" indicating that there's no I/O there. This means that if you have two different Promises both resolving from the same I/O node then we only show one of them. However, in general we treat that as two different I/O entries to allow for things like batching to still show up separately. This fixes that by caching the return value for multiple visits. So if we found I/O (but no user space await) in one path and then we visit that path through a different Promise chain, then we'll still emit it twice. However, if we visit the same exact Promise that we emitted an await on then we skip it. Because there's no need to emit two awaits on the same thing. It only matters when the path ends up informing whether it has I/O or not.
…t order (facebook#35011) Right now it's possible for things like server environments to appear before other content in the timeline just because it's in a different document order. Ofc the order in production is not guaranteed but we can at least use the timing information we have as a hint towards the actual order. Unfortunately since the end time of the RSC stream itself is always after the content that resolved to produce it, it becomes kind of determined by the chunking. Similarly since for a clean refresh, the scripts and styles will typically load after the server content they appear later. Similarly SSR typically finishes after the RSC parts. Therefore a hack here is that I artificially delay everything with a non-null environment (RSC) so that RSC always comes after client-side (Suspense). This is also consistent with how we color things that have an environment even if children are just Suspense. To ensure that we never show a child before a parent, in the timeline, each child has a minimum time of its parent.
…Document (facebook#34641) It's annoying to have to try to find where it lines up with no hints. This way when you hover over something it should be on screen. The strategy I went with is that it scrolls to a percentage along the scrollable axis but the two might not be exactly the same. Partially because they have different aspect ratios but also because suspended boundaries can shrink the document while the suspense tab needs to still be able to show the boundaries that are currently invisible.
…ok#35012) When rects are close together (or overlapping) the outline can end up being covered up by sibling rects or deeper rects. This renders the selected outline on top of everything so it's always visible. <img width="275" height="730" alt="Screenshot 2025-10-29 at 8 43 28 PM" src="https://github.com/user-attachments/assets/69224883-f548-45ec-ada1-1a04ec17eaf5" /> <img width="266" height="737" alt="Screenshot 2025-10-29 at 8 58 53 PM" src="https://github.com/user-attachments/assets/946f7dde-450d-49fd-9fbd-57487f67f461" /> Additionally, this makes it so that it's not part of the translucent tree when things are hidden by the timeline. That way it's easier to see what is selected inside a hidden tree. <img width="498" height="196" alt="Screenshot 2025-10-29 at 8 45 24 PM" src="https://github.com/user-attachments/assets/723107ab-a92c-42c2-8a7d-a548ac3332d0" /> <img width="571" height="735" alt="Screenshot 2025-10-29 at 8 59 06 PM" src="https://github.com/user-attachments/assets/d653f1a7-4096-45c3-b92a-ef155d4742e6" />
…penseList (facebook#35018) We have warned about this for a while now so we can make the switch. Often when you reach for SuspenseList, you mean forwards. It doesn't make sense to have the default to just be a noop. While "together" is another useful mode that's more like a Group so isn't so associated with the default as List. So we're switching it. However, tail=hidden isn't as obvious of a default it does allow for a convenient pattern for streaming in list of items by default. This doesn't yet switch the rendering order of "backwards". That's coming in a follow up.
…rder (facebook#35021) Stacked on facebook#35018. This mounts the children of SuspenseList backwards. Meaning the first child is mounted last in the DOM (and effect list). It's like calling reverse() on the children. This is meant to set us up for allowing AsyncIterable children where the unknown number of children streams in at the end (which is the beginning in a backwards SuspenseList). For consistency we do that with other children too. `unstable_legacy-backwards` still exists for the old mode but is meant to be deprecated. <img width="100" alt="image" src="https://github.com/user-attachments/assets/5c2a95d7-34c4-4a4e-b602-3646a834d779" />
…book#35036) In facebook#35019, we excluded debug I/O info from being considered for enhancing the owner stack if it resolved after the defined `endTime` option that can be passed to the Flight client. However, we should include any I/O that was awaited before that end time, even if it resolved later.
This PR adds a `unstable_reactFragments?: Set<FragmentInstance>` property to DOM nodes that belong to a Fragment with a ref (top level host components). This allows you to access a FragmentInstance from a DOM node. This is flagged behind `enableFragmentRefsInstanceHandles`. The primary use case to unblock is reusing IntersectionObserver instances. A fairly common practice is to cache and reuse IntersectionObservers that share the same config, with a map of node->callbacks to run for each entry in the IO callback. Currently this is not possible with Fragment Ref `observeUsing` because the key in the cache would have to be the `FragmentInstance` and you can't find it without a handle from the node. This works now by accessing `entry.target.fragments`. This also opens up possibilities to use `FragmentInstance` operations in other places, such as events. We can do `event.target.unstable_reactFragments`, then access `fragmentInstance.getClientRects` for example. In a future PR, we can assign an event's `currentTarget` as the Fragment Ref for a more direct handle when the event has been dispatched by the Fragment itself. The first commit here implemented a handle only on observed elements. This is awkward because there isn't a good way to document or expose this temporary property. `element.fragments` is closer to what we would expect from a DOM API if a standard was implemented here. And by assigning it to all top-level nodes of a Fragment, it can be used beyond the cached IntersectionObserver callback. One tradeoff here is adding extra work during the creation of FragmentInstances as well as keeping track of adding/removing nodes. Previously we only track the Fiber on creation but here we add a traversal which could apply to a large set of top-level host children. The `element.unstable_reactFragments` Set can also be randomly ordered.
…cebook#35039) For Edge Flight servers, that use Web Streams, we're defining the `debugChannel` option as: ``` debugChannel?: {readable?: ReadableStream, writable?: WritableStream, ...} ``` Whereas for Node.js Flight servers, that use Node.js Streams, we're defining it as: ``` debugChannel?: Readable | Writable | Duplex | WebSocket ``` For the Edge Flight clients, there is currently only one direction of the debug channel supported, so we define the option as: ``` debugChannel?: {readable?: ReadableStream, ...} ``` Consequently, for the Node.js Flight clients, we define the option as: ``` debugChannel?: Readable ``` The presence of a readable debug channel is passed to the Flight client internally via the `hasReadable` flag on the internal `debugChannel` option. For the Node.js clients, that flag was accidentally derived from the public option `debugChannel.readable`, which is conceptually incorrect, because `debugChannel` is a `Readable` stream, not an options object with a `readable` property. However, a `Readable` also has a `readable` property, which is a boolean that indicates whether the stream is in a readable state. This meant that the `hasReadable` flag was incidentally still set correctly. Regardless, this was confusing and unintentional, so we're now fixing it to always set `hasReadable` to `true` when a `debugChannel` is provided to the Node.js clients. We'll revisit this in case we ever add support for writable debug channels in Node.js (and Edge) clients.
We were not recording uEE calls in component/hook syntax. Easy fix. Added tests matching function component syntax for component syntax + added one for hooks
…acebook#35042) Normally if you suspend in a SuspenseList row above a Suspense boundary in that row, it'll suspend the parent. Which can itself delay the commit or resuspend a parent boundary. That's because SuspenseList mostly just coordinates the state of the inner boundaries and isn't a boundary itself. However, for tail "hidden" and "collapsed" this is not quite the case because the rows themselves can avoid being rendered. In the case of "collapsed" we require at least one Suspense boundary above to have successfully rendered before committing the list because the idea of this mode is that you should at least always show some indicator that things are still loading. Since we'd never try the next one after that at all, this just works. Expect there was an unrelated bug that meant that "suspend with delay" on a Retry didn't suspend the commit. This caused a scenario were it'd allow a commit proceed when it shouldn't. So I fixed that too. The counter intuitive thing here is that we won't actually show a previous completed row if the loading state of the next row is still loading. For tail "hidden" it's a little different because we don't actually require any loading indicator at all to be shown while it's loading. If we attempt a row and it suspends, we can just hide it (and the rest) and move to commit. Therefore this implements a path where if all the rest of the tail are new mounts (we wouldn't be required to unmount any existing boundaries) then we can treat the SuspenseList boundary itself as "catching" the suspense. This is more coherent semantics since any future row that we didn't attempt also wouldn't resuspend the parent. This allows simple cases like `<SuspenseList>{list}</SuspenseList>` to stream in each row without any indicator and no need for Suspense boundaries.
I don't think we're ready to land this yet since we're using it to run other experiments and our tests. I'm opening this PR to indicate intent to disable and to ensure tests in other combinations still work. Such as enableHalt without enablePostpone. I think we'll also need to rewrite some tests that depend on enablePostpone to preserve some coverage. The conclusion after this experiment is that try/catch around these are too likely to block these signals and consider them error. Throwing works for Hooks and `use()` because the lint rule can ensure that they're not wrapped in try/catch. Throwing in arbitrary functions not quite ecosystem compatible. It's also why there's `use()` and not just throwing a Promise. This might also affect the Catch proposal. The "prerender" for SSR that's supporting "Partial Prerendering" is still there. This just disables the `React.postpone()` API for creating the holes.
We're not shipping this and it's a lot of code to maintain that is blocking my refactor of Fizz for SuspenseList.
…mplement in SSR (facebook#35022) We've long had the CPU suspense feature behind a flag under the terrible API `unstable_expectedLoadTime={arbitraryNumber}`. We've known for a long time we want it to just be `defer={true}` (or just `<Suspense defer>` in the short hand syntax). So this adds the new name and warns for the old name. For only the new name, I also implemented SSR semantics in Fizz. It has two effects here. 1) It renders the fallback before the content (similar to prerender) allowing siblings to complete quicker. 2) It always outlines the result. When streaming this should really happen naturally but if you defer a prerendered content it also implies that it's expensive and should be outlined. It gives you a opt-in to outlining similar to suspensey images and css but let you control it manually.
It's now replaced by defer.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Mirrored from facebook/react PR facebook#35051