Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype and functions not maintained in the process it was created #42

Open
TheSimpleZ opened this issue Jul 27, 2019 · 1 comment
Open

Comments

@TheSimpleZ
Copy link

TheSimpleZ commented Jul 27, 2019

The problem

I use this library in a project where i store a class in my state, kind of like this:

class MyCount {
  var count = 0

  getCurrentCount() {
     return count
  }
}

export default new Vuex.Store({
  state: {
    myCount: new MyCount()
  },

  actions: {
    newCounter(store, payload) {
      store.commit("newCounter", payload)
    }
  },

  mutations: {
    newCounter(state, payload) {
      state.myCount = payload
    }
  },

  plugins: [createPersistedState(), createSharedMutations()],
  strict: process.env.NODE_ENV !== "production"
})

Now this is an oversimplified example. In my case it's not really a class, but an object that has functions added to it by a 3rd party library.

The problem is that when i dispatch the newCounter action from a renderer process the action is being intercepted and processed on the main process instead.
For this to happen, you currently send the dispatch type and payload using ipcRenderer.send(), which results in the payload losing the prototype chain and all functions as stated in the docs.

Proposed solution

I tried modifying the code of sharedMutations.js locally to simply sync mutations both ways instead of broadcasting them from main.
The result is that the prototypes and functions will be available within the process they were created, which i feel makes more sense than having all prototypes in the main process.
It seems to work well for my application, but I'm curious to whether or not you see an issue with this implementation.

I also removed the restriction of having to use actions in the renderer process, any mutations are now synced both ways.

rendererProcessLogic() {
  // Connect renderer to main process
  this.connect()

  var mainMutating = false

  // Subscribe on changes from main process and apply them
  this.onNotifyRenderers((event, { type, payload }) => {
    mainMutating = true
    this.store.commit(type, payload)
    mainMutating = false
  })

  // Subscribe on changes from Vuex store
  this.store.subscribe(mutation => {
    if (!mainMutating) {
      const { type, payload } = mutation

      // Forward changes to renderer processes
      this.notifyMain({ type, payload })
    }
  })
}

mainProcessLogic() {
  const connections = {}

  // Save new connection
  this.onConnect(event => {
    const win = event.sender
    const winId = win.id

    connections[winId] = win

    // Remove connection when window is closed
    win.on('destroyed', () => {
      delete connections[winId]
    })
  })

  // Subscribe on changes from renderer processes
  this.onNotifyMain((event, { type, payload }) => {
    const win = event.sender
    const winId = win.id
    delete connections[winId]
    this.store.commit(type, payload)
    connections[winId] = win
  })

  // Subscribe on changes from Vuex store
  this.store.subscribe(mutation => {
    if (connections) {
      const { type, payload } = mutation

      // Forward changes to renderer processes

      this.notifyRenderers(connections, { type, payload })
    }
  })
}

I am willing to set up a PR if this is something you would like to use.

@akodkod
Copy link
Contributor

akodkod commented Aug 29, 2019

#44

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants