@prose-reader/streamer 1.40.0 → 1.42.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.
@@ -4,7 +4,7 @@ import { Archive } from "../../../archives/types";
4
4
  * Handle archive which contains ComicInfo.xml. This is a meta file
5
5
  * used to define cbz, etc. I believe it comes from some sites or apps.
6
6
  */
7
- export declare const comicInfoHook: ({ archive, baseUrl }: {
7
+ export declare const comicInfoHook: ({ archive }: {
8
8
  archive: Archive;
9
9
  baseUrl: string;
10
10
  }) => (manifest: Manifest) => Promise<Manifest>;
@@ -1,6 +1,6 @@
1
1
  import { Manifest } from "@prose-reader/shared";
2
2
  import { Archive } from "../../../archives/types";
3
- export declare const epubOptimizerHook: ({ archive, baseUrl }: {
3
+ export declare const epubOptimizerHook: ({ archive }: {
4
4
  archive: Archive;
5
5
  baseUrl: string;
6
6
  }) => (manifest: Manifest) => Promise<Manifest>;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,573 @@
1
+ import { urlJoin as v, PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME as J, isXmlBasedMimeType as q, detectMimeTypeFromName as O } from "@prose-reader/shared";
2
+ import g, { XmlDocument as Y } from "xmldoc";
3
+ let b = !1;
4
+ const h = {
5
+ enable: (e) => {
6
+ b = e;
7
+ },
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ log: (...e) => {
10
+ b && console.log("[prose-reader-streamer]", ...e);
11
+ },
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ warn: (...e) => {
14
+ b && console.warn("[prose-reader-streamer]", ...e);
15
+ },
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ error: (...e) => {
18
+ console.error(...e);
19
+ },
20
+ time: (e) => {
21
+ b && console.time(`[prose-reader-streamer] [metric] ${e}`);
22
+ },
23
+ timeEnd: (e) => {
24
+ b && console.timeEnd(`[prose-reader-streamer] [metric] ${e}`);
25
+ },
26
+ metric: (e, n = 1 / 0) => {
27
+ const i = typeof e == "number" ? e : e.duration;
28
+ b && (e.duration <= n ? console.log("[prose-reader-streamer] [metric] ", `${e.name} took ${i}ms`) : console.warn(
29
+ "[prose-reader-streamer] [metric] ",
30
+ `${e.name} took ${e.duration}ms which is above the ${n}ms target for this function`
31
+ ));
32
+ },
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ measurePerformance: (e, n = 10, i) => (...t) => {
35
+ const a = performance.now(), r = i(...t);
36
+ if (r && r.then)
37
+ return r.then((s) => {
38
+ const l = performance.now();
39
+ return h.metric({ name: e, duration: l - a }, n), s;
40
+ });
41
+ const o = performance.now();
42
+ return h.metric({ name: e, duration: o - a }, n), r;
43
+ }
44
+ }, K = (e) => {
45
+ var i;
46
+ const n = (i = e.descendantWithPath("head")) == null ? void 0 : i.childrenNamed("meta").find((t) => t.attr.name === "calibre:cover");
47
+ return !!(n && n.attr.name === "calibre:cover");
48
+ }, Q = (e) => {
49
+ var n, i, t;
50
+ return (t = (i = (n = e.descendantWithPath("body")) == null ? void 0 : n.descendantWithPath("div")) == null ? void 0 : i.childrenNamed("svg")) == null ? void 0 : t.find((a) => a.attr.width === "100%" && a.attr.preserveAspectRatio === "none");
51
+ }, Z = ({ archive: e, resourcePath: n }) => async (i) => {
52
+ const t = Object.values(e.files).find((a) => a.uri === n);
53
+ if (t != null && t.basename.endsWith(".xhtml")) {
54
+ const a = i.body ?? await t.string(), r = new Y(a);
55
+ if (K(r)) {
56
+ const o = Q(r);
57
+ return o && delete o.attr.preserveAspectRatio, {
58
+ ...i,
59
+ body: r == null ? void 0 : r.toString()
60
+ };
61
+ }
62
+ }
63
+ return i;
64
+ }, E = ({ archive: e, resourcePath: n }) => async (i) => Z({ archive: e, resourcePath: n })(i), ee = ({ archive: e, resourcePath: n }) => async (i) => {
65
+ const t = Object.values(e.files).find((a) => a.uri === n);
66
+ if (t != null && t.basename.endsWith(".css")) {
67
+ const r = (i.body ?? await t.string()).replaceAll("-webkit-writing-mode", "writing-mode");
68
+ return {
69
+ ...i,
70
+ body: r
71
+ };
72
+ }
73
+ return i;
74
+ }, F = (e) => {
75
+ const i = Object.values(e.files).filter((t) => !t.dir).find((t) => t.uri.endsWith(".opf"));
76
+ return {
77
+ data: i,
78
+ basePath: (i == null ? void 0 : i.uri.substring(0, i.uri.lastIndexOf("/"))) || ""
79
+ };
80
+ }, P = (e, { opfBasePath: n, baseUrl: i }) => {
81
+ const t = {
82
+ contents: [],
83
+ path: "",
84
+ href: "",
85
+ title: ""
86
+ };
87
+ let a = e.childNamed("span") || e.childNamed("a");
88
+ t.title = (a == null ? void 0 : a.attr.title) || (a == null ? void 0 : a.val.trim()) || t.title;
89
+ let r = a == null ? void 0 : a.name;
90
+ r !== "a" && (a = e.descendantWithPath(`${r}.a`), a && (r = a.name.toLowerCase())), r === "a" && (a != null && a.attr.href) && (t.path = v(n, a.attr.href), t.href = v(i, n, a.attr.href));
91
+ const o = e.childNamed("ol");
92
+ if (o) {
93
+ const s = o.childrenNamed("li");
94
+ s && s.length > 0 && (t.contents = s.map((l) => P(l, { opfBasePath: n, baseUrl: i })));
95
+ }
96
+ return t;
97
+ }, te = (e, { opfBasePath: n, baseUrl: i }) => {
98
+ var r, o;
99
+ const t = [];
100
+ let a;
101
+ return e.descendantWithPath("body.nav.ol") ? a = (r = e.descendantWithPath("body.nav.ol")) == null ? void 0 : r.children : e.descendantWithPath("body.section.nav.ol") && (a = (o = e.descendantWithPath("body.section.nav.ol")) == null ? void 0 : o.children), a && a.length > 0 && a.filter((s) => s.name === "li").forEach((s) => t.push(P(s, { opfBasePath: n, baseUrl: i }))), t;
102
+ }, ne = async (e, n, { opfBasePath: i, baseUrl: t }) => {
103
+ var r;
104
+ const a = (r = e.childNamed("manifest")) == null ? void 0 : r.childrenNamed("item").find((o) => o.attr.properties === "nav");
105
+ if (a) {
106
+ const o = Object.values(n.files).find((s) => s.uri.endsWith(a.attr.href || ""));
107
+ if (o) {
108
+ const s = new g.XmlDocument(await o.string());
109
+ return te(s, { opfBasePath: i, baseUrl: t });
110
+ }
111
+ }
112
+ }, j = (e, { opfBasePath: n, baseUrl: i, prefix: t }) => {
113
+ var s, l;
114
+ const a = ((s = e == null ? void 0 : e.childNamed(`${t}content`)) == null ? void 0 : s.attr.src) || "", r = {
115
+ title: ((l = e == null ? void 0 : e.descendantWithPath(`${t}navLabel.${t}text`)) == null ? void 0 : l.val) || "",
116
+ path: v(n, a),
117
+ href: v(i, n, a),
118
+ contents: []
119
+ }, o = e.childrenNamed(`${t}navPoint`);
120
+ return o && o.length > 0 && (r.contents = o.map((p) => j(p, { opfBasePath: n, baseUrl: i, prefix: t }))), r;
121
+ }, re = (e, { opfBasePath: n, baseUrl: i }) => {
122
+ var o;
123
+ const t = [], a = e.name;
124
+ let r = "";
125
+ return a.indexOf(":") !== -1 && (r = a.split(":")[0] + ":"), (o = e.childNamed(`${r}navMap`)) == null || o.childrenNamed(`${r}navPoint`).forEach((s) => t.push(j(s, { opfBasePath: n, baseUrl: i, prefix: r }))), t;
126
+ }, ae = async ({
127
+ opfData: e,
128
+ opfBasePath: n,
129
+ baseUrl: i,
130
+ archive: t
131
+ }) => {
132
+ var o;
133
+ const a = e.childNamed("spine"), r = a && a.attr.toc;
134
+ if (r) {
135
+ const s = (o = e.childNamed("manifest")) == null ? void 0 : o.childrenNamed("item").find((l) => l.attr.id === r);
136
+ if (s) {
137
+ const l = `${n}${n === "" ? "" : "/"}${s.attr.href}`, p = Object.values(t.files).find((m) => m.uri.endsWith(l));
138
+ if (p) {
139
+ const m = new g.XmlDocument(await p.string());
140
+ return re(m, { opfBasePath: n, baseUrl: i });
141
+ }
142
+ }
143
+ }
144
+ }, ie = async (e, n, { baseUrl: i }) => {
145
+ const { basePath: t } = F(n) || {}, a = await ae({
146
+ opfData: e,
147
+ opfBasePath: t,
148
+ archive: n,
149
+ baseUrl: i
150
+ });
151
+ return a || await ne(e, n, { opfBasePath: t, baseUrl: i });
152
+ }, oe = async (e) => {
153
+ const n = {
154
+ renditionLayout: void 0
155
+ };
156
+ return await Promise.all(
157
+ e.files.map(async (i) => {
158
+ var t, a;
159
+ if (i.uri.endsWith("com.kobobooks.display-options.xml")) {
160
+ const o = (t = new g.XmlDocument(await i.string()).childNamed("platform")) == null ? void 0 : t.childNamed("option");
161
+ ((a = o == null ? void 0 : o.attr) == null ? void 0 : a.name) === "fixed-layout" && o.val === "true" && (n.renditionLayout = "pre-paginated");
162
+ }
163
+ })
164
+ ), n;
165
+ }, z = async ({ archive: e }) => {
166
+ const { data: n, basePath: i } = F(e) || {}, t = await (n == null ? void 0 : n.string());
167
+ if (!t)
168
+ return [];
169
+ const a = new g.XmlDocument(t), r = a.childNamed("manifest"), o = a.childNamed("spine"), s = o == null ? void 0 : o.childrenNamed("itemref").map((m) => m.attr.idref), l = (r == null ? void 0 : r.childrenNamed("item").filter((m) => s.includes(m.attr.id || ""))) || [];
170
+ return e.files.filter((m) => l.find((f) => i ? `${i}/${f.attr.href}` === m.uri : `${f.attr.href}` === m.uri));
171
+ }, X = (e) => {
172
+ var i;
173
+ const n = e.childNamed("manifest");
174
+ return ((i = n == null ? void 0 : n.childrenNamed("item")) == null ? void 0 : i.map((t) => ({
175
+ href: t.attr.href || "",
176
+ id: t.attr.id || "",
177
+ mediaType: t.attr["media-type"]
178
+ }))) || [];
179
+ }, se = ({ archive: e, baseUrl: n }) => async (i) => {
180
+ var D;
181
+ const { data: t, basePath: a } = F(e) || {}, r = await oe(e);
182
+ if (!t)
183
+ return i;
184
+ const o = await t.string();
185
+ h.log(o, r);
186
+ const s = new g.XmlDocument(o), l = await ie(s, e, { baseUrl: n }) || [], p = s.childNamed("metadata"), m = s.childNamed("manifest"), f = s.childNamed("spine"), x = s.childNamed("guide"), w = p == null ? void 0 : p.childNamed("dc:title"), $ = (p == null ? void 0 : p.childrenNamed("meta")) || [], N = $.find((d) => d.attr.property === "rendition:layout"), T = $.find((d) => d.attr.property === "rendition:flow"), I = $.find((d) => d.attr.property === "rendition:spread"), k = N == null ? void 0 : N.val, B = T == null ? void 0 : T.val, M = I == null ? void 0 : I.val, _ = (w == null ? void 0 : w.val) || ((D = e.files.find(({ dir: d }) => d)) == null ? void 0 : D.basename) || "", H = f == null ? void 0 : f.attr["page-progression-direction"], U = (await z({ archive: e })).reduce((d, c) => c.size + d, 0);
187
+ return {
188
+ filename: e.filename,
189
+ nav: {
190
+ toc: l
191
+ },
192
+ renditionLayout: k || r.renditionLayout || "reflowable",
193
+ renditionFlow: B || "auto",
194
+ renditionSpread: M,
195
+ title: _,
196
+ readingDirection: H || "ltr",
197
+ spineItems: (f == null ? void 0 : f.childrenNamed("itemref").map((d) => {
198
+ var R, W, L;
199
+ const c = m == null ? void 0 : m.childrenNamed("item").find((u) => u.attr.id === (d == null ? void 0 : d.attr.idref)), V = (c == null ? void 0 : c.attr.href) || "", A = ((R = d == null ? void 0 : d.attr.properties) == null ? void 0 : R.split(" ")) || [], G = ((W = e.files.find((u) => u.uri.endsWith(V))) == null ? void 0 : W.size) || 0, S = n ?? "";
200
+ return {
201
+ id: (c == null ? void 0 : c.attr.id) || "",
202
+ href: (L = c == null ? void 0 : c.attr.href) != null && L.startsWith("https://") ? c == null ? void 0 : c.attr.href : a ? `${S}${a}/${c == null ? void 0 : c.attr.href}` : `${S}${c == null ? void 0 : c.attr.href}`,
203
+ renditionLayout: k || "reflowable",
204
+ ...A.find((u) => u === "rendition:layout-reflowable") && {
205
+ renditionLayout: "reflowable"
206
+ },
207
+ progressionWeight: G / U,
208
+ pageSpreadLeft: A.some((u) => u === "page-spread-left") || void 0,
209
+ pageSpreadRight: A.some((u) => u === "page-spread-right") || void 0,
210
+ // size: itemSize
211
+ mediaType: c == null ? void 0 : c.attr["media-type"]
212
+ };
213
+ })) || [],
214
+ items: X(s),
215
+ guide: x == null ? void 0 : x.childrenNamed("reference").map((d) => ({
216
+ href: d.attr.href || "",
217
+ title: d.attr.title || "",
218
+ type: d.attr.type
219
+ }))
220
+ };
221
+ }, ce = async (e, n) => {
222
+ var a, r;
223
+ const t = await ((a = F(e).data) == null ? void 0 : a.string());
224
+ if (t) {
225
+ const o = new g.XmlDocument(t);
226
+ return {
227
+ mediaType: (r = X(o).find((l) => n.endsWith(l.href))) == null ? void 0 : r.mediaType
228
+ };
229
+ }
230
+ return {
231
+ mediaType: de(n)
232
+ };
233
+ }, de = (e) => {
234
+ if (e.endsWith(".css"))
235
+ return "text/css; charset=UTF-8";
236
+ if (e.endsWith(".jpg"))
237
+ return "image/jpg";
238
+ if (e.endsWith(".xhtml"))
239
+ return "application/xhtml+xml";
240
+ if (e.endsWith(".mp4"))
241
+ return "video/mp4";
242
+ if (e.endsWith(".svg"))
243
+ return "image/svg+xml";
244
+ }, le = ({ archive: e, resourcePath: n }) => async (i) => {
245
+ const t = Object.values(e.files).find((r) => r.uri === n);
246
+ if (!t)
247
+ return i;
248
+ const a = await ce(e, n);
249
+ return {
250
+ ...i,
251
+ params: {
252
+ ...i.params,
253
+ status: 200,
254
+ headers: {
255
+ ...(t == null ? void 0 : t.encodingFormat) && {
256
+ "Content-Type": t.encodingFormat
257
+ },
258
+ ...a.mediaType && {
259
+ "Content-Type": a.mediaType
260
+ }
261
+ }
262
+ }
263
+ };
264
+ }, Fe = async (e, n) => {
265
+ const i = Object.values(e.files).find((r) => r.uri === n);
266
+ if (!i)
267
+ throw new Error("no file found");
268
+ const t = {
269
+ params: {
270
+ status: 200
271
+ }
272
+ }, a = [
273
+ le({ archive: e, resourcePath: n }),
274
+ ee({ archive: e, resourcePath: n }),
275
+ E({ archive: e, resourcePath: n })
276
+ ];
277
+ try {
278
+ const r = await a.reduce(async (o, s) => await s(await o), Promise.resolve(t));
279
+ return h.log("Generated resource", n, r), {
280
+ ...r,
281
+ body: r.body || await i.blob()
282
+ };
283
+ } catch (r) {
284
+ throw h.error(r), r;
285
+ }
286
+ }, $e = (e) => ({
287
+ body: `
288
+ <!DOCTYPE html>
289
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
290
+ <head>
291
+ <meta name="${J}" content="${String(e)}" />
292
+ </head>
293
+ <body>
294
+ <pre>${String(e)}</pre>
295
+ </body>
296
+ </html>
297
+ `,
298
+ params: {
299
+ status: 500,
300
+ headers: {
301
+ "Content-Type": "text/html;charset=UTF-8"
302
+ }
303
+ }
304
+ }), me = ({ archive: e, baseUrl: n }) => async () => {
305
+ var t;
306
+ const i = Object.values(e.files).filter((a) => !a.dir);
307
+ return {
308
+ filename: e.filename,
309
+ title: ((t = e.files.find(({ dir: a }) => a)) == null ? void 0 : t.basename.replace(/\/$/, "")) || "",
310
+ renditionLayout: "pre-paginated",
311
+ renditionSpread: "auto",
312
+ readingDirection: "ltr",
313
+ spineItems: i.map((a, r) => ({
314
+ // some books such as cbz can have same basename inside different sub folder
315
+ // we need to make sure to have unique index
316
+ // /chap01/01.png, /chap02/01.png, etc
317
+ id: `${r}.${a.basename}`,
318
+ href: encodeURI(`${n}${a.uri}`),
319
+ renditionLayout: "pre-paginated",
320
+ progressionWeight: 1 / i.length,
321
+ pageSpreadLeft: void 0,
322
+ pageSpreadRight: void 0,
323
+ mediaType: a.encodingFormat
324
+ })),
325
+ items: i.map((a, r) => ({
326
+ id: `${r}.${a.basename}`,
327
+ href: `${n}${a.uri}`
328
+ }))
329
+ };
330
+ }, pe = ({ archive: e }) => async (n) => {
331
+ var r;
332
+ const i = e.files.find((o) => o.basename.toLowerCase() === "comicinfo.xml");
333
+ if (!i)
334
+ return n;
335
+ const t = {
336
+ ...n,
337
+ spineItems: n.spineItems.filter((o) => o.id.toLowerCase() !== "comicinfo.xml")
338
+ }, a = await i.string();
339
+ try {
340
+ const s = ((r = new g.XmlDocument(a).childNamed("Manga")) == null ? void 0 : r.val) || "unknown";
341
+ return {
342
+ ...t,
343
+ readingDirection: s === "YesAndRightToLeft" ? "rtl" : "ltr"
344
+ };
345
+ } catch (o) {
346
+ return console.error(`Unable to parse comicinfo.xml for content
347
+ `, a), console.error(o), t;
348
+ }
349
+ }, fe = (e) => {
350
+ var i;
351
+ const n = (i = e.descendantWithPath("head")) == null ? void 0 : i.childrenNamed("meta").find((t) => t.attr.name === "viewport");
352
+ return !!(n && n.attr.name === "viewport");
353
+ }, ue = (e) => e.reduce(async (n, i) => {
354
+ if (!await n || !q({
355
+ mimeType: i.encodingFormat,
356
+ uri: i.uri
357
+ }))
358
+ return !1;
359
+ const a = await i.string();
360
+ return a ? fe(new g.XmlDocument(a)) : !1;
361
+ }, Promise.resolve(!0)), he = ({ archive: e }) => async (n) => {
362
+ if (n.renditionLayout === "reflowable" && n.spineItems.every((t) => t.renditionLayout === "reflowable")) {
363
+ const t = await z({ archive: e });
364
+ if (await ue(t))
365
+ return {
366
+ ...n,
367
+ spineItems: n.spineItems.map((r) => ({
368
+ ...r,
369
+ renditionLayout: "pre-paginated"
370
+ })),
371
+ renditionLayout: "pre-paginated"
372
+ };
373
+ }
374
+ return n;
375
+ }, C = (e, n) => {
376
+ var a;
377
+ const i = e.split(/(\d+)/), t = n.split(/(\d+)/);
378
+ for (let r = 0, o = i.length; r < o; r++)
379
+ if (i[r] !== t[r])
380
+ return (a = i[r]) != null && a.match(/\d/) ? +(i[r] || "") - +(t[r] || "") : (i[r] || "").localeCompare(t[r] || "");
381
+ return 1;
382
+ }, ge = ({ archive: e, baseUrl: n }) => async (i) => {
383
+ if (i.nav)
384
+ return i;
385
+ const t = [...e.files].sort((r, o) => C(r.uri, o.uri)), a = Object.values(t).reduce(
386
+ (r, o) => {
387
+ const s = o.uri.split("/");
388
+ return !o.dir && s.length > 1 && s.forEach((p, m) => {
389
+ if (m === s.length - 1)
390
+ return;
391
+ r.find(({ title: w }) => w === p) || r.push({
392
+ contents: [],
393
+ href: v(n, encodeURI(o.uri)).replace(/\/$/, ""),
394
+ path: o.uri.replace(/\/$/, ""),
395
+ title: s[0] ?? ""
396
+ });
397
+ }), r;
398
+ },
399
+ []
400
+ );
401
+ return a.length === 0 ? i : {
402
+ ...i,
403
+ nav: {
404
+ toc: a
405
+ }
406
+ };
407
+ }, ye = {
408
+ filename: "",
409
+ items: [],
410
+ nav: {
411
+ toc: []
412
+ },
413
+ readingDirection: "ltr",
414
+ renditionLayout: "pre-paginated",
415
+ renditionSpread: "auto",
416
+ spineItems: [],
417
+ title: ""
418
+ }, Ne = async (e, { baseUrl: n = "" } = {}) => {
419
+ const i = [
420
+ me({ archive: e, baseUrl: n }),
421
+ se({ archive: e, baseUrl: n }),
422
+ he({ archive: e, baseUrl: n }),
423
+ pe({ archive: e, baseUrl: n }),
424
+ ge({ archive: e, baseUrl: n })
425
+ ];
426
+ try {
427
+ const t = await i.reduce(async (a, r) => await r(await a), Promise.resolve(ye));
428
+ return h.log("Generated manifest", t), t;
429
+ } catch (t) {
430
+ throw h.error(t), t;
431
+ }
432
+ }, y = (e) => e.substring(e.lastIndexOf("/") + 1) || e, Te = async (e, n) => {
433
+ const i = `
434
+ <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
435
+ <metadata>
436
+ <meta property="rendition:layout">${n != null && n.useRenditionFlow ? "reflowable" : "pre-paginated"}</meta>
437
+ ${n != null && n.useRenditionFlow ? '<meta property="rendition:flow">scrolled-continuous</meta>' : ""}
438
+ </metadata>
439
+ <manifest>
440
+ ${e.map((r) => `<item id="${y(r)}" href="${r}" media-type="${O(r)}"/>`).join(`
441
+ `)}
442
+ </manifest>
443
+ <spine>
444
+ ${e.map((r) => `<itemref idref="${y(r)}" />`).join(`
445
+ `)}
446
+ </spine>
447
+ </package>
448
+ `, t = e.map((r) => ({
449
+ dir: !1,
450
+ basename: y(r),
451
+ encodingFormat: O(r),
452
+ uri: r,
453
+ size: 100 / e.length,
454
+ base64: async () => "",
455
+ blob: async () => new Blob(),
456
+ string: async () => ""
457
+ }));
458
+ return {
459
+ filename: "",
460
+ files: [{
461
+ dir: !1,
462
+ basename: "content.opf",
463
+ uri: "content.opf",
464
+ size: 0,
465
+ base64: async () => i,
466
+ blob: async () => new Blob(),
467
+ string: async () => i
468
+ }, ...t]
469
+ };
470
+ }, be = async (e) => new Promise((n) => {
471
+ const i = new FileReader();
472
+ i.readAsDataURL(e), i.onloadend = function() {
473
+ const t = i.result;
474
+ n(t);
475
+ };
476
+ }), Ie = async (e, {
477
+ mimeType: n,
478
+ direction: i
479
+ } = { mimeType: "text/plain" }) => {
480
+ const t = `
481
+ <?xml version="1.0" encoding="UTF-8"?>
482
+ <package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
483
+ unique-identifier="ootuya-id">
484
+ <metadata xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/"
485
+ xmlns:dcterms="http://purl.org/dc/terms/">
486
+ <meta property="rendition:layout">reflowable</meta>
487
+ </metadata>
488
+ <manifest>
489
+ <item id="p01" href="p01.txt" media-type="text/plain"/>
490
+ </manifest>
491
+ <spine page-progression-direction="${i ?? "ltr"}">
492
+ <itemref idref="p01" />
493
+ </spine>
494
+ </package>
495
+ `;
496
+ return {
497
+ filename: "content.txt",
498
+ files: [
499
+ {
500
+ dir: !1,
501
+ basename: y("generated.opf"),
502
+ uri: "generated.opf",
503
+ blob: async () => new Blob([t]),
504
+ string: async () => t,
505
+ base64: async () => btoa(t),
506
+ size: 0
507
+ },
508
+ {
509
+ dir: !1,
510
+ basename: y("p01.txt"),
511
+ uri: "p01.txt",
512
+ blob: async () => typeof e == "string" ? new Blob([e]) : e,
513
+ string: async () => typeof e == "string" ? e : e.text(),
514
+ base64: async () => typeof e == "string" ? btoa(e) : be(e),
515
+ size: typeof e == "string" ? e.length : e.size,
516
+ encodingFormat: n
517
+ }
518
+ ]
519
+ };
520
+ }, Ae = async (e, { orderByAlpha: n, name: i } = {}) => {
521
+ let t = Object.values(e.files);
522
+ n && (t = t.sort((r, o) => C(r.name, o.name)));
523
+ const a = {
524
+ filename: i || "",
525
+ files: t.map((r) => ({
526
+ dir: r.dir,
527
+ basename: y(r.name),
528
+ uri: r.name,
529
+ blob: () => r.async("blob"),
530
+ string: () => r.async("string"),
531
+ base64: () => r.async("base64"),
532
+ ...r.internalStream && {
533
+ stream: r.internalStream
534
+ },
535
+ // this is private API
536
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
537
+ // @ts-ignore
538
+ size: r._data.uncompressedSize
539
+ }))
540
+ };
541
+ return h.log("Generated archive", a), a;
542
+ }, Ce = async (e, { orderByAlpha: n, name: i } = {}) => {
543
+ let t = e;
544
+ return n && (t = t.sort((a, r) => C(a.name, r.name))), {
545
+ filename: i || "",
546
+ files: t.map((a) => ({
547
+ dir: a.isDir,
548
+ basename: y(a.name),
549
+ uri: a.name,
550
+ blob: async () => new Blob([await a.data()]),
551
+ string: async () => {
552
+ const r = await a.data();
553
+ return String.fromCharCode.apply(null, Array.from(new Uint16Array(r)));
554
+ },
555
+ base64: async () => "",
556
+ size: a.size
557
+ }))
558
+ };
559
+ }, ke = ({ enableReport: e } = {}) => {
560
+ h.enable(!!e);
561
+ };
562
+ export {
563
+ ke as configure,
564
+ Ce as createArchiveFromArrayBufferList,
565
+ Ae as createArchiveFromJszip,
566
+ Ie as createArchiveFromText,
567
+ Te as createArchiveFromUrls,
568
+ Ne as generateManifestFromArchive,
569
+ Fe as generateResourceFromArchive,
570
+ $e as generateResourceFromError,
571
+ F as getArchiveOpfInfo
572
+ };
573
+ //# sourceMappingURL=index.js.map