### Install Einf Package Source: https://github.com/archergu/einf/blob/main/README.md Instructions for installing the 'einf' package using npm, Yarn, or PNPM. This is the first step to integrating the framework into your Electron project. ```shell npm i einf # Or Yarn yarn add einf # Or PNPM pnpm add einf ``` -------------------------------- ### Electron App Entry Point with Einf Source: https://github.com/archergu/einf/blob/main/README.md Example of an Electron application's entry point (`index.ts`) using the `createEinf` function. It demonstrates how to initialize Einf with a BrowserWindow, controllers, and custom injectables. ```typescript import { createEinf } from 'einf' import { app, BrowserWindow } from 'electron' import { AppController } from './app.controller' async function bootstrap() { const window = new BrowserWindow() window.loadURL('https://github.com') await createEinf({ // window to create window, // controllers will be automatically initialized controllers: [AppController], // custom items to inject injects: [{ name: 'IS_DEV', inject: !app.isPackaged, }], }) } bootstrap() ``` -------------------------------- ### Einf Injectable Service Source: https://github.com/archergu/einf/blob/main/README.md Example of an `AppService` class decorated with `@Injectable()` in Einf. This shows how to create a service that can be injected into controllers or other services, promoting reusable logic. ```typescript import { Injectable } from 'einf' @Injectable() export class AppService { public createMsg(msg: string): string { return `"${msg}" is created by app service` } } ``` -------------------------------- ### Einf Controller Definition and IPC Handling Source: https://github.com/archergu/einf/blob/main/README.md Example of an `AppController` class using Einf decorators like `@Controller`, `@Inject`, `@IpcSend`, and `@IpcHandle`. This demonstrates dependency injection and setting up IPC communication between the main and renderer processes. ```typescript import type { BrowserWindow } from 'electron' import { Controller, Inject, IpcHandle, IpcSend, Window } from 'einf' import { app } from 'electron' import { AppService } from './app.service' @Controller() export class AppController { constructor( private appService: AppService, @Inject('IS_DEV') private isDev: boolean, @Window() private win: BrowserWindow, ) {} @IpcSend('reply-msg') public replyMsg(msg: string) { return msg } @IpcHandle('send-msg') public sendMsg(msg: string) { console.log(msg) return 'Get msg' } @IpcHandle('exit') public exit() { app.quit() } } ``` -------------------------------- ### Declare Injectable Services for Dependency Injection in Einf (TypeScript) Source: https://context7.com/archergu/einf/llms.txt Marks classes as injectable, allowing them to be automatically injected into controllers or other services. This example shows nested dependency injection, where `AppService` depends on `DatabaseService`. ```typescript import { Injectable } from 'einf' @Injectable() export class DatabaseService { private data: Map = new Map() public save(key: string, value: any): void { this.data.set(key, value) } public get(key: string): any { return this.data.get(key) } } @Injectable() export class AppService { constructor(private dbService: DatabaseService) { // Nested dependency injection works automatically } public processData(input: any): any { const processed = { ...input, processed: true, timestamp: Date.now() } this.dbService.save(`data_${Date.now()}`, processed) return processed } public getData(key: string): any { return this.dbService.get(key) } } ``` -------------------------------- ### Bidirectional IPC Handler with @IpcHandle (TypeScript) Source: https://context7.com/archergu/einf/llms.txt Registers a method as an IPC handler that responds to `ipcRenderer.invoke()` calls from the renderer process. It allows for two-way communication, where the renderer sends a request and waits for a response. This example shows file selection and saving functionality. ```typescript import { Controller, IpcHandle } from 'einf' import { dialog } from 'electron' @Controller() export class FileController { @IpcHandle('select-file') public async selectFile() { const result = await dialog.showOpenDialog({ properties: ['openFile'], filters: [ { name: 'Text Files', extensions: ['txt', 'md'] }, { name: 'All Files', extensions: ['*'] }, ], }) if (result.canceled) { return null } return result.filePaths[0] } @IpcHandle('save-file') public async saveFile(content: string) { const result = await dialog.showSaveDialog({ filters: [{ name: 'Text Files', extensions: ['txt'] }], }) if (result.canceled) { throw new Error('Save operation canceled') } const fs = require('fs').promises await fs.writeFile(result.filePath, content) return { success: true, path: result.filePath } } } // Renderer process usage: // const filePath = await ipcRenderer.invoke('select-file') // const result = await ipcRenderer.invoke('save-file', 'Hello World') ``` -------------------------------- ### One-way IPC Listener with @IpcOn (TypeScript) Source: https://context7.com/archergu/einf/llms.txt Registers a method as an IPC listener that responds to `ipcRenderer.send()` calls without returning a value. This is useful for events where the renderer sends data to the main process but doesn't need an immediate response. This example handles logging information. ```typescript import { Controller, IpcOn, Injectable } from 'einf' @Injectable() export class LogService { private logs: string[] = [] public addLog(message: string): void { const timestamp = new Date().toISOString() this.logs.push(`[${timestamp}] ${message}`) console.log(`[${timestamp}] ${message}`) } public getLogs(): string[] { return this.logs } } @Controller() export class LogController { constructor(private logService: LogService) {} @IpcOn('log-info') public logInfo(message: string) { this.logService.addLog(`INFO: ${message}`) } @IpcOn('log-error') public logError(error: string) { this.logService.addLog(`ERROR: ${error}`) } @IpcOn('log-debug') public logDebug(message: string, data: any) { this.logService.addLog(`DEBUG: ${message} - ${JSON.stringify(data)}`) } } // Renderer process usage: // ipcRenderer.send('log-info', 'User clicked button') // ipcRenderer.send('log-error', 'Failed to load data') // ipcRenderer.send('log-debug', 'State changed', { state: 'active' }) ``` -------------------------------- ### Bootstrap Einf Application with Controllers and Injectables (TypeScript) Source: https://context7.com/archergu/einf/llms.txt Initializes and configures the Einf application, including setting up the main window, registering controllers, and defining custom injectable items. It handles potential errors during bootstrapping and quits the application if initialization fails. ```typescript import { createEinf } from 'einf' import { app, BrowserWindow } from 'electron' import { AppController } from './app.controller' async function bootstrap() { try { // Create a browser window const window = new BrowserWindow({ webPreferences: { nodeIntegration: false, contextIsolation: true, }, }) window.loadURL('https://example.com') // Initialize Einf with controllers and custom injectables await createEinf({ window: window, // Can be a BrowserWindow, array of WindowOpts, or factory function controllers: [AppController], // Controllers to initialize injects: [ { name: 'IS_DEV', inject: !app.isPackaged, }, { name: 'APP_VERSION', inject: app.getVersion(), }, ], }) } catch (error) { console.error('Failed to bootstrap Einf:', error) app.quit() } } // Start when Electron app is ready bootstrap() ``` -------------------------------- ### Inject BrowserWindow Instance with @Window Source: https://context7.com/archergu/einf/llms.txt Shows how to inject an Electron BrowserWindow instance into controllers or services using the @Window decorator. This allows direct manipulation and access to window properties. Dependencies include 'einf' and 'electron'. ```typescript import { Controller, Window, IpcHandle } from 'einf' import { BrowserWindow } from 'electron' import { createEinf } from 'einf' @Controller() export class WindowController { constructor( @Window() private mainWin: BrowserWindow, // Inject default window @Window('settings') private settingsWin: BrowserWindow, // Inject named window ) { this.mainWin.setTitle('Main Window') this.settingsWin.setTitle('Settings Window') } @IpcHandle('toggle-fullscreen') public toggleFullscreen(windowName: string) { const win = windowName === 'settings' ? this.settingsWin : this.mainWin win.setFullScreen(!win.isFullScreen()) return win.isFullScreen() } @IpcHandle('get-window-info') public getWindowInfo(windowName: string) { const win = windowName === 'settings' ? this.settingsWin : this.mainWin const bounds = win.getBounds() return { title: win.getTitle(), isFullScreen: win.isFullScreen(), isMaximized: win.isMaximized(), bounds, } } @IpcHandle('close-settings') public closeSettings() { this.settingsWin.close() return { success: true } } } // Bootstrap with multiple windows const mainWindow = new BrowserWindow({ width: 800, height: 600 }) const settingsWindow = new BrowserWindow({ width: 400, height: 300 }) await createEinf({ window: [ { name: 'main', win: mainWindow }, { name: 'settings', win: settingsWindow }, ], controllers: [WindowController], }) ``` -------------------------------- ### Inject Custom Values with @Inject Source: https://context7.com/archergu/einf/llms.txt Demonstrates how to inject custom values provided during application initialization using the @Inject decorator. This is useful for providing configuration settings or constants to controllers and services. Dependencies include 'einf' and 'electron'. ```typescript import { Controller, Inject, IpcHandle } from 'einf' import { createEinf } from 'einf' import { app } from 'electron' @Controller() export class ConfigController { constructor( @Inject('IS_DEV') private isDev: boolean, @Inject('APP_VERSION') private appVersion: string, @Inject('API_URL') private apiUrl: string, @Inject('MAX_RETRIES') private maxRetries: number, ) { console.log('Configuration loaded:', { isDev: this.isDev, version: this.appVersion, apiUrl: this.apiUrl, }) } @IpcHandle('get-config') public getConfig() { return { isDev: this.isDev, version: this.appVersion, apiUrl: this.apiUrl, maxRetries: this.maxRetries, } } @IpcHandle('fetch-data') public async fetchData(endpoint: string) { const url = `${this.apiUrl}${endpoint}` let attempts = 0 while (attempts < this.maxRetries) { try { // Fetch logic here return { success: true, data: 'mock data' } } catch (error) { attempts++ if (attempts >= this.maxRetries) throw error } } } } // Bootstrap with custom injects await createEinf({ window: mainWindow, controllers: [ConfigController], injects: [ { name: 'IS_DEV', inject: !app.isPackaged }, { name: 'APP_VERSION', inject: app.getVersion() }, { name: 'API_URL', inject: 'https://api.example.com' }, { name: 'MAX_RETRIES', inject: 3 }, ], }) ``` -------------------------------- ### Create Colorized Logger with createLogger Source: https://context7.com/archergu/einf/llms.txt Illustrates the usage of the `createLogger` utility from 'einf' to generate a logger instance with colorized output for different log levels (info, success, warn, error). It can also be used within services for application logging. ```typescript import { createLogger } from 'einf' // Create logger with custom name const logger = createLogger('MyApp') // Log different types of messages logger.info('Application starting...') logger.success('Connected to database') logger.warn('Configuration file not found, using defaults') logger.error('Failed to load plugin') // Plain log without type logger.log('Plain message') // Add line break logger.break() // Example: Use in service import { Injectable } from 'einf' @Injectable() export class DataService { private logger = createLogger('DataService') public async loadData() { this.logger.info('Loading data...') try { // Simulate data loading await new Promise(resolve => setTimeout(resolve, 1000)) this.logger.success('Data loaded successfully') return { records: 100 } } catch (error) { this.logger.error(`Failed to load data: ${error.message}`) throw error } } public async saveData(data: any) { this.logger.info('Saving data...') if (!data) { this.logger.warn('No data provided, skipping save') return } // Save logic this.logger.success('Data saved') } } ``` -------------------------------- ### Enable Decorators and Metadata for Einf (TypeScript) Source: https://context7.com/archergu/einf/llms.txt This configuration enables experimental decorators and emits decorator metadata, which are essential for the Einf framework's functionality. It sets the target to ES2020, uses CommonJS modules, and includes specific compiler options for decorator support, interoperability, and strict type checking. The configuration also specifies input and output directories and excludes certain folders from the build process. ```json { "compilerOptions": { "target": "ES2020", "module": "commonjs", "lib": ["ES2020"], "experimentalDecorators": true, "emitDecoratorMetadata": true, "esModuleInterop": true, "skipLibCheck": true, "strict": true, "resolveJsonModule": true, "outDir": "./dist", "rootDir": "./src" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } ``` -------------------------------- ### Declare an Einf Controller with IPC Handlers and Dependency Injection (TypeScript) Source: https://context7.com/archergu/einf/llms.txt Marks a class as a controller, enabling automatic initialization and IPC handler registration. It demonstrates injecting services, custom items, and the main window, along with defining IPC handlers for receiving and sending messages. ```typescript import { Controller, Inject, IpcHandle, IpcSend, Window } from 'einf' import { app, BrowserWindow } from 'electron' import { AppService } from './app.service' @Controller() export class AppController { constructor( private appService: AppService, // Inject service @Inject('IS_DEV') private isDev: boolean, // Inject custom item @Window() private win: BrowserWindow, // Inject main window ) { // Constructor runs after all dependencies are injected this.win.setTitle('My Application') console.log(`Running in ${this.isDev ? 'development' : 'production'} mode`) } @IpcHandle('get-app-info') public async getAppInfo() { return { version: app.getVersion(), isDev: this.isDev, title: this.win.getTitle(), } } @IpcHandle('process-data') public async processData(data: any) { // Use injected service return this.appService.processData(data) } @IpcSend('notification') public sendNotification(message: string) { // Return value will be sent to renderer via 'notification' channel return { message, timestamp: Date.now() } } } ``` -------------------------------- ### Push Data to Renderer (@IpcSend) Source: https://context7.com/archergu/einf/llms.txt Automatically send the return value of a method to the renderer process via a specified channel using `ipcRenderer.on()`. ```APIDOC ## POST /ipcSend ### Description Allows the main process to push data to the renderer process. The return value of the decorated method is automatically sent to the renderer on the specified channel. ### Method POST (via @IpcSend decorator) ### Endpoint As defined by the channel name string passed to `@IpcSend` (e.g., 'status-update', 'progress-update'). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body Arguments passed to the method when it's called (e.g., from another IPC handler). ### Request Example ```typescript // In the main process, calling a method decorated with @IpcSend: this.sendStatus('processing'); // Renderer Process Usage: ipcRenderer.on('status-update', (event, data) => { console.log('Status received:', data); }); // Example of triggering an @IpcSend method via @IpcHandle: // await ipcRenderer.invoke('start-process'); ``` ### Response #### Success Response (200) The return value of the decorated method is sent to the renderer. #### Response Example ```json // Example for 'status-update': { "status": "completed", "timestamp": 1678886400000, "windowTitle": "My App" } // Example for 'progress-update': { "current": 5, "total": 10, "percentage": 50 } ``` ``` -------------------------------- ### One-way IPC Listener (@IpcOn) Source: https://context7.com/archergu/einf/llms.txt Register methods to listen for `ipcRenderer.send()` calls from the renderer process. These handlers do not return values. ```APIDOC ## POST /ipcOn ### Description Handles one-way IPC communication, allowing the main process to listen for `ipcRenderer.send()` calls from the renderer process. These handlers do not return values directly to the sender. ### Method POST (via @IpcOn decorator) ### Endpoint As defined by the channel name string passed to `@IpcOn` (e.g., 'log-info', 'log-error'). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body Arguments passed from `ipcRenderer.send()`. ### Request Example ```typescript // Renderer Process Usage: ipcRenderer.send('log-info', 'User logged in'); ipcRenderer.send('log-error', 'Database connection failed'); ipcRenderer.send('log-debug', 'Data fetched', { userId: 123 }); ``` ### Response #### Success Response (200) No direct response is sent back to the renderer process. #### Response Example N/A ``` -------------------------------- ### TypeScript Configuration for Einf Decorators Source: https://github.com/archergu/einf/blob/main/README.md Configuration snippet for `tsconfig.json` required by Einf. It ensures that `experimentalDecorators` and `emitDecoratorMetadata` are enabled, which are necessary for the framework's decorator-based functionality. ```json { "compilerOptions": { // ... other options "experimentalDecorators": true, "emitDecoratorMetadata": true } } ``` -------------------------------- ### Bidirectional IPC Handler (@IpcHandle) Source: https://context7.com/archergu/einf/llms.txt Register methods to handle `ipcRenderer.invoke()` calls from the renderer process. These handlers can return values back to the caller. ```APIDOC ## POST /ipcHandle ### Description Handles bidirectional IPC communication, allowing the main process to respond to `ipcRenderer.invoke()` calls from the renderer process. ### Method POST (via @IpcHandle decorator) ### Endpoint As defined by the channel name string passed to `@IpcHandle` (e.g., 'select-file', 'save-file'). ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body Arguments passed from `ipcRenderer.invoke()`. ### Request Example ```typescript // Renderer Process Usage: const filePath = await ipcRenderer.invoke('select-file'); const result = await ipcRenderer.invoke('save-file', 'File content'); ``` ### Response #### Success Response (200) Data returned from the handler method. Can be any serializable type, or null. #### Response Example ```json // Example for 'select-file': "/path/to/selected/file.txt" // Example for 'save-file': { "success": true, "path": "/path/to/saved/file.txt" } ``` ### Error Handling Throws an error if the handler encounters an issue (e.g., save operation canceled). ``` -------------------------------- ### Push Data to Renderer with @IpcSend (TypeScript) Source: https://context7.com/archergu/einf/llms.txt Registers a method that automatically sends its return value to the renderer process via a specified channel. This is ideal for scenarios where the main process needs to update the renderer with data, such as status or progress updates. It can also be triggered by other IPC handlers. ```typescript import { Controller, IpcSend, IpcHandle, Window } from 'einf' import { BrowserWindow } from 'electron' @Controller() export class NotificationController { constructor(@Window() private win: BrowserWindow) {} // Method's return value is automatically sent to renderer @IpcSend('status-update') public sendStatus(status: string) { return { status, timestamp: Date.now(), windowTitle: this.win.getTitle(), } } @IpcSend('progress-update') public sendProgress(current: number, total: number) { return { current, total, percentage: Math.round((current / total) * 100), } } // Can be triggered from other IPC handlers @IpcHandle('start-process') public async startProcess() { for (let i = 1; i <= 10; i++) { await new Promise(resolve => setTimeout(resolve, 500)) this.sendProgress(i, 10) } this.sendStatus('completed') return { success: true } } } // Renderer process usage: // ipcRenderer.on('status-update', (event, data) => { // console.log('Status:', data.status, 'at', data.timestamp) // }) // ipcRenderer.on('progress-update', (event, data) => { // console.log(`Progress: ${data.percentage}%`) // }) // await ipcRenderer.invoke('start-process') ``` -------------------------------- ### Renderer IPC: Send, Reply, Error, Log, Exit Source: https://github.com/archergu/einf/blob/main/tests/mock/index.html This JavaScript code runs in the renderer process, utilizing `window.electron` for IPC. It logs messages, sends data to the main process, awaits replies, simulates an error, and eventually exits the application. Dependencies include the Electron `window.electron` object. ```javascript const { sendMsg, sendAnotherMsg, throwError, printLog, onReplyMsg, exit } = window.electron printLog('Call ipc on') onReplyMsg(async (msg) => { printLog(msg) const msgFromMain = await sendMsg('hello, this is the renderer') printLog(msgFromMain) const anotherMsgFromMain = await sendAnotherMsg('hello, this is the renderer again') printLog(anotherMsgFromMain) try { await throwError() } catch (error) { await printLog(error.message) } setTimeout(() => { exit() }, 500) }) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.