@prose-reader/streamer 1.305.0 → 1.307.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/archives/createArchive.d.ts +10 -0
- package/dist/archives/createArchiveFromJszip/index.cjs.js +2 -0
- package/dist/archives/createArchiveFromJszip/index.cjs.js.map +1 -0
- package/dist/archives/createArchiveFromJszip/index.es.js +39 -0
- package/dist/archives/createArchiveFromJszip/index.es.js.map +1 -0
- package/dist/archives/createArchiveFromJszip.d.ts +2 -29
- package/dist/archives/createArchiveFromLibArchive/index.cjs.js +2 -0
- package/dist/archives/createArchiveFromLibArchive/index.cjs.js.map +1 -0
- package/dist/archives/createArchiveFromLibArchive/index.es.js +24 -0
- package/dist/archives/createArchiveFromLibArchive/index.es.js.map +1 -0
- package/dist/archives/createArchiveFromLibArchive.d.ts +3 -10
- package/dist/archives/createArchiveFromText.d.ts +1 -2
- package/dist/archives/createArchiveFromUnzipper/index.cjs.js +2 -0
- package/dist/archives/createArchiveFromUnzipper/index.cjs.js.map +1 -0
- package/dist/archives/createArchiveFromUnzipper/index.es.js +42 -0
- package/dist/archives/createArchiveFromUnzipper/index.es.js.map +1 -0
- package/dist/archives/createArchiveFromUnzipper.d.ts +7 -0
- package/dist/archives/fileAccessors.d.ts +15 -0
- package/dist/archives/readRecordAsText.d.ts +7 -0
- package/dist/archives/types.d.ts +21 -14
- package/dist/epubs/getSpineItemFilesFromArchive.d.ts +1 -1
- package/dist/fileAccessors-DWVChFUB.cjs +2 -0
- package/dist/fileAccessors-DWVChFUB.cjs.map +1 -0
- package/dist/fileAccessors-etcCPnpQ.js +12 -0
- package/dist/fileAccessors-etcCPnpQ.js.map +1 -0
- package/dist/index/index.cjs.js +32 -0
- package/dist/index/index.cjs.js.map +1 -0
- package/dist/index/index.es.js +827 -0
- package/dist/index/index.es.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/printTree-CJzGASVu.js +20 -0
- package/dist/printTree-CJzGASVu.js.map +1 -0
- package/dist/printTree-DTFYKvW1.cjs +3 -0
- package/dist/printTree-DTFYKvW1.cjs.map +1 -0
- package/dist/report-Cs9DVdJl.cjs +2 -0
- package/dist/report-Cs9DVdJl.cjs.map +1 -0
- package/dist/report-uURLD5cl.js +15 -0
- package/dist/report-uURLD5cl.js.map +1 -0
- package/dist/uri-DBZYnB1I.js +13 -0
- package/dist/uri-DBZYnB1I.js.map +1 -0
- package/dist/uri-DW0-P-ng.cjs +2 -0
- package/dist/uri-DW0-P-ng.cjs.map +1 -0
- package/package.json +44 -10
- package/dist/index.js +0 -899
- package/dist/index.js.map +0 -1
- package/dist/index.umd.cjs +0 -33
- package/dist/index.umd.cjs.map +0 -1
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Archive } from './types';
|
|
2
|
+
type ArchiveInit = Omit<Archive, "recordsByUri">;
|
|
3
|
+
/**
|
|
4
|
+
* Builds an {@link Archive} from its records and derives the `recordsByUri`
|
|
5
|
+
* lookup index once, so consumers resolve records in O(1) on the hot path
|
|
6
|
+
* instead of scanning {@link Archive.records}. Duplicate URIs keep the first
|
|
7
|
+
* record, matching the previous `Array.prototype.find` semantics.
|
|
8
|
+
*/
|
|
9
|
+
export declare const createArchive: ({ records, ...rest }: ArchiveInit) => Archive;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../report-Cs9DVdJl.cjs"),t=require("../../uri-DW0-P-ng.cjs"),n=require("../../printTree-DTFYKvW1.cjs");let r=require("@prose-reader/shared");var i=async(i,{orderByAlpha:a,name:o,encodingFormat:s}={})=>{let c=Object.values(i.files);a&&(c=c.slice().sort((e,n)=>t.i(e.name,n.name)));let l=e.n({filename:o,encodingFormat:s,records:c.map(e=>{let n=t.n(e.name);return e.dir?{dir:!0,basename:n,uri:e.name}:{dir:!1,basename:t.n(e.name),uri:e.name,encodingFormat:(0,r.detectMimeTypeFromName)(e.name),blob:()=>e.async(`blob`),arrayBuffer:()=>e.async(`arraybuffer`),size:e._data.uncompressedSize}}),close:()=>Promise.resolve()});if(e.t.log(`Generated archive`,l),process.env.NODE_ENV===`development`&&e.t.isEnabled()){let t=n.t(c.map(e=>e.name));e.t.groupCollapsed(...e.t.getGroupArgs(`Archive folder structure`)),e.t.log(`\n${t}`),e.t.groupEnd()}return l};exports.createArchiveFromJszip=i;
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","names":[],"sources":["../../../src/archives/createArchiveFromJszip.ts"],"sourcesContent":["import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport type JSZip from \"jszip\"\nimport { Report } from \"../report\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport { printTree } from \"./printTree\"\nimport type { Archive } from \"./types\"\n\nexport const createArchiveFromJszip = async (\n jszip: JSZip,\n {\n orderByAlpha,\n name,\n encodingFormat,\n }: { orderByAlpha?: boolean; name?: string; encodingFormat?: string } = {},\n): Promise<Archive> => {\n let files = Object.values(jszip.files)\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.name, b.name))\n }\n\n const archive = createArchive({\n filename: name,\n encodingFormat,\n records: files.map((file) => {\n const basename = getUriBasename(file.name)\n\n if (file.dir) {\n return {\n dir: true,\n basename,\n uri: file.name,\n }\n }\n\n return {\n dir: false,\n basename: getUriBasename(file.name),\n uri: file.name,\n encodingFormat: detectMimeTypeFromName(file.name),\n blob: () => file.async(`blob`),\n arrayBuffer: () => file.async(`arraybuffer`),\n // this is private API\n // @ts-expect-error\n size: file._data.uncompressedSize,\n }\n }),\n close: () => Promise.resolve(),\n })\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(files.map((file) => file.name))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n"],"mappings":"oOASA,IAAa,EAAyB,MACpC,EACA,CACE,eACA,OACA,kBACsE,CAAC,IACpD,CACrB,IAAI,EAAQ,OAAO,OAAO,EAAM,KAAK,EAEjC,IACF,EAAQ,EAAM,MAAM,EAAE,MAAM,EAAG,IAAM,EAAA,EAAsB,EAAE,KAAM,EAAE,IAAI,CAAC,GAG5E,IAAM,EAAU,EAAA,EAAc,CAC5B,SAAU,EACV,iBACA,QAAS,EAAM,IAAK,GAAS,CAC3B,IAAM,EAAW,EAAA,EAAe,EAAK,IAAI,EAUzC,OARI,EAAK,IACA,CACL,IAAK,GACL,WACA,IAAK,EAAK,IACZ,EAGK,CACL,IAAK,GACL,SAAU,EAAA,EAAe,EAAK,IAAI,EAClC,IAAK,EAAK,KACV,gBAAA,EAAA,EAAA,wBAAuC,EAAK,IAAI,EAChD,SAAY,EAAK,MAAM,MAAM,EAC7B,gBAAmB,EAAK,MAAM,aAAa,EAG3C,KAAM,EAAK,MAAM,gBACnB,CACF,CAAC,EACD,UAAa,QAAQ,QAAQ,CAC/B,CAAC,EAID,GAFA,EAAA,EAAO,IAAI,oBAAqB,CAAO,EAEvC,QAAA,IAAA,WAA6B,eACvB,EAAA,EAAO,UAAU,EAAG,CACtB,IAAM,EAAqB,EAAA,EAAU,EAAM,IAAK,GAAS,EAAK,IAAI,CAAC,EACnE,EAAA,EAAO,eAAe,GAAG,EAAA,EAAO,aAAa,0BAA0B,CAAC,EACxE,EAAA,EAAO,IAAI,KAAK,GAAoB,EACpC,EAAA,EAAO,SAAS,CAClB,CAGF,OAAO,CACT"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { n as e, t } from "../../report-uURLD5cl.js";
|
|
2
|
+
import { i as n, n as r } from "../../uri-DBZYnB1I.js";
|
|
3
|
+
import { t as i } from "../../printTree-CJzGASVu.js";
|
|
4
|
+
import { detectMimeTypeFromName as a } from "@prose-reader/shared";
|
|
5
|
+
//#region src/archives/createArchiveFromJszip.ts
|
|
6
|
+
var o = async (o, { orderByAlpha: s, name: c, encodingFormat: l } = {}) => {
|
|
7
|
+
let u = Object.values(o.files);
|
|
8
|
+
s && (u = u.slice().sort((e, t) => n(e.name, t.name)));
|
|
9
|
+
let d = e({
|
|
10
|
+
filename: c,
|
|
11
|
+
encodingFormat: l,
|
|
12
|
+
records: u.map((e) => {
|
|
13
|
+
let t = r(e.name);
|
|
14
|
+
return e.dir ? {
|
|
15
|
+
dir: !0,
|
|
16
|
+
basename: t,
|
|
17
|
+
uri: e.name
|
|
18
|
+
} : {
|
|
19
|
+
dir: !1,
|
|
20
|
+
basename: r(e.name),
|
|
21
|
+
uri: e.name,
|
|
22
|
+
encodingFormat: a(e.name),
|
|
23
|
+
blob: () => e.async("blob"),
|
|
24
|
+
arrayBuffer: () => e.async("arraybuffer"),
|
|
25
|
+
size: e._data.uncompressedSize
|
|
26
|
+
};
|
|
27
|
+
}),
|
|
28
|
+
close: () => Promise.resolve()
|
|
29
|
+
});
|
|
30
|
+
if (t.log("Generated archive", d), process.env.NODE_ENV === "development" && t.isEnabled()) {
|
|
31
|
+
let e = i(u.map((e) => e.name));
|
|
32
|
+
t.groupCollapsed(...t.getGroupArgs("Archive folder structure")), t.log(`\n${e}`), t.groupEnd();
|
|
33
|
+
}
|
|
34
|
+
return d;
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { o as createArchiveFromJszip };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","names":[],"sources":["../../../src/archives/createArchiveFromJszip.ts"],"sourcesContent":["import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport type JSZip from \"jszip\"\nimport { Report } from \"../report\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport { printTree } from \"./printTree\"\nimport type { Archive } from \"./types\"\n\nexport const createArchiveFromJszip = async (\n jszip: JSZip,\n {\n orderByAlpha,\n name,\n encodingFormat,\n }: { orderByAlpha?: boolean; name?: string; encodingFormat?: string } = {},\n): Promise<Archive> => {\n let files = Object.values(jszip.files)\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.name, b.name))\n }\n\n const archive = createArchive({\n filename: name,\n encodingFormat,\n records: files.map((file) => {\n const basename = getUriBasename(file.name)\n\n if (file.dir) {\n return {\n dir: true,\n basename,\n uri: file.name,\n }\n }\n\n return {\n dir: false,\n basename: getUriBasename(file.name),\n uri: file.name,\n encodingFormat: detectMimeTypeFromName(file.name),\n blob: () => file.async(`blob`),\n arrayBuffer: () => file.async(`arraybuffer`),\n // this is private API\n // @ts-expect-error\n size: file._data.uncompressedSize,\n }\n }),\n close: () => Promise.resolve(),\n })\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(files.map((file) => file.name))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n"],"mappings":";;;;;AASA,IAAa,IAAyB,OACpC,GACA,EACE,iBACA,SACA,sBACsE,CAAC,MACpD;CACrB,IAAI,IAAQ,OAAO,OAAO,EAAM,KAAK;CAErC,AAAI,MACF,IAAQ,EAAM,MAAM,EAAE,MAAM,GAAG,MAAM,EAAsB,EAAE,MAAM,EAAE,IAAI,CAAC;CAG5E,IAAM,IAAU,EAAc;EAC5B,UAAU;EACV;EACA,SAAS,EAAM,KAAK,MAAS;GAC3B,IAAM,IAAW,EAAe,EAAK,IAAI;GAUzC,OARI,EAAK,MACA;IACL,KAAK;IACL;IACA,KAAK,EAAK;GACZ,IAGK;IACL,KAAK;IACL,UAAU,EAAe,EAAK,IAAI;IAClC,KAAK,EAAK;IACV,gBAAgB,EAAuB,EAAK,IAAI;IAChD,YAAY,EAAK,MAAM,MAAM;IAC7B,mBAAmB,EAAK,MAAM,aAAa;IAG3C,MAAM,EAAK,MAAM;GACnB;EACF,CAAC;EACD,aAAa,QAAQ,QAAQ;CAC/B,CAAC;CAID,IAFA,EAAO,IAAI,qBAAqB,CAAO,GAEvC,QAAA,IAAA,aAA6B,iBACvB,EAAO,UAAU,GAAG;EACtB,IAAM,IAAqB,EAAU,EAAM,KAAK,MAAS,EAAK,IAAI,CAAC;EAGnE,AAFA,EAAO,eAAe,GAAG,EAAO,aAAa,0BAA0B,CAAC,GACxE,EAAO,IAAI,KAAK,GAAoB,GACpC,EAAO,SAAS;CAClB;CAGF,OAAO;AACT"}
|
|
@@ -1,34 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
base64: string;
|
|
4
|
-
string: string;
|
|
5
|
-
text: string;
|
|
6
|
-
binarystring: string;
|
|
7
|
-
array: number[];
|
|
8
|
-
uint8array: Uint8Array;
|
|
9
|
-
arraybuffer: ArrayBuffer;
|
|
10
|
-
blob: Blob;
|
|
11
|
-
nodebuffer: Buffer;
|
|
12
|
-
}
|
|
13
|
-
type OutputType = keyof OutputByType;
|
|
14
|
-
interface JSZipObject {
|
|
15
|
-
name: string;
|
|
16
|
-
dir: boolean;
|
|
17
|
-
date: Date;
|
|
18
|
-
comment: string;
|
|
19
|
-
unixPermissions: number | string | null;
|
|
20
|
-
dosPermissions: number | null;
|
|
21
|
-
async<T extends OutputType>(type: T): Promise<OutputByType[T]>;
|
|
22
|
-
internalStream?: (type?: `uint8array`) => StreamResult;
|
|
23
|
-
}
|
|
24
|
-
interface JSZip {
|
|
25
|
-
files: {
|
|
26
|
-
[key: string]: JSZipObject;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
1
|
+
import { default as JSZip } from 'jszip';
|
|
2
|
+
import { Archive } from './types';
|
|
29
3
|
export declare const createArchiveFromJszip: (jszip: JSZip, { orderByAlpha, name, encodingFormat, }?: {
|
|
30
4
|
orderByAlpha?: boolean;
|
|
31
5
|
name?: string;
|
|
32
6
|
encodingFormat?: string;
|
|
33
7
|
}) => Promise<Archive>;
|
|
34
|
-
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../report-Cs9DVdJl.cjs"),t=require("../../fileAccessors-DWVChFUB.cjs");let n=require("@prose-reader/shared");var r=async(r,{name:i,encodingFormat:a})=>{let o=e.n({close:()=>r.close(),filename:i,encodingFormat:a,records:(await r.getFilesArray()).map(e=>({dir:!1,basename:e.file.name,encodingFormat:(0,n.detectMimeTypeFromName)(e.file.name),size:e.file.size,uri:`${e.path}${e.file.name}`,...t.n(()=>e.file.extract())}))});return e.t.log(`Generated archive`,o),o};exports.createArchiveFromLibArchive=r;
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","names":[],"sources":["../../../src/archives/createArchiveFromLibArchive.ts"],"sourcesContent":["/**\n * @see https://github.com/nika-begiashvili/libarchivejs.\n *\n * Does not work in service worker due to usage of web worker.\n */\nimport { detectMimeTypeFromName } from \"@prose-reader/shared\"\n// libarchive.js only re-exports `Archive` from its package root; the reader and\n// compressed-file types live in the compiled output, so we reach for them there.\nimport type { ArchiveReader } from \"libarchive.js/dist/build/compiled/archive-reader\"\nimport type { CompressedFile } from \"libarchive.js/dist/build/compiled/compressed-file\"\nimport { Report } from \"../report\"\nimport { createArchive } from \"./createArchive\"\nimport { blobFileAccessors } from \"./fileAccessors\"\nimport type { Archive } from \"./types\"\n\nexport const createArchiveFromLibArchive = async (\n libArchive: ArchiveReader,\n {\n name,\n encodingFormat,\n }: { orderByAlpha?: boolean; name: string; encodingFormat?: string },\n): Promise<Archive> => {\n const objArray = await libArchive.getFilesArray()\n\n const archive = createArchive({\n close: () => libArchive.close(),\n filename: name,\n encodingFormat,\n records: objArray.map((item: { file: CompressedFile; path: string }) => ({\n dir: false,\n basename: item.file.name,\n encodingFormat: detectMimeTypeFromName(item.file.name),\n size: item.file.size,\n uri: `${item.path}${item.file.name}`,\n // libarchivejs `extract()` is typed `any`; it resolves to a `File`.\n ...blobFileAccessors(() => item.file.extract() as Promise<File>),\n })),\n })\n\n Report.log(\"Generated archive\", archive)\n\n return archive\n}\n"],"mappings":"oMAeA,IAAa,EAA8B,MACzC,EACA,CACE,OACA,oBAEmB,CAGrB,IAAM,EAAU,EAAA,EAAc,CAC5B,UAAa,EAAW,MAAM,EAC9B,SAAU,EACV,iBACA,SAAS,MANY,EAAW,cAAc,GAM5B,IAAK,IAAkD,CACvE,IAAK,GACL,SAAU,EAAK,KAAK,KACpB,gBAAA,EAAA,EAAA,wBAAuC,EAAK,KAAK,IAAI,EACrD,KAAM,EAAK,KAAK,KAChB,IAAK,GAAG,EAAK,OAAO,EAAK,KAAK,OAE9B,GAAG,EAAA,MAAwB,EAAK,KAAK,QAAQ,CAAkB,CACjE,EAAE,CACJ,CAAC,EAID,OAFA,EAAA,EAAO,IAAI,oBAAqB,CAAO,EAEhC,CACT"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { n as e, t } from "../../report-uURLD5cl.js";
|
|
2
|
+
import { n } from "../../fileAccessors-etcCPnpQ.js";
|
|
3
|
+
import { detectMimeTypeFromName as r } from "@prose-reader/shared";
|
|
4
|
+
//#region src/archives/createArchiveFromLibArchive.ts
|
|
5
|
+
var i = async (i, { name: a, encodingFormat: o }) => {
|
|
6
|
+
let s = e({
|
|
7
|
+
close: () => i.close(),
|
|
8
|
+
filename: a,
|
|
9
|
+
encodingFormat: o,
|
|
10
|
+
records: (await i.getFilesArray()).map((e) => ({
|
|
11
|
+
dir: !1,
|
|
12
|
+
basename: e.file.name,
|
|
13
|
+
encodingFormat: r(e.file.name),
|
|
14
|
+
size: e.file.size,
|
|
15
|
+
uri: `${e.path}${e.file.name}`,
|
|
16
|
+
...n(() => e.file.extract())
|
|
17
|
+
}))
|
|
18
|
+
});
|
|
19
|
+
return t.log("Generated archive", s), s;
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { i as createArchiveFromLibArchive };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","names":[],"sources":["../../../src/archives/createArchiveFromLibArchive.ts"],"sourcesContent":["/**\n * @see https://github.com/nika-begiashvili/libarchivejs.\n *\n * Does not work in service worker due to usage of web worker.\n */\nimport { detectMimeTypeFromName } from \"@prose-reader/shared\"\n// libarchive.js only re-exports `Archive` from its package root; the reader and\n// compressed-file types live in the compiled output, so we reach for them there.\nimport type { ArchiveReader } from \"libarchive.js/dist/build/compiled/archive-reader\"\nimport type { CompressedFile } from \"libarchive.js/dist/build/compiled/compressed-file\"\nimport { Report } from \"../report\"\nimport { createArchive } from \"./createArchive\"\nimport { blobFileAccessors } from \"./fileAccessors\"\nimport type { Archive } from \"./types\"\n\nexport const createArchiveFromLibArchive = async (\n libArchive: ArchiveReader,\n {\n name,\n encodingFormat,\n }: { orderByAlpha?: boolean; name: string; encodingFormat?: string },\n): Promise<Archive> => {\n const objArray = await libArchive.getFilesArray()\n\n const archive = createArchive({\n close: () => libArchive.close(),\n filename: name,\n encodingFormat,\n records: objArray.map((item: { file: CompressedFile; path: string }) => ({\n dir: false,\n basename: item.file.name,\n encodingFormat: detectMimeTypeFromName(item.file.name),\n size: item.file.size,\n uri: `${item.path}${item.file.name}`,\n // libarchivejs `extract()` is typed `any`; it resolves to a `File`.\n ...blobFileAccessors(() => item.file.extract() as Promise<File>),\n })),\n })\n\n Report.log(\"Generated archive\", archive)\n\n return archive\n}\n"],"mappings":";;;;AAeA,IAAa,IAA8B,OACzC,GACA,EACE,SACA,wBAEmB;CAGrB,IAAM,IAAU,EAAc;EAC5B,aAAa,EAAW,MAAM;EAC9B,UAAU;EACV;EACA,UAAS,MANY,EAAW,cAAc,GAM5B,KAAK,OAAkD;GACvE,KAAK;GACL,UAAU,EAAK,KAAK;GACpB,gBAAgB,EAAuB,EAAK,KAAK,IAAI;GACrD,MAAM,EAAK,KAAK;GAChB,KAAK,GAAG,EAAK,OAAO,EAAK,KAAK;GAE9B,GAAG,QAAwB,EAAK,KAAK,QAAQ,CAAkB;EACjE,EAAE;CACJ,CAAC;CAID,OAFA,EAAO,IAAI,qBAAqB,CAAO,GAEhC;AACT"}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
+
import { ArchiveReader } from 'libarchive.js/dist/build/compiled/archive-reader';
|
|
1
2
|
import { Archive } from './types';
|
|
2
|
-
|
|
3
|
-
getFilesArray(): Promise<any[]>;
|
|
4
|
-
/**
|
|
5
|
-
* Terminate worker to free up memory
|
|
6
|
-
*/
|
|
7
|
-
close(): Promise<void>;
|
|
8
|
-
}
|
|
9
|
-
export declare const createArchiveFromLibArchive: (libArchive: ArchiveReader, { name, encodingFormat, }?: {
|
|
3
|
+
export declare const createArchiveFromLibArchive: (libArchive: ArchiveReader, { name, encodingFormat, }: {
|
|
10
4
|
orderByAlpha?: boolean;
|
|
11
|
-
name
|
|
5
|
+
name: string;
|
|
12
6
|
encodingFormat?: string;
|
|
13
7
|
}) => Promise<Archive>;
|
|
14
|
-
export {};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { Archive } from './types';
|
|
2
1
|
/**
|
|
3
2
|
* Useful to create archive from txt content
|
|
4
3
|
*/
|
|
5
4
|
export declare const createArchiveFromText: (content: string | Blob, { mimeType, direction, }?: {
|
|
6
5
|
direction?: `ltr` | `rtl`;
|
|
7
6
|
mimeType?: string;
|
|
8
|
-
}) => Promise<Archive>;
|
|
7
|
+
}) => Promise<import('./types').Archive>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../report-Cs9DVdJl.cjs"),t=require("../../uri-DW0-P-ng.cjs"),n=require("../../fileAccessors-DWVChFUB.cjs"),r=require("../../printTree-DTFYKvW1.cjs");let i=require("@prose-reader/shared");var a=async(a,{orderByAlpha:o,name:s,encodingFormat:c}={})=>{let l=a.files;o&&(l=l.slice().sort((e,n)=>t.i(e.path,n.path)));let u=e.n({filename:s,encodingFormat:c,records:l.map(e=>{let r=t.n(e.path);return e.type===`Directory`?{dir:!0,basename:r,uri:e.path}:{dir:!1,basename:r,uri:e.path,encodingFormat:(0,i.detectMimeTypeFromName)(e.path),size:e.uncompressedSize,...n.t(async()=>{let t=await e.buffer(),n=t.buffer;return t.byteOffset===0&&t.byteLength===n.byteLength?n:n.slice(t.byteOffset,t.byteOffset+t.byteLength)},(0,i.detectMimeTypeFromName)(e.path)??``)}}),close:()=>Promise.resolve()});if(e.t.log(`Generated archive`,u),process.env.NODE_ENV===`development`&&e.t.isEnabled()){let t=r.t(l.map(e=>e.path));e.t.groupCollapsed(...e.t.getGroupArgs(`Archive folder structure`)),e.t.log(`\n${t}`),e.t.groupEnd()}return u};exports.createArchiveFromUnzipper=a;
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","names":[],"sources":["../../../src/archives/createArchiveFromUnzipper.ts"],"sourcesContent":["import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport type { CentralDirectory } from \"unzipper\"\nimport { Report } from \"../report\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport { arrayBufferFileAccessors } from \"./fileAccessors\"\nimport { printTree } from \"./printTree\"\nimport type { Archive } from \"./types\"\n\nexport const createArchiveFromUnzipper = async (\n directory: CentralDirectory,\n {\n orderByAlpha,\n name,\n encodingFormat,\n }: { orderByAlpha?: boolean; name?: string; encodingFormat?: string } = {},\n): Promise<Archive> => {\n let files = directory.files\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.path, b.path))\n }\n\n const archive = createArchive({\n filename: name,\n encodingFormat,\n records: files.map((file) => {\n const basename = getUriBasename(file.path)\n\n if (file.type === `Directory`) {\n return {\n dir: true,\n basename,\n uri: file.path,\n }\n }\n\n return {\n dir: false,\n basename,\n uri: file.path,\n encodingFormat: detectMimeTypeFromName(file.path),\n size: file.uncompressedSize,\n ...arrayBufferFileAccessors(async () => {\n const buffer = await file.buffer()\n // unzipper decodes into a regular Node `Buffer`, whose backing store\n // is always an `ArrayBuffer` (never a `SharedArrayBuffer`); the cast\n // only drops the `SharedArrayBuffer` arm that cannot occur here.\n const backing = buffer.buffer as ArrayBuffer\n\n // Non-pooled (large) allocations own a dedicated, exactly-sized\n // backing buffer, so they can be handed out without copying. Pooled\n // small buffers share their backing store with other entries and\n // must be sliced out.\n return buffer.byteOffset === 0 &&\n buffer.byteLength === backing.byteLength\n ? backing\n : backing.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n )\n }, detectMimeTypeFromName(file.path) ?? ``),\n }\n }),\n close: () => Promise.resolve(),\n })\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(files.map((file) => file.path))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n"],"mappings":"kRAUA,IAAa,EAA4B,MACvC,EACA,CACE,eACA,OACA,kBACsE,CAAC,IACpD,CACrB,IAAI,EAAQ,EAAU,MAElB,IACF,EAAQ,EAAM,MAAM,EAAE,MAAM,EAAG,IAAM,EAAA,EAAsB,EAAE,KAAM,EAAE,IAAI,CAAC,GAG5E,IAAM,EAAU,EAAA,EAAc,CAC5B,SAAU,EACV,iBACA,QAAS,EAAM,IAAK,GAAS,CAC3B,IAAM,EAAW,EAAA,EAAe,EAAK,IAAI,EAUzC,OARI,EAAK,OAAS,YACT,CACL,IAAK,GACL,WACA,IAAK,EAAK,IACZ,EAGK,CACL,IAAK,GACL,WACA,IAAK,EAAK,KACV,gBAAA,EAAA,EAAA,wBAAuC,EAAK,IAAI,EAChD,KAAM,EAAK,iBACX,GAAG,EAAA,EAAyB,SAAY,CACtC,IAAM,EAAS,MAAM,EAAK,OAAO,EAI3B,EAAU,EAAO,OAMvB,OAAO,EAAO,aAAe,GAC3B,EAAO,aAAe,EAAQ,WAC5B,EACA,EAAQ,MACN,EAAO,WACP,EAAO,WAAa,EAAO,UAC7B,CACN,GAAA,EAAA,EAAA,wBAA0B,EAAK,IAAI,GAAK,EAAE,CAC5C,CACF,CAAC,EACD,UAAa,QAAQ,QAAQ,CAC/B,CAAC,EAID,GAFA,EAAA,EAAO,IAAI,oBAAqB,CAAO,EAEvC,QAAA,IAAA,WAA6B,eACvB,EAAA,EAAO,UAAU,EAAG,CACtB,IAAM,EAAqB,EAAA,EAAU,EAAM,IAAK,GAAS,EAAK,IAAI,CAAC,EACnE,EAAA,EAAO,eAAe,GAAG,EAAA,EAAO,aAAa,0BAA0B,CAAC,EACxE,EAAA,EAAO,IAAI,KAAK,GAAoB,EACpC,EAAA,EAAO,SAAS,CAClB,CAGF,OAAO,CACT"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { n as e, t } from "../../report-uURLD5cl.js";
|
|
2
|
+
import { i as n, n as r } from "../../uri-DBZYnB1I.js";
|
|
3
|
+
import { t as i } from "../../fileAccessors-etcCPnpQ.js";
|
|
4
|
+
import { t as a } from "../../printTree-CJzGASVu.js";
|
|
5
|
+
import { detectMimeTypeFromName as o } from "@prose-reader/shared";
|
|
6
|
+
//#region src/archives/createArchiveFromUnzipper.ts
|
|
7
|
+
var s = async (s, { orderByAlpha: c, name: l, encodingFormat: u } = {}) => {
|
|
8
|
+
let d = s.files;
|
|
9
|
+
c && (d = d.slice().sort((e, t) => n(e.path, t.path)));
|
|
10
|
+
let f = e({
|
|
11
|
+
filename: l,
|
|
12
|
+
encodingFormat: u,
|
|
13
|
+
records: d.map((e) => {
|
|
14
|
+
let t = r(e.path);
|
|
15
|
+
return e.type === "Directory" ? {
|
|
16
|
+
dir: !0,
|
|
17
|
+
basename: t,
|
|
18
|
+
uri: e.path
|
|
19
|
+
} : {
|
|
20
|
+
dir: !1,
|
|
21
|
+
basename: t,
|
|
22
|
+
uri: e.path,
|
|
23
|
+
encodingFormat: o(e.path),
|
|
24
|
+
size: e.uncompressedSize,
|
|
25
|
+
...i(async () => {
|
|
26
|
+
let t = await e.buffer(), n = t.buffer;
|
|
27
|
+
return t.byteOffset === 0 && t.byteLength === n.byteLength ? n : n.slice(t.byteOffset, t.byteOffset + t.byteLength);
|
|
28
|
+
}, o(e.path) ?? "")
|
|
29
|
+
};
|
|
30
|
+
}),
|
|
31
|
+
close: () => Promise.resolve()
|
|
32
|
+
});
|
|
33
|
+
if (t.log("Generated archive", f), process.env.NODE_ENV === "development" && t.isEnabled()) {
|
|
34
|
+
let e = a(d.map((e) => e.path));
|
|
35
|
+
t.groupCollapsed(...t.getGroupArgs("Archive folder structure")), t.log(`\n${e}`), t.groupEnd();
|
|
36
|
+
}
|
|
37
|
+
return f;
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { s as createArchiveFromUnzipper };
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.es.js","names":[],"sources":["../../../src/archives/createArchiveFromUnzipper.ts"],"sourcesContent":["import { detectMimeTypeFromName } from \"@prose-reader/shared\"\nimport type { CentralDirectory } from \"unzipper\"\nimport { Report } from \"../report\"\nimport { sortByTitleComparator } from \"../utils/sortByTitleComparator\"\nimport { getUriBasename } from \"../utils/uri\"\nimport { createArchive } from \"./createArchive\"\nimport { arrayBufferFileAccessors } from \"./fileAccessors\"\nimport { printTree } from \"./printTree\"\nimport type { Archive } from \"./types\"\n\nexport const createArchiveFromUnzipper = async (\n directory: CentralDirectory,\n {\n orderByAlpha,\n name,\n encodingFormat,\n }: { orderByAlpha?: boolean; name?: string; encodingFormat?: string } = {},\n): Promise<Archive> => {\n let files = directory.files\n\n if (orderByAlpha) {\n files = files.slice().sort((a, b) => sortByTitleComparator(a.path, b.path))\n }\n\n const archive = createArchive({\n filename: name,\n encodingFormat,\n records: files.map((file) => {\n const basename = getUriBasename(file.path)\n\n if (file.type === `Directory`) {\n return {\n dir: true,\n basename,\n uri: file.path,\n }\n }\n\n return {\n dir: false,\n basename,\n uri: file.path,\n encodingFormat: detectMimeTypeFromName(file.path),\n size: file.uncompressedSize,\n ...arrayBufferFileAccessors(async () => {\n const buffer = await file.buffer()\n // unzipper decodes into a regular Node `Buffer`, whose backing store\n // is always an `ArrayBuffer` (never a `SharedArrayBuffer`); the cast\n // only drops the `SharedArrayBuffer` arm that cannot occur here.\n const backing = buffer.buffer as ArrayBuffer\n\n // Non-pooled (large) allocations own a dedicated, exactly-sized\n // backing buffer, so they can be handed out without copying. Pooled\n // small buffers share their backing store with other entries and\n // must be sliced out.\n return buffer.byteOffset === 0 &&\n buffer.byteLength === backing.byteLength\n ? backing\n : backing.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n )\n }, detectMimeTypeFromName(file.path) ?? ``),\n }\n }),\n close: () => Promise.resolve(),\n })\n\n Report.log(\"Generated archive\", archive)\n\n if (process.env.NODE_ENV === \"development\") {\n if (Report.isEnabled()) {\n const folderStructureStr = printTree(files.map((file) => file.path))\n Report.groupCollapsed(...Report.getGroupArgs(\"Archive folder structure\"))\n Report.log(`\\n${folderStructureStr}`)\n Report.groupEnd()\n }\n }\n\n return archive\n}\n"],"mappings":";;;;;;AAUA,IAAa,IAA4B,OACvC,GACA,EACE,iBACA,SACA,sBACsE,CAAC,MACpD;CACrB,IAAI,IAAQ,EAAU;CAEtB,AAAI,MACF,IAAQ,EAAM,MAAM,EAAE,MAAM,GAAG,MAAM,EAAsB,EAAE,MAAM,EAAE,IAAI,CAAC;CAG5E,IAAM,IAAU,EAAc;EAC5B,UAAU;EACV;EACA,SAAS,EAAM,KAAK,MAAS;GAC3B,IAAM,IAAW,EAAe,EAAK,IAAI;GAUzC,OARI,EAAK,SAAS,cACT;IACL,KAAK;IACL;IACA,KAAK,EAAK;GACZ,IAGK;IACL,KAAK;IACL;IACA,KAAK,EAAK;IACV,gBAAgB,EAAuB,EAAK,IAAI;IAChD,MAAM,EAAK;IACX,GAAG,EAAyB,YAAY;KACtC,IAAM,IAAS,MAAM,EAAK,OAAO,GAI3B,IAAU,EAAO;KAMvB,OAAO,EAAO,eAAe,KAC3B,EAAO,eAAe,EAAQ,aAC5B,IACA,EAAQ,MACN,EAAO,YACP,EAAO,aAAa,EAAO,UAC7B;IACN,GAAG,EAAuB,EAAK,IAAI,KAAK,EAAE;GAC5C;EACF,CAAC;EACD,aAAa,QAAQ,QAAQ;CAC/B,CAAC;CAID,IAFA,EAAO,IAAI,qBAAqB,CAAO,GAEvC,QAAA,IAAA,aAA6B,iBACvB,EAAO,UAAU,GAAG;EACtB,IAAM,IAAqB,EAAU,EAAM,KAAK,MAAS,EAAK,IAAI,CAAC;EAGnE,AAFA,EAAO,eAAe,GAAG,EAAO,aAAa,0BAA0B,CAAC,GACxE,EAAO,IAAI,KAAK,GAAoB,GACpC,EAAO,SAAS;CAClB;CAGF,OAAO;AACT"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CentralDirectory } from 'unzipper';
|
|
2
|
+
import { Archive } from './types';
|
|
3
|
+
export declare const createArchiveFromUnzipper: (directory: CentralDirectory, { orderByAlpha, name, encodingFormat, }?: {
|
|
4
|
+
orderByAlpha?: boolean;
|
|
5
|
+
name?: string;
|
|
6
|
+
encodingFormat?: string;
|
|
7
|
+
}) => Promise<Archive>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FileRecord } from './types';
|
|
2
|
+
type FileContentAccessors = Pick<FileRecord, "blob" | "arrayBuffer">;
|
|
3
|
+
/**
|
|
4
|
+
* Derives the content accessors of a {@link FileRecord} from a single `Blob`
|
|
5
|
+
* source. Content is not retained between calls so a long-lived archive does
|
|
6
|
+
* not pin decompressed bytes in memory.
|
|
7
|
+
*/
|
|
8
|
+
export declare const blobFileAccessors: (blob: () => Promise<Blob>) => FileContentAccessors;
|
|
9
|
+
/**
|
|
10
|
+
* Derives the content accessors of a {@link FileRecord} from an `ArrayBuffer`
|
|
11
|
+
* source, avoiding a `Blob` round-trip for binary-native archives. Content is
|
|
12
|
+
* not retained between calls.
|
|
13
|
+
*/
|
|
14
|
+
export declare const arrayBufferFileAccessors: (arrayBuffer: () => Promise<ArrayBuffer>, type?: string) => FileContentAccessors;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { FileRecord } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Decodes a record's bytes as UTF-8. The caller asserts the record is text;
|
|
4
|
+
* there is intentionally no `string()` accessor on {@link FileRecord} so that
|
|
5
|
+
* decoding a binary record is always a deliberate act at the call site.
|
|
6
|
+
*/
|
|
7
|
+
export declare const readRecordAsText: (record: FileRecord) => Promise<string>;
|
package/dist/archives/types.d.ts
CHANGED
|
@@ -1,35 +1,42 @@
|
|
|
1
|
-
export interface StreamResult {
|
|
2
|
-
on(e: `data`, cb: (data: Uint8Array) => void): void;
|
|
3
|
-
on(e: `error`, cb: (error: Error) => void): void;
|
|
4
|
-
on(e: `end`, cb: () => void): void;
|
|
5
|
-
resume(): void;
|
|
6
|
-
}
|
|
7
1
|
export type FileRecord = {
|
|
8
2
|
dir: false;
|
|
9
3
|
basename: string;
|
|
10
4
|
uri: string;
|
|
11
|
-
|
|
12
|
-
string: () => Promise<string>;
|
|
13
|
-
stream?: () => StreamResult;
|
|
5
|
+
/** Uncompressed byte length of the record, or `0` when unknown. */
|
|
14
6
|
size: number;
|
|
15
7
|
encodingFormat?: string;
|
|
8
|
+
blob: () => Promise<Blob>;
|
|
9
|
+
arrayBuffer: () => Promise<ArrayBuffer>;
|
|
16
10
|
};
|
|
17
11
|
export type DirectoryRecord = {
|
|
18
12
|
dir: true;
|
|
19
13
|
basename: string;
|
|
20
14
|
uri: string;
|
|
21
|
-
size: number;
|
|
22
|
-
encodingFormat?: undefined;
|
|
23
15
|
};
|
|
16
|
+
export type ArchiveRecord = FileRecord | DirectoryRecord;
|
|
24
17
|
export type Archive = {
|
|
25
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Container-level filename when known (e.g. the originating `.cbz`/`.epub`
|
|
20
|
+
* file name). Absent for synthetic archives that have no real source file
|
|
21
|
+
* (URL lists, raw array buffers). Consumers use it as a detection signal, so
|
|
22
|
+
* it must never be fabricated.
|
|
23
|
+
*/
|
|
24
|
+
filename?: string;
|
|
26
25
|
/**
|
|
27
26
|
* Archive-level media type when known (e.g. `application/vnd.comicbook+zip`
|
|
28
27
|
* for a CBZ). This is the mime type of the container itself, not of any
|
|
29
28
|
* individual record; record-level mime types live on {@link FileRecord}.
|
|
30
29
|
*/
|
|
31
30
|
encodingFormat?: string;
|
|
32
|
-
records:
|
|
31
|
+
records: ArchiveRecord[];
|
|
32
|
+
/**
|
|
33
|
+
* `uri` → record index built once at construction (see `createArchive`).
|
|
34
|
+
* Resource resolution is a per-fetched-file hot path, so prefer this (or
|
|
35
|
+
* {@link getArchiveFileRecordByUri}) over scanning {@link Archive.records}.
|
|
36
|
+
*/
|
|
37
|
+
recordsByUri: ReadonlyMap<string, ArchiveRecord>;
|
|
33
38
|
close: () => Promise<void>;
|
|
34
39
|
};
|
|
35
|
-
export declare const isFileRecord: (record:
|
|
40
|
+
export declare const isFileRecord: (record: ArchiveRecord) => record is FileRecord;
|
|
41
|
+
export declare const isDirectoryRecord: (record: ArchiveRecord) => record is DirectoryRecord;
|
|
42
|
+
export declare const getArchiveFileRecordByUri: (archive: Pick<Archive, "recordsByUri">, uri: string) => FileRecord | undefined;
|
|
@@ -3,4 +3,4 @@ import { ArchiveOpfParsed } from './readArchiveOpf';
|
|
|
3
3
|
export declare const getSpineItemFilesFromArchive: ({ archive, archiveOpf, }: {
|
|
4
4
|
archive: Archive;
|
|
5
5
|
archiveOpf: ArchiveOpfParsed | undefined;
|
|
6
|
-
}) => Promise<
|
|
6
|
+
}) => Promise<import('..').ArchiveRecord[]>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var e=e=>({blob:e,arrayBuffer:()=>e().then(e=>e.arrayBuffer())}),t=(e,t=``)=>({arrayBuffer:e,blob:()=>e().then(e=>new Blob([e],{type:t}))});Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return t}});
|
|
2
|
+
//# sourceMappingURL=fileAccessors-DWVChFUB.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileAccessors-DWVChFUB.cjs","names":[],"sources":["../src/archives/fileAccessors.ts"],"sourcesContent":["import type { FileRecord } from \"./types\"\n\ntype FileContentAccessors = Pick<FileRecord, \"blob\" | \"arrayBuffer\">\n\n/**\n * Derives the content accessors of a {@link FileRecord} from a single `Blob`\n * source. Content is not retained between calls so a long-lived archive does\n * not pin decompressed bytes in memory.\n */\nexport const blobFileAccessors = (\n blob: () => Promise<Blob>,\n): FileContentAccessors => ({\n blob,\n arrayBuffer: () => blob().then((value) => value.arrayBuffer()),\n})\n\n/**\n * Derives the content accessors of a {@link FileRecord} from an `ArrayBuffer`\n * source, avoiding a `Blob` round-trip for binary-native archives. Content is\n * not retained between calls.\n */\nexport const arrayBufferFileAccessors = (\n arrayBuffer: () => Promise<ArrayBuffer>,\n type = ``,\n): FileContentAccessors => ({\n arrayBuffer,\n blob: () => arrayBuffer().then((value) => new Blob([value], { type })),\n})\n"],"mappings":"AASA,IAAa,EACX,IAC0B,CAC1B,OACA,gBAAmB,EAAK,EAAE,KAAM,GAAU,EAAM,YAAY,CAAC,CAC/D,GAOa,GACX,EACA,EAAO,MACmB,CAC1B,cACA,SAAY,EAAY,EAAE,KAAM,GAAU,IAAI,KAAK,CAAC,CAAK,EAAG,CAAE,MAAK,CAAC,CAAC,CACvE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/archives/fileAccessors.ts
|
|
2
|
+
var e = (e) => ({
|
|
3
|
+
blob: e,
|
|
4
|
+
arrayBuffer: () => e().then((e) => e.arrayBuffer())
|
|
5
|
+
}), t = (e, t = "") => ({
|
|
6
|
+
arrayBuffer: e,
|
|
7
|
+
blob: () => e().then((e) => new Blob([e], { type: t }))
|
|
8
|
+
});
|
|
9
|
+
//#endregion
|
|
10
|
+
export { e as n, t };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=fileAccessors-etcCPnpQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileAccessors-etcCPnpQ.js","names":[],"sources":["../src/archives/fileAccessors.ts"],"sourcesContent":["import type { FileRecord } from \"./types\"\n\ntype FileContentAccessors = Pick<FileRecord, \"blob\" | \"arrayBuffer\">\n\n/**\n * Derives the content accessors of a {@link FileRecord} from a single `Blob`\n * source. Content is not retained between calls so a long-lived archive does\n * not pin decompressed bytes in memory.\n */\nexport const blobFileAccessors = (\n blob: () => Promise<Blob>,\n): FileContentAccessors => ({\n blob,\n arrayBuffer: () => blob().then((value) => value.arrayBuffer()),\n})\n\n/**\n * Derives the content accessors of a {@link FileRecord} from an `ArrayBuffer`\n * source, avoiding a `Blob` round-trip for binary-native archives. Content is\n * not retained between calls.\n */\nexport const arrayBufferFileAccessors = (\n arrayBuffer: () => Promise<ArrayBuffer>,\n type = ``,\n): FileContentAccessors => ({\n arrayBuffer,\n blob: () => arrayBuffer().then((value) => new Blob([value], { type })),\n})\n"],"mappings":";AASA,IAAa,KACX,OAC0B;CAC1B;CACA,mBAAmB,EAAK,EAAE,MAAM,MAAU,EAAM,YAAY,CAAC;AAC/D,IAOa,KACX,GACA,IAAO,QACmB;CAC1B;CACA,YAAY,EAAY,EAAE,MAAM,MAAU,IAAI,KAAK,CAAC,CAAK,GAAG,EAAE,QAAK,CAAC,CAAC;AACvE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../report-Cs9DVdJl.cjs"),t=require("../uri-DW0-P-ng.cjs"),n=require("../fileAccessors-DWVChFUB.cjs");let r=require("@prose-reader/shared"),i=require("@prose-reader/archive-parser"),a=require("xmldoc"),o=require("rxjs");var s=async(i,{orderByAlpha:a,name:o,encodingFormat:s}={})=>{let c=i;return a&&(c=c.slice().sort((e,n)=>t.i(e.name,n.name))),e.n({filename:o,encodingFormat:s,records:c.map(e=>{let i=t.n(e.name);return e.isDir?{dir:!0,basename:i,uri:e.name}:{dir:e.isDir,basename:i,encodingFormat:(0,r.detectMimeTypeFromName)(e.name),uri:e.name,size:e.size,...n.t(e.data,(0,r.detectMimeTypeFromName)(e.name)??``)}}),close:()=>Promise.resolve()})},c=async(r,{mimeType:i,direction:a}={mimeType:`text/plain`})=>{let o=`
|
|
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="${a??`ltr`}">
|
|
13
|
+
<itemref idref="p01" />
|
|
14
|
+
</spine>
|
|
15
|
+
</package>
|
|
16
|
+
`;return e.n({filename:`content.txt`,encodingFormat:i,records:[{dir:!1,basename:t.n(`generated.opf`),uri:`generated.opf`,size:0,...n.n(async()=>new Blob([o]))},{dir:!1,basename:t.n(`p01.txt`),uri:`p01.txt`,size:typeof r==`string`?new Blob([r]).size:r.size,encodingFormat:i,...n.n(async()=>typeof r==`string`?new Blob([r]):r)}],close:()=>Promise.resolve()})},l=/^[A-Za-z0-9_][A-Za-z0-9_.-]*$/,u=/^[A-Za-z0-9_]/,d=/^xml/i,f=/[^A-Za-z0-9_.-]+/g,p=`_`,m=e=>e.replace(/^_+|_+$/g,``),h=e=>m(e.trim().replaceAll(`/`,`_`).replace(f,`_`)),g=e=>{if(l.test(e)&&!d.test(e))return e;let t=h(e),n=t&&!d.test(t)?t:`${p}${t}`;return u.test(n)?n:`${p}${n}`},_=(e,t)=>{let n=g(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},v=()=>{let e=new Set;return t=>_(t,e)},ee=async(i,a)=>{let o=v(),s=i.map(e=>({id:o(e),url:e})),c=`
|
|
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">${a?.useRenditionFlow?`reflowable`:`pre-paginated`}</meta>
|
|
20
|
+
${a?.useRenditionFlow?`<meta property="rendition:flow">scrolled-continuous</meta>`:``}
|
|
21
|
+
</metadata>
|
|
22
|
+
<manifest>
|
|
23
|
+
${s.map(({id:e,url:t})=>{let n=(0,r.detectMimeTypeFromName)(t);return`<item id="${e}" href="${(0,r.escapeXmlAttributeValue)(t)}" media-type="${(0,r.escapeXmlAttributeValue)(n??``)}"/>`}).join(`
|
|
24
|
+
`)}
|
|
25
|
+
</manifest>
|
|
26
|
+
<spine>
|
|
27
|
+
${s.map(({id:e})=>`<itemref idref="${e}" />`).join(`
|
|
28
|
+
`)}
|
|
29
|
+
</spine>
|
|
30
|
+
</package>
|
|
31
|
+
`,l=i.map(e=>({dir:!1,basename:t.n(e),encodingFormat:(0,r.detectMimeTypeFromName)(e),uri:e,size:0,...n.n(async()=>(await fetch(e)).blob())}));return e.n({records:[{dir:!1,basename:`content.opf`,uri:`content.opf`,size:0,...n.n(async()=>new Blob([c]))},...l],close:()=>Promise.resolve()})},y=e=>!e.dir,b=e=>e.dir,x=(e,t)=>{let n=e.recordsByUri.get(t);return n&&y(n)?n:void 0},S=i.COMIC_INFO_FILENAME.toLowerCase(),C=e=>e.records.find(e=>y(e)&&e.basename.toLowerCase()===S),w=async e=>new TextDecoder().decode(await e.arrayBuffer()),te=({enableReport:t}={})=>{e.t.enable(!!t)},T=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 E(e){let{data:t,basePath:n}=T(e)||{};if(!(!t||t.dir))return{opf:(0,i.parseOpf)(await w(t)),basePath:n}}var D=i.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME.toLowerCase(),ne=({archive:e})=>async t=>{let n=e.records.find(e=>!e.dir&&e.basename.toLowerCase()===D);if(!n||n.dir)return t;let r=await w(n);try{let{renditionLayout:e}=(0,i.resolveArchiveMetadata)((0,i.parseAppleDisplayOptionsXml)(r));return{...t,renditionLayout:t.renditionLayout??e}}catch(e){return console.error(`Unable to parse ${i.APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME} for content\n`,r),console.error(e),t}},re=i.COMIC_INFO_FILENAME.toLowerCase(),ie=({archive:e})=>async t=>{let n=C(e);if(!n)return t;let r={...t,spineItems:t.spineItems.filter(e=>!e.id.toLowerCase().endsWith(re)).map((e,t,n)=>({...e,progressionWeight:1/n.length}))},a=await w(n);try{let e=(0,i.resolveArchiveMetadata)((0,i.parseComicInfo)(a));return{...r,readingDirection:e.readingDirection??r.readingDirection}}catch(e){return console.error(`Unable to parse ${i.COMIC_INFO_FILENAME} for content\n`,a),console.error(e),r}},ae=({baseUrl:e=``,resourcePath:t})=>{if(!e&&/^https?:\/\//.test(t))return encodeURI(t);let n=e?`${e}${e.endsWith(`/`)?``:`/`}`:`file://`;return encodeURI(`${n}${t}`)},oe=({archive:e,baseUrl:t})=>async()=>{let n=e.records.filter(e=>!e.dir),r=v(),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:ae({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}`)}))}},O=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))},k=(e,t,n)=>{let{basePath:r}=T(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}})},se=e=>{let t=e?.trim();return t===`scrolled-continuous`||t===`scrolled-doc`||t===`paginated`||t===`auto`?t:`auto`},ce=e=>{let t=e?.trim();if(t===`none`||t===`landscape`||t===`portrait`||t===`both`||t===`auto`)return t},le=e=>{let t=e?.trim();if(t===`cover`||t===`title-page`||t===`copyright-page`||t===`text`)return t},A=({archive:t,baseUrl:n,archiveOpf:r})=>async a=>{if(!r)return a;let{opf:o,basePath:s}=r,c=(0,i.resolveArchiveMetadata)(o);e.t.groupCollapsed(...e.t.getGroupArgs(`OPF parsed`)),e.t.log(`opf`,o),e.t.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 O({archive:t,archiveOpf:r})).filter(y).reduce((e,t)=>t.size+e,0),m=o.guide,h=[];for(let e of m){let t=le(e.type);t!==void 0&&h.push({href:e.href,title:e.title,type:t})}return{filename:t.filename??``,renditionLayout:u,renditionFlow:se(o.renditionFlowMeta),renditionSpread:ce(o.renditionSpreadMeta),title:d,readingDirection:f,spineItems:o.spineRows.map((e,r)=>{let i=x(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:k(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,r.isXmlBasedMimeType)({mimeType:y(t)?t.encodingFormat:void 0,uri:t.uri}))return!1;let n=t.dir?null:await w(t);return n?j(new a.XmlDocument(n)):!1},Promise.resolve(!0)),N=({archive:e,archiveOpf:t})=>async n=>n.renditionLayout===`reflowable`&&n.spineItems.every(e=>e.renditionLayout===`reflowable`)&&await M(await O({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(i.KOBO_DISPLAY_OPTIONS_FILENAME))return;let n=await w(e);try{let{renditionLayout:e}=(0,i.parseKoboXml)(n);e&&(t=e)}catch(e){console.error(`Unable to parse ${i.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,i.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 n=e.records.find(e=>decodeURI(t.href).endsWith(e.uri)),i=(0,r.parseContentType)((n&&y(n)?n.encodingFormat:void 0)??``)||(0,r.detectMimeTypeFromName)(n?.basename??``);return{...t,renditionLayout:i&&(0,r.isMediaContentMimeType)(i)?`pre-paginated`:t.renditionLayout}})},B=e=>e?e.children.map(e=>e instanceof a.XmlTextNode?e.text:e instanceof a.XmlElement?B(e):``).join(``).trim():``,V=e=>(0,i.tokenizeXmlSpaceSeparatedList)(e.properties).includes(`nav`),H=(e,{basePath:t,baseUrl:n})=>{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,r.urlJoin)(t,a.attr.href),i.href=(0,r.urlJoin)(n,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:n})))}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(e,n,{baseUrl:r})=>{let i=e.manifestItems.find(V);if(i?.href){let e=n.records.find(e=>e.uri.endsWith(i.href));if(e&&!e.dir)return U(new a.XmlDocument(await w(e)),{basePath:t.t(e.uri),baseUrl:r})}},G=(e,{opfBasePath:t,baseUrl:n,prefix:i})=>{let a=e?.childNamed(`${i}content`)?.attr.src||``,o={title:e?.descendantWithPath(`${i}navLabel.${i}text`)?.val||``,path:(0,r.urlJoin)(t,a),href:(0,r.urlJoin)(n,t,a),contents:[]},s=e.childrenNamed(`${i}navPoint`);return s&&s.length>0&&(o.contents=s.map(e=>G(e,{opfBasePath:t,baseUrl:n,prefix:i}))),o},ue=(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},de=async({opf:e,opfBasePath:t,baseUrl:n,archive:r})=>{let i=e.spineTocIdref;if(i){let o=e.manifestItems.find(e=>e.id===i);if(o){let e=`${t}${t===``?``:`/`}${o.href}`,i=r.records.find(t=>t.uri.endsWith(e));if(i&&!i.dir)return ue(new a.XmlDocument(await w(i)),{opfBasePath:t,baseUrl:n})}}},fe=async(e,t,{baseUrl:n})=>{let{basePath:r}=T(t)||{},i=await W(e,t,{baseUrl:n});if(i)return i;let a=await de({opf:e,opfBasePath:r??``,archive:t,baseUrl:n});if(a)return a},pe=e=>e.replace(/\.[^.]+$/,``).replace(/[_-]/g,` `).replace(/\s+/g,` `).trim(),me=(e,t)=>{if(e.spineItems.length!==0&&e.spineItems.every(e=>((0,r.parseContentType)(e.mediaType??``)||(0,r.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:pe(n?.basename??e.href),href:e.href,path:n?.uri??e.href,contents:[]}})},he=(e,{baseUrl:n})=>{let i=[...e.records].sort((e,n)=>t.i(e.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);return i?a(e,i,o,(0,r.urlJoin)(n,encodeURI(t.uri)).replace(/\/$/,``),t.uri.replace(/\/$/,``)):e},[])},ge=async(e,t,{baseUrl:n,archiveOpf:r})=>{if(r)return await fe(r.opf,e,{baseUrl:n})||[];let i=me(t,e);if(i)return i;let a=he(e,{baseUrl:n});if(a.length!==0)return a},_e=({archive:e,baseUrl:t,archiveOpf:n})=>async r=>{if(r.nav)return r;let i=await ge(e,r,{baseUrl:t,archiveOpf:n});return i?{...r,nav:{toc:i}}:r},ve=e=>e?e.endsWith(`/`)?e:`${e}/`:``,K=async(t,{baseUrl:n=``,hooks:r={}}={})=>{e.t.log(`Generating manifest from archive`,t);let i=await E(t),a=ve(n),o=e=>(e??[]).map(e=>e({archive:t,baseUrl:a})),s=[A({archive:t,baseUrl:a,archiveOpf:i}),ie({archive:t,baseUrl:a}),ne({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=[_e({archive:t,baseUrl:a,archiveOpf:i}),...o(r.navigation)],d=[...s,...c,...l,...u,P()];try{let n=oe({archive:t,baseUrl:a})(),r=await d.reduce(async(e,t)=>await t(await e),n);if(e.t.log(`Generated manifest`,r),process.env.NODE_ENV===`development`&&e.t.isEnabled()){let t=JSON.stringify(r,null,2);e.t.groupCollapsed(...e.t.getGroupArgs(`Generated manifest`)),e.t.log(`\n${t}`),e.t.groupEnd()}return r}catch(t){throw e.t.error(t),t}},ye=e=>{let t=e.descendantWithPath(`head`)?.childrenNamed(`meta`).find(e=>e.attr.name===`calibre:cover`);return!!(t&&t.attr.name===`calibre:cover`)},be=e=>e.descendantWithPath(`body`)?.descendantWithPath(`div`)?.childrenNamed(`svg`)?.find(e=>e.attr.width===`100%`&&e.attr.preserveAspectRatio===`none`),xe=({archive:e,resourcePath:t})=>async n=>{let r=x(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=new a.XmlDocument(typeof n.body==`string`?n.body:await w(r));if(ye(e)){let t=be(e);return t&&delete t.attr.preserveAspectRatio,{...n,body:e?.toString()}}}return n},Se=({archive:e,resourcePath:t})=>async n=>xe({archive:e,resourcePath:t})(n),Ce=({archive:e,resourcePath:t})=>async n=>{let r=x(e,t);if(r?.basename.endsWith(`.css`)){let e=(typeof n.body==`string`?n.body:await w(r)).replaceAll(`-webkit-writing-mode`,`writing-mode`);return{...n,body:e}}return n},we=async(e,t)=>{let n=await E(e);if(n){let{opf:r}=n,i=k(r.manifestItems,e,()=>``).find(e=>t.endsWith(e.href))?.mediaType;if(i)return{mediaType:i}}return{mediaType:Te(t)}},Te=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`},Ee=({archive:e,resourcePath:t})=>async n=>{let r=x(e,t);if(!r)return n;let i=await we(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(`.`),De=({archive:e,resourcePath:t})=>async n=>{let r=x(e,t);if(r?.basename.endsWith(`.xhtml`)){let e=typeof n.body==`string`?n.body:await w(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})),Ee({archive:t,resourcePath:n}),De({archive:t,resourcePath:n}),Ce({archive:t,resourcePath:n}),Se({archive:t,resourcePath:n})];try{let r=await a.reduce(async(e,t)=>await t(await e),Promise.resolve(i));if(e.t.log(`Generated resource`,n,r),r.body!==void 0)return r;let o=x(t,n);if(!o)throw Error(`no file found for resourcePath:${n}`);return{...r,body:await o.blob()}}catch(t){throw e.t.error(t),t}},Oe=class{constructor(e){this.cleanArchiveAfter=e,this.state$=new o.BehaviorSubject({status:`idle`,locks:0})}update(e){this.state$.next({...this.state$.getValue(),...e})}get locks$(){return this.state$.pipe((0,o.map)(({locks:e})=>e))}get state(){return this.state$.getValue()}get isUnlocked$(){return this.locks$.pipe((0,o.map)(e=>e<=0),(0,o.distinctUntilChanged)(),(0,o.shareReplay)())}get overTTL$(){return this.isUnlocked$.pipe((0,o.switchMap)(e=>e?this.cleanArchiveAfter===1/0?o.NEVER:(0,o.timer)(this.cleanArchiveAfter):o.NEVER))}},ke=({getArchive:t,cleanArchiveAfter:n=300*1e3})=>{let r=new o.Subject,i=new o.Subject,a=new o.Subject,s={};return r.pipe((0,o.mergeMap)(n=>{let r=s[n];if(!r||r.state.status!==`idle`)return o.EMPTY;let i=!1,c=t=>{e.t.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,o.pairwise)(),(0,o.filter)(([e,t])=>t>e),(0,o.startWith)(!0));return(0,o.from)(t(n)).pipe((0,o.tap)(e=>{r.update({archive:e,status:`success`})}),(0,o.catchError)(e=>(c(n),r.update({status:`error`,error:e}),o.EMPTY)),(0,o.switchMap)(()=>(0,o.merge)(d.pipe((0,o.switchMap)(()=>a),(0,o.switchMap)(()=>u),(0,o.filter)(e=>e)),r.overTTL$).pipe((0,o.first)(),(0,o.tap)(()=>{c(n)}))))}),(0,o.takeUntil)(i)).subscribe(),{access:e=>{let t=!1,i=s[e]??new Oe(n);s[e]=i,i.update({locks:i.state.locks+1});let a=()=>{t||(t=!0,i.update({locks:i.state.locks-1}))};return r.next(e),(0,o.merge)(i.state$.pipe((0,o.map)(({archive:e})=>e),(0,o.filter)(e=>!!e)),i.state$.pipe((0,o.tap)(({error:e})=>{if(e)throw e}),(0,o.ignoreElements)())).pipe((0,o.first)(),(0,o.map)(e=>({archive:e,release:a})),(0,o.catchError)(e=>{throw a(),e}))},purge:()=>{a.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},Ae=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}},X=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}}}},je=({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=Ae(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=X(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://`,Me=/^https?:\/\//,Ne=e=>{try{return decodeURIComponent(e)}catch{return e}},Q=e=>e.startsWith(Z)?e.slice(Z.length):e,Pe=e=>{let t=Q(e);return Me.test(t)?t:Q(Ne(t))},$=class{constructor({hooks:e,onError:t,onManifestSuccess:n,...r}){this.onError=e=>(console.error(e),new Response(String(e),{status:500})),this.archiveLoader=ke(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,o.map)(({archive:e,release:t})=>(t(),e)))}withArchiveResponse({key:e,getResponse:t}){return(0,o.lastValueFrom)(this.accessArchive(e).pipe((0,o.mergeMap)(({archive:e,release:n})=>(0,o.from)(t(e)).pipe((0,o.finalize)(()=>{n()}))),(0,o.catchError)(e=>(0,o.of)(this.onError(e)))))}fetchManifest({key:e,baseUrl:t}){return this.withArchiveResponse({key:e,getResponse:e=>(0,o.from)(K(e,{baseUrl:t,hooks:this.hooks.manifest})).pipe((0,o.switchMap)(t=>(0,o.from)(this.onManifestSuccess({manifest:t,archive:e}))),(0,o.map)(e=>new Response(JSON.stringify(e),{status:200})))})}fetchResource({key:e,resourcePath:t,request:n}){return this.withArchiveResponse({key:e,getResponse:e=>(0,o.from)(J(e,Pe(t),{hooks:this.hooks.resource})).pipe((0,o.map)(e=>je({body:e.body??``,contentType:e.params.contentType,rangeHeader:n?.headers.get(`range`)})))})}},Fe=class extends ${constructor({getUriInfo:e,...t}){super(t),this.getUriInfo=e,this.fetchEventListener=this.fetchEventListener.bind(this)}fetchEventListener(e){try{let n=this.getUriInfo(e);if(!n)return;let r=t.r(n.baseUrl),i=e.request.url.substring(r.length+1),[a=``]=i.split(`/`),o=t.r(i.substring(a.length+1));i.endsWith(`/manifest`)?e.respondWith(this.fetchManifest({key:a,baseUrl:`${r}/${a}/`})):e.respondWith(this.fetchResource({key:a,resourcePath:o,request:e.request}))}catch(t){e.respondWith(new Response(String(t),{status:500}))}}};exports.ServiceWorkerStreamer=Fe,exports.Streamer=$,exports.arrayBufferFileAccessors=n.t,exports.blobFileAccessors=n.n,exports.configure=te,exports.createArchive=e.n,exports.createArchiveFromArrayBufferList=s,exports.createArchiveFromText=c,exports.createArchiveFromUrls=ee,exports.createUniqueXmlSafeId=_,exports.createXmlSafeId=g,exports.createXmlSafeIdFactory=v,exports.generateManifestFromArchive=K,exports.generateResourceFromArchive=J,exports.getArchiveFileRecordByUri=x,exports.getArchiveHasComicInfo=C,exports.getArchiveOpfInfo=T,exports.getUriBasePath=t.t,exports.getUriBasename=t.n,exports.isDirectoryRecord=b,exports.isFileRecord=y,exports.readRecordAsText=w,exports.removeTrailingSlash=t.r,exports.sortByTitleComparator=t.i;
|
|
32
|
+
//# sourceMappingURL=index.cjs.js.map
|