Răsfoiți Sursa

feat(logger): `createLogger` can optionally log actions (#987)

Daniel Almaguer 5 ani în urmă
părinte
comite
18be128ad9
4 a modificat fișierele cu 81 adăugiri și 30 ștergeri
  1. 4 0
      dist/logger.d.ts
  2. 11 0
      docs/guide/plugins.md
  3. 4 0
      src/plugins/devtool.js
  4. 62 30
      src/plugins/logger.js

+ 4 - 0
dist/logger.d.ts

@@ -10,6 +10,10 @@ export interface LoggerOption<S> {
   filter?: <P extends Payload>(mutation: P, stateBefore: S, stateAfter: S) => boolean;
   transformer?: (state: S) => any;
   mutationTransformer?: <P extends Payload>(mutation: P) => any;
+  actionFilter?: <P extends Payload>(action: P, state: S) => boolean;
+  actionTransformer?: <P extends Payload>(action: P) => any;
+  logActions?: boolean;
+  logMutations?: boolean;
 }
 
 export default function createLogger<S>(option?: LoggerOption<S>): Plugin<S>;

+ 11 - 0
docs/guide/plugins.md

@@ -109,6 +109,11 @@ const logger = createLogger({
     // `mutation` is a `{ type, payload }`
     return mutation.type !== "aBlacklistedMutation"
   },
+  actionFilter (action, state) {
+    // same as `filter` but for actions
+    // `action` is a `{ type, payload }`
+    return action.type !== "aBlacklistedAction"
+  },
   transformer (state) {
     // transform the state before logging it.
     // for example return only a specific sub-tree
@@ -119,6 +124,12 @@ const logger = createLogger({
     // we can format it any way we want.
     return mutation.type
   },
+  actionTransformer (action) {
+    // Same as mutationTransformer but for actions
+    return action.type
+  },
+  logActions: true, // Log Actions
+  logMutations: true, // Log mutations
   logger: console, // implementation of the `console` API, default `console`
 })
 ```

+ 4 - 0
src/plugins/devtool.js

@@ -19,4 +19,8 @@ export default function devtoolPlugin (store) {
   store.subscribe((mutation, state) => {
     devtoolHook.emit('vuex:mutation', mutation, state)
   })
+
+  store.subscribeAction((action, state) => {
+    devtoolHook.emit('vuex:action', action, state)
+  })
 }

+ 62 - 30
src/plugins/logger.js

@@ -7,49 +7,81 @@ export default function createLogger ({
   filter = (mutation, stateBefore, stateAfter) => true,
   transformer = state => state,
   mutationTransformer = mut => mut,
+  actionFilter = (action, state) => true,
+  actionTransformer = act => act,
+  logActions = true,
+  logMutations = true,
   logger = console
 } = {}) {
   return store => {
     let prevState = deepCopy(store.state)
 
-    store.subscribe((mutation, state) => {
-      if (typeof logger === 'undefined') {
-        return
-      }
-      const nextState = deepCopy(state)
-
-      if (filter(mutation, prevState, nextState)) {
-        const time = new Date()
-        const formattedTime = ` @ ${pad(time.getHours(), 2)}:${pad(time.getMinutes(), 2)}:${pad(time.getSeconds(), 2)}.${pad(time.getMilliseconds(), 3)}`
-        const formattedMutation = mutationTransformer(mutation)
-        const message = `mutation ${mutation.type}${formattedTime}`
-        const startMessage = collapsed
-          ? logger.groupCollapsed
-          : logger.group
-
-        // render
-        try {
-          startMessage.call(logger, message)
-        } catch (e) {
-          console.log(message)
+    if (typeof logger === 'undefined') {
+      return
+    }
+
+    if (logMutations) {
+      store.subscribe((mutation, state) => {
+        const nextState = deepCopy(state)
+
+        if (filter(mutation, prevState, nextState)) {
+          const formattedTime = getFormattedTime()
+          const formattedMutation = mutationTransformer(mutation)
+          const message = `mutation ${mutation.type}${formattedTime}`
+
+          startMessage(logger, message, collapsed)
+          logger.log('%c prev state', 'color: #9E9E9E; font-weight: bold', transformer(prevState))
+          logger.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation)
+          logger.log('%c next state', 'color: #4CAF50; font-weight: bold', transformer(nextState))
+          endMessage(logger)
         }
 
-        logger.log('%c prev state', 'color: #9E9E9E; font-weight: bold', transformer(prevState))
-        logger.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation)
-        logger.log('%c next state', 'color: #4CAF50; font-weight: bold', transformer(nextState))
+        prevState = nextState
+      })
+    }
 
-        try {
-          logger.groupEnd()
-        } catch (e) {
-          logger.log('—— log end ——')
+    if (logActions) {
+      store.subscribeAction((action, state) => {
+        if (actionFilter(action, state)) {
+          const formattedTime = getFormattedTime()
+          const formattedAction = actionTransformer(action)
+          const message = `action ${action.type}${formattedTime}`
+
+          startMessage(logger, message, collapsed)
+          logger.log('%c action', 'color: #03A9F4; font-weight: bold', formattedAction)
+          endMessage(logger)
         }
-      }
+      })
+    }
+  }
+}
 
-      prevState = nextState
-    })
+function startMessage (logger, message, collapsed) {
+  const startMessage = collapsed
+    ? logger.groupCollapsed
+    : logger.group
+
+  // render
+  try {
+    startMessage.call(logger, message)
+  } catch (e) {
+    logger.log(message)
+  }
+}
+
+function endMessage (logger) {
+  try {
+    logger.groupEnd()
+  } catch (e) {
+    logger.log('—— log end ——')
   }
 }
 
+function getFormattedTime () {
+  const time = new Date()
+  return ` @ ${pad(time.getHours(), 2)}:${pad(time.getMinutes(), 2)}:${pad(time.getSeconds(), 2)}.${pad(time.getMilliseconds(), 3)}`
+}
+
 function repeat (str, times) {
   return (new Array(times + 1)).join(str)
 }