@prose-reader/streamer 1.282.0 → 1.284.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,118 +1,118 @@
1
- import { detectMimeTypeFromName as x, Report as se, isXmlBasedMimeType as ie, parseContentType as ae, urlJoin as T } from "@prose-reader/shared";
2
- import { XmlDocument as y, XmlTextNode as ce, XmlElement as de } from "xmldoc";
3
- import { Subject as R, mergeMap as O, EMPTY as B, pairwise as le, filter as P, startWith as pe, from as W, tap as j, catchError as S, switchMap as I, merge as X, first as V, takeUntil as me, map as $, ignoreElements as ue, BehaviorSubject as fe, distinctUntilChanged as he, shareReplay as ge, NEVER as H, timer as ye, finalize as _, of as G, lastValueFrom as q } from "rxjs";
4
- const D = (n, t) => {
5
- const s = n.split(/(\d+)/), r = t.split(/(\d+)/);
6
- for (let e = 0, o = s.length; e < o; e++)
7
- if (s[e] !== r[e])
8
- return s[e]?.match(/\d/) ? +(s[e] || "") - +(r[e] || "") : (s[e] || "").localeCompare(r[e] || "");
1
+ import { detectMimeTypeFromName as w, Report as se, isXmlBasedMimeType as ie, parseContentType as q, isMediaContentMimeType as oe, urlJoin as N } from "@prose-reader/shared";
2
+ import { XmlDocument as y, XmlTextNode as ae, XmlElement as ce } from "xmldoc";
3
+ import { Subject as W, mergeMap as J, EMPTY as M, pairwise as de, filter as C, startWith as le, from as R, tap as P, catchError as z, switchMap as I, merge as U, first as V, takeUntil as pe, map as x, ignoreElements as ue, BehaviorSubject as me, distinctUntilChanged as fe, shareReplay as he, NEVER as X, timer as ge, finalize as ye, of as be, lastValueFrom as ve } from "rxjs";
4
+ const j = (e, n) => {
5
+ const i = e.split(/(\d+)/), r = n.split(/(\d+)/);
6
+ for (let t = 0, s = i.length; t < s; t++)
7
+ if (i[t] !== r[t])
8
+ return i[t]?.match(/\d/) ? +(i[t] || "") - +(r[t] || "") : (i[t] || "").localeCompare(r[t] || "");
9
9
  return 1;
10
- }, w = (n) => n.substring(n.lastIndexOf("/") + 1) || n, J = (n) => n.endsWith("/") ? n.slice(0, -1) : n, be = (n) => {
11
- const t = n.lastIndexOf("/");
12
- return t >= 0 ? n.substring(0, t) : "";
13
- }, it = async (n, { orderByAlpha: t, name: s } = {}) => {
14
- let r = n;
15
- return t && (r = r.slice().sort((e, o) => D(e.name, o.name))), {
16
- filename: s || "",
17
- records: r.map((e) => {
18
- const o = e.size, i = w(e.name);
19
- return e.isDir ? {
10
+ }, v = (e) => e.substring(e.lastIndexOf("/") + 1) || e, _ = (e) => e.endsWith("/") ? e.slice(0, -1) : e, we = (e) => {
11
+ const n = e.lastIndexOf("/");
12
+ return n >= 0 ? e.substring(0, n) : "";
13
+ }, mt = async (e, { orderByAlpha: n, name: i } = {}) => {
14
+ let r = e;
15
+ return n && (r = r.slice().sort((t, s) => j(t.name, s.name))), {
16
+ filename: i || "",
17
+ records: r.map((t) => {
18
+ const s = t.size, o = v(t.name);
19
+ return t.isDir ? {
20
20
  dir: !0,
21
- basename: i,
22
- uri: e.name,
23
- size: o
21
+ basename: o,
22
+ uri: t.name,
23
+ size: s
24
24
  } : {
25
- dir: e.isDir,
26
- basename: i,
27
- encodingFormat: x(e.name),
28
- uri: e.name,
29
- blob: async () => new Blob([await e.data()], {
30
- type: x(e.name) ?? ""
25
+ dir: t.isDir,
26
+ basename: o,
27
+ encodingFormat: w(t.name),
28
+ uri: t.name,
29
+ blob: async () => new Blob([await t.data()], {
30
+ type: w(t.name) ?? ""
31
31
  }),
32
32
  string: async () => {
33
- const a = await e.data();
33
+ const a = await t.data();
34
34
  return String.fromCharCode.apply(
35
35
  null,
36
36
  Array.from(new Uint16Array(a))
37
37
  );
38
38
  },
39
- size: o
39
+ size: s
40
40
  };
41
41
  }),
42
42
  close: () => Promise.resolve()
43
43
  };
44
- }, we = "@prose-reader/streamer", m = se.namespace(we, !1, {
44
+ }, $e = "@prose-reader/streamer", u = se.namespace($e, !1, {
45
45
  color: "#ffae42"
46
- }), ve = (n) => {
47
- const t = {};
48
- for (const r of n) {
49
- const e = r.split("/");
50
- let o = t;
51
- for (let i = 0; i < e.length; i++) {
52
- const a = e[i];
53
- a !== void 0 && (o[a] || (o[a] = {}), o = o[a]);
46
+ }), xe = (e) => {
47
+ const n = {};
48
+ for (const r of e) {
49
+ const t = r.split("/");
50
+ let s = n;
51
+ for (let o = 0; o < t.length; o++) {
52
+ const a = t[o];
53
+ a !== void 0 && (s[a] || (s[a] = {}), s = s[a]);
54
54
  }
55
55
  }
56
- const s = (r, e = "") => Object.keys(r).sort().map((o, i, a) => {
57
- const l = i === a.length - 1, c = e + (l ? "└── " : "├── "), d = e + (l ? " " : "│ "), p = r[o];
58
- return p && Object.keys(p).length > 0 ? `${c}${o}/
59
- ${s(p, d)}` : `${c}${o}`;
56
+ const i = (r, t = "") => Object.keys(r).sort().map((s, o, a) => {
57
+ const c = o === a.length - 1, d = t + (c ? "└── " : "├── "), l = t + (c ? " " : "│ "), p = r[s];
58
+ return p && Object.keys(p).length > 0 ? `${d}${s}/
59
+ ${i(p, l)}` : `${d}${s}`;
60
60
  }).join(`
61
61
  `);
62
- return s(t);
63
- }, at = async (n, { orderByAlpha: t, name: s } = {}) => {
64
- let r = Object.values(n.files);
65
- t && (r = r.slice().sort((o, i) => D(o.name, i.name)));
66
- const e = {
67
- filename: s || "",
68
- records: r.map((o) => {
69
- const i = o._data.uncompressedSize, a = w(o.name);
70
- return o.dir ? {
62
+ return i(n);
63
+ }, ft = async (e, { orderByAlpha: n, name: i } = {}) => {
64
+ let r = Object.values(e.files);
65
+ n && (r = r.slice().sort((s, o) => j(s.name, o.name)));
66
+ const t = {
67
+ filename: i || "",
68
+ records: r.map((s) => {
69
+ const o = s._data.uncompressedSize, a = v(s.name);
70
+ return s.dir ? {
71
71
  dir: !0,
72
72
  basename: a,
73
- uri: o.name,
74
- size: i
73
+ uri: s.name,
74
+ size: o
75
75
  } : {
76
76
  dir: !1,
77
- basename: w(o.name),
78
- uri: o.name,
79
- encodingFormat: x(o.name),
80
- blob: () => o.async("blob"),
81
- string: () => o.async("string"),
82
- ...o.internalStream && {
83
- stream: o.internalStream
77
+ basename: v(s.name),
78
+ uri: s.name,
79
+ encodingFormat: w(s.name),
80
+ blob: () => s.async("blob"),
81
+ string: () => s.async("string"),
82
+ ...s.internalStream && {
83
+ stream: s.internalStream
84
84
  },
85
85
  // this is private API
86
86
  // @ts-expect-error
87
- size: o._data.uncompressedSize
87
+ size: s._data.uncompressedSize
88
88
  };
89
89
  }),
90
90
  close: () => Promise.resolve()
91
91
  };
92
- if (m.log("Generated archive", e), process.env.NODE_ENV === "development" && m.isEnabled()) {
93
- const o = ve(r.map((i) => i.name));
94
- m.groupCollapsed(...m.getGroupArgs("Archive folder structure")), m.log(`
95
- ${o}`), m.groupEnd();
92
+ if (u.log("Generated archive", t), process.env.NODE_ENV === "development" && u.isEnabled()) {
93
+ const s = xe(r.map((o) => o.name));
94
+ u.groupCollapsed(...u.getGroupArgs("Archive folder structure")), u.log(`
95
+ ${s}`), u.groupEnd();
96
96
  }
97
- return e;
98
- }, ct = async (n, { name: t } = {}) => {
99
- const s = await n.getFilesArray(), r = {
100
- close: () => n.close(),
101
- filename: t ?? "",
102
- records: s.map((e) => ({
97
+ return t;
98
+ }, ht = async (e, { name: n } = {}) => {
99
+ const i = await e.getFilesArray(), r = {
100
+ close: () => e.close(),
101
+ filename: n ?? "",
102
+ records: i.map((t) => ({
103
103
  dir: !1,
104
- basename: e.file.name,
105
- encodingFormat: x(e.file.name),
106
- size: e.file.size,
107
- uri: `${e.path}${e.file.name}`,
108
- blob: async () => await e.file.extract(),
109
- string: async () => (await e.file.extract()).text()
104
+ basename: t.file.name,
105
+ encodingFormat: w(t.file.name),
106
+ size: t.file.size,
107
+ uri: `${t.path}${t.file.name}`,
108
+ blob: async () => await t.file.extract(),
109
+ string: async () => (await t.file.extract()).text()
110
110
  }))
111
111
  };
112
- return m.log("Generated archive", r), r;
113
- }, dt = async (n, {
114
- mimeType: t,
115
- direction: s
112
+ return u.log("Generated archive", r), r;
113
+ }, gt = async (e, {
114
+ mimeType: n,
115
+ direction: i
116
116
  } = { mimeType: "text/plain" }) => {
117
117
  const r = `
118
118
  <?xml version="1.0" encoding="UTF-8"?>
@@ -125,7 +125,7 @@ ${o}`), m.groupEnd();
125
125
  <manifest>
126
126
  <item id="p01" href="p01.txt" media-type="text/plain"/>
127
127
  </manifest>
128
- <spine page-progression-direction="${s ?? "ltr"}">
128
+ <spine page-progression-direction="${i ?? "ltr"}">
129
129
  <itemref idref="p01" />
130
130
  </spine>
131
131
  </package>
@@ -135,7 +135,7 @@ ${o}`), m.groupEnd();
135
135
  records: [
136
136
  {
137
137
  dir: !1,
138
- basename: w("generated.opf"),
138
+ basename: v("generated.opf"),
139
139
  uri: "generated.opf",
140
140
  blob: async () => new Blob([r]),
141
141
  string: async () => r,
@@ -143,41 +143,41 @@ ${o}`), m.groupEnd();
143
143
  },
144
144
  {
145
145
  dir: !1,
146
- basename: w("p01.txt"),
146
+ basename: v("p01.txt"),
147
147
  uri: "p01.txt",
148
- blob: async () => typeof n == "string" ? new Blob([n]) : n,
149
- string: async () => typeof n == "string" ? n : n.text(),
150
- size: typeof n == "string" ? n.length : n.size,
151
- encodingFormat: t
148
+ blob: async () => typeof e == "string" ? new Blob([e]) : e,
149
+ string: async () => typeof e == "string" ? e : e.text(),
150
+ size: typeof e == "string" ? e.length : e.size,
151
+ encodingFormat: n
152
152
  }
153
153
  ],
154
154
  close: () => Promise.resolve()
155
155
  };
156
- }, lt = async (n, t) => {
157
- const s = `
156
+ }, yt = async (e, n) => {
157
+ const i = `
158
158
  <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
159
159
  <metadata>
160
- <meta property="rendition:layout">${t?.useRenditionFlow ? "reflowable" : "pre-paginated"}</meta>
161
- ${t?.useRenditionFlow ? '<meta property="rendition:flow">scrolled-continuous</meta>' : ""}
160
+ <meta property="rendition:layout">${n?.useRenditionFlow ? "reflowable" : "pre-paginated"}</meta>
161
+ ${n?.useRenditionFlow ? '<meta property="rendition:flow">scrolled-continuous</meta>' : ""}
162
162
  </metadata>
163
163
  <manifest>
164
- ${n.map(
165
- (o) => `<item id="${w(o)}" href="${o}" media-type="${x(o)}"/>`
164
+ ${e.map(
165
+ (s) => `<item id="${v(s)}" href="${s}" media-type="${w(s)}"/>`
166
166
  ).join(`
167
167
  `)}
168
168
  </manifest>
169
169
  <spine>
170
- ${n.map((o) => `<itemref idref="${w(o)}" />`).join(`
170
+ ${e.map((s) => `<itemref idref="${v(s)}" />`).join(`
171
171
  `)}
172
172
  </spine>
173
173
  </package>
174
- `, r = n.map((o) => ({
174
+ `, r = e.map((s) => ({
175
175
  dir: !1,
176
- basename: w(o),
177
- encodingFormat: x(o),
178
- uri: o,
179
- size: 100 / n.length,
180
- blob: async () => (await fetch(o)).blob(),
176
+ basename: v(s),
177
+ encodingFormat: w(s),
178
+ uri: s,
179
+ size: 100 / e.length,
180
+ blob: async () => (await fetch(s)).blob(),
181
181
  string: async () => ""
182
182
  }));
183
183
  return {
@@ -188,487 +188,502 @@ ${o}`), m.groupEnd();
188
188
  uri: "content.opf",
189
189
  size: 0,
190
190
  blob: async () => new Blob(),
191
- string: async () => s
191
+ string: async () => i
192
192
  }, ...r],
193
193
  close: () => Promise.resolve()
194
194
  };
195
- }, pt = ({
196
- enableReport: n
195
+ }, bt = ({
196
+ enableReport: e
197
197
  } = {}) => {
198
- m.enable(!!n);
199
- }, E = (n) => {
200
- const s = Object.values(n.records).filter(
198
+ u.enable(!!e);
199
+ }, A = (e) => {
200
+ const i = Object.values(e.records).filter(
201
201
  (r) => !r.dir
202
202
  ).find((r) => r.uri.endsWith(".opf"));
203
203
  return {
204
- data: s,
205
- basePath: s?.uri.substring(0, s.uri.lastIndexOf("/")) || ""
204
+ data: i,
205
+ basePath: i?.uri.substring(0, i.uri.lastIndexOf("/")) || ""
206
206
  };
207
- }, $e = ({ archive: n }) => async (t) => {
208
- const s = n.records.find(
209
- (e) => e.basename.toLowerCase() === "com.apple.ibooks.display-options.xml"
207
+ }, Fe = ({ archive: e }) => async (n) => {
208
+ const i = e.records.find(
209
+ (t) => t.basename.toLowerCase() === "com.apple.ibooks.display-options.xml"
210
210
  );
211
- if (!s || s.dir)
212
- return t;
213
- const r = await (await s.blob()).text();
211
+ if (!i || i.dir)
212
+ return n;
213
+ const r = await (await i.blob()).text();
214
214
  try {
215
- const i = new y(r).childNamed("platform")?.childrenNamed("option")?.find((a) => a.attr.name === "fixed-layout")?.val || "false";
215
+ const o = new y(r).childNamed("platform")?.childrenNamed("option")?.find((a) => a.attr.name === "fixed-layout")?.val || "false";
216
216
  return {
217
- ...t,
218
- renditionLayout: i === "true" ? "pre-paginated" : t.renditionLayout
217
+ ...n,
218
+ renditionLayout: o === "true" ? "pre-paginated" : n.renditionLayout
219
219
  };
220
- } catch (e) {
220
+ } catch (t) {
221
221
  return console.error(
222
222
  `Unable to parse com.apple.ibooks.display-options.xml for content
223
223
  `,
224
224
  r
225
- ), console.error(e), t;
225
+ ), console.error(t), n;
226
226
  }
227
- }, xe = async (n) => {
228
- const t = {
227
+ }, Ae = async (e) => {
228
+ const n = {
229
229
  renditionLayout: void 0
230
230
  };
231
231
  return await Promise.all(
232
- n.records.map(async (s) => {
233
- if (s.uri.endsWith("com.kobobooks.display-options.xml") && !s.dir) {
234
- const e = new y(await s.string()).childNamed("platform")?.childNamed("option");
235
- e?.attr?.name === "fixed-layout" && e.val === "true" && (t.renditionLayout = "pre-paginated");
232
+ e.records.map(async (i) => {
233
+ if (i.uri.endsWith("com.kobobooks.display-options.xml") && !i.dir) {
234
+ const t = new y(await i.string()).childNamed("platform")?.childNamed("option");
235
+ t?.attr?.name === "fixed-layout" && t.val === "true" && (n.renditionLayout = "pre-paginated");
236
236
  }
237
237
  })
238
- ), t;
239
- }, Fe = ({ archive: n }) => async (t) => {
240
- const s = await xe(n);
238
+ ), n;
239
+ }, Te = ({ archive: e }) => async (n) => {
240
+ const i = await Ae(e);
241
241
  return {
242
- ...t,
243
- renditionLayout: t.renditionLayout ?? s.renditionLayout
242
+ ...n,
243
+ renditionLayout: n.renditionLayout ?? i.renditionLayout
244
244
  };
245
- }, Ee = ({ archive: n, baseUrl: t }) => async () => {
246
- const s = Object.values(n.records).filter((r) => !r.dir);
245
+ }, Ee = ({ archive: e, baseUrl: n }) => async () => {
246
+ const i = Object.values(e.records).filter((r) => !r.dir);
247
247
  return {
248
- filename: n.filename,
249
- title: n.records.find(({ dir: r }) => r)?.basename.replace(/\/$/, "") || n.filename,
248
+ filename: e.filename,
249
+ title: e.records.find(({ dir: r }) => r)?.basename.replace(/\/$/, "") || e.filename,
250
250
  renditionLayout: void 0,
251
251
  renditionSpread: "auto",
252
252
  readingDirection: "ltr",
253
- spineItems: s.filter((r) => !r.basename.endsWith(".db")).map((r, e) => {
254
- const o = t || (/^https?:\/\//.test(r.uri) ? "" : "file://");
253
+ spineItems: i.filter((r) => !r.basename.endsWith(".db")).map((r, t) => {
254
+ const s = n || (/^https?:\/\//.test(r.uri) ? "" : "file://");
255
255
  return {
256
256
  // some books such as cbz can have same basename inside different sub folder
257
257
  // we need to make sure to have unique index
258
258
  // /chap01/01.png, /chap02/01.png, etc
259
- id: `${e}.${r.basename}`,
260
- index: e,
261
- href: encodeURI(`${o}${r.uri}`),
259
+ id: `${t}.${r.basename}`,
260
+ index: t,
261
+ href: encodeURI(`${s}${r.uri}`),
262
262
  renditionLayout: void 0,
263
- progressionWeight: 1 / s.length,
263
+ progressionWeight: 1 / i.length,
264
264
  pageSpreadLeft: void 0,
265
265
  pageSpreadRight: void 0,
266
266
  mediaType: r.encodingFormat
267
267
  };
268
268
  }),
269
- items: s.map((r, e) => ({
270
- id: `${e}.${r.basename}`,
271
- href: encodeURI(`${t}${r.uri}`)
269
+ items: i.map((r, t) => ({
270
+ id: `${t}.${r.basename}`,
271
+ href: encodeURI(`${n}${r.uri}`)
272
272
  }))
273
273
  };
274
- }, Y = async ({
275
- archive: n
274
+ }, K = async ({
275
+ archive: e
276
276
  }) => {
277
- const { data: t, basePath: s } = E(n) || {}, r = await t?.string();
277
+ const { data: n, basePath: i } = A(e) || {}, r = await n?.string();
278
278
  if (!r) return [];
279
- const e = new y(r), o = e.childNamed("manifest"), a = e.childNamed("spine")?.childrenNamed("itemref").map((d) => d.attr.idref), l = o?.childrenNamed("item").filter((d) => a.includes(d.attr.id || "")) || [];
280
- return n.records.filter((d) => l.find((p) => s ? `${s}/${p.attr.href}` === d.uri : `${p.attr.href}` === d.uri));
281
- }, Ne = (n) => {
282
- const t = n.attr.properties?.split(" ") || [];
283
- let s;
284
- return t.find((r) => r === "rendition:layout-reflowable") && (s = "reflowable"), t.find((r) => r === "rendition:layout-pre-paginated") && (s = "pre-paginated"), {
285
- renditionLayout: s,
286
- pageSpreadLeft: t.some((r) => r === "page-spread-left") || void 0,
287
- pageSpreadRight: t.some((r) => r === "page-spread-right") || void 0
279
+ const t = new y(r), s = t.childNamed("manifest"), a = t.childNamed("spine")?.childrenNamed("itemref").map((l) => l.attr.idref), c = s?.childrenNamed("item").filter((l) => a.includes(l.attr.id || "")) || [];
280
+ return e.records.filter((l) => c.find((p) => i ? `${i}/${p.attr.href}` === l.uri : `${p.attr.href}` === l.uri));
281
+ }, Re = (e) => {
282
+ const n = e.attr.properties?.split(" ") || [];
283
+ let i;
284
+ return n.find((r) => r === "rendition:layout-reflowable") && (i = "reflowable"), n.find((r) => r === "rendition:layout-pre-paginated") && (i = "pre-paginated"), {
285
+ renditionLayout: i,
286
+ pageSpreadLeft: n.some((r) => r === "page-spread-left") || void 0,
287
+ pageSpreadRight: n.some((r) => r === "page-spread-right") || void 0
288
288
  };
289
- }, Ae = (n, t, s) => {
290
- const r = n.attr.href || "", e = s?.(n);
289
+ }, Ie = (e, n, i) => {
290
+ const r = e.attr.href || "", t = i?.(e);
291
291
  return {
292
- href: t ? `${e}${t}/${r}` : `${e}${r}`,
293
- id: n.attr.id || "",
294
- mediaType: n.attr["media-type"]
292
+ href: n ? `${t}${n}/${r}` : `${t}${r}`,
293
+ id: e.attr.id || "",
294
+ mediaType: e.attr["media-type"]
295
295
  };
296
- }, Q = (n, t, s) => {
297
- const r = n.childNamed("manifest"), { basePath: e } = E(t) || {};
298
- return r?.childrenNamed("item")?.map((o) => Ae(o, e, s)) || [];
299
- }, Ie = ({ archive: n, baseUrl: t }) => async (s) => {
300
- const { data: r, basePath: e } = E(n) || {};
296
+ }, Y = (e, n, i) => {
297
+ const r = e.childNamed("manifest"), { basePath: t } = A(n) || {};
298
+ return r?.childrenNamed("item")?.map((s) => Ie(s, t, i)) || [];
299
+ }, Ne = ({ archive: e, baseUrl: n }) => async (i) => {
300
+ const { data: r, basePath: t } = A(e) || {};
301
301
  if (!r)
302
- return s;
303
- const o = await r.string();
304
- m.groupCollapsed(...m.getGroupArgs("OPF data")), m.log("data", o), m.groupEnd();
305
- const i = new y(o), a = i.childNamed("metadata"), l = i.childNamed("manifest"), c = i.childNamed("spine"), d = i.childNamed("guide"), p = a?.childNamed("dc:title"), g = a?.childrenNamed("meta") || [], b = g.find(
306
- (u) => u.attr.property === "rendition:layout"
307
- ), N = g.find(
308
- (u) => u.attr.property === "rendition:flow"
302
+ return i;
303
+ const s = await r.string();
304
+ u.groupCollapsed(...u.getGroupArgs("OPF data")), u.log("data", s), u.groupEnd();
305
+ const o = new y(s), a = o.childNamed("metadata"), c = o.childNamed("manifest"), d = o.childNamed("spine"), l = o.childNamed("guide"), p = a?.childNamed("dc:title"), g = a?.childrenNamed("meta") || [], b = g.find(
306
+ (m) => m.attr.property === "rendition:layout"
307
+ ), T = g.find(
308
+ (m) => m.attr.property === "rendition:flow"
309
309
  ), f = g.find(
310
- (u) => u.attr.property === "rendition:spread"
311
- ), L = b?.val, h = N?.val, F = f?.val, k = p?.val || n.records.find(({ dir: u }) => u)?.basename || "", ne = c?.attr["page-progression-direction"], re = (await Y({ archive: n })).reduce(
312
- (u, A) => A.size + u,
310
+ (m) => m.attr.property === "rendition:spread"
311
+ ), S = b?.val, h = T?.val, F = f?.val, L = p?.val || e.records.find(({ dir: m }) => m)?.basename || "", te = d?.attr["page-progression-direction"], ne = (await K({ archive: e })).reduce(
312
+ (m, E) => E.size + m,
313
313
  0
314
314
  );
315
315
  return {
316
- filename: n.filename,
317
- renditionLayout: L,
316
+ filename: e.filename,
317
+ renditionLayout: S,
318
318
  renditionFlow: h || "auto",
319
319
  renditionSpread: F,
320
- title: k,
321
- readingDirection: ne || "ltr",
320
+ title: L,
321
+ readingDirection: te || "ltr",
322
322
  /**
323
323
  * @see https://www.w3.org/TR/epub/#sec-itemref-elem
324
324
  */
325
- spineItems: c?.childrenNamed("itemref").map((u, A) => {
326
- const v = l?.childrenNamed("item").find((C) => C.attr.id === u?.attr.idref), z = v?.attr.href || "", oe = n.records.find((C) => C.uri.endsWith(z))?.size || 0, M = t || (/^https?:\/\//.test(z) ? "" : "file://"), U = Ne(u);
325
+ spineItems: d?.childrenNamed("itemref").map((m, E) => {
326
+ const $ = c?.childrenNamed("item").find((k) => k.attr.id === m?.attr.idref), O = $?.attr.href || "", re = e.records.find((k) => k.uri.endsWith(O))?.size || 0, B = n || (/^https?:\/\//.test(O) ? "" : "file://"), D = Re(m);
327
327
  return {
328
- ...U,
329
- id: v?.attr.id || "",
330
- index: A,
331
- href: v?.attr.href?.startsWith("https://") ? v?.attr.href : e ? `${M}${e}/${v?.attr.href}` : `${M}${v?.attr.href}`,
332
- renditionLayout: U.renditionLayout ?? L,
333
- progressionWeight: oe / re,
328
+ ...D,
329
+ id: $?.attr.id || "",
330
+ index: E,
331
+ href: $?.attr.href?.startsWith("https://") ? $?.attr.href : t ? `${B}${t}/${$?.attr.href}` : `${B}${$?.attr.href}`,
332
+ renditionLayout: D.renditionLayout ?? S,
333
+ progressionWeight: re / ne,
334
334
  // size: itemSize
335
- mediaType: v?.attr["media-type"]
335
+ mediaType: $?.attr["media-type"]
336
336
  };
337
337
  }) || [],
338
- items: Q(i, n, (u) => {
339
- const A = u.attr.href || "";
340
- return /^https?:\/\//.test(A) ? "" : t || "file://";
338
+ items: Y(o, e, (m) => {
339
+ const E = m.attr.href || "";
340
+ return /^https?:\/\//.test(E) ? "" : n || "file://";
341
341
  }),
342
- guide: d?.childrenNamed("reference").map((u) => ({
343
- href: u.attr.href || "",
344
- title: u.attr.title || "",
345
- type: u.attr.type
342
+ guide: l?.childrenNamed("reference").map((m) => ({
343
+ href: m.attr.href || "",
344
+ title: m.attr.title || "",
345
+ type: m.attr.type
346
346
  }))
347
347
  };
348
- }, Te = (n) => {
349
- const t = n.descendantWithPath("head")?.childrenNamed("meta").find((s) => s.attr.name === "viewport");
350
- return !!(t && t.attr.name === "viewport");
351
- }, We = (n) => n.reduce(async (t, s) => {
352
- if (!await t || !ie({
353
- mimeType: s.encodingFormat,
354
- uri: s.uri
348
+ }, Se = (e) => {
349
+ const n = e.descendantWithPath("head")?.childrenNamed("meta").find((i) => i.attr.name === "viewport");
350
+ return !!(n && n.attr.name === "viewport");
351
+ }, Le = (e) => e.reduce(async (n, i) => {
352
+ if (!await n || !ie({
353
+ mimeType: i.encodingFormat,
354
+ uri: i.uri
355
355
  }))
356
356
  return !1;
357
- const e = s.dir ? null : await s.string();
358
- return e ? Te(new y(e)) : !1;
359
- }, Promise.resolve(!0)), Se = ({ archive: n }) => async (t) => {
360
- if (t.renditionLayout === "reflowable" && t.spineItems.every((r) => r.renditionLayout === "reflowable")) {
361
- const r = await Y({ archive: n });
362
- if (await We(r))
357
+ const t = i.dir ? null : await i.string();
358
+ return t ? Se(new y(t)) : !1;
359
+ }, Promise.resolve(!0)), ke = ({ archive: e }) => async (n) => {
360
+ if (n.renditionLayout === "reflowable" && n.spineItems.every((r) => r.renditionLayout === "reflowable")) {
361
+ const r = await K({ archive: e });
362
+ if (await Le(r))
363
363
  return {
364
- ...t,
365
- spineItems: t.spineItems.map((o) => ({
366
- ...o,
364
+ ...n,
365
+ spineItems: n.spineItems.map((s) => ({
366
+ ...s,
367
367
  renditionLayout: "pre-paginated"
368
368
  })),
369
369
  renditionLayout: "pre-paginated"
370
370
  };
371
371
  }
372
- return t;
373
- }, Le = ({ archive: n }) => async (t) => {
374
- const s = n.records.find(
375
- (o) => o.basename.toLowerCase() === "comicinfo.xml" && !o.dir
372
+ return n;
373
+ }, We = ({ archive: e }) => async (n) => {
374
+ const i = e.records.find(
375
+ (s) => s.basename.toLowerCase() === "comicinfo.xml" && !s.dir
376
376
  );
377
- if (!s || s.dir)
378
- return t;
377
+ if (!i || i.dir)
378
+ return n;
379
379
  const r = {
380
- ...t,
381
- spineItems: t.spineItems.filter((o) => !o.id.toLowerCase().endsWith("comicinfo.xml")).map((o, i, a) => ({
382
- ...o,
380
+ ...n,
381
+ spineItems: n.spineItems.filter((s) => !s.id.toLowerCase().endsWith("comicinfo.xml")).map((s, o, a) => ({
382
+ ...s,
383
383
  progressionWeight: 1 / a.length
384
384
  }))
385
- }, e = await s.string();
385
+ }, t = await i.string();
386
386
  try {
387
- const i = new y(e).childNamed("Manga")?.val || "unknown";
387
+ const o = new y(t).childNamed("Manga")?.val || "unknown";
388
388
  return {
389
389
  ...r,
390
- readingDirection: i === "YesAndRightToLeft" ? "rtl" : "ltr"
390
+ readingDirection: o === "YesAndRightToLeft" ? "rtl" : "ltr"
391
391
  };
392
- } catch (o) {
392
+ } catch (s) {
393
393
  return console.error(`Unable to parse comicinfo.xml for content
394
- `, e), console.error(o), r;
394
+ `, t), console.error(s), r;
395
395
  }
396
- }, ke = (n) => n.records.some((t) => t.basename.endsWith(".opf")), Ce = ({ archive: n }) => async (t) => ke(n) ? t : {
397
- ...t,
398
- spineItems: t.spineItems.map((r) => {
399
- const e = n.records.find(
400
- (i) => decodeURI(r.href).endsWith(i.uri)
401
- ), o = ae(e?.encodingFormat ?? "") || x(e?.basename ?? "");
396
+ }, Ce = (e) => e.records.some((n) => n.basename.endsWith(".opf")), Pe = ({ archive: e }) => async (n) => Ce(e) ? n : {
397
+ ...n,
398
+ spineItems: n.spineItems.map((r) => {
399
+ const t = e.records.find(
400
+ (o) => decodeURI(r.href).endsWith(o.uri)
401
+ ), s = q(t?.encodingFormat ?? "") || w(t?.basename ?? "");
402
402
  return {
403
403
  ...r,
404
- renditionLayout: o?.startsWith("image/") ? "pre-paginated" : r.renditionLayout
404
+ renditionLayout: s && oe(s) ? "pre-paginated" : r.renditionLayout
405
405
  };
406
406
  })
407
- }, Z = (n) => n ? n.children.map((t) => t instanceof ce ? t.text : t instanceof de ? Z(t) : "").join("").trim() : "", ee = (n, { basePath: t, baseUrl: s }) => {
407
+ }, Q = (e) => e ? e.children.map((n) => n instanceof ae ? n.text : n instanceof ce ? Q(n) : "").join("").trim() : "", Z = (e, { basePath: n, baseUrl: i }) => {
408
408
  const r = {
409
409
  contents: [],
410
410
  path: "",
411
411
  href: "",
412
412
  title: ""
413
413
  };
414
- let e = n.childNamed("span") || n.childNamed("a");
415
- r.title = (e?.attr.title || e?.val.trim() || Z(e)) ?? "";
416
- let o = e?.name;
417
- o !== "a" && (e = n.descendantWithPath(`${o}.a`), e && (o = e.name.toLowerCase())), o === "a" && e?.attr.href && (r.path = T(t, e.attr.href), r.href = T(s, t, e.attr.href));
418
- const i = n.childNamed("ol");
419
- if (i) {
420
- const a = i.childrenNamed("li");
414
+ let t = e.childNamed("span") || e.childNamed("a");
415
+ r.title = (t?.attr.title || t?.val.trim() || Q(t)) ?? "";
416
+ let s = t?.name;
417
+ s !== "a" && (t = e.descendantWithPath(`${s}.a`), t && (s = t.name.toLowerCase())), s === "a" && t?.attr.href && (r.path = N(n, t.attr.href), r.href = N(i, n, t.attr.href));
418
+ const o = e.childNamed("ol");
419
+ if (o) {
420
+ const a = o.childrenNamed("li");
421
421
  a && a.length > 0 && (r.contents = a.map(
422
- (l) => ee(l, { basePath: t, baseUrl: s })
422
+ (c) => Z(c, { basePath: n, baseUrl: i })
423
423
  ));
424
424
  }
425
425
  return r;
426
- }, Re = (n, { basePath: t, baseUrl: s }) => {
426
+ }, ze = (e, { basePath: n, baseUrl: i }) => {
427
427
  const r = [];
428
- let e;
429
- return n.descendantWithPath("body.nav.ol") ? e = n.descendantWithPath("body.nav.ol")?.children : n.descendantWithPath("body.section.nav.ol") && (e = n.descendantWithPath("body.section.nav.ol")?.children), e && e.length > 0 && e.filter((o) => o.name === "li").forEach((o) => {
430
- r.push(ee(o, { basePath: t, baseUrl: s }));
428
+ let t;
429
+ return e.descendantWithPath("body.nav.ol") ? t = e.descendantWithPath("body.nav.ol")?.children : e.descendantWithPath("body.section.nav.ol") && (t = e.descendantWithPath("body.section.nav.ol")?.children), t && t.length > 0 && t.filter((s) => s.name === "li").forEach((s) => {
430
+ r.push(Z(s, { basePath: n, baseUrl: i }));
431
431
  }), r;
432
- }, Pe = async (n, t, { baseUrl: s }) => {
433
- const r = n.childNamed("manifest")?.childrenNamed("item").find((e) => e.attr.properties === "nav");
432
+ }, je = async (e, n, { baseUrl: i }) => {
433
+ const r = e.childNamed("manifest")?.childrenNamed("item").find((t) => t.attr.properties === "nav");
434
434
  if (r) {
435
- const e = Object.values(t.records).find(
436
- (o) => o.uri.endsWith(r.attr.href || "")
435
+ const t = Object.values(n.records).find(
436
+ (s) => s.uri.endsWith(r.attr.href || "")
437
437
  );
438
- if (e && !e.dir) {
439
- const o = new y(await e.string()), i = be(e.uri);
440
- return Re(o, { basePath: i, baseUrl: s });
438
+ if (t && !t.dir) {
439
+ const s = new y(await t.string()), o = we(t.uri);
440
+ return ze(s, { basePath: o, baseUrl: i });
441
441
  }
442
442
  }
443
- }, te = (n, {
444
- opfBasePath: t,
445
- baseUrl: s,
443
+ }, ee = (e, {
444
+ opfBasePath: n,
445
+ baseUrl: i,
446
446
  prefix: r
447
447
  }) => {
448
- const e = n?.childNamed(`${r}content`)?.attr.src || "", o = {
449
- title: n?.descendantWithPath(`${r}navLabel.${r}text`)?.val || "",
450
- path: T(t, e),
451
- href: T(s, t, e),
448
+ const t = e?.childNamed(`${r}content`)?.attr.src || "", s = {
449
+ title: e?.descendantWithPath(`${r}navLabel.${r}text`)?.val || "",
450
+ path: N(n, t),
451
+ href: N(i, n, t),
452
452
  contents: []
453
- }, i = n.childrenNamed(`${r}navPoint`);
454
- return i && i.length > 0 && (o.contents = i.map(
455
- (a) => te(a, { opfBasePath: t, baseUrl: s, prefix: r })
456
- )), o;
457
- }, je = (n, { opfBasePath: t, baseUrl: s }) => {
458
- const r = [], e = n.name;
459
- let o = "";
460
- return e.indexOf(":") !== -1 && (o = `${e.split(":")[0]}:`), n.childNamed(`${o}navMap`)?.childrenNamed(`${o}navPoint`).forEach((i) => {
461
- r.push(te(i, { opfBasePath: t, baseUrl: s, prefix: o }));
453
+ }, o = e.childrenNamed(`${r}navPoint`);
454
+ return o && o.length > 0 && (s.contents = o.map(
455
+ (a) => ee(a, { opfBasePath: n, baseUrl: i, prefix: r })
456
+ )), s;
457
+ }, Oe = (e, { opfBasePath: n, baseUrl: i }) => {
458
+ const r = [], t = e.name;
459
+ let s = "";
460
+ return t.indexOf(":") !== -1 && (s = `${t.split(":")[0]}:`), e.childNamed(`${s}navMap`)?.childrenNamed(`${s}navPoint`).forEach((o) => {
461
+ r.push(ee(o, { opfBasePath: n, baseUrl: i, prefix: s }));
462
462
  }), r;
463
- }, Oe = async ({
464
- opfData: n,
465
- opfBasePath: t,
466
- baseUrl: s,
463
+ }, Be = async ({
464
+ opfData: e,
465
+ opfBasePath: n,
466
+ baseUrl: i,
467
467
  archive: r
468
468
  }) => {
469
- const o = n.childNamed("spine")?.attr.toc;
470
- if (o) {
471
- const i = n.childNamed("manifest")?.childrenNamed("item").find((a) => a.attr.id === o);
472
- if (i) {
473
- const a = `${t}${t === "" ? "" : "/"}${i.attr.href}`, l = Object.values(r.records).find(
474
- (c) => c.uri.endsWith(a)
469
+ const s = e.childNamed("spine")?.attr.toc;
470
+ if (s) {
471
+ const o = e.childNamed("manifest")?.childrenNamed("item").find((a) => a.attr.id === s);
472
+ if (o) {
473
+ const a = `${n}${n === "" ? "" : "/"}${o.attr.href}`, c = Object.values(r.records).find(
474
+ (d) => d.uri.endsWith(a)
475
475
  );
476
- if (l && !l.dir) {
477
- const c = new y(await l.string());
478
- return je(c, { opfBasePath: t, baseUrl: s });
476
+ if (c && !c.dir) {
477
+ const d = new y(await c.string());
478
+ return Oe(d, { opfBasePath: n, baseUrl: i });
479
479
  }
480
480
  }
481
481
  }
482
- }, De = async (n, t, { baseUrl: s }) => {
483
- const { basePath: r } = E(t) || {}, e = await Pe(n, t, {
484
- baseUrl: s
482
+ }, De = async (e, n, { baseUrl: i }) => {
483
+ const { basePath: r } = A(n) || {}, t = await je(e, n, {
484
+ baseUrl: i
485
485
  });
486
- if (e)
487
- return e;
488
- const o = await Oe({
489
- opfData: n,
486
+ if (t)
487
+ return t;
488
+ const s = await Be({
489
+ opfData: e,
490
490
  opfBasePath: r,
491
- archive: t,
492
- baseUrl: s
491
+ archive: n,
492
+ baseUrl: i
493
493
  });
494
- if (o)
495
- return o;
496
- }, ze = (n, { baseUrl: t }) => {
497
- const s = [...n.records].sort(
498
- (e, o) => D(e.uri, o.uri)
499
- ), r = (e, o, i, a, l) => {
500
- const c = e.find((g) => g.title === o), [d, ...p] = i;
501
- return c ? d ? [
502
- ...e.filter((b) => b !== c),
494
+ if (s)
495
+ return s;
496
+ }, Me = (e) => e.replace(/\.[^.]+$/, "").replace(/[_-]/g, " ").replace(/\s+/g, " ").trim(), Ue = (e, n) => {
497
+ if (!(e.spineItems.length === 0 || !e.spineItems.every((r) => (q(r.mediaType ?? "") || w(r.href))?.startsWith("audio/"))))
498
+ return e.spineItems.map((r) => {
499
+ const t = n.records.find(
500
+ (s) => !s.dir && decodeURI(r.href).endsWith(s.uri)
501
+ );
502
+ return {
503
+ title: Me(t?.basename ?? r.href),
504
+ href: r.href,
505
+ path: t?.uri ?? r.href,
506
+ contents: []
507
+ };
508
+ });
509
+ }, Ve = (e, { baseUrl: n }) => {
510
+ const i = [...e.records].sort(
511
+ (t, s) => j(t.uri, s.uri)
512
+ ), r = (t, s, o, a, c) => {
513
+ const d = t.find((g) => g.title === s), [l, ...p] = o;
514
+ return d ? l ? [
515
+ ...t.filter((b) => b !== d),
503
516
  {
504
- ...c,
517
+ ...d,
505
518
  contents: [
506
- ...c.contents,
519
+ ...d.contents,
507
520
  ...r(
508
- c.contents,
509
- d,
521
+ d.contents,
522
+ l,
510
523
  p,
511
524
  a,
512
- l
525
+ c
513
526
  )
514
527
  ]
515
528
  }
516
- ] : c.path.split("/").length > l.split("/").length ? [
517
- ...e.filter((b) => b !== c),
529
+ ] : d.path.split("/").length > c.split("/").length ? [
530
+ ...t.filter((b) => b !== d),
518
531
  {
519
- ...c,
520
- path: l,
532
+ ...d,
533
+ path: c,
521
534
  href: a
522
535
  }
523
- ] : e : d ? [
524
- ...e,
536
+ ] : t : l ? [
537
+ ...t,
525
538
  {
526
539
  contents: r(
527
540
  [],
528
- d,
541
+ l,
529
542
  p,
530
543
  a,
531
- l
544
+ c
532
545
  ),
533
546
  href: a,
534
- path: l,
535
- title: o
547
+ path: c,
548
+ title: s
536
549
  }
537
550
  ] : [
538
- ...e,
551
+ ...t,
539
552
  {
540
553
  contents: [],
541
554
  href: a,
542
- path: l,
543
- title: o
555
+ path: c,
556
+ title: s
544
557
  }
545
558
  ];
546
559
  };
547
- return s.reduce((e, o) => {
548
- if (o.dir) return e;
549
- const i = o.uri.split("/").slice(0, -1), [a, ...l] = i;
550
- if (!a) return e;
551
- const c = T(t, encodeURI(o.uri)).replace(/\/$/, ""), d = o.uri.replace(/\/$/, "");
552
- return r(e, a, l, c, d);
560
+ return i.reduce((t, s) => {
561
+ if (s.dir) return t;
562
+ const o = s.uri.split("/").slice(0, -1), [a, ...c] = o;
563
+ if (!a) return t;
564
+ const d = N(n, encodeURI(s.uri)).replace(/\/$/, ""), l = s.uri.replace(/\/$/, "");
565
+ return r(t, a, c, d, l);
553
566
  }, []);
554
- }, Me = async (n, { baseUrl: t }) => {
555
- const { data: s } = E(n) || {};
556
- if (s && !s.dir) {
557
- const e = new y(await s.string());
558
- return await De(e, n, { baseUrl: t }) || [];
567
+ }, Xe = async (e, n, { baseUrl: i }) => {
568
+ const { data: r } = A(e) || {};
569
+ if (r && !r.dir) {
570
+ const o = new y(await r.string());
571
+ return await De(o, e, { baseUrl: i }) || [];
559
572
  }
560
- const r = ze(n, { baseUrl: t });
561
- if (r.length !== 0)
562
- return r;
563
- }, Ue = ({ archive: n, baseUrl: t }) => async (s) => {
564
- if (s.nav) return s;
565
- const r = await Me(n, { baseUrl: t });
573
+ const t = Ue(n, e);
574
+ if (t) return t;
575
+ const s = Ve(e, { baseUrl: i });
576
+ if (s.length !== 0)
577
+ return s;
578
+ }, _e = ({ archive: e, baseUrl: n }) => async (i) => {
579
+ if (i.nav) return i;
580
+ const r = await Xe(e, i, { baseUrl: n });
566
581
  return r ? {
567
- ...s,
582
+ ...i,
568
583
  nav: {
569
584
  toc: r
570
585
  }
571
- } : s;
572
- }, Be = async (n, { baseUrl: t = "" } = {}) => {
573
- const s = [
574
- Ie({ archive: n, baseUrl: t }),
575
- Le({ archive: n }),
576
- $e({ archive: n }),
577
- Ce({ archive: n }),
578
- Se({ archive: n }),
579
- Fe({ archive: n }),
580
- Ue({ archive: n, baseUrl: t })
586
+ } : i;
587
+ }, He = async (e, { baseUrl: n = "" } = {}) => {
588
+ const i = [
589
+ Ne({ archive: e, baseUrl: n }),
590
+ We({ archive: e }),
591
+ Fe({ archive: e }),
592
+ Pe({ archive: e }),
593
+ ke({ archive: e }),
594
+ Te({ archive: e }),
595
+ _e({ archive: e, baseUrl: n })
581
596
  ];
582
597
  try {
583
- const r = Ee({ archive: n, baseUrl: t })(), e = await s.reduce(async (o, i) => await i(await o), r);
584
- if (m.log("Generated manifest", e), process.env.NODE_ENV === "development" && m.isEnabled()) {
585
- const o = JSON.stringify(e, null, 2);
586
- m.groupCollapsed(...m.getGroupArgs("Generated manifest")), m.log(`
587
- ${o}`), m.groupEnd();
598
+ const r = Ee({ archive: e, baseUrl: n })(), t = await i.reduce(async (s, o) => await o(await s), r);
599
+ if (u.log("Generated manifest", t), process.env.NODE_ENV === "development" && u.isEnabled()) {
600
+ const s = JSON.stringify(t, null, 2);
601
+ u.groupCollapsed(...u.getGroupArgs("Generated manifest")), u.log(`
602
+ ${s}`), u.groupEnd();
588
603
  }
589
- return e;
604
+ return t;
590
605
  } catch (r) {
591
- throw m.error(r), r;
606
+ throw u.error(r), r;
592
607
  }
593
- }, Xe = (n) => {
594
- const t = n.descendantWithPath("head")?.childrenNamed("meta").find((s) => s.attr.name === "calibre:cover");
595
- return !!(t && t.attr.name === "calibre:cover");
596
- }, Ve = (n) => n.descendantWithPath("body")?.descendantWithPath("div")?.childrenNamed("svg")?.find(
597
- (t) => t.attr.width === "100%" && t.attr.preserveAspectRatio === "none"
598
- ), He = ({ archive: n, resourcePath: t }) => async (s) => {
599
- const r = Object.values(n.records).find(
600
- (e) => e.uri === t && !e.dir
608
+ }, Ge = (e) => {
609
+ const n = e.descendantWithPath("head")?.childrenNamed("meta").find((i) => i.attr.name === "calibre:cover");
610
+ return !!(n && n.attr.name === "calibre:cover");
611
+ }, qe = (e) => e.descendantWithPath("body")?.descendantWithPath("div")?.childrenNamed("svg")?.find(
612
+ (n) => n.attr.width === "100%" && n.attr.preserveAspectRatio === "none"
613
+ ), Je = ({ archive: e, resourcePath: n }) => async (i) => {
614
+ const r = Object.values(e.records).find(
615
+ (t) => t.uri === n && !t.dir
601
616
  );
602
617
  if (r && !r.dir && r.basename.endsWith(".xhtml")) {
603
- const e = s.body ?? await r.string(), o = new y(e);
604
- if (Xe(o)) {
605
- const i = Ve(o);
606
- return i && delete i.attr.preserveAspectRatio, {
607
- ...s,
608
- body: o?.toString()
618
+ const t = i.body ?? await r.string(), s = new y(t);
619
+ if (Ge(s)) {
620
+ const o = qe(s);
621
+ return o && delete o.attr.preserveAspectRatio, {
622
+ ...i,
623
+ body: s?.toString()
609
624
  };
610
625
  }
611
626
  }
612
- return s;
613
- }, _e = ({ archive: n, resourcePath: t }) => async (s) => He({ archive: n, resourcePath: t })(s), Ge = ({ archive: n, resourcePath: t }) => async (s) => {
614
- const r = Object.values(n.records).find(
615
- (e) => e.uri === t && !e.dir
627
+ return i;
628
+ }, Ke = ({ archive: e, resourcePath: n }) => async (i) => Je({ archive: e, resourcePath: n })(i), Ye = ({ archive: e, resourcePath: n }) => async (i) => {
629
+ const r = Object.values(e.records).find(
630
+ (t) => t.uri === n && !t.dir
616
631
  );
617
632
  if (r && !r.dir && r.basename.endsWith(".css")) {
618
- const o = (s.body ?? await r.string()).replaceAll(
633
+ const s = (i.body ?? await r.string()).replaceAll(
619
634
  "-webkit-writing-mode",
620
635
  "writing-mode"
621
636
  );
622
637
  return {
623
- ...s,
624
- body: o
638
+ ...i,
639
+ body: s
625
640
  };
626
641
  }
627
- return s;
628
- }, qe = async (n, t) => {
629
- const r = await E(n).data?.string();
642
+ return i;
643
+ }, Qe = async (e, n) => {
644
+ const r = await A(e).data?.string();
630
645
  if (r) {
631
- const e = new y(r), o = Q(e, n, () => "");
632
- if (o.find(
633
- (a) => t.endsWith(a.href)
646
+ const t = new y(r), s = Y(t, e, () => "");
647
+ if (s.find(
648
+ (a) => n.endsWith(a.href)
634
649
  )?.mediaType)
635
650
  return {
636
- mediaType: o.find((a) => t.endsWith(a.href))?.mediaType
651
+ mediaType: s.find((a) => n.endsWith(a.href))?.mediaType
637
652
  };
638
653
  }
639
654
  return {
640
- mediaType: Je(t)
655
+ mediaType: Ze(n)
641
656
  };
642
- }, Je = (n) => {
643
- if (n.endsWith(".css"))
657
+ }, Ze = (e) => {
658
+ if (e.endsWith(".css"))
644
659
  return "text/css; charset=UTF-8";
645
- if (n.endsWith(".jpg"))
660
+ if (e.endsWith(".jpg"))
646
661
  return "image/jpg";
647
- if (n.endsWith(".xhtml"))
662
+ if (e.endsWith(".xhtml"))
648
663
  return "application/xhtml+xml";
649
- if (n.endsWith(".mp4"))
664
+ if (e.endsWith(".mp4"))
650
665
  return "video/mp4";
651
- if (n.endsWith(".svg"))
666
+ if (e.endsWith(".svg"))
652
667
  return "image/svg+xml";
653
- }, Ke = ({ archive: n, resourcePath: t }) => async (s) => {
654
- const r = Object.values(n.records).find(
655
- (o) => o.uri === t && !o.dir
668
+ }, et = ({ archive: e, resourcePath: n }) => async (i) => {
669
+ const r = Object.values(e.records).find(
670
+ (s) => s.uri === n && !s.dir
656
671
  );
657
- if (!r || r.dir) return s;
658
- const e = await qe(n, t);
672
+ if (!r || r.dir) return i;
673
+ const t = await Qe(e, n);
659
674
  return {
660
- ...s,
675
+ ...i,
661
676
  params: {
662
- ...s.params,
677
+ ...i.params,
663
678
  ...r?.encodingFormat && {
664
679
  contentType: r.encodingFormat
665
680
  },
666
- ...e.mediaType && {
667
- contentType: e.mediaType
681
+ ...t.mediaType && {
682
+ contentType: t.mediaType
668
683
  }
669
684
  }
670
685
  };
671
- }, K = [
686
+ }, H = [
672
687
  "div",
673
688
  "span",
674
689
  "p",
@@ -719,282 +734,396 @@ ${o}`), m.groupEnd();
719
734
  "canvas",
720
735
  "script",
721
736
  "style"
722
- ], Ye = ({ archive: n, resourcePath: t }) => async (s) => {
723
- const r = Object.values(n.records).find(
724
- (e) => e.uri === t && !e.dir
737
+ ], tt = ({ archive: e, resourcePath: n }) => async (i) => {
738
+ const r = Object.values(e.records).find(
739
+ (t) => t.uri === n && !t.dir
725
740
  );
726
741
  if (r && !r.dir && r.basename.endsWith(".xhtml")) {
727
- const e = s.body ?? await r.string();
742
+ const t = i.body ?? await r.string();
728
743
  if (!new RegExp(
729
- `<(${K.join("|")})[\\s/>]`,
744
+ `<(${H.join("|")})[\\s/>]`,
730
745
  "i"
731
- ).test(e))
732
- return s;
733
- const i = new RegExp(
734
- `<(${K.join("|")})(\\s[^>]*)?\\s*/>`,
746
+ ).test(t))
747
+ return i;
748
+ const o = new RegExp(
749
+ `<(${H.join("|")})(\\s[^>]*)?\\s*/>`,
735
750
  "gi"
736
- ), a = e.replace(
737
- i,
738
- (l, c, d = "") => `<${c} ${d.trim()}></${c}>`
751
+ ), a = t.replace(
752
+ o,
753
+ (c, d, l = "") => `<${d} ${l.trim()}></${d}>`
739
754
  );
740
755
  return {
741
- ...s,
756
+ ...i,
742
757
  body: a
743
758
  };
744
759
  }
745
- return s;
746
- }, Qe = async (n, t) => {
747
- const s = Object.values(n.records).find(
748
- (o) => o.uri === t && !o.dir
760
+ return i;
761
+ }, nt = async (e, n) => {
762
+ const i = Object.values(e.records).find(
763
+ (s) => s.uri === n && !s.dir
749
764
  );
750
- if (!s || s.dir)
751
- throw new Error(`no file found for resourcePath:${t}`);
765
+ if (!i || i.dir)
766
+ throw new Error(`no file found for resourcePath:${n}`);
752
767
  const r = {
753
768
  params: {}
754
- }, e = [
755
- Ke({ archive: n, resourcePath: t }),
756
- Ye({ archive: n, resourcePath: t }),
757
- Ge({ archive: n, resourcePath: t }),
758
- _e({ archive: n, resourcePath: t })
769
+ }, t = [
770
+ et({ archive: e, resourcePath: n }),
771
+ tt({ archive: e, resourcePath: n }),
772
+ Ye({ archive: e, resourcePath: n }),
773
+ Ke({ archive: e, resourcePath: n })
759
774
  ];
760
775
  try {
761
- const o = await e.reduce(async (i, a) => await a(await i), Promise.resolve(r));
762
- return m.log("Generated resource", t, o), {
763
- ...o,
764
- body: o.body ?? await s.blob()
776
+ const s = await t.reduce(async (o, a) => await a(await o), Promise.resolve(r));
777
+ return u.log("Generated resource", n, s), {
778
+ ...s,
779
+ body: s.body ?? await i.blob()
765
780
  };
766
- } catch (o) {
767
- throw m.error(o), o;
781
+ } catch (s) {
782
+ throw u.error(s), s;
768
783
  }
769
784
  };
770
- class Ze {
771
- constructor(t) {
772
- this.cleanArchiveAfter = t, this.state$ = new fe({
785
+ class rt {
786
+ constructor(n) {
787
+ this.cleanArchiveAfter = n, this.state$ = new me({
773
788
  status: "idle",
774
789
  locks: 0
775
790
  });
776
791
  }
777
- update(t) {
778
- this.state$.next({ ...this.state$.getValue(), ...t });
792
+ update(n) {
793
+ this.state$.next({ ...this.state$.getValue(), ...n });
779
794
  }
780
795
  get locks$() {
781
- return this.state$.pipe($(({ locks: t }) => t));
796
+ return this.state$.pipe(x(({ locks: n }) => n));
782
797
  }
783
798
  get state() {
784
799
  return this.state$.getValue();
785
800
  }
786
801
  get isUnlocked$() {
787
802
  return this.locks$.pipe(
788
- $((t) => t <= 0),
789
- he(),
790
- ge()
803
+ x((n) => n <= 0),
804
+ fe(),
805
+ he()
791
806
  );
792
807
  }
793
808
  get overTTL$() {
794
809
  return this.isUnlocked$.pipe(
795
810
  I(
796
- (t) => t ? this.cleanArchiveAfter === 1 / 0 ? H : ye(this.cleanArchiveAfter) : H
811
+ (n) => n ? this.cleanArchiveAfter === 1 / 0 ? X : ge(this.cleanArchiveAfter) : X
797
812
  )
798
813
  );
799
814
  }
800
815
  }
801
- const et = ({
802
- getArchive: n,
803
- cleanArchiveAfter: t = 300 * 1e3
816
+ const st = ({
817
+ getArchive: e,
818
+ cleanArchiveAfter: n = 300 * 1e3
804
819
  // 5mn
805
820
  }) => {
806
- const s = new R(), r = new R(), e = new R(), o = {}, i = s.pipe(
807
- O((c) => {
808
- const d = o[c];
809
- if (!d || d.state.status !== "idle") return B;
821
+ const i = new W(), r = new W(), t = new W(), s = {}, o = i.pipe(
822
+ J((d) => {
823
+ const l = s[d];
824
+ if (!l || l.state.status !== "idle") return M;
810
825
  let p = !1;
811
826
  const g = (h) => {
812
- m.debug(`Cleaning up archive with key: ${h}`);
813
- const F = o[h];
814
- delete o[h], p || (F?.state.archive?.close(), p = !0);
827
+ u.debug(`Cleaning up archive with key: ${h}`);
828
+ const F = s[h];
829
+ delete s[h], p || (F?.state.archive?.close(), p = !0);
815
830
  };
816
- d.update({
831
+ l.update({
817
832
  status: "loading"
818
833
  });
819
- const b = d.locks$, N = d.isUnlocked$, f = b.pipe(
820
- le(),
821
- P(([h, F]) => F > h),
822
- pe(!0)
834
+ const b = l.locks$, T = l.isUnlocked$, f = b.pipe(
835
+ de(),
836
+ C(([h, F]) => F > h),
837
+ le(!0)
823
838
  );
824
- return W(n(c)).pipe(
825
- j((h) => {
826
- d.update({
839
+ return R(e(d)).pipe(
840
+ P((h) => {
841
+ l.update({
827
842
  archive: h,
828
843
  status: "success"
829
844
  });
830
845
  }),
831
- S((h) => (g(c), d.update({
846
+ z((h) => (g(d), l.update({
832
847
  status: "error",
833
848
  error: h
834
- }), B)),
849
+ }), M)),
835
850
  I(() => {
836
851
  const h = f.pipe(
837
- I(() => e),
838
- I(() => N),
839
- P((k) => k)
852
+ I(() => t),
853
+ I(() => T),
854
+ C((L) => L)
840
855
  );
841
- return X(h, d.overTTL$).pipe(
856
+ return U(h, l.overTTL$).pipe(
842
857
  V(),
843
- j(() => {
844
- g(c);
858
+ P(() => {
859
+ g(d);
845
860
  })
846
861
  );
847
862
  })
848
863
  );
849
864
  }),
850
- me(r)
851
- ), a = (c) => {
852
- let d = !1;
853
- const p = o[c] ?? new Ze(t);
854
- o[c] = p, p.update({
865
+ pe(r)
866
+ ), a = (d) => {
867
+ let l = !1;
868
+ const p = s[d] ?? new rt(n);
869
+ s[d] = p, p.update({
855
870
  locks: p.state.locks + 1
856
871
  });
857
872
  const g = () => {
858
- d || (d = !0, p.update({
873
+ l || (l = !0, p.update({
859
874
  locks: p.state.locks - 1
860
875
  }));
861
876
  };
862
- s.next(c);
877
+ i.next(d);
863
878
  const b = p.state$.pipe(
864
- $(({ archive: f }) => f),
865
- P((f) => !!f)
866
- ), N = p.state$.pipe(
867
- j(({ error: f }) => {
879
+ x(({ archive: f }) => f),
880
+ C((f) => !!f)
881
+ ), T = p.state$.pipe(
882
+ P(({ error: f }) => {
868
883
  if (f)
869
884
  throw f;
870
885
  }),
871
886
  ue()
872
887
  );
873
- return X(b, N).pipe(
888
+ return U(b, T).pipe(
874
889
  V(),
875
- $((f) => ({ archive: f, release: g })),
876
- S((f) => {
890
+ x((f) => ({ archive: f, release: g })),
891
+ z((f) => {
877
892
  throw g(), f;
878
893
  })
879
894
  );
880
- }, l = () => {
881
- e.next();
895
+ }, c = () => {
896
+ t.next();
882
897
  };
883
- return i.subscribe(), {
898
+ return o.subscribe(), {
884
899
  access: a,
885
- purge: l,
886
- _archives: o
900
+ purge: c,
901
+ _archives: s
887
902
  };
903
+ }, G = (e) => e ? /^\d+$/.test(e) ? {
904
+ valid: !0,
905
+ value: Number.parseInt(e, 10)
906
+ } : {
907
+ valid: !1,
908
+ value: void 0
909
+ } : {
910
+ valid: !0,
911
+ value: void 0
912
+ }, it = (e) => {
913
+ if (!e.toLowerCase().startsWith("bytes="))
914
+ return {
915
+ kind: "missing"
916
+ };
917
+ const n = e.slice(6).trim();
918
+ if (!n)
919
+ return {
920
+ kind: "invalid"
921
+ };
922
+ if (n.includes(","))
923
+ return {
924
+ kind: "multi"
925
+ };
926
+ const i = /^(\d*)-(\d*)$/.exec(n);
927
+ if (!i)
928
+ return {
929
+ kind: "invalid"
930
+ };
931
+ const [, r = "", t = ""] = i, s = G(r.trim()), o = G(t.trim());
932
+ return !s.valid || !o.valid ? {
933
+ kind: "invalid"
934
+ } : {
935
+ kind: "single",
936
+ start: s.value,
937
+ end: o.value
938
+ };
939
+ }, ot = (e) => {
940
+ if (e instanceof Blob)
941
+ return {
942
+ size: e.size,
943
+ slice: (i, r) => {
944
+ const t = e.slice(i, r);
945
+ return { content: t, length: t.size };
946
+ }
947
+ };
948
+ const n = new TextEncoder().encode(e);
949
+ return {
950
+ size: n.byteLength,
951
+ slice: (i, r) => {
952
+ const t = n.slice(i, r);
953
+ return { content: t, length: t.byteLength };
954
+ }
955
+ };
956
+ }, at = ({
957
+ body: e,
958
+ contentType: n,
959
+ rangeHeader: i
960
+ }) => {
961
+ const r = new Headers();
962
+ if (n && r.set("Content-Type", n), r.set("Accept-Ranges", "bytes"), !i)
963
+ return e instanceof Blob && r.set("Content-Length", String(e.size)), new Response(e, {
964
+ status: 200,
965
+ headers: r
966
+ });
967
+ const t = it(i);
968
+ if (t.kind === "missing" || t.kind === "multi")
969
+ return e instanceof Blob && r.set("Content-Length", String(e.size)), new Response(e, {
970
+ status: 200,
971
+ headers: r
972
+ });
973
+ const s = ot(e), o = s.size;
974
+ if (t.kind === "invalid")
975
+ return new Response(null, {
976
+ status: 416,
977
+ headers: {
978
+ "Content-Range": `bytes */${o}`
979
+ }
980
+ });
981
+ let a = t.start, c = t.end;
982
+ if (a === void 0 && c === void 0)
983
+ return new Response(null, {
984
+ status: 416,
985
+ headers: {
986
+ "Content-Range": `bytes */${o}`
987
+ }
988
+ });
989
+ if (a === void 0) {
990
+ const l = Math.min(c ?? 0, o);
991
+ a = Math.max(0, o - l), c = o - 1;
992
+ } else (c === void 0 || c >= o) && (c = o - 1);
993
+ if (a < 0 || c < 0 || a >= o || c >= o || a > c)
994
+ return new Response(null, {
995
+ status: 416,
996
+ headers: {
997
+ "Content-Range": `bytes */${o}`
998
+ }
999
+ });
1000
+ const d = s.slice(a, c + 1);
1001
+ return r.set("Content-Length", String(d.length)), r.set("Content-Range", `bytes ${a}-${c}/${o}`), new Response(d.content, {
1002
+ status: 206,
1003
+ headers: r
1004
+ });
888
1005
  };
889
- class tt {
1006
+ class ct {
890
1007
  constructor({
891
- onError: t,
892
- onManifestSuccess: s,
1008
+ onError: n,
1009
+ onManifestSuccess: i,
893
1010
  ...r
894
1011
  }) {
895
- this.onError = (e) => (console.error(e), new Response(String(e), { status: 500 })), this.epubLoader = et(r), this.onManifestSuccess = s ?? (({ manifest: e }) => Promise.resolve(e)), this.onError = t ?? this.onError;
1012
+ this.onError = (t) => (console.error(t), new Response(String(t), { status: 500 })), this.epubLoader = st(r), this.onManifestSuccess = i ?? (({ manifest: t }) => Promise.resolve(t)), this.onError = n ?? this.onError;
896
1013
  }
897
1014
  prune() {
898
1015
  this.epubLoader.purge();
899
1016
  }
900
- accessArchive(t) {
901
- return this.lastAccessedKey !== void 0 && this.lastAccessedKey !== t && this.epubLoader.purge(), this.lastAccessedKey = t, this.epubLoader.access(t);
1017
+ accessArchive(n) {
1018
+ return this.lastAccessedKey !== void 0 && this.lastAccessedKey !== n && this.epubLoader.purge(), this.lastAccessedKey = n, this.epubLoader.access(n);
902
1019
  }
903
- accessArchiveWithoutLock(t) {
904
- return this.accessArchive(t).pipe(
905
- $(({ archive: s, release: r }) => (r(), s))
1020
+ accessArchiveWithoutLock(n) {
1021
+ return this.accessArchive(n).pipe(
1022
+ x(({ archive: i, release: r }) => (r(), i))
906
1023
  );
907
1024
  }
908
- fetchManifest({ key: t, baseUrl: s }) {
909
- const r = this.accessArchive(t).pipe(
910
- O(({ archive: e, release: o }) => W(
911
- Be(e, { baseUrl: s })
1025
+ withArchiveResponse({
1026
+ key: n,
1027
+ getResponse: i
1028
+ }) {
1029
+ const r = this.accessArchive(n).pipe(
1030
+ J(
1031
+ ({ archive: t, release: s }) => R(i(t)).pipe(
1032
+ ye(() => {
1033
+ s();
1034
+ })
1035
+ )
1036
+ ),
1037
+ z((t) => be(this.onError(t)))
1038
+ );
1039
+ return ve(r);
1040
+ }
1041
+ fetchManifest({ key: n, baseUrl: i }) {
1042
+ return this.withArchiveResponse({
1043
+ key: n,
1044
+ getResponse: (r) => R(
1045
+ He(r, { baseUrl: i })
912
1046
  ).pipe(
913
1047
  I(
914
- (a) => W(this.onManifestSuccess({ manifest: a, archive: e }))
1048
+ (s) => R(this.onManifestSuccess({ manifest: s, archive: r }))
915
1049
  ),
916
- $(
917
- (a) => new Response(JSON.stringify(a), {
1050
+ x(
1051
+ (s) => new Response(JSON.stringify(s), {
918
1052
  status: 200
919
1053
  })
920
- ),
921
- _(() => {
922
- o();
923
- })
924
- )),
925
- S((e) => G(this.onError(e)))
926
- );
927
- return q(r);
1054
+ )
1055
+ )
1056
+ });
928
1057
  }
929
1058
  fetchResource({
930
- key: t,
931
- resourcePath: s
1059
+ key: n,
1060
+ resourcePath: i,
1061
+ request: r
932
1062
  }) {
933
- const r = this.accessArchive(t).pipe(
934
- O(({ archive: e, release: o }) => {
935
- const i = s.replaceAll("file://", "");
936
- return W(
937
- Qe(e, i)
1063
+ return this.withArchiveResponse({
1064
+ key: n,
1065
+ getResponse: (t) => {
1066
+ const s = i.replaceAll("file://", "");
1067
+ return R(
1068
+ nt(t, s)
938
1069
  ).pipe(
939
- $(
940
- (l) => new Response(l.body, {
941
- status: 200,
942
- headers: {
943
- ...l.params.contentType && {
944
- "Content-Type": l.params.contentType
945
- }
946
- }
1070
+ x(
1071
+ (a) => at({
1072
+ body: a.body ?? "",
1073
+ contentType: a.params.contentType,
1074
+ rangeHeader: r?.headers.get("range")
947
1075
  })
948
- ),
949
- _(() => {
950
- o();
951
- })
1076
+ )
952
1077
  );
953
- }),
954
- S((e) => G(this.onError(e)))
955
- );
956
- return q(r);
1078
+ }
1079
+ });
957
1080
  }
958
1081
  }
959
- class mt extends tt {
1082
+ class vt extends ct {
960
1083
  constructor({
961
- getUriInfo: t,
962
- ...s
1084
+ getUriInfo: n,
1085
+ ...i
963
1086
  }) {
964
- super(s), this.getUriInfo = t, this.fetchEventListener = this.fetchEventListener.bind(this);
1087
+ super(i), this.getUriInfo = n, this.fetchEventListener = this.fetchEventListener.bind(this);
965
1088
  }
966
- fetchEventListener(t) {
1089
+ fetchEventListener(n) {
967
1090
  try {
968
- const s = this.getUriInfo(t);
969
- if (!s) return;
970
- const r = J(s.baseUrl), e = t.request.url.substring(
1091
+ const i = this.getUriInfo(n);
1092
+ if (!i) return;
1093
+ const r = _(i.baseUrl), t = n.request.url.substring(
971
1094
  r.length + 1
972
- ), [o = ""] = e.split("/"), i = decodeURIComponent(
973
- J(e.substring(o.length + 1))
1095
+ ), [s = ""] = t.split("/"), o = decodeURIComponent(
1096
+ _(t.substring(s.length + 1))
1097
+ );
1098
+ t.endsWith("/manifest") ? n.respondWith(
1099
+ this.fetchManifest({ key: s, baseUrl: `${r}/${s}/` })
1100
+ ) : n.respondWith(
1101
+ this.fetchResource({
1102
+ key: s,
1103
+ resourcePath: o,
1104
+ request: n.request
1105
+ })
974
1106
  );
975
- e.endsWith("/manifest") ? t.respondWith(
976
- this.fetchManifest({ key: o, baseUrl: `${r}/${o}/` })
977
- ) : t.respondWith(this.fetchResource({ key: o, resourcePath: i }));
978
- } catch (s) {
979
- t.respondWith(new Response(String(s), { status: 500 }));
1107
+ } catch (i) {
1108
+ n.respondWith(new Response(String(i), { status: 500 }));
980
1109
  }
981
1110
  }
982
1111
  }
983
1112
  export {
984
- mt as ServiceWorkerStreamer,
985
- tt as Streamer,
986
- pt as configure,
987
- it as createArchiveFromArrayBufferList,
988
- at as createArchiveFromJszip,
989
- ct as createArchiveFromLibArchive,
990
- dt as createArchiveFromText,
991
- lt as createArchiveFromUrls,
992
- Be as generateManifestFromArchive,
993
- Qe as generateResourceFromArchive,
994
- E as getArchiveOpfInfo,
995
- be as getUriBasePath,
996
- w as getUriBasename,
997
- J as removeTrailingSlash,
998
- D as sortByTitleComparator
1113
+ vt as ServiceWorkerStreamer,
1114
+ ct as Streamer,
1115
+ bt as configure,
1116
+ mt as createArchiveFromArrayBufferList,
1117
+ ft as createArchiveFromJszip,
1118
+ ht as createArchiveFromLibArchive,
1119
+ gt as createArchiveFromText,
1120
+ yt as createArchiveFromUrls,
1121
+ He as generateManifestFromArchive,
1122
+ nt as generateResourceFromArchive,
1123
+ A as getArchiveOpfInfo,
1124
+ we as getUriBasePath,
1125
+ v as getUriBasename,
1126
+ _ as removeTrailingSlash,
1127
+ j as sortByTitleComparator
999
1128
  };
1000
1129
  //# sourceMappingURL=index.js.map