/** * @param {number} ms */ export function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } export function next() { return sleep(0); } /** * * @template {(...args: any[]) => any} F * @param {F} callback * @param {number} [wait] */ export function throttle(callback, wait = 1000) { /** @type {number | null} */ let timeoutId = null; /** @type {Parameters} */ let latestArgs; let hasTrailing = false; return (/** @type {Parameters} */ ...args) => { latestArgs = args; if (timeoutId) { hasTrailing = true; return; } callback(...latestArgs); timeoutId = setTimeout(() => { timeoutId = null; if (hasTrailing) { hasTrailing = false; callback(...latestArgs); } }, wait); }; } /** * @template {(...args: any[]) => any} F * @param {F} callback * @param {number} [wait] */ export function debounce(callback, wait = 1000) { /** @type {number | null} */ let timeoutId = null; return (/** @type {Parameters} */ ...args) => { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { callback(...args); timeoutId = null; }, wait); }; }