DictionaryIndex: JMdict in SQLite, answering Candidate lookups #8

Closed
opened 2026-08-10 09:25:51 +00:00 by aiko · 1 comment
Owner

Parent

#1

What to build

The plugin gains a dictionary. The jmdict-eng archive from jmdict-simplified is embedded in the dll as a resource; on first start the plugin expands it and builds a SQLite database under its data dir, keyed to the JMdict version so a restart with an unchanged dictionary skips the build entirely.

An authenticated data endpoint takes a batch of Candidate Headwords and returns the Entry for each one that exists: readings, senses, part of speech per sense, misc tags (sl, col, net-sl, vulg), and priority. It returns them in no particular order and filters nothing — ranking belongs to the browser (ADR 0006).

While the build is running the endpoint reports a building state rather than failing, so the phone can say what is happening instead of showing an error.

This slice is server-only and verifiable with curl. Nothing on the phone changes.

Acceptance criteria

  • jmdict-eng ships inside the dll; the deploy loop is still just the dll and meta.json
  • First start builds the database; a second start with the same JMdict version does not rebuild
  • A version change rebuilds, and the stale database is not left behind
  • Posting a batch of Headwords returns one Entry each for those JMdict holds, and nothing for those it does not
  • Entries carry readings, senses, per-sense part of speech, misc tags, and priority
  • The endpoint reports a distinguishable building state while the build runs
  • The endpoint requires the same Jellyfin authentication as the existing data endpoints
  • Tests cover the module boundary — Headwords in, Entries out — against a small fixture dictionary, not the real 214k-entry build

Blocked by

None - can start immediately

## Parent #1 ## What to build The plugin gains a dictionary. The `jmdict-eng` archive from jmdict-simplified is embedded in the dll as a resource; on first start the plugin expands it and builds a SQLite database under its data dir, keyed to the JMdict version so a restart with an unchanged dictionary skips the build entirely. An authenticated data endpoint takes a batch of Candidate Headwords and returns the Entry for each one that exists: readings, senses, part of speech per sense, misc tags (`sl`, `col`, `net-sl`, `vulg`), and priority. It returns them in no particular order and filters nothing — ranking belongs to the browser (ADR 0006). While the build is running the endpoint reports a building state rather than failing, so the phone can say what is happening instead of showing an error. This slice is server-only and verifiable with curl. Nothing on the phone changes. ## Acceptance criteria - [ ] `jmdict-eng` ships inside the dll; the deploy loop is still just the dll and `meta.json` - [ ] First start builds the database; a second start with the same JMdict version does not rebuild - [ ] A version change rebuilds, and the stale database is not left behind - [ ] Posting a batch of Headwords returns one Entry each for those JMdict holds, and nothing for those it does not - [ ] Entries carry readings, senses, per-sense part of speech, misc tags, and priority - [ ] The endpoint reports a distinguishable building state while the build runs - [ ] The endpoint requires the same Jellyfin authentication as the existing data endpoints - [ ] Tests cover the module boundary — Headwords in, Entries out — against a small fixture dictionary, not the real 214k-entry build ## Blocked by None - can start immediately
Author
Owner

This was generated by AI during triage.

Merged to main in 168b131.

The jmdict-eng 3.6.2 archive is embedded in the dll and streamed into SQLite under the plugin data dir on first start, keyed to the JMdict version. POST Kurageyomi/api/Entries takes a batch of Candidate Headwords and returns Entries — readings, senses, per-sense part of speech, misc tags, priority — unordered and unfiltered, per ADR 0006.

Measured against the real archive: 4.4s build, 62MB database. はし returns 8 Entries; 食べる comes back [v1,vt] with priority. The deploy loop is still just the dll and meta.json; the dll is now 11.5MB.

Covered by DictionaryIndexTests and EntriesEndpointTests against a small fixture dictionary — the suite never touches the real 214k-entry build.

One acceptance criterion was wrong and was corrected: "returns one Entry each" contradicts "filters nothing", since JMdict holds eight words under はし and picking one is ranking. It returns all Entries per Headword, flat.

Carried to #13: Microsoft.Data.Sqlite is not shipped in the plugin — it resolves at runtime from Jellyfin's own copy. That is what keeps the deploy to one dll, and it is unverified on a real server.

> *This was generated by AI during triage.* Merged to `main` in 168b131. The `jmdict-eng` 3.6.2 archive is embedded in the dll and streamed into SQLite under the plugin data dir on first start, keyed to the JMdict version. `POST Kurageyomi/api/Entries` takes a batch of Candidate Headwords and returns Entries — readings, senses, per-sense part of speech, misc tags, priority — unordered and unfiltered, per ADR 0006. Measured against the real archive: **4.4s build, 62MB database**. `はし` returns 8 Entries; `食べる` comes back `[v1,vt]` with priority. The deploy loop is still just the dll and `meta.json`; the dll is now 11.5MB. Covered by `DictionaryIndexTests` and `EntriesEndpointTests` against a small fixture dictionary — the suite never touches the real 214k-entry build. **One acceptance criterion was wrong and was corrected:** "returns one Entry each" contradicts "filters nothing", since JMdict holds eight words under `はし` and picking one is ranking. It returns all Entries per Headword, flat. **Carried to #13:** `Microsoft.Data.Sqlite` is not shipped in the plugin — it resolves at runtime from Jellyfin's own copy. That is what keeps the deploy to one dll, and it is unverified on a real server.
aiko closed this issue 2026-08-10 10:59:35 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mobrule/kurageyomi#8
No description provided.