Novel userscript's client-side latest-chapter scan is still scoped to the derived slug (lnw) #91
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Follow-up from #89 (part of #80 / #77).
lightnovelworld.latestChapterFromAnchors(anchors, seriesId)inuserscript/novel-bookmark.user.jsbuildslightnovelworld\.net/<seriesId>-chapter-([0-9.]+)/— the same scoping the backend Poll is dropping in #87, but on the client side.Since #89,
seriesIdis the Series slug read from the page pointer, not the Chapter Slug. On a divergent novel the two differ (immortality-simulatorvs chapter addresses undermy-longevity-simulation), so the client-side scan matches zero anchors and the background latest-chapter check yields nothing for exactly the novels this work exists to fix. On the split novel it happens to still work, because the higher range is published under the Series slug.Impact is limited: the backend Poll is the authority for Latest Chapter, and it will be unscoped after #87. The client-side check is an optimisation that refreshes between polls, so the failure mode is staleness between polls, not a wrong value.
Deliberately left out of #89's scope rather than smuggled in. The fix likely mirrors #87: match any chapter-shaped address on the host, with whatever the client-side equivalent of the
wpd-threadstruncation needs to be — the userscript scans anchors it has already extracted, so whether the comment-poisoning risk applies there needs checking before copying the backend's approach.Problem Statement
A Reader tracking a lightnovelworld novel whose chapters are published under more than one Chapter Slug sees the userscript's own latest-chapter check contribute nothing. Since #89 the stored
series_idis the Series slug read from the page pointer, while chapter addresses carry a Chapter Slug; the client scan scopes its anchor match to the stored slug, so on exactly the divergent novels this line of work exists to fix it matches zero anchors and yields no Latest Chapter.The failure is silent and the value is never wrong — the backend Poll is the authority for Latest Chapter and #87 already unscoped it there. What the Reader gets is staleness between polls, on one Site, on the subset of novels that were already the hardest case.
Solution
Remove the client-side latest-chapter scan for lightnovelworld rather than porting #87's fix to it. The Poll refreshes a lightnovelworld Series roughly four times more often than the client ever can (poll cooldown one hour, plain-TLS fetcher, no per-navigation gating; client throttle four hours, one Series per navigation), so the client scan on this Site is an optimisation that optimises nothing while carrying a shared-row poisoning risk that fixing it would require defending.
novelfull's client scan is untouched, as are all four manga Sites.
User Stories
Implementation Decisions
latestChapterFromAnchorsfrom the lightnovelworld adapter in the novel userscript. Do not stub it to return null: absence is what the fetch guard keys off, and a stub would keep the background fetch happening.Testing Decisions
A good test here asserts what the script computes for a Site, not which functions exist on an adapter object. Asserting that a property is
undefinedpins the implementation shape and passes for the wrong reasons; asserting that no anchor set produces a Latest Chapter for this Site pins the behaviour a Reader and a shared row actually depend on.--testsuite for the novel script, driving the script's module exports — the same seam that already covers the adapter scans, the max-chapter helper and the stale-row repair. No new seam, no new file, no test framework.node --check userscript/novel-bookmark.user.jsandnode --test userscript/test/novel-logic.test.js. No backend run is needed; the manga suite should stay green untouched.Out of Scope
Further Notes
Measured facts behind the decision, so it can be re-argued against numbers rather than intuition:
Acceptance criteria:
node --check userscript/novel-bookmark.user.jsandnode --test userscript/test/novel-logic.test.jspassImplemented per the spec on this ticket — branch ticket/91-client-lnw-scan-removed, PR #93.
lightnovelworld.latestChapterFromAnchorsdeleted, not stubbed: absence is what the background-fetch guard keys off, so no Series page is fetched and no freshness timestamp is recorded for this Site.computeLatestChapteryields null for an adapter without a scanner and is exported as the test seam; both call paths (on-page + background) go dead for this Site.userscript/AGENTS.mdrecords that the client performs no latest-chapter scan for this Site, and why (the Poll's one-hour cooldown dominates the client's four-hour throttle; the wpdiscuz thread is a public write surface).30/30 novel tests pass — the old lnw scan test was replaced with a
computeLatestChapterpin asserting no anchor set yields a Latest Chapter for lightnovelworld, comment-shaped anchors included, plus a novelfull positive proving the removal is Site-local. Manga suite 35/35,node --checkclean. All seven acceptance criteria met.Known gap, accepted in the spec: standing on a lightnovelworld Series page no longer records the newest chapter on sight, so Latest Chapter is up to one poll cooldown (1h) stale on non-divergent novels; on divergent novels that path already yielded nothing.