From a9ddf3d80464a7c0555414795f3ba914361ee1cf Mon Sep 17 00:00:00 2001 From: Sulthan Zaki Date: Mon, 27 Jul 2026 17:20:43 +0700 Subject: [PATCH] docs: record the userscript retry queue --- CLAUDE.md | 17 +++++++++++++++-- userscript/manga-bookmark.user.js | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index dfc7fcb..9768195 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -78,11 +78,24 @@ Bromite userscript (isolated world, per-site adapters, localStorage cache) 1. **Site adapters** — one per host, `detect(location, document)` returns page `type` + IDs. Identify type/IDs from **URL regex** (most stable); pull `title`/`cover` from **`og:title`/`og:image` meta tags**, not CSS classes. 2. **API client** — `apiGet/apiPut/apiDelete` with bearer header; `localStorage` key `mangabm:cache` for instant render + offline fallback. 3. **Progress logic** — auto-upsert `last_chapter` only when `chapterNum >= stored last_chapter_num` (re-reading old chapters must not regress progress; unparseable -> set current). Manual panel override forces any value. -4. **UI** — rendered inside a **Shadow DOM** root to isolate from site CSS +4. **Retry queue** — every write goes through `pushBookmark`/`pushDelete`, so a + failed mutation is parked in `localStorage` (`mangabm:queue`) and replayed on + the next navigation, reconnect, or `refresh()`. Entries are markers + (`{key, op, sendStatus, attempts}`), never payloads — the body is read from + the cache at send time, so one entry per key gives ordering and coalescing for + free. `sendStatus` is **sticky**: while an archive is pending, later writes to + that key keep carrying the bucket, which is what stops a successful + in-between write from silently un-archiving the series. `refresh()` drains + before it fetches and overlays anything still pending, so the list never + flaps. A 400 drops the entry, a 401 aborts the pass and keeps the queue, and + transient failures retry to a cap of 10. Latest-chapter writes deliberately + stay out of the queue. See + `docs/superpowers/specs/2026-07-27-offline-retry-queue-design.md`. +5. **UI** — rendered inside a **Shadow DOM** root to isolate from site CSS (critical on mobile). Three tabs (All / Favourites / Archived) and a row of link chips to the web UI and both manga sites; `WEB_BASE` sits in the CONFIG block next to `API_BASE`. -5. **SPA navigation** — Asura is Astro, client-routed on the comic/chapter pages: patch `history.pushState`/`replaceState` + listen `popstate`, re-run `detect()` on URL change so auto-update fires without reload. Demonic uses classic reloads (initial `document-idle` run suffices). +6. **SPA navigation** — Asura is Astro, client-routed on the comic/chapter pages: patch `history.pushState`/`replaceState` + listen `popstate`, re-run `detect()` on URL change so auto-update fires without reload. Demonic uses classic reloads (initial `document-idle` run suffices). ### Live URL shapes (verified 2026-07-26, may drift — re-check against live pages before trusting) diff --git a/userscript/manga-bookmark.user.js b/userscript/manga-bookmark.user.js index 5b7d483..efc9be8 100644 --- a/userscript/manga-bookmark.user.js +++ b/userscript/manga-bookmark.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Manga Bookmark Sync // @namespace mangabm -// @version 1.3.0 +// @version 1.4.0 // @description Track read progress on Asura & Demonic and sync to a self-hosted backend. Bromite-compatible (no GM_* APIs). // @author you // @match https://asuracomic.net/*