UNPKG

3.68 kBJavaScriptView Raw
1import { formatTime } from './helpers';
2import diffLogger from './diff';
3
4/**
5 * Get log level string based on supplied params
6 *
7 * @param {string | function | object} level - console[level]
8 * @param {object} action - selected action
9 * @param {array} payload - selected payload
10 * @param {string} type - log entry type
11 *
12 * @returns {string} level
13 */
14function getLogLevel(level, action, payload, type) {
15 switch (typeof level) {
16 case `object`:
17 return typeof level[type] === `function` ? level[type](...payload) : level[type];
18 case `function`:
19 return level(action);
20 default:
21 return level;
22 }
23}
24
25function defaultTitleFormatter(options) {
26 const {
27 timestamp,
28 duration,
29 } = options;
30
31 return (action, time, took) => {
32 const parts = [`action`];
33
34 if (timestamp) parts.push(`@ ${time}`);
35 parts.push(String(action.type));
36 if (duration) parts.push(`(in ${took.toFixed(2)} ms)`);
37
38 return parts.join(` `);
39 };
40}
41
42export function printBuffer(buffer, options) {
43 const {
44 logger,
45 actionTransformer,
46 titleFormatter = defaultTitleFormatter(options),
47 collapsed,
48 colors,
49 level,
50 diff,
51 } = options;
52
53 buffer.forEach((logEntry, key) => {
54 const { started, startedTime, action, prevState, error } = logEntry;
55 let { took, nextState } = logEntry;
56 const nextEntry = buffer[key + 1];
57
58 if (nextEntry) {
59 nextState = nextEntry.prevState;
60 took = nextEntry.started - started;
61 }
62
63 // Message
64 const formattedAction = actionTransformer(action);
65 const isCollapsed = (typeof collapsed === `function`) ? collapsed(() => nextState, action, logEntry) : collapsed;
66
67 const formattedTime = formatTime(startedTime);
68 const titleCSS = colors.title ? `color: ${colors.title(formattedAction)};` : null;
69 const title = titleFormatter(formattedAction, formattedTime, took);
70
71 // Render
72 try {
73 if (isCollapsed) {
74 if (colors.title) logger.groupCollapsed(`%c ${title}`, titleCSS);
75 else logger.groupCollapsed(title);
76 } else {
77 if (colors.title) logger.group(`%c ${title}`, titleCSS);
78 else logger.group(title);
79 }
80 } catch (e) {
81 logger.log(title);
82 }
83
84 const prevStateLevel = getLogLevel(level, formattedAction, [prevState], `prevState`);
85 const actionLevel = getLogLevel(level, formattedAction, [formattedAction], `action`);
86 const errorLevel = getLogLevel(level, formattedAction, [error, prevState], `error`);
87 const nextStateLevel = getLogLevel(level, formattedAction, [nextState], `nextState`);
88
89 if (prevStateLevel) {
90 if (colors.prevState) logger[prevStateLevel](`%c prev state`, `color: ${colors.prevState(prevState)}; font-weight: bold`, prevState);
91 else logger[prevStateLevel](`prev state`, prevState);
92 }
93
94 if (actionLevel) {
95 if (colors.action) logger[actionLevel](`%c action`, `color: ${colors.action(formattedAction)}; font-weight: bold`, formattedAction);
96 else logger[actionLevel](`action`, formattedAction);
97 }
98
99 if (error && errorLevel) {
100 if (colors.error) logger[errorLevel](`%c error`, `color: ${colors.error(error, prevState)}; font-weight: bold`, error);
101 else logger[errorLevel](`error`, error);
102 }
103
104 if (nextStateLevel) {
105 if (colors.nextState) logger[nextStateLevel](`%c next state`, `color: ${colors.nextState(nextState)}; font-weight: bold`, nextState);
106 else logger[nextStateLevel](`next state`, nextState);
107 }
108
109 if (diff) {
110 diffLogger(prevState, nextState, logger, isCollapsed);
111 }
112
113 try {
114 logger.groupEnd();
115 } catch (e) {
116 logger.log(`—— log end ——`);
117 }
118 });
119}