@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.
Files changed (47) hide show
  1. package/dist/archives/createArchive.d.ts +10 -0
  2. package/dist/archives/createArchiveFromJszip/index.cjs.js +2 -0
  3. package/dist/archives/createArchiveFromJszip/index.cjs.js.map +1 -0
  4. package/dist/archives/createArchiveFromJszip/index.es.js +39 -0
  5. package/dist/archives/createArchiveFromJszip/index.es.js.map +1 -0
  6. package/dist/archives/createArchiveFromJszip.d.ts +2 -29
  7. package/dist/archives/createArchiveFromLibArchive/index.cjs.js +2 -0
  8. package/dist/archives/createArchiveFromLibArchive/index.cjs.js.map +1 -0
  9. package/dist/archives/createArchiveFromLibArchive/index.es.js +24 -0
  10. package/dist/archives/createArchiveFromLibArchive/index.es.js.map +1 -0
  11. package/dist/archives/createArchiveFromLibArchive.d.ts +3 -10
  12. package/dist/archives/createArchiveFromText.d.ts +1 -2
  13. package/dist/archives/createArchiveFromUnzipper/index.cjs.js +2 -0
  14. package/dist/archives/createArchiveFromUnzipper/index.cjs.js.map +1 -0
  15. package/dist/archives/createArchiveFromUnzipper/index.es.js +42 -0
  16. package/dist/archives/createArchiveFromUnzipper/index.es.js.map +1 -0
  17. package/dist/archives/createArchiveFromUnzipper.d.ts +7 -0
  18. package/dist/archives/fileAccessors.d.ts +15 -0
  19. package/dist/archives/readRecordAsText.d.ts +7 -0
  20. package/dist/archives/types.d.ts +21 -14
  21. package/dist/epubs/getSpineItemFilesFromArchive.d.ts +1 -1
  22. package/dist/fileAccessors-DWVChFUB.cjs +2 -0
  23. package/dist/fileAccessors-DWVChFUB.cjs.map +1 -0
  24. package/dist/fileAccessors-etcCPnpQ.js +12 -0
  25. package/dist/fileAccessors-etcCPnpQ.js.map +1 -0
  26. package/dist/index/index.cjs.js +32 -0
  27. package/dist/index/index.cjs.js.map +1 -0
  28. package/dist/index/index.es.js +827 -0
  29. package/dist/index/index.es.js.map +1 -0
  30. package/dist/index.d.ts +5 -3
  31. package/dist/printTree-CJzGASVu.js +20 -0
  32. package/dist/printTree-CJzGASVu.js.map +1 -0
  33. package/dist/printTree-DTFYKvW1.cjs +3 -0
  34. package/dist/printTree-DTFYKvW1.cjs.map +1 -0
  35. package/dist/report-Cs9DVdJl.cjs +2 -0
  36. package/dist/report-Cs9DVdJl.cjs.map +1 -0
  37. package/dist/report-uURLD5cl.js +15 -0
  38. package/dist/report-uURLD5cl.js.map +1 -0
  39. package/dist/uri-DBZYnB1I.js +13 -0
  40. package/dist/uri-DBZYnB1I.js.map +1 -0
  41. package/dist/uri-DW0-P-ng.cjs +2 -0
  42. package/dist/uri-DW0-P-ng.cjs.map +1 -0
  43. package/package.json +44 -10
  44. package/dist/index.js +0 -899
  45. package/dist/index.js.map +0 -1
  46. package/dist/index.umd.cjs +0 -33
  47. package/dist/index.umd.cjs.map +0 -1
