API Reference
The public surface of @prose-reader/streamer. Everything below is exported from the package root (@prose-reader/streamer) unless a subpath is called out explicitly.
import { generateManifestFromArchive, generateResourceFromArchive,} from "@prose-reader/streamer"The package splits into a few areas. Archives and hooks have dedicated guides — this page is the canonical index of what is exported and documents the pieces that don't have a page of their own (manifest/resource generation and the streaming classes).
| Area | Exports | Where |
|---|---|---|
| Manifest & resources | generateManifestFromArchive, generateResourceFromArchive, createManifestResourceHref |
below |
| Streaming | Streamer, ServiceWorkerStreamer |
below · Node · Service Worker · Web (dom) |
| Hooks | StreamerHooks, StreamerManifestHook*, StreamerResourceHook*, HookResource types |
Hooks |
| Setup | configure |
below |
Archives
Section titled “Archives”The streamer consumes archives, it does not create or understand them: the Archive type, the createArchiveFrom* creators, the file-accessor factories, the lookup helpers, and the whole resolve layer (resolveArchive, resolveArchiveReadingOrder, resolveArchiveToc, the ResolvedMetadata vocabulary) all live in @prose-reader/archive-reader and are covered in full on the Archive Reader page. Building an Archive is always the first step, whatever the source.
Generic string helpers previously exported here (createXmlSafeId, createUniqueXmlSafeId, createXmlSafeIdFactory, sortByTitleComparator, removeTrailingSlash, getUriBasename, getUriBasePath) moved to @prose-reader/shared.
Manifest & resource generation
Section titled “Manifest & resource generation”generateManifestFromArchive(archive, options?)
Section titled “generateManifestFromArchive(archive, options?)”generateManifestFromArchive( archive: Archive, options?: { baseUrl?: string; hooks?: StreamerManifestHookFactory[] },): Promise<Manifest>Produces a reader Manifest: the archive is resolved by @prose-reader/archive-reader's resolveArchive (with the viewport layoutScan enabled), mapped into serving space (baseUrl rebasing, XML-safe ids, guide passthrough, audiobook/folder toc), then handed to any user hooks before the final defaults.
import { createArchiveFromJszip } from "@prose-reader/archive-reader/archives/createArchiveFromJszip"import { generateManifestFromArchive } from "@prose-reader/streamer"
const archive = await createArchiveFromJszip(zip)const manifest = await generateManifestFromArchive(archive)generateResourceFromArchive(archive, resourcePath, options?)
Section titled “generateResourceFromArchive(archive, resourcePath, options?)”generateResourceFromArchive( archive: Archive, resourcePath: string, options?: { hooks?: StreamerResourceHookFactory[] },): Promise<HookResource> // resolved resource with a guaranteed `body` (string | Blob)Resolves a single archive resource by URI, running it through the resource hook pipeline (default / self-closing-tags / css / calibre fixes, plus any user hooks) and falling back to the raw file blob when no hook sets a body.
createManifestResourceHref({ baseUrl?, resourcePath })
Section titled “createManifestResourceHref({ baseUrl?, resourcePath })”createManifestResourceHref(params: { baseUrl?: string // default "" resourcePath: string}): stringBuilds the href used for a manifest resource. An absolute http(s):// resourcePath is returned untouched (when no baseUrl is given); otherwise the path is prefixed with baseUrl (a trailing / is added when missing) or with file:// when no baseUrl is provided. The result is always passed through encodeURI, and #/? characters appearing in the resource path itself are additionally escaped (%23/%3F) — in an archive filename they are data, not fragment/query delimiters.
import { createManifestResourceHref } from "@prose-reader/streamer"
createManifestResourceHref({ resourcePath: "OEBPS/chapter-1.xhtml" })// "file://OEBPS/chapter-1.xhtml"
createManifestResourceHref({ baseUrl: "https://cdn.example.com/book", resourcePath: "OEBPS/chapter-1.xhtml" })// "https://cdn.example.com/book/OEBPS/chapter-1.xhtml"Streaming
Section titled “Streaming”The streaming classes turn manifest and resource requests into HTTP Responses. See Node, Web (dom) and Service Worker for end-to-end setups.
Streamer
Section titled “Streamer”new Streamer(options: { // archive loader options (how archives are created/cached by key) hooks?: StreamerHooks onError?: (error: unknown) => Response onManifestSuccess?: (params: { manifest: Manifest; archive: Archive }) => Observable<Manifest> | Promise<Manifest>})
streamer.fetchManifest(params: { key: string; baseUrl?: string }): Promise<Response>streamer.fetchResource(params: { key: string; resourcePath: string; request?: Request }): Promise<Response>streamer.accessArchive(key: string): Observable<{ archive: Archive; release: () => void }>streamer.accessArchiveWithoutLock(key: string): Observable<Archive>streamer.prune(): voidCore archive-serving engine: it loads and caches archives by key and generates the matching Responses. fetchManifest / fetchResource produce the manifest and resource responses (resource responses support HTTP range requests); accessArchive acquires a locked archive handle you release with release(); accessArchiveWithoutLock yields just the archive and releases immediately; prune purges the archive cache.
ServiceWorkerStreamer
Section titled “ServiceWorkerStreamer”new ServiceWorkerStreamer(options: /* Streamer options */ & { getUriInfo: (event: FetchEvent) => { baseUrl: string } | undefined})
serviceWorkerStreamer.fetchEventListener(event: FetchEvent): voidA Streamer subclass for service-worker fetch events. getUriInfo maps a request to its baseUrl (or undefined to ignore the request); the bound fetchEventListener parses the request URL into { key, resourcePath } and calls event.respondWith using fetchManifest (for /manifest URLs) or fetchResource otherwise.
Debug logging
Section titled “Debug logging”Internal Report logging auto-configures from the globalThis.__PROSE_READER_DEBUG flag (set it to true or "true"). The flag is read from globalThis, so it also works where window does not exist — service workers, web workers, node — as long as it is set before the prose-reader modules evaluate (e.g. an early side-effect import in a worker bundle). This is how every package's logging is enabled, @prose-reader/archive-reader included.
configure(options?)
Section titled “configure(options?)”configure(options?: { enableReport?: boolean }): voidExplicit toggle for the streamer's own Report logging, for setups where the global flag cannot be set early enough (it force-enables or force-disables regardless of the flag).