diff --git a/src/lib/util/baseGenerator.js b/src/lib/util/baseGenerator.ts similarity index 66% rename from src/lib/util/baseGenerator.js rename to src/lib/util/baseGenerator.ts index 793435c..d08fb1b 100644 --- a/src/lib/util/baseGenerator.js +++ b/src/lib/util/baseGenerator.ts @@ -1,38 +1,37 @@ - -/** - * @typedef Chapter - * @property {string} id - * @property {number} number - * @property {number?} volume - * @property {string[]} links - * @property {string} hash - * @property {string} baseUrl - * @property {string} title - */ - import request, { proxy, imageproxy } from "./request"; const RETRY_LIMIT = 10; +interface Chapter { + id: string, + number: string, + volume?: string, + links: string[], + hash: string, + hashes: string[], + baseUrl: string, + title: string +} + +interface Opts { + quality: string, + file: WritableStream, + title: string, + id: string, + language: string, + author: string, + updatedAt: string | Date, + chapters: Chapter[], + callback?: (chapter: string | number, link: number, finished: boolean) => void, + onerror?: (error: Error) => void +} + /** * Base generator, to be extended */ export class BaseGenerator { - /** - * - * @param {object} opts - * @param {string} opts.quality - * @param {WritableStream} opts.file - * @param {string} opts.title - * @param {string} opts.id - * @param {string} opts.language - * @param {string} opts.author - * @param {string|Date} opts.updatedAt - * @param {Chapter[]} opts.chapters - * @param {(chapter: number, link: number, finished: boolean) => void} [opts.callback] - * @param {(error: Error) => void} [opts.onerror] - */ - constructor(opts) { + opts: Opts; + constructor(opts: Opts) { this.opts = opts; this.opts.quality = "data"; } @@ -83,9 +82,9 @@ export class BaseGenerator { * @param {number} link * @param {boolean} finished */ - callback(chapter = -1, link = -1, finished = false) { + callback(chapter: string | number = -1, link: number = -1, finished = false) { if(this.opts.callback) { - this.opts.callback(chapter, parseInt(link), finished); + this.opts.callback(chapter, Number(link), finished); } } } \ No newline at end of file diff --git a/src/lib/util/generateEpub.js b/src/lib/util/generateEpub.ts similarity index 75% rename from src/lib/util/generateEpub.js rename to src/lib/util/generateEpub.ts index 936e3b2..da53aeb 100644 --- a/src/lib/util/generateEpub.js +++ b/src/lib/util/generateEpub.ts @@ -8,6 +8,10 @@ const enc = new TextEncoder(); * Handles epub generation */ export class EpubGenerator extends BaseGenerator { + writer: WritableStreamDefaultWriter; + zip: Zip; + hashes: { hash: string, chapter: string }[]; + async generate() { this.writer = this.opts.file.getWriter(); this.zip = new Zip(); @@ -34,7 +38,7 @@ export class EpubGenerator extends BaseGenerator { chapter.links = data.urls; chapter.hashes = data.hashes; chapter.hash = data.hash; - this.hashes.push(...chapter.hashes); + this.hashes.push(...(chapter.hashes.map(t => ({ hash: t, chapter: chapterI })))); } } @@ -52,7 +56,7 @@ export class EpubGenerator extends BaseGenerator { for(const i in chapter.links) { let url = chapter.links[i]; let hash = chapter.hashes[i]; - this.callback(chapterI, i, false); + this.callback(chapterI, Number(i), false); const start = performance.now(); const res = await this.fetchImage(url, chapter); const image = new ZipPassThrough("OEBPS/" + hash); @@ -67,12 +71,13 @@ export class EpubGenerator extends BaseGenerator { url: url }); image.push(data, true); - const textContent = new ZipPassThrough("OEBPS/" + i + ".xhtml"); + let fileI = this.hashes.findIndex(t => t.hash === hash); + const textContent = new ZipPassThrough(`OEBPS/${fileI}.xhtml`); this.zip.add(textContent); textContent.push(enc.encode(` - Page ${i + 1} + Chapter ${chapterI} Page ${Number(i) + 1} @@ -80,7 +85,7 @@ export class EpubGenerator extends BaseGenerator { `), true); - this.callback(chapterI, i, true); + this.callback(chapterI, Number(i), true); } } @@ -113,28 +118,28 @@ export class EpubGenerator extends BaseGenerator { - ${this.opts.title} - ${this.opts.language || "en"} - ${this.opts.author} - ${this.opts.id} - Image + ${this.opts.title} + ${this.opts.language || "en"} + ${this.opts.author} + ${this.opts.id} + Image - ${this.opts.updatedAt.toString().split("+")[0]}Z - pre-paginated - portrait - landscape + ${this.opts.updatedAt.toString().split("+")[0]}Z + pre-paginated + portrait + landscape - ${this.hashes.map((t, i) => ` `).join("\n")} + ${this.hashes.map((t, i) => ` `).join("\n")} ${this.hashes.map((t, i) => ` `).join("\n")} - + ${this.hashes.map((t, i) => ` `).join("\n")} - + `), true); @@ -142,6 +147,7 @@ export class EpubGenerator extends BaseGenerator { toc() { const ncx = new ZipPassThrough("OEBPS/toc.ncx"); + this.zip.add(ncx); ncx.push(enc.encode(` @@ -159,14 +165,14 @@ export class EpubGenerator extends BaseGenerator { - ${this.opts.chapters.map((t, i) => t.links.map((link, i) => ` - + ${this.opts.chapters.map((t, i) => ` + - ${this.opts.title} Chapter ${t.number} Page ${i + 1} + ${this.opts.title} Chapter ${t.number} - + - `)).flat().join("\n")} + `).flat().join("\n")} `), true); } diff --git a/tsconfig.json b/tsconfig.json index 3a34de7..f1db826 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,6 @@ "$lib/*": ["src/lib/*"] } }, - "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"], + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte", "src/**/*.ts"], "extends": "./.svelte-kit/tsconfig.json" } \ No newline at end of file