electron-typed-ipc-bridge
v2.1.1
Published
Fully type-safe Electron context bridge generator for IPC (Inter-Process Communication).
Downloads
825
Maintainers
Readme
What is the electron-typed-ipc-bridge?
Generate api on the bridge across isolated contexts of the electron.
Why use this library?
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??)
How to use it?
install
npm install electron-typed-ipc-bridge
How to implement this library??
Core
There are 5 STEPS to use this library.
Create api on
main
scriptImplement 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 aton
by step.1-1)IpcBridgeApi
: For the type of exposed api(exposed to renderer, defined atinvoke
andon
by 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
Add handler at
main.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 ofipcApi
is same asIpcBridgeApiEmitter
exported 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
Add invoker at
preload.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
Add type decoration
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
Call the exposed API or add a handler for messages sent via the API at renderer.
Use api defined at
invoke
with type-safe!window.api.invoke.showContextMenu()
Add handler of messages from main defined at
on
with type-safe!window.api.on.updateCounter((_e, value) => (counter.value = counter.value + value))
See the playground code:
renderer/src/App.vue
Logging for this library
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.
Disable logging
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: {} })
Implement custom logger.
Import 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() } })
Log Level
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 |