Remove the client latest-chapter scan for lightnovelworld (#91)

The scan was scoped to the stored series_id, which since #89 is the Series
slug while chapter addresses carry a Chapter Slug, so on divergent novels it
matched zero anchors. The Poll refreshes lnw Series on a one-hour cooldown,
four times faster than the client throttle, so the scan optimised nothing
while its unscoped alternative would have let a public wpdiscuz comment
anchor write a Latest Chapter every Reader of the row shares. Delete the
adapter method; the shared computation yields null for an adapter without a
scanner, and the background refresh skips the Site before the due filter so
no Series page is fetched and no freshness timestamp is recorded.
This commit is contained in:
2026-08-11 20:23:51 +07:00
parent e7e22a12a5
commit 3f897b6a65
+12 -10
View File
@@ -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 };
}
// ============================================================