import { getManga, getSimilarMangas, type MangaCard } from '$lib/api/mangas'; import { listChapters } from '$lib/api/chapters'; import { listMyBookmarksOrEmpty } from '$lib/api/bookmarks'; import { getMyReadProgressForManga } from '$lib/api/read_progress'; import { getMyReactionForManga } from '$lib/api/reactions'; import type { PageLoad } from './$types'; import type { DetailData } from './types'; export const ssr = false; export const load: PageLoad = ({ params }) => { // Streamed (the load doesn't await) so the page renders a // MangaDetailSkeleton while the bundle loads instead of blocking // navigation on all six calls. A getManga 404 / any hard failure rejects // the bundle and is handled by the page's {:catch}. const bundle: Promise = Promise.all([ getManga(params.id), listChapters(params.id), listMyBookmarksOrEmpty(), // Null when guest or never-read — the page handles both cases. getMyReadProgressForManga(params.id), // Non-critical: any failure degrades to an unset toggle, never a // broken page. getMyReactionForManga(params.id).catch(() => null), // Recommendations are non-critical: fall back to an empty list. getSimilarMangas(params.id).catch(() => [] as MangaCard[]) ]).then(([manga, chapters, bookmarks, readProgress, reaction, similar]) => ({ manga, chapters: chapters.items, bookmarks: bookmarks.items, readProgress, reaction, similar })); return { bundle }; };