Skip to content

Commit 511936b

Browse files
committed
support React 19.1
1 parent a1ea0b8 commit 511936b

6 files changed

Lines changed: 36 additions & 29 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ Configuration options for the test renderer. Many of these options correspond to
106106
| `transformHiddenInstanceProps` | `({ props, type }: { props: Record<string, unknown>; type: string }) => Record<string, unknown>` | Transforms host instance props when React marks an instance as hidden (for example, while Suspense fallback is shown). Return a new props object instead of mutating the provided one. When provided, hidden instances stay visible in `children` and `toJSON()` output using transformed props. |
107107
| `identifierPrefix` | `string` | A string prefix React uses for IDs generated by `useId()`. Useful to avoid conflicts when using multiple roots. |
108108
| `isStrictMode` | `boolean` | Enable React Strict Mode. When enabled, components render twice and effects run twice in development. |
109-
| `onCaughtError` | `(error: unknown, errorInfo: { componentStack: string }) => void` | Callback called when React catches an error in an Error Boundary. Called with the error caught by the Error Boundary and an errorInfo object containing the component stack. |
110-
| `onUncaughtError` | `(error: unknown, errorInfo: { componentStack: string }) => void` | Callback called when an error is thrown and not caught by an Error Boundary. Called with the error that was thrown and an errorInfo object containing the component stack. |
111-
| `onRecoverableError` | `(error: unknown, errorInfo: { componentStack: string }) => void` | Callback called when React automatically recovers from errors. Called with an error React throws and an errorInfo object containing the component stack. Some recoverable errors may include the original error cause as `error.cause`. |
109+
| `onCaughtError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when React catches an error in an Error Boundary. Called with the error caught by the Error Boundary and an errorInfo object containing the component stack. |
110+
| `onUncaughtError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when an error is thrown and not caught by an Error Boundary. Called with the error that was thrown and an errorInfo object containing the component stack. |
111+
| `onRecoverableError` | `(error: unknown, errorInfo: { componentStack?: string }) => void` | Callback called when React automatically recovers from errors. Called with an error React throws and an errorInfo object containing the component stack. Some recoverable errors may include the original error cause as `error.cause`. |
112112

113113
### `TestInstance` {#test-instance}
114114

