Skip to content

Redux IPC abstraction layer that uses middleware to forward actions between the main and renderer processes.

License

Notifications You must be signed in to change notification settings

laserware/redial

Repository files navigation

Redial

Redux IPC abstraction layer that uses middleware to forward actions between the main and renderer processes.

Dependencies

  • Node.js >= v22
  • TypeScript >= v5
  • Electron >= v30

Usage

Getting the library working is a three-step process:

  1. Set up the communication layer in a preload script.
  2. Add Redial middleware to the Redux store in the main process
  3. Add Redial middleware to the Redux store in the renderer process

Step 1: Expose Redial API in Preload Script

Note

The preload step was added to v4 to ensure the library is adhering to recommended security practices when using the ipcRenderer API.

Import the preload script.

/** src/preload.js */

import "@laserware/redial/preload";

Step 2: Add Redial Middleware to Main Process Redux Store

Call the createRedialMainMiddleware function in your Redux store configuration code in the main process.

/** src/main.ts */

import { createRedialMainMiddleware } from "@laserware/redial/main";
import { configureStore, type Store } from "@reduxjs/toolkit";
import { app, BrowserWindow } from "electron";

import { rootReducer } from "../common/rootReducer";

function createStore(): Store {
  const redialMiddleware = createRedialMainMiddleware();

  const store = configureStore({
    reducer: rootReducer,
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware().concat(redialMiddleware),
  });

  app.on("before-quit", () => {
    // Perform cleanup:
    redialMiddleware.dispose();
  });
}

function createWindow(): void {
  const mainWindow = new BrowserWindow({
    webPreferences: {
      contextIsolation: true,
      // Assuming the preload script is in the same directory 
      // as the `main` file output:
      preload: join(__dirname, "preload.js"),
    },
  });
}

async function start(): Promise<void> {
  await app.whenReady();
  
  createStore();
  
  createWindow();
}

start();

Step 3: Add Redial Middleware to Renderer Process Redux Store

Call the createRedialRendererMiddleware in your Redux store configuration code in the renderer process.

/** src/renderer.ts */

import { createRedialRendererMiddleware } from "@laserware/redial/renderer";
import { configureStore, type Store } from "@reduxjs/toolkit";

import { rootReducer } from "../common/rootReducer";

export function createStore(): Store {
  const redialMiddleware = createRedialRendererMiddleware();

  let preloadedState;
  // If using Vite:
  if (import.meta.env.MODE === "development") {
    preloadedState = redialMiddleware.getMainStateSync();
  }

  const store = configureStore({
    preloadedState,
    reducer: rootReducer,
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware().concat(redialMiddleware),
  });
}

Migrating from v2 to v3

The API was completely changed in version 3 to use a single middleware import with methods, rather than returning the store from an initializer function (withRedial).

If you want to request the current state from the main process, the return value of createRedialRendererMiddleware provides two methods:

  1. getMainState, which is asynchronous
  2. getMainStateSync, which is synchronous (and blocking!)
export function createStore() {
  const redialMiddleware = createRedialRendererMiddleware();

  const stateFromMain = redialMiddleware.getMainStateSync();
}

In the main process, listeners are automatically added to return the state when requested.

Migrating from v3 to v4

The preload step was added in version 4 to adhere to recommended security practices when using the ipcRenderer API.

You must now call exposeRedialInMainWorld in a preload script and load that script when creating a BrowserWindow.

See the Usage instructions above for additional information.

Migrating from v4 to v5

The exported preload function was renamed from exposeRedialInMainWorld to preloadRedial.

/** src/preload.js */

/* Before */
import { exposeRedialInMainWorld } from "@laserware/redial/preload";
/* After */
import { preloadRedial } from "@laserware/redial/preload";

// Set up the communication layer between the main and renderer processes:
/* Before */
exposeRedialInMainWorld();
/* After */
preloadRedial();

Migrating from v5 to v6

The preload file was changed to a side-effect import.

/** src/preload.js */

/* Before */
import { preloadRedial } from "@laserware/redial/preload";

preloadRedial();

/* After */
import "@laserware/redial/preload";

About

Redux IPC abstraction layer that uses middleware to forward actions between the main and renderer processes.

Topics

Resources

License

Stars

Watchers

Forks