1 | import { formatTime } from './helpers';
|
2 | import diffLogger from './diff';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | function 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 |
|
25 | function 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 |
|
42 | export 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 |
|
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 |
|
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 | }
|