2026-07-07 07:11:50 +00:00
/** @license React v0.20.2
2026-07-05 06:41:32 +00:00
* scheduler.development.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict' ;
if ( process . env . NODE _ENV !== "production" ) {
( function ( ) {
2026-07-07 07:11:50 +00:00
'use strict' ;
var enableSchedulerDebugging = false ;
var enableProfiling = false ;
var requestHostCallback ;
var requestHostTimeout ;
var cancelHostTimeout ;
var requestPaint ;
var hasPerformanceNow = typeof performance === 'object' && typeof performance . now === 'function' ;
2026-07-05 06:41:32 +00:00
2026-07-07 07:11:50 +00:00
if ( hasPerformanceNow ) {
var localPerformance = performance ;
exports . unstable _now = function ( ) {
return localPerformance . now ( ) ;
} ;
} else {
var localDate = Date ;
var initialTime = localDate . now ( ) ;
2026-07-05 06:41:32 +00:00
2026-07-07 07:11:50 +00:00
exports . unstable _now = function ( ) {
return localDate . now ( ) - initialTime ;
} ;
}
if ( // If Scheduler runs in a non-DOM environment, it falls back to a naive
// implementation using setTimeout.
typeof window === 'undefined' || // Check if MessageChannel is supported, too.
typeof MessageChannel !== 'function' ) {
// If this accidentally gets imported in a non-browser environment, e.g. JavaScriptCore,
// fallback to a naive implementation.
var _callback = null ;
var _timeoutID = null ;
var _flushCallback = function ( ) {
if ( _callback !== null ) {
try {
var currentTime = exports . unstable _now ( ) ;
var hasRemainingTime = true ;
_callback ( hasRemainingTime , currentTime ) ;
_callback = null ;
} catch ( e ) {
setTimeout ( _flushCallback , 0 ) ;
throw e ;
}
}
} ;
requestHostCallback = function ( cb ) {
if ( _callback !== null ) {
// Protect against re-entrancy.
setTimeout ( requestHostCallback , 0 , cb ) ;
} else {
_callback = cb ;
setTimeout ( _flushCallback , 0 ) ;
}
} ;
requestHostTimeout = function ( cb , ms ) {
_timeoutID = setTimeout ( cb , ms ) ;
} ;
cancelHostTimeout = function ( ) {
clearTimeout ( _timeoutID ) ;
} ;
exports . unstable _shouldYield = function ( ) {
return false ;
} ;
requestPaint = exports . unstable _forceFrameRate = function ( ) { } ;
} else {
// Capture local references to native APIs, in case a polyfill overrides them.
var _setTimeout = window . setTimeout ;
var _clearTimeout = window . clearTimeout ;
if ( typeof console !== 'undefined' ) {
// TODO: Scheduler no longer requires these methods to be polyfilled. But
// maybe we want to continue warning if they don't exist, to preserve the
// option to rely on it in the future?
var requestAnimationFrame = window . requestAnimationFrame ;
var cancelAnimationFrame = window . cancelAnimationFrame ;
if ( typeof requestAnimationFrame !== 'function' ) {
// Using console['error'] to evade Babel and ESLint
console [ 'error' ] ( "This browser doesn't support requestAnimationFrame. " + 'Make sure that you load a ' + 'polyfill in older browsers. https://reactjs.org/link/react-polyfills' ) ;
}
if ( typeof cancelAnimationFrame !== 'function' ) {
// Using console['error'] to evade Babel and ESLint
console [ 'error' ] ( "This browser doesn't support cancelAnimationFrame. " + 'Make sure that you load a ' + 'polyfill in older browsers. https://reactjs.org/link/react-polyfills' ) ;
}
}
var isMessageLoopRunning = false ;
var scheduledHostCallback = null ;
var taskTimeoutID = - 1 ; // Scheduler periodically yields in case there is other work on the main
// thread, like user events. By default, it yields multiple times per frame.
// It does not attempt to align with frame boundaries, since most tasks don't
// need to be frame aligned; for those that do, use requestAnimationFrame.
var yieldInterval = 5 ;
var deadline = 0 ; // TODO: Make this configurable
{
// `isInputPending` is not available. Since we have no way of knowing if
// there's pending input, always yield at the end of the frame.
exports . unstable _shouldYield = function ( ) {
return exports . unstable _now ( ) >= deadline ;
} ; // Since we yield every frame regardless, `requestPaint` has no effect.
requestPaint = function ( ) { } ;
}
exports . unstable _forceFrameRate = function ( fps ) {
if ( fps < 0 || fps > 125 ) {
// Using console['error'] to evade Babel and ESLint
console [ 'error' ] ( 'forceFrameRate takes a positive int between 0 and 125, ' + 'forcing frame rates higher than 125 fps is not supported' ) ;
return ;
}
if ( fps > 0 ) {
yieldInterval = Math . floor ( 1000 / fps ) ;
} else {
// reset the framerate
yieldInterval = 5 ;
}
} ;
var performWorkUntilDeadline = function ( ) {
if ( scheduledHostCallback !== null ) {
var currentTime = exports . unstable _now ( ) ; // Yield after `yieldInterval` ms, regardless of where we are in the vsync
// cycle. This means there's always time remaining at the beginning of
// the message event.
deadline = currentTime + yieldInterval ;
var hasTimeRemaining = true ;
try {
var hasMoreWork = scheduledHostCallback ( hasTimeRemaining , currentTime ) ;
if ( ! hasMoreWork ) {
isMessageLoopRunning = false ;
scheduledHostCallback = null ;
} else {
// If there's more work, schedule the next message event at the end
// of the preceding one.
port . postMessage ( null ) ;
}
} catch ( error ) {
// If a scheduler task throws, exit the current browser task so the
// error can be observed.
port . postMessage ( null ) ;
throw error ;
}
} else {
isMessageLoopRunning = false ;
} // Yielding to the browser will give it a chance to paint, so we can
} ;
var channel = new MessageChannel ( ) ;
var port = channel . port2 ;
channel . port1 . onmessage = performWorkUntilDeadline ;
requestHostCallback = function ( callback ) {
scheduledHostCallback = callback ;
if ( ! isMessageLoopRunning ) {
isMessageLoopRunning = true ;
port . postMessage ( null ) ;
}
} ;
requestHostTimeout = function ( callback , ms ) {
taskTimeoutID = _setTimeout ( function ( ) {
callback ( exports . unstable _now ( ) ) ;
} , ms ) ;
} ;
cancelHostTimeout = function ( ) {
_clearTimeout ( taskTimeoutID ) ;
taskTimeoutID = - 1 ;
} ;
2026-07-05 06:41:32 +00:00
}
function push ( heap , node ) {
var index = heap . length ;
heap . push ( node ) ;
siftUp ( heap , node , index ) ;
}
function peek ( heap ) {
2026-07-07 07:11:50 +00:00
var first = heap [ 0 ] ;
return first === undefined ? null : first ;
2026-07-05 06:41:32 +00:00
}
function pop ( heap ) {
var first = heap [ 0 ] ;
2026-07-07 07:11:50 +00:00
if ( first !== undefined ) {
var last = heap . pop ( ) ;
2026-07-05 06:41:32 +00:00
2026-07-07 07:11:50 +00:00
if ( last !== first ) {
heap [ 0 ] = last ;
siftDown ( heap , last , 0 ) ;
}
return first ;
} else {
return null ;
}
2026-07-05 06:41:32 +00:00
}
function siftUp ( heap , node , i ) {
var index = i ;
2026-07-07 07:11:50 +00:00
while ( true ) {
2026-07-05 06:41:32 +00:00
var parentIndex = index - 1 >>> 1 ;
var parent = heap [ parentIndex ] ;
2026-07-07 07:11:50 +00:00
if ( parent !== undefined && compare ( parent , node ) > 0 ) {
2026-07-05 06:41:32 +00:00
// The parent is larger. Swap positions.
heap [ parentIndex ] = node ;
heap [ index ] = parent ;
index = parentIndex ;
} else {
// The parent is smaller. Exit.
return ;
}
}
}
function siftDown ( heap , node , i ) {
var index = i ;
var length = heap . length ;
2026-07-07 07:11:50 +00:00
while ( index < length ) {
2026-07-05 06:41:32 +00:00
var leftIndex = ( index + 1 ) * 2 - 1 ;
var left = heap [ leftIndex ] ;
var rightIndex = leftIndex + 1 ;
var right = heap [ rightIndex ] ; // If the left or right node is smaller, swap with the smaller of those.
2026-07-07 07:11:50 +00:00
if ( left !== undefined && compare ( left , node ) < 0 ) {
if ( right !== undefined && compare ( right , left ) < 0 ) {
2026-07-05 06:41:32 +00:00
heap [ index ] = right ;
heap [ rightIndex ] = node ;
index = rightIndex ;
} else {
heap [ index ] = left ;
heap [ leftIndex ] = node ;
index = leftIndex ;
}
2026-07-07 07:11:50 +00:00
} else if ( right !== undefined && compare ( right , node ) < 0 ) {
2026-07-05 06:41:32 +00:00
heap [ index ] = right ;
heap [ rightIndex ] = node ;
index = rightIndex ;
} else {
// Neither child is smaller. Exit.
return ;
}
}
}
function compare ( a , b ) {
// Compare sort index first, then task id.
var diff = a . sortIndex - b . sortIndex ;
return diff !== 0 ? diff : a . id - b . id ;
}
// TODO: Use symbols?
var ImmediatePriority = 1 ;
var UserBlockingPriority = 2 ;
var NormalPriority = 3 ;
var LowPriority = 4 ;
var IdlePriority = 5 ;
function markTaskErrored ( task , ms ) {
}
/* eslint-disable no-var */
// Math.pow(2, 30) - 1
// 0b111111111111111111111111111111
var maxSigned31BitInt = 1073741823 ; // Times out immediately
var IMMEDIATE _PRIORITY _TIMEOUT = - 1 ; // Eventually times out
var USER _BLOCKING _PRIORITY _TIMEOUT = 250 ;
var NORMAL _PRIORITY _TIMEOUT = 5000 ;
var LOW _PRIORITY _TIMEOUT = 10000 ; // Never times out
var IDLE _PRIORITY _TIMEOUT = maxSigned31BitInt ; // Tasks are stored on a min heap
var taskQueue = [ ] ;
var timerQueue = [ ] ; // Incrementing id counter. Used to maintain insertion order.
var taskIdCounter = 1 ; // Pausing the scheduler is useful for debugging.
var currentTask = null ;
2026-07-07 07:11:50 +00:00
var currentPriorityLevel = NormalPriority ; // This is set while performing work, to prevent re-entrancy.
2026-07-05 06:41:32 +00:00
var isPerformingWork = false ;
var isHostCallbackScheduled = false ;
2026-07-07 07:11:50 +00:00
var isHostTimeoutScheduled = false ;
2026-07-05 06:41:32 +00:00
function advanceTimers ( currentTime ) {
// Check for tasks that are no longer delayed and add them to the queue.
var timer = peek ( timerQueue ) ;
while ( timer !== null ) {
if ( timer . callback === null ) {
// Timer was cancelled.
pop ( timerQueue ) ;
} else if ( timer . startTime <= currentTime ) {
// Timer fired. Transfer to the task queue.
pop ( timerQueue ) ;
timer . sortIndex = timer . expirationTime ;
push ( taskQueue , timer ) ;
} else {
// Remaining timers are pending.
return ;
}
timer = peek ( timerQueue ) ;
}
}
function handleTimeout ( currentTime ) {
isHostTimeoutScheduled = false ;
advanceTimers ( currentTime ) ;
if ( ! isHostCallbackScheduled ) {
if ( peek ( taskQueue ) !== null ) {
isHostCallbackScheduled = true ;
requestHostCallback ( flushWork ) ;
} else {
var firstTimer = peek ( timerQueue ) ;
if ( firstTimer !== null ) {
requestHostTimeout ( handleTimeout , firstTimer . startTime - currentTime ) ;
}
}
}
}
function flushWork ( hasTimeRemaining , initialTime ) {
isHostCallbackScheduled = false ;
if ( isHostTimeoutScheduled ) {
// We scheduled a timeout but it's no longer needed. Cancel it.
isHostTimeoutScheduled = false ;
cancelHostTimeout ( ) ;
}
isPerformingWork = true ;
var previousPriorityLevel = currentPriorityLevel ;
try {
if ( enableProfiling ) {
try {
return workLoop ( hasTimeRemaining , initialTime ) ;
} catch ( error ) {
if ( currentTask !== null ) {
var currentTime = exports . unstable _now ( ) ;
markTaskErrored ( currentTask , currentTime ) ;
currentTask . isQueued = false ;
}
throw error ;
}
} else {
// No catch in prod code path.
return workLoop ( hasTimeRemaining , initialTime ) ;
}
} finally {
currentTask = null ;
currentPriorityLevel = previousPriorityLevel ;
isPerformingWork = false ;
}
}
function workLoop ( hasTimeRemaining , initialTime ) {
var currentTime = initialTime ;
advanceTimers ( currentTime ) ;
currentTask = peek ( taskQueue ) ;
while ( currentTask !== null && ! ( enableSchedulerDebugging ) ) {
2026-07-07 07:11:50 +00:00
if ( currentTask . expirationTime > currentTime && ( ! hasTimeRemaining || exports . unstable _shouldYield ( ) ) ) {
2026-07-05 06:41:32 +00:00
// This currentTask hasn't expired, and we've reached the deadline.
break ;
}
var callback = currentTask . callback ;
if ( typeof callback === 'function' ) {
currentTask . callback = null ;
currentPriorityLevel = currentTask . priorityLevel ;
var didUserCallbackTimeout = currentTask . expirationTime <= currentTime ;
var continuationCallback = callback ( didUserCallbackTimeout ) ;
currentTime = exports . unstable _now ( ) ;
if ( typeof continuationCallback === 'function' ) {
currentTask . callback = continuationCallback ;
} else {
if ( currentTask === peek ( taskQueue ) ) {
pop ( taskQueue ) ;
}
}
advanceTimers ( currentTime ) ;
} else {
pop ( taskQueue ) ;
}
currentTask = peek ( taskQueue ) ;
} // Return whether there's additional work
if ( currentTask !== null ) {
return true ;
} else {
var firstTimer = peek ( timerQueue ) ;
if ( firstTimer !== null ) {
requestHostTimeout ( handleTimeout , firstTimer . startTime - currentTime ) ;
}
return false ;
}
}
function unstable _runWithPriority ( priorityLevel , eventHandler ) {
switch ( priorityLevel ) {
case ImmediatePriority :
case UserBlockingPriority :
case NormalPriority :
case LowPriority :
case IdlePriority :
break ;
default :
priorityLevel = NormalPriority ;
}
var previousPriorityLevel = currentPriorityLevel ;
currentPriorityLevel = priorityLevel ;
try {
return eventHandler ( ) ;
} finally {
currentPriorityLevel = previousPriorityLevel ;
}
}
function unstable _next ( eventHandler ) {
var priorityLevel ;
switch ( currentPriorityLevel ) {
case ImmediatePriority :
case UserBlockingPriority :
case NormalPriority :
// Shift down to normal priority
priorityLevel = NormalPriority ;
break ;
default :
// Anything lower than normal priority should remain at the current level.
priorityLevel = currentPriorityLevel ;
break ;
}
var previousPriorityLevel = currentPriorityLevel ;
currentPriorityLevel = priorityLevel ;
try {
return eventHandler ( ) ;
} finally {
currentPriorityLevel = previousPriorityLevel ;
}
}
function unstable _wrapCallback ( callback ) {
var parentPriorityLevel = currentPriorityLevel ;
return function ( ) {
// This is a fork of runWithPriority, inlined for performance.
var previousPriorityLevel = currentPriorityLevel ;
currentPriorityLevel = parentPriorityLevel ;
try {
return callback . apply ( this , arguments ) ;
} finally {
currentPriorityLevel = previousPriorityLevel ;
}
} ;
}
function unstable _scheduleCallback ( priorityLevel , callback , options ) {
var currentTime = exports . unstable _now ( ) ;
var startTime ;
if ( typeof options === 'object' && options !== null ) {
var delay = options . delay ;
if ( typeof delay === 'number' && delay > 0 ) {
startTime = currentTime + delay ;
} else {
startTime = currentTime ;
}
} else {
startTime = currentTime ;
}
var timeout ;
switch ( priorityLevel ) {
case ImmediatePriority :
timeout = IMMEDIATE _PRIORITY _TIMEOUT ;
break ;
case UserBlockingPriority :
timeout = USER _BLOCKING _PRIORITY _TIMEOUT ;
break ;
case IdlePriority :
timeout = IDLE _PRIORITY _TIMEOUT ;
break ;
case LowPriority :
timeout = LOW _PRIORITY _TIMEOUT ;
break ;
case NormalPriority :
default :
timeout = NORMAL _PRIORITY _TIMEOUT ;
break ;
}
var expirationTime = startTime + timeout ;
var newTask = {
id : taskIdCounter ++ ,
callback : callback ,
priorityLevel : priorityLevel ,
startTime : startTime ,
expirationTime : expirationTime ,
sortIndex : - 1
} ;
if ( startTime > currentTime ) {
// This is a delayed task.
newTask . sortIndex = startTime ;
push ( timerQueue , newTask ) ;
if ( peek ( taskQueue ) === null && newTask === peek ( timerQueue ) ) {
// All tasks are delayed, and this is the task with the earliest delay.
if ( isHostTimeoutScheduled ) {
// Cancel an existing timeout.
cancelHostTimeout ( ) ;
} else {
isHostTimeoutScheduled = true ;
} // Schedule a timeout.
requestHostTimeout ( handleTimeout , startTime - currentTime ) ;
}
} else {
newTask . sortIndex = expirationTime ;
push ( taskQueue , newTask ) ;
// wait until the next time we yield.
if ( ! isHostCallbackScheduled && ! isPerformingWork ) {
isHostCallbackScheduled = true ;
requestHostCallback ( flushWork ) ;
}
}
return newTask ;
}
function unstable _pauseExecution ( ) {
}
function unstable _continueExecution ( ) {
if ( ! isHostCallbackScheduled && ! isPerformingWork ) {
isHostCallbackScheduled = true ;
requestHostCallback ( flushWork ) ;
}
}
function unstable _getFirstCallbackNode ( ) {
return peek ( taskQueue ) ;
}
function unstable _cancelCallback ( task ) {
// remove from the queue because you can't remove arbitrary nodes from an
// array based heap, only the first one.)
task . callback = null ;
}
function unstable _getCurrentPriorityLevel ( ) {
return currentPriorityLevel ;
}
var unstable _requestPaint = requestPaint ;
var unstable _Profiling = null ;
exports . unstable _IdlePriority = IdlePriority ;
exports . unstable _ImmediatePriority = ImmediatePriority ;
exports . unstable _LowPriority = LowPriority ;
exports . unstable _NormalPriority = NormalPriority ;
exports . unstable _Profiling = unstable _Profiling ;
exports . unstable _UserBlockingPriority = UserBlockingPriority ;
exports . unstable _cancelCallback = unstable _cancelCallback ;
exports . unstable _continueExecution = unstable _continueExecution ;
exports . unstable _getCurrentPriorityLevel = unstable _getCurrentPriorityLevel ;
exports . unstable _getFirstCallbackNode = unstable _getFirstCallbackNode ;
exports . unstable _next = unstable _next ;
exports . unstable _pauseExecution = unstable _pauseExecution ;
exports . unstable _requestPaint = unstable _requestPaint ;
exports . unstable _runWithPriority = unstable _runWithPriority ;
exports . unstable _scheduleCallback = unstable _scheduleCallback ;
exports . unstable _wrapCallback = unstable _wrapCallback ;
} ) ( ) ;
}