package/dist/index.js DELETED
@@ -1,899 +0,0 @@
1
- import { Report as e, detectMimeTypeFromName as t, escapeXmlAttributeValue as n, isMediaContentMimeType as r, isXmlBasedMimeType as i, parseContentType as a, urlJoin as o } from "@prose-reader/shared";
2
- import { APPLE_IBOOKS_DISPLAY_OPTIONS_FILENAME as s, COMIC_INFO_FILENAME as c, KOBO_DISPLAY_OPTIONS_FILENAME as l, parseAppleDisplayOptionsXml as u, parseComicInfo as d, parseKoboXml as f, parseOpf as p, resolveArchiveMetadata as m, tokenizeXmlSpaceSeparatedList as ee } from "@prose-reader/archive-parser";
3
- import { XmlDocument as h, XmlElement as te, XmlTextNode as ne } from "xmldoc";
4
- import { BehaviorSubject as re, EMPTY as g, NEVER as _, Subject as v, catchError as y, distinctUntilChanged as ie, filter as b, finalize as ae, first as x, from as S, ignoreElements as oe, lastValueFrom as se, map as C, merge as w, mergeMap as T, of as ce, pairwise as le, shareReplay as ue, startWith as de, switchMap as E, takeUntil as fe, tap as D, timer as pe } from "rxjs";
5
- //#region src/utils/sortByTitleComparator.ts
6
- var O = (e, t) => {
7
- let n = e.split(/(\d+)/), r = t.split(/(\d+)/);
8
- for (let e = 0, t = n.length; e < t; e++) if (n[e] !== r[e]) return n[e]?.match(/\d/) ? (n[e] || "") - +(r[e] || "") : (n[e] || "").localeCompare(r[e] || "");
9
- return 1;
10
- }, k = (e) => e.substring(e.lastIndexOf("/") + 1) || e, A = (e) => e.endsWith("/") ? e.slice(0, -1) : e, j = (e) => {
11
- let t = e.lastIndexOf("/");
12
- return t >= 0 ? e.substring(0, t) : "";
13
- }, me = async (e, { orderByAlpha: n, name: r, encodingFormat: i } = {}) => {
14
- let a = e;
15
- return n && (a = a.slice().sort((e, t) => O(e.name, t.name))), {
16
- filename: r || "",
17
- encodingFormat: i,
18
- records: a.map((e) => {
19
- let n = e.size, r = k(e.name);
20
- return e.isDir ? {
21
- dir: !0,
22
- basename: r,
23
- uri: e.name,
24
- size: n
25
- } : {
26
- dir: e.isDir,
27
- basename: r,
28
- encodingFormat: t(e.name),
29
- uri: e.name,
30
- blob: async () => new Blob([await e.data()], { type: t(e.name) ?? "" }),
31
- string: async () => {
32
- let t = await e.data();
33
- return String.fromCharCode.apply(null, Array.from(new Uint16Array(t)));
34
- },
35
- size: n
36
- };
37
- }),
38
- close: () => Promise.resolve()
39
- };
40
- }, M = e.namespace("@prose-reader/streamer", !1, { color: "#ffae42" }), he = (e) => {
41
- let t = {};
42
- for (let n of e) {
43
- let e = n.split("/"), r = t;
44
- for (let t = 0; t < e.length; t++) {
45
- let n = e[t];
46
- n !== void 0 && (r[n] || (r[n] = {}), r = r[n]);
47
- }
48
- }
49
- let n = (e, t = "") => Object.keys(e).sort().map((r, i, a) => {
50
- let o = i === a.length - 1, s = t + (o ? "└── " : "├── "), c = t + (o ? " " : "│ "), l = e[r];
51
- return l && Object.keys(l).length > 0 ? `${s}${r}/\n${n(l, c)}` : `${s}${r}`;
52
- }).join("\n");
53
- return n(t);
54
- }, ge = async (e, { orderByAlpha: n, name: r, encodingFormat: i } = {}) => {
55
- let a = Object.values(e.files);
56
- n && (a = a.slice().sort((e, t) => O(e.name, t.name)));
57
- let o = {
58
- filename: r || "",
59
- encodingFormat: i,
60
- records: a.map((e) => {
61
- let n = e._data.uncompressedSize, r = k(e.name);
62
- return e.dir ? {
63
- dir: !0,
64
- basename: r,
65
- uri: e.name,
66
- size: n
67
- } : {
68
- dir: !1,
69
- basename: k(e.name),
70
- uri: e.name,
71
- encodingFormat: t(e.name),
72
- blob: () => e.async("blob"),
73
- string: () => e.async("string"),
74
- ...e.internalStream && { stream: e.internalStream },
75
- size: e._data.uncompressedSize
76
- };
77
- }),
78
- close: () => Promise.resolve()
79
- };
80
- if (M.log("Generated archive", o), process.env.NODE_ENV === "development" && M.isEnabled()) {
81
- let e = he(a.map((e) => e.name));
82
- M.groupCollapsed(...M.getGroupArgs("Archive folder structure")), M.log(`\n${e}`), M.groupEnd();
83
- }
84
- return o;
85
- }, _e = async (e, { name: n, encodingFormat: r } = {}) => {
86
- let i = await e.getFilesArray(), a = {
87
- close: () => e.close(),
88
- filename: n ?? "",
89
- encodingFormat: r,
90
- records: i.map((e) => ({
91
- dir: !1,
92
- basename: e.file.name,
93
- encodingFormat: t(e.file.name),
94
- size: e.file.size,
95
- uri: `${e.path}${e.file.name}`,
96
- blob: async () => await e.file.extract(),
97
- string: async () => (await e.file.extract()).text()
98
- }))
99
- };
100
- return M.log("Generated archive", a), a;
101
- }, ve = async (e, { mimeType: t, direction: n } = { mimeType: "text/plain" }) => {
102
- let r = `
103
- <?xml version="1.0" encoding="UTF-8"?>
104
- <package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
105
- unique-identifier="ootuya-id">
106
- <metadata xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/"
107
- xmlns:dcterms="http://purl.org/dc/terms/">
108
- <meta property="rendition:layout">reflowable</meta>
109
- </metadata>
110
- <manifest>
111
- <item id="p01" href="p01.txt" media-type="text/plain"/>
112
- </manifest>
113
- <spine page-progression-direction="${n ?? "ltr"}">
114
- <itemref idref="p01" />
115
- </spine>
116
- </package>
117
- `;
118
- return {
119
- filename: "content.txt",
120
- encodingFormat: t,
121
- records: [{
122
- dir: !1,
123
- basename: k("generated.opf"),
124
- uri: "generated.opf",
125
- blob: async () => new Blob([r]),
126
- string: async () => r,
127
- size: 0
128
- }, {
129
- dir: !1,
130
- basename: k("p01.txt"),
131
- uri: "p01.txt",
132
- blob: async () => typeof e == "string" ? new Blob([e]) : e,
133
- string: async () => typeof e == "string" ? e : e.text(),
134
- size: typeof e == "string" ? e.length : e.size,
135
- encodingFormat: t
136
- }],
137
- close: () => Promise.resolve()
138
- };
139
- }, ye = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/, be = /^[A-Za-z0-9_]/, N = /^xml/i, xe = /[^A-Za-z0-9_.-]+/g, P = "_", Se = (e) => e.replace(/^_+|_+$/g, ""), Ce = (e) => Se(e.trim().replaceAll("/", "_").replace(xe, "_")), F = (e) => {
140
- if (ye.test(e) && !N.test(e)) return e;
141
- let t = Ce(e), n = t && !N.test(t) ? t : `${P}${t}`;
142
- return be.test(n) ? n : `${P}${n}`;
143
- }, I = (e, t) => {
144
- let n = F(e);
145
- if (!t.has(n)) return t.add(n), n;
146
- let r = 2, i = `${n}-${r}`;
147
- for (; t.has(i);) r += 1, i = `${n}-${r}`;
148
- return t.add(i), i;
149
- }, L = () => {
150
- let e = /* @__PURE__ */ new Set();
151
- return (t) => I(t, e);
152
- }, we = async (e, r) => {
153
- let i = L(), a = e.map((e) => ({
154
- id: i(e),
155
- url: e
156
- })), o = `
157
- <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
158
- <metadata>
159
- <meta property="rendition:layout">${r?.useRenditionFlow ? "reflowable" : "pre-paginated"}</meta>
160
- ${r?.useRenditionFlow ? "<meta property=\"rendition:flow\">scrolled-continuous</meta>" : ""}
161
- </metadata>
162
- <manifest>
163
- ${a.map(({ id: e, url: r }) => {
164
- let i = t(r);
165
- return `<item id="${e}" href="${n(r)}" media-type="${n(i ?? "")}"/>`;
166
- }).join("\n")}
167
- </manifest>
168
- <spine>
169
- ${a.map(({ id: e }) => `<itemref idref="${e}" />`).join("\n")}
170
- </spine>
171
- </package>
172
- `;
173
- return {
174
- filename: "",
175
- records: [{
176
- dir: !1,
177
- basename: "content.opf",
178
- uri: "content.opf",
179
- size: 0,
180
- blob: async () => new Blob(),
181
- string: async () => o
182
- }, ...e.map((n) => ({
183
- dir: !1,
184
- basename: k(n),
185
- encodingFormat: t(n),
186
- uri: n,
187
- size: 100 / e.length,
188
- blob: async () => (await fetch(n)).blob(),
189
- string: async () => ""
190
- }))],
191
- close: () => Promise.resolve()
192
- };
193
- }, Te = (e) => !e.dir, Ee = c.toLowerCase(), R = (e) => e.records.find((e) => Te(e) && e.basename.toLowerCase() === Ee), De = ({ enableReport: e } = {}) => {
194
- M.enable(!!e);
195
- }, z = (e) => {
196
- let t = Object.values(e.records).filter((e) => !e.dir).find((e) => e.uri.endsWith(".opf"));
197
- return {
198
- data: t,
199
- basePath: t?.uri.substring(0, t.uri.lastIndexOf("/")) || ""
200
- };
201
- };
202
- //#endregion
203
- //#region src/epubs/readArchiveOpf.ts
204
- async function B(e) {
205
- let { data: t, basePath: n } = z(e) || {};
206
- if (!(!t || t.dir)) return {
207
- opf: p(await t.string()),
208
- basePath: n
209
- };
210
- }
211
- //#endregion
212
- //#region src/generators/manifest/hooks/apple.ts
213
- var Oe = s.toLowerCase(), ke = ({ archive: e }) => async (t) => {
214
- let n = e.records.find((e) => !e.dir && e.basename.toLowerCase() === Oe);
215
- if (!n || n.dir) return t;
216
- let r = await n.string();
217
- try {
218
- let { renditionLayout: e } = m(u(r));
219
- return {
220
- ...t,
221
- renditionLayout: t.renditionLayout ?? e
222
- };
223
- } catch (e) {
224
- return console.error(`Unable to parse ${s} for content\n`, r), console.error(e), t;
225
- }
226
- }, Ae = c.toLowerCase(), je = ({ archive: e }) => async (t) => {
227
- let n = R(e);
228
- if (!n) return t;
229
- let r = {
230
- ...t,
231
- spineItems: t.spineItems.filter((e) => !e.id.toLowerCase().endsWith(Ae)).map((e, t, n) => ({
232
- ...e,
233
- progressionWeight: 1 / n.length
234
- }))
235
- }, i = await n.string();
236
- try {
237
- let e = m(d(i));
238
- return {
239
- ...r,
240
- readingDirection: e.readingDirection ?? r.readingDirection
241
- };
242
- } catch (e) {
243
- return console.error(`Unable to parse ${c} for content\n`, i), console.error(e), r;
244
- }
245
- }, Me = ({ baseUrl: e = "", resourcePath: t }) => {
246
- if (!e && /^https?:\/\//.test(t)) return encodeURI(t);
247
- let n = e ? `${e}${e.endsWith("/") ? "" : "/"}` : "file://";
248
- return encodeURI(`${n}${t}`);
249
- }, Ne = ({ archive: e, baseUrl: t }) => async () => {
250
- let n = Object.values(e.records).filter((e) => !e.dir), r = L(), i = n.map((e) => ({
251
- file: e,
252
- id: r(e.uri)
253
- }));
254
- return {
255
- filename: e.filename,
256
- title: e.records.find(({ dir: e }) => e)?.basename.replace(/\/$/, "") || e.filename,
257
- renditionLayout: void 0,
258
- renditionSpread: "auto",
259
- readingDirection: void 0,
260
- spineItems: i.filter(({ file: e }) => !e.basename.endsWith(".db")).map(({ file: e, id: r }, i) => ({
261
- id: r,
262
- index: i,
263
- href: Me({
264
- baseUrl: t,
265
- resourcePath: e.uri
266
- }),
267
- renditionLayout: void 0,
268
- progressionWeight: 1 / n.length,
269
- pageSpreadLeft: void 0,
270
- pageSpreadRight: void 0,
271
- mediaType: e.encodingFormat
272
- })),
273
- items: i.map(({ file: e, id: n }) => ({
274
- id: n,
275
- href: encodeURI(`${t}${e.uri}`)
276
- }))
277
- };
278
- }, V = async ({ archive: e, archiveOpf: t }) => {
279
- if (!t) return [];
280
- let { opf: n, basePath: r } = t, { spineRows: i } = n;
281
- return e.records.filter((e) => i.find((t) => r ? `${r}/${t.href}` === e.uri : `${t.href}` === e.uri));
282
- }, H = (e, t, n) => {
283
- let { basePath: r } = z(t) || {};
284
- return e.map((e) => {
285
- let t = e.href, i = n?.(t) ?? "";
286
- return {
287
- href: r ? `${i}${r}/${t}` : `${i}${t}`,
288
- id: e.id,
289
- mediaType: e.mediaType
290
- };
291
- });
292
- }, Pe = (e) => {
293
- let t = e?.trim();
294
- return t === "scrolled-continuous" || t === "scrolled-doc" || t === "paginated" || t === "auto" ? t : "auto";
295
- }, Fe = (e) => {
296
- let t = e?.trim();
297
- if (t === "none" || t === "landscape" || t === "portrait" || t === "both" || t === "auto") return t;
298
- }, Ie = (e) => {
299
- let t = e?.trim();
300
- if (t === "cover" || t === "title-page" || t === "copyright-page" || t === "text") return t;
301
- }, Le = ({ archive: e, baseUrl: t, archiveOpf: n }) => async (r) => {
302
- if (!n) return r;
303
- let { opf: i, basePath: a } = n, o = m(i);
304
- M.groupCollapsed(...M.getGroupArgs("OPF parsed")), M.log("opf", i), M.groupEnd();
305
- let s = i.renditionLayoutMeta?.trim(), c = s === "reflowable" || s === "pre-paginated" ? s : o.renditionLayout, l = i.title?.trim() || e.records.find(({ dir: e }) => e)?.basename || "", u = o.readingDirection ?? r.readingDirection, d = (await V({
306
- archive: e,
307
- archiveOpf: n
308
- })).reduce((e, t) => t.size + e, 0), f = i.guide, p = [];
309
- for (let e of f) {
310
- let t = Ie(e.type);
311
- t !== void 0 && p.push({
312
- href: e.href,
313
- title: e.title,
314
- type: t
315
- });
316
- }
317
- return {
318
- filename: e.filename,
319
- renditionLayout: c,
320
- renditionFlow: Pe(i.renditionFlowMeta),
321
- renditionSpread: Fe(i.renditionSpreadMeta),
322
- title: l,
323
- readingDirection: u,
324
- spineItems: i.spineRows.map((n, r) => {
325
- let i = e.records.find((e) => e.uri.endsWith(n.href))?.size || 0, o = t || (/^https?:\/\//.test(n.href) ? "" : "file://");
326
- return {
327
- id: n.id,
328
- index: r,
329
- href: n.href.startsWith("https://") ? n.href : a ? `${o}${a}/${n.href}` : `${o}${n.href}`,
330
- renditionLayout: n.renditionLayout ?? c,
331
- ...n.renditionFlow === void 0 ? {} : { renditionFlow: n.renditionFlow },
332
- progressionWeight: i / d,
333
- pageSpreadLeft: n.pageSpreadLeft,
334
- pageSpreadRight: n.pageSpreadRight,
335
- mediaType: n.mediaType
336
- };
337
- }),
338
- items: H(i.manifestItems, e, (e) => /^https?:\/\//.test(e) ? "" : t || "file://"),
339
- guide: p.length > 0 ? p : void 0
340
- };
341
- }, Re = (e) => {
342
- let t = e.descendantWithPath("head")?.childrenNamed("meta").find((e) => e.attr.name === "viewport");
343
- return !!(t && t.attr.name === "viewport");
344
- }, ze = (e) => e.reduce(async (e, t) => {
345
- if (!await e || !i({
346
- mimeType: t.encodingFormat,
347
- uri: t.uri
348
- })) return !1;
349
- let n = t.dir ? null : await t.string();
350
- return n ? Re(new h(n)) : !1;
351
- }, Promise.resolve(!0)), Be = ({ archive: e, archiveOpf: t }) => async (n) => n.renditionLayout === "reflowable" && n.spineItems.every((e) => e.renditionLayout === "reflowable") && await ze(await V({
352
- archive: e,
353
- archiveOpf: t
354
- })) ? {
355
- ...n,
356
- spineItems: n.spineItems.map((e) => ({
357
- ...e,
358
- renditionLayout: "pre-paginated"
359
- })),
360
- renditionLayout: "pre-paginated"
361
- } : n, Ve = () => (e) => ({
362
- ...e,
363
- readingDirection: e.readingDirection ?? "ltr"
364
- }), He = async (e) => {
365
- let t;
366
- return await Promise.all(e.records.map(async (e) => {
367
- if (e.dir || !e.uri.endsWith(l)) return;
368
- let n = await e.string();
369
- try {
370
- let { renditionLayout: e } = f(n);
371
- e && (t = e);
372
- } catch (e) {
373
- console.error(`Unable to parse ${l} for content\n`, n), console.error(e);
374
- }
375
- })), {
376
- kind: "kobo",
377
- ...t === void 0 ? {} : { renditionLayout: t }
378
- };
379
- }, Ue = ({ archive: e }) => async (t) => {
380
- let { renditionLayout: n } = m(await He(e));
381
- return {
382
- ...t,
383
- renditionLayout: t.renditionLayout ?? n
384
- };
385
- }, U = (e) => e.toLowerCase().endsWith(".opf"), We = (e) => e.records.some((e) => !e.dir && (U(e.basename) || U(e.uri))), Ge = ({ archive: e }) => async (n) => We(e) ? n : {
386
- ...n,
387
- spineItems: n.spineItems.map((n) => {
388
- let i = e.records.find((e) => decodeURI(n.href).endsWith(e.uri)), o = a(i?.encodingFormat ?? "") || t(i?.basename ?? "");
389
- return {
390
- ...n,
391
- renditionLayout: o && r(o) ? "pre-paginated" : n.renditionLayout
392
- };
393
- })
394
- }, W = (e) => e ? e.children.map((e) => e instanceof ne ? e.text : e instanceof te ? W(e) : "").join("").trim() : "", Ke = (e) => ee(e.properties).includes("nav"), G = (e, { basePath: t, baseUrl: n }) => {
395
- let r = {
396
- contents: [],
397
- path: "",
398
- href: "",
399
- title: ""
400
- }, i = e.childNamed("span") || e.childNamed("a");
401
- r.title = (i?.attr.title || i?.val.trim() || W(i)) ?? "";
402
- let a = i?.name;
403
- a !== "a" && (i = e.descendantWithPath(`${a}.a`), i && (a = i.name.toLowerCase())), a === "a" && i?.attr.href && (r.path = o(t, i.attr.href), r.href = o(n, t, i.attr.href));
404
- let s = e.childNamed("ol");
405
- if (s) {
406
- let e = s.childrenNamed("li");
407
- e && e.length > 0 && (r.contents = e.map((e) => G(e, {
408
- basePath: t,
409
- baseUrl: n
410
- })));
411
- }
412
- return r;
413
- }, qe = (e, { basePath: t, baseUrl: n }) => {
414
- let r = [], i;
415
- 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) => {
416
- r.push(G(e, {
417
- basePath: t,
418
- baseUrl: n
419
- }));
420
- }), r;
421
- }, Je = async (e, t, { baseUrl: n }) => {
422
- let r = e.manifestItems.find(Ke);
423
- if (r?.href) {
424
- let e = Object.values(t.records).find((e) => e.uri.endsWith(r.href));
425
- if (e && !e.dir) return qe(new h(await e.string()), {
426
- basePath: j(e.uri),
427
- baseUrl: n
428
- });
429
- }
430
- }, K = (e, { opfBasePath: t, baseUrl: n, prefix: r }) => {
431
- let i = e?.childNamed(`${r}content`)?.attr.src || "", a = {
432
- title: e?.descendantWithPath(`${r}navLabel.${r}text`)?.val || "",
433
- path: o(t, i),
434
- href: o(n, t, i),
435
- contents: []
436
- }, s = e.childrenNamed(`${r}navPoint`);
437
- return s && s.length > 0 && (a.contents = s.map((e) => K(e, {
438
- opfBasePath: t,
439
- baseUrl: n,
440
- prefix: r
441
- }))), a;
442
- }, Ye = (e, { opfBasePath: t, baseUrl: n }) => {
443
- let r = [], i = e.name, a = "";
444
- return i.indexOf(":") !== -1 && (a = `${i.split(":")[0]}:`), e.childNamed(`${a}navMap`)?.childrenNamed(`${a}navPoint`).forEach((e) => {
445
- r.push(K(e, {
446
- opfBasePath: t,
447
- baseUrl: n,
448
- prefix: a
449
- }));
450
- }), r;
451
- }, Xe = async ({ opf: e, opfBasePath: t, baseUrl: n, archive: r }) => {
452
- let i = e.spineTocIdref;
453
- if (i) {
454
- let a = e.manifestItems.find((e) => e.id === i);
455
- if (a) {
456
- let e = `${t}${t === "" ? "" : "/"}${a.href}`, i = Object.values(r.records).find((t) => t.uri.endsWith(e));
457
- if (i && !i.dir) return Ye(new h(await i.string()), {
458
- opfBasePath: t,
459
- baseUrl: n
460
- });
461
- }
462
- }
463
- }, Ze = async (e, t, { baseUrl: n }) => {
464
- let { basePath: r } = z(t) || {}, i = await Je(e, t, { baseUrl: n });
465
- if (i) return i;
466
- let a = await Xe({
467
- opf: e,
468
- opfBasePath: r ?? "",
469
- archive: t,
470
- baseUrl: n
471
- });
472
- if (a) return a;
473
- }, Qe = (e) => e.replace(/\.[^.]+$/, "").replace(/[_-]/g, " ").replace(/\s+/g, " ").trim(), $e = (e, n) => {
474
- if (e.spineItems.length !== 0 && e.spineItems.every((e) => (a(e.mediaType ?? "") || t(e.href))?.startsWith("audio/"))) return e.spineItems.map((e) => {
475
- let t = n.records.find((t) => !t.dir && decodeURI(e.href).endsWith(t.uri));
476
- return {
477
- title: Qe(t?.basename ?? e.href),
478
- href: e.href,
479
- path: t?.uri ?? e.href,
480
- contents: []
481
- };
482
- });
483
- }, et = (e, { baseUrl: t }) => {
484
- let n = [...e.records].sort((e, t) => O(e.uri, t.uri)), r = (e, t, n, i, a) => {
485
- let o = e.find((e) => e.title === t), [s, ...c] = n;
486
- return o ? s ? [...e.filter((e) => e !== o), {
487
- ...o,
488
- contents: [...o.contents, ...r(o.contents, s, c, i, a)]
489
- }] : o.path.split("/").length > a.split("/").length ? [...e.filter((e) => e !== o), {
490
- ...o,
491
- path: a,
492
- href: i
493
- }] : e : s ? [...e, {
494
- contents: r([], s, c, i, a),
495
- href: i,
496
- path: a,
497
- title: t
498
- }] : [...e, {
499
- contents: [],
500
- href: i,
501
- path: a,
502
- title: t
503
- }];
504
- };
505
- return n.reduce((e, n) => {
506
- if (n.dir) return e;
507
- let [i, ...a] = n.uri.split("/").slice(0, -1);
508
- return i ? r(e, i, a, o(t, encodeURI(n.uri)).replace(/\/$/, ""), n.uri.replace(/\/$/, "")) : e;
509
- }, []);
510
- }, tt = async (e, t, { baseUrl: n, archiveOpf: r }) => {
511
- if (r) return await Ze(r.opf, e, { baseUrl: n }) || [];
512
- let i = $e(t, e);
513
- if (i) return i;
514
- let a = et(e, { baseUrl: n });
515
- if (a.length !== 0) return a;
516
- }, nt = ({ archive: e, baseUrl: t, archiveOpf: n }) => async (r) => {
517
- if (r.nav) return r;
518
- let i = await tt(e, r, {
519
- baseUrl: t,
520
- archiveOpf: n
521
- });
522
- return i ? {
523
- ...r,
524
- nav: { toc: i }
525
- } : r;
526
- }, rt = (e) => e ? e.endsWith("/") ? e : `${e}/` : "", q = async (e, { baseUrl: t = "", hooks: n = {} } = {}) => {
527
- M.log("Generating manifest from archive", e);
528
- let r = await B(e), i = rt(t), a = (t) => (t ?? []).map((t) => t({
529
- archive: e,
530
- baseUrl: i
531
- })), o = [
532
- Le({
533
- archive: e,
534
- baseUrl: i,
535
- archiveOpf: r
536
- }),
537
- je({
538
- archive: e,
539
- baseUrl: i
540
- }),
541
- ke({
542
- archive: e,
543
- baseUrl: i
544
- }),
545
- Ge({
546
- archive: e,
547
- baseUrl: i
548
- }),
549
- ...a(n.content)
550
- ], s = a(n.spine), c = [
551
- Be({
552
- archive: e,
553
- baseUrl: i,
554
- archiveOpf: r
555
- }),
556
- Ue({
557
- archive: e,
558
- baseUrl: i
559
- }),
560
- ...a(n.presentation)
561
- ], l = [nt({
562
- archive: e,
563
- baseUrl: i,
564
- archiveOpf: r
565
- }), ...a(n.navigation)], u = [
566
- ...o,
567
- ...s,
568
- ...c,
569
- ...l,
570
- Ve()
571
- ];
572
- try {
573
- let t = Ne({
574
- archive: e,
575
- baseUrl: i
576
- })(), n = await u.reduce(async (e, t) => await t(await e), t);
577
- if (M.log("Generated manifest", n), process.env.NODE_ENV === "development" && M.isEnabled()) {
578
- let e = JSON.stringify(n, null, 2);
579
- M.groupCollapsed(...M.getGroupArgs("Generated manifest")), M.log(`\n${e}`), M.groupEnd();
580
- }
581
- return n;
582
- } catch (e) {
583
- throw M.error(e), e;
584
- }
585
- }, it = (e) => {
586
- let t = e.descendantWithPath("head")?.childrenNamed("meta").find((e) => e.attr.name === "calibre:cover");
587
- return !!(t && t.attr.name === "calibre:cover");
588
- }, at = (e) => e.descendantWithPath("body")?.descendantWithPath("div")?.childrenNamed("svg")?.find((e) => e.attr.width === "100%" && e.attr.preserveAspectRatio === "none"), ot = ({ archive: e, resourcePath: t }) => async (n) => {
589
- let r = Object.values(e.records).find((e) => e.uri === t && !e.dir);
590
- if (r && !r.dir && r.basename.endsWith(".xhtml")) {
591
- let e = new h(typeof n.body == "string" ? n.body : await r.string());
592
- if (it(e)) {
593
- let t = at(e);
594
- return t && delete t.attr.preserveAspectRatio, {
595
- ...n,
596
- body: e?.toString()
597
- };
598
- }
599
- }
600
- return n;
601
- }, st = ({ archive: e, resourcePath: t }) => async (n) => ot({
602
- archive: e,
603
- resourcePath: t
604
- })(n), ct = ({ archive: e, resourcePath: t }) => async (n) => {
605
- let r = Object.values(e.records).find((e) => e.uri === t && !e.dir);
606
- if (r && !r.dir && r.basename.endsWith(".css")) {
607
- let e = (typeof n.body == "string" ? n.body : await r.string()).replaceAll("-webkit-writing-mode", "writing-mode");
608
- return {
609
- ...n,
610
- body: e
611
- };
612
- }
613
- return n;
614
- }, lt = async (e, t) => {
615
- let n = await B(e);
616
- if (n) {
617
- let { opf: r } = n, i = H(r.manifestItems, e, () => "");
618
- if (i.find((e) => t.endsWith(e.href))?.mediaType) return { mediaType: i.find((e) => t.endsWith(e.href))?.mediaType };
619
- }
620
- return { mediaType: ut(t) };
621
- }, ut = (e) => {
622
- if (e.endsWith(".css")) return "text/css; charset=UTF-8";
623
- if (e.endsWith(".jpg")) return "image/jpg";
624
- if (e.endsWith(".xhtml")) return "application/xhtml+xml";
625
- if (e.endsWith(".mp4")) return "video/mp4";
626
- if (e.endsWith(".svg")) return "image/svg+xml";
627
- }, dt = ({ archive: e, resourcePath: t }) => async (n) => {
628
- let r = Object.values(e.records).find((e) => e.uri === t && !e.dir);
629
- if (!r || r.dir) return n;
630
- let i = await lt(e, t);
631
- return {
632
- ...n,
633
- params: {
634
- ...n.params,
635
- ...r?.encodingFormat && { contentType: r.encodingFormat },
636
- ...i.mediaType && { contentType: i.mediaType }
637
- }
638
- };
639
- }, J = /* @__PURE__ */ "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("."), ft = ({ archive: e, resourcePath: t }) => async (n) => {
640
- let r = Object.values(e.records).find((e) => e.uri === t && !e.dir);
641
- if (r && !r.dir && r.basename.endsWith(".xhtml")) {
642
- let e = typeof n.body == "string" ? n.body : await r.string();
643
- if (!RegExp(`<(${J.join("|")})[\\s/>]`, "i").test(e)) return n;
644
- let t = RegExp(`<(${J.join("|")})(\\s[^>]*)?\\s*/>`, "gi"), i = e.replace(t, (e, t, n = "") => `<${t} ${n.trim()}></${t}>`);
645
- return {
646
- ...n,
647
- body: i
648
- };
649
- }
650
- return n;
651
- }, Y = async (e, t, { hooks: n = [] } = {}) => {
652
- let r = { params: {} }, i = [
653
- ...n.map((n) => n({
654
- archive: e,
655
- resourcePath: t
656
- })),
657
- dt({
658
- archive: e,
659
- resourcePath: t
660
- }),
661
- ft({
662
- archive: e,
663
- resourcePath: t
664
- }),
665
- ct({
666
- archive: e,
667
- resourcePath: t
668
- }),
669
- st({
670
- archive: e,
671
- resourcePath: t
672
- })
673
- ];
674
- try {
675
- let n = await i.reduce(async (e, t) => await t(await e), Promise.resolve(r));
676
- if (M.log("Generated resource", t, n), n.body !== void 0) return n;
677
- let a = Object.values(e.records).find((e) => e.uri === t && !e.dir);
678
- if (!a || a.dir) throw Error(`no file found for resourcePath:${t}`);
679
- return {
680
- ...n,
681
- body: await a.blob()
682
- };
683
- } catch (e) {
684
- throw M.error(e), e;
685
- }
686
- }, pt = class {
687
- constructor(e) {
688
- this.cleanArchiveAfter = e, this.state$ = new re({
689
- status: "idle",
690
- locks: 0
691
- });
692
- }
693
- update(e) {
694
- this.state$.next({
695
- ...this.state$.getValue(),
696
- ...e
697
- });
698
- }
699
- get locks$() {
700
- return this.state$.pipe(C(({ locks: e }) => e));
701
- }
702
- get state() {
703
- return this.state$.getValue();
704
- }
705
- get isUnlocked$() {
706
- return this.locks$.pipe(C((e) => e <= 0), ie(), ue());
707
- }
708
- get overTTL$() {
709
- return this.isUnlocked$.pipe(E((e) => e ? this.cleanArchiveAfter === Infinity ? _ : pe(this.cleanArchiveAfter) : _));
710
- }
711
- }, mt = ({ getArchive: e, cleanArchiveAfter: t = 300 * 1e3 }) => {
712
- let n = new v(), r = new v(), i = new v(), a = {};
713
- return n.pipe(T((t) => {
714
- let n = a[t];
715
- if (!n || n.state.status !== "idle") return g;
716
- let r = !1, o = (e) => {
717
- M.debug(`Cleaning up archive with key: ${e}`);
718
- let t = a[e];
719
- delete a[e], r ||= (t?.state.archive?.close(), !0);
720
- };
721
- n.update({ status: "loading" });
722
- let s = n.locks$, c = n.isUnlocked$, l = s.pipe(le(), b(([e, t]) => t > e), de(!0));
723
- return S(e(t)).pipe(D((e) => {
724
- n.update({
725
- archive: e,
726
- status: "success"
727
- });
728
- }), y((e) => (o(t), n.update({
729
- status: "error",
730
- error: e
731
- }), g)), E(() => w(l.pipe(E(() => i), E(() => c), b((e) => e)), n.overTTL$).pipe(x(), D(() => {
732
- o(t);
733
- }))));
734
- }), fe(r)).subscribe(), {
735
- access: (e) => {
736
- let r = !1, i = a[e] ?? new pt(t);
737
- a[e] = i, i.update({ locks: i.state.locks + 1 });
738
- let o = () => {
739
- r || (r = !0, i.update({ locks: i.state.locks - 1 }));
740
- };
741
- return n.next(e), w(i.state$.pipe(C(({ archive: e }) => e), b((e) => !!e)), i.state$.pipe(D(({ error: e }) => {
742
- if (e) throw e;
743
- }), oe())).pipe(x(), C((e) => ({
744
- archive: e,
745
- release: o
746
- })), y((e) => {
747
- throw o(), e;
748
- }));
749
- },
750
- purge: () => {
751
- i.next();
752
- },
753
- _archives: a
754
- };
755
- }, X = (e) => e ? /^\d+$/.test(e) ? {
756
- valid: !0,
757
- value: Number.parseInt(e, 10)
758
- } : {
759
- valid: !1,
760
- value: void 0
761
- } : {
762
- valid: !0,
763
- value: void 0
764
- }, ht = (e) => {
765
- if (!e.toLowerCase().startsWith("bytes=")) return { kind: "missing" };
766
- let t = e.slice(6).trim();
767
- if (!t) return { kind: "invalid" };
768
- if (t.includes(",")) return { kind: "multi" };
769
- let n = /^(\d*)-(\d*)$/.exec(t);
770
- if (!n) return { kind: "invalid" };
771
- let [, r = "", i = ""] = n, a = X(r.trim()), o = X(i.trim());
772
- return !a.valid || !o.valid ? { kind: "invalid" } : {
773
- kind: "single",
774
- start: a.value,
775
- end: o.value
776
- };
777
- }, gt = (e) => {
778
- if (e instanceof Blob) return {
779
- size: e.size,
780
- slice: (t, n) => {
781
- let r = e.slice(t, n);
782
- return {
783
- content: r,
784
- length: r.size
785
- };
786
- }
787
- };
788
- let t = new TextEncoder().encode(e);
789
- return {
790
- size: t.byteLength,
791
- slice: (e, n) => {
792
- let r = t.slice(e, n);
793
- return {
794
- content: r,
795
- length: r.byteLength
796
- };
797
- }
798
- };
799
- }, _t = ({ body: e, contentType: t, rangeHeader: n }) => {
800
- let r = new Headers();
801
- 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, {
802
- status: 200,
803
- headers: r
804
- });
805
- let i = ht(n);
806
- if (i.kind === "missing" || i.kind === "multi") return e instanceof Blob && r.set("Content-Length", String(e.size)), new Response(e, {
807
- status: 200,
808
- headers: r
809
- });
810
- let a = gt(e), o = a.size;
811
- if (i.kind === "invalid") return new Response(null, {
812
- status: 416,
813
- headers: { "Content-Range": `bytes */${o}` }
814
- });
815
- let s = i.start, c = i.end;
816
- 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, {
817
- status: 416,
818
- headers: { "Content-Range": `bytes */${o}` }
819
- });
820
- let l = a.slice(s, c + 1);
821
- return r.set("Content-Length", String(l.length)), r.set("Content-Range", `bytes ${s}-${c}/${o}`), new Response(l.content, {
822
- status: 206,
823
- headers: r
824
- });
825
- }, Z = "file://", vt = /^https?:\/\//, yt = (e) => {
826
- try {
827
- return decodeURIComponent(e);
828
- } catch {
829
- return e;
830
- }
831
- }, Q = (e) => e.startsWith(Z) ? e.slice(Z.length) : e, bt = (e) => {
832
- let t = Q(e);
833
- return vt.test(t) ? t : Q(yt(t));
834
- }, $ = class {
835
- constructor({ hooks: e, onError: t, onManifestSuccess: n, ...r }) {
836
- this.onError = (e) => (console.error(e), new Response(String(e), { status: 500 })), this.archiveLoader = mt(r), this.hooks = e ?? {}, this.onManifestSuccess = n ?? (({ manifest: e }) => Promise.resolve(e)), this.onError = t ?? this.onError;
837
- }
838
- prune() {
839
- this.archiveLoader.purge();
840
- }
841
- accessArchive(e) {
842
- return this.lastAccessedKey !== void 0 && this.lastAccessedKey !== e && this.archiveLoader.purge(), this.lastAccessedKey = e, this.archiveLoader.access(e);
843
- }
844
- accessArchiveWithoutLock(e) {
845
- return this.accessArchive(e).pipe(C(({ archive: e, release: t }) => (t(), e)));
846
- }
847
- withArchiveResponse({ key: e, getResponse: t }) {
848
- return se(this.accessArchive(e).pipe(T(({ archive: e, release: n }) => S(t(e)).pipe(ae(() => {
849
- n();
850
- }))), y((e) => ce(this.onError(e)))));
851
- }
852
- fetchManifest({ key: e, baseUrl: t }) {
853
- return this.withArchiveResponse({
854
- key: e,
855
- getResponse: (e) => S(q(e, {
856
- baseUrl: t,
857
- hooks: this.hooks.manifest
858
- })).pipe(E((t) => S(this.onManifestSuccess({
859
- manifest: t,
860
- archive: e
861
- }))), C((e) => new Response(JSON.stringify(e), { status: 200 })))
862
- });
863
- }
864
- fetchResource({ key: e, resourcePath: t, request: n }) {
865
- return this.withArchiveResponse({
866
- key: e,
867
- getResponse: (e) => S(Y(e, bt(t), { hooks: this.hooks.resource })).pipe(C((e) => _t({
868
- body: e.body ?? "",
869
- contentType: e.params.contentType,
870
- rangeHeader: n?.headers.get("range")
871
- })))
872
- });
873
- }
874
- }, xt = class extends $ {
875
- constructor({ getUriInfo: e, ...t }) {
876
- super(t), this.getUriInfo = e, this.fetchEventListener = this.fetchEventListener.bind(this);
877
- }
878
- fetchEventListener(e) {
879
- try {
880
- let t = this.getUriInfo(e);
881
- if (!t) return;
882
- let n = A(t.baseUrl), r = e.request.url.substring(n.length + 1), [i = ""] = r.split("/"), a = A(r.substring(i.length + 1));
883
- r.endsWith("/manifest") ? e.respondWith(this.fetchManifest({
884
- key: i,
885
- baseUrl: `${n}/${i}/`
886
- })) : e.respondWith(this.fetchResource({
887
- key: i,
888
- resourcePath: a,
889
- request: e.request
890
- }));
891
- } catch (t) {
892
- e.respondWith(new Response(String(t), { status: 500 }));
893
- }
894
- }
895
- };
896
- //#endregion
897
- export { xt as ServiceWorkerStreamer, $ as Streamer, De as configure, me as createArchiveFromArrayBufferList, ge as createArchiveFromJszip, _e as createArchiveFromLibArchive, ve as createArchiveFromText, we as createArchiveFromUrls, I as createUniqueXmlSafeId, F as createXmlSafeId, L as createXmlSafeIdFactory, q as generateManifestFromArchive, Y as generateResourceFromArchive, R as getArchiveHasComicInfo, z as getArchiveOpfInfo, j as getUriBasePath, k as getUriBasename, A as removeTrailingSlash, O as sortByTitleComparator };
898
-
899
- //# sourceMappingURL=index.js.map