diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index ab0705fa7a..a13b9f7a81 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.new.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.new.js @@ -978,6 +978,7 @@ function updateTracingMarkerComponent( const markerInstance: TracingMarkerInstance = { transitions: new Set(currentTransitions), pendingSuspenseBoundaries: new Map(), + name: workInProgress.pendingProps.name, }; workInProgress.stateNode = markerInstance; } diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.old.js b/packages/react-reconciler/src/ReactFiberBeginWork.old.js index 48a932df78..b7b32a43ad 100644 --- a/packages/react-reconciler/src/ReactFiberBeginWork.old.js +++ b/packages/react-reconciler/src/ReactFiberBeginWork.old.js @@ -978,6 +978,7 @@ function updateTracingMarkerComponent( const markerInstance: TracingMarkerInstance = { transitions: new Set(currentTransitions), pendingSuspenseBoundaries: new Map(), + name: workInProgress.pendingProps.name, }; workInProgress.stateNode = markerInstance; } diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.new.js b/packages/react-reconciler/src/ReactFiberCommitWork.new.js index 2900de2d65..c17a5b1ba6 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.new.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.new.js @@ -145,6 +145,7 @@ import { addTransitionStartCallbackToPendingTransition, addTransitionProgressCallbackToPendingTransition, addTransitionCompleteCallbackToPendingTransition, + addMarkerProgressCallbackToPendingTransition, addMarkerCompleteCallbackToPendingTransition, setIsRunningInsertionEffect, } from './ReactFiberWorkLoop.new'; @@ -1250,6 +1251,7 @@ function commitTransitionProgress(offscreenFiber: Fiber) { if (pendingMarkers !== null) { pendingMarkers.forEach(markerInstance => { const pendingBoundaries = markerInstance.pendingSuspenseBoundaries; + const transitions = markerInstance.transitions; if ( pendingBoundaries !== null && !pendingBoundaries.has(offscreenInstance) @@ -1257,13 +1259,21 @@ function commitTransitionProgress(offscreenFiber: Fiber) { pendingBoundaries.set(offscreenInstance, { name, }); - if (markerInstance.transitions !== null) { - markerInstance.transitions.forEach(transition => { - addTransitionProgressCallbackToPendingTransition( - transition, + if (transitions !== null) { + if (markerInstance.name) { + addMarkerProgressCallbackToPendingTransition( + markerInstance.name, + transitions, pendingBoundaries, ); - }); + } else { + transitions.forEach(transition => { + addTransitionProgressCallbackToPendingTransition( + transition, + pendingBoundaries, + ); + }); + } } } }); @@ -1275,18 +1285,27 @@ function commitTransitionProgress(offscreenFiber: Fiber) { if (pendingMarkers !== null) { pendingMarkers.forEach(markerInstance => { const pendingBoundaries = markerInstance.pendingSuspenseBoundaries; + const transitions = markerInstance.transitions; if ( pendingBoundaries !== null && pendingBoundaries.has(offscreenInstance) ) { pendingBoundaries.delete(offscreenInstance); - if (markerInstance.transitions !== null) { - markerInstance.transitions.forEach(transition => { - addTransitionProgressCallbackToPendingTransition( - transition, + if (transitions !== null) { + if (markerInstance.name) { + addMarkerProgressCallbackToPendingTransition( + markerInstance.name, + transitions, pendingBoundaries, ); - }); + } else { + transitions.forEach(transition => { + addTransitionProgressCallbackToPendingTransition( + transition, + pendingBoundaries, + ); + }); + } } } }); @@ -3083,19 +3102,18 @@ function commitPassiveMountOnFiber( // and add a start transition callback for each of them const instance = finishedWork.stateNode; if ( - instance.pendingSuspenseBoundaries === null || - instance.pendingSuspenseBoundaries.size === 0 + instance.transitions !== null && + (instance.pendingSuspenseBoundaries === null || + instance.pendingSuspenseBoundaries.size === 0) ) { - if (instance.transitions !== null) { - instance.transitions.forEach(transition => { - addMarkerCompleteCallbackToPendingTransition({ - transition, - name: finishedWork.memoizedProps.name, - }); + instance.transitions.forEach(transition => { + addMarkerCompleteCallbackToPendingTransition({ + transition, + name: finishedWork.memoizedProps.name, }); - instance.transitions = null; - instance.pendingSuspenseBoundaries = null; - } + }); + instance.transitions = null; + instance.pendingSuspenseBoundaries = null; } } break; diff --git a/packages/react-reconciler/src/ReactFiberCommitWork.old.js b/packages/react-reconciler/src/ReactFiberCommitWork.old.js index 9c7235b56a..d2efc3edf2 100644 --- a/packages/react-reconciler/src/ReactFiberCommitWork.old.js +++ b/packages/react-reconciler/src/ReactFiberCommitWork.old.js @@ -145,6 +145,7 @@ import { addTransitionStartCallbackToPendingTransition, addTransitionProgressCallbackToPendingTransition, addTransitionCompleteCallbackToPendingTransition, + addMarkerProgressCallbackToPendingTransition, addMarkerCompleteCallbackToPendingTransition, setIsRunningInsertionEffect, } from './ReactFiberWorkLoop.old'; @@ -1250,6 +1251,7 @@ function commitTransitionProgress(offscreenFiber: Fiber) { if (pendingMarkers !== null) { pendingMarkers.forEach(markerInstance => { const pendingBoundaries = markerInstance.pendingSuspenseBoundaries; + const transitions = markerInstance.transitions; if ( pendingBoundaries !== null && !pendingBoundaries.has(offscreenInstance) @@ -1257,13 +1259,21 @@ function commitTransitionProgress(offscreenFiber: Fiber) { pendingBoundaries.set(offscreenInstance, { name, }); - if (markerInstance.transitions !== null) { - markerInstance.transitions.forEach(transition => { - addTransitionProgressCallbackToPendingTransition( - transition, + if (transitions !== null) { + if (markerInstance.name) { + addMarkerProgressCallbackToPendingTransition( + markerInstance.name, + transitions, pendingBoundaries, ); - }); + } else { + transitions.forEach(transition => { + addTransitionProgressCallbackToPendingTransition( + transition, + pendingBoundaries, + ); + }); + } } } }); @@ -1275,18 +1285,27 @@ function commitTransitionProgress(offscreenFiber: Fiber) { if (pendingMarkers !== null) { pendingMarkers.forEach(markerInstance => { const pendingBoundaries = markerInstance.pendingSuspenseBoundaries; + const transitions = markerInstance.transitions; if ( pendingBoundaries !== null && pendingBoundaries.has(offscreenInstance) ) { pendingBoundaries.delete(offscreenInstance); - if (markerInstance.transitions !== null) { - markerInstance.transitions.forEach(transition => { - addTransitionProgressCallbackToPendingTransition( - transition, + if (transitions !== null) { + if (markerInstance.name) { + addMarkerProgressCallbackToPendingTransition( + markerInstance.name, + transitions, pendingBoundaries, ); - }); + } else { + transitions.forEach(transition => { + addTransitionProgressCallbackToPendingTransition( + transition, + pendingBoundaries, + ); + }); + } } } }); @@ -3083,19 +3102,18 @@ function commitPassiveMountOnFiber( // and add a start transition callback for each of them const instance = finishedWork.stateNode; if ( - instance.pendingSuspenseBoundaries === null || - instance.pendingSuspenseBoundaries.size === 0 + instance.transitions !== null && + (instance.pendingSuspenseBoundaries === null || + instance.pendingSuspenseBoundaries.size === 0) ) { - if (instance.transitions !== null) { - instance.transitions.forEach(transition => { - addMarkerCompleteCallbackToPendingTransition({ - transition, - name: finishedWork.memoizedProps.name, - }); + instance.transitions.forEach(transition => { + addMarkerCompleteCallbackToPendingTransition({ + transition, + name: finishedWork.memoizedProps.name, }); - instance.transitions = null; - instance.pendingSuspenseBoundaries = null; - } + }); + instance.transitions = null; + instance.pendingSuspenseBoundaries = null; } } break; diff --git a/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.new.js b/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.new.js index 8e1a60d38c..ceae6dec33 100644 --- a/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.new.js +++ b/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.new.js @@ -26,6 +26,7 @@ export type PendingTransitionCallbacks = { transitionStart: Array | null, transitionProgress: Map | null, transitionComplete: Array | null, + markerProgress: Map | null, markerComplete: Array | null, }; @@ -43,6 +44,7 @@ export type BatchConfigTransition = { export type TracingMarkerInstance = {| pendingSuspenseBoundaries: PendingSuspenseBoundaries | null, transitions: Set | null, + name?: string, |}; export type PendingSuspenseBoundaries = Map; @@ -63,6 +65,28 @@ export function processTransitionCallbacks( }); } + const markerProgress = pendingTransitions.markerProgress; + const onMarkerProgress = callbacks.onMarkerProgress; + if (onMarkerProgress != null && markerProgress !== null) { + markerProgress.forEach((markerInstance, markerName) => { + if (markerInstance.transitions !== null) { + const pending = + markerInstance.pendingSuspenseBoundaries !== null + ? Array.from(markerInstance.pendingSuspenseBoundaries.values()) + : []; + markerInstance.transitions.forEach(transition => { + onMarkerProgress( + transition.name, + markerName, + transition.startTime, + endTime, + pending, + ); + }); + } + }); + } + const markerComplete = pendingTransitions.markerComplete; if (markerComplete !== null) { markerComplete.forEach(marker => { diff --git a/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.old.js b/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.old.js index 0a5693823e..bf9268445a 100644 --- a/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.old.js +++ b/packages/react-reconciler/src/ReactFiberTracingMarkerComponent.old.js @@ -26,6 +26,7 @@ export type PendingTransitionCallbacks = { transitionStart: Array | null, transitionProgress: Map | null, transitionComplete: Array | null, + markerProgress: Map | null, markerComplete: Array | null, }; @@ -43,6 +44,7 @@ export type BatchConfigTransition = { export type TracingMarkerInstance = {| pendingSuspenseBoundaries: PendingSuspenseBoundaries | null, transitions: Set | null, + name?: string, |}; export type PendingSuspenseBoundaries = Map; @@ -63,6 +65,28 @@ export function processTransitionCallbacks( }); } + const markerProgress = pendingTransitions.markerProgress; + const onMarkerProgress = callbacks.onMarkerProgress; + if (onMarkerProgress != null && markerProgress !== null) { + markerProgress.forEach((markerInstance, markerName) => { + if (markerInstance.transitions !== null) { + const pending = + markerInstance.pendingSuspenseBoundaries !== null + ? Array.from(markerInstance.pendingSuspenseBoundaries.values()) + : []; + markerInstance.transitions.forEach(transition => { + onMarkerProgress( + transition.name, + markerName, + transition.startTime, + endTime, + pending, + ); + }); + } + }); + } + const markerComplete = pendingTransitions.markerComplete; if (markerComplete !== null) { markerComplete.forEach(marker => { diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 67e84f263c..92ffbd4e72 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -342,6 +342,7 @@ export function addTransitionStartCallbackToPendingTransition( transitionStart: [], transitionProgress: null, transitionComplete: null, + markerProgress: null, markerComplete: null, }; } @@ -354,6 +355,33 @@ export function addTransitionStartCallbackToPendingTransition( } } +export function addMarkerProgressCallbackToPendingTransition( + markerName: string, + transitions: Set, + pendingSuspenseBoundaries: PendingSuspenseBoundaries | null, +) { + if (enableTransitionTracing) { + if (currentPendingTransitionCallbacks === null) { + currentPendingTransitionCallbacks = { + transitionStart: null, + transitionProgress: null, + transitionComplete: null, + markerProgress: new Map(), + markerComplete: null, + }; + } + + if (currentPendingTransitionCallbacks.markerProgress === null) { + currentPendingTransitionCallbacks.markerProgress = new Map(); + } + + currentPendingTransitionCallbacks.markerProgress.set(markerName, { + pendingSuspenseBoundaries, + transitions, + }); + } +} + export function addMarkerCompleteCallbackToPendingTransition( transition: MarkerTransition, ) { @@ -363,6 +391,7 @@ export function addMarkerCompleteCallbackToPendingTransition( transitionStart: null, transitionProgress: null, transitionComplete: null, + markerProgress: null, markerComplete: [], }; } @@ -385,6 +414,7 @@ export function addTransitionProgressCallbackToPendingTransition( transitionStart: null, transitionProgress: new Map(), transitionComplete: null, + markerProgress: null, markerComplete: null, }; } @@ -409,6 +439,7 @@ export function addTransitionCompleteCallbackToPendingTransition( transitionStart: null, transitionProgress: null, transitionComplete: [], + markerProgress: null, markerComplete: null, }; } diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index a3a9c88d84..c522a06970 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -342,6 +342,7 @@ export function addTransitionStartCallbackToPendingTransition( transitionStart: [], transitionProgress: null, transitionComplete: null, + markerProgress: null, markerComplete: null, }; } @@ -354,6 +355,33 @@ export function addTransitionStartCallbackToPendingTransition( } } +export function addMarkerProgressCallbackToPendingTransition( + markerName: string, + transitions: Set, + pendingSuspenseBoundaries: PendingSuspenseBoundaries | null, +) { + if (enableTransitionTracing) { + if (currentPendingTransitionCallbacks === null) { + currentPendingTransitionCallbacks = { + transitionStart: null, + transitionProgress: null, + transitionComplete: null, + markerProgress: new Map(), + markerComplete: null, + }; + } + + if (currentPendingTransitionCallbacks.markerProgress === null) { + currentPendingTransitionCallbacks.markerProgress = new Map(); + } + + currentPendingTransitionCallbacks.markerProgress.set(markerName, { + pendingSuspenseBoundaries, + transitions, + }); + } +} + export function addMarkerCompleteCallbackToPendingTransition( transition: MarkerTransition, ) { @@ -363,6 +391,7 @@ export function addMarkerCompleteCallbackToPendingTransition( transitionStart: null, transitionProgress: null, transitionComplete: null, + markerProgress: null, markerComplete: [], }; } @@ -385,6 +414,7 @@ export function addTransitionProgressCallbackToPendingTransition( transitionStart: null, transitionProgress: new Map(), transitionComplete: null, + markerProgress: null, markerComplete: null, }; } @@ -409,6 +439,7 @@ export function addTransitionCompleteCallbackToPendingTransition( transitionStart: null, transitionProgress: null, transitionComplete: [], + markerProgress: null, markerComplete: null, }; } diff --git a/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js b/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js index bd92a41d48..3c0011a9cb 100644 --- a/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js +++ b/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js @@ -941,7 +941,91 @@ describe('ReactInteractionTracing', () => { }); // @gate enableTransitionTracing - it('should correctly trace interactions for tracing markers complete', async () => { + it('should correctly trace basic interaction with tracing markers', async () => { + const transitionCallbacks = { + onTransitionStart: (name, startTime) => { + Scheduler.unstable_yieldValue( + `onTransitionStart(${name}, ${startTime})`, + ); + }, + onTransitionProgress: (name, startTime, endTime, pending) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.unstable_yieldValue( + `onTransitionProgress(${name}, ${startTime}, ${endTime}, [${suspenseNames}])`, + ); + }, + onTransitionComplete: (name, startTime, endTime) => { + Scheduler.unstable_yieldValue( + `onTransitionComplete(${name}, ${startTime}, ${endTime})`, + ); + }, + onMarkerProgress: ( + transitioName, + markerName, + startTime, + currentTime, + pending, + ) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.unstable_yieldValue( + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`, + ); + }, + onMarkerComplete: (transitioName, markerName, startTime, endTime) => { + Scheduler.unstable_yieldValue( + `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`, + ); + }, + }; + + let navigateToPageTwo; + function App() { + const [navigate, setNavigate] = useState(false); + navigateToPageTwo = () => { + setNavigate(true); + }; + + return ( +
+ {navigate ? ( + + + + ) : ( + + + + )} +
+ ); + } + + const root = ReactNoop.createRoot({transitionCallbacks}); + await act(async () => { + root.render(); + ReactNoop.expire(1000); + await advanceTimers(1000); + + expect(Scheduler).toFlushAndYield(['Page One']); + + await act(async () => { + startTransition(() => navigateToPageTwo(), {name: 'page transition'}); + + ReactNoop.expire(1000); + await advanceTimers(1000); + + expect(Scheduler).toFlushAndYield([ + 'Page Two', + 'onTransitionStart(page transition, 1000)', + 'onMarkerComplete(page transition, marker two, 1000, 2000)', + 'onTransitionComplete(page transition, 1000, 2000)', + ]); + }); + }); + }); + + // @gate enableTransitionTracing + it('should correctly trace interactions for tracing markers', async () => { const transitionCallbacks = { onTransitionStart: (name, startTime) => { Scheduler.unstable_yieldValue( @@ -953,6 +1037,18 @@ describe('ReactInteractionTracing', () => { `onTransitionComplete(${name}, ${startTime}, ${endTime})`, ); }, + onMarkerProgress: ( + transitioName, + markerName, + startTime, + currentTime, + pending, + ) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.unstable_yieldValue( + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`, + ); + }, onMarkerComplete: (transitioName, markerName, startTime, endTime) => { Scheduler.unstable_yieldValue( `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`, @@ -971,13 +1067,13 @@ describe('ReactInteractionTracing', () => { {navigate ? ( } - name="suspense page"> + unstable_name="suspense page"> } - name="marker suspense"> + unstable_name="marker suspense"> @@ -1020,6 +1116,7 @@ describe('ReactInteractionTracing', () => { 'Page Two', 'Suspend [Marker Text]', 'Loading...', + 'onMarkerProgress(page transition, async marker, 1000, 3000, [marker suspense])', 'onMarkerComplete(page transition, sync marker, 1000, 3000)', ]); @@ -1029,6 +1126,7 @@ describe('ReactInteractionTracing', () => { expect(Scheduler).toFlushAndYield([ 'Marker Text', + 'onMarkerProgress(page transition, async marker, 1000, 4000, [])', 'onMarkerComplete(page transition, async marker, 1000, 4000)', 'onTransitionComplete(page transition, 1000, 4000)', ]); @@ -1048,6 +1146,18 @@ describe('ReactInteractionTracing', () => { `onTransitionComplete(${name}, ${startTime}, ${endTime})`, ); }, + onMarkerProgress: ( + transitioName, + markerName, + startTime, + currentTime, + pending, + ) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.unstable_yieldValue( + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`, + ); + }, onMarkerComplete: (transitioName, markerName, startTime, endTime) => { Scheduler.unstable_yieldValue( `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`, @@ -1066,14 +1176,20 @@ describe('ReactInteractionTracing', () => {
{navigate ? ( - }> + } + unstable_name="outer"> - }> + } + unstable_name="inner one"> - }> + } + unstable_name="inner two"> @@ -1110,6 +1226,7 @@ describe('ReactInteractionTracing', () => { 'Inner Two...', 'Outer...', 'onTransitionStart(page transition, 1000)', + 'onMarkerProgress(page transition, outer marker, 1000, 2000, [outer])', ]); ReactNoop.expire(1000); @@ -1125,6 +1242,7 @@ describe('ReactInteractionTracing', () => { 'Suspend [Inner Text One]', 'Inner One...', 'Inner Text Two', + 'onMarkerProgress(page transition, outer marker, 1000, 4000, [inner one])', 'onMarkerComplete(page transition, marker two, 1000, 4000)', ]); @@ -1133,6 +1251,7 @@ describe('ReactInteractionTracing', () => { await resolveText('Inner Text One'); expect(Scheduler).toFlushAndYield([ 'Inner Text One', + 'onMarkerProgress(page transition, outer marker, 1000, 5000, [])', 'onMarkerComplete(page transition, marker one, 1000, 5000)', 'onMarkerComplete(page transition, outer marker, 1000, 5000)', 'onTransitionComplete(page transition, 1000, 5000)', @@ -1233,6 +1352,18 @@ describe('ReactInteractionTracing', () => { `onTransitionComplete(${name}, ${startTime}, ${endTime})`, ); }, + onMarkerProgress: ( + transitioName, + markerName, + startTime, + currentTime, + pending, + ) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.unstable_yieldValue( + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`, + ); + }, onMarkerComplete: (transitioName, markerName, startTime, endTime) => { Scheduler.unstable_yieldValue( `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`, @@ -1279,6 +1410,7 @@ describe('ReactInteractionTracing', () => { 'Suspend [Page Two]', 'Loading...', 'onTransitionStart(page transition, 1000)', + 'onMarkerProgress(page transition, old marker, 1000, 1000, [])', ]); ReactNoop.expire(1000); @@ -1311,6 +1443,18 @@ describe('ReactInteractionTracing', () => { `onTransitionComplete(${name}, ${startTime}, ${endTime})`, ); }, + onMarkerProgress: ( + transitioName, + markerName, + startTime, + currentTime, + pending, + ) => { + const suspenseNames = pending.map(p => p.name || '').join(', '); + Scheduler.unstable_yieldValue( + `onMarkerProgress(${transitioName}, ${markerName}, ${startTime}, ${currentTime}, [${suspenseNames}])`, + ); + }, onMarkerComplete: (transitioName, markerName, startTime, endTime) => { Scheduler.unstable_yieldValue( `onMarkerComplete(${transitioName}, ${markerName}, ${startTime}, ${endTime})`, @@ -1357,6 +1501,7 @@ describe('ReactInteractionTracing', () => { 'Suspend [Page Two]', 'Loading...', 'onTransitionStart(page transition, 1000)', + 'onMarkerProgress(page transition, old marker, 1000, 2000, [])', ]); ReactNoop.expire(1000); @@ -1367,6 +1512,9 @@ describe('ReactInteractionTracing', () => { 'Suspend [Page Two]', 'Loading...', 'onTransitionStart(marker transition, 2000)', + 'onMarkerProgress(marker transition, new marker, 2000, 3000, [])', + 'onMarkerComplete(marker transition, new marker, 2000, 3000)', + 'onTransitionComplete(marker transition, 2000, 3000)', ]); ReactNoop.expire(1000); await advanceTimers(1000);