docs(latest): correct the browser-site comments the comix change made stale

Review findings from #98: BrowserFetcher's doc still described two sites and
two read shapes, Get's doc enumerated them a second time, and the Fallback
field doc omitted comix. The comix fixture comment now records the live
in-tab body it was re-checked against.
This commit is contained in:
2026-08-16 12:08:28 +07:00
parent 86160c164a
commit f000cc7eaa
3 changed files with 15 additions and 12 deletions
+8 -8
View File
@@ -44,10 +44,11 @@ var comixSeriesPathRe = regexp.MustCompile(`^/title/[^/?#]+/?$`)
// sync that break silently and separately. The browser's own cookie jar
// persists across polls, so the challenge is solved once every few hours.
//
// The two sites differ in how the chapter list is read: kagane serves it from
// a JSON API that must be called from inside the page (so the request carries
// the clearance cookie), while novelfull renders it into the HTML so the
// cleared DOM is the payload.
// The three sites differ in what a cleared tab is asked for: kagane fetches a
// JSON API from inside the page (the list exists nowhere else), comix fetches
// its own Series URL from inside the page (the served HTML carries the facts,
// and rendering the SPA costs ~65 requests instead of one), and novelfull
// renders its list into the HTML so the cleared DOM is the payload.
type BrowserFetcher struct {
allocCtx context.Context
cancel context.CancelFunc
@@ -91,10 +92,9 @@ func (f *BrowserFetcher) Close() {
}
// Get navigates to seriesURL, lets any challenge resolve, then reads the
// payload the Site's registry entry describes — kagane's chapter-list API from
// inside the page so the request carries the clearance cookie, novelfull's
// served HTML. The returned body is whatever the Site's chapter list lives in,
// which is what the entry's LatestChapter parse expects.
// payload the Site's registry entry describes (the shapes are listed on
// BrowserFetcher). The returned body is whatever the Site's chapter list lives
// in, which is what the entry's LatestChapter parse expects.
func (f *BrowserFetcher) Get(ctx context.Context, seriesURL string) (string, int, error) {
var body string
// Sorted order (browserBackedSites sorts) makes dispatch deterministic:
+3 -3
View File
@@ -47,9 +47,9 @@ type browserRead struct {
// Done reports whether the payload arrived.
Done func(body string) bool
// Fallback allows the plain-TLS fetcher when no browser is configured.
// False skips the Site instead. kagane is false — a plain fetch would
// only ever retrieve a challenge page — and novelfull is true, because
// its challenge is a live time-varying fact (AGENTS.md).
// False skips the Site instead. kagane and comix are false — a plain fetch
// would only ever retrieve a challenge page — and novelfull is true,
// because its challenge is a live time-varying fact (AGENTS.md).
Fallback bool
}
+4 -1
View File
@@ -44,7 +44,10 @@ const challengeFixture = `<!DOCTYPE html><html><head><title>Just a moment...</ti
//
// Still the right fixture after comix moved behind the challenge (#98): the
// browser read is an in-tab fetch of the Series URL, so the body a poll parses
// is this same server-rendered HTML, not a rendered DOM.
// is this same server-rendered HTML, not a rendered DOM. Confirmed against a
// live cleared tab 2026-08-16 (TestSmokeComix): the in-tab fetch returned
// 24793 bytes of server-rendered HTML that these same parses read a chapter
// and a cover out of.
const comixSeriesFixture = `
{"firstChapterUrl":"/title/n8we-dungeons-and-crayons/5038739-chapter-1","latestChapterUrl":"/title/n8we-dungeons-and-crayons/11139891-chapter-80"},
{""manga","recommended","n8we",1]":{"items":[{"latestChapterUrl":"/title/qqwrm-full-time-awakening/99999999-chapter-999"}]}