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 | 9x 8x 10x 10x 1x 9x 8x 8x 8x 13x 13x 13x 8x 8x 8x 22x 22x 6x 8x 22x 107x 36x 71x 73x 32x 39x 36x 36x 88x 55x 88x 88x 28x 28x | 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 => { Iif (!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 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(); } |