From 81602c6a7a0fc5ac0de6793ab689bfdbf0ed24f1 Mon Sep 17 00:00:00 2001 From: Daniel Almaguer Date: Sat, 2 Sep 2017 12:13:28 -0500 Subject: [PATCH] Gloobal action enhancers --- src/store.js | 21 ++++++++++++++++++--- src/util.js | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/store.js b/src/store.js index 0a540e809..9dcd47096 100644 --- a/src/store.js +++ b/src/store.js @@ -1,7 +1,7 @@ import applyMixin from './mixin' import devtoolPlugin from './plugins/devtool' import ModuleCollection from './module/module-collection' -import { forEachValue, isObject, isPromise, assert } from './util' +import { compose, forEachValue, isObject, isPromise, assert } from './util' let Vue // bind on install @@ -21,6 +21,7 @@ export class Store { } const { + actionEnhancers = [], plugins = [], strict = false } = options @@ -42,9 +43,14 @@ export class Store { this._subscribers = [] this._watcherVM = new Vue() - // bind commit and dispatch to self const store = this - const { dispatch, commit } = this + const { commit } = this + let { dispatch } = this + + const actionEnhancerChain = getActionEnhancerChain(store, state, actionEnhancers) + dispatch = compose(...actionEnhancerChain)(dispatch.bind(store)) + + // bind commit and dispatch to self this.dispatch = function boundDispatch (type, payload) { return dispatch.call(store, type, payload) } @@ -438,6 +444,15 @@ function enableStrictMode (store) { }, { deep: true, sync: true }) } +function getActionEnhancerChain (store, state, actionEnhancers) { + return actionEnhancers.map(actionEnhancer => actionEnhancer({ + dispatch: store.dispatch, + commit: store.commit, + getters: store.getters, + state + })) +} + function getNestedState (state, path) { return path.length ? path.reduce((state, key) => state[key], state) diff --git a/src/util.js b/src/util.js index 8642b82f8..d1b591b20 100644 --- a/src/util.js +++ b/src/util.js @@ -64,3 +64,26 @@ export function isPromise (val) { export function assert (condition, msg) { if (!condition) throw new Error(`[vuex] ${msg}`) } + +/** + * Taken from Redux repo + * Composes single-argument functions from right to left. The rightmost + * function can take multiple arguments as it provides the signature for + * the resulting composite function. + * + * @param {...Function} funcs The functions to compose. + * @returns {Function} A function obtained by composing the argument functions + * from right to left. For example, compose(f, g, h) is identical to doing + * (...args) => f(g(h(...args))). + */ +export function compose (...funcs) { + if (funcs.length === 0) { + return arg => arg + } + + if (funcs.length === 1) { + return funcs[0] + } + + return funcs.reduce((a, b) => (...args) => a(b(...args))) +}