@prose-reader/streamer 1.320.0 → 1.321.0
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.
- package/dist/Streamer.d.ts +2 -2
- package/dist/{archives/archiveLoader.d.ts → archiveLoader.d.ts} +1 -1
- package/dist/generators/manifest/hooks/apple.d.ts +1 -1
- package/dist/generators/manifest/hooks/audiobookToc.d.ts +1 -1
- package/dist/generators/manifest/hooks/comicInfo.d.ts +1 -1
- package/dist/generators/manifest/hooks/default.d.ts +1 -1
- package/dist/generators/manifest/hooks/epub/epub.d.ts +1 -2
- package/dist/generators/manifest/hooks/epubOptimizer.d.ts +1 -2
- package/dist/generators/manifest/hooks/kobo.d.ts +1 -1
- package/dist/generators/manifest/hooks/nonEpub.d.ts +1 -1
- package/dist/generators/manifest/hooks/toc.d.ts +1 -2
- package/dist/generators/manifest/index.d.ts +1 -1
- package/dist/generators/resources/hooks/calibreFixHook.d.ts +1 -1
- package/dist/generators/resources/hooks/cssFixHook.d.ts +1 -1
- package/dist/generators/resources/hooks/defaultHook.d.ts +1 -1
- package/dist/generators/resources/hooks/selfClosingTagsFixHook.d.ts +1 -1
- package/dist/generators/resources/index.d.ts +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/index/index.cjs +1 -31
- package/dist/index/index.cjs.map +1 -1
- package/dist/index/index.js +197 -424
- package/dist/index/index.js.map +1 -1
- package/dist/index.d.ts +0 -14
- package/package.json +5 -63
- package/dist/archives/createArchive.d.ts +0 -10
- package/dist/archives/createArchiveFromArrayBufferList.d.ts +0 -11
- package/dist/archives/createArchiveFromEntries.d.ts +0 -29
- package/dist/archives/createArchiveFromJszip/index.cjs +0 -2
- package/dist/archives/createArchiveFromJszip/index.cjs.map +0 -1
- package/dist/archives/createArchiveFromJszip/index.js +0 -19
- package/dist/archives/createArchiveFromJszip/index.js.map +0 -1
- package/dist/archives/createArchiveFromJszip.d.ts +0 -7
- package/dist/archives/createArchiveFromLibArchive/index.cjs +0 -2
- package/dist/archives/createArchiveFromLibArchive/index.cjs.map +0 -1
- package/dist/archives/createArchiveFromLibArchive/index.js +0 -16
- package/dist/archives/createArchiveFromLibArchive/index.js.map +0 -1
- package/dist/archives/createArchiveFromLibArchive.d.ts +0 -7
- package/dist/archives/createArchiveFromNodeUnrarJs/index.cjs +0 -2
- package/dist/archives/createArchiveFromNodeUnrarJs/index.cjs.map +0 -1
- package/dist/archives/createArchiveFromNodeUnrarJs/index.js +0 -27
- package/dist/archives/createArchiveFromNodeUnrarJs/index.js.map +0 -1
- package/dist/archives/createArchiveFromNodeUnrarJs.d.ts +0 -7
- package/dist/archives/createArchiveFromText.d.ts +0 -7
- package/dist/archives/createArchiveFromUnzipper/index.cjs +0 -2
- package/dist/archives/createArchiveFromUnzipper/index.cjs.map +0 -1
- package/dist/archives/createArchiveFromUnzipper/index.js +0 -23
- package/dist/archives/createArchiveFromUnzipper/index.js.map +0 -1
- package/dist/archives/createArchiveFromUnzipper.d.ts +0 -7
- package/dist/archives/createArchiveFromUrls.d.ts +0 -9
- package/dist/archives/createArchiveFromZipJs/index.cjs +0 -2
- package/dist/archives/createArchiveFromZipJs/index.cjs.map +0 -1
- package/dist/archives/createArchiveFromZipJs/index.js +0 -20
- package/dist/archives/createArchiveFromZipJs/index.js.map +0 -1
- package/dist/archives/createArchiveFromZipJs.d.ts +0 -7
- package/dist/archives/fileAccessors.d.ts +0 -15
- package/dist/archives/getArchiveHasComicInfo.d.ts +0 -2
- package/dist/archives/printTree.d.ts +0 -1
- package/dist/archives/readRecordAsText.d.ts +0 -7
- package/dist/archives/types.d.ts +0 -42
- package/dist/createArchiveFromEntries-CNz716dm.js +0 -68
- package/dist/createArchiveFromEntries-CNz716dm.js.map +0 -1
- package/dist/createArchiveFromEntries-DL9Q2cPL.cjs +0 -3
- package/dist/createArchiveFromEntries-DL9Q2cPL.cjs.map +0 -1
- package/dist/epubs/getArchiveOpfInfo.d.ts +0 -5
- package/dist/epubs/getSpineItemFilesFromArchive.d.ts +0 -6
- package/dist/epubs/isArchiveEpub.d.ts +0 -2
- package/dist/epubs/readArchiveOpf.d.ts +0 -17
- package/dist/fileAccessors-DWVChFUB.cjs +0 -2
- package/dist/fileAccessors-DWVChFUB.cjs.map +0 -1
- package/dist/fileAccessors-etcCPnpQ.js +0 -12
- package/dist/fileAccessors-etcCPnpQ.js.map +0 -1
- package/dist/parsers/nav.d.ts +0 -5
- package/dist/parsers/nav.test.d.ts +0 -1
- package/dist/parsers/xml.d.ts +0 -2
- package/dist/tests/setupTests.d.ts +0 -0
- package/dist/utils/createXmlSafeId.d.ts +0 -3
- package/dist/utils/createXmlSafeId.test.d.ts +0 -1
- package/dist/utils/sortByTitleComparator.d.ts +0 -1
- package/dist/utils/sortByTitleComparator.test.d.ts +0 -1
- package/dist/utils/uri.d.ts +0 -3
- package/dist/utils/uri.test.d.ts +0 -1
- /package/dist/{archives/archiveLoader.test.d.ts → archiveLoader.test.d.ts} +0 -0
package/dist/Streamer.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { Archive } from '@prose-reader/archive-reader';
|
|
1
2
|
import { Manifest } from '@prose-reader/shared';
|
|
2
3
|
import { Observable } from 'rxjs';
|
|
3
|
-
import { createArchiveLoader } from './
|
|
4
|
-
import { Archive } from './archives/types';
|
|
4
|
+
import { createArchiveLoader } from './archiveLoader';
|
|
5
5
|
import { StreamerHooks } from './hooks';
|
|
6
6
|
type OnError = (error: unknown) => Response;
|
|
7
7
|
type OnManifestSuccess = (params: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { Archive } from '@prose-reader/archive-reader';
|
|
1
2
|
import { Manifest } from '@prose-reader/shared';
|
|
2
|
-
import { Archive } from '../../../archives/types';
|
|
3
3
|
type Toc = NonNullable<Manifest["nav"]>["toc"];
|
|
4
4
|
export declare const normalizeFilenameAsTitle: (filename: string) => string;
|
|
5
5
|
export declare const buildAudiobookToc: (manifest: Manifest, archive: Archive) => Toc | undefined;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import { ArchiveOpfParsed, Archive } from '@prose-reader/archive-reader';
|
|
1
2
|
import { Manifest } from '@prose-reader/shared';
|
|
2
|
-
import { Archive } from '../../../../archives/types';
|
|
3
|
-
import { ArchiveOpfParsed } from '../../../../epubs/readArchiveOpf';
|
|
4
3
|
export declare const getItemsFromDoc: (manifestItems: ReadonlyArray<{
|
|
5
4
|
id: string;
|
|
6
5
|
href: string;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import { ArchiveOpfParsed, Archive } from '@prose-reader/archive-reader';
|
|
1
2
|
import { Manifest } from '@prose-reader/shared';
|
|
2
|
-
import { Archive } from '../../../archives/types';
|
|
3
|
-
import { ArchiveOpfParsed } from '../../../epubs/readArchiveOpf';
|
|
4
3
|
export declare const epubOptimizerHook: ({ archive, archiveOpf, }: {
|
|
5
4
|
archive: Archive;
|
|
6
5
|
baseUrl: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { Archive } from '@prose-reader/archive-reader';
|
|
1
2
|
import { Manifest } from '@prose-reader/shared';
|
|
2
|
-
import { Archive } from '../../../archives/types';
|
|
3
3
|
/**
|
|
4
4
|
* If we don't have a regular epub, we have an archive that could be many things.
|
|
5
5
|
* We try to refine the manifest based on the type of content as much as possible.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import { Archive, ArchiveOpfParsed } from '@prose-reader/archive-reader';
|
|
1
2
|
import { Manifest } from '@prose-reader/shared';
|
|
2
|
-
import { Archive } from '../../../archives/types';
|
|
3
|
-
import { ArchiveOpfParsed } from '../../../epubs/readArchiveOpf';
|
|
4
3
|
/**
|
|
5
4
|
* Resolve the table of contents from a single entry point.
|
|
6
5
|
* Internally handles EPUB nav, NCX, and folder fallback.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Archive } from '
|
|
1
|
+
import { Archive } from '@prose-reader/archive-reader';
|
|
2
2
|
import { StreamerManifestHooks } from '../../hooks';
|
|
3
3
|
export declare const generateManifestFromArchive: (archive: Archive, { baseUrl, hooks, }?: {
|
|
4
4
|
baseUrl?: string;
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { Archive } from '@prose-reader/archive-reader';
|
|
1
2
|
import { Manifest } from '@prose-reader/shared';
|
|
2
|
-
import { Archive } from './archives/types';
|
|
3
3
|
import { HookResource } from './generators/resources/hooks/types';
|
|
4
4
|
export type { HookResource };
|
|
5
5
|
export type StreamerManifestHookContext = {
|
package/dist/index/index.cjs
CHANGED
|
@@ -1,32 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../createArchiveFromEntries-DL9Q2cPL.cjs"),t=require("../fileAccessors-DWVChFUB.cjs");let n=require("@prose-reader/shared"),r=require("@prose-reader/archive-reader"),i=require("xmldoc"),a=require("rxjs");var o=async(r,i={})=>e.t(r,e=>e.isDir?{dir:!0,uri:e.name}:{dir:!1,uri:e.name,size:e.size,...t.t(e.data,(0,n.detectMimeTypeFromName)(e.name)??``)},{...i,close:()=>Promise.resolve()}),s=async(n,{mimeType:r,direction:i}={mimeType:`text/plain`})=>{let a=`
|
|
2
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
3
|
-
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
|
|
4
|
-
unique-identifier="ootuya-id">
|
|
5
|
-
<metadata xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
6
|
-
xmlns:dcterms="http://purl.org/dc/terms/">
|
|
7
|
-
<meta property="rendition:layout">reflowable</meta>
|
|
8
|
-
</metadata>
|
|
9
|
-
<manifest>
|
|
10
|
-
<item id="p01" href="p01.txt" media-type="text/plain"/>
|
|
11
|
-
</manifest>
|
|
12
|
-
<spine page-progression-direction="${i??`ltr`}">
|
|
13
|
-
<itemref idref="p01" />
|
|
14
|
-
</spine>
|
|
15
|
-
</package>
|
|
16
|
-
`;return e.o({filename:`content.txt`,encodingFormat:r,records:[{dir:!1,basename:e.r(`generated.opf`),uri:`generated.opf`,size:0,...t.n(async()=>new Blob([a]))},{dir:!1,basename:e.r(`p01.txt`),uri:`p01.txt`,size:typeof n==`string`?new Blob([n]).size:n.size,encodingFormat:r,...t.n(async()=>typeof n==`string`?new Blob([n]):n)}],close:()=>Promise.resolve()})},c=/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/,l=/^[A-Za-z0-9_]/,u=/^xml/i,d=/[^A-Za-z0-9_.-]+/g,f=`_`,p=e=>e.replace(/^_+|_+$/g,``),m=e=>p(e.trim().replaceAll(`/`,`_`).replace(d,`_`)),h=e=>{if(c.test(e)&&!u.test(e))return e;let t=m(e),n=t&&!u.test(t)?t:`${f}${t}`;return l.test(n)?n:`${f}${n}`},g=(e,t)=>{let n=h(e);if(!t.has(n))return t.add(n),n;let r=2,i=`${n}-${r}`;for(;t.has(i);)r+=1,i=`${n}-${r}`;return t.add(i),i},_=()=>{let e=new Set;return t=>g(t,e)},ee=async(r,i)=>{let a=_(),o=r.map(e=>({id:a(e),url:e})),s=`
|
|
17
|
-
<?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
|
|
18
|
-
<metadata>
|
|
19
|
-
<meta property="rendition:layout">${i?.useRenditionFlow?`reflowable`:`pre-paginated`}</meta>
|
|
20
|
-
${i?.useRenditionFlow?`<meta property="rendition:flow">scrolled-continuous</meta>`:``}
|
|
21
|
-
</metadata>
|
|
22
|
-
<manifest>
|
|
23
|
-
${o.map(({id:e,url:t})=>{let r=(0,n.detectMimeTypeFromName)(t);return`<item id="${e}" href="${(0,n.escapeXmlAttributeValue)(t)}" media-type="${(0,n.escapeXmlAttributeValue)(r??``)}"/>`}).join(`
|
|
24
|
-
`)}
|
|
25
|
-
</manifest>
|
|
26
|
-
<spine>
|
|
27
|
-
${o.map(({id:e})=>`<itemref idref="${e}" />`).join(`
|
|
28
|
-
`)}
|
|
29
|
-
</spine>
|
|
30
|
-
</package>
|
|
31
|
-
`,c=r.map(r=>({dir:!1,basename:e.r(r),encodingFormat:(0,n.detectMimeTypeFromName)(r),uri:r,size:0,...t.n(async()=>(await fetch(r)).blob())}));return e.o({records:[{dir:!1,basename:`content.opf`,uri:`content.opf`,size:0,...t.n(async()=>new Blob([s]))},...c],close:()=>Promise.resolve()})},v=e=>!e.dir,y=e=>e.dir,b=(e,t)=>{let n=e.recordsByUri.get(t);return n&&v(n)?n:void 0},te=r.COMIC_INFO_FILENAME.toLowerCase(),x=e=>e.records.find(e=>v(e)&&e.basename.toLowerCase()===te),S=async e=>new TextDecoder().decode(await e.arrayBuffer()),ne=({enableReport:t}={})=>{e.s.enable(!!t)},C=e=>{let t=e.records.filter(e=>!e.dir).find(e=>e.uri.endsWith(`.opf`));return{data:t,basePath:t?.uri.substring(0,t.uri.lastIndexOf(`/`))||``}};async function w(e){let{data:t,basePath:n}=C(e)||{};if(!(!t||t.dir))return{opf:(0,r.parseOpf)(await S(t)),basePath:n}}var T=r.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME.toLowerCase(),E=({archive:e})=>async t=>{let n=e.records.find(e=>!e.dir&&e.basename.toLowerCase()===T);if(!n||n.dir)return t;let i=await S(n);try{let{renditionLayout:e}=(0,r.resolveArchiveMetadata)((0,r.parseAppleDisplayOptionsXml)(i));return{...t,renditionLayout:t.renditionLayout??e}}catch(e){return console.error(`Unable to parse ${r.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME} for content\n`,i),console.error(e),t}},D=r.COMIC_INFO_FILENAME.toLowerCase(),re=({archive:e})=>async t=>{let n=x(e);if(!n)return t;let i={...t,spineItems:t.spineItems.filter(e=>!e.id.toLowerCase().endsWith(D)).map((e,t,n)=>({...e,progressionWeight:1/n.length}))},a=await S(n);try{let e=(0,r.resolveArchiveMetadata)((0,r.parseComicInfo)(a));return{...i,readingDirection:e.readingDirection??i.readingDirection}}catch(e){return console.error(`Unable to parse ${r.COMIC_INFO_FILENAME} for content\n`,a),console.error(e),i}},O=({baseUrl:e=``,resourcePath:t})=>{if(!e&&/^https?:\/\//.test(t))return encodeURI(t);let n=e?`${e}${e.endsWith(`/`)?``:`/`}`:`file://`;return encodeURI(`${n}${t}`)},ie=({archive:e,baseUrl:t})=>async()=>{let n=e.records.filter(e=>!e.dir),r=_(),i=n.map(e=>({file:e,id:r(e.uri)}));return{filename:e.filename??``,title:e.records.find(({dir:e})=>e)?.basename.replace(/\/$/,``)||e.filename||``,renditionLayout:void 0,renditionSpread:`auto`,readingDirection:void 0,spineItems:i.filter(({file:e})=>!e.basename.endsWith(`.db`)).map(({file:e,id:r},i)=>({id:r,index:i,href:O({baseUrl:t,resourcePath:e.uri}),renditionLayout:void 0,progressionWeight:1/n.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:e.encodingFormat})),items:i.map(({file:e,id:n})=>({id:n,href:encodeURI(`${t}${e.uri}`)}))}},k=async({archive:e,archiveOpf:t})=>{if(!t)return[];let{opf:n,basePath:r}=t,{spineRows:i}=n;return e.records.filter(e=>i.find(t=>r?`${r}/${t.href}`===e.uri:`${t.href}`===e.uri))},A=(e,t,n)=>{let{basePath:r}=C(t)||{};return e.map(e=>{let t=e.href,i=n?.(t)??``;return{href:r?`${i}${r}/${t}`:`${i}${t}`,id:e.id,mediaType:e.mediaType}})},ae=e=>{let t=e?.trim();return t===`scrolled-continuous`||t===`scrolled-doc`||t===`paginated`||t===`auto`?t:`auto`},oe=e=>{let t=e?.trim();if(t===`none`||t===`landscape`||t===`portrait`||t===`both`||t===`auto`)return t},se=e=>{let t=e?.trim();if(t===`cover`||t===`title-page`||t===`copyright-page`||t===`text`)return t},ce=({archive:t,baseUrl:n,archiveOpf:i})=>async a=>{if(!i)return a;let{opf:o,basePath:s}=i,c=(0,r.resolveArchiveMetadata)(o);e.s.groupCollapsed(...e.s.getGroupArgs(`OPF parsed`)),e.s.log(`opf`,o),e.s.groupEnd();let l=o.renditionLayoutMeta?.trim(),u=l===`reflowable`||l===`pre-paginated`?l:c.renditionLayout,d=o.title?.trim()||t.records.find(({dir:e})=>e)?.basename||``,f=c.readingDirection??a.readingDirection,p=(await k({archive:t,archiveOpf:i})).filter(v).reduce((e,t)=>t.size+e,0),m=o.guide,h=[];for(let e of m){let t=se(e.type);t!==void 0&&h.push({href:e.href,title:e.title,type:t})}return{filename:t.filename??``,renditionLayout:u,renditionFlow:ae(o.renditionFlowMeta),renditionSpread:oe(o.renditionSpreadMeta),title:d,readingDirection:f,spineItems:o.spineRows.map((e,r)=>{let i=b(t,s?`${s}/${e.href}`:e.href),a=i?i.size:0,c=n||(/^https?:\/\//.test(e.href)?``:`file://`);return{id:e.id,index:r,href:e.href.startsWith(`https://`)?e.href:s?`${c}${s}/${e.href}`:`${c}${e.href}`,renditionLayout:e.renditionLayout??u,...e.renditionFlow===void 0?{}:{renditionFlow:e.renditionFlow},progressionWeight:p>0?a/p:1/o.spineRows.length,pageSpreadLeft:e.pageSpreadLeft,pageSpreadRight:e.pageSpreadRight,mediaType:e.mediaType}}),items:A(o.manifestItems,t,e=>/^https?:\/\//.test(e)?``:n||`file://`),guide:h.length>0?h:void 0}},j=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`viewport`);return!!(t&&t.attr.name===`viewport`)},M=e=>e.reduce(async(e,t)=>{if(!await e||!(0,n.isXmlBasedMimeType)({mimeType:v(t)?t.encodingFormat:void 0,uri:t.uri}))return!1;let r=t.dir?null:await S(t);return r?j(new i.XmlDocument(r)):!1},Promise.resolve(!0)),N=({archive:e,archiveOpf:t})=>async n=>n.renditionLayout===`reflowable`&&n.spineItems.every(e=>e.renditionLayout===`reflowable`)&&await M(await k({archive:e,archiveOpf:t}))?{...n,spineItems:n.spineItems.map(e=>({...e,renditionLayout:`pre-paginated`})),renditionLayout:`pre-paginated`}:n,P=()=>e=>({...e,readingDirection:e.readingDirection??`ltr`}),F=async e=>{let t;return await Promise.all(e.records.map(async e=>{if(e.dir||!e.uri.endsWith(r.KOBO_DISPLAY_OPTIONS_FILENAME))return;let n=await S(e);try{let{renditionLayout:e}=(0,r.parseKoboXml)(n);e&&(t=e)}catch(e){console.error(`Unable to parse ${r.KOBO_DISPLAY_OPTIONS_FILENAME} for content\n`,n),console.error(e)}})),{kind:`kobo`,...t===void 0?{}:{renditionLayout:t}}},I=({archive:e})=>async t=>{let{renditionLayout:n}=(0,r.resolveArchiveMetadata)(await F(e));return{...t,renditionLayout:t.renditionLayout??n}},L=e=>e.toLowerCase().endsWith(`.opf`),R=e=>e.records.some(e=>!e.dir&&(L(e.basename)||L(e.uri))),z=({archive:e})=>async t=>R(e)?t:{...t,spineItems:t.spineItems.map(t=>{let r=e.records.find(e=>decodeURI(t.href).endsWith(e.uri)),i=(0,n.parseContentType)((r&&v(r)?r.encodingFormat:void 0)??``)||(0,n.detectMimeTypeFromName)(r?.basename??``);return{...t,renditionLayout:i&&(0,n.isMediaContentMimeType)(i)?`pre-paginated`:t.renditionLayout}})},B=e=>e?e.children.map(e=>e instanceof i.XmlTextNode?e.text:e instanceof i.XmlElement?B(e):``).join(``).trim():``,V=e=>(0,r.tokenizeXmlSpaceSeparatedList)(e.properties).includes(`nav`),H=(e,{basePath:t,baseUrl:r})=>{let i={contents:[],path:``,href:``,title:``},a=e.childNamed(`span`)||e.childNamed(`a`);i.title=(a?.attr.title||a?.val.trim()||B(a))??``;let o=a?.name;o!==`a`&&(a=e.descendantWithPath(`${o}.a`),a&&(o=a.name.toLowerCase())),o===`a`&&a?.attr.href&&(i.path=(0,n.urlJoin)(t,a.attr.href),i.href=(0,n.urlJoin)(r,t,a.attr.href));let s=e.childNamed(`ol`);if(s){let e=s.childrenNamed(`li`);e&&e.length>0&&(i.contents=e.map(e=>H(e,{basePath:t,baseUrl:r})))}return i},U=(e,{basePath:t,baseUrl:n})=>{let r=[],i;return e.descendantWithPath(`body.nav.ol`)?i=e.descendantWithPath(`body.nav.ol`)?.children:e.descendantWithPath(`body.section.nav.ol`)&&(i=e.descendantWithPath(`body.section.nav.ol`)?.children),i&&i.length>0&&i.filter(e=>e.name===`li`).forEach(e=>{r.push(H(e,{basePath:t,baseUrl:n}))}),r},W=async(t,n,{baseUrl:r})=>{let a=t.manifestItems.find(V);if(a?.href){let t=n.records.find(e=>e.uri.endsWith(a.href));if(t&&!t.dir)return U(new i.XmlDocument(await S(t)),{basePath:e.n(t.uri),baseUrl:r})}},G=(e,{opfBasePath:t,baseUrl:r,prefix:i})=>{let a=e?.childNamed(`${i}content`)?.attr.src||``,o={title:e?.descendantWithPath(`${i}navLabel.${i}text`)?.val||``,path:(0,n.urlJoin)(t,a),href:(0,n.urlJoin)(r,t,a),contents:[]},s=e.childrenNamed(`${i}navPoint`);return s&&s.length>0&&(o.contents=s.map(e=>G(e,{opfBasePath:t,baseUrl:r,prefix:i}))),o},le=(e,{opfBasePath:t,baseUrl:n})=>{let r=[],i=e.name,a=``;return i.indexOf(`:`)!==-1&&(a=`${i.split(`:`)[0]}:`),e.childNamed(`${a}navMap`)?.childrenNamed(`${a}navPoint`).forEach(e=>{r.push(G(e,{opfBasePath:t,baseUrl:n,prefix:a}))}),r},ue=async({opf:e,opfBasePath:t,baseUrl:n,archive:r})=>{let a=e.spineTocIdref;if(a){let o=e.manifestItems.find(e=>e.id===a);if(o){let e=`${t}${t===``?``:`/`}${o.href}`,a=r.records.find(t=>t.uri.endsWith(e));if(a&&!a.dir)return le(new i.XmlDocument(await S(a)),{opfBasePath:t,baseUrl:n})}}},de=async(e,t,{baseUrl:n})=>{let{basePath:r}=C(t)||{},i=await W(e,t,{baseUrl:n});if(i)return i;let a=await ue({opf:e,opfBasePath:r??``,archive:t,baseUrl:n});if(a)return a},fe=e=>e.replace(/\.[^.]+$/,``).replace(/[_-]/g,` `).replace(/\s+/g,` `).trim(),pe=(e,t)=>{if(e.spineItems.length!==0&&e.spineItems.every(e=>((0,n.parseContentType)(e.mediaType??``)||(0,n.detectMimeTypeFromName)(e.href))?.startsWith(`audio/`)))return e.spineItems.map(e=>{let n=t.records.find(t=>!t.dir&&decodeURI(e.href).endsWith(t.uri));return{title:fe(n?.basename??e.href),href:e.href,path:n?.uri??e.href,contents:[]}})},me=(t,{baseUrl:r})=>{let i=[...t.records].sort((t,n)=>e.a(t.uri,n.uri)),a=(e,t,n,r,i)=>{let o=e.find(e=>e.title===t),[s,...c]=n;return o?s?[...e.filter(e=>e!==o),{...o,contents:[...o.contents,...a(o.contents,s,c,r,i)]}]:o.path.split(`/`).length>i.split(`/`).length?[...e.filter(e=>e!==o),{...o,path:i,href:r}]:e:s?[...e,{contents:a([],s,c,r,i),href:r,path:i,title:t}]:[...e,{contents:[],href:r,path:i,title:t}]};return i.reduce((e,t)=>{if(t.dir)return e;let[i,...o]=t.uri.split(`/`).slice(0,-1);if(!i)return e;let s=(0,n.urlJoin)(r,encodeURI(t.uri)).replace(/\/$/,``),c=t.uri.replace(/\/$/,``);return a(e,i,o,s,c)},[])},he=async(e,t,{baseUrl:n,archiveOpf:r})=>{if(r)return await de(r.opf,e,{baseUrl:n})||[];let i=pe(t,e);if(i)return i;let a=me(e,{baseUrl:n});if(a.length!==0)return a},ge=({archive:e,baseUrl:t,archiveOpf:n})=>async r=>{if(r.nav)return r;let i=await he(e,r,{baseUrl:t,archiveOpf:n});return i?{...r,nav:{toc:i}}:r},_e=e=>e?e.endsWith(`/`)?e:`${e}/`:``,K=async(t,{baseUrl:n=``,hooks:r={}}={})=>{e.s.log(`Generating manifest from archive`,t);let i=await w(t),a=_e(n),o=e=>(e??[]).map(e=>e({archive:t,baseUrl:a})),s=[ce({archive:t,baseUrl:a,archiveOpf:i}),re({archive:t,baseUrl:a}),E({archive:t,baseUrl:a}),z({archive:t,baseUrl:a}),...o(r.content)],c=o(r.spine),l=[N({archive:t,baseUrl:a,archiveOpf:i}),I({archive:t,baseUrl:a}),...o(r.presentation)],u=[ge({archive:t,baseUrl:a,archiveOpf:i}),...o(r.navigation)],d=[...s,...c,...l,...u,P()];try{let n=ie({archive:t,baseUrl:a})(),r=await d.reduce(async(e,t)=>await t(await e),n);if(e.s.log(`Generated manifest`,r),process.env.NODE_ENV===`development`&&e.s.isEnabled()){let t=JSON.stringify(r,null,2);e.s.groupCollapsed(...e.s.getGroupArgs(`Generated manifest`)),e.s.log(`\n${t}`),e.s.groupEnd()}return r}catch(t){throw e.s.error(t),t}},ve=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`calibre:cover`);return!!(t&&t.attr.name===`calibre:cover`)},ye=e=>e.descendantWithPath(`body`)?.descendantWithPath(`div`)?.childrenNamed(`svg`)?.find(e=>e.attr.width===`100%`&&e.attr.preserveAspectRatio===`none`),be=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=new i.XmlDocument(typeof n.body==`string`?n.body:await S(r));if(ve(e)){let t=ye(e);return t&&delete t.attr.preserveAspectRatio,{...n,body:e?.toString()}}}return n},xe=({archive:e,resourcePath:t})=>async n=>be({archive:e,resourcePath:t})(n),Se=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.css`)){let e=(typeof n.body==`string`?n.body:await S(r)).replaceAll(`-webkit-writing-mode`,`writing-mode`);return{...n,body:e}}return n},Ce=async(e,t)=>{let n=await w(e);if(n){let{opf:r}=n,i=A(r.manifestItems,e,()=>``).find(e=>t.endsWith(e.href))?.mediaType;if(i)return{mediaType:i}}return{mediaType:we(t)}},we=e=>{if(e.endsWith(`.css`))return`text/css; charset=UTF-8`;if(e.endsWith(`.jpg`))return`image/jpg`;if(e.endsWith(`.xhtml`))return`application/xhtml+xml`;if(e.endsWith(`.mp4`))return`video/mp4`;if(e.endsWith(`.svg`))return`image/svg+xml`},Te=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(!r)return n;let i=await Ce(e,t);return{...n,params:{...n.params,...r?.encodingFormat&&{contentType:r.encodingFormat},...i.mediaType&&{contentType:i.mediaType}}}},q=`div.span.p.a.li.ul.ol.h1.h2.h3.h4.h5.h6.table.tr.td.th.thead.tbody.tfoot.section.article.header.footer.nav.aside.main.figure.figcaption.blockquote.pre.code.form.textarea.select.option.button.label.fieldset.legend.caption.dl.dt.dd.iframe.video.audio.canvas.script.style`.split(`.`),Ee=({archive:e,resourcePath:t})=>async n=>{let r=b(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=typeof n.body==`string`?n.body:await S(r);if(!RegExp(`<(${q.join(`|`)})[\\s/>]`,`i`).test(e))return n;let t=RegExp(`<(${q.join(`|`)})(\\s[^>]*)?\\s*/>`,`gi`),i=e.replace(t,(e,t,n=``)=>`<${t} ${n.trim()}></${t}>`);return{...n,body:i}}return n},J=async(t,n,{hooks:r=[]}={})=>{let i={params:{}},a=[...r.map(e=>e({archive:t,resourcePath:n})),Te({archive:t,resourcePath:n}),Ee({archive:t,resourcePath:n}),Se({archive:t,resourcePath:n}),xe({archive:t,resourcePath:n})];try{let r=await a.reduce(async(e,t)=>await t(await e),Promise.resolve(i));if(e.s.log(`Generated resource`,n,r),r.body!==void 0)return r;let o=b(t,n);if(!o)throw Error(`no file found for resourcePath:${n}`);return{...r,body:await o.blob()}}catch(t){throw e.s.error(t),t}},De=class{constructor(e){this.cleanArchiveAfter=e,this.state$=new a.BehaviorSubject({status:`idle`,locks:0})}update(e){this.state$.next({...this.state$.getValue(),...e})}get locks$(){return this.state$.pipe((0,a.map)(({locks:e})=>e))}get state(){return this.state$.getValue()}get isUnlocked$(){return this.locks$.pipe((0,a.map)(e=>e<=0),(0,a.distinctUntilChanged)(),(0,a.shareReplay)())}get overTTL$(){return this.isUnlocked$.pipe((0,a.switchMap)(e=>e?this.cleanArchiveAfter===1/0?a.NEVER:(0,a.timer)(this.cleanArchiveAfter):a.NEVER))}},Oe=({getArchive:t,cleanArchiveAfter:n=300*1e3})=>{let r=new a.Subject,i=new a.Subject,o=new a.Subject,s={};return r.pipe((0,a.mergeMap)(n=>{let r=s[n];if(r?.state.status!==`idle`)return a.EMPTY;let i=!1,c=t=>{e.s.debug(`Cleaning up archive with key: ${t}`);let n=s[t];delete s[t],i||=(n?.state.archive?.close(),!0)};r.update({status:`loading`});let l=r.locks$,u=r.isUnlocked$,d=l.pipe((0,a.pairwise)(),(0,a.filter)(([e,t])=>t>e),(0,a.startWith)(!0));return(0,a.from)(t(n)).pipe((0,a.tap)(e=>{r.update({archive:e,status:`success`})}),(0,a.catchError)(e=>(c(n),r.update({status:`error`,error:e}),a.EMPTY)),(0,a.switchMap)(()=>(0,a.merge)(d.pipe((0,a.switchMap)(()=>o),(0,a.switchMap)(()=>u),(0,a.filter)(e=>e)),r.overTTL$).pipe((0,a.first)(),(0,a.tap)(()=>{c(n)}))))}),(0,a.takeUntil)(i)).subscribe(),{access:e=>{let t=!1,i=s[e]??new De(n);s[e]=i,i.update({locks:i.state.locks+1});let o=()=>{t||(t=!0,i.update({locks:i.state.locks-1}))};return r.next(e),(0,a.merge)(i.state$.pipe((0,a.map)(({archive:e})=>e),(0,a.filter)(e=>!!e)),i.state$.pipe((0,a.tap)(({error:e})=>{if(e)throw e}),(0,a.ignoreElements)())).pipe((0,a.first)(),(0,a.map)(e=>({archive:e,release:o})),(0,a.catchError)(e=>{throw o(),e}))},purge:()=>{o.next()},_archives:s}},Y=e=>e?/^\d+$/.test(e)?{valid:!0,value:Number.parseInt(e,10)}:{valid:!1,value:void 0}:{valid:!0,value:void 0},ke=e=>{if(!e.toLowerCase().startsWith(`bytes=`))return{kind:`missing`};let t=e.slice(6).trim();if(!t)return{kind:`invalid`};if(t.includes(`,`))return{kind:`multi`};let n=/^(\d*)-(\d*)$/.exec(t);if(!n)return{kind:`invalid`};let[,r=``,i=``]=n,a=Y(r.trim()),o=Y(i.trim());return!a.valid||!o.valid?{kind:`invalid`}:{kind:`single`,start:a.value,end:o.value}},Ae=e=>{if(e instanceof Blob)return{size:e.size,slice:(t,n)=>{let r=e.slice(t,n);return{content:r,length:r.size}}};let t=new TextEncoder().encode(e);return{size:t.byteLength,slice:(e,n)=>{let r=t.slice(e,n);return{content:r,length:r.byteLength}}}},X=({body:e,contentType:t,rangeHeader:n})=>{let r=new Headers;if(t&&r.set(`Content-Type`,t),r.set(`Accept-Ranges`,`bytes`),!n)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let i=ke(n);if(i.kind===`missing`||i.kind===`multi`)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let a=Ae(e),o=a.size;if(i.kind===`invalid`)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let s=i.start,c=i.end;if(s===void 0&&c===void 0||(s===void 0?(s=Math.max(0,o-Math.min(c??0,o)),c=o-1):(c===void 0||c>=o)&&(c=o-1),s<0||c<0||s>=o||c>=o||s>c))return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let l=a.slice(s,c+1);return r.set(`Content-Length`,String(l.length)),r.set(`Content-Range`,`bytes ${s}-${c}/${o}`),new Response(l.content,{status:206,headers:r})},Z=`file://`,je=/^https?:\/\//,Me=e=>{try{return decodeURIComponent(e)}catch{return e}},Q=e=>e.startsWith(Z)?e.slice(Z.length):e,Ne=e=>{let t=Q(e);return je.test(t)?t:Q(Me(t))},$=class{constructor({hooks:e,onError:t,onManifestSuccess:n,...r}){this.onError=e=>(console.error(e),new Response(String(e),{status:500})),this.archiveLoader=Oe(r),this.hooks=e??{},this.onManifestSuccess=n??(({manifest:e})=>Promise.resolve(e)),this.onError=t??this.onError}prune(){this.archiveLoader.purge()}accessArchive(e){return this.lastAccessedKey!==void 0&&this.lastAccessedKey!==e&&this.archiveLoader.purge(),this.lastAccessedKey=e,this.archiveLoader.access(e)}accessArchiveWithoutLock(e){return this.accessArchive(e).pipe((0,a.map)(({archive:e,release:t})=>(t(),e)))}withArchiveResponse({key:e,getResponse:t}){return(0,a.lastValueFrom)(this.accessArchive(e).pipe((0,a.mergeMap)(({archive:e,release:n})=>(0,a.from)(t(e)).pipe((0,a.finalize)(()=>{n()}))),(0,a.catchError)(e=>(0,a.of)(this.onError(e)))))}fetchManifest({key:e,baseUrl:t}){return this.withArchiveResponse({key:e,getResponse:e=>(0,a.from)(K(e,{baseUrl:t,hooks:this.hooks.manifest})).pipe((0,a.switchMap)(t=>(0,a.from)(this.onManifestSuccess({manifest:t,archive:e}))),(0,a.map)(e=>new Response(JSON.stringify(e),{status:200})))})}fetchResource({key:e,resourcePath:t,request:n}){return this.withArchiveResponse({key:e,getResponse:e=>(0,a.from)(J(e,Ne(t),{hooks:this.hooks.resource})).pipe((0,a.map)(e=>X({body:e.body??``,contentType:e.params.contentType,rangeHeader:n?.headers.get(`range`)})))})}},Pe=class extends ${constructor({getUriInfo:e,...t}){super(t),this.getUriInfo=e,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(t){try{let n=this.getUriInfo(t);if(!n)return;let r=e.i(n.baseUrl),i=t.request.url.substring(r.length+1),[a=``]=i.split(`/`),o=e.i(i.substring(a.length+1));i.endsWith(`/manifest`)?t.respondWith(this.fetchManifest({key:a,baseUrl:`${r}/${a}/`})):t.respondWith(this.fetchResource({key:a,resourcePath:o,request:t.request}))}catch(e){t.respondWith(new Response(String(e),{status:500}))}}};exports.ServiceWorkerStreamer=Pe,exports.Streamer=$,exports.arrayBufferFileAccessors=t.t,exports.blobFileAccessors=t.n,exports.configure=ne,exports.createArchive=e.o,exports.createArchiveFromArrayBufferList=o,exports.createArchiveFromEntries=e.t,exports.createArchiveFromText=s,exports.createArchiveFromUrls=ee,exports.createManifestResourceHref=O,exports.createUniqueXmlSafeId=g,exports.createXmlSafeId=h,exports.createXmlSafeIdFactory=_,exports.generateManifestFromArchive=K,exports.generateResourceFromArchive=J,exports.getArchiveFileRecordByUri=b,exports.getArchiveHasComicInfo=x,exports.getArchiveOpfInfo=C,exports.getUriBasePath=e.n,exports.getUriBasename=e.r,exports.isDirectoryRecord=y,exports.isFileRecord=v,exports.readRecordAsText=S,exports.removeTrailingSlash=e.i,exports.sortByTitleComparator=e.a;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@prose-reader/shared"),t=require("@prose-reader/archive-reader"),n=require("xmldoc"),r=require("rxjs");var i=e.Report.namespace(`@prose-reader/streamer`,void 0,{color:`#ffae42`}),a=({enableReport:e}={})=>{i.enable(!!e)},o=t.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME.toLowerCase(),s=({archive:e})=>async n=>{let r=e.records.find(e=>!e.dir&&e.basename.toLowerCase()===o);if(!r||r.dir)return n;let i=await(0,t.readRecordAsText)(r);try{let{renditionLayout:e}=(0,t.resolveArchiveMetadata)((0,t.parseAppleDisplayOptionsXml)(i));return{...n,renditionLayout:n.renditionLayout??e}}catch(e){return console.error(`Unable to parse ${t.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME} for content\n`,i),console.error(e),n}},c=t.COMIC_INFO_FILENAME.toLowerCase(),l=({archive:e})=>async n=>{let r=(0,t.getArchiveHasComicInfo)(e);if(!r)return n;let i={...n,spineItems:n.spineItems.filter(e=>!e.id.toLowerCase().endsWith(c)).map((e,t,n)=>({...e,progressionWeight:1/n.length}))},a=await(0,t.readRecordAsText)(r);try{let e=(0,t.resolveArchiveMetadata)((0,t.parseComicInfo)(a));return{...i,readingDirection:e.readingDirection??i.readingDirection}}catch(e){return console.error(`Unable to parse ${t.COMIC_INFO_FILENAME} for content\n`,a),console.error(e),i}},u=({baseUrl:e=``,resourcePath:t})=>{if(!e&&/^https?:\/\//.test(t))return encodeURI(t);let n=e?`${e}${e.endsWith(`/`)?``:`/`}`:`file://`;return encodeURI(`${n}${t}`)},d=({archive:t,baseUrl:n})=>async()=>{let r=t.records.filter(e=>!e.dir),i=(0,e.createXmlSafeIdFactory)(),a=r.map(e=>({file:e,id:i(e.uri)}));return{filename:t.filename??``,title:t.records.find(({dir:e})=>e)?.basename.replace(/\/$/,``)||t.filename||``,renditionLayout:void 0,renditionSpread:`auto`,readingDirection:void 0,spineItems:a.filter(({file:e})=>!e.basename.endsWith(`.db`)).map(({file:e,id:t},i)=>({id:t,index:i,href:u({baseUrl:n,resourcePath:e.uri}),renditionLayout:void 0,progressionWeight:1/r.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:e.encodingFormat})),items:a.map(({file:e,id:t})=>({id:t,href:encodeURI(`${n}${e.uri}`)}))}},f=(e,n,r)=>{let{basePath:i}=(0,t.getArchiveOpfInfo)(n)||{};return e.map(e=>{let t=e.href,n=r?.(t)??``;return{href:i?`${n}${i}/${t}`:`${n}${t}`,id:e.id,mediaType:e.mediaType}})},p=e=>{let t=e?.trim();return t===`scrolled-continuous`||t===`scrolled-doc`||t===`paginated`||t===`auto`?t:`auto`},m=e=>{let t=e?.trim();if(t===`none`||t===`landscape`||t===`portrait`||t===`both`||t===`auto`)return t},h=e=>{let t=e?.trim();if(t===`cover`||t===`title-page`||t===`copyright-page`||t===`text`)return t},g=({archive:e,baseUrl:n,archiveOpf:r})=>async a=>{if(!r)return a;let{opf:o,basePath:s}=r,c=(0,t.resolveArchiveMetadata)(o);i.groupCollapsed(...i.getGroupArgs(`OPF parsed`)),i.log(`opf`,o),i.groupEnd();let l=o.renditionLayoutMeta?.trim(),u=l===`reflowable`||l===`pre-paginated`?l:c.renditionLayout,d=o.title?.trim()||e.records.find(({dir:e})=>e)?.basename||``,g=c.readingDirection??a.readingDirection,_=(await(0,t.getSpineItemFilesFromArchive)({archive:e,archiveOpf:r})).filter(t.isFileRecord).reduce((e,t)=>t.size+e,0),v=o.guide,y=[];for(let e of v){let t=h(e.type);t!==void 0&&y.push({href:e.href,title:e.title,type:t})}return{filename:e.filename??``,renditionLayout:u,renditionFlow:p(o.renditionFlowMeta),renditionSpread:m(o.renditionSpreadMeta),title:d,readingDirection:g,spineItems:o.spineRows.map((r,i)=>{let a=(0,t.getArchiveFileRecordByUri)(e,s?`${s}/${r.href}`:r.href),c=a?a.size:0,l=n||(/^https?:\/\//.test(r.href)?``:`file://`);return{id:r.id,index:i,href:r.href.startsWith(`https://`)?r.href:s?`${l}${s}/${r.href}`:`${l}${r.href}`,renditionLayout:r.renditionLayout??u,...r.renditionFlow===void 0?{}:{renditionFlow:r.renditionFlow},progressionWeight:_>0?c/_:1/o.spineRows.length,pageSpreadLeft:r.pageSpreadLeft,pageSpreadRight:r.pageSpreadRight,mediaType:r.mediaType}}),items:f(o.manifestItems,e,e=>/^https?:\/\//.test(e)?``:n||`file://`),guide:y.length>0?y:void 0}},_=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`viewport`);return!!(t&&t.attr.name===`viewport`)},v=r=>r.reduce(async(r,i)=>{if(!await r||!(0,e.isXmlBasedMimeType)({mimeType:(0,t.isFileRecord)(i)?i.encodingFormat:void 0,uri:i.uri}))return!1;let a=i.dir?null:await(0,t.readRecordAsText)(i);return a?_(new n.XmlDocument(a)):!1},Promise.resolve(!0)),y=({archive:e,archiveOpf:n})=>async r=>r.renditionLayout===`reflowable`&&r.spineItems.every(e=>e.renditionLayout===`reflowable`)&&await v(await(0,t.getSpineItemFilesFromArchive)({archive:e,archiveOpf:n}))?{...r,spineItems:r.spineItems.map(e=>({...e,renditionLayout:`pre-paginated`})),renditionLayout:`pre-paginated`}:r,b=()=>e=>({...e,readingDirection:e.readingDirection??`ltr`}),x=async e=>{let n;return await Promise.all(e.records.map(async e=>{if(e.dir||!e.uri.endsWith(t.KOBO_DISPLAY_OPTIONS_FILENAME))return;let r=await(0,t.readRecordAsText)(e);try{let{renditionLayout:e}=(0,t.parseKoboXml)(r);e&&(n=e)}catch(e){console.error(`Unable to parse ${t.KOBO_DISPLAY_OPTIONS_FILENAME} for content\n`,r),console.error(e)}})),{kind:`kobo`,...n===void 0?{}:{renditionLayout:n}}},S=({archive:e})=>async n=>{let{renditionLayout:r}=(0,t.resolveArchiveMetadata)(await x(e));return{...n,renditionLayout:n.renditionLayout??r}},C=({archive:n})=>async r=>(0,t.isArchiveEpub)(n)?r:{...r,spineItems:r.spineItems.map(r=>{let i=n.records.find(e=>decodeURI(r.href).endsWith(e.uri)),a=(0,e.parseContentType)((i&&(0,t.isFileRecord)(i)?i.encodingFormat:void 0)??``)||(0,e.detectMimeTypeFromName)(i?.basename??``);return{...r,renditionLayout:a&&(0,e.isMediaContentMimeType)(a)?`pre-paginated`:r.renditionLayout}})},w=e=>e.replace(/\.[^.]+$/,``).replace(/[_-]/g,` `).replace(/\s+/g,` `).trim(),T=(t,n)=>{if(t.spineItems.length!==0&&t.spineItems.every(t=>((0,e.parseContentType)(t.mediaType??``)||(0,e.detectMimeTypeFromName)(t.href))?.startsWith(`audio/`)))return t.spineItems.map(e=>{let t=n.records.find(t=>!t.dir&&decodeURI(e.href).endsWith(t.uri));return{title:w(t?.basename??e.href),href:e.href,path:t?.uri??e.href,contents:[]}})},E=t=>n=>({title:n.title,path:n.path,href:n.containerHref?(0,e.urlJoin)(t,n.containerHref):``,contents:n.contents.map(E(t))}),D=async(e,n,{baseUrl:r,archiveOpf:i})=>{if(i)return(await(0,t.resolveArchiveToc)(e,{opf:i})??[]).map(E(r));let a=T(n,e);if(a)return a;let o=await(0,t.resolveArchiveToc)(e);if(o)return o.map(E(r))},O=({archive:e,baseUrl:t,archiveOpf:n})=>async r=>{if(r.nav)return r;let i=await D(e,r,{baseUrl:t,archiveOpf:n});return i?{...r,nav:{toc:i}}:r},k=e=>e?e.endsWith(`/`)?e:`${e}/`:``,A=async(e,{baseUrl:n=``,hooks:r={}}={})=>{i.log(`Generating manifest from archive`,e);let a=await(0,t.readArchiveOpf)(e),o=k(n),c=t=>(t??[]).map(t=>t({archive:e,baseUrl:o})),u=[g({archive:e,baseUrl:o,archiveOpf:a}),l({archive:e,baseUrl:o}),s({archive:e,baseUrl:o}),C({archive:e,baseUrl:o}),...c(r.content)],f=c(r.spine),p=[y({archive:e,baseUrl:o,archiveOpf:a}),S({archive:e,baseUrl:o}),...c(r.presentation)],m=[O({archive:e,baseUrl:o,archiveOpf:a}),...c(r.navigation)],h=[...u,...f,...p,...m,b()];try{let t=d({archive:e,baseUrl:o})(),n=await h.reduce(async(e,t)=>await t(await e),t);if(i.log(`Generated manifest`,n),process.env.NODE_ENV===`development`&&i.isEnabled()){let e=JSON.stringify(n,null,2);i.groupCollapsed(...i.getGroupArgs(`Generated manifest`)),i.log(`\n${e}`),i.groupEnd()}return n}catch(e){throw i.error(e),e}},j=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`calibre:cover`);return!!(t&&t.attr.name===`calibre:cover`)},M=e=>e.descendantWithPath(`body`)?.descendantWithPath(`div`)?.childrenNamed(`svg`)?.find(e=>e.attr.width===`100%`&&e.attr.preserveAspectRatio===`none`),N=({archive:e,resourcePath:r})=>async i=>{let a=(0,t.getArchiveFileRecordByUri)(e,r);if(a?.basename.endsWith(`.xhtml`)){let e=new n.XmlDocument(typeof i.body==`string`?i.body:await(0,t.readRecordAsText)(a));if(j(e)){let t=M(e);return t&&delete t.attr.preserveAspectRatio,{...i,body:e?.toString()}}}return i},P=({archive:e,resourcePath:t})=>async n=>N({archive:e,resourcePath:t})(n),F=({archive:e,resourcePath:n})=>async r=>{let i=(0,t.getArchiveFileRecordByUri)(e,n);if(i?.basename.endsWith(`.css`)){let e=(typeof r.body==`string`?r.body:await(0,t.readRecordAsText)(i)).replaceAll(`-webkit-writing-mode`,`writing-mode`);return{...r,body:e}}return r},I=async(e,n)=>{let r=await(0,t.readArchiveOpf)(e);if(r){let{opf:t}=r,i=f(t.manifestItems,e,()=>``).find(e=>n.endsWith(e.href))?.mediaType;if(i)return{mediaType:i}}return{mediaType:L(n)}},L=e=>{if(e.endsWith(`.css`))return`text/css; charset=UTF-8`;if(e.endsWith(`.jpg`))return`image/jpg`;if(e.endsWith(`.xhtml`))return`application/xhtml+xml`;if(e.endsWith(`.mp4`))return`video/mp4`;if(e.endsWith(`.svg`))return`image/svg+xml`},R=({archive:e,resourcePath:n})=>async r=>{let i=(0,t.getArchiveFileRecordByUri)(e,n);if(!i)return r;let a=await I(e,n);return{...r,params:{...r.params,...i?.encodingFormat&&{contentType:i.encodingFormat},...a.mediaType&&{contentType:a.mediaType}}}},z=`div.span.p.a.li.ul.ol.h1.h2.h3.h4.h5.h6.table.tr.td.th.thead.tbody.tfoot.section.article.header.footer.nav.aside.main.figure.figcaption.blockquote.pre.code.form.textarea.select.option.button.label.fieldset.legend.caption.dl.dt.dd.iframe.video.audio.canvas.script.style`.split(`.`),B=({archive:e,resourcePath:n})=>async r=>{let i=(0,t.getArchiveFileRecordByUri)(e,n);if(i?.basename.endsWith(`.xhtml`)){let e=typeof r.body==`string`?r.body:await(0,t.readRecordAsText)(i);if(!RegExp(`<(${z.join(`|`)})[\\s/>]`,`i`).test(e))return r;let n=RegExp(`<(${z.join(`|`)})(\\s[^>]*)?\\s*/>`,`gi`),a=e.replace(n,(e,t,n=``)=>`<${t} ${n.trim()}></${t}>`);return{...r,body:a}}return r},V=async(e,n,{hooks:r=[]}={})=>{let a={params:{}},o=[...r.map(t=>t({archive:e,resourcePath:n})),R({archive:e,resourcePath:n}),B({archive:e,resourcePath:n}),F({archive:e,resourcePath:n}),P({archive:e,resourcePath:n})];try{let r=await o.reduce(async(e,t)=>await t(await e),Promise.resolve(a));if(i.log(`Generated resource`,n,r),r.body!==void 0)return r;let s=(0,t.getArchiveFileRecordByUri)(e,n);if(!s)throw Error(`no file found for resourcePath:${n}`);return{...r,body:await s.blob()}}catch(e){throw i.error(e),e}},H=class{constructor(e){this.cleanArchiveAfter=e,this.state$=new r.BehaviorSubject({status:`idle`,locks:0})}update(e){this.state$.next({...this.state$.getValue(),...e})}get locks$(){return this.state$.pipe((0,r.map)(({locks:e})=>e))}get state(){return this.state$.getValue()}get isUnlocked$(){return this.locks$.pipe((0,r.map)(e=>e<=0),(0,r.distinctUntilChanged)(),(0,r.shareReplay)())}get overTTL$(){return this.isUnlocked$.pipe((0,r.switchMap)(e=>e?this.cleanArchiveAfter===1/0?r.NEVER:(0,r.timer)(this.cleanArchiveAfter):r.NEVER))}},U=({getArchive:e,cleanArchiveAfter:t=300*1e3})=>{let n=new r.Subject,a=new r.Subject,o=new r.Subject,s={};return n.pipe((0,r.mergeMap)(t=>{let n=s[t];if(n?.state.status!==`idle`)return r.EMPTY;let a=!1,c=e=>{i.debug(`Cleaning up archive with key: ${e}`);let t=s[e];delete s[e],a||=(t?.state.archive?.close(),!0)};n.update({status:`loading`});let l=n.locks$,u=n.isUnlocked$,d=l.pipe((0,r.pairwise)(),(0,r.filter)(([e,t])=>t>e),(0,r.startWith)(!0));return(0,r.from)(e(t)).pipe((0,r.tap)(e=>{n.update({archive:e,status:`success`})}),(0,r.catchError)(e=>(c(t),n.update({status:`error`,error:e}),r.EMPTY)),(0,r.switchMap)(()=>(0,r.merge)(d.pipe((0,r.switchMap)(()=>o),(0,r.switchMap)(()=>u),(0,r.filter)(e=>e)),n.overTTL$).pipe((0,r.first)(),(0,r.tap)(()=>{c(t)}))))}),(0,r.takeUntil)(a)).subscribe(),{access:e=>{let i=!1,a=s[e]??new H(t);s[e]=a,a.update({locks:a.state.locks+1});let o=()=>{i||(i=!0,a.update({locks:a.state.locks-1}))};return n.next(e),(0,r.merge)(a.state$.pipe((0,r.map)(({archive:e})=>e),(0,r.filter)(e=>!!e)),a.state$.pipe((0,r.tap)(({error:e})=>{if(e)throw e}),(0,r.ignoreElements)())).pipe((0,r.first)(),(0,r.map)(e=>({archive:e,release:o})),(0,r.catchError)(e=>{throw o(),e}))},purge:()=>{o.next()},_archives:s}},W=e=>e?/^\d+$/.test(e)?{valid:!0,value:Number.parseInt(e,10)}:{valid:!1,value:void 0}:{valid:!0,value:void 0},G=e=>{if(!e.toLowerCase().startsWith(`bytes=`))return{kind:`missing`};let t=e.slice(6).trim();if(!t)return{kind:`invalid`};if(t.includes(`,`))return{kind:`multi`};let n=/^(\d*)-(\d*)$/.exec(t);if(!n)return{kind:`invalid`};let[,r=``,i=``]=n,a=W(r.trim()),o=W(i.trim());return!a.valid||!o.valid?{kind:`invalid`}:{kind:`single`,start:a.value,end:o.value}},K=e=>{if(e instanceof Blob)return{size:e.size,slice:(t,n)=>{let r=e.slice(t,n);return{content:r,length:r.size}}};let t=new TextEncoder().encode(e);return{size:t.byteLength,slice:(e,n)=>{let r=t.slice(e,n);return{content:r,length:r.byteLength}}}},q=({body:e,contentType:t,rangeHeader:n})=>{let r=new Headers;if(t&&r.set(`Content-Type`,t),r.set(`Accept-Ranges`,`bytes`),!n)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let i=G(n);if(i.kind===`missing`||i.kind===`multi`)return e instanceof Blob&&r.set(`Content-Length`,String(e.size)),new Response(e,{status:200,headers:r});let a=K(e),o=a.size;if(i.kind===`invalid`)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let s=i.start,c=i.end;if(s===void 0&&c===void 0||(s===void 0?(s=Math.max(0,o-Math.min(c??0,o)),c=o-1):(c===void 0||c>=o)&&(c=o-1),s<0||c<0||s>=o||c>=o||s>c))return new Response(null,{status:416,headers:{"Content-Range":`bytes */${o}`}});let l=a.slice(s,c+1);return r.set(`Content-Length`,String(l.length)),r.set(`Content-Range`,`bytes ${s}-${c}/${o}`),new Response(l.content,{status:206,headers:r})},J=`file://`,Y=/^https?:\/\//,X=e=>{try{return decodeURIComponent(e)}catch{return e}},Z=e=>e.startsWith(J)?e.slice(J.length):e,Q=e=>{let t=Z(e);return Y.test(t)?t:Z(X(t))},$=class{constructor({hooks:e,onError:t,onManifestSuccess:n,...r}){this.onError=e=>(console.error(e),new Response(String(e),{status:500})),this.archiveLoader=U(r),this.hooks=e??{},this.onManifestSuccess=n??(({manifest:e})=>Promise.resolve(e)),this.onError=t??this.onError}prune(){this.archiveLoader.purge()}accessArchive(e){return this.lastAccessedKey!==void 0&&this.lastAccessedKey!==e&&this.archiveLoader.purge(),this.lastAccessedKey=e,this.archiveLoader.access(e)}accessArchiveWithoutLock(e){return this.accessArchive(e).pipe((0,r.map)(({archive:e,release:t})=>(t(),e)))}withArchiveResponse({key:e,getResponse:t}){return(0,r.lastValueFrom)(this.accessArchive(e).pipe((0,r.mergeMap)(({archive:e,release:n})=>(0,r.from)(t(e)).pipe((0,r.finalize)(()=>{n()}))),(0,r.catchError)(e=>(0,r.of)(this.onError(e)))))}fetchManifest({key:e,baseUrl:t}){return this.withArchiveResponse({key:e,getResponse:e=>(0,r.from)(A(e,{baseUrl:t,hooks:this.hooks.manifest})).pipe((0,r.switchMap)(t=>(0,r.from)(this.onManifestSuccess({manifest:t,archive:e}))),(0,r.map)(e=>new Response(JSON.stringify(e),{status:200})))})}fetchResource({key:e,resourcePath:t,request:n}){return this.withArchiveResponse({key:e,getResponse:e=>(0,r.from)(V(e,Q(t),{hooks:this.hooks.resource})).pipe((0,r.map)(e=>q({body:e.body??``,contentType:e.params.contentType,rangeHeader:n?.headers.get(`range`)})))})}},ee=class extends ${constructor({getUriInfo:e,...t}){super(t),this.getUriInfo=e,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(t){try{let n=this.getUriInfo(t);if(!n)return;let r=(0,e.removeTrailingSlash)(n.baseUrl),i=t.request.url.substring(r.length+1),[a=``]=i.split(`/`),o=(0,e.removeTrailingSlash)(i.substring(a.length+1));i.endsWith(`/manifest`)?t.respondWith(this.fetchManifest({key:a,baseUrl:`${r}/${a}/`})):t.respondWith(this.fetchResource({key:a,resourcePath:o,request:t.request}))}catch(e){t.respondWith(new Response(String(e),{status:500}))}}};exports.ServiceWorkerStreamer=ee,exports.Streamer=$,exports.configure=a,exports.createManifestResourceHref=u,exports.generateManifestFromArchive=A,exports.generateResourceFromArchive=V;
|
|
32
2
|
//# sourceMappingURL=index.cjs.map
|