| import requestAnimationFrame from '../shims/requestAnimationFrame.js'; | 
|   | 
| // Defines minimum timeout before adding a trailing call. | 
| const trailingTimeout = 2; | 
|   | 
| /** | 
|  * Creates a wrapper function which ensures that provided callback will be | 
|  * invoked only once during the specified delay period. | 
|  * | 
|  * @param {Function} callback - Function to be invoked after the delay period. | 
|  * @param {number} delay - Delay after which to invoke callback. | 
|  * @returns {Function} | 
|  */ | 
| export default function (callback, delay) { | 
|     let leadingCall = false, | 
|         trailingCall = false, | 
|         lastCallTime = 0; | 
|   | 
|     /** | 
|      * Invokes the original callback function and schedules new invocation if | 
|      * the "proxy" was called during current request. | 
|      * | 
|      * @returns {void} | 
|      */ | 
|     function resolvePending() { | 
|         if (leadingCall) { | 
|             leadingCall = false; | 
|   | 
|             callback(); | 
|         } | 
|   | 
|         if (trailingCall) { | 
|             proxy(); | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * Callback invoked after the specified delay. It will further postpone | 
|      * invocation of the original function delegating it to the | 
|      * requestAnimationFrame. | 
|      * | 
|      * @returns {void} | 
|      */ | 
|     function timeoutCallback() { | 
|         requestAnimationFrame(resolvePending); | 
|     } | 
|   | 
|     /** | 
|      * Schedules invocation of the original function. | 
|      * | 
|      * @returns {void} | 
|      */ | 
|     function proxy() { | 
|         const timeStamp = Date.now(); | 
|   | 
|         if (leadingCall) { | 
|             // Reject immediately following calls. | 
|             if (timeStamp - lastCallTime < trailingTimeout) { | 
|                 return; | 
|             } | 
|   | 
|             // Schedule new call to be in invoked when the pending one is resolved. | 
|             // This is important for "transitions" which never actually start | 
|             // immediately so there is a chance that we might miss one if change | 
|             // happens amids the pending invocation. | 
|             trailingCall = true; | 
|         } else { | 
|             leadingCall = true; | 
|             trailingCall = false; | 
|   | 
|             setTimeout(timeoutCallback, delay); | 
|         } | 
|   | 
|         lastCallTime = timeStamp; | 
|     } | 
|   | 
|     return proxy; | 
| } |