diff --git a/packages/react-reconciler/src/ReactFiberBeginWork.new.js b/packages/react-reconciler/src/ReactFiberBeginWork.new.js index ab0705fa7a964..a13b9f7a811b6 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 48a932df7803d..b7b32a43adb72 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 097628db06d15..8bd7df0e0e410 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'; @@ -1122,6 +1123,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) @@ -1129,13 +1131,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, + ); + }); + } } } }); @@ -1147,18 +1157,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, + ); + }); + } } } }); @@ -3041,19 +3060,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 252200fd5fbf3..56615329053ad 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'; @@ -1122,6 +1123,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) @@ -1129,13 +1131,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, + ); + }); + } } } }); @@ -1147,18 +1157,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, + ); + }); + } } } }); @@ -3041,19 +3060,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 8e1a60d38caba..ceae6dec33642 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 0a5693823edad..bf9268445a062 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 11d41148abb88..481950eb36718 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 539d7e2f7731a..6f99497115ca4 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 29d9cc8f492a6..e50930f190212 100644 --- a/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js +++ b/packages/react-reconciler/src/__tests__/ReactTransitionTracing-test.js @@ -860,7 +860,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( @@ -872,6 +956,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})`, @@ -890,13 +986,13 @@ describe('ReactInteractionTracing', () => { {navigate ? ( } - name="suspense page"> + unstable_name="suspense page"> } - name="marker suspense"> + unstable_name="marker suspense"> @@ -939,6 +1035,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)', ]); @@ -948,6 +1045,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)', ]); @@ -967,6 +1065,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})`, @@ -985,14 +1095,20 @@ describe('ReactInteractionTracing', () => {
{navigate ? ( - }> + } + unstable_name="outer"> - }> + } + unstable_name="inner one"> - }> + } + unstable_name="inner two"> @@ -1029,6 +1145,7 @@ describe('ReactInteractionTracing', () => { 'Inner Two...', 'Outer...', 'onTransitionStart(page transition, 1000)', + 'onMarkerProgress(page transition, outer marker, 1000, 2000, [outer])', ]); ReactNoop.expire(1000); @@ -1044,6 +1161,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)', ]); @@ -1052,6 +1170,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)', @@ -1152,6 +1271,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})`, @@ -1198,6 +1329,7 @@ describe('ReactInteractionTracing', () => { 'Suspend [Page Two]', 'Loading...', 'onTransitionStart(page transition, 1000)', + 'onMarkerProgress(page transition, old marker, 1000, 1000, [])', ]); ReactNoop.expire(1000); @@ -1230,6 +1362,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})`, @@ -1276,6 +1420,7 @@ describe('ReactInteractionTracing', () => { 'Suspend [Page Two]', 'Loading...', 'onTransitionStart(page transition, 1000)', + 'onMarkerProgress(page transition, old marker, 1000, 2000, [])', ]); ReactNoop.expire(1000); @@ -1286,6 +1431,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);