All files / src StateLogger.ts

0% Statements 0/40
0% Branches 0/20
0% Functions 0/3
0% Lines 0/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80                                                                                                                                                               
/* tslint:disable:no-console */
 
import { Store } from './Store';
import { ActionLike } from './types';
import { formatTime, getActionDescription } from './utils';
 
export class StateLogger {
  private prevState: any = {};
  private nextState: any = {};
  private start: number | null = null;
  private end: number | null = null;
 
  constructor(private stores: Store<any>[]) {}
 
  setState(type: 'prevState' | 'nextState', state: any) {
    if (type === 'nextState') {
      this.end = Date.now();
    }
 
    this[type] = state;
 
    if (type === 'prevState') {
      this.start = Date.now();
    }
  }
 
  log(action: ActionLike) {
    if (!this.end || !this.start) {
      throw new Error('prev or next state not calculated');
    }
    const gray = 'color: gray; font-weight: lighter;';
    const bold = 'font-weight: bold';
    const boldBlue = 'font-weight: bold; color: blue';
    const boldBlack = 'font-weight: bold; color: black';
    const boldGray = 'font-weight: bold; color: gray';
    const boldGreen = 'font-weight: bold; color: green';
    const boldRed = 'font-weight: bold; color: red';
    const actionType = getActionDescription(action.type!);
    const duration = (this.end - this.start).toFixed(2);
    const time = formatTime(new Date(this.start));
    const extraArgs = action.payload ? [action.payload] : [];
    if (console.groupCollapsed) {
      console.groupCollapsed(
        `%c action%c ${actionType} %c@ ${time} (in ${duration} ms)%c`,
        gray,
        bold,
        gray,
        boldGreen,
        ...extraArgs
      );
    } else {
      console.log(
        `action  ${actionType} @ ${time} (in ${duration} ms)`,
        ...extraArgs
      );
    }
    console.log('%c prev state', boldGray, this.prevState);
    console.log('%c action   ', boldBlue, action);
    console.log('%c next state', boldGreen, this.nextState);
    if (console.groupEnd) {
      console.groupEnd();
    }
    for (const store of this.stores) {
      const key = store.displayName;
      if (this.prevState[key] !== this.nextState[key]) {
        if (console.group) {
          console.group(`%c   update %c ${key}`, boldRed, boldBlack);
        } else {
          console.log(`   update ${key}`);
        }
        console.log('%c prev state', boldGray, this.prevState[key]);
        console.log('%c next state', boldGreen, this.nextState[key]);
      }
      if (console.groupEnd) {
        console.groupEnd();
      }
    }
  }
}