| 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
 | | 'use strict'; |  |   |  | const unique = arr => arr.filter((v, i) => arr.lastIndexOf(v) === i); |  | const compact = arr => unique(arr).filter(Boolean); |  |   |  | module.exports = (action, data = {}, value = '') => { |  |   let { past = [], present = '' } = data; |  |   let rest, prev; |  |   |  |   switch (action) { |  |     case 'prev': |  |     case 'undo': |  |       rest = past.slice(0, past.length - 1); |  |       prev = past[past.length - 1] || ''; |  |       return { |  |         past: compact([value, ...rest]), |  |         present: prev |  |       }; |  |   |  |     case 'next': |  |     case 'redo': |  |       rest = past.slice(1); |  |       prev = past[0] || ''; |  |       return { |  |         past: compact([...rest, value]), |  |         present: prev |  |       }; |  |   |  |     case 'save': |  |       return { |  |         past: compact([...past, value]), |  |         present: '' |  |       }; |  |   |  |     case 'remove': |  |       prev = compact(past.filter(v => v !== value)); |  |       present = ''; |  |   |  |       if (prev.length) { |  |         present = prev.pop(); |  |       } |  |   |  |       return { |  |         past: prev, |  |         present |  |       }; |  |   |  |     default: { |  |       throw new Error(`Invalid action: "${action}"`); |  |     } |  |   } |  | }; | 
 |