@modern-kit/utils
Version:
85 lines (82 loc) • 1.96 kB
JavaScript
;
function debounce(func, wait, options = {}) {
let pendingThis = void 0;
let pendingArgs = null;
let pendingAt = null;
let timeoutId = null;
const { signal, leading = false, trailing = true, maxWait } = options;
const invoke = () => {
if (pendingArgs != null) {
func.apply(pendingThis, pendingArgs);
pendingThis = void 0;
pendingArgs = null;
pendingAt = null;
}
};
const onTimerEnd = () => {
if (trailing) {
invoke();
}
cancel();
};
const getWaitTime = () => {
if (typeof maxWait === "number" && pendingAt != null) {
const timeSinceFirstCall = Date.now() - pendingAt;
const remainingMaxWait = maxWait - timeSinceFirstCall;
if (remainingMaxWait <= 0) {
onTimerEnd();
return;
}
return Math.min(wait, remainingMaxWait);
}
return wait;
};
const schedule = () => {
if (timeoutId != null) {
clearTimeout(timeoutId);
}
const waitTime = getWaitTime();
timeoutId = setTimeout(() => {
timeoutId = null;
onTimerEnd();
}, waitTime);
};
const cancelTimer = () => {
if (timeoutId != null) {
clearTimeout(timeoutId);
timeoutId = null;
}
};
const cancel = () => {
cancelTimer();
pendingThis = void 0;
pendingArgs = null;
pendingAt = null;
};
const flush = () => {
cancelTimer();
invoke();
pendingAt = null;
};
const debounced = function(...args) {
if (signal?.aborted) {
return;
}
pendingThis = this;
pendingArgs = args;
const isFirstCall = timeoutId == null;
if (isFirstCall) {
pendingAt = Date.now();
}
schedule();
if (leading && isFirstCall) {
invoke();
}
};
debounced.cancel = cancel;
debounced.flush = flush;
signal?.addEventListener("abort", cancel, { once: true });
return debounced;
}
exports.debounce = debounce;
//# sourceMappingURL=index.cjs.map