@prose-reader/streamer 0.0.22

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 (39) hide show
  1. package/dist/archives/createArchiveFromArrayBufferList.d.ts +10 -0
  2. package/dist/archives/createArchiveFromArrayBufferList.js +35 -0
  3. package/dist/archives/createArchiveFromJszip.d.ts +34 -0
  4. package/dist/archives/createArchiveFromJszip.js +26 -0
  5. package/dist/archives/createArchiveFromText.d.ts +7 -0
  6. package/dist/archives/createArchiveFromText.js +67 -0
  7. package/dist/archives/createArchiveFromUrls.d.ts +7 -0
  8. package/dist/archives/createArchiveFromUrls.js +29 -0
  9. package/dist/archives/getArchiveOpfInfo.d.ts +15 -0
  10. package/dist/archives/getArchiveOpfInfo.js +8 -0
  11. package/dist/archives/types.d.ts +20 -0
  12. package/dist/archives/types.js +1 -0
  13. package/dist/generators/manifest.d.ts +10 -0
  14. package/dist/generators/manifest.js +141 -0
  15. package/dist/generators/resources.d.ts +2 -0
  16. package/dist/generators/resources.js +95 -0
  17. package/dist/index.d.ts +10 -0
  18. package/dist/index.js +5709 -0
  19. package/dist/index.js.LICENSE.txt +10 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/parsers/kobo.d.ts +6 -0
  22. package/dist/parsers/kobo.js +26 -0
  23. package/dist/parsers/nav.d.ts +5 -0
  24. package/dist/parsers/nav.js +121 -0
  25. package/dist/report.d.ts +13 -0
  26. package/dist/report.js +68 -0
  27. package/dist/streamer/src/archives/createArchiveFromJszip.d.ts +34 -0
  28. package/dist/streamer/src/generators/manifest.d.ts +10 -0
  29. package/dist/streamer/src/generators/resources.d.ts +2 -0
  30. package/dist/streamer/src/index.d.ts +10 -0
  31. package/dist/streamer/src/parsers/kobo.d.ts +6 -0
  32. package/dist/streamer/src/parsers/nav.d.ts +5 -0
  33. package/dist/utils/blobToBAse64.d.ts +1 -0
  34. package/dist/utils/blobToBAse64.js +19 -0
  35. package/dist/utils/sortByTitleComparator.d.ts +1 -0
  36. package/dist/utils/sortByTitleComparator.js +18 -0
  37. package/dist/utils/uri.d.ts +1 -0
  38. package/dist/utils/uri.js +1 -0
  39. package/package.json +41 -0
