- image-gen, text-gen: books list streamed (listBooks is expensive on cold cache) - ai-jobs: jobs list streamed; add 30s cache to listAIJobs (was uncached listAll) - changelog: Gitea releases streamed on cold cache; cached path stays synchronous - admin/+layout.svelte: remove duplicate audio/translation/image-gen nav links
45 lines
1.3 KiB
TypeScript
45 lines
1.3 KiB
TypeScript
import type { PageServerLoad } from './$types';
|
|
import * as cache from '$lib/server/cache';
|
|
|
|
export interface Release {
|
|
id: number;
|
|
tag_name: string;
|
|
name: string;
|
|
body: string;
|
|
published_at: string;
|
|
prerelease: boolean;
|
|
draft: boolean;
|
|
}
|
|
|
|
const GITEA_RELEASES_URL =
|
|
'https://gitea.kalekber.cc/api/v1/repos/kamil/libnovel/releases?limit=50&page=1';
|
|
|
|
const CACHE_KEY = 'admin:changelog:releases';
|
|
const CACHE_TTL = 5 * 60; // 5 minutes
|
|
|
|
export const load: PageServerLoad = async ({ fetch }) => {
|
|
// Return cached data synchronously (no streaming needed — already fast).
|
|
const cached = await cache.get<Release[]>(CACHE_KEY);
|
|
if (cached) {
|
|
return { releases: cached, error: undefined as string | undefined };
|
|
}
|
|
|
|
// Cache miss: stream the external Gitea request so navigation isn't blocked.
|
|
const releasesPromise = (async () => {
|
|
try {
|
|
const res = await fetch(GITEA_RELEASES_URL, {
|
|
headers: { Accept: 'application/json' }
|
|
});
|
|
if (!res.ok) return [] as Release[];
|
|
const releases: Release[] = await res.json();
|
|
const filtered = releases.filter((r) => !r.draft);
|
|
await cache.set(CACHE_KEY, filtered, CACHE_TTL);
|
|
return filtered;
|
|
} catch {
|
|
return [] as Release[];
|
|
}
|
|
})();
|
|
|
|
return { releases: releasesPromise, error: undefined as string | undefined };
|
|
};
|