main
js 85 lines 2.65 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @flow
8 */
9
10 import type {LazyComponent} from 'react/src/ReactLazy';
11
12 import type {ReactComponentInfo} from 'shared/ReactTypes';
13
14 import type {ReactClientValue} from './ReactFlightServer';
15
16 import {setCurrentOwner} from './flight/ReactFlightCurrentOwner';
17
18 // These indirections exists so we can exclude its stack frame in DEV (and anything below it).
19 // TODO: Consider marking the whole bundle instead of these boundaries.
20
21 const callComponent = {
22 react_stack_bottom_frame: function <Props, R>(
23 Component: (p: Props, arg: void) => R,
24 props: Props,
25 componentDebugInfo: ReactComponentInfo,
26 ): R {
27 // The secondArg is always undefined in Server Components since refs error early.
28 const secondArg = undefined;
29 setCurrentOwner(componentDebugInfo);
30 try {
31 return Component(props, secondArg);
32 } finally {
33 setCurrentOwner(null);
34 }
35 },
36 };
37
38 export const callComponentInDEV: <Props, R>(
39 Component: (p: Props, arg: void) => R,
40 props: Props,
41 componentDebugInfo: ReactComponentInfo,
42 ) => R = __DEV__
43 ? // We use this technique to trick minifiers to preserve the function name.
44 (callComponent.react_stack_bottom_frame.bind(callComponent) as any)
45 : (null as any);
46
47 const callLazyInit = {
48 react_stack_bottom_frame: function (lazy: LazyComponent<any, any>): any {
49 const payload = lazy._payload;
50 const init = lazy._init;
51 return init(payload);
52 },
53 };
54
55 export const callLazyInitInDEV: (lazy: LazyComponent<any, any>) => any = __DEV__
56 ? // We use this technique to trick minifiers to preserve the function name.
57 (callLazyInit.react_stack_bottom_frame.bind(callLazyInit) as any)
58 : (null as any);
59
60 const callIterator = {
61 react_stack_bottom_frame: function (
62 iterator: $AsyncIterator<ReactClientValue, ReactClientValue, void>,
63 progress: (
64 entry:
65 | {done: false, +value: ReactClientValue, ...}
66 | {done: true, +value: ReactClientValue, ...},
67 ) => void,
68 error: (reason: mixed) => void,
69 ): void {
70 iterator.next().then(progress, error);
71 },
72 };
73
74 export const callIteratorInDEV: (
75 iterator: $AsyncIterator<ReactClientValue, ReactClientValue, void>,
76 progress: (
77 entry:
78 | {done: false, +value: ReactClientValue, ...}
79 | {done: true, +value: ReactClientValue, ...},
80 ) => void,
81 error: (reason: mixed) => void,
82 ) => void = __DEV__
83 ? // We use this technique to trick minifiers to preserve the function name.
84 (callIterator.react_stack_bottom_frame.bind(callIterator) as any)
85 : (null as any);