refactor(character-dictionary): extract applyCharacterDictionarySelection helper

- Add `applyCharacterDictionarySelection` in its own module with injected deps
- Catches sync errors and emits a warning instead of propagating
- Remove duplicated inline logic from IPC and CLI startup handlers in main.ts
- Add unit test covering sync-failure resilience
This commit is contained in:
2026-04-25 20:03:38 -07:00
parent a05a698774
commit de19c40118
3 changed files with 75 additions and 12 deletions

View File

@@ -534,6 +534,7 @@ import {
resolveSubtitleSourcePath,
} from './main/runtime/subtitle-prefetch-source';
import { createSubtitlePrefetchInitController } from './main/runtime/subtitle-prefetch-init';
import { applyCharacterDictionarySelection } from './main/character-dictionary-selection';
import { codecToExtension, getSubsyncConfig } from './subsync/utils';
if (process.platform === 'linux') {
@@ -4861,12 +4862,16 @@ const { registerIpcRuntimeHandlers } = composeIpcRuntimeHandlers({
retryAnilistQueueNow: () => processNextAnilistRetryUpdate(),
getCharacterDictionarySelection: () =>
characterDictionaryRuntime.getManualSelectionSnapshot(),
setCharacterDictionarySelection: async (mediaId: number) => {
const result = await characterDictionaryRuntime.setManualSelection({ mediaId });
resetAnilistMediaGuessState();
await characterDictionaryAutoSyncRuntime.runSyncNow();
return result;
},
setCharacterDictionarySelection: async (mediaId: number) =>
applyCharacterDictionarySelection(
{ mediaId },
{
setManualSelection: (request) => characterDictionaryRuntime.setManualSelection(request),
resetAnilistMediaGuessState,
runSyncNow: () => characterDictionaryAutoSyncRuntime.runSyncNow(),
warn: (message, error) => logger.warn(message, error),
},
),
appendClipboardVideoToQueue: () => appendClipboardVideoToQueue(),
...playlistBrowserMainDeps,
getImmersionTracker: () => appState.immersionTracker,
@@ -4951,12 +4956,14 @@ const { handleCliCommand, handleInitialArgs } = composeCliStartupHandlers({
},
getCharacterDictionarySelection: async (targetPath?: string) =>
characterDictionaryRuntime.getManualSelectionSnapshot(targetPath),
setCharacterDictionarySelection: async (request) => {
const result = await characterDictionaryRuntime.setManualSelection(request);
resetAnilistMediaGuessState();
await characterDictionaryAutoSyncRuntime.runSyncNow();
return result;
},
setCharacterDictionarySelection: async (request) =>
applyCharacterDictionarySelection(request, {
setManualSelection: (selectionRequest) =>
characterDictionaryRuntime.setManualSelection(selectionRequest),
resetAnilistMediaGuessState,
runSyncNow: () => characterDictionaryAutoSyncRuntime.runSyncNow(),
warn: (message, error) => logger.warn(message, error),
}),
runJellyfinCommand: (argsFromCommand: CliArgs) => runJellyfinCommand(argsFromCommand),
runStatsCommand: (argsFromCommand: CliArgs, source: CliCommandSource) =>
runStatsCliCommand(argsFromCommand, source),