import { isBrowser } from '@typed/common' ; import { Disposable } from '@typed/disposable' ; import { Arity2 } from '@typed/lambda' ; import { Timer } from './types' ; type RequestIdleCallbackHandle = any ; type RequestIdleCallbackOptions = { timeout : number ; } ; export type RequestIdleCallbackDeadline = { readonly didTimeout : boolean ; timeRemaining : ( ) => number ; } ; declare global { interface Window { requestIdleCallback : ( callback : ( deadline : RequestIdleCallbackDeadline ) => void , opts ? : RequestIdleCallbackOptions ) => RequestIdleCallbackHandle ; cancelIdleCallback : ( handle : RequestIdleCallbackHandle ) => void ; } } param fn param timer returns export function whenIdle ( fn , timer ) { return whenIdleWithTimeout ( fn , Number . MAX_SAFE_INTEGER , timer ) ; } param fn param timeout param timer returns export function whenIdleWithTimeout ( fn , timeout , timer ) { if ( isBrowser && 'requestIdleCallback' in window ) { const handle = window . requestIdleCallback ( ( deadline ) => fn ( deadline , timer . currentTime ( ) ) , { timeout , } ) ; return { dispose : ( ) => window . cancelIdleCallback ( handle ) } ; } const deadline = { didTimeout : false , timeRemaining : ( ) => Infinity , } ; const disposable = timer . delay ( ( t ) => fn ( deadline , t ) , 0 ) ; const dispose = ( ) => { disposable . dispose ( ) ; deadline . timeRemaining = ( ) => 0 ; } ; return { dispose } ; }