44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
import { onBeforeUnmount, onMounted, ref, type Ref } from "vue";
|
|
|
|
export interface AutoRefreshOptions {
|
|
immediate?: boolean;
|
|
initialDelayMs?: number;
|
|
}
|
|
|
|
export function useAutoRefresh(callback: () => Promise<void> | void, intervalMs = 30_000, options: AutoRefreshOptions = {}): { active: Ref<boolean>; refreshNow: () => Promise<void> } {
|
|
const active = ref(false);
|
|
let intervalTimer: ReturnType<typeof setInterval> | null = null;
|
|
let initialTimer: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
async function refreshNow(): Promise<void> {
|
|
await callback();
|
|
}
|
|
|
|
onMounted(() => {
|
|
active.value = true;
|
|
const startInterval = (): void => {
|
|
if (intervalTimer !== null) return;
|
|
intervalTimer = setInterval(() => void refreshNow(), intervalMs);
|
|
};
|
|
if (options.immediate === false) {
|
|
const delay = Math.max(0, Math.trunc(Number(options.initialDelayMs ?? intervalMs)));
|
|
initialTimer = setTimeout(() => {
|
|
initialTimer = null;
|
|
void refreshNow();
|
|
startInterval();
|
|
}, delay);
|
|
return;
|
|
}
|
|
void refreshNow();
|
|
startInterval();
|
|
});
|
|
|
|
onBeforeUnmount(() => {
|
|
active.value = false;
|
|
if (initialTimer) clearTimeout(initialTimer);
|
|
if (intervalTimer) clearInterval(intervalTimer);
|
|
});
|
|
|
|
return { active, refreshNow };
|
|
}
|