@@ -254,6 +254,7 @@ export type Response = {
254
254
_rowLength : number , // remaining bytes in the row. 0 indicates that we're looking for a newline.
255
255
_buffer : Array < Uint8Array > , // chunks received so far as part of this row
256
256
_tempRefs : void | TemporaryReferenceSet , // the set temporary references can be resolved from
257
+ _debugRootTask ?: null | ConsoleTask , // DEV-only
257
258
} ;
258
259
259
260
function readChunk < T > (chunk: SomeChunk< T > ): T {
@@ -614,6 +615,7 @@ function getTaskName(type: mixed): string {
614
615
}
615
616
616
617
function createElement (
618
+ response : Response ,
617
619
type : mixed ,
618
620
key : mixed ,
619
621
props : mixed ,
@@ -697,9 +699,15 @@ function createElement(
697
699
const callStack = buildFakeCallStack ( stack , createTaskFn ) ;
698
700
// This owner should ideally have already been initialized to avoid getting
699
701
// user stack frames on the stack.
700
- const ownerTask = owner === null ? null : initializeFakeTask ( owner ) ;
702
+ const ownerTask =
703
+ owner === null ? null : initializeFakeTask ( response , owner ) ;
701
704
if ( ownerTask === null ) {
702
- task = callStack ( ) ;
705
+ const rootTask = response . _debugRootTask ;
706
+ if ( rootTask != null ) {
707
+ task = rootTask . run ( callStack ) ;
708
+ } else {
709
+ task = callStack ( ) ;
710
+ }
703
711
} else {
704
712
task = ownerTask . run ( callStack ) ;
705
713
}
@@ -1106,6 +1114,7 @@ function parseModelTuple(
1106
1114
// TODO: Consider having React just directly accept these arrays as elements.
1107
1115
// Or even change the ReactElement type to be an array.
1108
1116
return createElement (
1117
+ response ,
1109
1118
tuple [ 1 ] ,
1110
1119
tuple [ 2 ] ,
1111
1120
tuple [ 3 ] ,
@@ -1149,6 +1158,14 @@ export function createResponse(
1149
1158
_buffer : [ ] ,
1150
1159
_tempRefs : temporaryReferences ,
1151
1160
} ;
1161
+ if ( supportsCreateTask ) {
1162
+ // Any stacks that appear on the server need to be rooted somehow on the client
1163
+ // so we create a root Task for this response which will be the root owner for any
1164
+ // elements created by the server. We use the "use server" string to indicate that
1165
+ // this is where we enter the server from the client.
1166
+ // TODO: Make this string configurable.
1167
+ response. _debugRootTask = ( console : any ) . createTask ( '"use server"' ) ;
1168
+ }
1152
1169
// Don't inline this call because it causes closure to outline the call above.
1153
1170
response . _fromJSON = createFromJSONCallback ( response ) ;
1154
1171
return response ;
@@ -1730,6 +1747,7 @@ function buildFakeCallStack<T>(stack: string, innerCall: () => T): () => T {
1730
1747
}
1731
1748
1732
1749
function initializeFakeTask(
1750
+ response: Response,
1733
1751
debugInfo: ReactComponentInfo | ReactAsyncInfo,
1734
1752
): null | ConsoleTask {
1735
1753
if ( taskCache === null || typeof debugInfo . stack !== 'string' ) {
@@ -1745,7 +1763,7 @@ function initializeFakeTask(
1745
1763
const ownerTask =
1746
1764
componentInfo.owner == null
1747
1765
? null
1748
- : initializeFakeTask(componentInfo.owner);
1766
+ : initializeFakeTask(response, componentInfo.owner);
1749
1767
1750
1768
// eslint-disable-next-line react-internal/no-production-logging
1751
1769
const createTaskFn = (console: any).createTask.bind(
@@ -1755,7 +1773,12 @@ function initializeFakeTask(
1755
1773
const callStack = buildFakeCallStack(stack, createTaskFn);
1756
1774
1757
1775
if (ownerTask === null) {
1758
- return callStack ( ) ;
1776
+ const rootTask = response . _debugRootTask ;
1777
+ if ( rootTask != null ) {
1778
+ return rootTask . run ( callStack ) ;
1779
+ } else {
1780
+ return callStack ( ) ;
1781
+ }
1759
1782
} else {
1760
1783
return ownerTask . run ( callStack ) ;
1761
1784
}
@@ -1776,7 +1799,7 @@ function resolveDebugInfo(
1776
1799
// We eagerly initialize the fake task because this resolving happens outside any
1777
1800
// render phase so we're not inside a user space stack at this point. If we waited
1778
1801
// to initialize it when we need it, we might be inside user code.
1779
- initializeFakeTask(debugInfo);
1802
+ initializeFakeTask(response, debugInfo);
1780
1803
const chunk = getChunk(response, id);
1781
1804
const chunkDebugInfo: ReactDebugInfo =
1782
1805
chunk._debugInfo || (chunk._debugInfo = []);
@@ -1813,12 +1836,17 @@ function resolveConsoleEntry(
1813
1836
printToConsole.bind(null, methodName, args, env),
1814
1837
);
1815
1838
if (owner != null) {
1816
- const task = initializeFakeTask ( owner ) ;
1839
+ const task = initializeFakeTask ( response , owner ) ;
1817
1840
if ( task !== null ) {
1818
1841
task . run ( callStack ) ;
1819
1842
return ;
1820
1843
}
1821
1844
}
1845
+ const rootTask = response . _debugRootTask ;
1846
+ if ( rootTask != null ) {
1847
+ rootTask . run ( callStack ) ;
1848
+ return ;
1849
+ }
1822
1850
callStack();
1823
1851
}
1824
1852
0 commit comments