@@ -0,0 +1,10 @@
1
+ import { Archive } from "./types";
2
+ export declare const createArchiveFromArrayBufferList: (list: {
3
+ isDir: boolean;
4
+ name: string;
5
+ size: number;
6
+ data: () => Promise<ArrayBuffer>;
7
+ }[], { orderByAlpha, name }?: {
8
+ orderByAlpha?: boolean | undefined;
9
+ name?: string | undefined;
10
+ }) => Promise<Archive>;
@@ -0,0 +1,35 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { sortByTitleComparator } from "../utils/sortByTitleComparator";
11
+ import { getUriBasename } from "../utils/uri";
12
+ export const createArchiveFromArrayBufferList = (list, { orderByAlpha, name } = {}) => __awaiter(void 0, void 0, void 0, function* () {
13
+ let files = list;
14
+ if (orderByAlpha) {
15
+ files = files.sort((a, b) => sortByTitleComparator(a.name, b.name));
16
+ }
17
+ return {
18
+ filename: name || ``,
19
+ files: files.map(file => ({
20
+ dir: file.isDir,
21
+ basename: getUriBasename(file.name),
22
+ uri: file.name,
23
+ blob: () => __awaiter(void 0, void 0, void 0, function* () { return new Blob([yield file.data()]); }),
24
+ string: () => __awaiter(void 0, void 0, void 0, function* () {
25
+ const data = yield file.data();
26
+ return String.fromCharCode.apply(null, Array.from(new Uint16Array(data)));
27
+ }),
28
+ base64: () => __awaiter(void 0, void 0, void 0, function* () {
29
+ // @todo not used for now, lets implement it later if needed
30
+ return ``;
31
+ }),
32
+ size: file.size
33
+ }))
34
+ };
35
+ });
@@ -0,0 +1,34 @@
1
+ /// <reference types="node" />
2
+ import { Archive, StreamResult } from "./types";
3
+ interface OutputByType {
4
+ base64: string;
5
+ string: string;
6
+ text: string;
7
+ binarystring: string;
8
+ array: number[];
9
+ uint8array: Uint8Array;
10
+ arraybuffer: ArrayBuffer;
11
+ blob: Blob;
12
+ nodebuffer: Buffer;
13
+ }
14
+ declare type OutputType = keyof OutputByType;
15
+ interface JSZipObject {
16
+ name: string;
17
+ dir: boolean;
18
+ date: Date;
19
+ comment: string;
20
+ unixPermissions: number | string | null;
21
+ dosPermissions: number | null;
22
+ async<T extends OutputType>(type: T): Promise<OutputByType[T]>;
23
+ internalStream?: (type?: `uint8array`) => StreamResult;
24
+ }
25
+ interface JSZip {
26
+ files: {
27
+ [key: string]: JSZipObject;
28
+ };
29
+ }
30
+ export declare const createArchiveFromJszip: (jszip: JSZip, { orderByAlpha, name }?: {
31
+ orderByAlpha?: boolean | undefined;
32
+ name?: string | undefined;
33
+ }) => Promise<Archive>;
34
+ export {};
@@ -0,0 +1,26 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { sortByTitleComparator } from "../utils/sortByTitleComparator";
11
+ import { getUriBasename } from "../utils/uri";
12
+ export const createArchiveFromJszip = (jszip, { orderByAlpha, name } = {}) => __awaiter(void 0, void 0, void 0, function* () {
13
+ let files = Object.values(jszip.files);
14
+ if (orderByAlpha) {
15
+ files = files.sort((a, b) => sortByTitleComparator(a.name, b.name));
16
+ }
17
+ return {
18
+ filename: name || ``,
19
+ files: files.map(file => (Object.assign(Object.assign({ dir: file.dir, basename: getUriBasename(file.name), uri: file.name, blob: () => file.async(`blob`), string: () => file.async(`string`), base64: () => file.async(`base64`) }, file.internalStream && {
20
+ stream: file.internalStream
21
+ }), {
22
+ // this is private API
23
+ // @ts-ignore
24
+ size: file._data.uncompressedSize })))
25
+ };
26
+ });
@@ -0,0 +1,7 @@
1
+ import { Archive } from "./types";
2
+ /**
3
+ * Useful to create archive from txt content
4
+ */
5
+ export declare const createArchiveFromText: (content: string | Blob | File, options?: {
6
+ direction: `ltr` | `rtl`;
7
+ } | undefined) => Promise<Archive>;
@@ -0,0 +1,67 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { blobToBase64 } from "../utils/blobToBAse64";
11
+ import { getUriBasename } from "../utils/uri";
12
+ /**
13
+ * Useful to create archive from txt content
14
+ */
15
+ export const createArchiveFromText = (content, options) => __awaiter(void 0, void 0, void 0, function* () {
16
+ const txtOpfContent = `
17
+ <?xml version="1.0" encoding="UTF-8"?>
18
+ <package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
19
+ unique-identifier="ootuya-id">
20
+ <metadata xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/"
21
+ xmlns:dcterms="http://purl.org/dc/terms/">
22
+ <meta property="rendition:layout">reflowable</meta>
23
+ </metadata>
24
+ <manifest>
25
+ <item id="p01" href="p01.txt" media-type="text/plain"/>
26
+ </manifest>
27
+ <spine page-progression-direction="${(options === null || options === void 0 ? void 0 : options.direction) || `ltr`}">
28
+ <itemref idref="p01" />
29
+ </spine>
30
+ </package>
31
+ `;
32
+ const archive = {
33
+ filename: `content.txt`,
34
+ files: [{
35
+ dir: false,
36
+ basename: getUriBasename(`generated.opf`),
37
+ uri: `generated.opf`,
38
+ blob: () => __awaiter(void 0, void 0, void 0, function* () { return new Blob([txtOpfContent]); }),
39
+ string: () => __awaiter(void 0, void 0, void 0, function* () { return txtOpfContent; }),
40
+ base64: () => __awaiter(void 0, void 0, void 0, function* () { return btoa(txtOpfContent); }),
41
+ size: 0
42
+ },
43
+ {
44
+ dir: false,
45
+ basename: getUriBasename(`p01.txt`),
46
+ uri: `p01.txt`,
47
+ blob: () => __awaiter(void 0, void 0, void 0, function* () {
48
+ if (typeof content === `string`)
49
+ return new Blob([content]);
50
+ return content;
51
+ }),
52
+ string: () => __awaiter(void 0, void 0, void 0, function* () {
53
+ if (typeof content === `string`)
54
+ return content;
55
+ return content.text();
56
+ }),
57
+ base64: () => __awaiter(void 0, void 0, void 0, function* () {
58
+ if (typeof content === `string`)
59
+ return btoa(content);
60
+ return blobToBase64(content);
61
+ }),
62
+ size: typeof content === `string` ? content.length : content.size,
63
+ encodingFormat: `text/plain`
64
+ }]
65
+ };
66
+ return archive;
67
+ });
@@ -0,0 +1,7 @@
1
+ import { Archive } from "./types";
2
+ /**
3
+ * @important
4
+ * Make sure the urls are on the same origin or the cors header is set otherwise
5
+ * the resource cannot be consumed as it is on the web.
6
+ */
7
+ export declare const createArchiveFromUrls: (urls: string[]) => Promise<Archive>;
@@ -0,0 +1,29 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { getUriBasename } from "../utils/uri";
11
+ /**
12
+ * @important
13
+ * Make sure the urls are on the same origin or the cors header is set otherwise
14
+ * the resource cannot be consumed as it is on the web.
15
+ */
16
+ export const createArchiveFromUrls = (urls) => __awaiter(void 0, void 0, void 0, function* () {
17
+ return {
18
+ filename: ``,
19
+ files: urls.map(url => ({
20
+ dir: false,
21
+ basename: getUriBasename(url),
22
+ uri: url,
23
+ size: 100 / urls.length,
24
+ base64: () => __awaiter(void 0, void 0, void 0, function* () { return ``; }),
25
+ blob: () => __awaiter(void 0, void 0, void 0, function* () { return new Blob(); }),
26
+ string: () => __awaiter(void 0, void 0, void 0, function* () { return ``; })
27
+ }))
28
+ };
29
+ });
@@ -0,0 +1,15 @@
1
+ import { Archive } from "./types";
2
+ export declare const getArchiveOpfInfo: (archive: Archive) => {
3
+ data: {
4
+ dir: boolean;
5
+ basename: string;
6
+ uri: string;
7
+ blob: () => Promise<Blob>;
8
+ string: () => Promise<string>;
9
+ base64: () => Promise<string>;
10
+ stream?: (() => import("./types").StreamResult) | undefined;
11
+ size: number;
12
+ encodingFormat?: "text/plain" | undefined;
13
+ } | undefined;
14
+ basePath: string;
15
+ };
@@ -0,0 +1,8 @@
1
+ export const getArchiveOpfInfo = (archive) => {
2
+ const filesAsArray = Object.values(archive.files).filter(file => !file.dir);
3
+ const file = filesAsArray.find(file => file.uri.endsWith(`.opf`));
4
+ return {
5
+ data: file,
6
+ basePath: (file === null || file === void 0 ? void 0 : file.uri.substring(0, file.uri.lastIndexOf(`/`))) || ``
7
+ };
8
+ };
@@ -0,0 +1,20 @@
1
+ export interface StreamResult {
2
+ on(e: `data`, cb: (data: Uint8Array) => void): void;
3
+ on(e: `error`, cb: (error: Error) => void): void;
4
+ on(e: `end`, cb: () => void): void;
5
+ resume(): void;
6
+ }
7
+ export declare type Archive = {
8
+ filename: string;
9
+ files: {
10
+ dir: boolean;
11
+ basename: string;
12
+ uri: string;
13
+ blob: () => Promise<Blob>;
14
+ string: () => Promise<string>;
15
+ base64: () => Promise<string>;
16
+ stream?: () => StreamResult;
17
+ size: number;
18
+ encodingFormat?: undefined | `text/plain`;
19
+ }[];
20
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import xmldoc from 'xmldoc';
2
+ import { Archive } from '..';
3
+ export declare const getManifestFromArchive: (archive: Archive, { baseUrl }?: {
4
+ baseUrl?: string | undefined;
5
+ }) => Promise<Response>;
6
+ export declare const getItemsFromDoc: (doc: xmldoc.XmlDocument) => {
7
+ href: string;
8
+ id: string;
9
+ mediaType: string | undefined;
10
+ }[];
@@ -0,0 +1,141 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import xmldoc from 'xmldoc';
11
+ import { parseToc } from '../parsers/nav';
12
+ import { extractKoboInformationFromArchive } from '../parsers/kobo';
13
+ import { Report } from '../report';
14
+ import { getArchiveOpfInfo } from '..';
15
+ const generateManifestFromEpub = (archive, baseUrl) => __awaiter(void 0, void 0, void 0, function* () {
16
+ var _a;
17
+ const { data: opsFile, basePath: opfBasePath } = getArchiveOpfInfo(archive) || {};
18
+ const koboInformation = yield extractKoboInformationFromArchive(archive);
19
+ if (!opsFile) {
20
+ throw new Error(`No opf content`);
21
+ }
22
+ const data = yield opsFile.string();
23
+ Report.log(data, koboInformation);
24
+ const opfXmlDoc = new xmldoc.XmlDocument(data);
25
+ const toc = (yield parseToc(opfXmlDoc, archive, { baseUrl })) || [];
26
+ const metadataElm = opfXmlDoc.childNamed(`metadata`);
27
+ const manifestElm = opfXmlDoc.childNamed(`manifest`);
28
+ const spineElm = opfXmlDoc.childNamed(`spine`);
29
+ const guideElm = opfXmlDoc.childNamed(`guide`);
30
+ const titleElm = metadataElm === null || metadataElm === void 0 ? void 0 : metadataElm.childNamed(`dc:title`);
31
+ const metaElmChildren = (metadataElm === null || metadataElm === void 0 ? void 0 : metadataElm.childrenNamed(`meta`)) || [];
32
+ const metaElmWithRendition = metaElmChildren.find(meta => meta.attr.property === `rendition:layout`);
33
+ const metaElmWithRenditionFlow = metaElmChildren.find(meta => meta.attr.property === `rendition:flow`);
34
+ const metaElmWithRenditionSpread = metaElmChildren.find(meta => meta.attr.property === `rendition:spread`);
35
+ const publisherRenditionLayout = metaElmWithRendition === null || metaElmWithRendition === void 0 ? void 0 : metaElmWithRendition.val;
36
+ const publisherRenditionFlow = metaElmWithRenditionFlow === null || metaElmWithRenditionFlow === void 0 ? void 0 : metaElmWithRenditionFlow.val;
37
+ const renditionSpread = metaElmWithRenditionSpread === null || metaElmWithRenditionSpread === void 0 ? void 0 : metaElmWithRenditionSpread.val;
38
+ const title = (titleElm === null || titleElm === void 0 ? void 0 : titleElm.val) || ((_a = archive.files.find(({ dir }) => dir)) === null || _a === void 0 ? void 0 : _a.basename) || ``;
39
+ const pageProgressionDirection = spineElm === null || spineElm === void 0 ? void 0 : spineElm.attr[`page-progression-direction`];
40
+ const spineItemIds = spineElm === null || spineElm === void 0 ? void 0 : spineElm.childrenNamed(`itemref`).map((item) => item.attr.idref);
41
+ const manifestItemsFromSpine = (manifestElm === null || manifestElm === void 0 ? void 0 : manifestElm.childrenNamed(`item`).filter((item) => spineItemIds.includes(item.attr.id || ``))) || [];
42
+ const archiveSpineItems = archive.files.filter(file => {
43
+ return manifestItemsFromSpine.find(item => {
44
+ if (!opfBasePath)
45
+ return `${item.attr.href}` === file.uri;
46
+ return `${opfBasePath}/${item.attr.href}` === file.uri;
47
+ });
48
+ });
49
+ const totalSize = archiveSpineItems.reduce((size, file) => file.size + size, 1);
50
+ return {
51
+ filename: archive.filename,
52
+ nav: {
53
+ toc
54
+ },
55
+ renditionLayout: publisherRenditionLayout || koboInformation.renditionLayout || `reflowable`,
56
+ renditionFlow: publisherRenditionFlow || `auto`,
57
+ renditionSpread,
58
+ title,
59
+ readingDirection: pageProgressionDirection || `ltr`,
60
+ spineItems: (spineElm === null || spineElm === void 0 ? void 0 : spineElm.childrenNamed(`itemref`).map((itemrefElm) => {
61
+ var _a, _b;
62
+ const manifestItem = manifestElm === null || manifestElm === void 0 ? void 0 : manifestElm.childrenNamed(`item`).find((item) => item.attr.id === (itemrefElm === null || itemrefElm === void 0 ? void 0 : itemrefElm.attr.idref));
63
+ const href = (manifestItem === null || manifestItem === void 0 ? void 0 : manifestItem.attr.href) || ``;
64
+ const properties = (((_a = itemrefElm === null || itemrefElm === void 0 ? void 0 : itemrefElm.attr.properties) === null || _a === void 0 ? void 0 : _a.split(` `)) || []);
65
+ const itemSize = ((_b = archive.files.find(file => file.uri.endsWith(href))) === null || _b === void 0 ? void 0 : _b.size) || 0;
66
+ return Object.assign(Object.assign({ id: (manifestItem === null || manifestItem === void 0 ? void 0 : manifestItem.attr.id) || ``, path: opfBasePath ? `${opfBasePath}/${manifestItem === null || manifestItem === void 0 ? void 0 : manifestItem.attr.href}` : `${manifestItem === null || manifestItem === void 0 ? void 0 : manifestItem.attr.href}`,
67
+ // href: opfBasePath ? `${baseUrl}/${opfBasePath}/${manifestItem?.attr['href']}` : `${baseUrl}/${manifestItem?.attr['href']}`,
68
+ href: opfBasePath ? `${baseUrl}/${opfBasePath}/${manifestItem === null || manifestItem === void 0 ? void 0 : manifestItem.attr.href}` : `${baseUrl}/${manifestItem === null || manifestItem === void 0 ? void 0 : manifestItem.attr.href}`, renditionLayout: publisherRenditionLayout || `reflowable` }, properties.find(property => property === `rendition:layout-reflowable`) && {
69
+ renditionLayout: `reflowable`
70
+ }), { progressionWeight: itemSize / totalSize, pageSpreadLeft: properties.some(property => property === `page-spread-left`) || undefined, pageSpreadRight: properties.some(property => property === `page-spread-right`) || undefined,
71
+ // size: itemSize
72
+ mediaType: manifestItem === null || manifestItem === void 0 ? void 0 : manifestItem.attr[`media-type`] });
73
+ })) || [],
74
+ items: getItemsFromDoc(opfXmlDoc),
75
+ guide: guideElm === null || guideElm === void 0 ? void 0 : guideElm.childrenNamed(`reference`).map(elm => {
76
+ return {
77
+ href: elm.attr.href || ``,
78
+ title: elm.attr.title || ``,
79
+ type: elm.attr.type
80
+ };
81
+ })
82
+ };
83
+ });
84
+ /**
85
+ * Create a manifest from a generic archive.
86
+ * Will use direct
87
+ */
88
+ const generateManifestFromArchive = (archive, baseUrl) => __awaiter(void 0, void 0, void 0, function* () {
89
+ var _b;
90
+ const files = Object.values(archive.files).filter(file => !file.dir);
91
+ return {
92
+ filename: archive.filename,
93
+ nav: {
94
+ toc: []
95
+ },
96
+ title: ((_b = archive.files.find(({ dir }) => dir)) === null || _b === void 0 ? void 0 : _b.basename.replace(/\/$/, ``)) || ``,
97
+ renditionLayout: `pre-paginated`,
98
+ renditionSpread: `auto`,
99
+ readingDirection: `ltr`,
100
+ spineItems: files.map((file) => ({
101
+ id: file.basename,
102
+ path: `${file.uri}`,
103
+ href: baseUrl ? `${baseUrl}/${file.uri}` : file.uri,
104
+ renditionLayout: `pre-paginated`,
105
+ progressionWeight: (1 / files.length),
106
+ pageSpreadLeft: undefined,
107
+ pageSpreadRight: undefined
108
+ })),
109
+ items: files.map((file) => ({
110
+ id: file.basename,
111
+ href: baseUrl ? `${baseUrl}/${file.uri}` : file.uri
112
+ }))
113
+ };
114
+ });
115
+ export const getManifestFromArchive = (archive, { baseUrl = `` } = {}) => __awaiter(void 0, void 0, void 0, function* () {
116
+ var _c;
117
+ const { data: opsFile } = getArchiveOpfInfo(archive) || {};
118
+ try {
119
+ if (opsFile) {
120
+ const manifest = yield generateManifestFromEpub(archive, baseUrl);
121
+ const data = JSON.stringify(manifest);
122
+ return new Response(data, { status: 200 });
123
+ }
124
+ const manifest = yield generateManifestFromArchive(archive, baseUrl);
125
+ const data = JSON.stringify(manifest);
126
+ return new Response(data, { status: 200 });
127
+ }
128
+ catch (e) {
129
+ Report.error(e);
130
+ return new Response((_c = e) === null || _c === void 0 ? void 0 : _c.message, { status: 500 });
131
+ }
132
+ });
133
+ export const getItemsFromDoc = (doc) => {
134
+ var _a;
135
+ const manifestElm = doc.childNamed(`manifest`);
136
+ return ((_a = manifestElm === null || manifestElm === void 0 ? void 0 : manifestElm.childrenNamed(`item`)) === null || _a === void 0 ? void 0 : _a.map((el) => ({
137
+ href: el.attr.href || ``,
138
+ id: el.attr.id || ``,
139
+ mediaType: el.attr[`media-type`]
140
+ }))) || [];
141
+ };
@@ -0,0 +1,2 @@
1
+ import { Archive } from '..';
2
+ export declare const getResourceFromArchive: (archive: Archive, resourcePath: string) => Promise<Response>;
@@ -0,0 +1,95 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import xmldoc from 'xmldoc';
11
+ import { getArchiveOpfInfo } from '..';
12
+ import { getItemsFromDoc } from "./manifest";
13
+ export const getResourceFromArchive = (archive, resourcePath) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const file = Object.values(archive.files).find(file => file.uri === resourcePath);
15
+ const metadata = yield getMetadata(archive, resourcePath);
16
+ if (!file) {
17
+ throw new Error(`no file found`);
18
+ }
19
+ const blob = yield file.blob();
20
+ // if (file.stream) {
21
+ // const stream = file.stream()
22
+ // console.log(file, stream)
23
+ // stream.on(`data`, data => {
24
+ // console.log(`data`, data)
25
+ // })
26
+ // stream.on(`error`, data => {
27
+ // console.error(`error`, data)
28
+ // })
29
+ // stream.on(`end`, () => {
30
+ // console.log(`end`)
31
+ // })
32
+ // }
33
+ // const stream = file.stream!()
34
+ // const readableStream = new ReadableStream({
35
+ // start(controller) {
36
+ // function push() {
37
+ // stream.on(`data`, data => {
38
+ // controller.enqueue(data)
39
+ // })
40
+ // stream.on(`error`, data => {
41
+ // console.error(`error`, data)
42
+ // })
43
+ // stream.on(`end`, () => {
44
+ // controller.close()
45
+ // })
46
+ // stream.resume()
47
+ // }
48
+ // push();
49
+ // }
50
+ // })
51
+ const response = new Response(blob, {
52
+ headers: Object.assign(Object.assign(Object.assign({}, blob.type && {
53
+ 'Content-Type': blob.type
54
+ }), file.encodingFormat && {
55
+ 'Content-Type': file.encodingFormat
56
+ }), metadata.mediaType && {
57
+ 'Content-Type': metadata.mediaType
58
+ }
59
+ // 'Cache-Control': `no-cache, no-store, no-transform`
60
+ )
61
+ });
62
+ return response;
63
+ });
64
+ const getMetadata = (archive, resourcePath) => __awaiter(void 0, void 0, void 0, function* () {
65
+ var _a, _b;
66
+ const opfInfo = getArchiveOpfInfo(archive);
67
+ const data = yield ((_a = opfInfo.data) === null || _a === void 0 ? void 0 : _a.string());
68
+ if (data) {
69
+ const opfXmlDoc = new xmldoc.XmlDocument(data);
70
+ const items = getItemsFromDoc(opfXmlDoc);
71
+ return {
72
+ mediaType: (_b = items.find((item) => resourcePath.endsWith(item.href))) === null || _b === void 0 ? void 0 : _b.mediaType
73
+ };
74
+ }
75
+ return {
76
+ mediaType: getContentTypeFromExtension(resourcePath)
77
+ };
78
+ });
79
+ const getContentTypeFromExtension = (uri) => {
80
+ if (uri.endsWith(`.css`)) {
81
+ return `text/css; charset=UTF-8`;
82
+ }
83
+ if (uri.endsWith(`.jpg`)) {
84
+ return `image/jpg`;
85
+ }
86
+ if (uri.endsWith(`.xhtml`)) {
87
+ return `application/xhtml+xml`;
88
+ }
89
+ if (uri.endsWith(`.mp4`)) {
90
+ return `video/mp4`;
91
+ }
92
+ if (uri.endsWith(`.svg`)) {
93
+ return `image/svg+xml`;
94
+ }
95
+ };
@@ -0,0 +1,10 @@
1
+ export { getResourceFromArchive } from './generators/resources';
2
+ export { getManifestFromArchive } from './generators/manifest';
3
+ export type { Manifest } from '@prose-reader/shared';
4
+ export { Report } from './report';
5
+ export { Archive } from './archives/types';
6
+ export { getArchiveOpfInfo } from './archives/getArchiveOpfInfo';
7
+ export { createArchiveFromUrls } from './archives/createArchiveFromUrls';
8
+ export { createArchiveFromText } from './archives/createArchiveFromText';
9
+ export { createArchiveFromJszip } from './archives/createArchiveFromJszip';
10
+ export { createArchiveFromArrayBufferList } from './archives/createArchiveFromArrayBufferList';