Files
DeskClaw/electron/main/ipc-handlers.ts
Haze 1646536e40 feat(gateway): enhance gateway process management with auto-reconnection
Improve Gateway lifecycle management with the following features:

- Add exponential backoff reconnection (1s-30s delay, max 10 attempts)
- Add health check monitoring every 30 seconds
- Add proper restart method with graceful shutdown
- Handle server-initiated notifications (channel status, chat messages)
- Add 'reconnecting' state for better UI feedback
- Enhance IPC handlers with isConnected and health check endpoints
- Update preload script with new event channels
- Improve type safety and error handling throughout

Also fixes several TypeScript errors and unused variable warnings.
2026-02-05 23:15:07 +08:00

217 lines
5.2 KiB
TypeScript

/**
* IPC Handlers
* Registers all IPC handlers for main-renderer communication
*/
import { ipcMain, BrowserWindow, shell, dialog, app } from 'electron';
import { GatewayManager } from '../gateway/manager';
/**
* Register all IPC handlers
*/
export function registerIpcHandlers(
gatewayManager: GatewayManager,
mainWindow: BrowserWindow
): void {
// Gateway handlers
registerGatewayHandlers(gatewayManager, mainWindow);
// Shell handlers
registerShellHandlers();
// Dialog handlers
registerDialogHandlers();
// App handlers
registerAppHandlers();
}
/**
* Gateway-related IPC handlers
*/
function registerGatewayHandlers(
gatewayManager: GatewayManager,
mainWindow: BrowserWindow
): void {
// Get Gateway status
ipcMain.handle('gateway:status', () => {
return gatewayManager.getStatus();
});
// Check if Gateway is connected
ipcMain.handle('gateway:isConnected', () => {
return gatewayManager.isConnected();
});
// Start Gateway
ipcMain.handle('gateway:start', async () => {
try {
await gatewayManager.start();
return { success: true };
} catch (error) {
return { success: false, error: String(error) };
}
});
// Stop Gateway
ipcMain.handle('gateway:stop', async () => {
try {
await gatewayManager.stop();
return { success: true };
} catch (error) {
return { success: false, error: String(error) };
}
});
// Restart Gateway
ipcMain.handle('gateway:restart', async () => {
try {
await gatewayManager.restart();
return { success: true };
} catch (error) {
return { success: false, error: String(error) };
}
});
// Gateway RPC call
ipcMain.handle('gateway:rpc', async (_, method: string, params?: unknown, timeoutMs?: number) => {
try {
const result = await gatewayManager.rpc(method, params, timeoutMs);
return { success: true, result };
} catch (error) {
return { success: false, error: String(error) };
}
});
// Health check
ipcMain.handle('gateway:health', async () => {
try {
const health = await gatewayManager.checkHealth();
return { success: true, ...health };
} catch (error) {
return { success: false, ok: false, error: String(error) };
}
});
// Forward Gateway events to renderer
gatewayManager.on('status', (status) => {
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('gateway:status-changed', status);
}
});
gatewayManager.on('message', (message) => {
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('gateway:message', message);
}
});
gatewayManager.on('notification', (notification) => {
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('gateway:notification', notification);
}
});
gatewayManager.on('channel:status', (data) => {
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('gateway:channel-status', data);
}
});
gatewayManager.on('chat:message', (data) => {
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('gateway:chat-message', data);
}
});
gatewayManager.on('exit', (code) => {
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('gateway:exit', code);
}
});
gatewayManager.on('error', (error) => {
if (!mainWindow.isDestroyed()) {
mainWindow.webContents.send('gateway:error', error.message);
}
});
}
/**
* Shell-related IPC handlers
*/
function registerShellHandlers(): void {
// Open external URL
ipcMain.handle('shell:openExternal', async (_, url: string) => {
await shell.openExternal(url);
});
// Open path in file explorer
ipcMain.handle('shell:showItemInFolder', async (_, path: string) => {
shell.showItemInFolder(path);
});
// Open path
ipcMain.handle('shell:openPath', async (_, path: string) => {
return await shell.openPath(path);
});
}
/**
* Dialog-related IPC handlers
*/
function registerDialogHandlers(): void {
// Show open dialog
ipcMain.handle('dialog:open', async (_, options: Electron.OpenDialogOptions) => {
const result = await dialog.showOpenDialog(options);
return result;
});
// Show save dialog
ipcMain.handle('dialog:save', async (_, options: Electron.SaveDialogOptions) => {
const result = await dialog.showSaveDialog(options);
return result;
});
// Show message box
ipcMain.handle('dialog:message', async (_, options: Electron.MessageBoxOptions) => {
const result = await dialog.showMessageBox(options);
return result;
});
}
/**
* App-related IPC handlers
*/
function registerAppHandlers(): void {
// Get app version
ipcMain.handle('app:version', () => {
return app.getVersion();
});
// Get app name
ipcMain.handle('app:name', () => {
return app.getName();
});
// Get app path
ipcMain.handle('app:getPath', (_, name: Parameters<typeof app.getPath>[0]) => {
return app.getPath(name);
});
// Get platform
ipcMain.handle('app:platform', () => {
return process.platform;
});
// Quit app
ipcMain.handle('app:quit', () => {
app.quit();
});
// Relaunch app
ipcMain.handle('app:relaunch', () => {
app.relaunch();
app.quit();
});
}