Files
smartipc/ts/index.ts

132 lines
3.7 KiB
TypeScript

export * from './classes.transports.js';
export * from './classes.ipcchannel.js';
export * from './classes.ipcserver.js';
export * from './classes.ipcclient.js';
import { IpcServer } from './classes.ipcserver.js';
import { IpcClient } from './classes.ipcclient.js';
import { IpcChannel } from './classes.ipcchannel.js';
import type { IIpcServerOptions } from './classes.ipcserver.js';
import type { IIpcClientOptions, IConnectRetryConfig } from './classes.ipcclient.js';
import type { IIpcChannelOptions } from './classes.ipcchannel.js';
/**
* Main SmartIpc class - Factory for creating IPC servers, clients, and channels
*/
export class SmartIpc {
/**
* Create an IPC server
*/
/**
* Wait for a server to become ready at the given socket path
*/
public static async waitForServer(options: {
socketPath: string;
timeoutMs?: number;
}): Promise<void> {
const timeout = options.timeoutMs || 10000;
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
try {
// Create a temporary client with proper options
const testClient = SmartIpc.createClient({
id: 'test-probe',
socketPath: options.socketPath,
clientId: `probe-${process.pid}-${Date.now()}`,
heartbeat: false,
clientOnly: true,
connectRetry: {
enabled: false // Don't retry, we're handling retries here
},
registerTimeoutMs: 2000 // Short timeout for quick probing
});
// Try to connect and register with the server
await testClient.connect();
// Success! Clean up and return
await testClient.disconnect();
return;
} catch (error) {
// Server not ready yet, wait and retry
await new Promise(resolve => setTimeout(resolve, 200));
}
}
throw new Error(`Server not ready at ${options.socketPath} after ${timeout}ms`);
}
/**
* Helper to spawn a server process and connect a client
*/
public static async spawnAndConnect(options: {
serverScript: string;
socketPath: string;
clientId?: string;
spawnOptions?: any;
connectRetry?: IConnectRetryConfig;
timeoutMs?: number;
}): Promise<{
client: IpcClient;
serverProcess: any;
}> {
const { spawn } = await import('child_process');
// Spawn the server process
const serverProcess = spawn('node', [options.serverScript], {
detached: true,
stdio: 'pipe',
...options.spawnOptions
});
// Handle server process errors
serverProcess.on('error', (error: Error) => {
console.error('Server process error:', error);
});
// Wait for server to be ready
await SmartIpc.waitForServer({
socketPath: options.socketPath,
timeoutMs: options.timeoutMs || 10000
});
// Create and connect client
const client = new IpcClient({
id: options.clientId || 'test-client',
socketPath: options.socketPath,
connectRetry: options.connectRetry || {
enabled: true,
maxAttempts: 10,
initialDelay: 100,
maxDelay: 1000
}
});
await client.connect({ waitForReady: true });
return { client, serverProcess };
}
public static createServer(options: IIpcServerOptions): IpcServer {
return new IpcServer(options);
}
/**
* Create an IPC client
*/
public static createClient(options: IIpcClientOptions): IpcClient {
return new IpcClient(options);
}
/**
* Create a raw IPC channel (for advanced use cases)
*/
public static createChannel(options: IIpcChannelOptions): IpcChannel {
return new IpcChannel(options);
}
}
// Export the main class as default
export default SmartIpc;