@samitouri / QOS-React-2 / commits / 5e8c1961c0

[Transition Tracing] onMarkerProgress (#24861)

This PR adds support for `onMarkerProgress` (`onTransitionProgress(transitionName: string, markerName: string, startTime: number, currentTime: number, pending: Array<{name: null | string}>)`) We call this callback when: * When **a child suspense boundary of the marker commits in a fallback state**. Only the suspense boundaries that are triggered and commit in a fallback state when the transition first occurs (and all subsequent suspense boundaries in the initial suspense boundary's subtree) are considered a part of the transition * **A child suspense boundary of the marker resolves** When we call `onMarkerProgress`, we call the function with a `pending` array. This array contains the names of the transition's suspense boundaries that are still in a fallback state

Luna Ruan committed Jul 12, 2022 at 14:59 UTC 5e8c1961c03269ca0ee741182f3c877e0766efb8
9 files changed +344 -48
packages/react-reconciler/src/ReactFiberBeginWork.new.js
+1
@@ -978,6 +978,7 @@ function updateTracingMarkerComponent(
978 const markerInstance: TracingMarkerInstance = {
979 transitions: new Set(currentTransitions),
980 pendingSuspenseBoundaries: new Map(),
981 + name: workInProgress.pendingProps.name,
982 };
983 workInProgress.stateNode = markerInstance;
984 }
packages/react-reconciler/src/ReactFiberBeginWork.old.js
+1
@@ -978,6 +978,7 @@ function updateTracingMarkerComponent(
978 const markerInstance: TracingMarkerInstance = {
979 transitions: new Set(currentTransitions),
980 pendingSuspenseBoundaries: new Map(),
981 + name: workInProgress.pendingProps.name,
982 };
983 workInProgress.stateNode = markerInstance;
984 }
packages/react-reconciler/src/ReactFiberCommitWork.new.js
+39 -21
@@ -145,6 +145,7 @@ import {
145 addTransitionStartCallbackToPendingTransition,
146 addTransitionProgressCallbackToPendingTransition,
147 addTransitionCompleteCallbackToPendingTransition,
148 + addMarkerProgressCallbackToPendingTransition,
149 addMarkerCompleteCallbackToPendingTransition,
150 setIsRunningInsertionEffect,
151 } from './ReactFiberWorkLoop.new';
@@ -1250,6 +1251,7 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1251 if (pendingMarkers !== null) {
1252 pendingMarkers.forEach(markerInstance => {
1253 const pendingBoundaries = markerInstance.pendingSuspenseBoundaries;
1254 + const transitions = markerInstance.transitions;
1255 if (
1256 pendingBoundaries !== null &&
1257 !pendingBoundaries.has(offscreenInstance)
@@ -1257,13 +1259,21 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1259 pendingBoundaries.set(offscreenInstance, {
1260 name,
1261 });
1260 - if (markerInstance.transitions !== null) {
1261 - markerInstance.transitions.forEach(transition => {
1262 - addTransitionProgressCallbackToPendingTransition(
1263 - transition,
1262 + if (transitions !== null) {
1263 + if (markerInstance.name) {
1264 + addMarkerProgressCallbackToPendingTransition(
1265 + markerInstance.name,
1266 + transitions,
1267 pendingBoundaries,
1268 );
1266 - });
1269 + } else {
1270 + transitions.forEach(transition => {
1271 + addTransitionProgressCallbackToPendingTransition(
1272 + transition,
1273 + pendingBoundaries,
1274 + );
1275 + });
1276 + }
1277 }
1278 }
1279 });
@@ -1275,18 +1285,27 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1285 if (pendingMarkers !== null) {
1286 pendingMarkers.forEach(markerInstance => {
1287 const pendingBoundaries = markerInstance.pendingSuspenseBoundaries;
1288 + const transitions = markerInstance.transitions;
1289 if (
1290 pendingBoundaries !== null &&
1291 pendingBoundaries.has(offscreenInstance)
1292 ) {
1293 pendingBoundaries.delete(offscreenInstance);
1283 - if (markerInstance.transitions !== null) {
1284 - markerInstance.transitions.forEach(transition => {
1285 - addTransitionProgressCallbackToPendingTransition(
1286 - transition,
1294 + if (transitions !== null) {
1295 + if (markerInstance.name) {
1296 + addMarkerProgressCallbackToPendingTransition(
1297 + markerInstance.name,
1298 + transitions,
1299 pendingBoundaries,
1300 );
1289 - });
1301 + } else {
1302 + transitions.forEach(transition => {
1303 + addTransitionProgressCallbackToPendingTransition(
1304 + transition,
1305 + pendingBoundaries,
1306 + );
1307 + });
1308 + }
1309 }
1310 }
1311 });
@@ -3083,19 +3102,18 @@ function commitPassiveMountOnFiber(
3102 // and add a start transition callback for each of them
3103 const instance = finishedWork.stateNode;
3104 if (
3086 - instance.pendingSuspenseBoundaries === null ||
3087 - instance.pendingSuspenseBoundaries.size === 0
3105 + instance.transitions !== null &&
3106 + (instance.pendingSuspenseBoundaries === null ||
3107 + instance.pendingSuspenseBoundaries.size === 0)
3108 ) {
3089 - if (instance.transitions !== null) {
3090 - instance.transitions.forEach(transition => {
3091 - addMarkerCompleteCallbackToPendingTransition({
3092 - transition,
3093 - name: finishedWork.memoizedProps.name,
3094 - });
3109 + instance.transitions.forEach(transition => {
3110 + addMarkerCompleteCallbackToPendingTransition({
3111 + transition,
3112 + name: finishedWork.memoizedProps.name,
3113 });
3096 - instance.transitions = null;
3097 - instance.pendingSuspenseBoundaries = null;
3098 - }
3114 + });
3115 + instance.transitions = null;
3116 + instance.pendingSuspenseBoundaries = null;
3117 }
3118 }
3119 break;
packages/react-reconciler/src/ReactFiberCommitWork.old.js
+39 -21
@@ -145,6 +145,7 @@ import {
145 addTransitionStartCallbackToPendingTransition,
146 addTransitionProgressCallbackToPendingTransition,
147 addTransitionCompleteCallbackToPendingTransition,
148 + addMarkerProgressCallbackToPendingTransition,
149 addMarkerCompleteCallbackToPendingTransition,
150 setIsRunningInsertionEffect,
151 } from './ReactFiberWorkLoop.old';
@@ -1250,6 +1251,7 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1251 if (pendingMarkers !== null) {
1252 pendingMarkers.forEach(markerInstance => {
1253 const pendingBoundaries = markerInstance.pendingSuspenseBoundaries;
1254 + const transitions = markerInstance.transitions;
1255 if (
1256 pendingBoundaries !== null &&
1257 !pendingBoundaries.has(offscreenInstance)
@@ -1257,13 +1259,21 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1259 pendingBoundaries.set(offscreenInstance, {
1260 name,
1261 });
1260 - if (markerInstance.transitions !== null) {
1261 - markerInstance.transitions.forEach(transition => {
1262 - addTransitionProgressCallbackToPendingTransition(
1263 - transition,
1262 + if (transitions !== null) {
1263 + if (markerInstance.name) {
1264 + addMarkerProgressCallbackToPendingTransition(
1265 + markerInstance.name,
1266 + transitions,
1267 pendingBoundaries,
1268 );
1266 - });
1269 + } else {
1270 + transitions.forEach(transition => {
1271 + addTransitionProgressCallbackToPendingTransition(
1272 + transition,
1273 + pendingBoundaries,
1274 + );
1275 + });
1276 + }
1277 }
1278 }
1279 });
@@ -1275,18 +1285,27 @@ function commitTransitionProgress(offscreenFiber: Fiber) {
1285 if (pendingMarkers !== null) {
1286 pendingMarkers.forEach(markerInstance => {
1287 const pendingBoundaries = markerInstance.pendingSuspenseBoundaries;
1288 + const transitions = markerInstance.transitions;
1289 if (
1290 pendingBoundaries !== null &&
1291 pendingBoundaries.has(offscreenInstance)
1292 ) {
1293 pendingBoundaries.delete(offscreenInstance);
1283 - if (markerInstance.transitions !== null) {
1284 - markerInstance.transitions.forEach(transition => {
1285 - addTransitionProgressCallbackToPendingTransition(
1286 - transition,
1294 + if (transitions !== null) {
1295 + if (markerInstance.name) {
1296 + addMarkerProgressCallbackToPendingTransition(
1297 + markerInstance.name,
1298 + transitions,
1299 pendingBoundaries,
1300 );
1289 - });
1301 + } else {
1302 + transitions.forEach(transition => {
1303 + addTransitionProgressCallbackToPendingTransition(
1304 + transition,
1305 + pendingBoundaries,
1306 + );
1307 + });
1308 + }
1309 }
1310 }
1311 });
@@ -3083,19 +3102,18 @@ function commitPassiveMountOnFiber(
3102 // and add a start transition callback for each of them
3103 const instance = finishedWork.stateNode;
3104 if (
3086 - instance.pendingSuspenseBoundaries === null ||
3087 - instance.pendingSuspenseBoundaries.size === 0
3105 + instance.transitions !== null &&
3106 + (instance.pendingSuspenseBoundaries === null ||
3107 + instance.pendingSuspenseBoundaries.size === 0)
3108 ) {
3089 - if (instance.transitions !== null) {
3090 - instance.transitions.forEach(transition => {
3091 - addMarkerCompleteCallbackToPendingTransition({
3092 - transition,
3093 - name: finishedWork.memoizedProps.name,
3094 - });
3109 + instance.transitions.forEach(transition => {
3110 + addMarkerCompleteCallbackToPendingTransition({
3111 + transition,
3112 + name: finishedWork.memoizedProps.name,
3113 });
3096 - instance.transitions = null;
3097 - instance.pendingSuspenseBoundaries = null;
3098 - }
3114 + });
3115 + instance.transitions = null;
3116 + instance.pendingSuspenseBoundaries = null;
3117 }
3118 }
3119 break;
packages/react-reconciler/src/ReactFiberTracingMarkerComponent.new.js
+24
@@ -26,6 +26,7 @@ export type PendingTransitionCallbacks = {
26 transitionStart: Array<Transition> | null,
27 transitionProgress: Map<Transition, PendingSuspenseBoundaries> | null,
28 transitionComplete: Array<Transition> | null,
29 + markerProgress: Map<string, TracingMarkerInstance> | null,
30 markerComplete: Array<MarkerTransition> | null,
31 };
32
@@ -43,6 +44,7 @@ export type BatchConfigTransition = {
44 export type TracingMarkerInstance = {|
45 pendingSuspenseBoundaries: PendingSuspenseBoundaries | null,
46 transitions: Set<Transition> | null,
47 + name?: string,
48 |};
49
50 export type PendingSuspenseBoundaries = Map<OffscreenInstance, SuspenseInfo>;
@@ -63,6 +65,28 @@ export function processTransitionCallbacks(
65 });
66 }
67
68 + const markerProgress = pendingTransitions.markerProgress;
69 + const onMarkerProgress = callbacks.onMarkerProgress;
70 + if (onMarkerProgress != null && markerProgress !== null) {
71 + markerProgress.forEach((markerInstance, markerName) => {
72 + if (markerInstance.transitions !== null) {
73 + const pending =
74 + markerInstance.pendingSuspenseBoundaries !== null
75 + ? Array.from(markerInstance.pendingSuspenseBoundaries.values())
76 + : [];
77 + markerInstance.transitions.forEach(transition => {
78 + onMarkerProgress(
79 + transition.name,
80 + markerName,
81 + transition.startTime,
82 + endTime,
83 + pending,
84 + );
85 + });
86 + }
87 + });
88 + }
89 +
90 const markerComplete = pendingTransitions.markerComplete;
91 if (markerComplete !== null) {
92 markerComplete.forEach(marker => {
packages/react-reconciler/src/ReactFiberTracingMarkerComponent.old.js
+24
@@ -26,6 +26,7 @@ export type PendingTransitionCallbacks = {
26 transitionStart: Array<Transition> | null,
27 transitionProgress: Map<Transition, PendingSuspenseBoundaries> | null,
28 transitionComplete: Array<Transition> | null,
29 + markerProgress: Map<string, TracingMarkerInstance> | null,
30 markerComplete: Array<MarkerTransition> | null,
31 };
32
@@ -43,6 +44,7 @@ export type BatchConfigTransition = {
44 export type TracingMarkerInstance = {|
45 pendingSuspenseBoundaries: PendingSuspenseBoundaries | null,
46 transitions: Set<Transition> | null,
47 + name?: string,
48 |};
49
50 export type PendingSuspenseBoundaries = Map<OffscreenInstance, SuspenseInfo>;
@@ -63,6 +65,28 @@ export function processTransitionCallbacks(
65 });
66 }
67
68 + const markerProgress = pendingTransitions.markerProgress;
69 + const onMarkerProgress = callbacks.onMarkerProgress;
70 + if (onMarkerProgress != null && markerProgress !== null) {
71 + markerProgress.forEach((markerInstance, markerName) => {
72 + if (markerInstance.transitions !== null) {
73 + const pending =
74 + markerInstance.pendingSuspenseBoundaries !== null
75 + ? Array.from(markerInstance.pendingSuspenseBoundaries.values())
76 + : [];
77 + markerInstance.transitions.forEach(transition => {
78 + onMarkerProgress(
79 + transition.name,
80 + markerName,
81 + transition.startTime,
82 + endTime,
83 + pending,
84 + );
85 + });
86 + }
87 + });
88 + }
89 +
90 const markerComplete = pendingTransitions.markerComplete;
91 if (markerComplete !== null) {
92 markerComplete.forEach(marker => {
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+31
@@ -342,6 +342,7 @@ export function addTransitionStartCallbackToPendingTransition(
342 transitionStart: [],
343 transitionProgress: null,
344 transitionComplete: null,
345 + markerProgress: null,
346 markerComplete: null,
347 };
348 }
@@ -354,6 +355,33 @@ export function addTransitionStartCallbackToPendingTransition(
355 }
356 }
357
358 +export function addMarkerProgressCallbackToPendingTransition(
359 + markerName: string,
360 + transitions: Set<Transition>,
361 + pendingSuspenseBoundaries: PendingSuspenseBoundaries | null,
362 +) {
363 + if (enableTransitionTracing) {
364 + if (currentPendingTransitionCallbacks === null) {
365 + currentPendingTransitionCallbacks = {
366 + transitionStart: null,
367 + transitionProgress: null,
368 + transitionComplete: null,
369 + markerProgress: new Map(),
370 + markerComplete: null,
371 + };
372 + }
373 +
374 + if (currentPendingTransitionCallbacks.markerProgress === null) {
375 + currentPendingTransitionCallbacks.markerProgress = new Map();
376 + }
377 +
378 + currentPendingTransitionCallbacks.markerProgress.set(markerName, {
379 + pendingSuspenseBoundaries,
380 + transitions,
381 + });
382 + }
383 +}
384 +
385 export function addMarkerCompleteCallbackToPendingTransition(
386 transition: MarkerTransition,
387 ) {
@@ -363,6 +391,7 @@ export function addMarkerCompleteCallbackToPendingTransition(
391 transitionStart: null,
392 transitionProgress: null,
393 transitionComplete: null,
394 + markerProgress: null,
395 markerComplete: [],
396 };
397 }
@@ -385,6 +414,7 @@ export function addTransitionProgressCallbackToPendingTransition(
414 transitionStart: null,
415 transitionProgress: new Map(),
416 transitionComplete: null,
417 + markerProgress: null,
418 markerComplete: null,
419 };
420 }
@@ -409,6 +439,7 @@ export function addTransitionCompleteCallbackToPendingTransition(
439 transitionStart: null,
440 transitionProgress: null,
441 transitionComplete: [],
442 + markerProgress: null,
443 markerComplete: null,
444 };
445 }
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+31
@@ -342,6 +342,7 @@ export function addTransitionStartCallbackToPendingTransition(
342 transitionStart: [],
343 transitionProgress: null,
344 transitionComplete: null,
345 + markerProgress: null,
346 markerComplete: null,
347 };
348 }
@@ -354,6 +355,33 @@ export function addTransitionStartCallbackToPendingTransition(
355 }
356 }
357
358 +export function addMarkerProgressCallbackToPendingTransition(
359 + markerName: string,
360 + transitions: Set<Transition>,
361 + pendingSuspenseBoundaries: PendingSuspenseBoundaries | null,
362 +) {
363 + if (enableTransitionTracing) {
364 + if (currentPendingTransitionCallbacks === null) {
365 + currentPendingTransitionCallbacks = {
366 + transitionStart: null,
367 + transitionProgress: null,
368 + transitionComplete: null,
369 + markerProgress: new Map(),
370 + markerComplete: null,
371 + };
372 + }
373 +
374 + if (currentPendingTransitionCallbacks.markerProgress === null) {
375 + currentPendingTransitionCallbacks.markerProgress = new Map();
376 + }
377 +
378 + currentPendingTransitionCallbacks.markerProgress.set(markerName, {
379 + pendingSuspenseBoundaries,
380 + transitions,
381 + });
382 + }
383 +}
384 +
385 export function addMarkerCompleteCallbackToPendingTransition(
386 transition: MarkerTransition,
387 ) {
@@ -363,6 +391,7 @@ export function addMarkerCompleteCallbackToPendingTransition(
391 transitionStart: null,
392 transitionProgress: null,
393 transitionComplete: null,
394 + markerProgress: null,
395 markerComplete: [],
396 };
397 }
@@ -385,6 +414,7 @@ export function addTransitionProgressCallbackToPendingTransition(
414 transitionStart: null,
415 transitionProgress: new Map(),
416 transitionComplete: null,
417 + markerProgress: null,
418 markerComplete: null,
419 };
420 }
@@ -409,6 +439,7 @@ export function addTransitionCompleteCallbackToPendingTransition(
439 transitionStart: null,
440 transitionProgress: null,
441 transitionComplete: [],
442 + markerProgress: null,
443 markerComplete: null,
444 };
445 }
packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js
+154 -6
@@ -941,18 +941,114 @@ describe('ReactInteractionTracing', () => {
941 });
942
943 // @gate enableTransitionTracing
944 - it('should correctly trace interactions for tracing markers complete', async () => {
944 + it('should correctly trace basic interaction with tracing markers', async () => {
945 const transitionCallbacks = {
946 onTransitionStart: (name, startTime) => {
947 Scheduler.unstable_yieldValue(
948 `onTransitionStart(${name}, ${startTime})`,
949 );
950 },
951 + onTransitionProgress: (name, startTime, endTime, pending) => {
952 + const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
953 + Scheduler.unstable_yieldValue(
954 + `onTransitionProgress(${name}, ${startTime}, ${endTime}, [${suspenseNames}])`,
955 + );
956 + },
957 onTransitionComplete: (name, startTime, endTime) => {
958 Scheduler.unstable_yieldValue(
959 `onTransitionComplete(${name}, ${startTime}, ${endTime})`,
960 );
961 },
962 + onMarkerProgress: (
963 + transitioName,
964 + markerName,
965 + startTime,
966 + currentTime,
967 + pending,
968 + ) => {
969 + const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
970 + Scheduler.unstable_yieldValue(
971 + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`,
972 + );
973 + },
974 + onMarkerComplete: (transitioName, markerName, startTime, endTime) => {
975 + Scheduler.unstable_yieldValue(
976 + `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`,
977 + );
978 + },
979 + };
980 +
981 + let navigateToPageTwo;
982 + function App() {
983 + const [navigate, setNavigate] = useState(false);
984 + navigateToPageTwo = () => {
985 + setNavigate(true);
986 + };
987 +
988 + return (
989 + <div>
990 + {navigate ? (
991 + <React.unstable_TracingMarker name="marker two" key="marker two">
992 + <Text text="Page Two" />
993 + </React.unstable_TracingMarker>
994 + ) : (
995 + <React.unstable_TracingMarker name="marker one">
996 + <Text text="Page One" />
997 + </React.unstable_TracingMarker>
998 + )}
999 + </div>
1000 + );
1001 + }
1002 +
1003 + const root = ReactNoop.createRoot({transitionCallbacks});
1004 + await act(async () => {
1005 + root.render(<App />);
1006 + ReactNoop.expire(1000);
1007 + await advanceTimers(1000);
1008 +
1009 + expect(Scheduler).toFlushAndYield(['Page One']);
1010 +
1011 + await act(async () => {
1012 + startTransition(() => navigateToPageTwo(), {name: 'page transition'});
1013 +
1014 + ReactNoop.expire(1000);
1015 + await advanceTimers(1000);
1016 +
1017 + expect(Scheduler).toFlushAndYield([
1018 + 'Page Two',
1019 + 'onTransitionStart(page transition, 1000)',
1020 + 'onMarkerComplete(page transition, marker two, 1000, 2000)',
1021 + 'onTransitionComplete(page transition, 1000, 2000)',
1022 + ]);
1023 + });
1024 + });
1025 + });
1026 +
1027 + // @gate enableTransitionTracing
1028 + it('should correctly trace interactions for tracing markers', async () => {
1029 + const transitionCallbacks = {
1030 + onTransitionStart: (name, startTime) => {
1031 + Scheduler.unstable_yieldValue(
1032 + `onTransitionStart(${name}, ${startTime})`,
1033 + );
1034 + },
1035 + onTransitionComplete: (name, startTime, endTime) => {
1036 + Scheduler.unstable_yieldValue(
1037 + `onTransitionComplete(${name}, ${startTime}, ${endTime})`,
1038 + );
1039 + },
1040 + onMarkerProgress: (
1041 + transitioName,
1042 + markerName,
1043 + startTime,
1044 + currentTime,
1045 + pending,
1046 + ) => {
1047 + const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
1048 + Scheduler.unstable_yieldValue(
1049 + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`,
1050 + );
1051 + },
1052 onMarkerComplete: (transitioName, markerName, startTime, endTime) => {
1053 Scheduler.unstable_yieldValue(
1054 `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`,
@@ -971,13 +1067,13 @@ describe('ReactInteractionTracing', () => {
1067 {navigate ? (
1068 <Suspense
1069 fallback={<Text text="Loading..." />}
974 - name="suspense page">
1070 + unstable_name="suspense page">
1071 <AsyncText text="Page Two" />
1072 <React.unstable_TracingMarker name="sync marker" />
1073 <React.unstable_TracingMarker name="async marker">
1074 <Suspense
1075 fallback={<Text text="Loading..." />}
980 - name="marker suspense">
1076 + unstable_name="marker suspense">
1077 <AsyncText text="Marker Text" />
1078 </Suspense>
1079 </React.unstable_TracingMarker>
@@ -1020,6 +1116,7 @@ describe('ReactInteractionTracing', () => {
1116 'Page Two',
1117 'Suspend [Marker Text]',
1118 'Loading...',
1119 + 'onMarkerProgress(page transition, async marker, 1000, 3000, [marker suspense])',
1120 'onMarkerComplete(page transition, sync marker, 1000, 3000)',
1121 ]);
1122
@@ -1029,6 +1126,7 @@ describe('ReactInteractionTracing', () => {
1126
1127 expect(Scheduler).toFlushAndYield([
1128 'Marker Text',
1129 + 'onMarkerProgress(page transition, async marker, 1000, 4000, [])',
1130 'onMarkerComplete(page transition, async marker, 1000, 4000)',
1131 'onTransitionComplete(page transition, 1000, 4000)',
1132 ]);
@@ -1048,6 +1146,18 @@ describe('ReactInteractionTracing', () => {
1146 `onTransitionComplete(${name}, ${startTime}, ${endTime})`,
1147 );
1148 },
1149 + onMarkerProgress: (
1150 + transitioName,
1151 + markerName,
1152 + startTime,
1153 + currentTime,
1154 + pending,
1155 + ) => {
1156 + const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
1157 + Scheduler.unstable_yieldValue(
1158 + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`,
1159 + );
1160 + },
1161 onMarkerComplete: (transitioName, markerName, startTime, endTime) => {
1162 Scheduler.unstable_yieldValue(
1163 `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`,
@@ -1066,14 +1176,20 @@ describe('ReactInteractionTracing', () => {
1176 <div>
1177 {navigate ? (
1178 <React.unstable_TracingMarker name="outer marker">
1069 - <Suspense fallback={<Text text="Outer..." />}>
1179 + <Suspense
1180 + fallback={<Text text="Outer..." />}
1181 + unstable_name="outer">
1182 <AsyncText text="Outer Text" />
1071 - <Suspense fallback={<Text text="Inner One..." />}>
1183 + <Suspense
1184 + fallback={<Text text="Inner One..." />}
1185 + unstable_name="inner one">
1186 <React.unstable_TracingMarker name="marker one">
1187 <AsyncText text="Inner Text One" />
1188 </React.unstable_TracingMarker>
1189 </Suspense>
1076 - <Suspense fallback={<Text text="Inner Two..." />}>
1190 + <Suspense
1191 + fallback={<Text text="Inner Two..." />}
1192 + unstable_name="inner two">
1193 <React.unstable_TracingMarker name="marker two">
1194 <AsyncText text="Inner Text Two" />
1195 </React.unstable_TracingMarker>
@@ -1110,6 +1226,7 @@ describe('ReactInteractionTracing', () => {
1226 'Inner Two...',
1227 'Outer...',
1228 'onTransitionStart(page transition, 1000)',
1229 + 'onMarkerProgress(page transition, outer marker, 1000, 2000, [outer])',
1230 ]);
1231
1232 ReactNoop.expire(1000);
@@ -1125,6 +1242,7 @@ describe('ReactInteractionTracing', () => {
1242 'Suspend [Inner Text One]',
1243 'Inner One...',
1244 'Inner Text Two',
1245 + 'onMarkerProgress(page transition, outer marker, 1000, 4000, [inner one])',
1246 'onMarkerComplete(page transition, marker two, 1000, 4000)',
1247 ]);
1248
@@ -1133,6 +1251,7 @@ describe('ReactInteractionTracing', () => {
1251 await resolveText('Inner Text One');
1252 expect(Scheduler).toFlushAndYield([
1253 'Inner Text One',
1254 + 'onMarkerProgress(page transition, outer marker, 1000, 5000, [])',
1255 'onMarkerComplete(page transition, marker one, 1000, 5000)',
1256 'onMarkerComplete(page transition, outer marker, 1000, 5000)',
1257 'onTransitionComplete(page transition, 1000, 5000)',
@@ -1233,6 +1352,18 @@ describe('ReactInteractionTracing', () => {
1352 `onTransitionComplete(${name}, ${startTime}, ${endTime})`,
1353 );
1354 },
1355 + onMarkerProgress: (
1356 + transitioName,
1357 + markerName,
1358 + startTime,
1359 + currentTime,
1360 + pending,
1361 + ) => {
1362 + const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
1363 + Scheduler.unstable_yieldValue(
1364 + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`,
1365 + );
1366 + },
1367 onMarkerComplete: (transitioName, markerName, startTime, endTime) => {
1368 Scheduler.unstable_yieldValue(
1369 `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`,
@@ -1279,6 +1410,7 @@ describe('ReactInteractionTracing', () => {
1410 'Suspend [Page Two]',
1411 'Loading...',
1412 'onTransitionStart(page transition, 1000)',
1413 + 'onMarkerProgress(page transition, old marker, 1000, 1000, [<null>])',
1414 ]);
1415
1416 ReactNoop.expire(1000);
@@ -1311,6 +1443,18 @@ describe('ReactInteractionTracing', () => {
1443 `onTransitionComplete(${name}, ${startTime}, ${endTime})`,
1444 );
1445 },
1446 + onMarkerProgress: (
1447 + transitioName,
1448 + markerName,
1449 + startTime,
1450 + currentTime,
1451 + pending,
1452 + ) => {
1453 + const suspenseNames = pending.map(p => p.name || '<null>').join(', ');
1454 + Scheduler.unstable_yieldValue(
1455 + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`,
1456 + );
1457 + },
1458 onMarkerComplete: (transitioName, markerName, startTime, endTime) => {
1459 Scheduler.unstable_yieldValue(
1460 `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`,
@@ -1357,6 +1501,7 @@ describe('ReactInteractionTracing', () => {
1501 'Suspend [Page Two]',
1502 'Loading...',
1503 'onTransitionStart(page transition, 1000)',
1504 + 'onMarkerProgress(page transition, old marker, 1000, 2000, [<null>])',
1505 ]);
1506
1507 ReactNoop.expire(1000);
@@ -1367,6 +1512,9 @@ describe('ReactInteractionTracing', () => {
1512 'Suspend [Page Two]',
1513 'Loading...',
1514 'onTransitionStart(marker transition, 2000)',
1515 + 'onMarkerProgress(marker transition, new marker, 2000, 3000, [])',
1516 + 'onMarkerComplete(marker transition, new marker, 2000, 3000)',
1517 + 'onTransitionComplete(marker transition, 2000, 3000)',
1518 ]);
1519 ReactNoop.expire(1000);
1520 await advanceTimers(1000);