2.1.3 • Published 7 months ago

electron-typed-ipc-bridge v2.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

npm version Run Test codecov CodeFactor Maintainability GitHub

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.

  1. When implementing IPC using contextBridge, we want to use it in a type-safe.

  2. 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.

  1. Create api on main script

    1. Implement the API of the IPC context bridge

      • invoke : renderer --(data)--> main --(return data)--> renderer
        return data is the option
      • on : 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,
        },
      }
    2. Generate and export type definitions

      • IpcBridgeApiEmitter: For the type of Emitter to use message from main to renderer.(defined at on by step.1-1)
      • IpcBridgeApi : For the type of exposed api(exposed to renderer, defined at invoke and on 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

  2. Add handler at main.ts

    1. Resister IPC handlers(apis defined at invoke)

      import { getIpcBridgeApiEmitter, registerIpcHandler } from 'electron-typed-ipc-bridge/main'
      import { api } from './api'
      registerIpcHandler(api)
    2. Generate the Ipc context bridge API Emitter(apis defined at on)
      The type of ipcApi is same as IpcBridgeApiEmitter exported by Step1

      const 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

  3. Add invoker at preload.ts

    1. Generate Ipc Context Bridge API

      import { generateIpcBridgeApi } from 'electron-typed-ipc-bridge/preload'
      import type { IpcBridgeApi } from '../main/api'
      const api = await generateIpcBridgeApi<IpcBridgeApi>()
    2. Expose the API to renderer

    See the playground code: preload/index.ts

  4. 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

  5. Call the exposed API or add a handler for messages sent via the API at renderer.

    1. Use api defined at invoke with type-safe!

      window.api.invoke.showContextMenu()
    2. 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.)

leveloverview
infoOutput the start and end of processing by the library
warn- (Not used)
errorOutput the message when runtime error occurred.
verbose- (Not used)
debugOutput detailed log regarding IpcBridgeApi generation process
sillyOutput the function name and channel every time IpcBridgeApi is used
2.1.3

7 months ago

2.1.2

8 months ago

2.1.1

8 months ago

2.0.2

9 months ago

2.1.0

9 months ago

1.2.0

9 months ago

2.0.1

9 months ago

2.0.0

9 months ago

1.1.0

9 months ago

1.0.0

9 months ago

0.0.10

9 months ago

0.0.9

9 months ago

0.0.8

9 months ago