1
1
// debug output
2
2
let __DEBUG__
3
- function debug ( ...args ) {
4
- /* istanbul ignore if */
5
- if ( __DEBUG__ ) {
6
- if ( ! console . group ) {
7
- args . unshift ( '%credux-undo' , 'font-style: italic' )
3
+ /* istanbul ignore next: debug messaging is not tested */
4
+ let debug = ( function debugGrouper ( ) {
5
+ let displayBuffer
6
+ const colors = {
7
+ prevState : '#9E9E9E' ,
8
+ action : '#03A9F4' ,
9
+ nextState : '#4CAF50'
10
+ }
11
+ function initBuffer ( ) {
12
+ displayBuffer = {
13
+ header : [ ] ,
14
+ prev : [ ] ,
15
+ action : [ ] ,
16
+ next : [ ] ,
17
+ msgs : [ ]
8
18
}
9
- console . log ( ...args )
10
19
}
11
- }
12
- function debugStart ( action , state ) {
13
- /* istanbul ignore if */
14
- if ( __DEBUG__ ) {
15
- const args = [ 'action' , action . type ]
20
+ function printBuffer ( ) {
21
+ let { header, prev, next, action, msgs } = displayBuffer
16
22
if ( console . group ) {
17
- args . unshift ( '%credux-undo' , 'font-style: italic' )
18
- console . groupCollapsed ( ...args )
19
- console . log ( 'received' , { state, action} )
23
+ console . groupCollapsed ( ...header )
24
+ console . log ( ...prev )
25
+ console . log ( ...action )
26
+ console . log ( ...next )
27
+ console . log ( ...msgs )
28
+ console . groupEnd ( )
20
29
} else {
21
- debug ( ...args )
30
+ console . log ( ...header )
31
+ console . log ( ...prev )
32
+ console . log ( ...action )
33
+ console . log ( ...next )
34
+ console . log ( ...msgs )
22
35
}
23
36
}
24
- }
25
- function debugEnd ( ) {
26
- /* istanbul ignore if */
27
- if ( __DEBUG__ ) {
28
- return console . groupEnd && console . groupEnd ( )
37
+
38
+ function colorFormat ( text , color , obj ) {
39
+ return [
40
+ `%c${ text } ` ,
41
+ `color: ${ color } ; font-weight: bold` ,
42
+ obj
43
+ ]
29
44
}
30
- }
45
+ function start ( action , state ) {
46
+ initBuffer ( )
47
+ if ( __DEBUG__ ) {
48
+ if ( console . group ) {
49
+ displayBuffer . header = [ '%credux-undo' , 'font-style: italic' , 'action' , action . type ]
50
+ displayBuffer . action = colorFormat ( 'action' , colors . action , action )
51
+ displayBuffer . prev = colorFormat ( 'prev history' , colors . prevState , state )
52
+ } else {
53
+ displayBuffer . header = [ 'redux-undo action' , action . type ]
54
+ displayBuffer . action = [ 'action' , action ]
55
+ displayBuffer . prev = [ 'prev history' , state ]
56
+ }
57
+ }
58
+ }
59
+
60
+ function end ( nextState ) {
61
+ if ( __DEBUG__ ) {
62
+ if ( console . group ) {
63
+ displayBuffer . next = colorFormat ( 'next history' , colors . nextState , nextState )
64
+ } else {
65
+ displayBuffer . next = [ 'next history' , nextState ]
66
+ }
67
+ printBuffer ( )
68
+ }
69
+ }
70
+
71
+ function log ( ...args ) {
72
+ if ( __DEBUG__ ) {
73
+ displayBuffer . msgs = displayBuffer . msgs
74
+ . concat ( [ ...args , '\n' ] )
75
+ }
76
+ }
77
+
78
+ return {
79
+ start,
80
+ end,
81
+ log
82
+ }
83
+ } ) ( )
31
84
// /debug output
32
85
33
86
// action types
@@ -75,7 +128,8 @@ function length (history) {
75
128
// into `past`, setting the new `state` as `present` and erasing
76
129
// the `future`.
77
130
function insert ( history , state , limit ) {
78
- debug ( 'insert' , { state, history, free : limit - length ( history ) } )
131
+ debug . log ( 'inserting' , state )
132
+ debug . log ( 'new free: ' , limit - length ( history ) )
79
133
80
134
const { past, present } = history
81
135
const historyOverflow = limit && length ( history ) >= limit
@@ -93,8 +147,6 @@ function insert (history, state, limit) {
93
147
94
148
// undo: go back to the previous point in history
95
149
function undo ( history ) {
96
- debug ( 'undo' , { history} )
97
-
98
150
const { past, present, future } = history
99
151
100
152
if ( past . length <= 0 ) return history
@@ -112,8 +164,6 @@ function undo (history) {
112
164
113
165
// redo: go to the next point in history
114
166
function redo ( history ) {
115
- debug ( 'redo' , { history} )
116
-
117
167
const { past, present, future } = history
118
168
119
169
if ( future . length <= 0 ) return history
@@ -208,21 +258,21 @@ export default function undoable (reducer, rawConfig = {}) {
208
258
}
209
259
210
260
return ( state = config . history , action = { } ) => {
211
- debugStart ( action , state )
261
+ debug . start ( action , state )
212
262
213
263
let history = state
214
264
if ( ! config . history ) {
215
- debug ( 'history is uninitialized' )
265
+ debug . log ( 'history is uninitialized' )
216
266
217
267
if ( state === undefined ) {
218
268
history = createHistory ( reducer ( state , { } ) )
219
- debug ( 'do not initialize on probe actions' )
269
+ debug . log ( 'do not initialize on probe actions' )
220
270
} else if ( isHistory ( state ) ) {
221
271
history = config . history = state
222
- debug ( 'initialHistory initialized: initialState is a history' , config . history )
272
+ debug . log ( 'initialHistory initialized: initialState is a history' , config . history )
223
273
} else {
224
274
history = config . history = createHistory ( state )
225
- debug ( 'initialHistory initialized: initialState is not a history' , config . history )
275
+ debug . log ( 'initialHistory initialized: initialState is not a history' , config . history )
226
276
}
227
277
}
228
278
@@ -233,67 +283,68 @@ export default function undoable (reducer, rawConfig = {}) {
233
283
234
284
case config . undoType :
235
285
res = undo ( history )
236
- debug ( 'after undo', res )
237
- debugEnd ( )
286
+ debug . log ( 'perform undo')
287
+ debug . end ( res )
238
288
return res
239
289
240
290
case config . redoType :
241
291
res = redo ( history )
242
- debug ( 'after redo', res )
243
- debugEnd ( )
292
+ debug . log ( 'perform redo')
293
+ debug . end ( res )
244
294
return res
245
295
246
296
case config . jumpToPastType :
247
297
res = jumpToPast ( history , action . index )
248
- debug ( 'after jumpToPast' , res )
249
- debugEnd ( )
298
+ debug . log ( `perform jumpToPast to ${ action . index } ` )
299
+ debug . end ( res )
250
300
return res
251
301
252
302
case config . jumpToFutureType :
253
303
res = jumpToFuture ( history , action . index )
254
- debug ( 'after jumpToFuture' , res )
255
- debugEnd ( )
304
+ debug . log ( `perform jumpToFuture to ${ action . index } ` )
305
+ debug . end ( res )
256
306
return res
257
307
258
308
case config . jumpType :
259
309
res = jump ( history , action . index )
260
- debug ( 'after jump' , res )
261
- debugEnd ( )
310
+ debug . log ( `perform jump to ${ action . index } ` )
311
+ debug . end ( res )
262
312
return res
263
313
264
314
case config . clearHistoryType :
265
315
res = createHistory ( history . present )
266
- debug ( 'cleared history' , res )
267
- debugEnd ( )
316
+ debug . log ( 'perform clearHistory' )
317
+ debug . end ( res )
268
318
return res
269
319
270
320
default :
271
321
res = reducer ( history . present , action )
272
322
273
323
if ( config . initTypes . some ( ( actionType ) => actionType === action . type ) ) {
274
- debug ( 'reset history due to init action' )
275
- debugEnd ( )
324
+ debug . log ( 'reset history due to init action' )
325
+ debug . end ( config . history )
276
326
return config . history
277
327
}
278
328
329
+ if ( history . present === res ) {
330
+ // Don't handle this action. Do not call debug.end here,
331
+ // because this action should not produce side effects to the console
332
+ return history
333
+ }
334
+
279
335
if ( typeof config . filter === 'function' && ! config . filter ( action , res , history ) ) {
280
- debug ( 'filter prevented action, not storing it' )
281
- debugEnd ( )
282
- return {
336
+ const nextState = {
283
337
...history ,
284
338
present : res
285
339
}
340
+ debug . log ( 'filter prevented action, not storing it' )
341
+ debug . end ( nextState )
342
+ return nextState
286
343
}
287
344
288
- if ( history . present !== res ) {
289
- history = insert ( history , res , config . limit )
290
- debug ( 'inserted new state into history' )
291
- } else {
292
- debug ( 'not inserted, history is unchanged' )
293
- }
294
-
295
- debug ( 'history: ' , history , ' free: ' , config . limit - length ( history ) )
296
- debugEnd ( )
345
+ history = insert ( history , res , config . limit )
346
+ debug . log ( 'inserted new state into history' )
347
+ debug . end ( history )
297
348
return history
298
349
}
299
350
}
0 commit comments