mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-28 06:22:45 -08:00
refactor: extract startup and initial args 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-20T11:06:51Z` |
|
| `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:14:14Z` |
|
||||||
| `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,11 @@
|
|||||||
|
|
||||||
## Current Work (newest first)
|
## Current Work (newest first)
|
||||||
|
|
||||||
|
- [2026-02-20T11:14:14Z] progress: extracted startup/app-lifecycle composition from `src/main.ts` into `src/main/runtime/startup-runtime-handlers.ts`; rewired `main.ts` to inject `createAppLifecycleRuntimeRunner` + `createStartupBootstrapRuntimeDeps` into `createStartupRuntimeHandlers(...)`.
|
||||||
|
- [2026-02-20T11:14:14Z] progress: extracted initial-args composition from `src/main.ts` into `src/main/runtime/initial-args-runtime-handler.ts`; `main.ts` now constructs `handleInitialArgsRuntimeHandler` with one runtime factory call.
|
||||||
|
- [2026-02-20T11:14:14Z] progress: added parity tests `src/main/runtime/startup-runtime-handlers.test.ts` and `src/main/runtime/initial-args-runtime-handler.test.ts` (fixing previous `node:sqlite` test-import leak by removing direct runtime imports from startup handler module).
|
||||||
|
- [2026-02-20T11:14:14Z] test: `bun run build` pass (expected macOS helper Swift cache fallback) + focused suites pass for `startup-runtime-handlers*`, `startup-lifecycle-main-deps*`, `startup-bootstrap-main-deps*`, `startup-bootstrap-deps-builder*`, `startup-warmups*`, `initial-args-runtime-handler*`, `initial-args-handler*`, `cli-command-context-factory*`, and `cli-command-prechecks*` (23/23).
|
||||||
|
- [2026-02-20T11:14:14Z] scope: staging `src/main.ts`, new startup/initial-args runtime handler modules + tests, and subagent bookkeeping only.
|
||||||
- [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: 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] 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] 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).
|
||||||
|
|||||||
113
src/main.ts
113
src/main.ts
@@ -243,8 +243,7 @@ import {
|
|||||||
createBuildStartJellyfinRemoteSessionMainDepsHandler,
|
createBuildStartJellyfinRemoteSessionMainDepsHandler,
|
||||||
createBuildStopJellyfinRemoteSessionMainDepsHandler,
|
createBuildStopJellyfinRemoteSessionMainDepsHandler,
|
||||||
} from './main/runtime/jellyfin-remote-session-main-deps';
|
} from './main/runtime/jellyfin-remote-session-main-deps';
|
||||||
import { createHandleInitialArgsHandler } from './main/runtime/initial-args-handler';
|
import { createInitialArgsRuntimeHandler } from './main/runtime/initial-args-runtime-handler';
|
||||||
import { createBuildHandleInitialArgsMainDepsHandler } from './main/runtime/initial-args-main-deps';
|
|
||||||
import { createHandleTexthookerOnlyModeTransitionHandler } from './main/runtime/cli-command-prechecks';
|
import { createHandleTexthookerOnlyModeTransitionHandler } from './main/runtime/cli-command-prechecks';
|
||||||
import { createBuildHandleTexthookerOnlyModeTransitionMainDepsHandler } from './main/runtime/cli-command-prechecks-main-deps';
|
import { createBuildHandleTexthookerOnlyModeTransitionMainDepsHandler } from './main/runtime/cli-command-prechecks-main-deps';
|
||||||
import {
|
import {
|
||||||
@@ -394,7 +393,6 @@ import {
|
|||||||
createBuildRestoreWindowsOnActivateMainDepsHandler,
|
createBuildRestoreWindowsOnActivateMainDepsHandler,
|
||||||
createBuildShouldRestoreWindowsOnActivateMainDepsHandler,
|
createBuildShouldRestoreWindowsOnActivateMainDepsHandler,
|
||||||
} from './main/runtime/app-lifecycle-main-activate';
|
} from './main/runtime/app-lifecycle-main-activate';
|
||||||
import { createBuildStartupBootstrapRuntimeFactoryDepsHandler } from './main/runtime/startup-bootstrap-deps-builder';
|
|
||||||
import {
|
import {
|
||||||
buildRestartRequiredConfigMessage,
|
buildRestartRequiredConfigMessage,
|
||||||
createConfigHotReloadAppliedHandler,
|
createConfigHotReloadAppliedHandler,
|
||||||
@@ -413,8 +411,7 @@ import {
|
|||||||
createBuildReloadConfigMainDepsHandler,
|
createBuildReloadConfigMainDepsHandler,
|
||||||
} from './main/runtime/startup-config-main-deps';
|
} from './main/runtime/startup-config-main-deps';
|
||||||
import { createBuildAppReadyRuntimeMainDepsHandler } from './main/runtime/app-ready-main-deps';
|
import { createBuildAppReadyRuntimeMainDepsHandler } from './main/runtime/app-ready-main-deps';
|
||||||
import { createBuildAppLifecycleRuntimeRunnerMainDepsHandler } from './main/runtime/startup-lifecycle-main-deps';
|
import { createStartupRuntimeHandlers } from './main/runtime/startup-runtime-handlers';
|
||||||
import { createBuildStartupBootstrapMainDepsHandler } from './main/runtime/startup-bootstrap-main-deps';
|
|
||||||
import {
|
import {
|
||||||
enforceUnsupportedWaylandMode,
|
enforceUnsupportedWaylandMode,
|
||||||
forceX11Backend,
|
forceX11Backend,
|
||||||
@@ -484,6 +481,8 @@ import { createAnilistUpdateQueue } from './core/services/anilist/anilist-update
|
|||||||
import { createJellyfinTokenStore } from './core/services/jellyfin-token-store';
|
import { createJellyfinTokenStore } from './core/services/jellyfin-token-store';
|
||||||
import { applyRuntimeOptionResultRuntime } from './core/services/runtime-options-ipc';
|
import { applyRuntimeOptionResultRuntime } from './core/services/runtime-options-ipc';
|
||||||
import { createAppReadyRuntimeRunner } from './main/app-lifecycle';
|
import { createAppReadyRuntimeRunner } from './main/app-lifecycle';
|
||||||
|
import { createStartupBootstrapRuntimeDeps } from './main/startup';
|
||||||
|
import { createAppLifecycleRuntimeRunner } from './main/startup-lifecycle';
|
||||||
import { handleMpvCommandFromIpcRuntime } from './main/ipc-mpv-command';
|
import { handleMpvCommandFromIpcRuntime } from './main/ipc-mpv-command';
|
||||||
import { registerIpcRuntimeServices } from './main/ipc-runtime';
|
import { registerIpcRuntimeServices } from './main/ipc-runtime';
|
||||||
import { createAnkiJimakuIpcRuntimeServiceDeps } from './main/dependencies';
|
import { createAnkiJimakuIpcRuntimeServiceDeps } from './main/dependencies';
|
||||||
@@ -500,13 +499,11 @@ import {
|
|||||||
} from './main/frequency-dictionary-runtime';
|
} from './main/frequency-dictionary-runtime';
|
||||||
import { createMediaRuntimeService } from './main/media-runtime';
|
import { createMediaRuntimeService } from './main/media-runtime';
|
||||||
import { createOverlayVisibilityRuntimeService } from './main/overlay-visibility-runtime';
|
import { createOverlayVisibilityRuntimeService } from './main/overlay-visibility-runtime';
|
||||||
import { type AppState, applyStartupState, createAppState } from './main/state';
|
import { type AppState, type StartupState, applyStartupState, createAppState } from './main/state';
|
||||||
import {
|
import {
|
||||||
isAllowedAnilistExternalUrl,
|
isAllowedAnilistExternalUrl,
|
||||||
isAllowedAnilistSetupNavigationUrl,
|
isAllowedAnilistSetupNavigationUrl,
|
||||||
} from './main/anilist-url-guard';
|
} from './main/anilist-url-guard';
|
||||||
import { createStartupBootstrapRuntimeDeps } from './main/startup';
|
|
||||||
import { createAppLifecycleRuntimeRunner } from './main/startup-lifecycle';
|
|
||||||
import {
|
import {
|
||||||
ConfigService,
|
ConfigService,
|
||||||
DEFAULT_CONFIG,
|
DEFAULT_CONFIG,
|
||||||
@@ -2130,8 +2127,12 @@ const buildAppReadyRuntimeMainDepsHandler = createBuildAppReadyRuntimeMainDepsHa
|
|||||||
});
|
});
|
||||||
const appReadyRuntimeRunner = createAppReadyRuntimeRunner(buildAppReadyRuntimeMainDepsHandler());
|
const appReadyRuntimeRunner = createAppReadyRuntimeRunner(buildAppReadyRuntimeMainDepsHandler());
|
||||||
|
|
||||||
const buildAppLifecycleRuntimeRunnerMainDepsHandler =
|
const { appLifecycleRuntimeRunner, runAndApplyStartupState } = createStartupRuntimeHandlers<
|
||||||
createBuildAppLifecycleRuntimeRunnerMainDepsHandler({
|
CliArgs,
|
||||||
|
StartupState,
|
||||||
|
ReturnType<typeof createStartupBootstrapRuntimeDeps>
|
||||||
|
>({
|
||||||
|
appLifecycleRuntimeRunnerMainDeps: {
|
||||||
app,
|
app,
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
shouldStartApp: (nextArgs: CliArgs) => shouldStartApp(nextArgs),
|
shouldStartApp: (nextArgs: CliArgs) => shouldStartApp(nextArgs),
|
||||||
@@ -2145,53 +2146,47 @@ const buildAppLifecycleRuntimeRunnerMainDepsHandler =
|
|||||||
shouldRestoreWindowsOnActivate: () => shouldRestoreWindowsOnActivateHandler(),
|
shouldRestoreWindowsOnActivate: () => shouldRestoreWindowsOnActivateHandler(),
|
||||||
restoreWindowsOnActivate: () => restoreWindowsOnActivateHandler(),
|
restoreWindowsOnActivate: () => restoreWindowsOnActivateHandler(),
|
||||||
shouldQuitOnWindowAllClosed: () => !appState.backgroundMode,
|
shouldQuitOnWindowAllClosed: () => !appState.backgroundMode,
|
||||||
});
|
},
|
||||||
const appLifecycleRuntimeRunnerMainDeps = buildAppLifecycleRuntimeRunnerMainDepsHandler();
|
createAppLifecycleRuntimeRunner: (params) => createAppLifecycleRuntimeRunner(params),
|
||||||
const appLifecycleRuntimeRunner = createAppLifecycleRuntimeRunner(
|
buildStartupBootstrapMainDeps: (startAppLifecycle) => ({
|
||||||
appLifecycleRuntimeRunnerMainDeps,
|
argv: process.argv,
|
||||||
);
|
parseArgs: (argv: string[]) => parseArgs(argv),
|
||||||
|
setLogLevel: (level: string, source: LogLevelSource) => {
|
||||||
|
setLogLevel(level, source);
|
||||||
|
},
|
||||||
|
forceX11Backend: (args: CliArgs) => {
|
||||||
|
forceX11Backend(args);
|
||||||
|
},
|
||||||
|
enforceUnsupportedWaylandMode: (args: CliArgs) => {
|
||||||
|
enforceUnsupportedWaylandMode(args);
|
||||||
|
},
|
||||||
|
shouldStartApp: (args: CliArgs) => shouldStartApp(args),
|
||||||
|
getDefaultSocketPath: () => getDefaultSocketPath(),
|
||||||
|
defaultTexthookerPort: DEFAULT_TEXTHOOKER_PORT,
|
||||||
|
configDir: CONFIG_DIR,
|
||||||
|
defaultConfig: DEFAULT_CONFIG,
|
||||||
|
generateConfigTemplate: (config: ResolvedConfig) => generateConfigTemplate(config),
|
||||||
|
generateDefaultConfigFile: (
|
||||||
|
args: CliArgs,
|
||||||
|
options: {
|
||||||
|
configDir: string;
|
||||||
|
defaultConfig: unknown;
|
||||||
|
generateTemplate: (config: unknown) => string;
|
||||||
|
},
|
||||||
|
) => generateDefaultConfigFile(args, options),
|
||||||
|
setExitCode: (code) => {
|
||||||
|
process.exitCode = code;
|
||||||
|
},
|
||||||
|
quitApp: () => app.quit(),
|
||||||
|
logGenerateConfigError: (message) => logger.error(message),
|
||||||
|
startAppLifecycle,
|
||||||
|
}),
|
||||||
|
createStartupBootstrapRuntimeDeps: (deps) => createStartupBootstrapRuntimeDeps(deps),
|
||||||
|
runStartupBootstrapRuntime,
|
||||||
|
applyStartupState: (startupState) => applyStartupState(appState, startupState),
|
||||||
|
});
|
||||||
|
|
||||||
const buildStartupBootstrapMainDepsHandler = createBuildStartupBootstrapMainDepsHandler({
|
runAndApplyStartupState();
|
||||||
argv: process.argv,
|
|
||||||
parseArgs: (argv: string[]) => parseArgs(argv),
|
|
||||||
setLogLevel: (level: string, source: LogLevelSource) => {
|
|
||||||
setLogLevel(level, source);
|
|
||||||
},
|
|
||||||
forceX11Backend: (args: CliArgs) => {
|
|
||||||
forceX11Backend(args);
|
|
||||||
},
|
|
||||||
enforceUnsupportedWaylandMode: (args: CliArgs) => {
|
|
||||||
enforceUnsupportedWaylandMode(args);
|
|
||||||
},
|
|
||||||
shouldStartApp: (args: CliArgs) => shouldStartApp(args),
|
|
||||||
getDefaultSocketPath: () => getDefaultSocketPath(),
|
|
||||||
defaultTexthookerPort: DEFAULT_TEXTHOOKER_PORT,
|
|
||||||
configDir: CONFIG_DIR,
|
|
||||||
defaultConfig: DEFAULT_CONFIG,
|
|
||||||
generateConfigTemplate: (config: ResolvedConfig) => generateConfigTemplate(config),
|
|
||||||
generateDefaultConfigFile: (
|
|
||||||
args: CliArgs,
|
|
||||||
options: {
|
|
||||||
configDir: string;
|
|
||||||
defaultConfig: unknown;
|
|
||||||
generateTemplate: (config: unknown) => string;
|
|
||||||
},
|
|
||||||
) => generateDefaultConfigFile(args, options),
|
|
||||||
setExitCode: (code) => {
|
|
||||||
process.exitCode = code;
|
|
||||||
},
|
|
||||||
quitApp: () => app.quit(),
|
|
||||||
logGenerateConfigError: (message) => logger.error(message),
|
|
||||||
startAppLifecycle: appLifecycleRuntimeRunner,
|
|
||||||
});
|
|
||||||
const buildStartupBootstrapRuntimeFactoryDepsHandler =
|
|
||||||
createBuildStartupBootstrapRuntimeFactoryDepsHandler(buildStartupBootstrapMainDepsHandler());
|
|
||||||
|
|
||||||
const startupState = runStartupBootstrapRuntime(
|
|
||||||
createStartupBootstrapRuntimeDeps(buildStartupBootstrapRuntimeFactoryDepsHandler()),
|
|
||||||
);
|
|
||||||
|
|
||||||
applyStartupState(appState, startupState);
|
|
||||||
void refreshAnilistClientSecretState({ force: true });
|
void refreshAnilistClientSecretState({ force: true });
|
||||||
anilistStateRuntime.refreshRetryQueueState();
|
anilistStateRuntime.refreshRetryQueueState();
|
||||||
|
|
||||||
@@ -2214,7 +2209,7 @@ function handleCliCommand(args: CliArgs, source: CliCommandSource = 'initial'):
|
|||||||
handleCliCommandRuntimeServiceWithContext(args, source, cliContext);
|
handleCliCommandRuntimeServiceWithContext(args, source, cliContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildHandleInitialArgsMainDepsHandler = createBuildHandleInitialArgsMainDepsHandler({
|
const handleInitialArgsRuntimeHandler = createInitialArgsRuntimeHandler({
|
||||||
getInitialArgs: () => appState.initialArgs,
|
getInitialArgs: () => appState.initialArgs,
|
||||||
isBackgroundMode: () => appState.backgroundMode,
|
isBackgroundMode: () => appState.backgroundMode,
|
||||||
ensureTray: () => ensureTray(),
|
ensureTray: () => ensureTray(),
|
||||||
@@ -2224,10 +2219,6 @@ const buildHandleInitialArgsMainDepsHandler = createBuildHandleInitialArgsMainDe
|
|||||||
logInfo: (message) => logger.info(message),
|
logInfo: (message) => logger.info(message),
|
||||||
handleCliCommand: (args, source) => handleCliCommand(args, source),
|
handleCliCommand: (args, source) => handleCliCommand(args, source),
|
||||||
});
|
});
|
||||||
const handleInitialArgsMainDeps = buildHandleInitialArgsMainDepsHandler();
|
|
||||||
const handleInitialArgsRuntimeHandler = createHandleInitialArgsHandler(
|
|
||||||
handleInitialArgsMainDeps,
|
|
||||||
);
|
|
||||||
|
|
||||||
function handleInitialArgs(): void {
|
function handleInitialArgs(): void {
|
||||||
handleInitialArgsRuntimeHandler();
|
handleInitialArgsRuntimeHandler();
|
||||||
|
|||||||
24
src/main/runtime/initial-args-runtime-handler.test.ts
Normal file
24
src/main/runtime/initial-args-runtime-handler.test.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import { createInitialArgsRuntimeHandler } from './initial-args-runtime-handler';
|
||||||
|
|
||||||
|
test('initial args runtime handler composes main deps and runs initial command flow', () => {
|
||||||
|
const calls: string[] = [];
|
||||||
|
const handleInitialArgs = createInitialArgsRuntimeHandler({
|
||||||
|
getInitialArgs: () => ({ start: true } as never),
|
||||||
|
isBackgroundMode: () => true,
|
||||||
|
ensureTray: () => calls.push('tray'),
|
||||||
|
isTexthookerOnlyMode: () => false,
|
||||||
|
hasImmersionTracker: () => true,
|
||||||
|
getMpvClient: () => ({
|
||||||
|
connected: false,
|
||||||
|
connect: () => calls.push('connect'),
|
||||||
|
}),
|
||||||
|
logInfo: (message) => calls.push(`log:${message}`),
|
||||||
|
handleCliCommand: (_args, source) => calls.push(`cli:${source}`),
|
||||||
|
});
|
||||||
|
|
||||||
|
handleInitialArgs();
|
||||||
|
|
||||||
|
assert.deepEqual(calls, ['tray', 'log:Auto-connecting MPV client for immersion tracking', 'connect', 'cli:initial']);
|
||||||
|
});
|
||||||
10
src/main/runtime/initial-args-runtime-handler.ts
Normal file
10
src/main/runtime/initial-args-runtime-handler.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { createHandleInitialArgsHandler } from './initial-args-handler';
|
||||||
|
import { createBuildHandleInitialArgsMainDepsHandler } from './initial-args-main-deps';
|
||||||
|
|
||||||
|
type InitialArgsMainDeps = Parameters<typeof createBuildHandleInitialArgsMainDepsHandler>[0];
|
||||||
|
|
||||||
|
export function createInitialArgsRuntimeHandler(deps: InitialArgsMainDeps) {
|
||||||
|
const buildHandleInitialArgsMainDepsHandler = createBuildHandleInitialArgsMainDepsHandler(deps);
|
||||||
|
const handleInitialArgsMainDeps = buildHandleInitialArgsMainDepsHandler();
|
||||||
|
return createHandleInitialArgsHandler(handleInitialArgsMainDeps);
|
||||||
|
}
|
||||||
72
src/main/runtime/startup-runtime-handlers.test.ts
Normal file
72
src/main/runtime/startup-runtime-handlers.test.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import test from 'node:test';
|
||||||
|
import type { CliArgs } from '../../cli/args';
|
||||||
|
import { createStartupRuntimeHandlers } from './startup-runtime-handlers';
|
||||||
|
|
||||||
|
test('startup runtime handlers compose lifecycle runner and startup bootstrap apply flow', () => {
|
||||||
|
const calls: string[] = [];
|
||||||
|
const appliedStates: Array<{ mode: string }> = [];
|
||||||
|
|
||||||
|
const runtime = createStartupRuntimeHandlers<
|
||||||
|
{ command: string },
|
||||||
|
{ mode: string },
|
||||||
|
{ startAppLifecycle: (args: CliArgs) => void }
|
||||||
|
>({
|
||||||
|
appLifecycleRuntimeRunnerMainDeps: {
|
||||||
|
app: { on: () => {} } as never,
|
||||||
|
platform: 'darwin',
|
||||||
|
shouldStartApp: () => true,
|
||||||
|
parseArgs: () => ({}) as never,
|
||||||
|
handleCliCommand: () => calls.push('handle-cli'),
|
||||||
|
printHelp: () => calls.push('help'),
|
||||||
|
logNoRunningInstance: () => calls.push('no-instance'),
|
||||||
|
onReady: async () => {
|
||||||
|
calls.push('ready');
|
||||||
|
},
|
||||||
|
onWillQuitCleanup: () => calls.push('cleanup'),
|
||||||
|
shouldRestoreWindowsOnActivate: () => true,
|
||||||
|
restoreWindowsOnActivate: () => calls.push('restore'),
|
||||||
|
shouldQuitOnWindowAllClosed: () => false,
|
||||||
|
},
|
||||||
|
createAppLifecycleRuntimeRunner: () => (args) => {
|
||||||
|
calls.push(`lifecycle:${args.command}`);
|
||||||
|
},
|
||||||
|
buildStartupBootstrapMainDeps: (startAppLifecycle) => ({
|
||||||
|
argv: ['node', 'main.js'],
|
||||||
|
parseArgs: () => ({ command: 'start' }) as never,
|
||||||
|
setLogLevel: () => {},
|
||||||
|
forceX11Backend: () => {},
|
||||||
|
enforceUnsupportedWaylandMode: () => {},
|
||||||
|
shouldStartApp: () => true,
|
||||||
|
getDefaultSocketPath: () => '/tmp/mpv.sock',
|
||||||
|
defaultTexthookerPort: 5174,
|
||||||
|
configDir: '/tmp/config',
|
||||||
|
defaultConfig: {} as never,
|
||||||
|
generateConfigTemplate: () => 'template',
|
||||||
|
generateDefaultConfigFile: async () => 0,
|
||||||
|
setExitCode: () => {},
|
||||||
|
quitApp: () => {},
|
||||||
|
logGenerateConfigError: () => {},
|
||||||
|
startAppLifecycle: (args) => {
|
||||||
|
const typedArgs = args as unknown as { command: string };
|
||||||
|
calls.push(`start-lifecycle:${typedArgs.command}`);
|
||||||
|
startAppLifecycle(typedArgs);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
createStartupBootstrapRuntimeDeps: (deps) => ({
|
||||||
|
startAppLifecycle: deps.startAppLifecycle,
|
||||||
|
}),
|
||||||
|
runStartupBootstrapRuntime: (deps) => {
|
||||||
|
deps.startAppLifecycle({ command: 'start' } as never);
|
||||||
|
return { mode: 'started' };
|
||||||
|
},
|
||||||
|
applyStartupState: (state) => {
|
||||||
|
appliedStates.push(state);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const state = runtime.runAndApplyStartupState();
|
||||||
|
assert.deepEqual(state, { mode: 'started' });
|
||||||
|
assert.deepEqual(appliedStates, [{ mode: 'started' }]);
|
||||||
|
assert.deepEqual(calls, ['start-lifecycle:start', 'lifecycle:start']);
|
||||||
|
});
|
||||||
55
src/main/runtime/startup-runtime-handlers.ts
Normal file
55
src/main/runtime/startup-runtime-handlers.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { createBuildStartupBootstrapRuntimeFactoryDepsHandler } from './startup-bootstrap-deps-builder';
|
||||||
|
import { createBuildAppLifecycleRuntimeRunnerMainDepsHandler } from './startup-lifecycle-main-deps';
|
||||||
|
import { createBuildStartupBootstrapMainDepsHandler } from './startup-bootstrap-main-deps';
|
||||||
|
|
||||||
|
type AppLifecycleRuntimeRunnerMainDeps = Parameters<
|
||||||
|
typeof createBuildAppLifecycleRuntimeRunnerMainDepsHandler
|
||||||
|
>[0];
|
||||||
|
type StartupBootstrapMainDeps = Parameters<typeof createBuildStartupBootstrapMainDepsHandler>[0];
|
||||||
|
type StartupBootstrapRuntimeFactoryDeps = Parameters<
|
||||||
|
typeof createBuildStartupBootstrapRuntimeFactoryDepsHandler
|
||||||
|
>[0];
|
||||||
|
|
||||||
|
export function createStartupRuntimeHandlers<
|
||||||
|
TCliArgs,
|
||||||
|
TStartupState,
|
||||||
|
TStartupBootstrapRuntimeDeps = unknown,
|
||||||
|
>(deps: {
|
||||||
|
appLifecycleRuntimeRunnerMainDeps: AppLifecycleRuntimeRunnerMainDeps;
|
||||||
|
createAppLifecycleRuntimeRunner: (
|
||||||
|
params: AppLifecycleRuntimeRunnerMainDeps,
|
||||||
|
) => (args: TCliArgs) => void;
|
||||||
|
buildStartupBootstrapMainDeps: (
|
||||||
|
startAppLifecycle: (args: TCliArgs) => void,
|
||||||
|
) => StartupBootstrapMainDeps;
|
||||||
|
createStartupBootstrapRuntimeDeps: (
|
||||||
|
deps: StartupBootstrapRuntimeFactoryDeps,
|
||||||
|
) => TStartupBootstrapRuntimeDeps;
|
||||||
|
runStartupBootstrapRuntime: (deps: TStartupBootstrapRuntimeDeps) => TStartupState;
|
||||||
|
applyStartupState: (startupState: TStartupState) => void;
|
||||||
|
}) {
|
||||||
|
const appLifecycleRuntimeRunnerMainDeps =
|
||||||
|
createBuildAppLifecycleRuntimeRunnerMainDepsHandler(deps.appLifecycleRuntimeRunnerMainDeps)();
|
||||||
|
const appLifecycleRuntimeRunner = deps.createAppLifecycleRuntimeRunner(
|
||||||
|
appLifecycleRuntimeRunnerMainDeps,
|
||||||
|
);
|
||||||
|
|
||||||
|
const startupBootstrapMainDeps = createBuildStartupBootstrapMainDepsHandler(
|
||||||
|
deps.buildStartupBootstrapMainDeps(appLifecycleRuntimeRunner),
|
||||||
|
)();
|
||||||
|
const startupBootstrapRuntimeFactoryDeps =
|
||||||
|
createBuildStartupBootstrapRuntimeFactoryDepsHandler(startupBootstrapMainDeps)();
|
||||||
|
|
||||||
|
const runAndApplyStartupState = (): TStartupState => {
|
||||||
|
const startupState = deps.runStartupBootstrapRuntime(
|
||||||
|
deps.createStartupBootstrapRuntimeDeps(startupBootstrapRuntimeFactoryDeps),
|
||||||
|
);
|
||||||
|
deps.applyStartupState(startupState);
|
||||||
|
return startupState;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
appLifecycleRuntimeRunner,
|
||||||
|
runAndApplyStartupState,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user