Installations
npm install vuex-electron-store
Developer Guide
Typescript
Yes
Module System
CommonJS
Node Version
14.18.3
NPM Version
7.22.0
Score
41.7
Supply Chain
94.3
Quality
72.6
Maintenance
50
Vulnerability
98.2
License
Releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (57.24%)
JavaScript (42.76%)
Developer
Download Statistics
Total Downloads
15,191
Last Day
1
Last Week
20
Last Month
59
Last Year
1,342
GitHub Statistics
19 Stars
253 Commits
5 Forks
3 Watching
9 Branches
2 Contributors
Package Meta Information
Latest Version
1.4.26
Package Id
vuex-electron-store@1.4.26
Unpacked Size
39.15 kB
Size
9.89 kB
File Count
9
NPM Version
7.22.0
Node Version
14.18.3
Total Downloads
Cumulative downloads
Total Downloads
15,191
Last day
-94.1%
1
Compared to previous day
Last week
-9.1%
20
Compared to previous week
Last month
47.5%
59
Compared to previous month
Last year
-56.8%
1,342
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Features
- 💾 Persistent state - persistently stores the Vuex state in your Electron app
- 🔌 Easy integration - integrates perfectly with Vue and Electron as a Vuex Plugin
- 🔨 Customization - specify what parts of your Vuex state you want to persist and which mutations are allowed
- ♻️ Migrations - the persisted state can be easily migrated between different versions of your Electron app
- 🔐 Encryption - you can optionally encrypt the storage file with a encryption key
- ⚙️ Electron main process - access the state & commit mutations/dispatch actions from the Electron main process
This library is a wrapper around electron-store to make it work directly with Vuex and offer additional features.
🚀 Get started
1npm install vuex-electron-store
Requires Electron 11 or later and currently only works with Vue 2
📚 Usage
To use vuex-electron-store, add it as a plugin to your Vuex store:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 plugins: [ 11 PersistedState.create() 12 ], 13 // ... 14})
And then initialize it in the Electron main process:
1import PersistedState from 'vuex-electron-store' 2 3PersistedState.initRenderer()
If you access the store from the main process (using
.getStoreFromRenderer()
) this is not needed
And you are done! Your Electron app now has a persistent Vuex state! 🎉
⚙️ Options
You can also pass an options object to .create()
to customize the behaviour of vuex-electron-store further:
1PersistedState.create({ 2 paths: [ 'auth.user' ] 3})
Here are all the options vuex-electron-store supports:
Name | Type | Description | Default |
---|---|---|---|
fileName | string | Name of the storage file (without extension) | vuex |
paths | array | An array of any paths to partially persist the state | n/a |
filter | function | A function which will be called on each mutation that triggers setState | n/a |
overwrite | boolean | Overwrite the existing state with the persisted state directly when rehydrating | false |
storageKey | string | Name of the key used for the stored state object | state |
checkStorage | boolean | Check if the storage file is available and can be accessed | true |
dev | boolean | Enable development mode | false |
reducer | function | A function to reduce the state to persist based on the given paths | n/a |
arrayMerger | function | A function for merging arrays when rehydrating state | combine arrays |
resetMutation | string | Name of a mutation which when called will reset the persisted state | n/a |
encryptionKey | string/Buffer/TypedArray/DataView | Encryption key used to encrypt the storage file | n/a |
storageFileLocation | string | Location where the storage file should be stored | config directory |
migrations | object | Migration operations to perform to the persisted state whenever a version is upgraded | n/a |
ipc | boolean | Enable IPC communication with the main process | false |
🛠️ Configuration
Here are some of the more important options in a more detailed form.
Paths
You can specify different paths (i.e. parts) of you state with the paths
option. It accepts an array of paths specified using dot notation e.g. user.name
.
If no paths are given, the complete state is persisted. If an empty array is given, no state is persisted.
See Example
1PersistedState.create({ 2 paths: ['user.token'] 3})
Here, only the user.token
will be persisted and rehydrated.
Filter
You can limit the mutations which can persist state with the filter
function. The specified function will be called on each mutation that triggers setState
.
See Example
1PersistedState.create({ 2 filter: (name) => name === 'increment' 3})
Here, only state changed by the increment
mutation will be persisted and rehydrated.
Overwrite
By default the the existing state will be merged using deepmerge with the persisted state. If you set overwrite
to true, the persisted state will overwrite the existing state directly when rehydrating.
See Example
1PersistedState.create({ 2 overwrite: true 3})
Development Mode
During development it might be useful to disable persisting and rehydrating the state. You can disable this with the dev
option. When it is set to true, all changes to the state will not be persisted (regardless of the paths provided), rehydration of the state will be skipped and migrations will not be performed.
See Example
1PersistedState.create({ 2 dev: true 3})
Migrations
You can specify operations to perform to the persisted state whenever a version is upgraded. The migrations
object should consist of a key-value pair of 'version': handler
(the version
can also be a semver range). In the handler you can manipulate the previously persisted state (just like any other JavaScript object) before it is rehydrated.
See Example
1PersistedState.create({ 2 migrations: { 3 '0.1.0': (state) => { 4 state.debugPhase = true 5 }, 6 '1.0.0': (state) => { 7 delete state.debugPhase 8 state.phase = '1.0.0' 9 }, 10 '1.0.2': (state) => { 11 state.phase = '1.0.2' 12 }, 13 '>=2.0.0': (state) => { 14 state.phase = '>=2.0.0' 15 } 16 } 17})
The state
parameter contains the persisted state before rehydration.
Reset Mutation
You can programmatically reset the persisted state by specifying the name of a mutation as the resetMutation
option. Once you call that mutation, the entire persisted state will be deleted. You have to create a mutation by the same name, even if it doesn't do anything.
See Example
1PersistedState.create({ 2 resetMutation: 'ELECTRON_STORE_RESET' 3})
You have to create a mutation by the same name, even if it doesn't do anything.:
1mutations: { 2 ELECTRON_STORE_RESET(state) { 3 // Optionally do something else here 4 } 5}
Later in a component or somewhere else:
1this.$store.commit('ELECTRON_STORE_RESET')
Encryption
You can optionally specify an encryption key which will be used to encrypt the storage file using the aes-256-cbc encryption algorithm. This is only secure if you don't store the key in plain text, but in a secure manner in the Node.js app. You could use node-keytar to store the encryption key securely, or deriving the key from a password entered by the user.
It might also be useful for obscurity. If a user looks through the config directory and finds the config file, since it's just a JSON file, they may be tempted to modify it. By providing an encryption key, the file will be obfuscated, which should hopefully deter any users from doing so.
See Example
1PersistedState.create({ 2 encryptionKey: 'superSecretKey' 3})
Don't store the key like this if security is of concern, the encryption key would be easily found in the Electron app.
IPC Mode
If you want to access the state or commit mutations/dispatch actions from the Electron main process, you need to enable ipc
mode.
You can then use the .getStoreFromRenderer()
method in the main process to listen for an IPC connection from the renderer. Once connected you can use the returned .commit()
and .dispatch()
methods like you would in a normal Vue Component. Calling .getState()
returns a promise containing the current Vuex state.
This can only be used with one renderer
See Example
Enable ipc
mode:
1PersistedState.create({ 2 ipc: true 3})
Then in the Electron main process:
1import PersistedState from 'vuex-electron-store' 2 3const store = await PersistedState.getStoreFromRenderer() 4 5// Commit a mutation 6store.commit(type, payload, options) 7 8// Dispatch an action 9store.dispatch(type, payload, options) 10 11// Get the current Vuex State 12const state = await store.getState() 13 14// Reset the persisted State 15store.clearState()
When you use
.getStoreFromRenderer()
you don't need to call.initRenderer()
📖 Examples
Here are a few examples to help you get started!
Before you use any of them, make sure you initialize the module in the Electron main process:
1import PersistedState from 'vuex-electron-store' 2 3PersistedState.initRenderer()
Basic Example
In this example the entire state will be persisted and rehydrated after a restart:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 state: { 11 username: '' 12 }, 13 plugins: [ 14 PersistedState.create() 15 ], 16 // ... 17})
Only partially persist state
In this example only part of the state will be persisted and rehydrated after a restart:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 state: { 11 input: '' 12 user: { 13 token: '' 14 } 15 }, 16 plugins: [ 17 PersistedState.create({ 18 paths: ['user.token'] 19 }) 20 ], 21 // ... 22})
Here, only the user.token
will be persisted and rehydrated.
Filter mutations
In this example we add a filter to specify which mutations can persist the updated state:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 mutations: { 11 // ... 12 increment(state) { 13 // mutate state 14 state.count++ 15 }, 16 decrement(state) { 17 // mutate state 18 state.count-- 19 } 20 }, 21 plugins: [ 22 PersistedState.create({ 23 filter: (name) => name === 'increment' 24 }) 25 ], 26 // ... 27})
Here, only state changed by the increment
mutation will be persisted and rehydrated.
Merging arrays
By default arrays from the existing state will be merged with arrays from the persisted state. You can change this behaviour by specifying a different arrayMerger
function which deepmerge will use to merge the two arrays.
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 state: { 11 todos: ['test1', 'test2'] 12 }, 13 plugins: [ 14 PersistedState.create({ 15 arrayMerger: (stateArray, persistedStateArray, options) => { /* ... */ } 16 }) 17 ], 18 // ... 19})
Use the function below to overwrite the existing arrays with the persisted arrays:
1const overwriteMerge = (stateArray, persistedStateArray, options) => persistedStateArray
If you want to overwrite the entire state, not just arrays, set the overwrite
option to true
instead.
Overwriting the existing state
By default the existing state will be merged with the persisted state using deepmerge. You can disable this behaviour and instead directly overwrite the existing state with the persisted state using the overwrite
option:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 plugins: [ 11 PersistedState.create({ 12 overwrite: true 13 }) 14 ], 15 // ... 16})
During development
Setting dev
to true will stop vuex-electron-store from persisting and rehydrating the state.
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 plugins: [ 11 PersistedState.create({ 12 dev: true 13 }) 14 ], 15 // ... 16})
Reset Mutation
You can reset the persisted state by specifying a mutation as the resetMutation
option and then calling it:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 mutations: { 11 ELECTRON_STORE_RESET(state) { 12 // Optionally do something else here 13 } 14 }, 15 plugins: [ 16 PersistedState.create({ 17 resetMutation: 'ELECTRON_STORE_RESET' 18 }) 19 ], 20 // ... 21}) 22 23// Later in a component or somewhere else 24this.$store.commit('ELECTRON_STORE_RESET')
You have to create a mutation by the same name, even if it doesn't do anything.
Encrypting the storage file
You can optionally encrypt/obfuscate the storage file by specifying an encryption key:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 plugins: [ 11 PersistedState.create({ 12 encryptionKey: 'superSecretKey' 13 }) 14 ], 15 // ... 16})
Don't store the key like this if security is of concern, the encryption key would be easily found in the Electron app.
Migration between versions
You can use migrations to perform operations on the persisted data whenever a version is upgraded. The migrations object should consist of a key-value pair of 'version': handler
. In the handler you can manipulate the state like any other JavaScript object:
1import Vue from 'vue' 2import Vuex from 'vuex' 3 4import PersistedState from 'vuex-electron-store' 5 6Vue.use(Vuex) 7 8export default new Vuex.Store({ 9 // ... 10 plugins: [ 11 PersistedState.create({ 12 migrations: { 13 '0.1.0': (state) => { 14 state.debugPhase = true 15 }, 16 '1.0.0': (state) => { 17 delete state.debugPhase 18 state.phase = '1.0.0' 19 }, 20 '1.0.2': (state) => { 21 state.phase = '1.0.2' 22 }, 23 '>=2.0.0': (state) => { 24 state.phase = '>=2.0.0' 25 } 26 } 27 }) 28 ], 29 // ... 30})
The state
parameter contains the persisted state before rehydration.
Access the store from the Electron main process
If you enable the ipc
mode you can access the state or commit mutations/dispatch actions from the Electron main process:
1import PersistedState from 'vuex-electron-store' 2 3const store = await PersistedState.getStoreFromRenderer() 4 5// Commit a mutation 6store.commit(type, payload, options) 7 8// Dispatch an action 9store.dispatch(type, payload, options) 10 11// Get the current Vuex State 12const state = await store.getState() 13 14// Reset the persisted State 15store.clearState()
When you use
.getStoreFromRenderer()
you don't need to call.initRenderer()
💻 Development
Issues and PRs are very welcome!
- run
yarn lint
ornpm run lint
to run eslint. - run
yarn watch
ornpm run watch
to watch for changes. - run
yarn build
ornpm run build
to produce a compiled version in thelib
folder.
Todo
- Add support for Vue 3
❔ About
This project was developed by me (@betahuhn) in my free time. If you want to support me:
Credit
This library is a wrapper around the great electron-store by @sindresorhus and was inspired by vuex-electron and vuex-persistedstate.
📄 License
Copyright 2021 Maximilian Schiller
This project is licensed under the MIT License - see the LICENSE file for details.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
dependency not pinned by hash detected -- score normalized to 3
Details
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/dependabot.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/dependabot.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/node.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/node.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/node.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/node.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/node.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/node.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/node.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/node.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-scheduler.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/release-scheduler.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/release.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/release.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/release.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/release.yml/master?enable=pin
- Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/release.yml/master?enable=pin
- Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/BetaHuhn/vuex-electron-store/release.yml/master?enable=pin
- Info: 0 out of 8 GitHub-owned GitHubAction dependencies pinned
- Info: 0 out of 6 third-party GitHubAction dependencies pinned
- Info: 4 out of 4 npmCommand dependencies pinned
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 0/16 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
- Warn: no topLevel permission defined: .github/workflows/dependabot.yml:1
- Warn: no topLevel permission defined: .github/workflows/node.yml:1
- Warn: no topLevel permission defined: .github/workflows/release-scheduler.yml:1
- Warn: no topLevel permission defined: .github/workflows/release.yml:1
- Info: no jobLevel write permissions found
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 14 are checked with a SAST tool
Reason
40 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-3p22-ghq8-v749
- Warn: Project is vulnerable to: GHSA-77xc-hjv8-ww97
- Warn: Project is vulnerable to: GHSA-mq8j-3h7h-p8g7
- Warn: Project is vulnerable to: GHSA-p2jh-44qj-pf2v
- Warn: Project is vulnerable to: GHSA-p7v2-p9m8-qqg7
- Warn: Project is vulnerable to: GHSA-7x97-j373-85x5
- Warn: Project is vulnerable to: GHSA-7m48-wc93-9g85
- Warn: Project is vulnerable to: GHSA-qqvq-6xgj-jw8g
- Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97
- Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j
- Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22
- Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp
- Warn: Project is vulnerable to: GHSA-896r-f27r-55mw
- Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj
- Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g
- Warn: Project is vulnerable to: GHSA-hj9c-8jmm-8c52
- Warn: Project is vulnerable to: GHSA-3j8f-xvm3-ffx4
- Warn: Project is vulnerable to: GHSA-4p35-cfcx-8653
- Warn: Project is vulnerable to: GHSA-7f3x-x4pr-wqhj
- Warn: Project is vulnerable to: GHSA-jpp7-7chh-cf67
- Warn: Project is vulnerable to: GHSA-q6wq-5p59-983w
- Warn: Project is vulnerable to: GHSA-j9fq-vwqv-2fm2
- Warn: Project is vulnerable to: GHSA-pqw5-jmp5-px4v
- Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-x2pg-mjhr-2m5x
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch
- Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-5j4c-8p2g-v4jx
- Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7
Score
2.7
/10
Last Scanned on 2024-12-23
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More