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; actions: any;
mutations: any; mutations: any;
_isMutating: boolean = false; _isMutating: boolean = false;
_isDirty: boolean = false;
history: any[] = []; history: any[] = [];
debug: boolean; debug: boolean;
env: any; env: any;
@@ -34,6 +33,7 @@ export class Store extends EventBus {
this.mutations = config.mutations; this.mutations = config.mutations;
this.env = config.env; this.env = config.env;
this.observer = makeObserver(); this.observer = makeObserver();
this.observer.allowMutations = false;
this.observer.observe(this.state); this.observer.observe(this.state);
if (this.debug) { if (this.debug) {
@@ -66,11 +66,13 @@ export class Store extends EventBus {
if (!this.mutations[type]) { if (!this.mutations[type]) {
throw new Error(`[Error] mutation ${type} is undefined`); throw new Error(`[Error] mutation ${type} is undefined`);
} }
this._isMutating = true;
const currentRev = this.observer.__rev__; const currentRev = this.observer.__rev__;
// observer.enableMutating()
this._isMutating = true;
this.observer.allowMutations = true;
this.mutations[type].call(null, this.state, payload); this.mutations[type].call(null, this.state, payload);
this.observer.allowMutations = false;
if (this.debug) { if (this.debug) {
this.history.push({ this.history.push({
state: this.state, state: this.state,
@@ -94,6 +96,7 @@ export class Store extends EventBus {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
interface Observer { interface Observer {
__rev__: number; __rev__: number;
allowMutations: boolean;
observe: (val: any) => void; observe: (val: any) => void;
set: (target: any, key: number | string, value: any) => void; set: (target: any, key: number | string, value: any) => void;
} }
@@ -101,6 +104,7 @@ interface Observer {
export function makeObserver(): Observer { export function makeObserver(): Observer {
const observer: Observer = { const observer: Observer = {
__rev__: 0, __rev__: 0,
allowMutations: true,
observe: observe, observe: observe,
set: set set: set
}; };
@@ -124,9 +128,9 @@ export function makeObserver(): Observer {
return value; return value;
}, },
set(newVal) { set(newVal) {
// if (!isMutating) [ if (!observer.allowMutations) {
// throw new Error(); throw new Error("State cannot be changed outside a mutation!");
// ] }
if (newVal !== value) { if (newVal !== value) {
value = newVal; value = newVal;
// observe(newVal); // observe(newVal);
+13
View File
@@ -41,6 +41,19 @@ describe("basic use", () => {
expect(store.state.n).toBe(15); 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", () => { test("can dispatch an action in an action", () => {
const state = { n: 1 }; const state = { n: 1 };
const mutations = { const mutations = {