Generate api on the bridge across isolated contexts of the electron.
There are following reasons.
-
When implementing IPC using contextBridge, we want to use it in a type-safe.
-
We want to be free from channel management.
This library is automatically generate channel ids with uuid.
We can feel free to manage channel strings.(don't worry about typos. e.g. say-hello or do-hello??)
npm install electron-typed-ipc-bridge
There are 5 STEPS to use this library.
-
-
Implement the API of the IPC context bridge
invoke: renderer --(data)--> main --(return data)--> renderer
return data is the optionon: main --(data)--> renderer
if you want to return data from renderer to main, use the invoke api.
export const api = { invoke: { ping: () => console.log('pong'), showContextMenu: getContextMenuHandler(), }, on: { updateCounter: (value: number) => value, }, }
-
Generate and export type definitions
IpcBridgeApiEmitter: For the type of Emitter to use message from main to renderer.(defined atonby step.1-1)IpcBridgeApi: For the type of exposed api(exposed to renderer, defined atinvokeandonby step.1-1)
import type { IpcBridgeApiEmitterGenerator, IpcBridgeApiGenerator, } from 'electron-typed-ipc-bridge/main' export type IpcBridgeApiEmitter = IpcBridgeApiEmitterGenerator<typeof api> export type IpcBridgeApi = IpcBridgeApiGenerator<typeof api>
See the playground code:
main/api/index.ts -
-
-
Resister IPC handlers(apis defined at
invoke)import { getIpcBridgeApiEmitter, registerIpcHandler } from 'electron-typed-ipc-bridge/main' import { api } from './api' registerIpcHandler(api)
-
Generate the Ipc context bridge API Emitter(apis defined at
on)
The type ofipcApiis same asIpcBridgeApiEmitterexported by Step1const ipcApi = getIpcBridgeApiEmitter(api) // When send a message to renderer, // use as following code //(see the playground code of `setMenu(mainWindow, api)` // at the `createWindow(ipcApi)`) ipcApi.send.updateCounter(mainWindow, 1)
See the playground code:
main/index.ts -
-
-
Generate Ipc Context Bridge API
import { generateIpcBridgeApi } from 'electron-typed-ipc-bridge/preload' import type { IpcBridgeApi } from '../main/api' const api = await generateIpcBridgeApi<IpcBridgeApi>()
-
Expose the API to renderer
See the playground code:
preload/index.ts -
-
Extends the window object.
Import the type exported by Step1 and use it as follow.import type { IpcBridgeApi } from '../main/api' declare global { interface Window { electron: ElectronAPI api: IpcBridgeApi } }
See the playground code:
preload/index.d.ts -
-
Use api defined at
invokewith type-safe!window.api.invoke.showContextMenu()
-
Add handler of messages from main defined at
onwith type-safe!window.api.on.updateCounter((_e, value) => (counter.value = counter.value + value))
See the playground code:
renderer/src/App.vue -
This library is implemented the logger using console.log, console.error and console.debug.
But you may want to disable logging or use another logging library(e.g. electron-log).
This library provides a way in which you can do so.
Import the initialize function and set empty object to logger.
Call it before calling another functions exported by this library.
-
main.ts
import { initialize } from 'electron-typed-ipc-bridge/main' initialize({ logger: {} })
-
preload.ts
import { initialize } from 'electron-typed-ipc-bridge/preload' initialize({ logger: {} })
Sample code is here.
Import AbstractLogger and implement it.
Please expand this section who are interested in.
AbstractLogger and implement it.Please expand this section who are interested in.
import { AbstractLogger, type LogLevel } from 'electron-typed-ipc-bridge'
export class MyLogger extends AbstractLogger {
protected writeLog(level: LogLevel, message: string): void {
switch (level) {
case 'info':
case 'warn':
console.log(message)
break
case 'error':
console.error(message)
break
case 'verbose':
case 'debug':
case 'silly':
console.debug(message)
break
}
}
}Set to the logger to this library.
-
main.ts
import { initialize } from 'electron-typed-ipc-bridge/main' initialize({ logger: { main: new MyLogger() } })
-
preload.ts
import { initialize } from 'electron-typed-ipc-bridge/preload' initialize({ logger: { preload: new MyLogger() } })
Each log levels are output following information.
(This is what we do now, but this may change in the future.)
| level | overview |
|---|---|
| info | Output the start and end of processing by the library |
| warn | - (Not used) |
| error | Output the message when runtime error occurred. |
| verbose | - (Not used) |
| debug | Output detailed log regarding IpcBridgeApi generation process |
| silly | Output the function name and channel every time IpcBridgeApi is used |