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.
217 lines
5.2 KiB
TypeScript
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();
|
|
});
|
|
}
|