All files / src utils.ts

69.64% Statements 39/56
80.56% Branches 29/36
68.75% Functions 11/16
70.37% Lines 38/54

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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124      39x             12x 53x 1x   52x 13x   39x     12x     12x     12x             28x 28x     28x     12x         12x                                                 12x 51x   51x   7x         12x 25x     35x 10x   25x       67x 20x   47x 48x 18x     29x       24x     24x 67x 38x   67x 67x         64x         64x    
import { ActionLike, AC, Action, ActionType } from './types';
 
function isSymbol(x: any): x is symbol {
  return (
    typeof x === 'symbol' ||
    (typeof x === 'object' &&
      Object.prototype.toString.call(x) === '[object Symbol]')
  );
}
 
export const isAction = (action: any): action is ActionLike => {
  if (!action) {
    return false;
  }
  if (!Array.isArray(action.type) || action.type.length !== 2) {
    return false;
  }
  return isSymbol(action.type[0]) && typeof action.type[1] === 'string';
};
 
export const repeat = (str: string, times: number) =>
  new Array(times + 1).join(str);
 
export const pad = (num: number, maxLength: number) =>
  repeat('0', maxLength - num.toString().length) + num;
 
export const formatTime = (time: Date) =>
  `${pad(time.getHours(), 2)}:${pad(time.getMinutes(), 2)}:${pad(
    time.getSeconds(),
    2
  )}.${pad(time.getMilliseconds(), 3)}`;
 
export function getDescription(s: symbol) {
  const match = /Symbol\((.+)\)/.exec(s.toString());
  Iif (!match) {
    throw new Error('Empty symbol: ' + s.toString());
  }
  return match[1];
}
 
export const getActionDescription = (action: ActionType) => {
  const [symbol, type] = action;
  return getDescription(symbol) + '/' + type;
};
 
export const logAction = (epicName: string, action: Action) => {
  const gray = 'color: gray; font-weight: lighter;';
  const bold = 'font-weight: bold';
  const boldBlue = 'font-weight: bold; color: blue';
  const boldRed = 'font-weight: bold; color: red';
  const actionType = getActionDescription(action.type);
  const time = formatTime(new Date());
  if (!actionType.startsWith(epicName)) {
    // tslint:disable-next-line:no-console
    console.log(
      `%c epic%c ${epicName}%c:%c${actionType} %c@ ${time}`,
      gray,
      boldBlue,
      gray,
      boldRed,
      gray
    );
  } else {
    // tslint:disable-next-line:no-console
    console.log(`%c epic%c ${actionType} %c@ ${time}`, gray, bold, gray);
  }
};
 
// FROM https://github.com/huynhsamha/js-snakecase/blob/master/index.js
// ISC
export const snakeCase = (str: string) => {
  Iif (!str) return '';
 
  return String(str)
    .replace(/^[^A-Za-z0-9]*|[^A-Za-z0-9]*$/g, '')
    .replace(/([a-z])([A-Z])/g, (m, a, b) => a + '_' + b.toLowerCase())
    .replace(/[^A-Za-z0-9]+|_+/g, '_')
    .toLowerCase();
};
 
export const toArray = <T>(input: T | T[]): T[] =>
  Array.isArray(input) ? input : [input];
 
export function objectIs(a: unknown, b: unknown) {
  if (a === b) {
    return a !== 0 || 1 / a === 1 / (b as number);
  } else {
    return a !== a && b !== b;
  }
}
export function shallowEqual(a: any[] | null, b: any[] | null) {
  if (!a || !b || a.length !== b.length) {
    return false;
  }
  for (let i = 0; i < a.length; i++) {
    if (a[i] !== b[i]) {
      return false;
    }
  }
  return true;
}
 
export function memoize(fn: (...args: any[]) => any) {
  let lastArgs: any[] | null = null;
  let lastResult: any[];
 
  return (...args: any[]) => {
    if (!shallowEqual(args, lastArgs)) {
      lastResult = fn(...args);
    }
    lastArgs = args;
    return lastResult;
  };
}
 
export function getACType(ac: AC) {
  Iif (!ac.getType) {
    throw new Error(
      'getType() not defined in Action Creator: ' + ac.toString()
    );
  }
  return ac.getType();
}