Giter VIP home page Giter VIP logo

vuex-webextensions's Introduction

Vuex WebExtensions

NPM

Build Status npm:size:gzip npm codebeat badge

A Node.JS module to use Vuex on WebExtensions on "shared" context, the module allows you to start several instances of Vuex store and keep them synchronized throught WebExtensions messaging API.

Uses the Vuex store instance on background script as master, and replicate the state of master to others instances on diferent context (popup or content scripts), when you commit any mutation to any store instance the rest will also be updated automatically.

You can work with the Vuex store like a unic instance (or standart Vue.js application), without worry for the different WebExtensions contexts, the module gona solve all WebExtensions problems for you automatically.

Installation

Run the following command inside your WebExtensions project to install the module:

npm install vuex-webextensions --save

Usage

Import the module into your store file:

import VuexWebExtensions from 'vuex-webextensions';

Then add it as plugin on Vuex store initialization:

export default new Vuex.Store({
  ...
  plugins: [VuexWebExtensions()]
});

All done!

Persistent states

⚠ Persistent states make use of LocalStorage to save the states in your browser, to use it, you should grant storage permision to your webextension

You can establish through the options of the plugin the states that you want to be persistent, your data will be preserved after the restart of the extension or the browser.

It is established passing the state names through persistentStates option in array:

export default new Vuex.Store({
  ...
  plugins: [VuexWebExtensions({
      persistentStates: ['stateone', 'statetwo']
    })]
});

Then stateone and statetwo gona have the value commited by last mutation after extension or browser restart.

Propagated actions

On version 2.5.0 vuex introduce a new method on their API to watch and hook any action of store, this plugin sync actions like mutations by default.

Note: Event objects (like click for example) on action payload are automatically trimmered because cause serialization errors, you can pass value or object as payload anyways always that are serializable.

If you want to disable the actions sync, just set syncActions to false on the plugin settings.

export default new Vuex.Store({
  ...
  plugins: [VuexWebExtensions({
      syncActions: false
    })]
});

You can ignore specific actions like mutations too on ignoredActions list.

Ignored mutations and actions

It's possible skip the sync on desired mutations or actions adding their type to ignoredMutations or ignoredActions option.

All mutations or actions added to this list skip the sync process, you should update the value or process manually on desired contexts.

export default new Vuex.Store({
  ...
  plugins: [VuexWebExtensions({
      ignoredMutations: ['MUTATION_TYPE_ONE', 'MUTATION_TYPE_TWO'],
      ignoredActions: ['ACTION_TYPE_ONE', 'ACTION_TYPE_TWO']
    })]
});

Logger level

It's possible specify the minimun logging level of the plugin with the loggerLevel option, by default only warnings and errors gona be printed on console.

The available options are: debug, verbose, info, warning, error and none.

The none option disable all logging related with the plugin.

export default new Vuex.Store({
  ...
  plugins: [VuexWebExtensions({
      loggerLevel: 'debug'
    })]
});

Changelog

1.3.3
  • Rollback builds to babel meanwhile I investigate a error on builds with rollup
  • Allow use of submodules states in persistent states options
  • Some minor typos fixed on example extension
1.3.2
  • Fixed build on npm (Thanks to @TCashion)
1.3.1
  • Fixed browser detection logic when browser it's defined as HTML element
1.3.0
  • Added ability to sync actions with vuex v2.5.0 or later
  • Implemented logger for advanced debug of the plugin
  • Updated dependencies and fix some vulnerabilities on it
  • Some adjustments on es-lint and editorconfig rules
1.2.10
  • Prevent the multiple initialization introduced on version 1.2.9
  • Fix logic error of ignoredMutations system
1.2.9
  • Reimplement the method of initialization of state, this fix the broken watchers and allow to check when the data are fully loaded
1.2.8
  • Implement ignoredMutations option to allow skip sync on the desired mutations, thanks to @tuantmtb for suggest it
  • Update dependencies and fix some vulnerabilities on it
1.2.7
  • Fix state sync on non persistent extensions, thanks to @KBoyarchuk, @mchusovlianov and @k1nghat
  • Allow unit testing when window are undefined, thanks to @blimmer
  • Don't process messages without type
  • Fix grammar typos on error messages, thanks to @jonathan-s
  • Update dependencies and fix some vulnerabilities
