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