UNPKG

@discoveryjs/discovery

Version:

Frontend framework for rapid data (JSON) analysis, shareable serverless reports and dashboards

120 lines (119 loc) 3.4 kB
function isObject(value) { return value !== null && (typeof value === "object" || typeof value === "function"); } export function debounce(func, options) { if (typeof func !== "function") { throw new TypeError("Expected a function"); } if (typeof options === "number") { options = { wait: options }; } if (!isObject(options)) { let result2; return Object.assign(function(...args) { return result2 = func.apply(this, args); }, { cancel() { }, flush() { return result2; }, pending() { return false; } }); } const wait = Math.max(0, Number(options.wait) || 0); const leading = Boolean(options.leading); const maxing = "maxWait" in options; const maxWait = maxing ? Math.max(Number(options.maxWait) || 0, wait) : Infinity; const trailing = "trailing" in options ? Boolean(options.trailing) : true; let lastArgs; let lastThis; let result; let timerId; let lastCallTime; let lastInvokeTime = 0; function invokeFunc(time) { const args = lastArgs; const thisArg = lastThis; lastArgs = lastThis = void 0; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function startTimer(pendingFunc, wait2) { return setTimeout(pendingFunc, wait2); } function cancelTimer(id) { clearTimeout(id); } function leadingEdge(time) { lastInvokeTime = time; timerId = startTimer(timerExpired, wait); return leading ? invokeFunc(time) : result; } function remainingWait(time, lastCallTime2) { const timeSinceLastCall = time - lastCallTime2; const timeSinceLastInvoke = time - lastInvokeTime; const timeWaiting = wait - timeSinceLastCall; return Math.min(timeWaiting, maxWait - timeSinceLastInvoke); } function shouldInvoke(time, lastCallTime2) { const timeSinceLastCall = time - lastCallTime2; const timeSinceLastInvoke = time - lastInvokeTime; return timeSinceLastCall >= wait || timeSinceLastCall < 0 || timeSinceLastInvoke >= maxWait; } function timerExpired() { const time = Date.now(); if (lastCallTime === void 0 || shouldInvoke(time, lastCallTime)) { return trailingEdge(time); } timerId = startTimer(timerExpired, remainingWait(time, lastCallTime)); } function trailingEdge(time) { timerId = void 0; if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = void 0; return result; } function cancel() { if (timerId !== void 0) { cancelTimer(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = void 0; } function flush() { return timerId === void 0 ? result : trailingEdge(Date.now()); } function pending() { return timerId !== void 0; } return Object.assign(function(...args) { const time = Date.now(); const isInvoking = lastCallTime === void 0 || shouldInvoke(time, lastCallTime); lastArgs = args; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === void 0) { return leadingEdge(lastCallTime); } if (maxing) { timerId = startTimer(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === void 0) { timerId = startTimer(timerExpired, wait); } return result; }, { cancel, flush, pending }); }