An open API service indexing awesome lists of open source software.

https://github.com/zoubingwu/electron-shared-state

❤️ easily sharing state across electron main and renderer processes.
https://github.com/zoubingwu/electron-shared-state

cross-process electron immer immutability shared-state state-management sync

Last synced: 6 months ago
JSON representation

❤️ easily sharing state across electron main and renderer processes.

Awesome Lists containing this project

README

          

# electron-shared-state

![](https://img.shields.io/npm/l/electron-shared-state)
![](https://badgen.net/npm/v/electron-shared-state)
![](https://badgen.net/npm/types/electron-shared-state)
![](https://badgen.net/bundlephobia/minzip/electron-shared-state)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/zoubingwu/electron-shared-state/publish.yaml?label=publish)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/zoubingwu/electron-shared-state/test.yaml?label=test)

Sharing state between main and renderer process can be this easy.

- 🚀 Mutate your state while keep them in sync with other process
- 🎯 Write in typescript with full typing support
- ❤️ Elegant and easy to learn API
- 👻 Immutability and structural sharing out of the box with built-in immer

![](./showcase.gif)

## Install

```sh
npm install electron-shared-state
```

or

```sh
yarn add electron-shared-state
```

## Usage

You can check source code under [example directory](/example).

```ts
// shared
export const initialState = 0;

// renderer
import { createSharedStore } from 'electron-shared-state';

const sharedStore = createSharedStore(initialState);

sharedStore.subscribe((state) => {
console.log(state);
});

setTimeout(() => {
sharedStore.setState((state) => {
state = state + 1;
});
}, 2000);

// main
import { createSharedStore } from 'electron-shared-state';

const sharedStore = createSharedStore(initialState);

sharedStore.subscribe((state) => {
console.log(state);
});

// both main and renderer will print the state after two seconds.
```

If your project already using state management tools like redux, you can easily replace a slice of your state with electron-shared-state, so you can just share part of the state you want to share without create a whole state tree in both processes.

```ts
// renderer

const sharedStore = createSharedStore(initialState);

// split state into a reducer
function sharedReducer(state, action) {
switch (action.type) {
case 'some action type':
const nextState = sharedStore.setState(...);
return nextState;
}
}

// combine with other reducer
const rootReducer = combindReducers({
other: ...,
shared: sharedReducer,
...
});

// create redux store
const store = createStore(rootReducer)

// in main process
// only this part of state will be shared across main and renderer
export const store = createSharedStore(initialState);
```

## API Reference

electron-shared-state only provides one simple function: `createSharedStore`. The signature is like below:

```ts
interface Options {
name?: string;
}

function createSharedStore(
state: T,
options?: Options
): {
setState: (recipe: (draft: T) => void, description?: string | undefined) => T;
getState: () => T;
subscribe: (
listener: (state: T, description?: string | undefined) => void
) => () => void;
};
```

The input is the state your want to share across processes, generally it's an object.

It also accepts an optional `Option` object, you can pass a store name if you want to have multiple stores.

```ts
const s1 = createSharedStore(..., { name: 's1' })
const s2 = createSharedStore(..., { name: 's2' })
```

It returns a Store object with a few methods on it.

**`setState(stateUpdater, description)`**

Accepts a stateUpdater function and a description string for debug purpose. The stateUpdater is like the second argument of immer's produce, so it inherits [immer's pitfalls](https://immerjs.github.io/immer/docs/pitfalls).

Returns the new state. It use immer underneath so the state remains immutable, to keep it in sync across processes, you should always use setState to update it.

**`getState()`**

Returns the current state.

**`subscribe(listener)`**

Adds a change listener. It will be called any time the state is changed, the listener receives the latest state and a description string as arguments.