Giter Site home page Giter Site logo

zoubingwu / electron-shared-state Goto Github PK

View Code? Open in Web Editor NEW
50.0 3.0 5.0 1.4 MB

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

License: MIT License

HTML 6.37% JavaScript 22.41% TypeScript 70.50% Shell 0.72%
electron immer state-management cross-process immutability sync shared-state

electron-shared-state's Introduction

electron-shared-state

GitHub Workflow Status GitHub Workflow Status

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

Install

npm install electron-shared-state

or

yarn add electron-shared-state

Usage

You can check source code under example directory.

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

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

interface Options {
  name?: string;
}

function createSharedStore<T>(
  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.

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.

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.

electron-shared-state's People

Contributors

jjeff avatar zoubingwu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

electron-shared-state's Issues

Requiering `dist/index.cjs.js` result in error "Cannot read properties of undefined (reading 'on')"

Using the latest version in an Electron app (electron-forge with webpack). If I import the library it works fine. But I also have to require it in main.js, since it is Common JS, and that results in the above error.

Since one uses the dist/index.mjs.js file and the other the dist/index.cjs.js I suspect something with how the latter is built is amiss.

It could conceivably also be how my project builds, but I donät think so since the error points straight to the file in node_modules.

I could also solve the problem by converting the project to mjs, but I tried that and got stuck 🙂 Too bad that the boilerplate is still in cjs ...

State is not synced with main/renderer after creation

Just add

store.setState(state => {
  state.count = 2000;
});

to your example/main.js

It will look like that
image

When you run your example you will find that renderer will show 0 instead of 2000.

It looks like you need to get the current state during store creation.

Multiple stores?

It looks like this module only allows you to create one shared store.

I have different states that I need to share between different windows. For instance, Store A needs to be shared between Main and Window 1, while Store B needs to be shared between Main, Window 1, and Window 2.

Would you be open to a pull request which adds the ability to create multiple named stores? Offhand, it might look like this:

const sharedStoreA = createSharedStore(initialStateA, 'store_a')
const sharedStoreB = createSharedStore(initialStateB, 'store_b')

Then we might append this name onto the INTERNAL_CHANNEL value so that the IPC listeners would just listen/send on different channels for the different stores. If someone didn't give a storeName value, then we would fall back to the current functionality.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.