@canlooks/roost-electron
v0.0.1
Published
A backend micro service framework
Downloads
162
Readme
@canlooks/roost-electron
Electron main process plugin for the Roost microservice framework. Bridges Electron's IPC (Inter-Process Communication) from renderer processes directly to Roost service controllers running in the main process.
Overview
@canlooks/roost-electron is a lightweight plugin that registers an ipcMain.handle() listener on a configurable channel. When a renderer process sends an IPC invoke call, the plugin forwards the invocation key and arguments to app.invoke(), routing the request to the matching Roost controller action.
Paired with @canlooks/roost-electron-renderer on the renderer side, this enables seamless RPC-style communication where renderer-side controller method calls are transparently proxied via Electron IPC to the main process.
Installation
npm install @canlooks/roost-electronPeer dependencies:
@canlooks/roost(core framework)electron(main process runtime)
Quick Start
Main Process
import { app, BrowserWindow } from 'electron'
import Roost from '@canlooks/roost'
import { ElectronMainPlugin } from '@canlooks/roost-electron'
import { MyService } from './services/MyService'
async function main() {
const roost = await Roost.create({
named: { MyService },
plugins: [
ElectronMainPlugin()
]
})
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
}
app.whenReady().then(main)Renderer Process (with @canlooks/roost-electron-renderer)
import { contextBridge, ipcRenderer } from 'electron'
import { createRoostRenderer } from '@canlooks/roost-electron-renderer'
import { MyService } from '../services/MyService'
contextBridge.exposeInMainWorld('roost', {
services: await createRoostRenderer(
{ MyService },
{ ipcRenderer }
)
})Then, in the renderer page:
// MyService methods are transparently proxied to the main process
const result = await window.roost.services.MyService.doSomething(args)API Reference
ElectronMainPlugin(options?)
Factory function that creates a Roost Plugin object for the Electron main process.
function ElectronMainPlugin(options?: ElectronMainPluginOptions): PluginElectronMainPluginOptions
| Property | Type | Default | Description |
| --------- | -------- | ----------------------------- | ---------------------------------------------------------- |
| channel | string | "@canlooks/roost-electron" | The IPC channel name used for ipcMain.handle(). Customize this to avoid conflicts with other IPC handlers. |
Return Value
Returns a Plugin object conforming to the Roost Plugin interface:
{
name: 'electron-main',
onStaticInjected: (app: Roost) => void
}registerIpcMain(app, options?)
Low-level function called internally by the plugin. Registers the ipcMain.handle() listener directly.
function registerIpcMain(app: Roost, options?: ElectronMainPluginOptions): voidThis is exported for advanced use cases where you need to control registration timing manually. In most cases, use
ElectronMainPlugin()instead.
How It Works
Architecture
┌─────────────────────────────────────────────────────────┐
│ Renderer Process │
│ ┌───────────────────────────────────────────────────┐ │
│ │ createRoostRenderer({ MyService }, { ipcRenderer })│ │
│ │ → Rewrites MyService methods to call │ │
│ │ ipcRenderer.invoke(channel, key, ...args) │ │
│ └───────────────────────┬───────────────────────────┘ │
└──────────────────────────┼──────────────────────────────┘
│ Electron IPC
┌──────────────────────────┼──────────────────────────────┐
│ Main Process │ │
│ ┌───────────────────────▼───────────────────────────┐ │
│ │ ElectronMainPlugin │ │
│ │ → ipcMain.handle(channel, (e, key, ...args) => { │ │
│ │ return app.invoke(key, ...args) │ │
│ │ }) │ │
│ └───────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌───────────────────────▼───────────────────────────┐ │
│ │ Roost App │ │
│ │ → app.invoke(key, ...args) │ │
│ │ → Route to matching @Controller/@Action │ │
│ │ → Execute, return result │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘Lifecycle
The plugin hooks into the onStaticInjected lifecycle event of Roost:
Roost.create()is called with the plugin in thepluginsarray.- Roost registers all modules and performs dependency injection.
onStaticInjectedfires — the plugin registersipcMain.handle()on the configured channel.- The main process is now ready to receive IPC calls from renderer processes.
Invocation Flow
When a renderer calls window.roost.services.MyService.doSomething(arg):
@canlooks/roost-electron-rendererrewrites the method to callipcRenderer.invoke('@canlooks/roost-electron', 'path/to/action', arg).- The IPC message arrives in the main process.
- The
ipcMain.handle()listener receives(event, key, arg). - It calls
app.invoke(key, arg)on the Roost instance. - Roost's
Invokermatches the key against registered controllers and actions (path-based, pattern-based, or regex-based routing). - The matched controller method executes and returns a result.
- The result is sent back through the IPC channel to the renderer.
Custom Channel
If the default channel name conflicts with other IPC handlers in your application, provide a custom channel:
ElectronMainPlugin({ channel: 'my-app:rpc' })Make sure to use the same channel name in the renderer side:
createRoostRenderer(
{ MyService },
{ ipcRenderer, channel: 'my-app:rpc' }
)Project Structure
packages/electron/
├── src/
│ ├── index.ts # Plugin factory + type exports
│ └── registerIpcMain.ts # IPC handler registration
├── dist/
│ ├── cjs/ # CommonJS build output
│ └── esm/ # ES Module build output
├── test/
├── package.json
├── tsconfig.json
├── LICENSE
└── README.mdTypeScript
The package is written in TypeScript and ships with declaration files. TypeScript 6.0+ and strict mode are used during development.
Exports
// Factory function
export function ElectronMainPlugin(options?: ElectronMainPluginOptions): Plugin
// Options type
export type ElectronMainPluginOptions = {
channel?: string
}
// Low-level registration function
export function registerIpcMain(app: Roost, options?: ElectronMainPluginOptions): voidRelated Packages
| Package | Description |
| ------- | ----------- |
| @canlooks/roost | Core microservice framework |
| @canlooks/roost-electron-renderer | Renderer-side companion — creates proxy controllers that communicate via IPC |
License
MIT © C.CanLiang
