64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import { ref } from "vue";
|
||
import * as api from "@/lib/backend/api";
|
||
import { beginMcpStatusRequest, isLatestMcpStatusRequest, mcpUpdateAvailability } from "@/lib/mcp/mcpUpdateStatus";
|
||
|
||
interface UseMcpUpdateBadgeOptions {
|
||
isDesktop: boolean;
|
||
updateNotificationsEnabled: () => boolean;
|
||
}
|
||
|
||
/**
|
||
* MCP server 更新徽章状态。
|
||
*
|
||
* 照搬 app/驱动两套 badge 模式:后台 silent 轮询 + computed 驱动红点 + 事件回传。
|
||
* 通过递增请求序号忽略过期响应,避免“定时检查旧请求晚返回、覆盖升级后新结果”的竞态。
|
||
*/
|
||
export function useMcpUpdateBadge(options: UseMcpUpdateBadgeOptions) {
|
||
const mcpUpdateAvailable = ref(false);
|
||
|
||
async function refreshMcpUpdateStatus() {
|
||
if (!options.isDesktop || !options.updateNotificationsEnabled()) return;
|
||
const requestId = beginMcpStatusRequest();
|
||
try {
|
||
const status = await api.checkMcpServerStatus();
|
||
if (!isLatestMcpStatusRequest(requestId)) return;
|
||
if (!options.updateNotificationsEnabled()) return;
|
||
const updateAvailable = mcpUpdateAvailability(status);
|
||
if (updateAvailable !== null) mcpUpdateAvailable.value = updateAvailable;
|
||
} catch {
|
||
// MCP 状态仅作徽章提示;取不到就保持原值,不打扰用户。
|
||
}
|
||
}
|
||
|
||
/**
|
||
* EditorSettingsDialog 刷新/升级后通过事件回传已获取的 update_available,
|
||
* 避免根组件重复查询 npm registry,同时使在途的定时检查失效。
|
||
*/
|
||
function applyMcpStatus(updateAvailable: boolean, requestId?: number) {
|
||
if (requestId !== undefined) {
|
||
if (!isLatestMcpStatusRequest(requestId)) return;
|
||
} else {
|
||
beginMcpStatusRequest();
|
||
}
|
||
mcpUpdateAvailable.value = updateAvailable;
|
||
}
|
||
|
||
function handleMcpStatusChanged(event: Event) {
|
||
const detail = (event as CustomEvent<{ updateAvailable?: boolean | null; requestId?: number } | null | undefined>).detail;
|
||
if (detail && typeof detail.updateAvailable === "boolean") {
|
||
applyMcpStatus(detail.updateAvailable, detail.requestId);
|
||
} else if (detail && typeof detail.requestId === "number") {
|
||
return;
|
||
} else {
|
||
void refreshMcpUpdateStatus();
|
||
}
|
||
}
|
||
|
||
return {
|
||
mcpUpdateAvailable,
|
||
refreshMcpUpdateStatus,
|
||
handleMcpStatusChanged,
|
||
applyMcpStatus,
|
||
};
|
||
}
|