refactor: split main runtime handlers into focused modules

This commit is contained in:
2026-02-19 21:27:42 -08:00
parent 45c326db6d
commit 4193a6ce8e
49 changed files with 4357 additions and 832 deletions

View File

@@ -0,0 +1,65 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {
createOnWillQuitCleanupHandler,
createRestoreWindowsOnActivateHandler,
createShouldRestoreWindowsOnActivateHandler,
} from './app-lifecycle-actions';
test('on will quit cleanup handler runs all cleanup steps', () => {
const calls: string[] = [];
const cleanup = createOnWillQuitCleanupHandler({
destroyTray: () => calls.push('destroy-tray'),
stopConfigHotReload: () => calls.push('stop-config'),
restorePreviousSecondarySubVisibility: () => calls.push('restore-sub'),
unregisterAllGlobalShortcuts: () => calls.push('unregister-shortcuts'),
stopSubtitleWebsocket: () => calls.push('stop-ws'),
stopTexthookerService: () => calls.push('stop-texthooker'),
destroyYomitanParserWindow: () => calls.push('destroy-yomitan-window'),
clearYomitanParserState: () => calls.push('clear-yomitan-state'),
stopWindowTracker: () => calls.push('stop-tracker'),
destroyMpvSocket: () => calls.push('destroy-socket'),
clearReconnectTimer: () => calls.push('clear-reconnect'),
destroySubtitleTimingTracker: () => calls.push('destroy-subtitle-tracker'),
destroyImmersionTracker: () => calls.push('destroy-immersion'),
destroyAnkiIntegration: () => calls.push('destroy-anki'),
destroyAnilistSetupWindow: () => calls.push('destroy-anilist-window'),
clearAnilistSetupWindow: () => calls.push('clear-anilist-window'),
destroyJellyfinSetupWindow: () => calls.push('destroy-jellyfin-window'),
clearJellyfinSetupWindow: () => calls.push('clear-jellyfin-window'),
stopJellyfinRemoteSession: () => calls.push('stop-jellyfin-remote'),
});
cleanup();
assert.equal(calls.length, 19);
assert.equal(calls[0], 'destroy-tray');
assert.equal(calls[calls.length - 1], 'stop-jellyfin-remote');
});
test('should restore windows on activate requires initialized runtime and no windows', () => {
let initialized = false;
let windowCount = 1;
const shouldRestore = createShouldRestoreWindowsOnActivateHandler({
isOverlayRuntimeInitialized: () => initialized,
getAllWindowCount: () => windowCount,
});
assert.equal(shouldRestore(), false);
initialized = true;
assert.equal(shouldRestore(), false);
windowCount = 0;
assert.equal(shouldRestore(), true);
});
test('restore windows on activate recreates windows then syncs visibility', () => {
const calls: string[] = [];
const restore = createRestoreWindowsOnActivateHandler({
createMainWindow: () => calls.push('main'),
createInvisibleWindow: () => calls.push('invisible'),
updateVisibleOverlayVisibility: () => calls.push('visible-sync'),
updateInvisibleOverlayVisibility: () => calls.push('invisible-sync'),
});
restore();
assert.deepEqual(calls, ['main', 'invisible', 'visible-sync', 'invisible-sync']);
});