UNPKG

@isthatuzii/create-nano-app

Version:

Desktop application scaffolding tool for the Nano Framework

193 lines (159 loc) 5.06 kB
/** * Simple Nano IPC Invoke System * * Clean, minimal invoke function for calling nano backend functions */ // This is now on NPM: https://www.npmjs.com/package/nano-invoke // Please use that instead of this file // import { invoke, configure } from 'nano-invoke'; // Optional: Configure the client // configure({ // debug: true, // timeout: 5000 // }); // Call any registered nano function // const result = await invoke('greet', { name: 'World' }); // console.log(result); // "Hello, World!" // Call external system functions // const calculation = await invoke('calculate', { // operation: 'add', // values: [10, 20, 30] // }); // console.log(calculation.result); // 60 // Simple IPC types export interface IpcRequest { cmd: string; args: Record<string, any>; id?: string; } export interface IpcResponse<T = any> { result?: T; error?: string; code?: string; id?: string; } /** * Simple invoke function for calling nano functions * * @param cmd - Function name to invoke * @param args - Arguments to pass to the function * @returns Promise resolving to the function result */ export async function invoke<T = any>( cmd: string, args: Record<string, any> = {} ): Promise<T> { const request: IpcRequest = { cmd, args: args || {} }; try { console.log(`[IPC] Invoking: ${cmd}`, args); const response = await fetch('/ipc', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(request), }); console.log(`[IPC] Response status: ${response.status} ${response.statusText}`); if (!response.ok) { // Try to get the response text for better error messages const errorText = await response.text(); console.error(`[IPC] Error response:`, errorText); if (response.status === 404) { throw new Error('IPC endpoint not found. Make sure the Nano server is running.'); } throw new Error(`HTTP ${response.status}: ${response.statusText} - ${errorText}`); } const result: IpcResponse<T> = await response.json(); console.log(`[IPC] Result:`, result); if (result.error) { throw new Error(result.error); } return result.result as T; } catch (error) { console.error(`[IPC] Invoke error:`, error); if (error instanceof TypeError && error.message.includes('fetch')) { throw new Error('Cannot connect to server. Make sure the Nano application is running.'); } throw new Error( error instanceof Error ? error.message : String(error) ); } } // Simple namespace for type safety (optional) export namespace Commands { // Just the basic types we need export interface SystemInfo { os: string; arch: string; hostname: string; } export interface UserInfo { name: string; age: number; email: string; } } // Simple event system (optional - for WebSocket events) export type EventListener<T = any> = (data: T) => void; export class EventManager { private ws: WebSocket | null = null; private listeners: Map<string, Set<EventListener>> = new Map(); async connect(): Promise<void> { return new Promise((resolve, reject) => { try { this.ws = new WebSocket(`ws://${window.location.host}/ws`); this.ws.onopen = () => { resolve(); }; this.ws.onmessage = (event) => { try { const message = JSON.parse(event.data); this.emit(message.event, message.payload); } catch (error) { console.error('Failed to parse event:', error); } }; this.ws.onerror = () => { reject(new Error('WebSocket connection failed')); }; } catch (error) { reject(error); } }); } on<T = any>(event: string, listener: EventListener<T>): void { if (!this.listeners.has(event)) { this.listeners.set(event, new Set()); } this.listeners.get(event)!.add(listener as EventListener); } off<T = any>(event: string, listener: EventListener<T>): void { const eventListeners = this.listeners.get(event); if (eventListeners) { eventListeners.delete(listener as EventListener); } } private emit(event: string, data: any): void { const eventListeners = this.listeners.get(event); if (eventListeners) { eventListeners.forEach(listener => { try { listener(data); } catch (error) { console.error(`Error in event listener:`, error); } }); } } } // Default event manager instance export const events = new EventManager(); // Simple utilities export namespace Utils { export async function ping(): Promise<string> { return await invoke('ping'); } }