// Import types and existing parsers import type { TOCItem } from "./types"; import { parseEPUB } from "../../parsers/epub-parsers"; import { parseFB2 } from "../../parsers/fb2-parser"; import { parseTXT } from "../../parsers/txt-parser"; import { parseHTML } from "../../parsers/html-parser"; import { UniversalReader } from "../../reader-shell"; // Parse any reflowable format export async function parseReflowable( file: File, format: "epub" | "fb2" | "txt" | "html", ): Promise { switch (format) { case "epub": { const cif = await parseEPUB(file); // Get EbookCIF return { // Wrap in UniversalReader structure type: "ebook", cif, // ← The EbookCIF goes here currentSpineIndex: 0, currentPage: 1, pagination: null, position: { currentPage: 1, spineIndex: 0, localPageIndex: 0, cfi: "", progress: 0, }, }; } case "fb2": { const cif = await parseFB2(file); return { type: "ebook", cif, currentSpineIndex: 0, currentPage: 1, pagination: null, position: { currentPage: 1, spineIndex: 0, localPageIndex: 0, cfi: "", progress: 0, }, }; } case "txt": { const cif = await parseTXT(file); return { type: "ebook", cif, currentSpineIndex: 0, currentPage: 1, pagination: null, position: { currentPage: 1, spineIndex: 0, localPageIndex: 0, cfi: "", progress: 0, }, }; } case "html": { const cif = await parseHTML(file); return { type: "ebook", cif, currentSpineIndex: 0, currentPage: 1, pagination: null, position: { currentPage: 1, spineIndex: 0, localPageIndex: 0, cfi: "", progress: 0, }, }; } default: throw new Error(`Unsupported reflowable format: ${format}`); } } // Validate parsed book data export function validateBook(book: UniversalReader): boolean { return book.cif.spine.length > 0 && book.cif.metadata.title !== ""; } // Get book title export function getBookTitle(book: UniversalReader): string { return book.cif.metadata.title || "Untitled"; } // Get book author export function getBookAuthor(book: UniversalReader): string { return book.cif.metadata.author || "Unknown"; } // Get total spine count export function getSpineCount(book: UniversalReader): number { return book.cif.spine.length; } // Get TOC as flat list export function getFlatTOC(book: UniversalReader): TOCItem[] { const flat: TOCItem[] = []; function traverse(items: TOCItem[]) { for (const item of items) { flat.push(item); if (item.children.length > 0) { traverse(item.children); } } } traverse(book.cif.toc); return flat; }