// requestIdleCallback sortof-polyfill if (!self.requestIdleCallback) { const IDLE_TIMEOUT = 10; self.requestIdleCallback = cb => { let start = Date.now(); return setTimeout( () => cb({ timeRemaining: () => Math.max(0, IDLE_TIMEOUT - (Date.now() - start)) }), 1 ); }; self.requestIdleCallback = clearTimeout; } export function backgroundTask(fn, timeout = undefined) { let id = null; const params = []; async function runTask({ didTimeout }) { if (didTimeout) { id = requestIdleCallback(runTask); return; } const start = Date.now(); const p = params.shift(); await fn(...p); if (params.length) { id = requestIdleCallback(runTask, { timeout }); } else { id = null; } } const wrapper = (...args) => { params.push(args); if (id !== null) { return false; } id = requestIdleCallback(runTask, { timeout }); return true; }; return wrapper; }