1.2.6
  • Remarkable performance improvement on persistent states, thanks to @KBoyarchuk
1.2.5
  • Improve performance deleting a redundant read/check on persistent states
1.2.4
  • Fix pending mutations queue, thanks to @KBoyarchuk
1.2.3
  • Enque commited mutations to store before initialization on content scripts
1.2.2
  • Fix persistent states initialization when localstorage don't have data yet
1.2.1
  • Fix Chrome detection because missed return, thanks to @Stormsher
1.2.0
  • Fix sync problems with the new connections pool
  • Fix crazy loop with mutations, now don't return again to the original sender script and start looping
  • Fix broken persistent states by b6e66f2 (Sorry :/)
  • Persistent states now are only saved when data change to don't abuse of I/O on hardcore mutated environments
  • Background and content scripts handling separated on his own class for easy development
1.1.3
  • Fix typo that prevent initialization of background store
1.1.2
  • Implemented own polyfills to make module compatible with Chrome, Firefox and Edge
1.1.1
  • Fix plugin initialization on injected content scripts
1.1.0
  • Implemented optional persistence of states
  • Now the plugin are minimized on build
1.0.2
  • Cleanup of redundant code
1.0.1
  • Remove old files from distribution
1.0.0

⚠ This version have a breaking changes please check the new install method and remove the old install on your scripts

  • Convert module as "true" plugin of vuex
0.1.1
  • Added lint and some prepublish methods to the package
  • Solve some issues detected by linter
  • Added Travis CI for automatic build and tests
0.1.0
  • First version

Contribute

If you encounter a problem, issue or question feel free to open a new issue on this repository.

If you have some improvements, new features or fixes feel free to fork this repository and send a pull request.

Pending work

  • Improve example
  • Add tests and coverage
  • Publish to Awesome Vue.js lists when no more pending work

vuex-webextensions's People

Contributors

blimmer avatar dependabot[bot] avatar jonathan-s avatar kboyarchuk avatar mitsuhakitsune avatar stormsher 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  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  avatar  avatar

vuex-webextensions's Issues

v1.3.2 npm build not working properly

It seems the compiled code is still not quite working as expected. The specific bug I found was in the vweReplaceState mutation:

...
Object.keys(str.state).forEach(function(key) {
      str.state[key] = payload[key];
 });
...

When debugging, I find that the payload object is passed through as a JSON string of the store object, so payload[key] resolves to undefined. Thus the content script store does not receive the proper values from the background script.

This only happens on the npm build. When I install the package directly from the Git repository, it works as expected.

I noticed that v1.3.0 was built using the rimraf dist && babel src -d dist command, not the rollup command. Could I suggest reverting to that build method?

Cannot read property 'xxx' of null when running for the first time

when I configured persistentStates and use store in Background/Content Script. This extension has some logic like this:

