75
isServerReference,
76
supportsRequestStorage,
77
requestStorage,
78
- supportsComponentStorage,
79
- componentStorage,
78
createHints,
79
initAsyncDebugInfo,
80
} from './ReactFlightServerConfig';
97
98
import {getOwnerStackByComponentInfoInDev} from './flight/ReactFlightComponentStack';
99
100
+import {
101
+ callComponentInDEV,
102
+ callLazyInitInDEV,
103
+ callIteratorInDEV,
104
+} from './ReactFlightCallUserSpace';
105
+
106
import {
107
getIteratorFn,
108
REACT_ELEMENT_TYPE,
133
// TODO: Make this configurable on the Request.
134
const externalRegExp = /\/node\_modules\/| \(node\:| node\:|\(\<anonymous\>\)/;
135
132
-let callComponentFrame: null | string = null;
133
-let callIteratorFrame: null | string = null;
134
-let callLazyInitFrame: null | string = null;
135
-
136
function isNotExternal(stackFrame: string): boolean {
137
return !externalRegExp.test(stackFrame);
138
}
168
}
169
}
170
171
-function initCallComponentFrame(): string {
172
- // Extract the stack frame of the callComponentInDEV function.
173
- const error = callComponentInDEV(Error, 'react-stack-top-frame', {}, null);
174
- const stack = getStack(error);
175
- const startIdx = stack.startsWith('Error: react-stack-top-frame\n') ? 29 : 0;
176
- const endIdx = stack.indexOf('\n', startIdx);
177
- if (endIdx === -1) {
178
- return stack.slice(startIdx);
179
- }
180
- return stack.slice(startIdx, endIdx);
181
-}
182
-
183
-function initCallIteratorFrame(): string {
184
- // Extract the stack frame of the callIteratorInDEV function.
185
- try {
186
- (callIteratorInDEV: any)({next: null});
187
- return '';
188
- } catch (error) {
189
- const stack = getStack(error);
190
- const startIdx = stack.startsWith('TypeError: ')
191
- ? stack.indexOf('\n') + 1
192
- : 0;
193
- const endIdx = stack.indexOf('\n', startIdx);
194
- if (endIdx === -1) {
195
- return stack.slice(startIdx);
196
- }
197
- return stack.slice(startIdx, endIdx);
198
- }
199
-}
200
-
201
-function initCallLazyInitFrame(): string {
202
- // Extract the stack frame of the callLazyInitInDEV function.
203
- const error = callLazyInitInDEV({
204
- $$typeof: REACT_LAZY_TYPE,
205
- _init: Error,
206
- _payload: 'react-stack-top-frame',
207
- });
208
- const stack = getStack(error);
209
- const startIdx = stack.startsWith('Error: react-stack-top-frame\n') ? 29 : 0;
210
- const endIdx = stack.indexOf('\n', startIdx);
211
- if (endIdx === -1) {
212
- return stack.slice(startIdx);
213
- }
214
- return stack.slice(startIdx, endIdx);
215
-}
216
-
171
function filterDebugStack(error: Error): string {
172
// Since stacks can be quite large and we pass a lot of them, we filter them out eagerly
173
// to save bandwidth even in DEV. We'll also replay these stacks on the client so by
179
// don't want/need.
180
stack = stack.slice(29);
181
}
228
- const frames = stack.split('\n').slice(1);
229
- if (callComponentFrame === null) {
230
- callComponentFrame = initCallComponentFrame();
231
- }
232
- let lastFrameIdx = frames.indexOf(callComponentFrame);
233
- if (lastFrameIdx === -1) {
234
- if (callLazyInitFrame === null) {
235
- callLazyInitFrame = initCallLazyInitFrame();
236
- }
237
- lastFrameIdx = frames.indexOf(callLazyInitFrame);
238
- if (lastFrameIdx === -1) {
239
- if (callIteratorFrame === null) {
240
- callIteratorFrame = initCallIteratorFrame();
241
- }
242
- lastFrameIdx = frames.indexOf(callIteratorFrame);
243
- }
182
+ let idx = stack.indexOf('react-stack-bottom-frame');
183
+ if (idx !== -1) {
184
+ idx = stack.lastIndexOf('\n', idx);
185
}
245
- if (lastFrameIdx !== -1) {
246
- // Cut off everything after our "callComponent" slot since it'll be Flight internals.
247
- frames.length = lastFrameIdx;
186
+ if (idx !== -1) {
187
+ // Cut off everything after the bottom frame since it'll be internals.
188
+ stack = stack.slice(0, idx);
189
}
190
+ const frames = stack.split('\n').slice(1);
191
return frames.filter(isNotExternal).join('\n');
192
}
193
758
return serializeByValueID(streamTask.id);
759
}
760
819
-// This indirect exists so we can exclude its stack frame in DEV (and anything below it).
820
-/** @noinline */
821
-function callIteratorInDEV(
822
- iterator: $AsyncIterator<ReactClientValue, ReactClientValue, void>,
823
- progress: (
824
- entry:
825
- | {done: false, +value: ReactClientValue, ...}
826
- | {done: true, +value: ReactClientValue, ...},
827
- ) => void,
828
- error: (reason: mixed) => void,
829
-) {
830
- iterator.next().then(progress, error);
831
-}
832
-
761
function serializeAsyncIterable(
762
request: Request,
763
task: Task,
957
return lazyType;
958
}
959
1032
-// This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1033
-/** @noinline */
1034
-function callComponentInDEV<Props, R>(
1035
- Component: (p: Props, arg: void) => R,
1036
- props: Props,
1037
- componentDebugInfo: ReactComponentInfo,
1038
- debugTask: null | ConsoleTask,
1039
-): R {
1040
- // The secondArg is always undefined in Server Components since refs error early.
1041
- const secondArg = undefined;
1042
- setCurrentOwner(componentDebugInfo);
1043
- try {
1044
- if (supportsComponentStorage) {
1045
- // Run the component in an Async Context that tracks the current owner.
1046
- if (enableOwnerStacks && debugTask) {
1047
- return debugTask.run(
1048
- // $FlowFixMe[method-unbinding]
1049
- componentStorage.run.bind(
1050
- componentStorage,
1051
- componentDebugInfo,
1052
- Component,
1053
- props,
1054
- secondArg,
1055
- ),
1056
- );
1057
- }
1058
- return componentStorage.run(
1059
- componentDebugInfo,
1060
- Component,
1061
- props,
1062
- secondArg,
1063
- );
1064
- } else {
1065
- if (enableOwnerStacks && debugTask) {
1066
- return debugTask.run(Component.bind(null, props, secondArg));
1067
- }
1068
- return Component(props, secondArg);
1069
- }
1070
- } finally {
1071
- setCurrentOwner(null);
1072
- }
1073
-}
1074
-
1075
-// This indirect exists so we can exclude its stack frame in DEV (and anything below it).
1076
-/** @noinline */
1077
-function callLazyInitInDEV(lazy: LazyComponent<any, any>): any {
1078
- const payload = lazy._payload;
1079
- const init = lazy._init;
1080
- return init(payload);
1081
-}
1082
-
960
function callWithDebugContextInDEV<A, T>(
961
task: Task,
962
callback: A => T,