imp: prevent store state change outside a mutation

This commit is contained in:
Géry Debongnie
2019-04-12 12:05:06 +02:00
parent 03511ce9ea
commit f1cc32de8f
2 changed files with 23 additions and 6 deletions
+10 -6
View File
@@ -20,7 +20,6 @@ export class Store extends EventBus {
actions: any;
mutations: any;
_isMutating: boolean = false;
_isDirty: boolean = false;
history: any[] = [];
debug: boolean;
env: any;
@@ -34,6 +33,7 @@ export class Store extends EventBus {
this.mutations = config.mutations;
this.env = config.env;
this.observer = makeObserver();
this.observer.allowMutations = false;
this.observer.observe(this.state);
if (this.debug) {
@@ -66,11 +66,13 @@ export class Store extends EventBus {
if (!this.mutations[type]) {
throw new Error(`[Error] mutation ${type} is undefined`);
}
this._isMutating = true;
const currentRev = this.observer.__rev__;
// observer.enableMutating()
this._isMutating = true;
this.observer.allowMutations = true;
this.mutations[type].call(null, this.state, payload);
this.observer.allowMutations = false;
if (this.debug) {
this.history.push({
state: this.state,
@@ -94,6 +96,7 @@ export class Store extends EventBus {
//------------------------------------------------------------------------------
interface Observer {
__rev__: number;
allowMutations: boolean;
observe: (val: any) => void;
set: (target: any, key: number | string, value: any) => void;
}
@@ -101,6 +104,7 @@ interface Observer {
export function makeObserver(): Observer {
const observer: Observer = {
__rev__: 0,
allowMutations: true,
observe: observe,
set: set
};
@@ -124,9 +128,9 @@ export function makeObserver(): Observer {
return value;
},
set(newVal) {
// if (!isMutating) [
// throw new Error();
// ]
if (!observer.allowMutations) {
throw new Error("State cannot be changed outside a mutation!");
}
if (newVal !== value) {
value = newVal;
// observe(newVal);
+13
View File
@@ -41,6 +41,19 @@ describe("basic use", () => {
expect(store.state.n).toBe(15);
});
test("modifying state outside of mutations trigger error", () => {
const state = { n: 1 };
const actions = {
inc({ state }) {
state.n++;
}
};
const store = new Store({ state, mutations: {}, actions });
expect(() => store.dispatch("inc")).toThrow();
expect(() => (store.state.n = 15)).toThrow();
});
test("can dispatch an action in an action", () => {
const state = { n: 1 };
const mutations = {