feat(reader): add core infrastructure for feature-based architecture

- Add reader-context.ts: defines ReaderContext interface and factory
- Add reader-events.ts: event bus for feature communication
- Add reader-state.ts: centralized state management
- Add reader-navigation.ts: unified navigation and rendering API
- Add reader-services.ts: shared services (progress, chapters)
- Establishes foundation for Feature Registration Pattern
This commit is contained in:
2026-04-04 13:37:47 -04:00
parent 3162d9b7ee
commit 96d90db036
6 changed files with 655 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
import type { ReaderMetadata } from "../../types/reader";
type ReaderType = "ebook" | "pdf" | "comic" | "manga";
interface UniversalReader {
type: "ebook";
cif: any;
currentSpineIndex: number;
}
interface PDFReader {
type: "pdf";
doc: any;
currentPage: number;
}
interface ComicReader {
type: "comic";
images: Blob[];
currentPage: number;
}
interface MangaReader {
type: "manga";
images: Blob[];
currentPage: number;
readingDirection: "rtl" | "vertical";
}
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: string, handler: Function) => readerEvents.on(event, handler),
emit: (event: string, data?: any) => readerEvents.emit(event, data),
},
};
}
import { readerEvents } from "./reader-events";