Files
plane/apps/web/core/lib/idle-task.ts

55 lines
1.7 KiB
TypeScript
Raw Permalink Normal View History

/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
export type IdleTaskHandle = {
cancel: () => void;
};
const requestIdleFallback = (callback: IdleRequestCallback, options?: IdleRequestOptions): number => {
const start = Date.now();
return globalThis.setTimeout(() => {
callback({
didTimeout: false,
timeRemaining: () => Math.max(0, 50 - (Date.now() - start)),
});
}, options?.timeout ?? 1) as unknown as number;
};
const cancelIdleFallback = (id: number) => {
globalThis.clearTimeout(id);
};
export const requestIdle = (callback: IdleRequestCallback, options?: IdleRequestOptions): number => {
if (typeof globalThis.requestIdleCallback === "function") return globalThis.requestIdleCallback(callback, options);
return requestIdleFallback(callback, options);
};
export const cancelIdle = (id: number) => {
if (typeof globalThis.cancelIdleCallback === "function") return globalThis.cancelIdleCallback(id);
return cancelIdleFallback(id);
};
export const installIdleCallbackPolyfill = () => {
if (typeof globalThis === "undefined") return;
globalThis.requestIdleCallback = globalThis.requestIdleCallback ?? requestIdleFallback;
globalThis.cancelIdleCallback = globalThis.cancelIdleCallback ?? cancelIdleFallback;
};
/**
* Schedule lightweight work for idle time and return a cancel handle.
* Falls back to setTimeout when requestIdleCallback is unavailable.
*/
export const runIdleTask = (callback: IdleRequestCallback): IdleTaskHandle => {
const idleId = requestIdle(callback, { timeout: 300 });
return {
cancel: () => cancelIdle(idleId),
};
};