wakatime.js (1761B)
1 const WAKATIME_TTL_MS = 5 * 60 * 1000; 2 3 const wakatimeCache = { 4 data: null, 5 timestamp: 0, 6 pending: null, 7 }; 8 const wakatimeListeners = new Set(); 9 let wakatimeRefreshTimer = 0; 10 let wakatimeRefreshing = null; 11 12 export async function getWakaTimeData(force = false) { 13 if (!force && wakatimeCache.data && isFresh(wakatimeCache.timestamp)) { 14 return wakatimeCache.data; 15 } 16 17 if (wakatimeCache.pending) { 18 return wakatimeCache.pending; 19 } 20 21 wakatimeCache.pending = fetch("/api/wakatime", { credentials: "same-origin" }) 22 .then((res) => (res.ok ? res.json() : null)) 23 .then((data) => { 24 if (data) { 25 wakatimeCache.data = data; 26 wakatimeCache.timestamp = Date.now(); 27 } 28 return data; 29 }) 30 .catch(() => null) 31 .finally(() => { 32 wakatimeCache.pending = null; 33 }); 34 35 return wakatimeCache.pending; 36 } 37 38 export function subscribeWakaTimeRefresh(listener) { 39 if (typeof listener !== "function") { 40 return () => {}; 41 } 42 43 wakatimeListeners.add(listener); 44 return () => { 45 wakatimeListeners.delete(listener); 46 }; 47 } 48 49 export function startWakaTimeRefreshTimer() { 50 if (wakatimeRefreshTimer) return; 51 52 wakatimeRefreshTimer = window.setInterval(() => { 53 void refreshWakaTimeData(); 54 }, WAKATIME_TTL_MS); 55 } 56 57 function isFresh(timestamp) { 58 return Date.now() - timestamp < WAKATIME_TTL_MS; 59 } 60 61 async function refreshWakaTimeData() { 62 if (wakatimeRefreshing) { 63 return wakatimeRefreshing; 64 } 65 66 wakatimeRefreshing = getWakaTimeData(true) 67 .then((data) => { 68 for (const listener of wakatimeListeners) { 69 try { 70 listener(data); 71 } catch {} 72 } 73 74 return data; 75 }) 76 .finally(() => { 77 wakatimeRefreshing = null; 78 }); 79 80 return wakatimeRefreshing; 81 }