mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-01 06:22:44 -08:00
refactor: extract overlay bootstrap runtime wiring
This commit is contained in:
@@ -6,7 +6,7 @@ Read first. Keep concise.
|
|||||||
| ------------ | -------------- | ---------------------------------------------------- | --------- | ------------------------------------- | ---------------------- |
|
| ------------ | -------------- | ---------------------------------------------------- | --------- | ------------------------------------- | ---------------------- |
|
||||||
| `codex-generate-minecard-image-20260220T112900Z-vsxr` | `codex-generate-minecard-image` | `Generate media fallbacks (GIF) from assets/minecard.webm and wire README/docs fallback markup` | `done` | `docs/subagents/agents/codex-generate-minecard-image-20260220T112900Z-vsxr.md` | `2026-02-20T11:35:30Z` |
|
| `codex-generate-minecard-image-20260220T112900Z-vsxr` | `codex-generate-minecard-image` | `Generate media fallbacks (GIF) from assets/minecard.webm and wire README/docs fallback markup` | `done` | `docs/subagents/agents/codex-generate-minecard-image-20260220T112900Z-vsxr.md` | `2026-02-20T11:35:30Z` |
|
||||||
| `codex-main` | `planner-exec` | `Fix frequency/N+1 regression in plugin --start flow` | `in_progress` | `docs/subagents/agents/codex-main.md` | `2026-02-19T19:36:46Z` |
|
| `codex-main` | `planner-exec` | `Fix frequency/N+1 regression in plugin --start flow` | `in_progress` | `docs/subagents/agents/codex-main.md` | `2026-02-19T19:36:46Z` |
|
||||||
| `codex-task85-20260219T233711Z-46hc` | `codex-task85` | `Resume TASK-85 maintainability refactor from latest handoff point` | `in_progress` | `docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md` | `2026-02-20T10:17:29Z` |
|
| `codex-task85-20260219T233711Z-46hc` | `codex-task85` | `Resume TASK-85 maintainability refactor from latest handoff point` | `in_progress` | `docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md` | `2026-02-20T11:06:51Z` |
|
||||||
| `codex-config-validation-20260219T172015Z-iiyf` | `codex-config-validation` | `Find root cause of config validation error for ~/.config/SubMiner/config.jsonc` | `completed` | `docs/subagents/agents/codex-config-validation-20260219T172015Z-iiyf.md` | `2026-02-19T17:26:17Z` |
|
| `codex-config-validation-20260219T172015Z-iiyf` | `codex-config-validation` | `Find root cause of config validation error for ~/.config/SubMiner/config.jsonc` | `completed` | `docs/subagents/agents/codex-config-validation-20260219T172015Z-iiyf.md` | `2026-02-19T17:26:17Z` |
|
||||||
| `codex-task85-20260219T233711Z-46hc` | `codex-task85` | `Resume TASK-85 maintainability refactor from latest handoff point` | `in_progress` | `docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md` | `2026-02-20T02:56:34Z` |
|
| `codex-task85-20260219T233711Z-46hc` | `codex-task85` | `Resume TASK-85 maintainability refactor from latest handoff point` | `in_progress` | `docs/subagents/agents/codex-task85-20260219T233711Z-46hc.md` | `2026-02-20T02:56:34Z` |
|
||||||
| `codex-anilist-deeplink-20260219T233926Z` | `anilist-deeplink` | `Fix external subminer:// AniList callback handling from browser` | `done` | `docs/subagents/agents/codex-anilist-deeplink-20260219T233926Z.md` | `2026-02-19T23:59:21Z` |
|
| `codex-anilist-deeplink-20260219T233926Z` | `anilist-deeplink` | `Fix external subminer:// AniList callback handling from browser` | `done` | `docs/subagents/agents/codex-anilist-deeplink-20260219T233926Z.md` | `2026-02-19T23:59:21Z` |
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
## Current Work (newest first)
|
## Current Work (newest first)
|
||||||
|
|
||||||
|
- [2026-02-20T11:06:51Z] progress: extracted overlay bootstrap composition from `src/main.ts` into `src/main/runtime/overlay-runtime-bootstrap-handlers.ts`; `main.ts` now creates `initializeOverlayRuntime` through `createOverlayRuntimeBootstrapHandlers(...)`.
|
||||||
|
- [2026-02-20T11:06:51Z] progress: added `src/main/runtime/overlay-runtime-bootstrap-handlers.test.ts` for composed bootstrap behavior.
|
||||||
|
- [2026-02-20T11:06:51Z] test: `bun run build` pass (expected macOS helper Swift cache fallback) + focused suites pass for `overlay-runtime-bootstrap-handlers*`, `overlay-runtime-bootstrap*`, `overlay-runtime-options*`, `overlay-window-runtime-handlers*`, `tray-runtime-handlers*`, and `cli-command-context-factory*` (8/8).
|
||||||
|
- [2026-02-20T11:06:51Z] scope: staging `src/main.ts`, new overlay bootstrap handlers module/tests, and subagent bookkeeping only.
|
||||||
- [2026-02-20T10:17:29Z] progress: extracted Yomitan settings opener composition from `src/main.ts` into `src/main/runtime/yomitan-settings-runtime.ts`; `main.ts` now uses `createYomitanSettingsRuntime(...)` and consumes `openYomitanSettings` from that runtime.
|
- [2026-02-20T10:17:29Z] progress: extracted Yomitan settings opener composition from `src/main.ts` into `src/main/runtime/yomitan-settings-runtime.ts`; `main.ts` now uses `createYomitanSettingsRuntime(...)` and consumes `openYomitanSettings` from that runtime.
|
||||||
- [2026-02-20T10:17:29Z] progress: added `src/main/runtime/yomitan-settings-runtime.test.ts` for composed runtime behavior.
|
- [2026-02-20T10:17:29Z] progress: added `src/main/runtime/yomitan-settings-runtime.test.ts` for composed runtime behavior.
|
||||||
- [2026-02-20T10:17:29Z] test: `bun run build` pass (expected macOS helper Swift cache fallback) + focused suites pass for `yomitan-settings-runtime*`, `yomitan-settings-opener*`, `yomitan-extension-runtime*`, `cli-command-context-factory*`, and `tray-runtime-handlers*` (7/7).
|
- [2026-02-20T10:17:29Z] test: `bun run build` pass (expected macOS helper Swift cache fallback) + focused suites pass for `yomitan-settings-runtime*`, `yomitan-settings-opener*`, `yomitan-extension-runtime*`, `cli-command-context-factory*`, and `tray-runtime-handlers*` (7/7).
|
||||||
|
|||||||
87
src/main.ts
87
src/main.ts
@@ -289,7 +289,6 @@ import {
|
|||||||
createBuildUpdateVisibleOverlayBoundsMainDepsHandler,
|
createBuildUpdateVisibleOverlayBoundsMainDepsHandler,
|
||||||
} from './main/runtime/overlay-window-layout-main-deps';
|
} from './main/runtime/overlay-window-layout-main-deps';
|
||||||
import { buildTrayMenuTemplateRuntime, resolveTrayIconPathRuntime } from './main/runtime/tray-runtime';
|
import { buildTrayMenuTemplateRuntime, resolveTrayIconPathRuntime } from './main/runtime/tray-runtime';
|
||||||
import { createInitializeOverlayRuntimeHandler } from './main/runtime/overlay-runtime-bootstrap';
|
|
||||||
import {
|
import {
|
||||||
createGetConfiguredShortcutsHandler,
|
createGetConfiguredShortcutsHandler,
|
||||||
createRefreshGlobalAndOverlayShortcutsHandler,
|
createRefreshGlobalAndOverlayShortcutsHandler,
|
||||||
@@ -381,14 +380,10 @@ import {
|
|||||||
import { createIpcRuntimeHandlers } from './main/runtime/ipc-runtime-handlers';
|
import { createIpcRuntimeHandlers } from './main/runtime/ipc-runtime-handlers';
|
||||||
import { createBuildMpvCommandFromIpcRuntimeMainDepsHandler } from './main/runtime/ipc-mpv-command-main-deps';
|
import { createBuildMpvCommandFromIpcRuntimeMainDepsHandler } from './main/runtime/ipc-mpv-command-main-deps';
|
||||||
import { createOverlayWindowRuntimeHandlers } from './main/runtime/overlay-window-runtime-handlers';
|
import { createOverlayWindowRuntimeHandlers } from './main/runtime/overlay-window-runtime-handlers';
|
||||||
import {
|
import { createOverlayRuntimeBootstrapHandlers } from './main/runtime/overlay-runtime-bootstrap-handlers';
|
||||||
createBuildInitializeOverlayRuntimeBootstrapMainDepsHandler,
|
|
||||||
} from './main/runtime/app-runtime-main-deps';
|
|
||||||
import { createTrayRuntimeHandlers } from './main/runtime/tray-runtime-handlers';
|
import { createTrayRuntimeHandlers } from './main/runtime/tray-runtime-handlers';
|
||||||
import { createYomitanExtensionRuntime } from './main/runtime/yomitan-extension-runtime';
|
import { createYomitanExtensionRuntime } from './main/runtime/yomitan-extension-runtime';
|
||||||
import { createYomitanSettingsRuntime } from './main/runtime/yomitan-settings-runtime';
|
import { createYomitanSettingsRuntime } from './main/runtime/yomitan-settings-runtime';
|
||||||
import { createBuildInitializeOverlayRuntimeOptionsHandler } from './main/runtime/overlay-runtime-options';
|
|
||||||
import { createBuildInitializeOverlayRuntimeMainDepsHandler } from './main/runtime/overlay-runtime-options-main-deps';
|
|
||||||
import {
|
import {
|
||||||
createOnWillQuitCleanupHandler,
|
createOnWillQuitCleanupHandler,
|
||||||
createRestoreWindowsOnActivateHandler,
|
createRestoreWindowsOnActivateHandler,
|
||||||
@@ -3082,49 +3077,47 @@ const yomitanExtensionRuntime = createYomitanExtensionRuntime({
|
|||||||
yomitanLoadInFlight = promise;
|
yomitanLoadInFlight = promise;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const buildInitializeOverlayRuntimeOptionsHandler = createBuildInitializeOverlayRuntimeOptionsHandler(
|
const { initializeOverlayRuntime: initializeOverlayRuntimeHandler } =
|
||||||
createBuildInitializeOverlayRuntimeMainDepsHandler({
|
createOverlayRuntimeBootstrapHandlers({
|
||||||
appState,
|
initializeOverlayRuntimeMainDeps: {
|
||||||
overlayManager: {
|
appState,
|
||||||
getVisibleOverlayVisible: () => overlayManager.getVisibleOverlayVisible(),
|
overlayManager: {
|
||||||
getInvisibleOverlayVisible: () => overlayManager.getInvisibleOverlayVisible(),
|
getVisibleOverlayVisible: () => overlayManager.getVisibleOverlayVisible(),
|
||||||
|
getInvisibleOverlayVisible: () => overlayManager.getInvisibleOverlayVisible(),
|
||||||
|
},
|
||||||
|
overlayVisibilityRuntime: {
|
||||||
|
updateVisibleOverlayVisibility: () => overlayVisibilityRuntime.updateVisibleOverlayVisibility(),
|
||||||
|
updateInvisibleOverlayVisibility: () =>
|
||||||
|
overlayVisibilityRuntime.updateInvisibleOverlayVisibility(),
|
||||||
|
},
|
||||||
|
overlayShortcutsRuntime: {
|
||||||
|
syncOverlayShortcuts: () => overlayShortcutsRuntime.syncOverlayShortcuts(),
|
||||||
|
},
|
||||||
|
getInitialInvisibleOverlayVisibility: () =>
|
||||||
|
configDerivedRuntime.getInitialInvisibleOverlayVisibility(),
|
||||||
|
createMainWindow: () => createMainWindow(),
|
||||||
|
createInvisibleWindow: () => createInvisibleWindow(),
|
||||||
|
registerGlobalShortcuts: () => registerGlobalShortcuts(),
|
||||||
|
updateVisibleOverlayBounds: (geometry) => updateVisibleOverlayBounds(geometry),
|
||||||
|
updateInvisibleOverlayBounds: (geometry) => updateInvisibleOverlayBounds(geometry),
|
||||||
|
getOverlayWindows: () => getOverlayWindows(),
|
||||||
|
getResolvedConfig: () => getResolvedConfig(),
|
||||||
|
showDesktopNotification,
|
||||||
|
createFieldGroupingCallback: () => createFieldGroupingCallback() as never,
|
||||||
|
getKnownWordCacheStatePath: () => path.join(USER_DATA_PATH, 'known-words-cache.json'),
|
||||||
},
|
},
|
||||||
overlayVisibilityRuntime: {
|
initializeOverlayRuntimeBootstrapDeps: {
|
||||||
updateVisibleOverlayVisibility: () => overlayVisibilityRuntime.updateVisibleOverlayVisibility(),
|
isOverlayRuntimeInitialized: () => appState.overlayRuntimeInitialized,
|
||||||
updateInvisibleOverlayVisibility: () =>
|
initializeOverlayRuntimeCore: (options) => initializeOverlayRuntimeCore(options as never),
|
||||||
overlayVisibilityRuntime.updateInvisibleOverlayVisibility(),
|
setInvisibleOverlayVisible: (visible) => {
|
||||||
|
overlayManager.setInvisibleOverlayVisible(visible);
|
||||||
|
},
|
||||||
|
setOverlayRuntimeInitialized: (initialized) => {
|
||||||
|
appState.overlayRuntimeInitialized = initialized;
|
||||||
|
},
|
||||||
|
startBackgroundWarmups: () => startBackgroundWarmups(),
|
||||||
},
|
},
|
||||||
overlayShortcutsRuntime: {
|
});
|
||||||
syncOverlayShortcuts: () => overlayShortcutsRuntime.syncOverlayShortcuts(),
|
|
||||||
},
|
|
||||||
getInitialInvisibleOverlayVisibility: () =>
|
|
||||||
configDerivedRuntime.getInitialInvisibleOverlayVisibility(),
|
|
||||||
createMainWindow: () => createMainWindow(),
|
|
||||||
createInvisibleWindow: () => createInvisibleWindow(),
|
|
||||||
registerGlobalShortcuts: () => registerGlobalShortcuts(),
|
|
||||||
updateVisibleOverlayBounds: (geometry) => updateVisibleOverlayBounds(geometry),
|
|
||||||
updateInvisibleOverlayBounds: (geometry) => updateInvisibleOverlayBounds(geometry),
|
|
||||||
getOverlayWindows: () => getOverlayWindows(),
|
|
||||||
getResolvedConfig: () => getResolvedConfig(),
|
|
||||||
showDesktopNotification,
|
|
||||||
createFieldGroupingCallback: () => createFieldGroupingCallback() as never,
|
|
||||||
getKnownWordCacheStatePath: () => path.join(USER_DATA_PATH, 'known-words-cache.json'),
|
|
||||||
})(),
|
|
||||||
);
|
|
||||||
const initializeOverlayRuntimeHandler = createInitializeOverlayRuntimeHandler(
|
|
||||||
createBuildInitializeOverlayRuntimeBootstrapMainDepsHandler({
|
|
||||||
isOverlayRuntimeInitialized: () => appState.overlayRuntimeInitialized,
|
|
||||||
initializeOverlayRuntimeCore: (options) => initializeOverlayRuntimeCore(options as never),
|
|
||||||
buildOptions: () => buildInitializeOverlayRuntimeOptionsHandler(),
|
|
||||||
setInvisibleOverlayVisible: (visible) => {
|
|
||||||
overlayManager.setInvisibleOverlayVisible(visible);
|
|
||||||
},
|
|
||||||
setOverlayRuntimeInitialized: (initialized) => {
|
|
||||||
appState.overlayRuntimeInitialized = initialized;
|
|
||||||
},
|
|
||||||
startBackgroundWarmups: () => startBackgroundWarmups(),
|
|
||||||
})(),
|
|
||||||
);
|
|
||||||
const { openYomitanSettings: openYomitanSettingsHandler } = createYomitanSettingsRuntime({
|
const { openYomitanSettings: openYomitanSettingsHandler } = createYomitanSettingsRuntime({
|
||||||
ensureYomitanExtensionLoaded: () => ensureYomitanExtensionLoaded(),
|
ensureYomitanExtensionLoaded: () => ensureYomitanExtensionLoaded(),
|
||||||
openYomitanSettingsWindow: ({ yomitanExt, getExistingWindow, setWindow }) => {
|
openYomitanSettingsWindow: ({ yomitanExt, getExistingWindow, setWindow }) => {
|
||||||
|
|||||||
66
src/main/runtime/overlay-runtime-bootstrap-handlers.test.ts
Normal file
66
src/main/runtime/overlay-runtime-bootstrap-handlers.test.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import { createOverlayRuntimeBootstrapHandlers } from './overlay-runtime-bootstrap-handlers';
|
||||||
|
|
||||||
|
test('overlay runtime bootstrap handlers compose options builder and bootstrap handler', () => {
|
||||||
|
const appState = {
|
||||||
|
backendOverride: null as string | null,
|
||||||
|
windowTracker: null as unknown,
|
||||||
|
subtitleTimingTracker: null as unknown,
|
||||||
|
mpvClient: null as unknown,
|
||||||
|
mpvSocketPath: '/tmp/mpv.sock',
|
||||||
|
runtimeOptionsManager: null as unknown,
|
||||||
|
ankiIntegration: null as unknown,
|
||||||
|
};
|
||||||
|
let initialized = false;
|
||||||
|
let invisibleOverlayVisible = false;
|
||||||
|
let warmupsStarted = 0;
|
||||||
|
|
||||||
|
const { initializeOverlayRuntime } = createOverlayRuntimeBootstrapHandlers({
|
||||||
|
initializeOverlayRuntimeMainDeps: {
|
||||||
|
appState,
|
||||||
|
overlayManager: {
|
||||||
|
getVisibleOverlayVisible: () => true,
|
||||||
|
getInvisibleOverlayVisible: () => false,
|
||||||
|
},
|
||||||
|
overlayVisibilityRuntime: {
|
||||||
|
updateVisibleOverlayVisibility: () => {},
|
||||||
|
updateInvisibleOverlayVisibility: () => {},
|
||||||
|
},
|
||||||
|
overlayShortcutsRuntime: {
|
||||||
|
syncOverlayShortcuts: () => {},
|
||||||
|
},
|
||||||
|
getInitialInvisibleOverlayVisibility: () => false,
|
||||||
|
createMainWindow: () => {},
|
||||||
|
createInvisibleWindow: () => {},
|
||||||
|
registerGlobalShortcuts: () => {},
|
||||||
|
updateVisibleOverlayBounds: () => {},
|
||||||
|
updateInvisibleOverlayBounds: () => {},
|
||||||
|
getOverlayWindows: () => [],
|
||||||
|
getResolvedConfig: () => ({}),
|
||||||
|
showDesktopNotification: () => {},
|
||||||
|
createFieldGroupingCallback: () => (async () => 'combined' as never),
|
||||||
|
getKnownWordCacheStatePath: () => '/tmp/known.json',
|
||||||
|
},
|
||||||
|
initializeOverlayRuntimeBootstrapDeps: {
|
||||||
|
isOverlayRuntimeInitialized: () => initialized,
|
||||||
|
initializeOverlayRuntimeCore: () => ({ invisibleOverlayVisible: true }),
|
||||||
|
setInvisibleOverlayVisible: (visible) => {
|
||||||
|
invisibleOverlayVisible = visible;
|
||||||
|
},
|
||||||
|
setOverlayRuntimeInitialized: (next) => {
|
||||||
|
initialized = next;
|
||||||
|
},
|
||||||
|
startBackgroundWarmups: () => {
|
||||||
|
warmupsStarted += 1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
initializeOverlayRuntime();
|
||||||
|
initializeOverlayRuntime();
|
||||||
|
|
||||||
|
assert.equal(invisibleOverlayVisible, true);
|
||||||
|
assert.equal(initialized, true);
|
||||||
|
assert.equal(warmupsStarted, 1);
|
||||||
|
});
|
||||||
30
src/main/runtime/overlay-runtime-bootstrap-handlers.ts
Normal file
30
src/main/runtime/overlay-runtime-bootstrap-handlers.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { createBuildInitializeOverlayRuntimeBootstrapMainDepsHandler } from './app-runtime-main-deps';
|
||||||
|
import { createInitializeOverlayRuntimeHandler } from './overlay-runtime-bootstrap';
|
||||||
|
import { createBuildInitializeOverlayRuntimeOptionsHandler } from './overlay-runtime-options';
|
||||||
|
import { createBuildInitializeOverlayRuntimeMainDepsHandler } from './overlay-runtime-options-main-deps';
|
||||||
|
|
||||||
|
type InitializeOverlayRuntimeMainDeps = Parameters<
|
||||||
|
typeof createBuildInitializeOverlayRuntimeMainDepsHandler
|
||||||
|
>[0];
|
||||||
|
type InitializeOverlayRuntimeBootstrapMainDeps = Parameters<
|
||||||
|
typeof createBuildInitializeOverlayRuntimeBootstrapMainDepsHandler
|
||||||
|
>[0];
|
||||||
|
|
||||||
|
export function createOverlayRuntimeBootstrapHandlers(deps: {
|
||||||
|
initializeOverlayRuntimeMainDeps: InitializeOverlayRuntimeMainDeps;
|
||||||
|
initializeOverlayRuntimeBootstrapDeps: Omit<InitializeOverlayRuntimeBootstrapMainDeps, 'buildOptions'>;
|
||||||
|
}) {
|
||||||
|
const buildInitializeOverlayRuntimeOptionsHandler = createBuildInitializeOverlayRuntimeOptionsHandler(
|
||||||
|
createBuildInitializeOverlayRuntimeMainDepsHandler(deps.initializeOverlayRuntimeMainDeps)(),
|
||||||
|
);
|
||||||
|
const initializeOverlayRuntime = createInitializeOverlayRuntimeHandler(
|
||||||
|
createBuildInitializeOverlayRuntimeBootstrapMainDepsHandler({
|
||||||
|
...deps.initializeOverlayRuntimeBootstrapDeps,
|
||||||
|
buildOptions: () => buildInitializeOverlayRuntimeOptionsHandler(),
|
||||||
|
})(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
initializeOverlayRuntime,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user