diff --git a/plugins/english/lnori.ts b/plugins/english/lnori.ts index 93c0a17ad..b3cdc401b 100644 --- a/plugins/english/lnori.ts +++ b/plugins/english/lnori.ts @@ -9,7 +9,7 @@ class LnorisPlugin implements Plugin.PluginBase { name = 'LNORI'; icon = 'src/en/lnori/icon.png'; site = 'https://lnori.com/'; - version = '1.0.0'; + version = '1.0.1'; private async getLibraryNovels(): Promise< { @@ -168,9 +168,21 @@ class LnorisPlugin implements Plugin.PluginBase { }; const volumeUrls = Object.keys(volumeMap); - const volumePromises = volumeUrls.map(async volUrl => { - const fullVolUrl = this.site.replace(/\/$/, '') + volUrl; - const volHtml = await fetchText(fullVolUrl); + + /** + * Volume pages weigh ~0.5MB each and a long series has dozens, so + * building the chapter list used to download and fully parse ~15MB at + * once — about a minute of blank screen on a phone, and one failed + * request failed the whole novel. The chapter names live in the page's + * ', start); + if (end === -1) return undefined; + return html.slice(start, end + ''.length); + }; + + const CONCURRENT_VOLUMES = 4; + const chapters2D: Plugin.ChapterItem[][] = []; + for (let i = 0; i < volumeUrls.length; i += CONCURRENT_VOLUMES) { + const batch = volumeUrls.slice(i, i + CONCURRENT_VOLUMES); + const results = await Promise.all( + batch.map(async volUrl => { + const fullVolUrl = this.site.replace(/\/$/, '') + volUrl; + const volHtml = await fetchText(fullVolUrl); + + const toc = sliceToc(volHtml); + if (toc) { + const fromToc = parseVolume(volUrl, toc, true); + if (fromToc) { + return fromToc; + } + } + return parseVolume(volUrl, volHtml, false) ?? []; + }), + ); + chapters2D.push(...results); + } - const chapters2D = await Promise.all(volumePromises); const chapters = chapters2D.flat(); novel.chapters = chapters.map((chap, idx) => ({