@nesvet/n
Version:
Various utilities
107 lines • 3.33 kB
JavaScript
import { noop } from "./noop.js";
import { StatefulPromise } from "./StatefulPromise.js";
export function debounce(callback, limit = 0, options = {}) {
let { leading = false, trailing = true } = options;
const { maxWait = Infinity } = options;
let timeout;
let maxWaitTimeout;
let end;
let context;
let args;
let initial;
let final;
let result;
const expired = async () => {
const n = Date.now();
if (n >= end) {
timeout = undefined;
end = undefined;
clearTimeout(maxWaitTimeout);
maxWaitTimeout = undefined;
if (typeof final == "function")
await final();
debounced.resolve(result);
initial = leading;
}
else {
clearTimeout(timeout);
timeout = setTimeout(expired, end - n);
}
};
const maxWaitExpired = Number.isFinite(maxWait) ? () => {
if (final === run)
final = false;
run();
maxWaitTimeout = setTimeout(maxWaitExpired, maxWait);
} : null;
async function run() {
try {
result = await callback.apply(context, args);
return result;
}
catch (error) {
debounced.reject(error);
throw error;
}
}
if (leading && typeof leading == "boolean")
leading = run;
initial = leading;
if (trailing && typeof trailing == "boolean")
trailing = run;
final = trailing;
const debounced = Object.assign(function (..._args) {
args = _args;
context = this; // eslint-disable-line no-invalid-this
end = Date.now() + limit;
final = trailing;
if (!debounced.promise.isPending)
debounced.promise = new StatefulPromise((resolve, reject) => {
debounced.resolve = resolve;
debounced.reject = reject;
if (typeof initial == "function") {
initial();
initial = false;
if (final === run)
final = false;
}
if (!timeout) {
timeout = setTimeout(expired, limit);
if (maxWaitExpired)
maxWaitTimeout = setTimeout(maxWaitExpired, maxWait);
}
});
return debounced.promise;
}, {
callback,
promise: StatefulPromise.resolved(undefined),
resolve: noop,
reject: noop,
run,
clear: async (shouldRun) => {
clearTimeout(timeout);
timeout = undefined;
clearTimeout(maxWaitTimeout);
maxWaitTimeout = undefined;
debounced.resolve(shouldRun ? await run() : result);
}
});
return debounced;
}
debounce.noop = Object.assign(() => { }, {
callback: noop,
promise: StatefulPromise.resolved(undefined), // eslint-disable-line unicorn/no-useless-undefined
resolve: noop,
reject: noop,
run: noop,
clear: noop
});
export function throttle(callback, limit, options) {
return debounce(callback, limit, {
maxWait: limit,
leading: true,
trailing: true,
...options
});
}
//# sourceMappingURL=debounce.js.map