Files
SubMiner/src/preload-syncui.ts
T
sudacode a013a7ea55 feat(sync-ui): defer app quit until async cleanup resolves
- check-host participates in active-run coordination and can be cancelled
- shutdown() cancels and awaits the active launcher run on quit
- onWillQuit calls preventDefault and re-triggers quit once cleanup settles
- Snapshot mode awaits tracker quiescent before writing output
- Auto-scheduler catches synchronous triggerHostSync failures
- SCP endpoint accepts Windows absolute paths; cmd.exe rejects % in quoted values
- runAppCommand unified (inherit vs pipe stdio) in launcher/mpv.ts
- Docs: add --check, --json, --ui, --sync-cli, --make-temp/--remove-temp examples
2026-07-12 03:35:39 -07:00

52 lines
2.5 KiB
TypeScript

import { contextBridge, ipcRenderer } from 'electron';
import { IPC_CHANNELS } from './shared/ipc/contracts';
import type {
SyncHostsState,
SyncUiAPI,
SyncUiCheckResult,
SyncUiHostUpdateRequest,
SyncUiProgressPayload,
SyncUiRunRequest,
SyncUiSnapshot,
SyncUiSnapshotFile,
SyncUiStartResult,
} from './types/sync-ui';
const syncUiAPI: SyncUiAPI = {
getSnapshot: (): Promise<SyncUiSnapshot> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiGetSnapshot),
saveHost: (update: SyncUiHostUpdateRequest): Promise<SyncHostsState> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiSaveHost, update),
removeHost: (host: string): Promise<SyncHostsState> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiRemoveHost, host),
setAutoSyncInterval: (minutes: number): Promise<SyncHostsState> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiSetAutoSyncInterval, minutes),
runSync: (request: SyncUiRunRequest): Promise<SyncUiStartResult> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiRunSync, request),
cancelRun: (): Promise<boolean> => ipcRenderer.invoke(IPC_CHANNELS.request.syncUiCancelRun),
checkHost: (host: string): Promise<SyncUiCheckResult> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiCheckHost, host),
createSnapshot: (): Promise<SyncUiStartResult> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiCreateSnapshot),
mergeSnapshotFile: (path: string, force?: boolean): Promise<SyncUiStartResult> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiMergeSnapshotFile, path, force === true),
deleteSnapshot: (path: string): Promise<SyncUiSnapshotFile[]> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiDeleteSnapshot, path),
revealSnapshot: (path: string): Promise<boolean> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiRevealSnapshot, path),
pickSnapshotFile: (): Promise<string | null> =>
ipcRenderer.invoke(IPC_CHANNELS.request.syncUiPickSnapshotFile),
onProgress: (listener: (payload: SyncUiProgressPayload) => void): (() => void) => {
const handler = (_event: unknown, payload: SyncUiProgressPayload): void => listener(payload);
ipcRenderer.on(IPC_CHANNELS.event.syncUiProgress, handler);
return () => ipcRenderer.removeListener(IPC_CHANNELS.event.syncUiProgress, handler);
},
onStateChanged: (listener: () => void): (() => void) => {
const handler = (): void => listener();
ipcRenderer.on(IPC_CHANNELS.event.syncUiStateChanged, handler);
return () => ipcRenderer.removeListener(IPC_CHANNELS.event.syncUiStateChanged, handler);
},
};
contextBridge.exposeInMainWorld('syncUiAPI', syncUiAPI);