diff --git a/backlog/tasks/task-81 - Tokenization-performance-disable-yomitan-mecab-and-persistent-local-mecab.md b/backlog/tasks/task-81 - Tokenization-performance-disable-yomitan-mecab-and-persistent-local-mecab.md index 9ef26bd..009622a 100644 --- a/backlog/tasks/task-81 - Tokenization-performance-disable-yomitan-mecab-and-persistent-local-mecab.md +++ b/backlog/tasks/task-81 - Tokenization-performance-disable-yomitan-mecab-and-persistent-local-mecab.md @@ -4,7 +4,7 @@ title: 'Tokenization performance: disable Yomitan MeCab parser, gate local MeCab status: Done assignee: [] created_date: '2026-03-02 07:44' -updated_date: '2026-03-02 09:20' +updated_date: '2026-03-02 20:34' labels: [] dependencies: [] priority: high @@ -45,6 +45,8 @@ Implemented tokenizer latency optimizations: - added regression tests for Yomitan parse flag, MeCab warmup gating, and persistent/idle lifecycle behavior; - fixed tokenization warmup gate so first-use warmup completion is sticky (`tokenizationWarmupCompleted`) and sequential `tokenizeSubtitle` calls no longer re-run Yomitan/dictionary warmup path; - added regression coverage in `src/main/runtime/composers/mpv-runtime-composer.test.ts` for sequential tokenize calls (`warmup` side effects run once); +- post-review critical fix: treat Yomitan default-profile Anki server sync `no-change` as successful check, so `lastSyncedYomitanAnkiServer` is cached and expensive sync checks do not repeat on every subtitle line; +- added regression assertion in `src/core/services/tokenizer/yomitan-parser-runtime.test.ts` for `updated: false` path returning sync success; - validated with targeted tests and `tsc --noEmit`. diff --git a/src/core/services/tokenizer/yomitan-parser-runtime.test.ts b/src/core/services/tokenizer/yomitan-parser-runtime.test.ts index c3eb09d..142c4ed 100644 --- a/src/core/services/tokenizer/yomitan-parser-runtime.test.ts +++ b/src/core/services/tokenizer/yomitan-parser-runtime.test.ts @@ -44,15 +44,19 @@ test('syncYomitanDefaultAnkiServer updates default profile server when script re assert.equal(infoLogs.length, 1); }); -test('syncYomitanDefaultAnkiServer returns false when script reports no change', async () => { +test('syncYomitanDefaultAnkiServer returns true when script reports no change', async () => { const deps = createDeps(async () => ({ updated: false })); + let infoLogCount = 0; - const updated = await syncYomitanDefaultAnkiServer('http://127.0.0.1:8766', deps, { + const synced = await syncYomitanDefaultAnkiServer('http://127.0.0.1:8766', deps, { error: () => undefined, - info: () => undefined, + info: () => { + infoLogCount += 1; + }, }); - assert.equal(updated, false); + assert.equal(synced, true); + assert.equal(infoLogCount, 0); }); test('syncYomitanDefaultAnkiServer logs and returns false on script failure', async () => { diff --git a/src/core/services/tokenizer/yomitan-parser-runtime.ts b/src/core/services/tokenizer/yomitan-parser-runtime.ts index ba24854..705f50d 100644 --- a/src/core/services/tokenizer/yomitan-parser-runtime.ts +++ b/src/core/services/tokenizer/yomitan-parser-runtime.ts @@ -846,7 +846,11 @@ export async function syncYomitanDefaultAnkiServer( logger.info?.(`Updated Yomitan default profile Anki server to ${normalizedTargetServer}`); return true; } - return false; + const checkedWithoutUpdate = + typeof result === 'object' && + result !== null && + (result as { updated?: unknown }).updated === false; + return checkedWithoutUpdate; } catch (err) { logger.error('Failed to sync Yomitan default profile Anki server:', (err as Error).message); return false; diff --git a/src/main.ts b/src/main.ts index b48bdb1..e08183a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2627,7 +2627,7 @@ async function syncYomitanDefaultProfileAnkiServer(): Promise { return; } - const updated = await syncYomitanDefaultAnkiServerCore( + const synced = await syncYomitanDefaultAnkiServerCore( targetUrl, { getYomitanExt: () => appState.yomitanExt, @@ -2654,8 +2654,7 @@ async function syncYomitanDefaultProfileAnkiServer(): Promise { }, ); - if (updated) { - logger.info(`Yomitan default profile Anki server set to ${targetUrl}`); + if (synced) { lastSyncedYomitanAnkiServer = targetUrl; } }