diff --git a/userscript/novel-bookmark.user.js b/userscript/novel-bookmark.user.js index 0241f11..847647e 100644 --- a/userscript/novel-bookmark.user.js +++ b/userscript/novel-bookmark.user.js @@ -218,12 +218,6 @@ } return { type: "other" }; }, - latestChapterFromAnchors(anchors, seriesId) { - return maxChapter( - anchors, - new RegExp("lightnovelworld\\.net/" + escapeRe(seriesId) + "-chapter-([0-9.]+)/") - ); - }, }; const ADAPTERS = [novelfull, lightnovelworld]; @@ -342,10 +336,11 @@ // Highest chapter the site lists, or null when the markup yields nothing. // seriesId is only consulted by adapters whose pages carry other series' - // chapter links; the rest ignore it. + // chapter links. An adapter without a scanner (lightnovelworld — see the + // AGENTS.md entry) yields null, not an error. function computeLatestChapter(site, anchors, seriesId) { const a = adapterFor(site); - return a ? a.latestChapterFromAnchors(anchors, seriesId) : null; + return a && a.latestChapterFromAnchors ? a.latestChapterFromAnchors(anchors, seriesId) : null; } function currentSite() { @@ -861,6 +856,14 @@ const site = currentSite(); if (!site) return; + // A Site with no client scanner (lightnovelworld) is refreshed by the Poll + // on a cooldown shorter than the client throttle; fetching its pages here + // would be a megabyte-scale request whose result is discarded. Skipping + // before the due filter records no freshness timestamp and consumes no + // per-navigation batch slot. + const adapter = adapterFor(site); + if (!adapter.latestChapterFromAnchors) return; + const checked = loadLastChecked(); const now = Date.now(); const due = state.list @@ -871,7 +874,6 @@ .slice(0, LATEST_CHECK_BATCH); if (due.length === 0) return; - const adapter = adapterFor(site); for (const bm of due) { // Recorded even when the fetch fails, so a broken series is retried on // the next throttle window rather than on every single page load. @@ -1750,7 +1752,7 @@ // Exposes pure logic only — see userscript/test/novel-logic.test.js. // ============================================================ if (typeof window === "undefined" && typeof module === "object" && module.exports) { - module.exports = { novelfull, lightnovelworld, anchorsFromHTML, statusOf, kindOf, maxChapter, escapeRe, repairLnwStaleRow }; + module.exports = { novelfull, lightnovelworld, anchorsFromHTML, statusOf, kindOf, maxChapter, escapeRe, computeLatestChapter, repairLnwStaleRow }; } // ============================================================