bun.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
"release": "release-it"
5252
},
5353
"dependencies": {
54-
"@types/react-reconciler": "~0.31.0",
55-
"react-reconciler": "~0.31.0"
54+
"@types/react-reconciler": "~0.32.0",
55+
"react-reconciler": "~0.32.0"
5656
},
5757
"devDependencies": {
5858
"@eslint/js": "^10.0.1",

src/reconciler.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { DefaultEventPriority, NoEventPriority } from "react-reconciler/constant
55
import { Tag } from "./constants";
66
import { mark, measureEnd, measureStart } from "./performance";
77
import { TestInstance } from "./test-instance";
8+
import { REACT_CONTEXT_TYPE } from "./test-utils/react-constants";
89
import { formatComponentList } from "./utils";
910

1011
export type Type = string;
@@ -37,6 +38,8 @@ export type Instance = {
3738
unstable_fiber: Fiber;
3839
};
3940

41+
export type FormInstance = Instance;
42+
4043
export type TextInstance = {
4144
tag: typeof Tag.Text;
4245
text: string;
@@ -46,21 +49,20 @@ export type TextInstance = {
4649
};
4750

4851
export type SuspenseInstance = object;
52+
export type SuspendedState = unknown;
4953
export type HydratableInstance = object;
5054
export type PublicInstance = object | null;
51-
export type UpdatePayload = unknown;
5255
export type ChildSet = unknown;
5356
export type TimeoutHandle = unknown;
5457
export type NoTimeout = unknown;
58+
export type TransitionStatus = unknown;
5559

5660
type HostContext = {
5761
type: string;
5862
isInsideText: boolean;
5963
config: ReconcilerConfig;
6064
};
6165

62-
// Newer react-reconciler builds expect these event-related host config methods at runtime,
63-
// but the published @types/react-reconciler package may lag behind and omit them.
6466
type ExtendedHostConfig = ReactReconciler.HostConfig<
6567
Type,
6668
Props,
@@ -69,17 +71,14 @@ type ExtendedHostConfig = ReactReconciler.HostConfig<
6971
TextInstance,
7072
SuspenseInstance,
7173
HydratableInstance,
74+
FormInstance,
7275
PublicInstance,
7376
HostContext,
74-
UpdatePayload,
7577
ChildSet,
7678
TimeoutHandle,
77-
NoTimeout
78-
> & {
79-
trackSchedulerEvent?: () => void;
80-
resolveEventType?: () => null | string;
81-
resolveEventTimeStamp?: () => number;
82-
};
79+
NoTimeout,
80+
TransitionStatus
81+
>;
8382

8483
const nodeToInstanceMap = new WeakMap<object, Instance>();
8584

@@ -709,8 +708,6 @@ const hostConfig: ExtendedHostConfig = {
709708
* be aware that it may change significantly between versions. You're taking on additional maintenance risk by
710709
* reading from it, and giving up all guarantees if you write something to it.
711710
*/
712-
// @ts-expect-error @types/react-reconciler types don't fully match react-reconciler's actual Flow types.
713-
// Correctness is verified through tests.
714711
commitUpdate(
715712
instance: Instance,
716713
type: Type,
@@ -856,7 +853,7 @@ const hostConfig: ExtendedHostConfig = {
856853
},
857854

858855
/**
859-
* #### `waitForCommitToBeReady()`
856+
* #### `waitForCommitToBeReady(state, timeoutOffset)`
860857
*
861858
* This method is called after all `suspendInstance` calls are complete.
862859
*
@@ -865,8 +862,8 @@ const hostConfig: ExtendedHostConfig = {
865862
* callback will initiate the commit when called. The return value is a cancellation function that the
866863
* Reconciler can use to abort the commit.
867864
*/
868-
waitForCommitToBeReady(type: Type, _props: Props) {
869-
mark("reconciler/waitForCommitToBeReady", { type });
865+
waitForCommitToBeReady(_state?: SuspendedState, _timeoutOffset?: number) {
866+
mark("reconciler/waitForCommitToBeReady");
870867

871868
return null;
872869
},
@@ -884,6 +881,14 @@ const hostConfig: ExtendedHostConfig = {
884881
supportsHydration: false,
885882

886883
NotPendingTransition: null,
884+
HostTransitionContext: {
885+
$$typeof: REACT_CONTEXT_TYPE,
886+
Provider: null as unknown as ReactReconciler.ReactProviderType<TransitionStatus>,
887+
Consumer: null as unknown as ReactReconciler.ReactContext<TransitionStatus>,
888+
_currentValue: null,
889+
_currentValue2: null,
890+
_threadCount: 0,
891+
} as ReactReconciler.ReactContext<TransitionStatus>,
887892

888893
resetFormInstance(_form: Instance) {
889894
mark("reconciler/resetFormInstance");

src/renderer.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const defaultOnCaughtError = (error: unknown, errorInfo: ErrorInfo) => {
2121
const defaultOnRecoverableError = (error: unknown, errorInfo: ErrorInfo) => {
2222
console.error("Recoverable error:", error, errorInfo);
2323
};
24+
const defaultOnDefaultTransitionIndicator = () => {};
2425

2526
/**
2627
* Options for configuring the test renderer root.
@@ -63,7 +64,7 @@ export type ErrorHandler = (error: unknown, errorInfo: ErrorInfo) => void;
6364

6465
/** Error information provided to error handlers. */
6566
export type ErrorInfo = {
66-
componentStack: string;
67+
componentStack?: string;
6768
};
6869

6970
/**
@@ -112,10 +113,8 @@ export function createRoot(options?: RootOptions): Root {
112113
options?.identifierPrefix ?? "",
113114
options?.onUncaughtError ?? defaultOnUncaughtError,
114115
options?.onCaughtError ?? defaultOnCaughtError,
115-
// @ts-expect-error @types/react-reconciler types don't include onRecoverableError parameter
116-
// in the createContainer signature, but react-reconciler's actual Flow types do.
117-
// Correctness is verified through tests.
118116
options?.onRecoverableError ?? defaultOnRecoverableError,
117+
defaultOnDefaultTransitionIndicator,
119118
null, // transitionCallbacks
120119
);
121120

src/test-utils/react-constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ export const DiscreteEventPriority = 2;
1212
export const ContinuousEventPriority = 8;
1313
export const DefaultEventPriority = 32;
1414
export const IdleEventPriority = 0b0010000000000000000000000000000;
15+
16+
// Source: https://github.com/facebook/react/blob/v19.1.0/packages/shared/ReactSymbols.js
17+
export const REACT_CONTEXT_TYPE = Symbol.for("react.context");

0 commit comments

Comments
 (0)