Commit Graph

21286 Commits

Author SHA1 Message Date
Sebastian "Sebbie" Silbermann
7fccd6b5a3 [DevTools] Fix console links not being openable (#35229) 2026-01-21 10:34:26 +01:00
Sebastian Markbåge
d29087523a Cancel animation when a custom Timeline is used (#35567)
Follow up to #35559.

The clean up function of the custom timeline doesn't necessarily clean
up the animation. Just the timeline's internal state.

This affects Firefox which doesn't support ScrollTimeline so uses the
polyfill's custom timeline.
2026-01-19 20:53:05 -05:00
Sebastian Markbåge
d343c39cce Remove Gesture warning when cloning the root (#35566)
Currently we always clone the root when a gesture transition happens.
The was to add an optimization where if a Transition could be isolated
to an absolutely positioned subtree then we could just clone that
subtree or just do a plain insertion if it was simple an Enter. That way
when switching between two absolutely positioned pages the shell
wouldn't need to be cloned. In that case `detectMutationOrInsertClones`
would return false. However, currently it always return true because we
don't yet have that optimization.

The idea was to warn when the root required cloning to ensure that you
optimize it intentionally since it's easy to accidentally update more
than necessary. However, since this is not yet actionable I'm removing
this warning for now.

Instead, I add a warning for particularly bad cases where you really
shouldn't clone like iframe and video. They may not be very actionable
without the optimization since you can't scope it down to a subtree
without the optimization. So if they're above the gesture then they're
always cloned atm. However, it might also be that it's unnecessary to
keep them mounted if they could be removed or hidden with Activity.
2026-01-19 19:28:12 -05:00
Sebastian Markbåge
1ecd99c774 Temporarily Mount useInsertionEffect while a Gesture snapshot is being computed (#35565)
`useInsertionEffect` is meant to be used to insert `<style>` tags that
affect the layout. It allows precomputing a layout before it mounts.

Since we're not normally firing any effects during the "apply gesture"
phase where we create the clones, it's possible for the target snapshot
to be missing styles. This makes it so that `useInsertionEffect` for a
new tree are mounted before the snapshot is taken and then unmounted
before the animation starts.

Note that because we are mounting a clone of the DOM tree and the
previous DOM tree remains mounted during the snapshot, we can't unmount
any previous insertion effects. This can lead to conflicts but that is
similar to what can happen with conflicts for two mounted Activity
boundaries since insertion effects can remain mounted inside those.

A revealed Activity will have already had their insertion effects fired
while offscreen.

However, one thing this doesn't yet do is handle the case where a
`useInsertionEffect` is *updated* as part of a gesture being applied.
This means it's still possible for it to miss some styles in that case.
The interesting thing there is that since the old state and the new
state will both be applicable to the global DOM in this phase, what
should really happen is that we should mount the new updated state
without unmounting the old state and then unmount the updated state.
Meaning you can have the same hook in the mounted state twice at the
same time.
2026-01-19 19:27:59 -05:00
Sebastian Markbåge
c55ffb5ca3 Add Clean Up Callbacks to View Transition and Gesture Transition Events (#35564)
Stacked on #35556 and #35559.

Given that we don't automatically clean up all view transition
animations since #35337 and browsers are buggy, it's important that you
clean up any `Animation` started manually from the events. However,
there was no clean up function for when the View Transition is forced to
stop. This also makes it harder to clean up custom timers etc too.

This lets you return a clean up function from all the events on
`<ViewTransition>`.
2026-01-19 19:27:45 -05:00
Sebastian Markbåge
a49952b303 Properly clean up gesture Animations (#35559)
Follow up to #35337.

During a gesture, we always cancel the original animation and create a
new one that we control. That's the one we need to add to the set that
needs to be cancelled. Otherwise future gestures hang.

An unfortunate consequence is that any custom ones that you start e.g.
with #35556 or through other means aren't automatically cleaned up (in
fact there's not even a clean up callback yet). This can lead these to
freeze the whole UI afterwards. It would be really good to get this
fixed in browsers instead so we can revert #35337.
2026-01-19 19:26:28 -05:00
Sebastian Markbåge
4bcf67e746 Support onGestureEnter/Exit/Share/Update events (#35556)
This is like the onEnter/Exit/Share/Update events but for gestures. It
allows manually controlling the animation using the passed timeline.
2026-01-19 19:26:09 -05:00
Sebastian "Sebbie" Silbermann
41b3e9a670 [Fizz] Push a stalled use() to the ownerStack/debugTask (#35226) 2026-01-19 09:10:16 +01:00
Ricky
195fd2286b [tests] Fix flaky flight tests (#35513)
Flights tests are failing locally and in CI non-deterministically
because we're not disabling async hooks after tests, and GC can clear
WeakRefs non-deterministically.

This PR fixes the issue by adding an afterEach to disable installed
hooks, and normalizing the `value` to `value: {value: undefined}}` when
snapshotting.
2026-01-18 15:36:00 -05:00
Ricky
d87298ae16 [tests] add silent reporter (#35547)
Adds silent reporter so you can run tests and only see the failed tests

This helps reduce context agents use, if you're inclined to use agents:

<img width="630" height="292" alt="Screenshot 2026-01-17 at 12 39 58 PM"
src="https://github.com/user-attachments/assets/373b9803-59a6-4b9a-99f9-d74a7b41462e"
/>
2026-01-18 10:17:17 -05:00
Ricky
be3fb29904 [internal] revert change merged accidentally (#35546)
I accidentally pushed this to new flag to
https://github.com/facebook/react/pull/35541 and then merged it.

Reverting it so I can submit a review.
2026-01-17 13:21:46 -05:00
Ricky
23e5edd05c [flags] clean up enableUseEffectEventHook (#35541)
This is landed everywhere
2026-01-17 12:46:05 -05:00
Jack Pope
3926e2438f Fix ViewTransition null stateNode with SuspenseList (#35520)
I was experimenting with animations in SuspenseList and hit a crash
using ViewTransition as a direct child with `revealOrder="together"`

```
    TypeError: Cannot read properties of null (reading 'autoName')

      33 |     return props.name;
      34 |   }
    > 35 |   if (instance.autoName !== null) {
         |                ^
      36 |     return instance.autoName;
      37 |   }
```

When ViewTransition is direct child of SuspenseList, the second render
pass calls resetChildFibers, setting stateNode to null. Other fibers
create stateNode in completeWork. ViewTransition does not, so stateNode
is lost.

Followed the pattern used for Offscreen to update stateNode in beginWork
if it is null.

Also added a regression test.
2026-01-16 16:39:25 -05:00
Hendrik Liebau
6baff7ac76 [Flight] Allow cyclic references to be serialized when unwrapping lazy elements (#35471)
When `renderModelDestructive` unwraps a lazy element and subsequently
calls `renderModelDestructive` again with the resolved model, we should
preserve the parent connection so that cyclic references can be
serialized properly. This can occur in an advanced scenario where the
result from the Flight Client is serialized again with the Flight
Server, e.g. for slicing a precomputed payload into multiple parts.

Note: The added test only fails when run with `--prod`. In dev mode, the
component info outlining prevents the issue from occurring.
2026-01-16 18:42:09 +01:00
Sebastian "Sebbie" Silbermann
bef88f7c11 [DevTools] Stop setting unused global variables (#35532) 2026-01-16 16:13:29 +01:00
Sebastian "Sebbie" Silbermann
01c4d03d84 [DevTools] Clear element inspection if host element not owned by any renderer is selected (#35504) 2026-01-16 13:20:44 +01:00
Sebastian "Sebbie" Silbermann
cbc4d40663 Typecheck React DevTools extension main script (#35519) 2026-01-16 13:08:28 +01:00
Josh Story
db71391c5c [Fiber] Instrument the lazy initializer thenable in all cases (#35521)
When a lazy element or component is initialized a thenable is returned
which was only be conditionally instrumented in dev when asyncDebugInfo
was enabled. When instrumented these thenables can be used in
conjunction with the SuspendOnImmediate optimization where if a thenable
resolves before the stack unwinds we can continue rendering from the
last suspended fiber. Without this change a recent fix to the useId
implementation cannot be easily tested in production because this
optimization pathway isn't available to regular React.lazy thenables. To
land the prior PR I changed the thenables to a custom type so I could
instrument manually in the test. WIth this change we can just use a
regular Promise since ReactLazy will instrument in all
environments/flags now
2026-01-15 19:05:23 -08:00
Sebastian Markbåge
4cf906380d Optimize gesture by allowing the original work in progress tree to be a suspended commit (#35510)
Stacked on #35487.

This is slightly different because the first suspended commit is on
blockers that prevent us from committing which still needs to be
resolved first.

If a gesture lane has to be rerendered while the gesture is happening
then it reenters this state with a new tree. (Currently this doesn't
happen for a ping I think which is not really how it usually works but
better in this case.)
2026-01-15 20:51:36 -05:00
Sebastian Markbåge
eac3c95537 Defer useDeferredValue updates in Gestures (#35511)
If an initial value is specified, then it's always used regardless as
part of the gesture render.

If a gesture render causes an update, then previously that was not
treated as deferred and could therefore be blocking the render. However,
a gesture is supposed to flush synchronously ideally. Therefore we
should consider these as urgent.

The effect is that useDeferredValue renders the previous state.
2026-01-15 20:46:11 -05:00
Sebastian Markbåge
35a81cecf7 Entangle Gesture revert commit with the corresponding Action commit (#35487)
Stacked on #35486.

When a Gesture commits, it leaves behind work on a Transition lane
(`revertLane`). This entangles that lane with whatever lane we're using
in the event that cancels the Gesture. This ensures that the revert and
the result of any resulting Action commits as one batch. Typically the
Action would apply a new state that is similar or the same as the revert
of the Gesture.

This makes it resilient to unbatching in #35392.
2026-01-15 20:45:14 -05:00
Sebastian Markbåge
4028aaa50c Commit the Gesture lane if a gesture ends closer to the target state (#35486)
Stacked on #35485.

Before this PR, the `startGestureTransition` API would itself never
commit its state. After the gesture releases it stops the animation in
the next commit which just leaves the DOM tree in the original state. If
there's an actual state change from the Action then that's committed as
the new DOM tree. To avoid animating from the original state to the new
state again, this is DOM without an animation. However, this means that
you can't have the actual action committing be in a slightly different
state and animate between the final gesture state and into the new
action.

Instead, we now actually keep the render tree around and commit it in
the end. Basically we assume that if the Timeline was closer to the end
then visually you're already there and we can commit into that state.
Most of the time this will be at the actual end state when you release
but if you have something else cancelling the gesture (e.g.
`touchcancel`) it can still commit this state even though your gesture
recognizer might not consider this an Action. I think this is ok and
keeps it simple.

When the gesture lane commits, it'll leave a Transition behind as work
from the revert lanes on the Optimistic updates. This means that if you
don't do anything in the Action this will cause another commit right
after which reverts. This revert can animate the snap back.

There's a few fixes needed in follow up PRs:

- Fixed in #35487. ~To support unentangled Transitions we need to
explicitly entangle the revert lane with the Action to avoid committing
a revert followed by a forward instead of committing the forward
entangled with the revert. This just works now since everything is
entangled but won't work with #35392.~
- Fixed in #35510. ~This currently rerenders the gesture lane once
before committing if it was already completed but blocked. We should be
able to commit the already completed tree as is.~
2026-01-15 20:43:52 -05:00
Josh Story
f0fbb0d199 [Fiber] fix useId tracking on replay (#35518)
When Fiber replays work after suspending and resolving in a microtask it
stripped the Forked flag from Fibers because this flag type was not
considered a Static flag. The Forked nature of a Fiber is not render
dependent and should persist after unwinding work. By making this change
the replay correctly generates the necessary tree context.
2026-01-15 17:27:58 -08:00
Sebastian "Sebbie" Silbermann
bb8a76c6cc [DevTools] Show fallback in inspected element pane when no element is selected (#35503) 2026-01-15 14:28:02 +01:00
Sebastian "Sebbie" Silbermann
fae15df40e [DevTools] Add React Element pane to browser Elements panel (#35240) 2026-01-15 13:24:06 +01:00
Błażej Kustra
53daaf5aba Improve the detection of changed hooks (#35123)
## Summary

cc @hoxyq 

Fixes https://github.com/facebook/react/issues/28584. Follow up to PR:
https://github.com/facebook/react/pull/34547

This PR updates getChangedHooksIndices to account for the fact that
`useSyncExternalStore`, `useTransition`, `useActionState`,
`useFormState` internally mounts more than one hook while DevTools
should treat it as a single user-facing hook.

Approach idea came from
[this](https://github.com/facebook/react/pull/34547#issuecomment-3504113776)
comment 😄

Before:


https://github.com/user-attachments/assets/6bd5ce80-8b52-4bb8-8bb1-5e91b1e65043


After:


https://github.com/user-attachments/assets/47f56898-ab34-46b6-be7a-a54024dcefee



## How did you test this change?

I used this component to reproduce this issue locally (I followed
instructions in `packages/react-devtools/CONTRIBUTING.md`).

<details><summary>Details</summary>

```ts

import * as React from 'react';

function useDeepNestedHook() {
  React.useState(0); // 1
  return React.useState(1); // 2
}

function useNestedHook() {
  const deepState = useDeepNestedHook();
  React.useState(2); // 3
  React.useState(3); // 4

  return deepState;
}

// Create a simple store for useSyncExternalStore
function createStore(initialValue) {
  let value = initialValue;
  const listeners = new Set();
  return {
    getSnapshot: () => value,
    subscribe: listener => {
      listeners.add(listener);
      return () => {
        listeners.delete(listener);
      };
    },
    update: newValue => {
      value = newValue;
      listeners.forEach(listener => listener());
    },
  };
}

const syncExternalStore = createStore(0);

export default function InspectableElements(): React.Node {
  const [nestedState, setNestedState] = useNestedHook();

  // 5
  const syncExternalValue = React.useSyncExternalStore(
    syncExternalStore.subscribe,
    syncExternalStore.getSnapshot,
  );

  // 6
  const [isPending, startTransition] = React.useTransition();

  // 7
  const [formState, formAction, formPending] = React.useActionState(
    async (prevState, formData) => {
      return {count: (prevState?.count || 0) + 1};
    },
    {count: 0},
  );

  const handleTransition = () => {
    startTransition(() => {
      setState(Math.random());
    });
  };

  // 8
  const [state, setState] = React.useState('test');

  return (
    <>
      <div
        style={{
          padding: '20px',
          display: 'flex',
          flexDirection: 'column',
          gap: '10px',
        }}>
        <div
          onClick={() => setNestedState(Math.random())}
          style={{backgroundColor: 'red', padding: '10px', cursor: 'pointer'}}>
          State: {nestedState}
        </div>

        <button onClick={handleTransition} style={{padding: '10px'}}>
          Trigger Transition {isPending ? '(pending...)' : ''}
        </button>

        <div style={{display: 'flex', gap: '10px', alignItems: 'center'}}>
          <button
            onClick={() => syncExternalStore.update(syncExternalValue + 1)}
            style={{padding: '10px'}}>
            Trigger useSyncExternalStore
          </button>
          <span>Value: {syncExternalValue}</span>
        </div>

        <form
          action={formAction}
          style={{display: 'flex', gap: '10px', alignItems: 'center'}}>
          <button
            type="submit"
            style={{padding: '10px'}}
            disabled={formPending}>
            Trigger useFormState {formPending ? '(pending...)' : ''}
          </button>
          <span>Count: {formState.count}</span>
        </form>

        <div
          onClick={() => setState(Math.random())}
          style={{backgroundColor: 'red', padding: '10px', cursor: 'pointer'}}>
          State: {state}
        </div>
      </div>
    </>
  );
}
```


</details>

---------

Co-authored-by: Ruslan Lesiutin <28902667+hoxyq@users.noreply.github.com>
2026-01-15 11:06:14 +00:00
Sebastian Markbåge
4a3d993e52 Add the suffix to cancelled view transition names (#35485)
When a View Transition might not need to update we add it to a queue. If
the parent are able to be reverted, we then cancel the already started
view transitions. We do this by adding an animation that hides the "old"
state and remove the view transition name from the old state.

There was a bug where if you have more than one child in a
`<ViewTransition>` we didn't add the right suffix to the name we added
in the queue so it wasn't adding an animation that hides the old state.
The effect was that it playing an exit animation instead of being
cancelled.
2026-01-14 10:00:06 -05:00
Ricky
3e1abcc8d7 [tests] Require exact error messages in assertConsole helpers (#35497)
Requires full error message in assert helpers. 

Some of the error messages we asset on add a native javascript stack
trace, which would be a pain to add to the messages and maintain. This
PR allows you to just add `\n in <stack>` placeholder to the error
message to denote a native stack trace is present in the message.

---
Note: i vibe coded this so it was a pain to backtrack this to break this
into a stack, I tried and gave up, sorry.
2026-01-13 15:52:53 -05:00
Josh Story
c18662405c [Fiber] Correctly handle replaying when hydrating (#35494)
When hydrating if something suspends and then resolves in a microtask it
is possible that React will resume the render without fully unwinding
work in progress. This can cause hydration cursors to be offset and lead
to hydration errors. This change adds a restore step when replaying
HostComponent to ensure the hydration cursor is in the appropriate
position when replaying.

fixes: #35210
2026-01-13 12:48:01 -08:00
Yukimasa Funaoka
583e200332 [DevTools] Enable minimal support in pages with sandbox Content-Security-Policy (#35208) 2026-01-13 17:49:44 +01:00
Sebastian "Sebbie" Silbermann
8a83073753 [test] Fix DevTools regression tests (#35501) 2026-01-13 16:00:16 +01:00
Sebastian "Sebbie" Silbermann
5aec1b2a8d [DevTools] Attach async info in filtered fallback to parent of Suspense (#35456) 2026-01-10 11:33:48 +01:00
lauren
d6cae440e3 [ci] Add size-balanced test sequencer for better shard distribution (#35458)
Jest's default test sequencer sorts alphabetically, causing large test
files
(eg ReactDOMFloat-test.js at 9k lines,
ReactHooksWithNoopRenderer-test.js at 4k
lines) to cluster in shard 3/5. This made shard 3/5 average 117s vs 77s
for
other shards, a 52% slowdown. I'm using filesize as a rough proxy for
number of tests.

This custom sequencer sorts tests by file size and distributes large
files evenly across all shards
instead of clustering them together.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35458).
* __->__ #35458
* #35459
2026-01-06 21:29:22 -05:00
lauren
00908be9ff [ci] Increase DevTools test shards and bump timeout (#35459)
[ci] Increase DevTools test shards and bump timeout

- Increase DevTools test shards from 3 to 5
- Bump timeout to 20s

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35459).
* #35458
* __->__ #35459
2026-01-06 21:23:05 -05:00
lauren
0e180141bf [ci] Separate DevTools test-build into dedicated job with fewer shards (#35457)
DevTools has ~45 test files which don't distribute well across 10
shards,
causing shard 3 to run 2x slower than others (104s vs ~50s). This moves
DevTools build tests to a separate job with 3 shards for better load
balancing.
2026-01-06 20:23:40 -05:00
Jon Jensen
65eec428c4 Use FormData submitter parameter (#29028) 2025-12-18 11:34:15 +01:00
Hendrik Liebau
454fc41fc7 [test] Add tests for cyclic arrays in Flight and Flight Reply (#35347)
We already had tests for cyclic objects, but not for cyclic arrays.
2025-12-17 18:08:16 +01:00
Sebastian Markbåge
f93b9fd44b Skip hydration errors when a view transition has been applied (#35380)
When the Fizz runtime runs a view-transition we apply
`view-transition-name` and `view-transition-class` to the `style`. These
can be observed by Fiber when hydrating which incorrectly leads to
hydration errors.

More over, even after we remove them, the `style` attribute has now been
normalized which we are unable to diff because we diff against the SSR
generated `style` attribute string and not the normalized form. So if
there are other inline styles defined, we have to skip diffing them in
this scenario.
2025-12-17 09:37:43 -05:00
Christian Van
b731fe28cc Improve cyclic thenable detection in ReactFlightReplyServer (#35369)
## Summary

This PR improves cyclic thenable detection in
`ReactFlightReplyServer.js`. Fixes #35368.
The previous fix only detected direct self-references (`inspectedValue
=== chunk`) and relied on the `cycleProtection` counter to eventually
bail out of longer cycles. This change keeps the existing
MAX_THENABLE_CYCLE_DEPTH ($1000$) `cycleProtection` cap as a hard
guardrail and adds a visited set so that we can detect self-cycles and
multi-node cycles as soon as any `ReactPromise` is revisited and while
still bounding the amount of work we do for deep acyclic chains via
`cycleProtection`.

## How did you test this change?

- Ran the existing test suite for the server renderer:

  ```bash
  yarn test react-server
  yarn test --prod react-server
  yarn flow dom-node
  yarn linc
  ```

---------

Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
2025-12-17 12:22:26 +01:00
Jack Pope
88ee1f5955 Add reporting modes for react-hooks/exhaustive-effect-dependencies and temporarily enable (#35365)
`react-hooks/exhaustive-effect-dependencies` from
`ValidateExhaustiveDeps` reports errors for both missing and extra
effect deps. We already have `react-hooks/exhaustive-deps` that errors
on missing dependencies. In the future we'd like to consolidate this all
to the compiler based error, but for now there's a lot of overlap. Let's
enable testing the extra dep warning by splitting out reporting modes.

This PR
- Creates `on`, `off`, `missing-only`, and `extra-only` reporting modes
for the effect dep validation flag
- Temporarily enables the new rule with `extra-only` in
`eslint-plugin-react-hooks`
- Adds additional null checking to `manualMemoLoc` to fix a bug found
when running against the fixture
2025-12-15 18:59:27 -05:00
emily8rown
bcf97c7564 Devtools disable log dimming strict mode setting (#35207)
<!--

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`).

-->

## Summary

Currently, every second console log is dimmed, receiving a special style
that indicates to user that it was raising because of [React Strict
Mode](https://react.dev/reference/react/StrictMode) second rendering.
This introduces a setting to disable this.

## How did you test this change?
Test in console-test.js


https://github.com/user-attachments/assets/af6663ac-f79b-4824-95c0-d46b0c8dec12

Browser extension react devtools


https://github.com/user-attachments/assets/7e2ecb7a-fbdf-4c72-ab45-7e3a1c6e5e44

React native dev tools:


https://github.com/user-attachments/assets/d875b3ac-1f27-43f8-8d9d-12b2d65fa6e6

---------

Co-authored-by: Ruslan Lesiutin <28902667+hoxyq@users.noreply.github.com>
2025-12-15 13:41:43 +00:00
Sebastian "Sebbie" Silbermann
ba5b843692 [test] Exclude repository root from assertions (#35361) 2025-12-15 11:45:17 +01:00
Jack Pope
b061b597f7 Upgrade nextjs for compiler playground (#35353)
Upgrading due to CVE-2025-55183 and CVE-2025-67779
2025-12-12 09:06:31 -05:00
Jorge Cabiedes
38a6f4e4a1 [compiler] Only run validations with env.logErrors on outputMode: 'lint' (#35216)
Summary:
These validations are not essential for compilation, with this we only
run that logic when outputMode is 'lint'

Test Plan:
Update fixtures and run tests
2025-12-11 16:36:36 -08:00
Nathan
b85cf6af3d [compiler] Fix VariableDeclarator source location (#35348)
Putting up https://github.com/facebook/react/pull/35129 again
Reverted in https://github.com/facebook/react/pull/35346 after breaking
main before security patch

This change impacts output formatting in a lot of snaps, so is very
sensitive to additions in main to the fixtures resulting in broken tests
after merging, so we should try merge quickly after rebasing or do a
fast follow to the merge with a snap update.
2025-12-11 18:02:05 -05:00
Sebastian Markbåge
b45bb335db [Flight] Add extra loop protection (#35351)
In case we get into loops.
2025-12-11 17:23:01 -05:00
Sebastian Markbåge
80cb7a9925 Revert "[compiler] Fix VariableDeclarator source location (#35129)" (#35346)
This broke main.
2025-12-11 15:27:07 -05:00
Sebastian Markbåge
894bc73cb4 [Flight] Patch Promise cycles and toString on Server Functions (#35345)
Server Functions can be stringified (sometimes implicitly) when passed
as data. This adds an override to hide the source code in that case -
just in case someone puts sensitive information in there.

Note that this still preserves the `name` field but this is also
available on the export but in practice is likely minified anyway.
There's nothing else on these referenes we'd consider unsafe unless you
explicitly expose expandos which are part of the `"use server"` export.

This adds a safety check to ensure you don't encode cyclic Promises.
This isn't a parser bug per se. Promises do have a safety mechanism that
avoids them infinite looping. However, since we use custom Thenables,
what can happen is that every time a native Promise awaits it, another
Promise wrapper is created around the Thenable which foils the
ECMAScript Promise cycle detection which can lead to an infinite loop.

This also ensures that embedded `ReadableStream` and `AsyncIterable`
streams are properly closed if the source stream closes early both on
the Server and Client. This doesn't cause an infinite loop but just to
make sure resource clean up can proceed properly.

We're also adding some more explicit clear errors for invalid payloads
since we no longer need to obfuscate the original issue.
2025-12-11 15:24:24 -05:00
Nathan
d3eb566291 [compiler] Fix VariableDeclarator source location (#35129)
### What
Fixes source locations for VariableDeclarator in the generated AST.
Fixes a number of the errors in the snapshot I added yesterday in the
source loc validator PR https://github.com/facebook/react/pull/35109

I'm not entirely sure why, but a side effect of the fix has resulted in
a ton of snaps needing updating, with some empty lines no longer present
in the generated output. I broke the change up into 2 separate commits.
The [first
commit](f4e4dc0f44)
has the core change and the update to the missing source locations test
expectation, and the [second
commit](cd4d9e944c)
has the rest of the snapshot updates.

### How
- Add location for variable declarators in ast codegen.
- We don't actually have the location preserved in HIR, since when we
lower the declarations we pass through the location for the
VariableDeclaration. Since VariableDeclarator is just a container for
each of the assignments, the start of the `id` and end of the `init` can
be used to accurately reconstruct it when generating the AST.
- Add source locations for object/array patterns for destructuring
assignment source location support
2025-12-11 14:35:03 -05:00
Ruslan Lesiutin
37bcdcde04 fix[devtools]: feature-check document with typeof instead of direct reference (#35343)
Follow-up to https://github.com/facebook/react/pull/35296.

We can get `ReferenceError` if this is unavailable. Using `typeof` check
instead for safety.
2025-12-11 12:15:00 +00:00