diff --git a/app/components/home/live/Stats.vue b/app/components/home/live/Stats.vue index 6674337..13490a6 100644 --- a/app/components/home/live/Stats.vue +++ b/app/components/home/live/Stats.vue @@ -2,9 +2,7 @@ import type { Stats } from '~~/types' import { usePrecision } from '@vueuse/math' -const { data: stats } = await useAsyncData('stats', () => $fetch('/api/stats'), { - lazy: true -}) +const { data: stats } = await useAsyncData('stats', () => $fetch('/api/stats')) const startDate = computed(() => new Date(stats.value!.coding.range.start)) const yearsCollected = useTimeAgo(startDate).value diff --git a/server/api/stats.get.ts b/server/api/stats.get.ts index b042cd2..fb9e00b 100644 --- a/server/api/stats.get.ts +++ b/server/api/stats.get.ts @@ -1,42 +1,56 @@ import type { H3Event } from 'h3' +const WAKATIME_HEADERS = { + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + 'Accept': 'application/json' +} + +const fetchWakatime = async (url: string) => { + try { + return await $fetch<{ data: unknown[] }>(url, { + headers: WAKATIME_HEADERS, + timeout: 5000 + }) + } + catch (err) { + console.error(`[Wakatime Error] Failed to fetch ${url}`, err) + return { data: [] } + } +} + const cachedWakatimeCoding = defineCachedFunction(async (event: H3Event) => { const config = useRuntimeConfig(event) - - return await $fetch<{ data: unknown[] }>(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.coding}.json`) + return await fetchWakatime(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.coding}.json`) }, { - maxAge: 60, - name: 'wakatime', + maxAge: 60 * 50, + name: 'wakatime:coding', getKey: () => 'coding' }) const cachedWakatimeEditors = defineCachedFunction(async (event: H3Event) => { const config = useRuntimeConfig(event) - - return await $fetch<{ data: unknown[] }>(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.editors}.json`) + return await fetchWakatime(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.editors}.json`) }, { - maxAge: 60, - name: 'wakatime', + maxAge: 60 * 60, + name: 'wakatime:editors', getKey: () => 'editors' }) const cachedWakatimeOs = defineCachedFunction(async (event: H3Event) => { const config = useRuntimeConfig(event) - - return await $fetch<{ data: unknown[] }>(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.os}.json`) + return await fetchWakatime(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.os}.json`) }, { - maxAge: 60, - name: 'wakatime', + maxAge: 60 * 60, + name: 'wakatime:os', getKey: () => 'os' }) const cachedWakatimeLanguages = defineCachedFunction(async (event: H3Event) => { const config = useRuntimeConfig(event) - - return await $fetch<{ data: unknown[] }>(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.languages}.json`) + return await fetchWakatime(`https://wakatime.com/share/${config.wakatime.userId}/${config.wakatime.languages}.json`) }, { - maxAge: 60, - name: 'wakatime', + maxAge: 60 * 60, + name: 'wakatime:languages', getKey: () => 'languages' })