// Restore persistent state datas from localstorage
if (this.settings.persistentStates.length) {
this.browser.getPersistentStates().then((savedStates) => {
this.store.replaceState({
...this.store.state,
...this.filterObject(savedStates, this.settings.persistentStates)
});
});

But if i run this method first, this.browser.getPersistentStates() will be resolve an empty value null: Source code at:src/browser.js#L86

Then executed this line: this.filterObject(savedStates, this.settings.persistentStates) will be failed and throw an exception with ` Cannot read property 'xxx' of null。

Because in function filterObject, the first argument source is null, and the second argument keys is an array. Source code at: [src/backgroundScript.js#L58-L66)](

filterObject(source, keys) {
const newObject = {};
keys.forEach((obj) => {
newObject[obj] = source[obj];
});
return newObject;
}

Vuex state with a Class inside is working in background, but not in popup

Hey! I finally have some time to use this Vuex plugin on a real project! :)

I think my problem is due to serialization/unserialization (JSON?) of my store state.

Given my store is:

import Vue from 'vue';
import Vuex from 'vuex';
import { Channel } from '...';

export const store = new Vuex.Store({
  state: {
    channels: [new Channel('foo', 'bar')]
  },
  getters: {
    firstChannel(state) {
      return state.channels[0];
    }
  }
})

When I use it in background, store.getters.firstChannel is an instance of Channel class.
But when I use it in my popup page inside a Vue component, this.$store.getters.firstChannel (or mapGetters(['firstChannel'])) is a plain object, without prototype.

I think it's a problem of serialization because some months ago, I had the same problem with chrome.runtime.sendMessage(). For each received data, I had to manually set __proto__ property:

<!-- in a .vue file -->
<script>
import { Channelfrom '...';

export default {
  data() {
    return {
      channels: []
    }
  },
  methods: {
    retrieveChannels() {
      chrome.runtime.sendMessage({ type: 'GET_CHANNELS' }, response => {
        this.channels = response.data.channels.map(channel => {
          channel.__proto__ = Channel.prototype;
          return channel;
        });
      });
    },
  },
}
</script>

But in this case I don't know how to do this.
Maybe a store watcher inside my popup/main.js or a Vue watcher inside popup/App.vue?

What do you think?

Thanks! :)

Problem with vue-router-sync

When I tried to use this plugin along with vue-router-sync, the following error occur during route transitions:

vue-router.esm.js?8c4f:16 [vue-router] uncaught error during route navigation:
warn @ vue-router.esm.js?8c4f:16
abort @ vue-router.esm.js?8c4f:1904
iterator @ vue-router.esm.js?8c4f:1968
step @ vue-router.esm.js?8c4f:1717
step @ vue-router.esm.js?8c4f:1721
(anonymous) @ vue-router.esm.js?8c4f:1718
(anonymous) @ vue-router.esm.js?8c4f:1964
(anonymous) @ middlewares.js?cf9a:6
iterator @ vue-router.esm.js?8c4f:1943
step @ vue-router.esm.js?8c4f:1717
step @ vue-router.esm.js?8c4f:1721
runQueue @ vue-router.esm.js?8c4f:1725
confirmTransition @ vue-router.esm.js?8c4f:1972
transitionTo @ vue-router.esm.js?8c4f:1874
push @ vue-router.esm.js?8c4f:2273
push @ vue-router.esm.js?8c4f:2534
(anonymous) @ Login.vue?7463:67
Promise.then (async)
login @ Login.vue?7463:66
invoker @ vue.runtime.esm.js?2b0e:2023
Vue.$emit @ vue.runtime.esm.js?2b0e:2534
click @ vuetify.js?ce5b:1357
invoker @ vue.runtime.esm.js?2b0e:2023
fn._withTask.fn._withTask @ vue.runtime.esm.js?2b0e:1822
vue-router.esm.js?8c4f:1905 TypeError: Converting circular structure to JSON
    at stringify (<anonymous>)
    at PortImpl.postMessage (extensions::messaging:107)
    at Port.publicClassPrototype.(anonymous function) [as postMessage] (extensions::utils:138:26)
    at a.sendMutation (contentScript.js?9bbc:8)
    at a.hookMutation (contentScript.js?9bbc:7)
    at eval (contentScript.js?9bbc:4)
    at eval (vuex.esm.js?2f62:392)
    at Array.forEach (<anonymous>)
    at Store.commit (vuex.esm.js?2f62:392)
    at Store.boundCommit [as commit] (vuex.esm.js?2f62:335)
abort @ vue-router.esm.js?8c4f:1905
iterator @ vue-router.esm.js?8c4f:1968
step @ vue-router.esm.js?8c4f:1717
step @ vue-router.esm.js?8c4f:1721
(anonymous) @ vue-router.esm.js?8c4f:1718
(anonymous) @ vue-router.esm.js?8c4f:1964
(anonymous) @ middlewares.js?cf9a:6
iterator @ vue-router.esm.js?8c4f:1943
step @ vue-router.esm.js?8c4f:1717
step @ vue-router.esm.js?8c4f:1721
runQueue @ vue-router.esm.js?8c4f:1725
confirmTransition @ vue-router.esm.js?8c4f:1972
transitionTo @ vue-router.esm.js?8c4f:1874
push @ vue-router.esm.js?8c4f:2273
push @ vue-router.esm.js?8c4f:2534
(anonymous) @ Login.vue?7463:67
Promise.then (async)
login @ Login.vue?7463:66
invoker @ vue.runtime.esm.js?2b0e:2023
Vue.$emit @ vue.runtime.esm.js?2b0e:2534
click @ vuetify.js?ce5b:1357
invoker @ vue.runtime.esm.js?2b0e:2023
fn._withTask.fn._withTask @ vue.runtime.esm.js?2b0e:1822

Usage of persistentStates with modules

I have module "player" and one of state keys "volume" and want to persist only this key, to make this happens i updated utils.filterObject

import { get, set } from 'lodash-es';

function filterObject(source, keys) {
  const newObject = {};
  keys.forEach(key => {
    const value = get(source, key);
    if (typeof value !== 'undefined') {
      set(newObject, key, value);
    }
  });
  return newObject;
}

export {filterObject};

now we can use path in keys:
VuexWebExtensions({ persistentStates: ['player.volume'] })

Dont work in Firefox, after extension is reloaded

Firefox version: 76.0.1
OS: windows 10 64-bit

import Vue from 'vue';
import Vuex from 'vuex';
import VuexWebExtensions from 'vuex-webextensions';

import { STORAGE } from './../background/storage';

Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [
    VuexWebExtensions({
      persistentStates: ['storage'],
      ignoredMutations: ['SET_CLOCK'],
      syncActions: false,
      loggerLevel: 'debug',
    }),
  ],
  state: {
    storage: STORAGE,
    isClock: false,
  },

...

After reloading extension or turn off/on, "storage" object is undefined
In Chrome and Edge it works fine

Vuex 4 support

Hi @MitsuhaKitsune,
thanks for the great plugin.

I'm trying to make it work with new version of Vuex and I'm getting following error:
Initial state not sent: DataCloneError: The object could not be cloned.

I believe problem lies in state object being wrapped with Proxy in new version, which cannot be handled by structured clone algorithm.

Problem is in initial @@STORE_SYNC_STATE message:

data: this.store.state

Quick workaround could be this.store._modules.root.state or JSON.parse(JSON.stringify(...)) as I haven't found any way how to get original object from Proxy.

How to set state non persistentStates

Currently, store have "currentUrl" = windows.location.href

export default new Vuex.Store({
  state: {
    urlCurrent: null
  },
  getters,
  mutations,
  actions,
  plugins: [
    VuexWebExtensions({
      persistentStates: []
    })
  ]
})

Currently, I open 2 tabs, state auto change value urlCurrent.
I want to state urlCurrent will not change when I open other tab.
How can I disable sync state: urlCurrent

Here is my package.json:

{
"dependencies": {
    "axios": "^0.19.0",
    "vue": "^2.6.10",
    "vue-router": "^3.0.7",
    "vuex": "^3.1.1",
    "vuex-webextensions": "^1.2.7",
    "webextension-polyfill": "^0.4.0"
  },
  "devDependencies": {
    "@babel/core": "^7.5.4",
    "@babel/plugin-proposal-optional-chaining": "^7.2.0",
    "@babel/preset-env": "^7.5.4",
    "@babel/runtime-corejs3": "^7.5.4",
    "archiver": "^3.0.0",
    "babel-eslint": "^10.0.2",
    "babel-loader": "^8.0.6",
    "copy-webpack-plugin": "^5.0.3",
    "core-js": "^3.1.4",
    "cross-env": "^5.2.0",
    "css-loader": "^3.0.0",
    "ejs": "^2.6.2",
    "eslint": "^6.0.1",
    "eslint-config-standard": "^12.0.0",
    "eslint-friendly-formatter": "^4.0.1",
    "eslint-loader": "^2.2.1",
    "eslint-plugin-import": "^2.18.0",
    "eslint-plugin-node": "^9.1.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.0",
    "eslint-plugin-vue": "^5.2.3",
    "file-loader": "^4.0.0",
    "mini-css-extract-plugin": "^0.7.0",
    "node-sass": "^4.12.0",
    "sass-loader": "^7.1.0",
    "vue-loader": "^15.7.0",
    "vue-template-compiler": "^2.6.10",
    "web-ext-types": "^3.2.0",
    "webpack": "^4.35.3",
    "webpack-cli": "^3.3.5",
    "webpack-extension-reloader": "^1.1.0"
  }
}

Store actions sync

this.store.subscribe((mutation) => {

Do you plan to implement this.store.subscribeAction?
I need to capture action invokation in popup via background's, but only mutations fired...

store.subscribe(({type, payload}) => {
    console.log(`[syncWithStore][mutation] type %o, payload %o`, type, payload);
});
store.subscribeAction(({type, payload}) => {
    console.log(`[syncWithStore][action] type %o, payload %o`, type, payload);
});

Race condition in contentScript.js

In contentScripts.js file there may be a problem. When we first open the extension popup, function sendMutation called before onMessage listener. In this case, when the data is written to the state, the onMessage handler is called with type STORE_INITIAL_STATE and the replaceState method overwrites the data that was previous written to the state.

As example:

extension

config to use localStorage instead ?

i have this case where i used injected script rather than content script, and injected script doesn't have access to chrome APIs... since it's injected into the current web page of the tab.

it would be good if there's a config to change storage adapter, either to use localStorage or browser.storage.

Can't get values from store in files that are not *.vue

I'm trying to access store.getters.user.token to check if there is an active user state. If there is, I want to redirect the user to the app, but if there isn't then they need to log in.

routes.ts

import store from '../../store';
...
  {
    path: '/',
    component: Portal,
    children: [
      {
        path: '',
        name: 'login',
        component: Login,
        beforeEnter(routeTo: any, routeFrom: any, next: any) {
          if (store.getters.user.token) {
            next({ name: "home" });
          } else {
            next();
          }
          next();
        }
      },
      ...
    ],
  },

In this context, store.getters.user.token is undefined because the user object looks like this:

Object 
  __ob__: At {
    value: {…}, dep: ct, vmCount: 0} 
  __proto__: Object

Whereas, in any *.vue file, the store.getters.user.token reveals the token:

Home.vue

<template>
  <div>
    <p>Home</p>
    {{this.token}}
  </div>
</template>

<script>
export default {
  data() {
    return {};
  },
  computed: {
    token() {
      return this.$store.state.user.token;
    },
  },
};
</script>

<style lang="scss" scoped>
p {
  font-size: 20px;
}
</style>

Home.vue showing the token:
image

But, when I console.log(store.state) in routes.ts I get the user object containing all the right values!
image

My hypothesis is that it has something to do with the object being loaded asynchronously, but I am not sure how to fix that issue. Do you have any ideas for what I could do?

Update
I am currently using a setTimeout to fix this issue. If someone could think of a more ideal solution, I'm all ears!

  {
    path: '/',
    component: Portal,
    children: [
      {
        path: '',
        name: 'login',
        component: Login,
        beforeEnter(routeTo: any, routeFrom: any, next: any) {
          setTimeout(() => {
            if (store.getters.isLoggedIn) {
              next({ name: "home" });
            } else {
              next();
            }
            next();
          }, 300)
        }
      },
      {
        path: '/register',
        name: 'register',
        component: Register,
      },
    ],
  },

Add some examples

Please some add examples to work with popup page/content script/option page. There is a small misunderstanding of how to use Vuex in background script.

Calling a vuex action in popup.js causing an infinite loop with a wrong commit payload

Hey,

I'm trying to use this plugin in a chrome extension with a simple store:

import Vue from 'vue'
import Vuex from 'vuex'
import VuexWebExtensions from 'vuex-webextensions';

Vue.use(Vuex)

const SET_IS_ENABLED = 'SET_IS_ENABLED'

export default new Vuex.Store({
  state: {
    isEnabled: false,
  },
  mutations: {
    [SET_IS_ENABLED] (state, newV) {
      console.log('SET_IS_ENABLED with:', newV)
      state.isEnabled = newV
    }
  },
  actions: {
    updateEnabledState ({ commit }, newV) {
      console.log('updateEnabledState with: ', newV)
      commit(SET_IS_ENABLED, newV)
    }
  },
  getters: {
    isEnabled: (state) => state.isEnabled
  },
  modules: {
  },
  plugins: [VuexWebExtensions()]
})

When calling updateEnabledState I see an infinite loop:
https://i.imgur.com/DugX402.png

Using:
[email protected]
[email protected]
[email protected]

Performance optimization

In some cases, the plug-in greatly slow the extension performance. For example, if extension need to update array (with a large number of nested object as elements) in state every second (in my case I do it mounted hook with setInterval), I must call mutations every second. This leads to the fact that when store subscribe to the mutations in backgroundScript

 // Compare first if previous saved values change to save to persistent states
      this.browser.getPersistentStates().then((savedStates) => {
        var currentState = this.filterObject(this.store.state, this.settings.persistentStates);

        if (JSON.stringify(currentState) !== JSON.stringify(savedStates)) {
          browser.savePersistentStates(currentState);
        }
      });

We call getPersistentStates method every time (which significantly reduces performance).
2018-08-20 17 07 28

Most likely the reason is that the method JSON.stringify for large arrays whose elements are deeply nested objects greatly slows performance.

chrome.storage.local.set({
   '@@vwe-persistence': JSON.stringify(datas)
});

Action background executing

Hi, I have proposal to implement custom background-side execution of actions.

It will be rather useful, U can just call action in content and get it proceed (AJAX calls ?) on background side. It became to look like complete replacement of messaging bus between BG and other parts.

What U think of it? Or maybe U have better idea?

Destructuring options not implemented correctly

In file index.js the options parameter takes the wrong value by merging defaultOptions and opt. For example for an object with such a structure:

   VuexWebExtensions("renderCount", "newDownloads", {
      persistentStates: [
        "notificationsOption",
        "soundsOption",
        "themeStyle",
        "selectedFileSize",
        "isMinimize",
        "locale"
      ]
    })

The parameter options takes the wrong value in accordance with the functionality of the plugin:

{ 
  '0': 'r',
  '1': 'e',
  '2': 'n',
  '3': 'd',
  '4': 'e',
  '5': 'r',
  '6': 'C',
  '7': 'o',
  '8': 'u',
  '9': 'n',
  '10': 't',
  connectionName: 'vuex-webextensions',
  persistentStates: [] 
}

This happens because opt parameter takes only first string parameter and destructuring it, but not array with parameters. And as a result in chrome storage we store incorrect data for state saving. To resolve this, we need to correctly accept the input parameter options.

export default function(...args) {
  let options = {...defaultOptions};
  for (let [index, option] of Array.from(...args).entries()) {
    if (
      typeof option === "object" &&
      option.hasOwnProperty("persistentStates")
    ) {
        options.persistentStates = [
        ...defaultOptions.persistentStates,
        ...option.persistentStates
    ];
    } else {
        options = {...options, ...defaultOptions, ...{[index]: option}};
    }
  }

  ....
}

Not persisting. Store is reset every time extension icon is clicked

Project is at https://github.com/IPFC/ipfc-extension

Screen Shot 2020-03-06 at 11 45 17 AM

// store.js
import Vue from 'vue';
import Vuex from 'vuex';
import VuexWebExtensions from 'vuex-webextensions';
import * as getters from './getters';
import mutations from './mutations';
import * as actions from './actions';

Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [
    VuexWebExtensions({
      persistentStates: ['jwt', 'pinataKeys'],
      loggerLevel: 'verbose',
    }),
  ],
  state: {
    jwt: 'initial',
    jwtValid: false,
    pinataKeys: null,
  },
  getters,
  mutations,
  actions,
});
```as you can see in the screenshot from the console.logs, the mutation ('setJwt') is successful, but as soon as i click elsewhere and reclick the extension icon, it gets reset and goes back to the store staring value.

Store state properties save in background script context

In the example that is attached to the repository, if remove from the list of properties "counter" (as example)

VuexWebExtensions({
      persistentStates: ['name']
})

and reopen popup page (preliminary having increased value of a variable "counter"), we will see that the value remains unchanged. Whether it is possible to initializes again all the values that are not in the "persistentStates" array, when reopen popup / content_script ?

state not set to localstorage on first load

when you first load an extension the state is not set to local storage. when i load an extension for the first time i get this from the background-script:

[Info] Vuex WebExtensions: Persistent states detected on config, reading from localstorage...
[Verbose] Vuex WebExtensions: Listening for actions
[Debug] Vuex WebExtensions: No data found on localstorage for persistent states

this is from the vuex-webextensions example extension. if you make a mutation from popup/content-script, then localstorage is set:

[Info] Vuex WebExtensions: Persistent states detected on config, reading from localstorage...
[Verbose] Vuex WebExtensions: Listening for actions
[Verbose] Vuex WebExtensions: Saved persistent states found on localstorage
[Debug] Vuex WebExtensions: Hooked mutation (vweReplaceState)

is this by design or should state be set to localstorage on install?

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.