@d-i-t-a/reader 3.0.0-alpha.14 → 3.0.0-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/esm/index.js +4730 -947
  2. package/dist/esm/index.js.map +4 -4
  3. package/dist/reader.js +72 -69
  4. package/dist/reader.js.map +4 -4
  5. package/dist/types/fetcher/Base64DecodingFetcher.d.ts +19 -0
  6. package/dist/types/fetcher/BlobUrlManager.d.ts +91 -0
  7. package/dist/types/fetcher/CacheFetcher.d.ts +36 -0
  8. package/dist/types/fetcher/Container.d.ts +21 -0
  9. package/dist/types/fetcher/ContentFetcher.d.ts +32 -0
  10. package/dist/types/fetcher/EpubParser.d.ts +48 -0
  11. package/dist/types/fetcher/Fetcher.d.ts +111 -0
  12. package/dist/types/fetcher/FontDeobfuscator.d.ts +65 -0
  13. package/dist/types/fetcher/HttpFetcher.d.ts +29 -0
  14. package/dist/types/fetcher/ReadError.d.ts +35 -0
  15. package/dist/types/fetcher/TransformingFetcher.d.ts +38 -0
  16. package/dist/types/fetcher/ZipContainer.d.ts +16 -0
  17. package/dist/types/fetcher/ZipFetcher.d.ts +51 -0
  18. package/dist/types/fetcher/mediaType.d.ts +5 -0
  19. package/dist/types/fetcher/types.d.ts +27 -0
  20. package/dist/types/index.d.ts +18 -1
  21. package/dist/types/model/user-settings/UserSettings.d.ts +2 -1
  22. package/dist/types/model/v3/Publication.d.ts +4 -4
  23. package/dist/types/modules/ModuleHost.d.ts +3 -1
  24. package/dist/types/modules/ModuleRegistry.d.ts +1 -1
  25. package/dist/types/modules/ReaderModule.d.ts +1 -1
  26. package/dist/types/modules/epub/search/SearchModule.d.ts +0 -1
  27. package/dist/types/navigator/EpubNavigator.d.ts +44 -54
  28. package/dist/types/navigator/InjectableManager.d.ts +32 -0
  29. package/dist/types/navigator/PDFNavigator.d.ts +3 -1
  30. package/dist/types/navigator/VisualNavigator.d.ts +1 -1
  31. package/dist/types/navigator/types.d.ts +166 -0
  32. package/package.json +2 -1
