readest/apps/readest-app
Huang Xin 2d37bbfc2e
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (rust) (push) Waiting to run
Publish Docker image / build (linux/amd64, ubuntu-latest) (push) Waiting to run
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm) (push) Waiting to run
Publish Docker image / merge (push) Blocked by required conditions
Build with Nix / tests (push) Waiting to run
PR checks / nix_flake_check (push) Waiting to run
PR checks / rust_lint (push) Waiting to run
PR checks / koplugin_rust_lint (push) Waiting to run
PR checks / build_web_app (push) Waiting to run
PR checks / test_web_app (1) (push) Waiting to run
PR checks / test_web_app (2) (push) Waiting to run
PR checks / test_extensions (push) Waiting to run
PR checks / build_tauri_app (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
Deploy to vercel on merge / build_and_deploy (push) Waiting to run
fix(kosync): send and read FB2 positions in crengine's FictionBook form (#6905)
* fix(kosync): send and read FB2 positions in crengine's FictionBook form

Readest sent KOReader an EPUB-style /body/DocFragment[N]/body/... XPointer
for FB2 books. crengine reads FB2 natively and builds no DocFragments, so
it couldn't resolve the pointer and KOReader went to the cover. The other
direction rejected KOReader's /FictionBook/... pointers and fell back to
the percentage.

xcfi now maps FB2 both ways: foliate's section for each child of the first
<body> (image, title, epigraph, section) to /FictionBook/body[1]/<tag>[N],
counted per tag the way crengine does, each notes body to body[N], and
foliate's renamed elements back to their FB2 tags (kept as each element's
first class). The push sites (KOSync, Readest progress and notes sync,
BookOrbit notes) pass the book format; range note pulls go through the new
getCFIFromXPointerRange so FB2 highlights from KOReader resolve too.
isXPointerProgress accepts /FictionBook pointers.

Verified against crengine itself: xpointer-oracle.lua (now FB2-aware) run
in the KOReader emulator on a new FB2 fixture dumped all 108 visible words;
xcfi.crengine-oracle.test.ts converts every word both ways exactly as
crengine writes it. Without the change xcfi.fb2.test.ts fails with
"expected '/body/DocFragment[4]/body/section/p[1]/text().4' to be
'/FictionBook/body[1]/section[1]/p[1]/text().4'", the notes-body pull
throws "Unsupported format for spine index extraction", and
kosyncProgress.test.ts fails with "expected false to be true". Related
xcfi, KOSync, progress, notes and BookOrbit suites pass (333 tests);
pnpm lint passes. Not run: a KOSync round trip on a device, and the
reporter's book.

Reported by email to support.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(kosync): cover one-body FB2 books and a leading body-level image

CREngine in the KOReader emulator writes /FictionBook/body/... (no index)
for an FB2 book with one body, and /FictionBook/body[1]/... when it also
has a notes body. Either form resolves in either book. It puts a leading
body-level image at /FictionBook/body/image.0.

A new one-body fixture (an image and a title before two sections) and its
oracle dump (19 words) add the following checks:
- every word converts both ways exactly as CREngine writes it;
- Readest writes body without an index for the one-body book;
- the leading image is /FictionBook/body/image in the one-body book and
  /FictionBook/body[1]/image in the book with notes;
- /FictionBook/body/image.0, /FictionBook/body[1]/image.0 and
  /FictionBook/body[1]/image[1] open section 0 in both books;
- both body forms open the same paragraph in the one-body book.

The code already did all of this, so nothing fails on this branch. With
the body step forced to body[1], three tests fail, e.g. expected
"/FictionBook/body/section[2]/p/text().2", received
"/FictionBook/body[1]/section[2]/p/text().2", and the oracle reports
"Readest -> KOReader: 19/19 mismatches".

