@cyoot/electron-nexus
v1.0.2
Published
Gerenciador de janelas robusto para Electron.
Maintainers
Readme
⚡ Electron Nexus
O elo perdido entre o Electron e uma arquitetura limpa.
Electron Nexus é um micro-framework robusto e tipado para o desenvolvimento de aplicações Electron profissionais. Ele transforma a complexidade do Processo Principal (Main Process) em uma arquitetura orientada a objetos, segura e escalável.
Índice
- Por que usar?
- Instalação
- Conceitos Principais
- Exemplo de Uso
- Segurança e Preload
- TypeScript
- Estrutura Sugerida
- Licença
Por que usar?
O desenvolvimento nativo ("Vanilla") no Electron apresenta desafios arquiteturais comuns que o Nexus resolve:
- Desacoplamento: Em vez de concentrar toda a lógica em arquivos ou variáveis soltas, cada janela possui sua própria Classe dedicada com visual, eventos e comunicação isolados.
- Gerenciamento de Instâncias: O Nexus mantém um registro interno (Registry) de todas as janelas ativas, eliminando a necessidade de gerenciar arrays manuais de IDs para evitar o Garbage Collection.
- IPC Seguro (Escopado): Diferente do 'ipcMain.on' nativo que é global, os canais criados com o Nexus são vinculados apenas à janela que os criou. Se uma janela dispara um evento, apenas o controlador dela responde.
- Roteamento Inteligente: Facilita a comunicação entre janelas (Broadcast) ou o envio direto de mensagens do Backend para o Frontend sem malabarismos com 'webContents'.
Instalação
npm install @cyoot/electron-nexus
# ou
yarn add @cyoot/electron-nexus
# ou
pnpm add @cyoot/electron-nexusConceitos Principais
| Componente | Função | | :--- | :--- | | WindowController | Inicia o app, gerencia o ciclo de vida e aplica configurações globais. | | WindowBuilder | Define aparência ('width', 'height', 'webPreferences') e conteúdo ('.file', '.url') no construtor da classe. | | IpcChannel | Cria canais de comunicação isolados por instância. O 'reply' volta sempre para o remetente correto. | | WindowEvents | Gerencia eventos nativos da janela ('close', 'blur', 'focus', etc) de forma limpa. | | WindowRouter | Utilitário para comunicação ativa (Backend -> Frontend) e Broadcasts. |
Exemplo de Uso
Neste exemplo, vamos criar uma aplicação onde a Janela Principal envia dados e abre uma Janela Modal.
1. Definindo a Janela Principal
A classe encapsula toda a lógica. Observe que usamos 'WindowBuilder' para o visual e 'IpcChannel' para a lógica.
// windows/MainWindow.ts
import { WindowBuilder, IpcChannel, WindowEvents, WindowRouter } from '@cyoot/electron-nexus';
import path from 'path';
export class MainWindow {
constructor() {
// 1. Configuração Visual
new WindowBuilder({ singleton: true }) // Impede múltiplas instâncias desta janela
.setup({ width: 800, height: 600, title: "Nexus App" })
.file(path.join(__dirname, 'index.html'))
.setup({ webPreferences: { preload: path.join(__dirname, 'preload.js') } });
// 2. Comunicação Segura
new IpcChannel()
.on('ping', (evt, win, data) => {
console.log(`[Nexus Main] Recebido:`, data);
// Responde apenas para quem chamou
evt.reply('pong', { msg: 'Pong do Nexus!' });
// Avisa outras janelas (Broadcast)
WindowRouter.broadcast('broadcast-event', { info: 'Atualização via Nexus' });
});
// 3. Eventos Nativos
new WindowEvents()
.on('close', (evt, win) => {
console.log("Main fechando...");
});
}
}2. Definindo uma Janela Modal
Uma janela secundária que será controlada pela principal.
// windows/ModalWindow.ts
import { WindowBuilder } from '@cyoot/electron-nexus';
import path from 'path';
export class ModalWindow {
constructor() {
new WindowBuilder()
.setup({
width: 400,
height: 300,
title: "Modal Nexus",
minimizable: false
// parent será definido automaticamente na abertura via controller
})
.file(path.join(__dirname, 'modal.html'))
.setup({ webPreferences: { preload: path.join(__dirname, 'preload.js') } });
}
}3. Configurando o Maestro (Main Process)
No arquivo principal ('main.ts'), inicializamos o controlador. Aqui definimos defaults globais e orquestramos a abertura.
// main.ts
import { app } from 'electron';
import { WindowController } from '@cyoot/electron-nexus';
import { MainWindow } from './MainWindow';
import { ModalWindow } from './ModalWindow';
// Configurações globais (aplicadas a todas as janelas abertas por este controller)
const nexus = new WindowController({
defaults: {
backgroundColor: '#f0f0f0',
frame: true,
icon: './assets/icon.png'
}
});
app.whenReady().then(() => {
// Ao abrir, recebemos a referência da INSTÂNCIA da classe
const mainInstance = nexus.open(MainWindow);
setTimeout(() => {
// Usamos a referência 'mainInstance' para definir o pai.
// A lib resolve automaticamente a janela nativa por trás dessa instância.
nexus.open(ModalWindow, {
parent: mainInstance,
modal: true
});
}, 3000);
});
app.on('window-all-closed', () => app.quit());Segurança e Preload
O Nexus encoraja o uso de Context Isolation. Em vez de expor métodos genéricos como 'send/on' (que podem ser inseguros), recomenda-se expor métodos específicos da sua aplicação.
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('api', {
// Exponha apenas o que a UI precisa chamar
ping: (mensagem) => ipcRenderer.send('ping', mensagem),
// Exponha apenas os ouvintes necessários
onPong: (callback) => {
const subscription = (event, ...args) => callback(...args);
ipcRenderer.on('pong', subscription);
// Retorna função de limpeza
return () => ipcRenderer.removeListener('pong', subscription);
}
});TypeScript
A biblioteca inclui definições de tipos ('.d.ts') completas. Use Generics nos métodos de IPC para garantir que o payload recebido esteja tipado corretamente no seu editor.
interface UserData {
id: number;
name: string;
}
new IpcChannel()
// O 'data' será automaticamente tipado como UserData
.on<UserData>('user:save', (evt, win, data) => {
console.log(data.name); // Autocomplete funcionando!
});Estrutura Sugerida
Para manter a arquitetura limpa, sugerimos a seguinte organização de pastas:
src/
├── main/
│ ├── windows/ # Suas classes de janela
│ │ ├── MainWindow.ts
│ │ └── ModalWindow.ts
│ └── main.ts # Entrada do Electron + Controller
├── preload/
│ └── index.ts
└── renderer/ # Seu Frontend (React, Vue, etc)Licença
MIT © Carlosyoot
