@prose-reader/streamer 1.283.0 → 1.285.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/index.umd.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
(function(p,
|
|
2
|
-
${o(
|
|
3
|
-
`);return o(
|
|
4
|
-
${
|
|
1
|
+
(function(p,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("@prose-reader/shared"),require("xmldoc"),require("rxjs")):typeof define=="function"&&define.amd?define(["exports","@prose-reader/shared","xmldoc","rxjs"],u):(p=typeof globalThis<"u"?globalThis:p||self,u(p["prose-streamer"]={},p.shared,p.xmldoc,p.rxjs))})(this,(function(p,u,b,c){"use strict";const R=(e,n)=>{const o=e.split(/(\d+)/),r=n.split(/(\d+)/);for(let t=0,i=o.length;t<i;t++)if(o[t]!==r[t])return o[t]?.match(/\d/)?+(o[t]||"")-+(r[t]||""):(o[t]||"").localeCompare(r[t]||"");return 1},$=e=>e.substring(e.lastIndexOf("/")+1)||e,I=e=>e.endsWith("/")?e.slice(0,-1):e,C=e=>{const n=e.lastIndexOf("/");return n>=0?e.substring(0,n):""},J=async(e,{orderByAlpha:n,name:o}={})=>{let r=e;return n&&(r=r.slice().sort((t,i)=>R(t.name,i.name))),{filename:o||"",records:r.map(t=>{const i=t.size,s=$(t.name);return t.isDir?{dir:!0,basename:s,uri:t.name,size:i}:{dir:t.isDir,basename:s,encodingFormat:u.detectMimeTypeFromName(t.name),uri:t.name,blob:async()=>new Blob([await t.data()],{type:u.detectMimeTypeFromName(t.name)??""}),string:async()=>{const a=await t.data();return String.fromCharCode.apply(null,Array.from(new Uint16Array(a)))},size:i}}),close:()=>Promise.resolve()}},f=u.Report.namespace("@prose-reader/streamer",!1,{color:"#ffae42"}),G=e=>{const n={};for(const r of e){const t=r.split("/");let i=n;for(let s=0;s<t.length;s++){const a=t[s];a!==void 0&&(i[a]||(i[a]={}),i=i[a])}}const o=(r,t="")=>Object.keys(r).sort().map((i,s,a)=>{const d=s===a.length-1,l=t+(d?"└── ":"├── "),m=t+(d?" ":"│ "),h=r[i];return h&&Object.keys(h).length>0?`${l}${i}/
|
|
2
|
+
${o(h,m)}`:`${l}${i}`}).join(`
|
|
3
|
+
`);return o(n)},K=async(e,{orderByAlpha:n,name:o}={})=>{let r=Object.values(e.files);n&&(r=r.slice().sort((i,s)=>R(i.name,s.name)));const t={filename:o||"",records:r.map(i=>{const s=i._data.uncompressedSize,a=$(i.name);return i.dir?{dir:!0,basename:a,uri:i.name,size:s}:{dir:!1,basename:$(i.name),uri:i.name,encodingFormat:u.detectMimeTypeFromName(i.name),blob:()=>i.async("blob"),string:()=>i.async("string"),...i.internalStream&&{stream:i.internalStream},size:i._data.uncompressedSize}}),close:()=>Promise.resolve()};if(f.log("Generated archive",t),process.env.NODE_ENV==="development"&&f.isEnabled()){const i=G(r.map(s=>s.name));f.groupCollapsed(...f.getGroupArgs("Archive folder structure")),f.log(`
|
|
4
|
+
${i}`),f.groupEnd()}return t},Y=async(e,{name:n}={})=>{const o=await e.getFilesArray(),r={close:()=>e.close(),filename:n??"",records:o.map(t=>({dir:!1,basename:t.file.name,encodingFormat:u.detectMimeTypeFromName(t.file.name),size:t.file.size,uri:`${t.path}${t.file.name}`,blob:async()=>await t.file.extract(),string:async()=>(await t.file.extract()).text()}))};return f.log("Generated archive",r),r},Q=async(e,{mimeType:n,direction:o}={mimeType:"text/plain"})=>{const r=`
|
|
5
5
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
6
6
|
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
|
|
7
7
|
unique-identifier="ootuya-id">
|
|
@@ -16,23 +16,23 @@ ${r}`),u.groupEnd()}return n},Y=async(t,{name:e}={})=>{const o=await t.getFilesA
|
|
|
16
16
|
<itemref idref="p01" />
|
|
17
17
|
</spine>
|
|
18
18
|
</package>
|
|
19
|
-
`;return{filename:"content.txt",records:[{dir:!1,basename:$("generated.opf"),uri:"generated.opf",blob:async()=>new Blob([
|
|
19
|
+
`;return{filename:"content.txt",records:[{dir:!1,basename:$("generated.opf"),uri:"generated.opf",blob:async()=>new Blob([r]),string:async()=>r,size:0},{dir:!1,basename:$("p01.txt"),uri:"p01.txt",blob:async()=>typeof e=="string"?new Blob([e]):e,string:async()=>typeof e=="string"?e:e.text(),size:typeof e=="string"?e.length:e.size,encodingFormat:n}],close:()=>Promise.resolve()}},Z=async(e,n)=>{const o=`
|
|
20
20
|
<?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
|
|
21
21
|
<metadata>
|
|
22
|
-
<meta property="rendition:layout">${
|
|
23
|
-
${
|
|
22
|
+
<meta property="rendition:layout">${n?.useRenditionFlow?"reflowable":"pre-paginated"}</meta>
|
|
23
|
+
${n?.useRenditionFlow?'<meta property="rendition:flow">scrolled-continuous</meta>':""}
|
|
24
24
|
</metadata>
|
|
25
25
|
<manifest>
|
|
26
|
-
${
|
|
26
|
+
${e.map(i=>`<item id="${$(i)}" href="${i}" media-type="${u.detectMimeTypeFromName(i)}"/>`).join(`
|
|
27
27
|
`)}
|
|
28
28
|
</manifest>
|
|
29
29
|
<spine>
|
|
30
|
-
${
|
|
30
|
+
${e.map(i=>`<itemref idref="${$(i)}" />`).join(`
|
|
31
31
|
`)}
|
|
32
32
|
</spine>
|
|
33
33
|
</package>
|
|
34
|
-
`,
|
|
35
|
-
`,
|
|
36
|
-
`,
|
|
37
|
-
${
|
|
34
|
+
`,r=e.map(i=>({dir:!1,basename:$(i),encodingFormat:u.detectMimeTypeFromName(i),uri:i,size:100/e.length,blob:async()=>(await fetch(i)).blob(),string:async()=>""}));return{filename:"",records:[{dir:!1,basename:"content.opf",uri:"content.opf",size:0,blob:async()=>new Blob,string:async()=>o},...r],close:()=>Promise.resolve()}},j=({enableReport:e}={})=>{f.enable(!!e)},T=e=>{const o=Object.values(e.records).filter(r=>!r.dir).find(r=>r.uri.endsWith(".opf"));return{data:o,basePath:o?.uri.substring(0,o.uri.lastIndexOf("/"))||""}},ee=({archive:e})=>async n=>{const o=e.records.find(t=>t.basename.toLowerCase()==="com.apple.ibooks.display-options.xml");if(!o||o.dir)return n;const r=await(await o.blob()).text();try{const s=new b.XmlDocument(r).childNamed("platform")?.childrenNamed("option")?.find(a=>a.attr.name==="fixed-layout")?.val||"false";return{...n,renditionLayout:s==="true"?"pre-paginated":n.renditionLayout}}catch(t){return console.error(`Unable to parse com.apple.ibooks.display-options.xml for content
|
|
35
|
+
`,r),console.error(t),n}},te=async e=>{const n={renditionLayout:void 0};return await Promise.all(e.records.map(async o=>{if(o.uri.endsWith("com.kobobooks.display-options.xml")&&!o.dir){const t=new b.XmlDocument(await o.string()).childNamed("platform")?.childNamed("option");t?.attr?.name==="fixed-layout"&&t.val==="true"&&(n.renditionLayout="pre-paginated")}})),n},ne=({archive:e})=>async n=>{const o=await te(e);return{...n,renditionLayout:n.renditionLayout??o.renditionLayout}},re=({archive:e,baseUrl:n})=>async()=>{const o=Object.values(e.records).filter(r=>!r.dir);return{filename:e.filename,title:e.records.find(({dir:r})=>r)?.basename.replace(/\/$/,"")||e.filename,renditionLayout:void 0,renditionSpread:"auto",readingDirection:"ltr",spineItems:o.filter(r=>!r.basename.endsWith(".db")).map((r,t)=>{const i=n||(/^https?:\/\//.test(r.uri)?"":"file://");return{id:`${t}.${r.basename}`,index:t,href:encodeURI(`${i}${r.uri}`),renditionLayout:void 0,progressionWeight:1/o.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:r.encodingFormat}}),items:o.map((r,t)=>({id:`${t}.${r.basename}`,href:encodeURI(`${n}${r.uri}`)}))}},P=async({archive:e})=>{const{data:n,basePath:o}=T(e)||{},r=await n?.string();if(!r)return[];const t=new b.XmlDocument(r),i=t.childNamed("manifest"),a=t.childNamed("spine")?.childrenNamed("itemref").map(m=>m.attr.idref),d=i?.childrenNamed("item").filter(m=>a.includes(m.attr.id||""))||[];return e.records.filter(m=>d.find(h=>o?`${o}/${h.attr.href}`===m.uri:`${h.attr.href}`===m.uri))},ie=e=>{const n=e.attr.properties?.split(" ")||[];let o;return n.find(r=>r==="rendition:layout-reflowable")&&(o="reflowable"),n.find(r=>r==="rendition:layout-pre-paginated")&&(o="pre-paginated"),{renditionLayout:o,pageSpreadLeft:n.some(r=>r==="page-spread-left")||void 0,pageSpreadRight:n.some(r=>r==="page-spread-right")||void 0}},oe=(e,n,o)=>{const r=e.attr.href||"",t=o?.(e);return{href:n?`${t}${n}/${r}`:`${t}${r}`,id:e.attr.id||"",mediaType:e.attr["media-type"]}},M=(e,n,o)=>{const r=e.childNamed("manifest"),{basePath:t}=T(n)||{};return r?.childrenNamed("item")?.map(i=>oe(i,t,o))||[]},se=({archive:e,baseUrl:n})=>async o=>{const{data:r,basePath:t}=T(e)||{};if(!r)return o;const i=await r.string();f.groupCollapsed(...f.getGroupArgs("OPF data")),f.log("data",i),f.groupEnd();const s=new b.XmlDocument(i),a=s.childNamed("metadata"),d=s.childNamed("manifest"),l=s.childNamed("spine"),m=s.childNamed("guide"),h=a?.childNamed("dc:title"),w=a?.childrenNamed("meta")||[],F=w.find(g=>g.attr.property==="rendition:layout"),E=w.find(g=>g.attr.property==="rendition:flow"),y=w.find(g=>g.attr.property==="rendition:spread"),L=F?.val,v=E?.val,N=y?.val,k=h?.val||e.records.find(({dir:g})=>g)?.basename||"",Oe=l?.attr["page-progression-direction"],Be=(await P({archive:e})).reduce((g,S)=>S.size+g,0);return{filename:e.filename,renditionLayout:L,renditionFlow:v||"auto",renditionSpread:N,title:k,readingDirection:Oe||"ltr",spineItems:l?.childrenNamed("itemref").map((g,S)=>{const A=d?.childrenNamed("item").find(W=>W.attr.id===g?.attr.idref),x=A?.attr.href||"",Ue=e.records.find(W=>W.uri.endsWith(x))?.size||0,H=n||(/^https?:\/\//.test(x)?"":"file://"),q=ie(g);return{...q,id:A?.attr.id||"",index:S,href:A?.attr.href?.startsWith("https://")?A?.attr.href:t?`${H}${t}/${A?.attr.href}`:`${H}${A?.attr.href}`,renditionLayout:q.renditionLayout??L,progressionWeight:Ue/Be,mediaType:A?.attr["media-type"]}})||[],items:M(s,e,g=>{const S=g.attr.href||"";return/^https?:\/\//.test(S)?"":n||"file://"}),guide:m?.childrenNamed("reference").map(g=>({href:g.attr.href||"",title:g.attr.title||"",type:g.attr.type}))}},ae=e=>{const n=e.descendantWithPath("head")?.childrenNamed("meta").find(o=>o.attr.name==="viewport");return!!(n&&n.attr.name==="viewport")},ce=e=>e.reduce(async(n,o)=>{if(!await n||!u.isXmlBasedMimeType({mimeType:o.encodingFormat,uri:o.uri}))return!1;const t=o.dir?null:await o.string();return t?ae(new b.XmlDocument(t)):!1},Promise.resolve(!0)),de=({archive:e})=>async n=>{if(n.renditionLayout==="reflowable"&&n.spineItems.every(r=>r.renditionLayout==="reflowable")){const r=await P({archive:e});if(await ce(r))return{...n,spineItems:n.spineItems.map(i=>({...i,renditionLayout:"pre-paginated"})),renditionLayout:"pre-paginated"}}return n},le=({archive:e})=>async n=>{const o=e.records.find(i=>i.basename.toLowerCase()==="comicinfo.xml"&&!i.dir);if(!o||o.dir)return n;const r={...n,spineItems:n.spineItems.filter(i=>!i.id.toLowerCase().endsWith("comicinfo.xml")).map((i,s,a)=>({...i,progressionWeight:1/a.length}))},t=await o.string();try{const s=new b.XmlDocument(t).childNamed("Manga")?.val||"unknown";return{...r,readingDirection:s==="YesAndRightToLeft"?"rtl":"ltr"}}catch(i){return console.error(`Unable to parse comicinfo.xml for content
|
|
36
|
+
`,t),console.error(i),r}},me=e=>e.records.some(n=>n.basename.endsWith(".opf")),pe=({archive:e})=>async n=>me(e)?n:{...n,spineItems:n.spineItems.map(r=>{const t=e.records.find(s=>decodeURI(r.href).endsWith(s.uri)),i=u.parseContentType(t?.encodingFormat??"")||u.detectMimeTypeFromName(t?.basename??"");return{...r,renditionLayout:i&&u.isMediaContentMimeType(i)?"pre-paginated":r.renditionLayout}})},D=e=>e?e.children.map(n=>n instanceof b.XmlTextNode?n.text:n instanceof b.XmlElement?D(n):"").join("").trim():"",z=(e,{basePath:n,baseUrl:o})=>{const r={contents:[],path:"",href:"",title:""};let t=e.childNamed("span")||e.childNamed("a");r.title=(t?.attr.title||t?.val.trim()||D(t))??"";let i=t?.name;i!=="a"&&(t=e.descendantWithPath(`${i}.a`),t&&(i=t.name.toLowerCase())),i==="a"&&t?.attr.href&&(r.path=u.urlJoin(n,t.attr.href),r.href=u.urlJoin(o,n,t.attr.href));const s=e.childNamed("ol");if(s){const a=s.childrenNamed("li");a&&a.length>0&&(r.contents=a.map(d=>z(d,{basePath:n,baseUrl:o})))}return r},ue=(e,{basePath:n,baseUrl:o})=>{const r=[];let t;return e.descendantWithPath("body.nav.ol")?t=e.descendantWithPath("body.nav.ol")?.children:e.descendantWithPath("body.section.nav.ol")&&(t=e.descendantWithPath("body.section.nav.ol")?.children),t&&t.length>0&&t.filter(i=>i.name==="li").forEach(i=>{r.push(z(i,{basePath:n,baseUrl:o}))}),r},fe=async(e,n,{baseUrl:o})=>{const r=e.childNamed("manifest")?.childrenNamed("item").find(t=>t.attr.properties==="nav");if(r){const t=Object.values(n.records).find(i=>i.uri.endsWith(r.attr.href||""));if(t&&!t.dir){const i=new b.XmlDocument(await t.string()),s=C(t.uri);return ue(i,{basePath:s,baseUrl:o})}}},O=(e,{opfBasePath:n,baseUrl:o,prefix:r})=>{const t=e?.childNamed(`${r}content`)?.attr.src||"",i={title:e?.descendantWithPath(`${r}navLabel.${r}text`)?.val||"",path:u.urlJoin(n,t),href:u.urlJoin(o,n,t),contents:[]},s=e.childrenNamed(`${r}navPoint`);return s&&s.length>0&&(i.contents=s.map(a=>O(a,{opfBasePath:n,baseUrl:o,prefix:r}))),i},he=(e,{opfBasePath:n,baseUrl:o})=>{const r=[],t=e.name;let i="";return t.indexOf(":")!==-1&&(i=`${t.split(":")[0]}:`),e.childNamed(`${i}navMap`)?.childrenNamed(`${i}navPoint`).forEach(s=>{r.push(O(s,{opfBasePath:n,baseUrl:o,prefix:i}))}),r},ge=async({opfData:e,opfBasePath:n,baseUrl:o,archive:r})=>{const i=e.childNamed("spine")?.attr.toc;if(i){const s=e.childNamed("manifest")?.childrenNamed("item").find(a=>a.attr.id===i);if(s){const a=`${n}${n===""?"":"/"}${s.attr.href}`,d=Object.values(r.records).find(l=>l.uri.endsWith(a));if(d&&!d.dir){const l=new b.XmlDocument(await d.string());return he(l,{opfBasePath:n,baseUrl:o})}}}},ye=async(e,n,{baseUrl:o})=>{const{basePath:r}=T(n)||{},t=await fe(e,n,{baseUrl:o});if(t)return t;const i=await ge({opfData:e,opfBasePath:r,archive:n,baseUrl:o});if(i)return i},be=e=>e.replace(/\.[^.]+$/,"").replace(/[_-]/g," ").replace(/\s+/g," ").trim(),ve=(e,n)=>{if(!(e.spineItems.length===0||!e.spineItems.every(r=>(u.parseContentType(r.mediaType??"")||u.detectMimeTypeFromName(r.href))?.startsWith("audio/"))))return e.spineItems.map(r=>{const t=n.records.find(i=>!i.dir&&decodeURI(r.href).endsWith(i.uri));return{title:be(t?.basename??r.href),href:r.href,path:t?.uri??r.href,contents:[]}})},we=(e,{baseUrl:n})=>{const o=[...e.records].sort((t,i)=>R(t.uri,i.uri)),r=(t,i,s,a,d)=>{const l=t.find(w=>w.title===i),[m,...h]=s;return l?m?[...t.filter(F=>F!==l),{...l,contents:[...l.contents,...r(l.contents,m,h,a,d)]}]:l.path.split("/").length>d.split("/").length?[...t.filter(F=>F!==l),{...l,path:d,href:a}]:t:m?[...t,{contents:r([],m,h,a,d),href:a,path:d,title:i}]:[...t,{contents:[],href:a,path:d,title:i}]};return o.reduce((t,i)=>{if(i.dir)return t;const s=i.uri.split("/").slice(0,-1),[a,...d]=s;if(!a)return t;const l=u.urlJoin(n,encodeURI(i.uri)).replace(/\/$/,""),m=i.uri.replace(/\/$/,"");return r(t,a,d,l,m)},[])},$e=async(e,n,{baseUrl:o})=>{const{data:r}=T(e)||{};if(r&&!r.dir){const s=new b.XmlDocument(await r.string());return await ye(s,e,{baseUrl:o})||[]}const t=ve(n,e);if(t)return t;const i=we(e,{baseUrl:o});if(i.length!==0)return i},Fe=({archive:e,baseUrl:n})=>async o=>{if(o.nav)return o;const r=await $e(e,o,{baseUrl:n});return r?{...o,nav:{toc:r}}:o},B=async(e,{baseUrl:n=""}={})=>{const o=[se({archive:e,baseUrl:n}),le({archive:e}),ee({archive:e}),pe({archive:e}),de({archive:e}),ne({archive:e}),Fe({archive:e,baseUrl:n})];try{const r=re({archive:e,baseUrl:n})(),t=await o.reduce(async(i,s)=>await s(await i),r);if(f.log("Generated manifest",t),process.env.NODE_ENV==="development"&&f.isEnabled()){const i=JSON.stringify(t,null,2);f.groupCollapsed(...f.getGroupArgs("Generated manifest")),f.log(`
|
|
37
|
+
${i}`),f.groupEnd()}return t}catch(r){throw f.error(r),r}},Te=e=>{const n=e.descendantWithPath("head")?.childrenNamed("meta").find(o=>o.attr.name==="calibre:cover");return!!(n&&n.attr.name==="calibre:cover")},Ae=e=>e.descendantWithPath("body")?.descendantWithPath("div")?.childrenNamed("svg")?.find(n=>n.attr.width==="100%"&&n.attr.preserveAspectRatio==="none"),Ne=({archive:e,resourcePath:n})=>async o=>{const r=Object.values(e.records).find(t=>t.uri===n&&!t.dir);if(r&&!r.dir&&r.basename.endsWith(".xhtml")){const t=o.body??await r.string(),i=new b.XmlDocument(t);if(Te(i)){const s=Ae(i);return s&&delete s.attr.preserveAspectRatio,{...o,body:i?.toString()}}}return o},Ee=({archive:e,resourcePath:n})=>async o=>Ne({archive:e,resourcePath:n})(o),Se=({archive:e,resourcePath:n})=>async o=>{const r=Object.values(e.records).find(t=>t.uri===n&&!t.dir);if(r&&!r.dir&&r.basename.endsWith(".css")){const i=(o.body??await r.string()).replaceAll("-webkit-writing-mode","writing-mode");return{...o,body:i}}return o},Re=async(e,n)=>{const r=await T(e).data?.string();if(r){const t=new b.XmlDocument(r),i=M(t,e,()=>"");if(i.find(a=>n.endsWith(a.href))?.mediaType)return{mediaType:i.find(a=>n.endsWith(a.href))?.mediaType}}return{mediaType:Ie(n)}},Ie=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"},Le=({archive:e,resourcePath:n})=>async o=>{const r=Object.values(e.records).find(i=>i.uri===n&&!i.dir);if(!r||r.dir)return o;const t=await Re(e,n);return{...o,params:{...o.params,...r?.encodingFormat&&{contentType:r.encodingFormat},...t.mediaType&&{contentType:t.mediaType}}}},U=["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"],ke=({archive:e,resourcePath:n})=>async o=>{const r=Object.values(e.records).find(t=>t.uri===n&&!t.dir);if(r&&!r.dir&&r.basename.endsWith(".xhtml")){const t=o.body??await r.string();if(!new RegExp(`<(${U.join("|")})[\\s/>]`,"i").test(t))return o;const s=new RegExp(`<(${U.join("|")})(\\s[^>]*)?\\s*/>`,"gi"),a=t.replace(s,(d,l,m="")=>`<${l} ${m.trim()}></${l}>`);return{...o,body:a}}return o},X=async(e,n)=>{const o=Object.values(e.records).find(i=>i.uri===n&&!i.dir);if(!o||o.dir)throw new Error(`no file found for resourcePath:${n}`);const r={params:{}},t=[Le({archive:e,resourcePath:n}),ke({archive:e,resourcePath:n}),Se({archive:e,resourcePath:n}),Ee({archive:e,resourcePath:n})];try{const i=await t.reduce(async(s,a)=>await a(await s),Promise.resolve(r));return f.log("Generated resource",n,i),{...i,body:i.body??await o.blob()}}catch(i){throw f.error(i),i}};class We{constructor(n){this.cleanArchiveAfter=n,this.state$=new c.BehaviorSubject({status:"idle",locks:0})}update(n){this.state$.next({...this.state$.getValue(),...n})}get locks$(){return this.state$.pipe(c.map(({locks:n})=>n))}get state(){return this.state$.getValue()}get isUnlocked$(){return this.locks$.pipe(c.map(n=>n<=0),c.distinctUntilChanged(),c.shareReplay())}get overTTL$(){return this.isUnlocked$.pipe(c.switchMap(n=>n?this.cleanArchiveAfter===1/0?c.NEVER:c.timer(this.cleanArchiveAfter):c.NEVER))}}const Ce=({getArchive:e,cleanArchiveAfter:n=300*1e3})=>{const o=new c.Subject,r=new c.Subject,t=new c.Subject,i={},s=o.pipe(c.mergeMap(l=>{const m=i[l];if(!m||m.state.status!=="idle")return c.EMPTY;let h=!1;const w=v=>{f.debug(`Cleaning up archive with key: ${v}`);const N=i[v];delete i[v],h||(N?.state.archive?.close(),h=!0)};m.update({status:"loading"});const F=m.locks$,E=m.isUnlocked$,y=F.pipe(c.pairwise(),c.filter(([v,N])=>N>v),c.startWith(!0));return c.from(e(l)).pipe(c.tap(v=>{m.update({archive:v,status:"success"})}),c.catchError(v=>(w(l),m.update({status:"error",error:v}),c.EMPTY)),c.switchMap(()=>{const v=y.pipe(c.switchMap(()=>t),c.switchMap(()=>E),c.filter(k=>k));return c.merge(v,m.overTTL$).pipe(c.first(),c.tap(()=>{w(l)}))}))}),c.takeUntil(r)),a=l=>{let m=!1;const h=i[l]??new We(n);i[l]=h,h.update({locks:h.state.locks+1});const w=()=>{m||(m=!0,h.update({locks:h.state.locks-1}))};o.next(l);const F=h.state$.pipe(c.map(({archive:y})=>y),c.filter(y=>!!y)),E=h.state$.pipe(c.tap(({error:y})=>{if(y)throw y}),c.ignoreElements());return c.merge(F,E).pipe(c.first(),c.map(y=>({archive:y,release:w})),c.catchError(y=>{throw w(),y}))},d=()=>{t.next()};return s.subscribe(),{access:a,purge:d,_archives:i}},V=e=>e?/^\d+$/.test(e)?{valid:!0,value:Number.parseInt(e,10)}:{valid:!1,value:void 0}:{valid:!0,value:void 0},Pe=e=>{if(!e.toLowerCase().startsWith("bytes="))return{kind:"missing"};const n=e.slice(6).trim();if(!n)return{kind:"invalid"};if(n.includes(","))return{kind:"multi"};const o=/^(\d*)-(\d*)$/.exec(n);if(!o)return{kind:"invalid"};const[,r="",t=""]=o,i=V(r.trim()),s=V(t.trim());return!i.valid||!s.valid?{kind:"invalid"}:{kind:"single",start:i.value,end:s.value}},Me=e=>{if(e instanceof Blob)return{size:e.size,slice:(o,r)=>{const t=e.slice(o,r);return{content:t,length:t.size}}};const n=new TextEncoder().encode(e);return{size:n.byteLength,slice:(o,r)=>{const t=n.slice(o,r);return{content:t,length:t.byteLength}}}},De=({body:e,contentType:n,rangeHeader:o})=>{const r=new Headers;if(n&&r.set("Content-Type",n),r.set("Accept-Ranges","bytes"),!o)return e instanceof Blob&&r.set("Content-Length",String(e.size)),new Response(e,{status:200,headers:r});const t=Pe(o);if(t.kind==="missing"||t.kind==="multi")return e instanceof Blob&&r.set("Content-Length",String(e.size)),new Response(e,{status:200,headers:r});const i=Me(e),s=i.size;if(t.kind==="invalid")return new Response(null,{status:416,headers:{"Content-Range":`bytes */${s}`}});let a=t.start,d=t.end;if(a===void 0&&d===void 0)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${s}`}});if(a===void 0){const m=Math.min(d??0,s);a=Math.max(0,s-m),d=s-1}else(d===void 0||d>=s)&&(d=s-1);if(a<0||d<0||a>=s||d>=s||a>d)return new Response(null,{status:416,headers:{"Content-Range":`bytes */${s}`}});const l=i.slice(a,d+1);return r.set("Content-Length",String(l.length)),r.set("Content-Range",`bytes ${a}-${d}/${s}`),new Response(l.content,{status:206,headers:r})};class _{constructor({onError:n,onManifestSuccess:o,...r}){this.onError=t=>(console.error(t),new Response(String(t),{status:500})),this.epubLoader=Ce(r),this.onManifestSuccess=o??(({manifest:t})=>Promise.resolve(t)),this.onError=n??this.onError}prune(){this.epubLoader.purge()}accessArchive(n){return this.lastAccessedKey!==void 0&&this.lastAccessedKey!==n&&this.epubLoader.purge(),this.lastAccessedKey=n,this.epubLoader.access(n)}accessArchiveWithoutLock(n){return this.accessArchive(n).pipe(c.map(({archive:o,release:r})=>(r(),o)))}withArchiveResponse({key:n,getResponse:o}){const r=this.accessArchive(n).pipe(c.mergeMap(({archive:t,release:i})=>c.from(o(t)).pipe(c.finalize(()=>{i()}))),c.catchError(t=>c.of(this.onError(t))));return c.lastValueFrom(r)}fetchManifest({key:n,baseUrl:o}){return this.withArchiveResponse({key:n,getResponse:r=>c.from(B(r,{baseUrl:o})).pipe(c.switchMap(i=>c.from(this.onManifestSuccess({manifest:i,archive:r}))),c.map(i=>new Response(JSON.stringify(i),{status:200})))})}fetchResource({key:n,resourcePath:o,request:r}){return this.withArchiveResponse({key:n,getResponse:t=>{const i=o.replaceAll("file://","");return c.from(X(t,i)).pipe(c.map(a=>De({body:a.body??"",contentType:a.params.contentType,rangeHeader:r?.headers.get("range")})))}})}}class ze extends _{constructor({getUriInfo:n,...o}){super(o),this.getUriInfo=n,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(n){try{const o=this.getUriInfo(n);if(!o)return;const r=I(o.baseUrl),t=n.request.url.substring(r.length+1),[i=""]=t.split("/"),s=decodeURIComponent(I(t.substring(i.length+1)));t.endsWith("/manifest")?n.respondWith(this.fetchManifest({key:i,baseUrl:`${r}/${i}/`})):n.respondWith(this.fetchResource({key:i,resourcePath:s,request:n.request}))}catch(o){n.respondWith(new Response(String(o),{status:500}))}}}p.ServiceWorkerStreamer=ze,p.Streamer=_,p.configure=j,p.createArchiveFromArrayBufferList=J,p.createArchiveFromJszip=K,p.createArchiveFromLibArchive=Y,p.createArchiveFromText=Q,p.createArchiveFromUrls=Z,p.generateManifestFromArchive=B,p.generateResourceFromArchive=X,p.getArchiveOpfInfo=T,p.getUriBasePath=C,p.getUriBasename=$,p.removeTrailingSlash=I,p.sortByTitleComparator=R,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})}));
|
|
38
38
|
//# sourceMappingURL=index.umd.cjs.map
|