Related xcfi, KOSync, progress, notes and BookOrbit suites pass
(164 tests), and pnpm lint passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 02:31:33 +08:00
..
.agents
.claude chore(agent): lessons from 2026-10-14 to 10-15 (#6842) 2026-10-18 17:42:12 +02:00
bench feat(library): add scoped full text search with fuzzy and nearby modes (#5389) 2026-08-01 21:24:31 +02:00
data/wordlens feat(wordlens): Traditional Chinese hints and an English→Arabic pack (#6303) 2026-09-19 16:49:10 +02:00
docs chore(agent): maintenance loops with a Reply Desk, lessons and acceptance rules (#6796) 2026-10-14 16:00:36 +02:00
e2e fix(reader): remove note bubbles when deleting highlights (#6545) 2026-10-02 07:19:11 +02:00
extensions fix(windows): stop the PDF preview pane from freezing Explorer, closes #6590 (#6594) 2026-10-03 13:36:14 +02:00
public fix(i18n): improve Turkish translations and add missing keys (#6830) 2026-10-15 14:20:51 +02:00
scripts build(android): ship per-ABI APKs (arm64, armv7, legacy) instead of universal (#6772) 2026-10-13 19:33:05 +02:00
src fix(kosync): send and read FB2 positions in crengine's FictionBook form (#6905) 2026-10-19 02:31:33 +08:00
src-tauri fix(epub): bound native zip entry reads during import (#6817) 2026-10-18 17:25:13 +02:00
workers
.env chore(auth): point clients at the Supabase project URL (#6729) 2026-10-12 13:12:32 +02:00
.env.local.example
.env.tauri
.env.tauri.example fix(api): validate DeepL and AI gateway request limits (#6818) 2026-10-18 17:28:59 +02:00
.env.web
.env.web.example fix(api): validate DeepL and AI gateway request limits (#6818) 2026-10-18 17:28:59 +02:00
.gitignore fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
AGENTS.md chore(agent): maintenance loops with a Reply Desk, lessons and acceptance rules (#6796) 2026-10-14 16:00:36 +02:00
CLAUDE.md
components.json feat(ui): migrate to daisyUI 5 and Tailwind CSS 4 (#5884) 2026-08-26 16:09:41 +02:00
DESIGN.md fix(windows): draw the missing window frame on Windows 10 (#6399) 2026-09-28 18:48:56 +02:00
i18n-langs.json feat(i18n): add Georgian translations (#5763) 2026-08-17 12:21:10 +02:00
i18next-scanner.config.cjs
LESSONS.md chore(agent): lessons from 2026-10-14 to 10-15 (#6842) 2026-10-18 17:42:12 +02:00
next.config.mjs fix(build): keep music-metadata out of the web server bundle (#6699) 2026-10-10 06:32:09 +02:00
open-next.config.ts
package.json fix(deps): resolve open Dependabot alerts (#6813) 2026-10-15 07:59:43 +02:00
pdfjs.d.ts fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
playwright.config.ts
postcss.config.mjs feat(ui): migrate to daisyUI 5 and Tailwind CSS 4 (#5884) 2026-08-26 16:09:41 +02:00
PRODUCT.md feat(reader): Notebook as a linked writing workspace (#5928) 2026-08-28 21:18:17 +02:00
raw-loader.d.ts
release-notes.json release: version 0.12.16 (#6779) 2026-10-14 00:33:31 +02:00
skills-lock.json
TODOS.md feat(reader): Notebook as a linked writing workspace (#5928) 2026-08-28 21:18:17 +02:00
tsconfig.json fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
vite.config.ts fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
vitest.android.config.mts
vitest.browser.config.mts fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
vitest.config.mts fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
vitest.env.mts
vitest.setup.ts feat(tts): custom OpenAI-compatible TTS services (#6746) 2026-10-13 14:33:28 +02:00
vitest.tauri.config.mts fix(build): repair the Docker and Nix builds after #6368 (#6379) 2026-09-23 15:13:35 +02:00
vitest.tauri.setup.ts
wdio.conf.ts
worker.ts feat(tts): move Readest Voice into its own service (#6732) 2026-10-12 15:10:19 +02:00
wrangler.toml feat(tts): move Readest Voice into its own service (#6732) 2026-10-12 15:10:19 +02:00