Autoplay priming called onSubtitleChange after a cache miss, which only asks
whether the text is new. When the miss came from an invalidation (mining a
card while the line is on screen) the text was unchanged, so nothing was
scheduled and the line stayed unannotated for as long as it was displayed.
refreshCurrentSubtitle checks the cache generation as well, so it re-tokenizes
for the new generation; the resume fallback is kept for the case where it
genuinely has nothing to do.
refreshCurrentSubtitle also returned false for empty text while a run was in
flight, even though that run goes on to emit the empty subtitle. It now
reports the pending emit so callers do not release the prefetch pause early.
The priming tests now drive the real subtitle processing controller instead of
a stub. The previous stub encoded the wrong assumption about unchanged text
and so could not catch either bug.
The repeated-subtitle pause leak was only fixed for ordinary subtitle
changes. Startup autoplay priming and visible-overlay priming pause the same
way and also ignored whether any tokenization was scheduled, so a cache miss
on text the controller already holds (mining a card while the line is on
screen) left prefetching idle for the rest of the cue.
Pause and release are now one operation via pausePrefetchUntilEmit, and both
controller entry points report whether an emit is expected. A repeat arriving
while a run is already in flight keeps the pause, since that run still emits.
Also invalidate the character dictionary lookups centrally from the sync
completion handler instead of at three manager call sites. Ordinary selection
sync never invalidated them, so a stale non-null name candidate list could
skip a newly added name for up to five seconds; a missing list falls back to
the exhaustive scan, but a stale one does not. Ordering matters: the
invalidation runs before the subtitle refreshes so they re-tokenize against
the new dictionary content.
Docs: subtitle-overlay-priming no longer claims every subtitle change calls
onSeek().
- drop the duplicate parseText full parse per line; the termsFind scanner walk
is now authoritative and emits its own unparsed filler runs (parseText kept
only as error fallback)
- install scan helpers once per parser window (__subminerYomitanScan) instead
of re-shipping ~500 lines of script per subtitle line
- persist termsFind results across lines in a window-scoped LRU keyed by
substring, invalidated via a cache epoch on dictionary/settings changes
- skip lookups at punctuation/whitespace positions and cap the shrinking-window
retry ladder at 4 lookups per position
- build tokenizer runtime deps once (JLPT lookup cache never hit before; mecab
availability check ran per line)
- stop restarting the prefetch run on every subtitle change; resume prefetch
only after the tokenized payload lands, not on provisional raw emits
- add per-stage debug timings (scanMs/mecabMs/frequencyMs/annotateMs)