/** * 首页"最近心跳":构建期拉 blog 仓最新 commit——本站自己的脉搏。 * 失败静默(返回 null,首页渲染"很久以前"兜底文案),绝不阻塞构建。 */ export interface Heartbeat { /** commit 首行(截 40 字符) */ msg: string; /** commit 时间(ISO) */ when: string; } const API = 'https://git.wait4x.online/api/v1/repos/wait4x/blog/commits?limit=1'; export async function fetchHeartbeat(): Promise { try { const res = await fetch(API, { headers: { Accept: 'application/json', 'User-Agent': 'wait4x-blog-build' }, signal: AbortSignal.timeout(8_000), }); if (!res.ok) return null; const [c] = (await res.json()) as Array<{ commit?: { message?: string; author?: { date?: string } } }>; const msg = c?.commit?.message?.split('\n')[0]?.slice(0, 40); const when = c?.commit?.author?.date; return msg && when ? { msg, when } : null; } catch { return null; } } /** 相对时长(中文短句;en 页由调用方换词条) */ export function agoZh(iso: string, now = Date.now()): string { const h = Math.floor((now - new Date(iso).getTime()) / 3_600_000); if (h < 1) return '刚刚'; if (h < 24) return `${h} 小时前`; const d = Math.floor(h / 24); if (d < 30) return `${d} 天前`; return `${Math.floor(d / 30)} 个月前`; }