import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; import { listBooks, allProgress, getSavedSlugs } from '$lib/server/pocketbase'; import { log } from '$lib/server/logger'; /** * GET /api/library * Returns the user's library: books they have started reading or explicitly saved. * Each item includes the book record, the last chapter read, and saved_at timestamp. * * Response shape mirrors LibraryItem in the iOS APIClient. */ export const GET: RequestHandler = async ({ locals }) => { let allBooks: Awaited>; let progressList: Awaited>; let savedSlugs: Set; try { [allBooks, progressList, savedSlugs] = await Promise.all([ listBooks(), allProgress(locals.sessionId, locals.user?.id), getSavedSlugs(locals.sessionId, locals.user?.id) ]); } catch (e) { log.error('api/library', 'failed to load library data', { err: String(e) }); allBooks = []; progressList = []; savedSlugs = new Set(); } const progressMap: Record = {}; const progressUpdatedMap: Record = {}; for (const p of progressList) { progressMap[p.slug] = p.chapter; progressUpdatedMap[p.slug] = p.updated; } const progressSlugs = new Set(progressList.map((p) => p.slug)); const books = allBooks.filter((b) => progressSlugs.has(b.slug) || savedSlugs.has(b.slug)); const withProgress = books.filter((b) => progressSlugs.has(b.slug)); const savedOnly = books .filter((b) => !progressSlugs.has(b.slug)) .sort((a, b) => (a.title ?? '').localeCompare(b.title ?? '')); withProgress.sort((a, b) => { const ta = progressUpdatedMap[a.slug] ?? ''; const tb = progressUpdatedMap[b.slug] ?? ''; return tb.localeCompare(ta); }); const ordered = [...withProgress, ...savedOnly]; const items = ordered.map((book) => ({ book, last_chapter: progressMap[book.slug] ?? null, saved_at: progressUpdatedMap[book.slug] ?? new Date().toISOString() })); return json(items); };