import { computed, onMounted, onUnmounted, readonly, shallowRef } from "vue"; import { createPreviewRuntimeSnapshot } from "../mock/runtime-preview"; import type { DesktopRuntimeSnapshot } from "../types"; const snapshot = shallowRef(null); const loading = shallowRef(false); const error = shallowRef(null); let intervalHandle: ReturnType | null = null; let subscribers = 0; async function refreshRuntimeSnapshot() { loading.value = true; error.value = null; try { if (window.desktopBridge?.app?.runtimeSnapshot) { snapshot.value = await window.desktopBridge.app.runtimeSnapshot(); return; } snapshot.value = createPreviewRuntimeSnapshot(); } catch (err) { error.value = err instanceof Error ? err.message : "runtime snapshot unavailable"; } finally { loading.value = false; } } function startPolling() { if (intervalHandle) { return; } intervalHandle = setInterval(() => { void refreshRuntimeSnapshot(); }, 15_000); } function stopPolling() { if (subscribers > 0 || !intervalHandle) { return; } clearInterval(intervalHandle); intervalHandle = null; } export function useDesktopRuntime() { onMounted(() => { subscribers += 1; if (!snapshot.value && !loading.value) { void refreshRuntimeSnapshot(); } startPolling(); }); onUnmounted(() => { subscribers = Math.max(0, subscribers - 1); stopPolling(); }); return { snapshot: readonly(snapshot), loading: readonly(loading), error: readonly(error), refresh: refreshRuntimeSnapshot, hasSnapshot: computed(() => snapshot.value !== null), }; }