npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

electron-typed-ipc-bridge

v2.1.1

Published

Fully type-safe Electron context bridge generator for IPC (Inter-Process Communication).

Downloads

825

Readme

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

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