@@ -1531,8 +1531,8 @@ describe('ReactInteractionTracing', () => {
15311531 'Loading...' ,
15321532 'Suspend [Sibling Text]' ,
15331533 'Sibling Loading...' ,
1534- 'onMarkerIncomplete(transition one, marker one, 1000, [{endTime: 3000, name: marker one, type: marker}])' ,
1535- 'onMarkerIncomplete(transition one, parent, 1000, [{endTime: 3000, name: marker one, type: marker}])' ,
1534+ 'onMarkerIncomplete(transition one, marker one, 1000, [{endTime: 3000, name: marker one, type: marker}, {endTime: 3000, name: suspense page, type: suspense} ])' ,
1535+ 'onMarkerIncomplete(transition one, parent, 1000, [{endTime: 3000, name: marker one, type: marker}, {endTime: 3000, name: suspense page, type: suspense ])' ,
15361536 ] ) ;
15371537
15381538 root . render ( < App navigate = { true } showMarker = { true } /> ) ;
@@ -1679,8 +1679,8 @@ describe('ReactInteractionTracing', () => {
16791679 expect ( Scheduler ) . toFlushAndYield ( [
16801680 'Suspend [Page Two]' ,
16811681 'Loading Two...' ,
1682- 'onMarkerIncomplete(transition, one, 1000, [{endTime: 3000, name: one, type: marker}])' ,
1683- 'onMarkerIncomplete(transition, parent, 1000, [{endTime: 3000, name: one, type: marker}])' ,
1682+ 'onMarkerIncomplete(transition, one, 1000, [{endTime: 3000, name: one, type: marker}, {endTime: 3000, name: suspense one, type: suspense} ])' ,
1683+ 'onMarkerIncomplete(transition, parent, 1000, [{endTime: 3000, name: one, type: marker}, {endTime: 3000, name: suspense one, type: suspense} ])' ,
16841684 ] ) ;
16851685
16861686 await resolveText ( 'Page Two' ) ;
@@ -1698,6 +1698,275 @@ describe('ReactInteractionTracing', () => {
16981698 } ) ;
16991699 } ) ;
17001700
1701+ // @gate enableTransitionTracing
1702+ it ( 'Suspense boundary added by the transition is deleted' , async ( ) => {
1703+ const transitionCallbacks = {
1704+ onTransitionStart : ( name , startTime ) => {
1705+ Scheduler . unstable_yieldValue (
1706+ `onTransitionStart(${ name } , ${ startTime } )` ,
1707+ ) ;
1708+ } ,
1709+ onTransitionProgress : ( name , startTime , endTime , pending ) => {
1710+ const suspenseNames = pending . map ( p => p . name || '<null>' ) . join ( ', ' ) ;
1711+ Scheduler . unstable_yieldValue (
1712+ `onTransitionProgress(${ name } , ${ startTime } , ${ endTime } , [${ suspenseNames } ])` ,
1713+ ) ;
1714+ } ,
1715+ onTransitionComplete : ( name , startTime , endTime ) => {
1716+ Scheduler . unstable_yieldValue (
1717+ `onTransitionComplete(${ name } , ${ startTime } , ${ endTime } )` ,
1718+ ) ;
1719+ } ,
1720+ onMarkerProgress : (
1721+ transitioName ,
1722+ markerName ,
1723+ startTime ,
1724+ currentTime ,
1725+ pending ,
1726+ ) => {
1727+ const suspenseNames = pending . map ( p => p . name || '<null>' ) . join ( ', ' ) ;
1728+ Scheduler . unstable_yieldValue (
1729+ `onMarkerProgress(${ transitioName } , ${ markerName } , ${ startTime } , ${ currentTime } , [${ suspenseNames } ])` ,
1730+ ) ;
1731+ } ,
1732+ onMarkerIncomplete : (
1733+ transitionName ,
1734+ markerName ,
1735+ startTime ,
1736+ deletions ,
1737+ ) => {
1738+ Scheduler . unstable_yieldValue (
1739+ `onMarkerIncomplete(${ transitionName } , ${ markerName } , ${ startTime } , [${ stringifyDeletions (
1740+ deletions ,
1741+ ) } ])`,
1742+ ) ;
1743+ } ,
1744+ onMarkerComplete : ( transitioName , markerName , startTime , endTime ) => {
1745+ Scheduler . unstable_yieldValue (
1746+ `onMarkerComplete(${ transitioName } , ${ markerName } , ${ startTime } , ${ endTime } )` ,
1747+ ) ;
1748+ } ,
1749+ } ;
1750+
1751+ function App ( { navigate, deleteOne} ) {
1752+ return (
1753+ < div >
1754+ { navigate ? (
1755+ < React . unstable_TracingMarker name = "parent" >
1756+ < React . unstable_TracingMarker name = "one" >
1757+ { ! deleteOne ? (
1758+ < Suspense
1759+ unstable_name = "suspense one"
1760+ fallback = { < Text text = "Loading One..." /> } >
1761+ < AsyncText text = "Page One" />
1762+ < React . unstable_TracingMarker name = "page one" />
1763+ < Suspense
1764+ unstable_name = "suspense child"
1765+ fallback = { < Text text = "Loading Child..." /> } >
1766+ < React . unstable_TracingMarker name = "child" />
1767+ < AsyncText text = "Child" />
1768+ </ Suspense >
1769+ </ Suspense >
1770+ ) : null }
1771+ </ React . unstable_TracingMarker >
1772+ < React . unstable_TracingMarker name = "two" >
1773+ < Suspense
1774+ unstable_name = "suspense two"
1775+ fallback = { < Text text = "Loading Two..." /> } >
1776+ < AsyncText text = "Page Two" />
1777+ </ Suspense >
1778+ </ React . unstable_TracingMarker >
1779+ </ React . unstable_TracingMarker >
1780+ ) : (
1781+ < Text text = "Page One" />
1782+ ) }
1783+ </ div >
1784+ ) ;
1785+ }
1786+ const root = ReactNoop . createRoot ( {
1787+ unstable_transitionCallbacks : transitionCallbacks ,
1788+ } ) ;
1789+ await act ( async ( ) => {
1790+ root . render ( < App navigate = { false } deleteOne = { false } /> ) ;
1791+
1792+ ReactNoop . expire ( 1000 ) ;
1793+ await advanceTimers ( 1000 ) ;
1794+ expect ( Scheduler ) . toFlushAndYield ( [ 'Page One' ] ) ;
1795+
1796+ startTransition (
1797+ ( ) => root . render ( < App navigate = { true } deleteOne = { false } /> ) ,
1798+ {
1799+ name : 'transition' ,
1800+ } ,
1801+ ) ;
1802+ ReactNoop . expire ( 1000 ) ;
1803+ await advanceTimers ( 1000 ) ;
1804+ expect ( Scheduler ) . toFlushAndYield ( [
1805+ 'Suspend [Page One]' ,
1806+ 'Suspend [Child]' ,
1807+ 'Loading Child...' ,
1808+ 'Loading One...' ,
1809+ 'Suspend [Page Two]' ,
1810+ 'Loading Two...' ,
1811+ 'onTransitionStart(transition, 1000)' ,
1812+ 'onMarkerProgress(transition, parent, 1000, 2000, [suspense one, suspense two])' ,
1813+ 'onMarkerProgress(transition, one, 1000, 2000, [suspense one])' ,
1814+ 'onMarkerProgress(transition, two, 1000, 2000, [suspense two])' ,
1815+ 'onTransitionProgress(transition, 1000, 2000, [suspense one, suspense two])' ,
1816+ ] ) ;
1817+
1818+ await resolveText ( 'Page One' ) ;
1819+ ReactNoop . expire ( 1000 ) ;
1820+ await advanceTimers ( 1000 ) ;
1821+ expect ( Scheduler ) . toFlushAndYield ( [
1822+ 'Page One' ,
1823+ 'Suspend [Child]' ,
1824+ 'Loading Child...' ,
1825+ 'onMarkerProgress(transition, parent, 1000, 3000, [suspense two, suspense child])' ,
1826+ 'onMarkerProgress(transition, one, 1000, 3000, [suspense child])' ,
1827+ 'onMarkerComplete(transition, page one, 1000, 3000)' ,
1828+ 'onTransitionProgress(transition, 1000, 3000, [suspense two, suspense child])' ,
1829+ ] ) ;
1830+
1831+ root . render ( < App navigate = { true } deleteOne = { true } /> ) ;
1832+ ReactNoop . expire ( 1000 ) ;
1833+ await advanceTimers ( 1000 ) ;
1834+ expect ( Scheduler ) . toFlushAndYield ( [
1835+ 'Suspend [Page Two]' ,
1836+ 'Loading Two...' ,
1837+ // "suspense one" has unsuspended so shouldn't be included
1838+ // tracing marker "page one" has completed so shouldn't be included
1839+ // all children of "suspense child" haven't yet been rendered so shouldn't be included
1840+ 'onMarkerIncomplete(transition, parent, 1000, [{endTime: 4000, name: suspense child, type: suspense}])' ,
1841+ 'onMarkerIncomplete(transition, one, 1000, [{endTime: 4000, name: suspense child, type: suspense}])' ,
1842+ ] ) ;
1843+
1844+ await resolveText ( 'Page Two' ) ;
1845+ ReactNoop . expire ( 1000 ) ;
1846+ await advanceTimers ( 1000 ) ;
1847+ expect ( Scheduler ) . toFlushAndYield ( [
1848+ 'Page Two' ,
1849+ 'onMarkerProgress(transition, parent, 1000, 5000, [])' ,
1850+ 'onMarkerProgress(transition, two, 1000, 5000, [])' ,
1851+ 'onMarkerComplete(transition, two, 1000, 5000)' ,
1852+ 'onTransitionProgress(transition, 1000, 5000, [])' ,
1853+ ] ) ;
1854+ } ) ;
1855+ } ) ;
1856+
1857+ // @gate enableTransitionTracing
1858+ it ( 'Suspense boundary not added by the transition is deleted ' , async ( ) => {
1859+ const transitionCallbacks = {
1860+ onTransitionStart : ( name , startTime ) => {
1861+ Scheduler . unstable_yieldValue (
1862+ `onTransitionStart(${ name } , ${ startTime } )` ,
1863+ ) ;
1864+ } ,
1865+ onTransitionProgress : ( name , startTime , endTime , pending ) => {
1866+ const suspenseNames = pending . map ( p => p . name || '<null>' ) . join ( ', ' ) ;
1867+ Scheduler . unstable_yieldValue (
1868+ `onTransitionProgress(${ name } , ${ startTime } , ${ endTime } , [${ suspenseNames } ])` ,
1869+ ) ;
1870+ } ,
1871+ onTransitionComplete : ( name , startTime , endTime ) => {
1872+ Scheduler . unstable_yieldValue (
1873+ `onTransitionComplete(${ name } , ${ startTime } , ${ endTime } )` ,
1874+ ) ;
1875+ } ,
1876+ onMarkerProgress : (
1877+ transitioName ,
1878+ markerName ,
1879+ startTime ,
1880+ currentTime ,
1881+ pending ,
1882+ ) => {
1883+ const suspenseNames = pending . map ( p => p . name || '<null>' ) . join ( ', ' ) ;
1884+ Scheduler . unstable_yieldValue (
1885+ `onMarkerProgress(${ transitioName } , ${ markerName } , ${ startTime } , ${ currentTime } , [${ suspenseNames } ])` ,
1886+ ) ;
1887+ } ,
1888+ onMarkerIncomplete : (
1889+ transitionName ,
1890+ markerName ,
1891+ startTime ,
1892+ deletions ,
1893+ ) => {
1894+ Scheduler . unstable_yieldValue (
1895+ `onMarkerIncomplete(${ transitionName } , ${ markerName } , ${ startTime } , [${ stringifyDeletions (
1896+ deletions ,
1897+ ) } ])`,
1898+ ) ;
1899+ } ,
1900+ onMarkerComplete : ( transitioName , markerName , startTime , endTime ) => {
1901+ Scheduler . unstable_yieldValue (
1902+ `onMarkerComplete(${ transitioName } , ${ markerName } , ${ startTime } , ${ endTime } )` ,
1903+ ) ;
1904+ } ,
1905+ } ;
1906+
1907+ function App ( { show} ) {
1908+ return (
1909+ < React . unstable_TracingMarker name = "parent" >
1910+ { show ? (
1911+ < Suspense unstable_name = "appended child" >
1912+ < AsyncText text = "Appended child" />
1913+ </ Suspense >
1914+ ) : null }
1915+ < Suspense unstable_name = "child" >
1916+ < AsyncText text = "Child" />
1917+ </ Suspense >
1918+ </ React . unstable_TracingMarker >
1919+ ) ;
1920+ }
1921+
1922+ const root = ReactNoop . createRoot ( {
1923+ unstable_transitionCallbacks : transitionCallbacks ,
1924+ } ) ;
1925+ await act ( async ( ) => {
1926+ startTransition ( ( ) => root . render ( < App show = { false } /> ) , {
1927+ name : 'transition' ,
1928+ } ) ;
1929+ ReactNoop . expire ( 1000 ) ;
1930+ await advanceTimers ( 1000 ) ;
1931+
1932+ expect ( Scheduler ) . toFlushAndYield ( [
1933+ 'Suspend [Child]' ,
1934+ 'onTransitionStart(transition, 0)' ,
1935+ 'onMarkerProgress(transition, parent, 0, 1000, [child])' ,
1936+ 'onTransitionProgress(transition, 0, 1000, [child])' ,
1937+ ] ) ;
1938+
1939+ root . render ( < App show = { true } /> ) ;
1940+ ReactNoop . expire ( 1000 ) ;
1941+ await advanceTimers ( 1000 ) ;
1942+ // This appended child isn't part of the transition so we
1943+ // don't call any callback
1944+ expect ( Scheduler ) . toFlushAndYield ( [
1945+ 'Suspend [Appended child]' ,
1946+ 'Suspend [Child]' ,
1947+ ] ) ;
1948+
1949+ // This deleted child isn't part of the transition so we
1950+ // don't call any callbacks
1951+ root . render ( < App show = { false } /> ) ;
1952+ ReactNoop . expire ( 1000 ) ;
1953+ await advanceTimers ( 1000 ) ;
1954+ expect ( Scheduler ) . toFlushAndYield ( [ 'Suspend [Child]' ] ) ;
1955+
1956+ await resolveText ( 'Child' ) ;
1957+ ReactNoop . expire ( 1000 ) ;
1958+ await advanceTimers ( 1000 ) ;
1959+
1960+ expect ( Scheduler ) . toFlushAndYield ( [
1961+ 'Child' ,
1962+ 'onMarkerProgress(transition, parent, 0, 4000, [])' ,
1963+ 'onMarkerComplete(transition, parent, 0, 4000)' ,
1964+ 'onTransitionProgress(transition, 0, 4000, [])' ,
1965+ 'onTransitionComplete(transition, 0, 4000)' ,
1966+ ] ) ;
1967+ } ) ;
1968+ } ) ;
1969+
17011970 // @gate enableTransitionTracing
17021971 it ( 'warns when marker name changes' , async ( ) => {
17031972 const transitionCallbacks = {
0 commit comments