From 585fea972c6da776ff911efce43efcd1f533006e Mon Sep 17 00:00:00 2001 From: sudacode Date: Sat, 14 Feb 2026 13:48:05 -0800 Subject: [PATCH] refactor(main): extract IPC registration wiring into main/ipc-runtime module --- src/main.ts | 157 +++++++++++++++++++--------------------- src/main/ipc-runtime.ts | 28 +++++++ 2 files changed, 103 insertions(+), 82 deletions(-) create mode 100644 src/main/ipc-runtime.ts diff --git a/src/main.ts b/src/main.ts index f7d7e23..6b9aae0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -97,7 +97,6 @@ import { createCliCommandDepsRuntimeService, createOverlayManagerService, createFieldGroupingOverlayRuntimeService, - createIpcDepsRuntimeService, createNumericShortcutRuntimeService, createOverlayContentMeasurementStoreService, createOverlayShortcutRuntimeHandlers, @@ -124,9 +123,7 @@ import { openYomitanSettingsWindow, playNextSubtitleRuntimeService, refreshOverlayShortcutsRuntimeService, - registerAnkiJimakuIpcRuntimeService, registerGlobalShortcutsService, - registerIpcHandlersService, registerOverlayShortcutsService, replayCurrentSubtitleRuntimeService, resolveJimakuApiKeyService, @@ -163,9 +160,7 @@ import type { SubsyncRuntimeDeps } from "./core/services/subsync-runner-service" import { applyRuntimeOptionResultRuntimeService } from "./core/services/runtime-options-ipc-service"; import { createRuntimeOptionsIpcDeps, - createAnkiJimakuIpcRuntimeServiceDeps, createCliCommandRuntimeServiceDeps, - createMainIpcRuntimeServiceDeps, createSubsyncRuntimeDeps, } from "./main/dependencies"; import { @@ -173,6 +168,10 @@ import { createAppReadyRuntimeDeps as createAppReadyRuntimeDepsBuilder, } from "./main/app-lifecycle"; import { handleMpvCommandFromIpcRuntime } from "./main/ipc-mpv-command"; +import { + registerAnkiJimakuIpcRuntimeServices, + registerMainIpcRuntimeServices, +} from "./main/ipc-runtime"; import { createStartupBootstrapRuntimeDeps } from "./main/startup"; import { ConfigService, @@ -1532,81 +1531,75 @@ const runtimeOptionsIpcDeps = createRuntimeOptionsIpcDeps({ showMpvOsd, }); -registerIpcHandlersService( - createIpcDepsRuntimeService( - createMainIpcRuntimeServiceDeps({ - getInvisibleWindow: () => overlayManager.getInvisibleWindow(), - getMainWindow: () => overlayManager.getMainWindow(), - getVisibleOverlayVisibility: () => overlayManager.getVisibleOverlayVisible(), - getInvisibleOverlayVisibility: () => overlayManager.getInvisibleOverlayVisible(), - onOverlayModalClosed: (modal) => { - handleOverlayModalClosed(modal as OverlayHostedModal); - }, - openYomitanSettings: () => openYomitanSettings(), - quitApp: () => app.quit(), - toggleVisibleOverlay: () => toggleVisibleOverlay(), - tokenizeCurrentSubtitle: () => tokenizeSubtitle(appState.currentSubText), - getCurrentSubtitleAss: () => appState.currentSubAssText, - getMpvSubtitleRenderMetrics: () => appState.mpvSubtitleRenderMetrics, - getSubtitlePosition: () => loadSubtitlePosition(), - getSubtitleStyle: () => getResolvedConfig().subtitleStyle ?? null, - saveSubtitlePosition: (position: unknown) => - saveSubtitlePosition(position as SubtitlePosition), - getMecabTokenizer: () => appState.mecabTokenizer, - handleMpvCommand: (command: (string | number)[]) => - handleMpvCommandFromIpc(command), - getKeybindings: () => appState.keybindings, - getSecondarySubMode: () => appState.secondarySubMode, - getMpvClient: () => appState.mpvClient, - runSubsyncManual: (request: unknown) => - runSubsyncManualFromIpc(request as SubsyncManualRunRequest), - getAnkiConnectStatus: () => appState.ankiIntegration !== null, - getRuntimeOptions: () => getRuntimeOptionsState(), - setRuntimeOption: runtimeOptionsIpcDeps.setRuntimeOption, - cycleRuntimeOption: runtimeOptionsIpcDeps.cycleRuntimeOption, - reportOverlayContentBounds: (payload: unknown) => { - overlayContentMeasurementStore.report(payload); - }, - }), - ), -); +registerMainIpcRuntimeServices({ + getInvisibleWindow: () => overlayManager.getInvisibleWindow(), + getMainWindow: () => overlayManager.getMainWindow(), + getVisibleOverlayVisibility: () => overlayManager.getVisibleOverlayVisible(), + getInvisibleOverlayVisibility: () => overlayManager.getInvisibleOverlayVisible(), + onOverlayModalClosed: (modal) => { + handleOverlayModalClosed(modal as OverlayHostedModal); + }, + openYomitanSettings: () => openYomitanSettings(), + quitApp: () => app.quit(), + toggleVisibleOverlay: () => toggleVisibleOverlay(), + tokenizeCurrentSubtitle: () => tokenizeSubtitle(appState.currentSubText), + getCurrentSubtitleAss: () => appState.currentSubAssText, + getMpvSubtitleRenderMetrics: () => appState.mpvSubtitleRenderMetrics, + getSubtitlePosition: () => loadSubtitlePosition(), + getSubtitleStyle: () => getResolvedConfig().subtitleStyle ?? null, + saveSubtitlePosition: (position: unknown) => + saveSubtitlePosition(position as SubtitlePosition), + getMecabTokenizer: () => appState.mecabTokenizer, + handleMpvCommand: (command: (string | number)[]) => + handleMpvCommandFromIpc(command), + getKeybindings: () => appState.keybindings, + getSecondarySubMode: () => appState.secondarySubMode, + getMpvClient: () => appState.mpvClient, + runSubsyncManual: (request: unknown) => + runSubsyncManualFromIpc(request as SubsyncManualRunRequest), + getAnkiConnectStatus: () => appState.ankiIntegration !== null, + getRuntimeOptions: () => getRuntimeOptionsState(), + setRuntimeOption: runtimeOptionsIpcDeps.setRuntimeOption, + cycleRuntimeOption: runtimeOptionsIpcDeps.cycleRuntimeOption, + reportOverlayContentBounds: (payload: unknown) => { + overlayContentMeasurementStore.report(payload); + }, +}); -registerAnkiJimakuIpcRuntimeService( - createAnkiJimakuIpcRuntimeServiceDeps({ - patchAnkiConnectEnabled: (enabled: boolean) => { - configService.patchRawConfig({ ankiConnect: { enabled } }); - }, - getResolvedConfig: () => getResolvedConfig(), - getRuntimeOptionsManager: () => appState.runtimeOptionsManager, - getSubtitleTimingTracker: () => appState.subtitleTimingTracker, - getMpvClient: () => appState.mpvClient, - getAnkiIntegration: () => appState.ankiIntegration, - setAnkiIntegration: (integration: AnkiIntegration | null) => { - appState.ankiIntegration = integration; - }, - showDesktopNotification, - createFieldGroupingCallback: () => createFieldGroupingCallback(), - broadcastRuntimeOptionsChanged: () => broadcastRuntimeOptionsChanged(), - getFieldGroupingResolver: () => getFieldGroupingResolver(), - setFieldGroupingResolver: ( - resolver: ((choice: KikuFieldGroupingChoice) => void) | null, - ) => setFieldGroupingResolver(resolver), - parseMediaInfo: (mediaPath: string | null) => - parseMediaInfo(resolveMediaPathForJimaku(mediaPath)), - getCurrentMediaPath: () => appState.currentMediaPath, - jimakuFetchJson: ( - endpoint: string, - query?: Record, - ): Promise> => - jimakuFetchJson(endpoint, query), - getJimakuMaxEntryResults: () => getJimakuMaxEntryResults(), - getJimakuLanguagePreference: () => getJimakuLanguagePreference(), - resolveJimakuApiKey: () => resolveJimakuApiKey(), - isRemoteMediaPath: (mediaPath: string) => isRemoteMediaPath(mediaPath), - downloadToFile: ( - url: string, - destPath: string, - headers: Record, - ) => downloadToFile(url, destPath, headers), - }), -); +registerAnkiJimakuIpcRuntimeServices({ + patchAnkiConnectEnabled: (enabled: boolean) => { + configService.patchRawConfig({ ankiConnect: { enabled } }); + }, + getResolvedConfig: () => getResolvedConfig(), + getRuntimeOptionsManager: () => appState.runtimeOptionsManager, + getSubtitleTimingTracker: () => appState.subtitleTimingTracker, + getMpvClient: () => appState.mpvClient, + getAnkiIntegration: () => appState.ankiIntegration, + setAnkiIntegration: (integration: AnkiIntegration | null) => { + appState.ankiIntegration = integration; + }, + showDesktopNotification, + createFieldGroupingCallback: () => createFieldGroupingCallback(), + broadcastRuntimeOptionsChanged: () => broadcastRuntimeOptionsChanged(), + getFieldGroupingResolver: () => getFieldGroupingResolver(), + setFieldGroupingResolver: ( + resolver: ((choice: KikuFieldGroupingChoice) => void) | null, + ) => setFieldGroupingResolver(resolver), + parseMediaInfo: (mediaPath: string | null) => + parseMediaInfo(resolveMediaPathForJimaku(mediaPath)), + getCurrentMediaPath: () => appState.currentMediaPath, + jimakuFetchJson: ( + endpoint: string, + query?: Record, + ): Promise> => + jimakuFetchJson(endpoint, query), + getJimakuMaxEntryResults: () => getJimakuMaxEntryResults(), + getJimakuLanguagePreference: () => getJimakuLanguagePreference(), + resolveJimakuApiKey: () => resolveJimakuApiKey(), + isRemoteMediaPath: (mediaPath: string) => isRemoteMediaPath(mediaPath), + downloadToFile: ( + url: string, + destPath: string, + headers: Record, + ) => downloadToFile(url, destPath, headers), +}); diff --git a/src/main/ipc-runtime.ts b/src/main/ipc-runtime.ts new file mode 100644 index 0000000..c2197e7 --- /dev/null +++ b/src/main/ipc-runtime.ts @@ -0,0 +1,28 @@ +import { + createIpcDepsRuntimeService, + registerAnkiJimakuIpcRuntimeService, + registerIpcHandlersService, +} from "../core/services"; +import { + createAnkiJimakuIpcRuntimeServiceDeps, + AnkiJimakuIpcRuntimeServiceDepsParams, + createMainIpcRuntimeServiceDeps, + MainIpcRuntimeServiceDepsParams, +} from "./dependencies"; + +export function registerMainIpcRuntimeServices( + params: MainIpcRuntimeServiceDepsParams, +): void { + registerIpcHandlersService( + createIpcDepsRuntimeService(createMainIpcRuntimeServiceDeps(params)), + ); +} + +export function registerAnkiJimakuIpcRuntimeServices( + params: AnkiJimakuIpcRuntimeServiceDepsParams, +): void { + registerAnkiJimakuIpcRuntimeService( + createAnkiJimakuIpcRuntimeServiceDeps(params), + ); +} +