fix(web,api): lecteur — worker pdf.js dédié, shell commun et préférences par livre

Régression worker PDF : le worker pdf.js est désormais instancié une
seule fois via un port dédié (?worker&url) et reconfiguré à chaque
montage, au lieu d'un workerSrc recalculé qui cassait le rendu.

- ReaderShell : chrome commun aux lecteurs (toolbar, zones de tap,
  statut) et contrat ReaderControls pour EPUB/PDF/CBZ
- préférences de lecture par livre (mode horizontal/vertical, fit) :
  table reader_preferences + migrations idempotentes, module API,
  DTO partagés, client web avec fallback localStorage hors-ligne

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Git Agent
2026-08-23 18:06:22 +02:00
parent 8024cab11c
commit 5de46a6f6d
19 changed files with 790 additions and 89 deletions

View File

@ -1,6 +1,6 @@
import { describe, expect, it } from "vitest";
import { epubFileName } from "./EpubReader";
import { pdfWorkerSrc } from "./pdfWorker";
import { configurePdfWorker, pdfWorkerSrc } from "./pdfWorker";
import { readerErrorMessage } from "./ReaderError";
describe("reader runtime helpers", () => {
@ -9,10 +9,23 @@ describe("reader runtime helpers", () => {
expect(epubFileName("http://readabook.local/files/example.epub")).toBe("example.epub");
});
it("keeps PDF.js worker source on the bundled module worker", () => {
it("keeps PDF.js worker fallback source on the bundled module worker", () => {
expect(pdfWorkerSrc).toContain("pdf.worker.min.mjs");
});
it("configures the PDF.js worker fallback without creating a worker outside the browser", () => {
const pdfjs = {
GlobalWorkerOptions: {
workerPort: null,
workerSrc: ""
}
};
expect(configurePdfWorker(pdfjs as unknown as Parameters<typeof configurePdfWorker>[0])).toBe(false);
expect(pdfjs.GlobalWorkerOptions.workerPort).toBeNull();
expect(pdfjs.GlobalWorkerOptions.workerSrc).toBe(pdfWorkerSrc);
});
it("normalizes reader technical errors", () => {
expect(readerErrorMessage(new Error("Setting up fake worker failed"), "PDF indisponible")).toBe("Setting up fake worker failed");
expect(readerErrorMessage("", "EPUB indisponible")).toBe("EPUB indisponible");