import { Reaction } from "mobx" ; import { ReactionCleanupTracking , IReactionTracking , CLEANUP_TIMER_LOOP_MILLIS , createTrackingData } from "./reactionCleanupTrackingCommon" ; /**
 * timers, gc-style, uncommitted reaction cleanup
 */ export function createTimerBasedReactionCleanupTracking ( ) { /**
     * Reactions created by components that have yet to be fully mounted.
     */ const uncommittedReactionRefs = new Set ( ) ; /**
     * Latest 'uncommitted reactions' cleanup timer handle.
     */ let reactionCleanupHandle ; /**
     * Only to be used by test functions; do not export outside of mobx-react-lite
     */ function forceCleanupTimerToRunNowForTests ( ) { if ( reactionCleanupHandle ) { clearTimeout ( reactionCleanupHandle ) ; cleanUncommittedReactions ( ) ; } } function resetCleanupScheduleForTests ( ) { if ( uncommittedReactionRefs . size > 0 ) { for ( const ref of uncommittedReactionRefs ) { const tracking = ref . current ; if ( tracking ) { tracking . reaction . dispose ( ) ; ref . current = null ; } } uncommittedReactionRefs . clear ( ) ; } if ( reactionCleanupHandle ) { clearTimeout ( reactionCleanupHandle ) ; reactionCleanupHandle = undefined ; } } function ensureCleanupTimerRunning ( ) { if ( reactionCleanupHandle === undefined ) { reactionCleanupHandle = setTimeout ( cleanUncommittedReactions , CLEANUP_TIMER_LOOP_MILLIS ) ; } } function scheduleCleanupOfReactionIfLeaked ( ref ) { uncommittedReactionRefs . add ( ref ) ; ensureCleanupTimerRunning ( ) ; } function recordReactionAsCommitted ( reactionRef ) { uncommittedReactionRefs . delete ( reactionRef ) ; } /**
     * Run by the cleanup timer to dispose any outstanding reactions
     */ function cleanUncommittedReactions ( ) { reactionCleanupHandle = undefined ; const now = Date . now ( ) ; uncommittedReactionRefs . forEach ( ref => { const tracking = ref . current ; if ( tracking ) { if ( now >= tracking . cleanAt ) { tracking . reaction . dispose ( ) ; ref . current = null ; uncommittedReactionRefs . delete ( ref ) ; } } } ) ; if ( uncommittedReactionRefs . size > 0 ) { ensureCleanupTimerRunning ( ) ; } } return { addReactionToTrack ( reactionTrackingRef , reaction , /**
         * On timer based implementation we don't really need this object,
         * but we keep the same api
         */ objectRetainedByReact ) { reactionTrackingRef . current = createTrackingData ( reaction ) ; scheduleCleanupOfReactionIfLeaked ( reactionTrackingRef ) ; return reactionTrackingRef . current ; } , recordReactionAsCommitted , forceCleanupTimerToRunNowForTests , resetCleanupScheduleForTests } ; }