From 6af5e5e7ce32a58881191d91ff19c0038188e8ce Mon Sep 17 00:00:00 2001 From: Laszlo Racz Date: Wed, 13 Nov 2024 11:26:52 +0100 Subject: [PATCH] feat(api): add caching for GitHub release API response --- src/server/api/update.ts | 70 ++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/src/server/api/update.ts b/src/server/api/update.ts index 84deff3..bc488dd 100644 --- a/src/server/api/update.ts +++ b/src/server/api/update.ts @@ -1,4 +1,8 @@ -import currentPackage from '~~/package.json' +import { ofetch } from 'ofetch' +import { useLogger } from '../utils/logger' + +// Current version - update this during releases +const CURRENT_VERSION = '0.15.4' export interface ReleasesLatest { url: string @@ -40,17 +44,63 @@ export interface ReleasesLatest { body: string } +interface CachedResponse { + data: { + available: boolean + version: string + } + timestamp: number +} + +// Cache duration - 24 hours in milliseconds +const CACHE_DURATION = 24 * 60 * 60 * 1000 + export default defineEventHandler(async () => { - const latestReleases = await $fetch('https://api.github.com/repos/hywax/mafl/releases/latest', { - parseResponse: (json) => JSON.parse(json), - }) - const latestVersion = latestReleases.tag_name.replace('v', '') + const storage = useStorage('updates') + const logger = useLogger('updates') + const now = Date.now() + + // Get cached response from storage + const cachedResponse = await storage.getItem('latest') + + // Return cached response if it's still valid + if (cachedResponse && (now - cachedResponse.timestamp) < CACHE_DURATION) { + logger.debug('Returning cached response:', cachedResponse.data) + return cachedResponse.data + } else { + logger.debug('Fetching latest release:', cachedResponse ? 'cached expired' : 'not cached') + } + + try { + logger.info('Fetching latest release from GitHub') + const latestReleases = await ofetch('https://api.github.com/repos/hywax/mafl/releases/latest') + const latestVersion = latestReleases.tag_name.replace('v', '') + + const parseVersion = (version: string): number => Number.parseInt(version.replace(/\./g, ''), 10) + const difference = parseVersion(latestVersion) - parseVersion(CURRENT_VERSION) + + const response = { + available: difference > 0, + version: latestVersion, + } + + // Cache the response in storage + await storage.setItem('latest', { + data: response, + timestamp: now, + }) - const parseVersion = (version: string): number => Number.parseInt(version.replace(/\./g, ''), 10) - const difference = parseVersion(latestVersion) - parseVersion(currentPackage.version) + return response + } catch (error) { + logger.error('Failed to fetch the latest release from GitHub API:', error) + // If GitHub API fails, return cached response if available, otherwise return no update + if (cachedResponse) { + return cachedResponse.data + } - return { - available: difference > 0, - version: latestVersion, + return { + available: false, + version: CURRENT_VERSION, + } } })