useFeeds.js had no concept of a sync/reload being in flight, so two passive mark-as-read paths could race a wholesale fetchData()/sync() list replacement: - handleIntersection() (list-view scroll marking) - markCurrentArticleRead() (article-view display/paging marking) Both are now gated by a refcount (activeSyncCount/beginSync/endSync/ isSyncing), mirroring the existing pendingReadCounts pattern for the same class of overlapping-async problem. A refcount rather than a boolean because sync() nests fetchData() inside it, and fetchData() can also run independently while a sync() elsewhere is still in flight. Reads suppressed during a sync/reload aren't dropped: their ids are queued and flushed (marked read, and swept out of the list) once every in-flight fetchData()/sync() call has finished. The explicit "Mark all read" action is left ungated, since it's a deliberate, already-confirmed action rather than a passive side effect. 87/87 frontend tests passing.
rss
This template should help get you started developing with Vue 3 in Vite.
Recommended IDE Setup
VSCode + Volar (and disable Vetur) + TypeScript Vue Plugin (Volar).
Customize configuration
See Vite Configuration Reference.
Project Setup
npm install
Compile and Hot-Reload for Development
npm run dev
Compile and Minify for Production
npm run build
Lint with ESLint
npm run lint