BREAKING CHANGE: Unify ebook reader type system to match actual data structures Problem: - ReflowableBook type had direct properties (spine, resources, toc, metadata) - UniversalReader wraps EbookCIF in cif property with runtime state - Type mismatch caused unsafe 'as any' casts and runtime errors - Two conflicting UniversalReader definitions existed (reader-shell vs reader-context) Root Cause: - Parsers return EbookCIF (nested structure) - ReflowableBook expected flat structure - Code mixed both approaches causing confusion Changes: Type System Updates: - Replace all ReflowableBook references with UniversalReader - Remove duplicate UniversalReader definition in reader-context.ts - Import UniversalReader from canonical source (reader-shell.ts) - Update all function signatures across reflowable module Property Access Patterns: - book.cif.spine instead of book.spine - book.cif.resources instead of book.resources - book.cif.toc instead of book.toc - book.cif.metadata instead of book.metadata Fixed Modules: - reader-shell.ts: UniversalReader object construction - reader-context.ts: Remove duplicate interface, import from reader-shell - reader-navigation.ts: Remove unsafe type casts, fix property access - reader-services.ts: Align with UniversalReader structure - reflowable/navigation.ts: Update all navigation function signatures - reflowable/progress-tracker.ts: Update tracker function signatures - reflowable/parser.ts: Return UniversalReader with proper structure - reflowable/page-calculator.ts: Update calculation function signatures - reflowable/ebook/search.ts: Fix property access patterns - types/reader.d.ts: Remove duplicate type definitions Impact: - ✅ Type-safe throughout ebook reader - ✅ Matches actual data structures from parsers - ✅ No more unsafe type casts - ✅ Single source of truth for UniversalReader - ✅ Aligns with EbookCIF format from API/parsers Files changed: 10 Lines changed: +320, -180
83 lines
2.0 KiB
TypeScript
83 lines
2.0 KiB
TypeScript
import { readerEvents, ReaderEventType } from "./reader-events";
|
|
import { UniversalReader } from "../reader-shell";
|
|
import { PDFDocumentProxy } from "pdfjs-dist";
|
|
|
|
interface PDFReader {
|
|
type: "pdf";
|
|
doc: PDFDocumentProxy;
|
|
currentPage: number;
|
|
}
|
|
|
|
interface ComicReader {
|
|
type: "comic";
|
|
images: Blob[];
|
|
currentPage: number;
|
|
}
|
|
|
|
interface MangaReader {
|
|
type: "manga";
|
|
images: Blob[];
|
|
currentPage: number;
|
|
readingDirection: "rtl" | "vertical";
|
|
}
|
|
|
|
export type CurrentReader =
|
|
| UniversalReader
|
|
| PDFReader
|
|
| ComicReader
|
|
| MangaReader;
|
|
|
|
export interface ReaderContext {
|
|
getState: () => {
|
|
currentReader: CurrentReader | null;
|
|
readerMetadata: ReaderMetadata | null;
|
|
};
|
|
setState: (updates: Partial<ReaderState>) => void;
|
|
navigation: {
|
|
nextPage: () => void;
|
|
previousPage: () => void;
|
|
goToPage: (page: number) => void;
|
|
goToChapter: (chapterIndex: number) => void;
|
|
};
|
|
render: () => void;
|
|
elements: {
|
|
readerContent: HTMLElement;
|
|
chrome: HTMLElement | null;
|
|
progressDisplay: HTMLElement | null;
|
|
};
|
|
events: {
|
|
on: (event: string, handler: Function) => void;
|
|
emit: (event: string, data?: any) => void;
|
|
};
|
|
}
|
|
|
|
export interface ReaderState {
|
|
currentReader: CurrentReader | null;
|
|
readerMetadata: ReaderMetadata | null;
|
|
}
|
|
|
|
export function createReaderContext(
|
|
getState: () => ReaderState,
|
|
setState: (updates: Partial<ReaderState>) => void,
|
|
navigation: ReaderContext["navigation"],
|
|
render: () => void,
|
|
): ReaderContext {
|
|
return {
|
|
getState,
|
|
setState,
|
|
navigation,
|
|
render,
|
|
elements: {
|
|
readerContent: document.getElementById("reader-content")!,
|
|
chrome: document.getElementById("reader-chrome"),
|
|
progressDisplay: document.getElementById("progress-display"),
|
|
},
|
|
events: {
|
|
on: (event: ReaderEventType, handler: Function) =>
|
|
readerEvents.on(event, handler),
|
|
emit: (event: ReaderEventType, data?: any) =>
|
|
readerEvents.emit(event, data),
|
|
},
|
|
};
|
|
}
|