UNPKG

@thepassle/app-tools

Version:

Collection of tools I regularly use to build apps. Maybe they're useful to somebody else. Maybe not. Most of these are thin wrappers around native API's, like the native `<dialog>` element, `fetch` API, and `URLPattern`.

80 lines (72 loc) 1.87 kB
export function debounce(f, scheduleTask, cancelTask) { let task; return (...args) => { cancelTask(task); task = scheduleTask(() => { task = null; f(...args); }); }; } export const debounceAtTimeout = (f, ms) => debounce(f, task => setTimeout(task, ms), clearTimeout); export const debounceAtFrame = (f) => debounce(f, requestAnimationFrame, cancelAnimationFrame); /** * @returns {Promise<number>} */ export const onePaint = () => new Promise(r => requestAnimationFrame(r)); /** * @param {HTMLElement} element * @returns {Promise<PromiseSettledResult<Animation>[]>} */ export const animationsComplete = element => Promise.allSettled(element.getAnimations().map(animation => animation.finished)); /** * @param {() => void} f * @param {number} ms * @param {{ * signal?: AbortSignal * }} options */ export function setAbortableTimeout(f, ms, {signal}) { let t; if(!signal?.aborted) { t = setTimeout(f, ms); } signal?.addEventListener('abort', () => clearTimeout(t), {once: true}); }; /** * @param {() => boolean} predicate * @param {{ * timeout?: number, * message?: string, * interval?: number * }} options * @returns {Promise<void>} */ export function waitUntil(predicate, options = {}) { const { timeout = 1000, message = `waitUntil timed out after ${timeout}ms`, interval = 50, } = options; return new Promise((resolve, reject) => { let timeoutId; setTimeout(() => { clearTimeout(timeoutId); reject(new Error(message)); }, timeout); async function nextInterval() { try { if (await predicate()) { resolve(); } else { timeoutId = setTimeout(() => { nextInterval(); }, interval); } } catch (error) { reject(error); } } nextInterval(); }); }