@adaptabletools/adaptable-cjs
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
125 lines (124 loc) • 3.85 kB
JavaScript
;
/**
* Creates a debounced function that delays invoking func until after wait
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a cancel method to cancel
* delayed func invocations and a flush method to immediately invoke them.
*
* Supports options: { leading, trailing, maxWait }
* Drop-in replacement for lodash/debounce.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = debounce;
function debounce(func, wait = 0, options) {
let lastArgs;
let lastThis;
let result;
let timerId;
let lastCallTime;
let lastInvokeTime = 0;
const leading = options?.leading ?? false;
const trailing = options?.trailing ?? true;
const maxWait = options?.maxWait;
const hasMaxWait = maxWait !== undefined;
const maxing = hasMaxWait;
function invokeFunc(time) {
const args = lastArgs;
const thisArg = lastThis;
lastArgs = undefined;
lastThis = undefined;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function startTimer(pendingFunc, waitMs) {
timerId = setTimeout(pendingFunc, waitMs);
}
function cancelTimer() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
timerId = undefined;
}
function remainingWait(time) {
const timeSinceLastCall = time - (lastCallTime ?? 0);
const timeSinceLastInvoke = time - lastInvokeTime;
const timeWaiting = wait - timeSinceLastCall;
return maxing
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting;
}
function shouldInvoke(time) {
const timeSinceLastCall = time - (lastCallTime ?? 0);
const timeSinceLastInvoke = time - lastInvokeTime;
return (lastCallTime === undefined ||
timeSinceLastCall >= wait ||
timeSinceLastCall < 0 ||
(maxing && timeSinceLastInvoke >= maxWait));
}
function timerExpired() {
const time = Date.now();
if (shouldInvoke(time)) {
trailingEdge(time);
return;
}
// Restart the timer
startTimer(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
if (trailing && lastArgs) {
invokeFunc(time);
}
else {
lastArgs = undefined;
lastThis = undefined;
}
}
function leadingEdge(time) {
lastInvokeTime = time;
startTimer(timerExpired, wait);
if (leading) {
invokeFunc(time);
}
}
function debounced(...args) {
const time = Date.now();
const isInvoking = shouldInvoke(time);
lastArgs = args;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === undefined) {
leadingEdge(time);
return result;
}
if (maxing) {
// Handle invocations in a tight loop with maxWait
cancelTimer();
startTimer(timerExpired, wait);
invokeFunc(time);
return result;
}
}
if (timerId === undefined) {
startTimer(timerExpired, wait);
}
return result;
}
debounced.cancel = function cancel() {
cancelTimer();
lastInvokeTime = 0;
lastArgs = undefined;
lastCallTime = undefined;
lastThis = undefined;
};
debounced.flush = function flush() {
if (timerId === undefined) {
return result;
}
trailingEdge(Date.now());
return result;
};
return debounced;
}