@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
123 lines (122 loc) • 3.55 kB
JavaScript
export 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;
}
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) {
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;
}
export function throttle(func, wait = 0, options) {
return debounce(func, wait, {
leading: options?.leading ?? true,
trailing: options?.trailing ?? true,
maxWait: wait,
});
}
export const TimingHelper = {
debounce,
throttle,
};
export default TimingHelper;