-
Notifications
You must be signed in to change notification settings - Fork 25
/
DispatcherRecorder.js
136 lines (122 loc) · 2.93 KB
/
DispatcherRecorder.js
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* DispatcherRecorder(alt: AltInstance): DispatcherInstance
*
* > Record and replay your actions at any point in time.
*
* This util allows you to record a set of dispatches which you can later
* replay at your convenience.
*
* Good for: Debugging, repeating, logging.
*
* Usage:
*
* ```js
* var recorder = new DispatcherRecorder(alt);
*
* // start recording
* recorder.record();
*
* // call a series of actions
*
* // stop recording
* recorder.stop();
*
* // replay the events that took place
* recorder.replay();
* ```
*/
function DispatcherRecorder(alt, maxEvents = Infinity) {
this.alt = alt
this.events = []
this.dispatchToken = null
this.maxEvents = maxEvents
}
/**
* If recording started you get true, otherwise false since there's a recording
* in progress.
* record(): boolean
*/
DispatcherRecorder.prototype.record = function record() {
if (this.dispatchToken) {
return false
}
this.dispatchToken = this.alt.dispatcher.register((payload) => {
if (this.events.length < this.maxEvents) {
this.events.push(payload)
}
})
return true
}
/**
* Stops the recording in progress.
* stop(): undefined
*/
DispatcherRecorder.prototype.stop = function stop() {
this.alt.dispatcher.unregister(this.dispatchToken)
this.dispatchToken = null
}
/**
* Clear all events from memory.
* clear(): undefined
*/
DispatcherRecorder.prototype.clear = function clear() {
this.events = []
}
/**
* (As|S)ynchronously replay all events that were recorded.
* replay(replayTime: ?number, done: ?function): undefined
*/
DispatcherRecorder.prototype.replay = function replay(replayTime, done) {
const alt = this.alt
if (replayTime === void 0) {
this.events.forEach((payload) => {
alt.dispatch(payload.action, payload.data)
})
}
const onNext = (payload, nextAction) => {
return () => {
setTimeout(() => {
alt.dispatch(payload.action, payload.data)
nextAction()
}, replayTime)
}
}
let next = done || () => {}
let i = this.events.length - 1
while (i >= 0) {
const event = this.events[i]
next = onNext(event, next)
i -= 1
}
next()
}
/**
* Serialize all the events so you can pass them around or load them into
* a separate recorder.
* serializeEvents(): string
*/
DispatcherRecorder.prototype.serializeEvents = function serializeEvents() {
const events = this.events.map((event) => {
return {
id: event.id,
action: event.action,
data: event.data || {},
}
})
return JSON.stringify(events)
}
/**
* Load serialized events into the recorder and overwrite the current events
* loadEvents(events: string): undefined
*/
DispatcherRecorder.prototype.loadEvents = function loadEvents(events) {
const parsedEvents = JSON.parse(events)
this.events = parsedEvents.map((event) => {
return {
action: event.action,
data: event.data,
}
})
return parsedEvents
}
export default DispatcherRecorder