Give each concurrent writer a distinct title, length, and term text so the
assertion identifies which writer's snapshot survived instead of only
checking that the file parses with the expected entry count.
The streamed snapshot writer keyed its temp file on the pid alone, so two
overlapping writes for the same media (a manual generate racing auto-sync)
streamed into one file and tore it; add a per-write sequence suffix.
Term banks were stringified 10k entries at a time, measured at ~38MB and
~135ms per bank on a real merged dictionary. Halving that block matters
more than the write itself: at 2k entries the longest event-loop stall in
a merged build drops from ~135ms to 28ms.
Generating and importing a large character dictionary froze the whole
app long enough for the compositor to raise its application-not-
responding dialog over the player. Multi-hundred-MB snapshot JSONs and
the merged archive were read, written, and zipped synchronously on the
main process, and the character image / name-candidate caches re-read
every cached snapshot synchronously inside a lookup whenever the
snapshot directory changed.
- snapshot reads/writes are async; writes stream in slices and rename
into place so a crash or concurrent writer cannot tear a snapshot
- buildDictionaryZip yields between ~8MB slices and CRC32 uses the
native zlib implementation
- the image and name-candidate lookup caches rebuild in the background
and serve the previous index while the rebuild runs
Worst main-thread stall over a 1.4GB snapshot set drops from 8s+ to
under 700ms.
Electron AppImages export LD_LIBRARY_PATH pointing at bundled libraries
whose stale libnotify kills the system notify-send with a symbol lookup
error, permanently disabling in-place replacement and forcing the
flickering Electron close-and-reopen fallback. Drop the override from
the child environment so the system binary resolves its own libraries.
- Add overlayBody override to ConfiguredStatusNotificationOptions so overlay/OSD/desktop can diverge
- Extract getSubsyncStatusNotificationOptions() to strip the ASCII spinner frame from the overlay card (OSD keeps it since it renders the raw spinner)
- Add tests for spinner stripping and subsync result notifications
The query test suite opened each temp database with SQLite's defaults
(rollback journal, synchronous=FULL) while the runtime opens them via
applyPragmas (WAL, synchronous=NORMAL). Every statement therefore ran as
its own fsync-ing transaction.
That is unnoticeable on a fast local disk but dominates on CI: the file
took 40.6s there versus 0.5s locally, and the 106-insert case
'getVocabularyStats pages past hidden rows' crossed the 5s per-test
timeout and failed the quality gate.
Open test databases through a helper that applies the same pragmas as
production, so the tests exercise the runtime's actual SQLite
configuration instead of a slower one.
- Add TsukiHime and AniSkip to feature table; note xz dependency
- Clarify Anki+AnkiConnect is required to mine, not to run
- Rework Windows setup with winget/scoop commands and PATH steps
- Note ffmpeg has no path-override setting, unlike mpv
- Fix screenshot alt text and installation.md anchor link
- Generate config.example.jsonc with a Linux socket path instead of Windows, so the example stays reproducible across platforms
- Document TsukiHime config (`tsukihime.*`), maturity-based known-word highlighting keys, and other config surfaces missing from the reference
- Correct secondary-subtitle auto-load defaults and Anki field-matching (case-insensitive) claims
- Expand Windows installation guide with winget/Scoop package tables and manual PATH setup
- Add docs-site/links.test.ts to catch broken internal links and heading-anchor mismatches
- Fix stale cross-references in jimaku-integration.md and demos.md
- Add formatRofiPrompt to trim trailing whitespace and append a single space, keeping the prompt from running into the input field
- Apply it across all rofi -p usages in picker.ts and history-command.ts
- Add tests for formatRofiPrompt edge cases (empty/whitespace-only prompts)
- Extract buildHistoryEntryActions to build the series action menu, now including a previous-episode option alongside replay/next/browse/quit
- Update docs and changelog entry to describe the new option
- Add tests covering previous/replay/next ordering and omission when last watched file is missing