UNPKG

electron-postman

Version:

Easy Electron IPC with focus on window-to-window communication and disabled node integration in renderers

278 lines (187 loc) 7.35 kB
# Electon Postman :mailbox_with_mail: Electron Postman is an easy-to-use wrapper around Electron's built-in IPC library. Features: - Similar IPC methods in main and renderer process - Easy and direct window-to-window communication - Integrates smoothly in `nodeIntegration` disabled and `contextIsolation` enabled BrowserWindows - Allows `invoke` calls not only from renderer to main process, but also the other way around ## Example You can register windows on creation. The window registration is broadcasted to all other windows automatically. ```js // main.js ipcMain.registerBrowserWindow('window-a', windowA); ``` From now on, windows can communicate directly with each other. ```js // windowB.js ipcRenderer.sendTo('window-a', 'channel-name', args); ``` If you implement [Electron's security recommandations](https://www.electronjs.org/docs/tutorial/security) and have disabled node integration and enabled context isolation for browser windows, you can expose Electron Postman easily via a preload script. ```js // preload.js ipcRenderer.exposeToMainWorld('ipc'); ``` ```js // windowA.js window.ipc.invokeTo('window-b').then((result) => console.log(result)); ``` ## Installation Yarn: ```sh yarn add electron-postman ``` npm: ```sh npm install electron-postman ``` ## Usage 1. Register a window **before** its content is loaded. ```js // main.js const { ipcMain } = require('electron-postman'); // ... const mainWindow = createMainWindow(); ipcMain.registerBrowserWindow('main-window', mainWindow); mainWindow.loadFile(path); ``` 2. (Optional) If using a preload script, expose the API to the renderer process. ```js // preload.js const { ipcRenderer } = require('electron-postman'); ipcRenderer.exposeToMainWorld('ipc'); ``` 3. Send, invoke, handle and receive messages in main and in renderer processes. ## API ### `ipcMain` #### `ipcMain.registerBrowserWindow(windowName, browserWindow)` - `windowName` String - `browserWindow` BrowserWindow Registers the window and is made known with all other existing windows. #### `ipcMain.sendTo(windowName, channel, ...args)` - `windowName` String - `channel` String - `...args` any[] Send an asynchronous message to the renderer process via `channel`, along with arguments. Requires that `windowName` is a registered window. The renderer process can handle the message by listening to `channel`. #### `ipcMain.on(windowName, channel, listener)` - `windowName` String - `channel` String - `listener` Function - `...args` any[] Listen to messages on `channel` from window `windowName`. Requires that `windowName` is a registered window. #### `ipcMain.once(windowName, channel, listener)` - `windowName` String - `channel` String - `listener` Function - `...args` any[] Same as `ipcMain.on`, but listener is removed once a message on `channel` was received. #### `ipcMain.invokeTo(windowName, channel, ...args)` - `windowName` String - `channel` String - `...args` any[] Returns `Promise<any>` - Resolves with the response from the other process. Send a message to `windowName` via `channel` and expect a result asynchronously. The other process should listen for channel with `ipcMain.handle()` or `ipcRenderer.handle()` respectively. #### `ipcMain.handle(windowName, channel, listener)` - `windowName` String - `channel` String - `listener` Function - `...args` any[] Adds a handler for an invokeable IPC. This handler will be called whenever a renderer calls `ipcRenderer.invoke(channel, ...args)` or `ipcRenderer.invokeTo('main', channel, ...args`. If listener returns a Promise, the eventual result of the promise will be returned as a reply to the remote caller. Otherwise, the return value of the listener will be used as the value of the reply. #### `ipcMain.handleOnce(windowName, channel, listener)` - `windowName` String - `channel` String - `listener` Function - `...args` any[] Same as `ipcMain.handle`, but handler is removed once an invoke call was handled. #### `ipcMain.removeAllListeners(windowName, channel)` - `windowName` String - `channel` String Removes all listeners registered on `windowName` and `channel`. #### `ipcMain.removeHandler(windowName, channel)` - `windowName` String - `channel` String Removes handler, registered on `windowame` and `channel`. ### `ipcRenderer` Each process is addressed with its process name (`processName`). For a renderer process, its process name is the registered window name (renderer-to-renderer communication), the main process has the process name `'main'` (renderer-to-main communication). #### `ipcRenderer.exposeToMainWorld(apiKey)` - `apiKey` String Exposes the IPC renderer API to context isolated renderer process. Works only, if `contextIsolation` is enabled for that window. Uses Electron's `contextBridge` API. #### `ipcRenderer.send(channel, ...args)` - `channel` String - `...args` any[] Equivalent to `ipcRenderer.sendTo('main', channel, ...args)`. #### `ipcRenderer.sendTo(processName, channel, ...args)` - `processName` String - `channel` String - `...args` any[] Send an asynchronous message to the process registered as `processName` via `channel`, along with arguments. The receiving process can handle the message by listening to `channel`. #### `ipcRenderer.on(processName, channel, listener)` - `processName` String - `channel` String - `listener` Function - `...args` any[] Listen to messages on `channel` from process `processName`. #### `ipcRenderer.once(processName, channel, listener)` - `processName` String - `channel` String - `listener` Function - `...args` any[] Same as `ipcMain.on`, but listener is removed once a message on `channel` was received. #### `ipcRenderer.invoke(channel, ...args)` - `processName` String - `channel` String - `...args` any[] Equivalent to `ipcRenderer.invokeTo('main', channel, ...args)`. #### `ipcRenderer.invokeTo(processName, channel, ...args)` - `processName` String - `channel` String - `...args` any[] Returns `Promise<any>` - Resolves with the response from the other process. Send a message to `windowName` via `channel` and expect a result asynchronously. The other process should listen for channel with `ipcMain.handle()` or `ipcRenderer.handle()` respectively. #### `ipcRenderer.handle(processName, channel, listener)` - `processName` String - `channel` String - `listener` Function - `...args` any[] Adds a handler for an invokeable IPC. This handler will be called whenever a process calls `.invoke('this-window-name', channel, ...args)`. If listener returns a Promise, the eventual result of the promise will be returned as a reply to the remote caller. Otherwise, the return value of the listener will be used as the value of the reply. #### `ipcRenderer.handleOnce(processName, channel, listener)` - `processName` String - `channel` String - `listener` Function - `...args` any[] Same as `ipcRenderer.handle`, but handler is removed once an invoke call was handled. #### `ipcRenderer.removeAllListeners(processName, channel)` - `processName` String - `channel` String Removes all listeners registered on `processName` and `channel`. #### `ipcRenderer.removeHandler(processName, channel)` - `processName` String - `channel` String Removes handler, registered on `processName` and `channel`.