Files
bookorbit/client
neon 5527852b4b fix(reader): follow inflections so define reaches a real definition
Looking up a plural showed only "plural of candelabra", and looking up "candelabra" added a Latin
declension line beneath it. Both come from the Wiktionary path, which English lookups fall through
to whenever api.dictionaryapi.dev fails; it 502s often enough that readers hit it regularly.

Read only the requested language section. Wiktionary keys a page by language and returns every
language that spells the word the same way, so iterating Object.values() merged Latin into English.
This was not a rare edge case: of 14 common words sampled, 13 carried foreign senses, and "fare"
rendered 129 definitions of which 18 were English.

Follow an inflection gloss to the word that carries the meaning, bounded to depth 2, three lemma
fetches and a visited set for cycles. Only a pointer in the leading sense of its block is followed,
which is what separates "candelabras" from the "simple past of bake" buried at sense 10 of "book".
A lemma that fails to resolve is dropped rather than failing the lookup. Detection requires every
word before "of" to be grammatical, so "Informal form of address used by juniors" stays a
definition rather than sending the reader to "address".

Drop script and style elements before reading textContent. Wiktionary ships an inline <style> with
some senses and its CSS was rendering as part of the definition, visibly so on "fare".

Merge blocks that share a part of speech and cap each at five senses, so a resolved chain stays
readable and the popover stops keying a v-for on a duplicated part of speech.

Pointer following is deliberately English-only. fr.wiktionary writes "pluriel de chat", and
guessing at sixteen languages of grammar vocabulary is not worth it; non-English lookups still gain
the language filter. The Free Dictionary path is also unchanged for "candelabras", where its own
gloss "A single candelabrum." is circular but not a recognizable pointer.

Closes #1020
2026-08-16 04:43:22 +00:00
..
…

BookOrbit - Client

Vue 3 SPA built with Vite and Tailwind CSS v4.

Running

From the repo root: pnpm dev (starts both server and client).

Client only: pnpm dev (from this directory). Runs at http://localhost:5173.

The Vite dev server proxies /api and /socket.io requests to the backend at localhost:3000.

IDE setup

  • VS Code: Install the Vue (Official) extension. Disable Vetur if installed.
  • WebStorm / IntelliJ: Vue support is built in. Enable TypeScript service for .vue files.
  • Browser: Install Vue.js devtools and enable Custom Object Formatters in DevTools settings.

Project layout

src/
├── features/           Feature modules (one folder per domain)
│   ├── auth/           Login, registration, password reset
│   ├── book/           Book detail, covers, metadata
│   ├── library/        Library management
│   ├── collection/     Book collections
│   ├── smart-scope/           Saved search views
│   ├── scanner/        Scan progress UI
│   ├── reader/         Book reader (epub, pdf, cbz)
│   ├── settings/       User settings
│   └── admin/          Admin panel (users, roles, settings)
├── components/         Shared components (header, sidebar, icons)
│   └── ui/             Reusable UI primitives (button, dialog, etc.)
├── composables/        Global composables
├── views/              Route-level page components
├── router/             Vue Router config and guards
├── lib/                Utilities (api client, helpers)
├── stores/             Pinia stores (theme only - prefer composables)
└── assets/             CSS, fonts, static assets

Testing

pnpm test:unit          # run unit tests
pnpm test:cov           # run unit tests with coverage

Key conventions

  • All components use <script setup lang="ts"> (Composition API only).
  • Feature state lives in composables (features/<name>/composables/use*.ts), not global stores.
  • HTTP calls use the native fetch API via src/lib/api.ts.
  • Styling with Tailwind CSS v4 utility classes. Theme tokens are CSS variables in src/assets/main.css.
  • Icons from @lucide/vue only.
  • Shared types imported from @bookorbit/types.