@@ -0,0 +1,19 @@
1
+ import type { Link } from "../model/v3";
2
+ import type { Fetcher, Resource } from "./Fetcher";
3
+ /**
4
+ * Wraps an inner Fetcher and base64-decodes document responses when
5
+ * needed. Composed into the chain when `RequestConfig.encoded === true`.
6
+ *
7
+ * Detects encoding by first character: document content starts with `<`;
8
+ * base64 doesn't. If text is already a document, pass through. Otherwise
9
+ * attempt atob; if atob succeeds, use the result.
10
+ */
11
+ export declare class Base64DecodingFetcher implements Fetcher {
12
+ private readonly inner;
13
+ constructor(inner: Fetcher);
14
+ get(link: Link): Promise<Resource>;
15
+ getByHref(href: string): Promise<Resource>;
16
+ cancel(href: string): void;
17
+ destroy(): void;
18
+ private maybeDecode;
19
+ }
@@ -0,0 +1,91 @@
1
+ import type { Container } from "./Container";
2
+ import type { Resource } from "./Fetcher";
3
+ import type { EncryptionInfo } from "./FontDeobfuscator";
4
+ import { ZipFetcher } from "./ZipFetcher";
5
+ /**
6
+ * A transform applied to resources before creating blob URLs.
7
+ * Same signature as ResourceTransform from TransformingFetcher.
8
+ */
9
+ type BlobTransform = (resource: Resource) => Resource | Promise<Resource>;
10
+ /**
11
+ * Creates and manages blob URLs for resources in a Container.
12
+ *
13
+ * When opening an .epub file directly, the browser can't fetch images,
14
+ * CSS, fonts, and scripts from the archive because they don't exist
15
+ * at any HTTP URL. This manager creates blob URLs for each resource
16
+ * so they can be referenced in document.write() iframe content.
17
+ *
18
+ * Transforms (e.g., font deobfuscation) can be applied to resources
19
+ * before blob URLs are created via `addTransform()`.
20
+ *
21
+ * After parsing HTML content with DOMParser, call `rewriteDom(doc, baseDir)`
22
+ * to replace relative src/href attributes with blob URLs. This works at
23
+ * the DOM level — no regex on raw HTML.
24
+ *
25
+ * Call `destroy()` when done to revoke all blob URLs and free memory.
26
+ */
27
+ export declare class BlobUrlManager {
28
+ private blobUrls;
29
+ private readonly container;
30
+ private transforms;
31
+ private encryptionMap?;
32
+ constructor(source: Container | ZipFetcher);
33
+ /**
34
+ * Set encryption metadata so Resources built during initialize()
35
+ * carry `properties.encrypted`. Transforms (e.g., deobfuscation)
36
+ * read this to know which resources to process.
37
+ */
38
+ setEncryptionMap(map: Map<string, EncryptionInfo>): void;
39
+ /**
40
+ * Add a transform applied to resources before blob URL creation.
41
+ * Transforms run in order. Must be called before initialize().
42
+ *
43
+ * Example: font deobfuscation
44
+ * ```ts
45
+ * manager.addTransform(createDeobfuscationTransform(identifier));
46
+ * ```
47
+ */
48
+ addTransform(transform: BlobTransform): void;
49
+ /**
50
+ * Create blob URLs for all resources in the container.
51
+ * Call once after construction and addTransform().
52
+ *
53
+ * Two-pass process:
54
+ * 1. Create blob URLs for all non-CSS resources (images, fonts, etc.)
55
+ * — applies any registered transforms before creating the blob URL.
56
+ * 2. Process CSS files — rewrite internal url() references to the
57
+ * blob URLs from pass 1, THEN create blob URLs for the rewritten CSS.
58
+ *
59
+ * This ensures that when the browser loads a CSS file via its blob URL,
60
+ * font/image/background references inside it also point to blob URLs.
61
+ */
62
+ initialize(): Promise<void>;
63
+ /**
64
+ * Rewrite resource references in a parsed DOM to blob URLs.
65
+ *
66
+ * Traverses the document and replaces relative `src`, `href`, and
67
+ * `xlink:href` attributes on img, link, script, image, use, audio,
68
+ * video, and source elements with their corresponding blob URLs.
69
+ *
70
+ * Also strips any Content-Security-Policy meta tags that would block
71
+ * the injected ReadiumCSS stylesheets.
72
+ *
73
+ * @param doc — the parsed XHTML document
74
+ * @param currentPath — the ZIP-internal path of the current HTML file
75
+ * (e.g., "OEBPS/Text/chapter1.xhtml"). Used to resolve relative URLs.
76
+ */
77
+ rewriteDom(doc: Document, currentPath: string): void;
78
+ /**
79
+ * Rewrite url() and @import references in CSS text.
80
+ *
81
+ * Handles:
82
+ * - `url("path")` / `url('path')` / `url(path)` — standard references
83
+ * - `@import url("path")` — url()-form imports (caught by the url() regex)
84
+ * - `@import "path"` / `@import 'path'` — bare string imports
85
+ */
86
+ private rewriteCssUrls;
87
+ private isAbsolute;
88
+ private resolve;
89
+ destroy(): void;
90
+ }
91
+ export {};
@@ -0,0 +1,36 @@
1
+ import type { Link } from "../model/v3";
2
+ import type { Fetcher, Resource } from "./Fetcher";
3
+ /**
4
+ * Caching wrapper around any Fetcher.
5
+ *
6
+ * Caches fetched resources by href in memory. Serves subsequent
7
+ * requests from cache without hitting the inner Fetcher. Enables
8
+ * predictive spine prefetching — the navigator calls `prefetch(link)`
9
+ * after each resource loads, and the next chapter is already in memory
10
+ * when the user turns the page.
11
+ *
12
+ * Memory management: call `evict(href)` to remove specific entries,
13
+ * or `clear()` to drop all cached resources.
14
+ */
15
+ export declare class CacheFetcher implements Fetcher {
16
+ private readonly inner;
17
+ private cache;
18
+ private pending;
19
+ constructor(inner: Fetcher);
20
+ get(link: Link): Promise<Resource>;
21
+ getByHref(href: string): Promise<Resource>;
22
+ /**
23
+ * Prefetch a resource into cache without blocking.
24
+ * Used by the navigator to preload adjacent spine items after
25
+ * the current resource finishes loading.
26
+ */
27
+ prefetch(link: Link): Promise<void>;
28
+ /** Check if a resource is cached. */
29
+ has(link: Link): Promise<boolean>;
30
+ /** Remove a specific resource from cache. */
31
+ evict(href: string): void;
32
+ /** Drop all cached resources. */
33
+ clear(): void;
34
+ cancel(href: string): void;
35
+ destroy(): void;
36
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Read-only container of named entries.
3
+ *
4
+ * A Container provides access to a collection of resources by path.
5
+ * It knows what entries exist and can return their raw bytes, but
6
+ * doesn't know anything about Fetcher, Resource, or media types.
7
+ *
8
+ * Implementations:
9
+ * - ZipContainer — entries from a ZIP archive (EPUB, CBZ)
10
+ * - Future: HttpContainer, FileSystemContainer, etc.
11
+ */
12
+ export interface Container {
13
+ /** All entry paths in the container. */
14
+ entries(): string[];
15
+ /** Get raw bytes for an entry, or undefined if not found. */
16
+ get(path: string): Uint8Array | undefined;
17
+ /** Check if an entry exists. */
18
+ has(path: string): boolean;
19
+ /** Release resources (close file handles, free memory). */
20
+ destroy(): void;
21
+ }
@@ -0,0 +1,32 @@
1
+ import type { Link } from "../model/v3";
2
+ import type { GetContent } from "./types";
3
+ import type { Fetcher, Resource } from "./Fetcher";
4
+ import type { Publication } from "../model/v3";
5
+ /**
6
+ * Fetcher that delegates publication-resource requests to the integrator's
7
+ * `api.getContent` callback.
8
+ *
9
+ * For hrefs that belong to the publication (readingOrder + resources in
10
+ * the manifest), `getContent(href)` is called first. If the integrator
11
+ * returns content, that content is used. If it returns `undefined`, the
12
+ * request falls through to the inner Fetcher.
13
+ *
14
+ * Requests for hrefs NOT in the manifest — positions service, external
15
+ * links, browser-chrome URLs — pass straight through to the inner Fetcher
16
+ * without touching getContent.
17
+ *
18
+ * Integrators use `api.getContent` to serve protected/licensed content,
19
+ * fetch from a custom source, or transform content before it reaches the
20
+ * reader.
21
+ */
22
+ export declare class ContentFetcher implements Fetcher {
23
+ private readonly inner;
24
+ private readonly getContent;
25
+ private readonly publicationResourceHrefs;
26
+ constructor(inner: Fetcher, getContent: GetContent, publication: Publication);
27
+ get(link: Link): Promise<Resource>;
28
+ getByHref(href: string): Promise<Resource>;
29
+ cancel(href: string): void;
30
+ destroy(): void;
31
+ private isPublicationResource;
32
+ }
@@ -0,0 +1,48 @@
1
+ import { Publication } from "../model/v3/Publication";
2
+ import type { ZipFetcher } from "./ZipFetcher";
3
+ /**
4
+ * Client-side EPUB parser.
5
+ *
6
+ * Reads an EPUB archive (via ZipFetcher) and produces a Publication
7
+ * (Readium RWPM format). Handles EPUB 2 and EPUB 3:
8
+ *
9
+ * 1. META-INF/container.xml → find the OPF rootfile path
10
+ * 2. OPF → parse metadata, manifest items, spine, TOC
11
+ * 3. Convert to the normalized JSON shape that Publication.fromJSON() expects
12
+ *
13
+ * Metadata: title, language, identifier, authors, publisher, description,
14
+ * subjects, published date, modified date, numberOfPages, layout,
15
+ * readingProgression, rendition properties, media overlay classes.
16
+ *
17
+ * Spine: reading order with page-spread properties, linear="no" filtering,
18
+ * page-progression-direction.
19
+ *
20
+ * Resources: non-spine manifest items + non-linear spine items, cover image
21
+ * detection (EPUB3 cover-image property + EPUB2 meta name="cover").
22
+ *
23
+ * TOC: EPUB3 nav document with fallback to EPUB2 NCX.
24
+ */
25
+ export declare class EpubParser {
26
+ /**
27
+ * Extract just the dc:identifier from an EPUB without full parsing.
28
+ * Used to generate a unique synthetic URL before the full parse.
29
+ */
30
+ static extractIdentifier(zip: ZipFetcher): Promise<string>;
31
+ /**
32
+ * Parse an EPUB from a ZipFetcher and return a Publication.
33
+ *
34
+ * @param zip — ZipFetcher wrapping the .epub archive
35
+ * @param baseUrl — synthetic base URL for the publication
36
+ * (e.g. `blob:...` or `epub://local/`). Used for href resolution.
37
+ */
38
+ static parse(zip: ZipFetcher, baseUrl: URL): Promise<Publication>;
39
+ /**
40
+ * Parse the EPUB 3 nav document (XHTML) to extract the TOC.
41
+ * Looks for `<nav epub:type="toc">` and extracts the `<ol>` structure.
42
+ */
43
+ private static parseNavToc;
44
+ /**
45
+ * Parse an EPUB2 NCX table of contents.
46
+ */
47
+ private static parseNcxToc;
48
+ }
@@ -0,0 +1,111 @@
1
+ import type { Link } from "../model/v3";
2
+ /**
3
+ * A fetched resource — the result of a Fetcher.get() call.
4
+ *
5
+ * Represents content retrieved from any source (HTTP, ZIP, cache,
6
+ * decryption pipeline). Consumers read `text` for string content
7
+ * (HTML, XML, JSON) or `bytes` for binary content (images, audio, PDF).
8
+ *
9
+ * The `partial` and `range` fields are reserved for future range/partial
10
+ * fetching (DRM workstream — page-level streaming). Fetchers that support
11
+ * partial content set these; consumers that don't need partial content
12
+ * ignore them.
13
+ */
14
+ export interface Resource {
15
+ /** The resolved content as a string (HTML, XML, JSON, etc.) */
16
+ readonly text: string;
17
+ /** The raw bytes — for binary content (images, audio, PDF) */
18
+ readonly bytes?: ArrayBuffer;
19
+ /** HTTP headers or equivalent metadata */
20
+ readonly headers: Record<string, string>;
21
+ /** The media type (e.g. "application/xhtml+xml", "application/pdf") */
22
+ readonly mediaType: string;
23
+ /** The resolved href */
24
+ readonly href: string;
25
+ /**
26
+ * Extensible metadata about this resource.
27
+ *
28
+ * Used to carry information through the Fetcher chain that
29
+ * isn't part of the content itself:
30
+ * - `encrypted?: { algorithm: string; originalLength?: number }` —
31
+ * encryption/obfuscation info from encryption.xml
32
+ * - `filename?: string` — original filename from the container
33
+ * - Custom properties set by TransformingFetcher or integrators
34
+ */
35
+ readonly properties?: Record<string, unknown>;
36
+ /**
37
+ * Reserved for future range/partial fetching (3.9).
38
+ * True if this resource contains a partial range, not the full content.
39
+ */
40
+ readonly partial?: boolean;
41
+ /**
42
+ * Reserved for future range/partial fetching (3.9).
43
+ * The byte range this resource represents within the full content.
44
+ */
45
+ readonly range?: {
46
+ start: number;
47
+ end: number;
48
+ total: number;
49
+ };
50
+ }
51
+ /**
52
+ * Content loading abstraction.
53
+ *
54
+ * All content in the reader flows through a Fetcher — chapter HTML,
55
+ * media overlay manifests, audio files, footnote popups, search content.
56
+ * The navigator and modules call `fetcher.get(link)` and receive a
57
+ * Resource without knowing where the content came from (HTTP, ZIP,
58
+ * cache, decryption pipeline).
59
+ *
60
+ * Fetchers are composable — stack them to build a content pipeline:
61
+ *
62
+ * ```ts
63
+ * // Server-based with decryption + caching:
64
+ * const fetcher = new CacheFetcher(
65
+ * new ContentFetcher(
66
+ * new HttpFetcher(requestConfig),
67
+ * api.getContent
68
+ * )
69
+ * )
70
+ *
71
+ * // Client-side EPUB with caching:
72
+ * const fetcher = new CacheFetcher(
73
+ * new ZipFetcher(epubBlob)
74
+ * )
75
+ * ```
76
+ */
77
+ export interface Fetcher {
78
+ /**
79
+ * Fetch a resource by Link.
80
+ * Returns a Resource with the content, headers, and media type.
81
+ * Throws ReadError on failure (access, decoding, or cancelled).
82
+ */
83
+ get(link: Link): Promise<Resource>;
84
+ /**
85
+ * Fetch a resource by href string (convenience overload).
86
+ * Throws ReadError on failure.
87
+ */
88
+ getByHref(href: string): Promise<Resource>;
89
+ /**
90
+ * Cancel an in-flight fetch for the given href.
91
+ * Optional — not all Fetcher implementations support cancellation.
92
+ */
93
+ cancel?(href: string): void;
94
+ /**
95
+ * Check if a resource is available without fetching it.
96
+ * Optional — useful for CacheFetcher (check cache hit) and
97
+ * ZipFetcher (check if file exists in ZIP).
98
+ */
99
+ has?(link: Link): Promise<boolean>;
100
+ /**
101
+ * Prefetch a resource into cache without blocking.
102
+ * Optional — only meaningful for Fetchers that cache (CacheFetcher).
103
+ * Non-caching Fetchers can ignore this or no-op.
104
+ */
105
+ prefetch?(link: Link): Promise<void>;
106
+ /**
107
+ * Release resources held by this Fetcher (close ZIP handles,
108
+ * clear caches, abort pending requests).
109
+ */
110
+ destroy?(): void;
111
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Font deobfuscation for EPUB archives.
3
+ *
4
+ * EPUB publishers can obfuscate embedded fonts to prevent casual reuse
5
+ * outside the publication. Two algorithms exist:
6
+ *
7
+ * - **IDPF** (`http://www.idpf.org/2008/embedding`):
8
+ * SHA-1 hash of the publication identifier, XOR first 1040 bytes.
9
+ *
10
+ * - **Adobe** (`http://ns.adobe.com/pdf/enc#RC`):
11
+ * UUID from the identifier (16 bytes), XOR first 1024 bytes.
12
+ *
13
+ * The encryption.xml file in META-INF lists which resources are
14
+ * obfuscated and with which algorithm. The publication's dc:identifier
15
+ * is used to derive the deobfuscation key.
16
+ *
17
+ * Reference implementations:
18
+ * - edrlab/r2-shared-js src/transform/transformer-obf-idpf.ts
19
+ * - edrlab/r2-shared-js src/transform/transformer-obf-adobe.ts
20
+ * - readium/swift-toolkit Sources/Streamer/Parser/EPUB/EPUBDeobfuscator.swift
21
+ */
22
+ /** Algorithm URIs as defined in the EPUB spec and Adobe's scheme. */
23
+ export declare const ALGORITHM_IDPF = "http://www.idpf.org/2008/embedding";
24
+ export declare const ALGORITHM_ADOBE = "http://ns.adobe.com/pdf/enc#RC";
25
+ /** Encryption info for a single resource, parsed from encryption.xml. */
26
+ export interface EncryptionInfo {
27
+ algorithm: string;
28
+ /** Original uncompressed length (from EncryptionProperties, if present). */
29
+ originalLength?: number;
30
+ }
31
+ /**
32
+ * Parse META-INF/encryption.xml and return a map of href → EncryptionInfo.
33
+ *
34
+ * Only extracts entries with IDPF or Adobe obfuscation algorithms.
35
+ * Other encryption types (e.g., LCP AES-256) are ignored here —
36
+ * those are handled by the integrator's getContent callback.
37
+ */
38
+ export declare function parseEncryptionXml(xmlText: string): Map<string, EncryptionInfo>;
39
+ /**
40
+ * Deobfuscate font data using the IDPF algorithm.
41
+ *
42
+ * SHA-1 hash of the identifier → XOR first 1040 bytes.
43
+ * Uses Web Crypto API (available in all modern browsers).
44
+ */
45
+ export declare function deobfuscateIdpf(data: Uint8Array, identifier: string): Promise<Uint8Array>;
46
+ /**
47
+ * Deobfuscate font data using the Adobe algorithm.
48
+ *
49
+ * Extract UUID from identifier (strip urn:uuid:, hyphens, whitespace),
50
+ * convert 16 hex pairs to 16 bytes → XOR first 1024 bytes.
51
+ */
52
+ export declare function deobfuscateAdobe(data: Uint8Array, identifier: string): Uint8Array;
53
+ /**
54
+ * Create a ResourceTransform that deobfuscates fonts based on
55
+ * encryption info stored in the Resource's `properties.encrypted`.
56
+ *
57
+ * Use with TransformingFetcher:
58
+ * ```ts
59
+ * new TransformingFetcher(inner, createDeobfuscationTransform(identifier))
60
+ * ```
61
+ *
62
+ * Resources without encryption properties pass through unchanged.
63
+ * Only IDPF and Adobe algorithms are handled.
64
+ */
65
+ export declare function createDeobfuscationTransform(identifier: string): (resource: import("./Fetcher").Resource) => Promise<import("./Fetcher").Resource>;
@@ -0,0 +1,29 @@
1
+ import type { Link } from "../model/v3";
2
+ import type { RequestConfig } from "./types";
3
+ import type { Fetcher, Resource } from "./Fetcher";
4
+ /**
5
+ * Default Fetcher implementation — loads resources via HTTP `fetch()`.
6
+ *
7
+ * Drop-in replacement for the current direct `fetch()` calls scattered
8
+ * across EpubNavigator, SearchModule, MediaOverlayModule, and Popup.
9
+ * Existing integrators get this automatically without changing anything.
10
+ *
11
+ * Handles:
12
+ * - Custom headers, credentials, and other RequestInit options via `requestConfig`
13
+ * - Media type detection from Content-Type header
14
+ *
15
+ * Base64-encoded content is handled by `Base64DecodingFetcher`, not here.
16
+ * HttpFetcher returns the response body as plain text. Decoding is
17
+ * composed in when `requestConfig.encoded` is true.
18
+ */
19
+ export declare class HttpFetcher implements Fetcher {
20
+ private readonly requestConfig?;
21
+ /** Track in-flight requests by href so each can be cancelled independently. */
22
+ private controllers;
23
+ constructor(requestConfig?: RequestConfig | undefined);
24
+ get(link: Link): Promise<Resource>;
25
+ getByHref(href: string): Promise<Resource>;
26
+ private fetchByHref;
27
+ cancel(href?: string): void;
28
+ destroy(): void;
29
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Typed errors for the Fetcher / Resource system.
3
+ *
4
+ * Every Fetcher implementation throws a ReadError subclass instead of
5
+ * a generic Error. Callers that need to distinguish failure reasons
6
+ * check `error.type`. Callers that don't just catch ReadError.
7
+ *
8
+ * Types:
9
+ * - `access` — the resource couldn't be reached (HTTP 4xx/5xx,
10
+ * missing ZIP entry, network failure)
11
+ * - `decoding` — the resource was reached but its content is
12
+ * invalid or corrupt (bad XML, unexpected format)
13
+ * - `cancelled` — the request was aborted (navigated away,
14
+ * AbortController.abort())
15
+ */
16
+ export type ReadErrorType = "access" | "decoding" | "cancelled";
17
+ export declare class ReadError extends Error {
18
+ readonly type: ReadErrorType;
19
+ readonly href?: string;
20
+ readonly statusCode?: number;
21
+ readonly cause?: Error;
22
+ constructor(opts: {
23
+ type: ReadErrorType;
24
+ message: string;
25
+ href?: string;
26
+ statusCode?: number;
27
+ cause?: Error;
28
+ });
29
+ /** Resource not found or unreachable. */
30
+ static access(href: string, message: string, statusCode?: number): ReadError;
31
+ /** Content is corrupt or can't be decoded. */
32
+ static decoding(href: string, message: string, cause?: Error): ReadError;
33
+ /** Request was cancelled. */
34
+ static cancelled(href: string): ReadError;
35
+ }
@@ -0,0 +1,38 @@
1
+ import type { Link } from "../model/v3";
2
+ import type { Fetcher, Resource } from "./Fetcher";
3
+ /**
4
+ * A transform function applied to resources in the Fetcher chain.
5
+ *
6
+ * Receives a Resource and returns a (possibly modified) Resource.
7
+ * Return the original resource unchanged to pass it through.
8
+ *
9
+ * Transforms run after the inner Fetcher returns the resource,
10
+ * so the content is already fetched/decoded when the transform sees it.
11
+ */
12
+ export type ResourceTransform = (resource: Resource) => Resource | Promise<Resource>;
13
+ /**
14
+ * Fetcher that applies one or more transforms to resources.
15
+ *
16
+ * Wraps an inner Fetcher and passes every returned Resource through
17
+ * a list of transform functions. Transforms run in order — the output
18
+ * of one is the input of the next.
19
+ *
20
+ * Used for:
21
+ * - Font deobfuscation (IDPF/Adobe XOR on encrypted font bytes)
22
+ * - Future: LCP content key decryption, accessibility transforms
23
+ *
24
+ * Chain position:
25
+ * CacheFetcher → ContentFetcher → TransformingFetcher → HttpFetcher/ZipFetcher
26
+ *
27
+ * The CacheFetcher caches the TRANSFORMED result, so transforms
28
+ * only run once per resource.
29
+ */
30
+ export declare class TransformingFetcher implements Fetcher {
31
+ private readonly inner;
32
+ private readonly transforms;
33
+ constructor(inner: Fetcher, ...transforms: ResourceTransform[]);
34
+ get(link: Link): Promise<Resource>;
35
+ getByHref(href: string): Promise<Resource>;
36
+ cancel(href: string): void;
37
+ destroy(): void;
38
+ }
@@ -0,0 +1,16 @@
1
+ import type { Container } from "./Container";
2
+ /**
3
+ * Container backed by a ZIP archive (EPUB, CBZ, etc.).
4
+ *
5
+ * Parses the ZIP on construction and provides read-only access to
6
+ * entries by path. All paths are as stored in the ZIP — no
7
+ * basePath resolution happens here (that's the Fetcher's job).
8
+ */
9
+ export declare class ZipContainer implements Container {
10
+ private data;
11
+ constructor(input: ArrayBuffer | Uint8Array);
12
+ entries(): string[];
13
+ get(path: string): Uint8Array | undefined;
14
+ has(path: string): boolean;
15
+ destroy(): void;
16
+ }
@@ -0,0 +1,51 @@
1
+ import type { Link } from "../model/v3";
2
+ import type { Fetcher, Resource } from "./Fetcher";
3
+ import type { Container } from "./Container";
4
+ import type { EncryptionInfo } from "./FontDeobfuscator";
5
+ /**
6
+ * Fetcher that reads resources from a Container (ZIP archive, etc.).
7
+ *
8
+ * Wraps a Container and builds Resource objects from its raw bytes.
9
+ * The Container owns the data; the ZipFetcher handles path resolution,
10
+ * media type guessing, and text decoding.
11
+ *
12
+ * Accepts raw ZIP bytes (creates a ZipContainer internally) or a
13
+ * pre-built Container for reuse across Fetchers.
14
+ *
15
+ * Used by:
16
+ * - D2Reader.load({ epub: file }) — opens an .epub file directly
17
+ * - DiViNaNavigator (3.11) — opens CBZ comic/manga archives
18
+ */
19
+ export declare class ZipFetcher implements Fetcher {
20
+ readonly container: Container;
21
+ private basePath;
22
+ private encryptionMap?;
23
+ /**
24
+ * Update the basePath after construction. Used when the identifier
25
+ * is extracted from the ZIP content and incorporated into the path.
26
+ */
27
+ setBasePath(basePath: string): void;
28
+ /**
29
+ * Set encryption info so Resources carry encryption metadata
30
+ * in their `properties.encrypted` field. The TransformingFetcher
31
+ * reads this to know which resources need deobfuscation.
32
+ */
33
+ setEncryptionMap(map: Map<string, EncryptionInfo>): void;
34
+ constructor(source: ArrayBuffer | Uint8Array | Container, basePath?: string);
35
+ get(link: Link): Promise<Resource>;
36
+ getByHref(href: string): Promise<Resource>;
37
+ has(link: Link): Promise<boolean>;
38
+ /** List all file paths in the container. */
39
+ list(): string[];
40
+ /** Read a specific entry as raw bytes. */
41
+ getBytes(path: string): Uint8Array | undefined;
42
+ destroy(): void;
43
+ /**
44
+ * Resolve an href to a container entry path.
45
+ * Strips the basePath prefix, query strings, fragments, and
46
+ * leading slashes.
47
+ */
48
+ private resolvePath;
49
+ /** @deprecated Use `guessMediaType` from `./mediaType` instead. */
50
+ static guessMediaType(path: string): string;
51
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Guess media type from a file path's extension.
3
+ * Covers types commonly found in EPUB, CBZ, and web publications.
4
+ */
5
+ export declare function guessMediaType(path: string): string;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Extends RequestInit with reader-specific options.
3
+ *
4
+ * Passed to HttpFetcher and through the Fetcher chain.
5
+ * `encoded` signals that the server returns base64-encoded content
6
+ * (used by some Readium-compatible streamers).
7
+ */
8
+ export interface RequestConfig extends RequestInit {
9
+ encoded?: boolean;
10
+ }
11
+ /**
12
+ * Integrator-provided content callback.
13
+ *
14
+ * Called by ContentFetcher for each resource request. If the integrator
15
+ * returns content (string), it's used directly. If it returns undefined,
16
+ * the request falls through to the inner Fetcher (typically HttpFetcher).
17
+ *
18
+ * Used for DRM decryption, custom content sources, content transformation.
19
+ */
20
+ export type GetContent = (href: string) => Promise<string | undefined>;
21
+ /**
22
+ * Callback to get the byte length of a resource.
23
+ *
24
+ * Used by Publication.autoGeneratePositions() to calculate
25
+ * reading positions from content size.
26
+ */
27
+ export type GetContentBytesLength = (href: string, requestConfig?: RequestConfig) => Promise<number>;
@@ -18,7 +18,24 @@ export { ModuleRegistry } from "./modules/ModuleRegistry";
18
18
  export { ModuleAccessors } from "./modules/ModuleAccessors";
19
19
  export type { IBookmarkModule, ISearchModule, IAnnotationModule, IHistoryModule, SearchOptions, } from "./modules/interfaces";
20
20
  export { getPageFromLocations } from "./model/v3";
21
- export type { ReaderConfig, ReaderRights, NavigatorAPI, IFrameAttributes, Injectable, RequestConfig, SampleRead, PublicationServices, InitialAnnotations, EpubNavigatorConfig, IFrameNavigatorConfig, } from "./navigator/EpubNavigator";
21
+ export type { Fetcher, Resource } from "./fetcher/Fetcher";
22
+ export type { Container } from "./fetcher/Container";
23
+ export type { RequestConfig, GetContent, GetContentBytesLength, } from "./fetcher/types";
24
+ export { ZipContainer } from "./fetcher/ZipContainer";
25
+ export { ReadError } from "./fetcher/ReadError";
26
+ export type { ReadErrorType } from "./fetcher/ReadError";
27
+ export { HttpFetcher } from "./fetcher/HttpFetcher";
28
+ export { ContentFetcher } from "./fetcher/ContentFetcher";
29
+ export { CacheFetcher } from "./fetcher/CacheFetcher";
30
+ export { ZipFetcher } from "./fetcher/ZipFetcher";
31
+ export { EpubParser } from "./fetcher/EpubParser";
32
+ export { BlobUrlManager } from "./fetcher/BlobUrlManager";
33
+ export { guessMediaType } from "./fetcher/mediaType";
34
+ export { TransformingFetcher } from "./fetcher/TransformingFetcher";
35
+ export type { ResourceTransform } from "./fetcher/TransformingFetcher";
36
+ export { parseEncryptionXml, deobfuscateIdpf, deobfuscateAdobe, createDeobfuscationTransform, } from "./fetcher/FontDeobfuscator";
37
+ export type { EncryptionInfo } from "./fetcher/FontDeobfuscator";
38
+ export type { ReaderConfig, ReaderRights, NavigatorAPI, IFrameAttributes, Injectable, SampleRead, PublicationServices, InitialAnnotations, EpubNavigatorConfig, IFrameNavigatorConfig, } from "./navigator/EpubNavigator";
22
39
  export type { IUserSettings, InitialUserSettings, } from "./model/user-settings/UserSettings";
23
40
  export type { UserSettingsIncrementable } from "./model/user-settings/UserProperties";
24
41
  export type { LocalStorageStoreConfig } from "./store/LocalStorageStore";