11import { combineReducers } from 'redux' ;
22
3- const ActionTypes = {
3+ export const ActionTypes = {
44 PERFORM_ACTION : 'PERFORM_ACTION' ,
55 RESET : 'RESET' ,
66 ROLLBACK : 'ROLLBACK' ,
@@ -10,10 +10,41 @@ const ActionTypes = {
1010 JUMP_TO_STATE : 'JUMP_TO_STATE'
1111} ;
1212
13- const INIT_ACTION = {
14- type : '@@INIT'
13+ /**
14+ * Action creators to change the History state.
15+ */
16+ export const ActionCreators = {
17+ performAction ( action ) {
18+ return { type : ActionTypes . PERFORM_ACTION , action, timestamp : Date . now ( ) } ;
19+ } ,
20+
21+ reset ( ) {
22+ return { type : ActionTypes . RESET , timestamp : Date . now ( ) } ;
23+ } ,
24+
25+ rollback ( ) {
26+ return { type : ActionTypes . ROLLBACK , timestamp : Date . now ( ) } ;
27+ } ,
28+
29+ commit ( ) {
30+ return { type : ActionTypes . COMMIT , timestamp : Date . now ( ) } ;
31+ } ,
32+
33+ sweep ( ) {
34+ return { type : ActionTypes . SWEEP } ;
35+ } ,
36+
37+ toggleAction ( index ) {
38+ return { type : ActionTypes . TOGGLE_ACTION , index } ;
39+ } ,
40+
41+ jumpToState ( index ) {
42+ return { type : ActionTypes . JUMP_TO_STATE , index } ;
43+ }
1544} ;
1645
46+ const INIT_ACTION = { type : '@@INIT' } ;
47+
1748function toggle ( obj , key ) {
1849 const clone = { ...obj } ;
1950 if ( clone [ key ] ) {
@@ -52,8 +83,6 @@ function computeNextEntry(reducer, action, state, error) {
5283
5384/**
5485 * Runs the reducer on all actions to get a fresh computation log.
55- * It's probably a good idea to do this only if the code has changed,
56- * but until we have some tests we'll just do it every time an action fires.
5786 */
5887function recomputeStates ( reducer , committedState , stagedActions , skippedActions ) {
5988 const computedStates = [ ] ;
@@ -77,10 +106,10 @@ function recomputeStates(reducer, committedState, stagedActions, skippedActions)
77106}
78107
79108/**
80- * Lifts the app state reducer into a DevTools state reducer.
109+ * Creates a history state reducer from an app's reducer.
81110 */
82- function createDevToolsStateReducer ( reducer , initialCommittedState ) {
83- const initialState = {
111+ function createHistoryReducer ( reducer , initialCommittedState ) {
112+ const initialHistoryState = {
84113 committedState : initialCommittedState ,
85114 stagedActions : [ INIT_ACTION ] ,
86115 skippedActions : { } ,
@@ -89,9 +118,9 @@ function createDevToolsStateReducer(reducer, initialCommittedState) {
89118 } ;
90119
91120 /**
92- * Manages how the DevTools actions modify the DevTools state.
121+ * Manages how the history actions modify the history state.
93122 */
94- return function devToolsState ( state = initialState , action ) {
123+ return ( historyState = initialHistoryState , historyAction ) => {
95124 let shouldRecomputeStates = true ;
96125 let {
97126 committedState,
@@ -100,34 +129,34 @@ function createDevToolsStateReducer(reducer, initialCommittedState) {
100129 computedStates,
101130 currentStateIndex,
102131 timestamps
103- } = state ;
132+ } = historyState ;
104133
105- switch ( action . type ) {
134+ switch ( historyAction . type ) {
106135 case ActionTypes . RESET :
107- committedState = initialState ;
136+ committedState = initialCommittedState ;
108137 stagedActions = [ INIT_ACTION ] ;
109138 skippedActions = { } ;
110139 currentStateIndex = 0 ;
111- timestamps = [ action . timestamp ] ;
140+ timestamps = [ historyAction . timestamp ] ;
112141 break ;
113142 case ActionTypes . COMMIT :
114143 committedState = computedStates [ currentStateIndex ] . state ;
115144 stagedActions = [ INIT_ACTION ] ;
116145 skippedActions = { } ;
117146 currentStateIndex = 0 ;
118- timestamps = [ action . timestamp ] ;
147+ timestamps = [ historyAction . timestamp ] ;
119148 break ;
120149 case ActionTypes . ROLLBACK :
121150 stagedActions = [ INIT_ACTION ] ;
122151 skippedActions = { } ;
123152 currentStateIndex = 0 ;
124- timestamps = [ action . timestamp ] ;
153+ timestamps = [ historyAction . timestamp ] ;
125154 break ;
126155 case ActionTypes . TOGGLE_ACTION :
127- skippedActions = toggle ( skippedActions , action . index ) ;
156+ skippedActions = toggle ( skippedActions , historyAction . index ) ;
128157 break ;
129158 case ActionTypes . JUMP_TO_STATE :
130- currentStateIndex = action . index ;
159+ currentStateIndex = historyAction . index ;
131160 // Optimization: we know the history has not changed.
132161 shouldRecomputeStates = false ;
133162 break ;
@@ -142,16 +171,16 @@ function createDevToolsStateReducer(reducer, initialCommittedState) {
142171 currentStateIndex ++ ;
143172 }
144173
145- stagedActions = [ ...stagedActions , action . action ] ;
146- timestamps = [ ...timestamps , action . timestamp ] ;
174+ stagedActions = [ ...stagedActions , historyAction . action ] ;
175+ timestamps = [ ...timestamps , historyAction . timestamp ] ;
147176
148177 // Optimization: we know that the past has not changed.
149178 shouldRecomputeStates = false ;
150179 // Instead of recomputing the states, append the next one.
151180 const previousEntry = computedStates [ computedStates . length - 1 ] ;
152181 const nextEntry = computeNextEntry (
153182 reducer ,
154- action . action ,
183+ historyAction . action ,
155184 previousEntry . state ,
156185 previousEntry . error
157186 ) ;
@@ -182,96 +211,58 @@ function createDevToolsStateReducer(reducer, initialCommittedState) {
182211}
183212
184213/**
185- * Lifts an app action to a DevTools action.
186- */
187- function liftAction ( action ) {
188- const liftedAction = {
189- type : ActionTypes . PERFORM_ACTION ,
190- action,
191- timestamp : Date . now ( )
192- } ;
193- return liftedAction ;
194- }
195-
196- /**
197- * Unlifts the DevTools state to the app state.
214+ * Provides a view into the History state that matches the current app state.
198215 */
199- function unliftState ( liftedState ) {
200- const { computedStates, currentStateIndex } = liftedState . devToolsState ;
216+ function selectAppState ( instrumentedState ) {
217+ const { computedStates, currentStateIndex } = instrumentedState . historyState ;
201218 const { state } = computedStates [ currentStateIndex ] ;
202219 return state ;
203220}
204221
205222/**
206- * Unlifts the DevTools store to act like the app's store.
223+ * Deinstruments the History store to act like the app's store.
207224 */
208- function mapToComputedStateStore ( devToolsStore , wrapReducer ) {
225+ function selectAppStore ( instrumentedStore , instrumentReducer ) {
209226 let lastDefinedState ;
210227
211228 return {
212- ...devToolsStore ,
229+ ...instrumentedStore ,
213230
214- devToolsStore ,
231+ instrumentedStore ,
215232
216233 dispatch ( action ) {
217- devToolsStore . dispatch ( liftAction ( action ) ) ;
234+ instrumentedStore . dispatch ( ActionCreators . performAction ( action ) ) ;
218235 return action ;
219236 } ,
220237
221238 getState ( ) {
222- const state = unliftState ( devToolsStore . getState ( ) ) ;
239+ const state = selectAppState ( instrumentedStore . getState ( ) ) ;
223240 if ( state !== undefined ) {
224241 lastDefinedState = state ;
225242 }
226243 return lastDefinedState ;
227244 } ,
228245
229246 replaceReducer ( nextReducer ) {
230- devToolsStore . replaceReducer ( wrapReducer ( nextReducer ) ) ;
247+ instrumentedStore . replaceReducer ( instrumentReducer ( nextReducer ) ) ;
231248 }
232249 } ;
233250}
234251
235252/**
236- * Action creators to change the DevTools state .
253+ * Redux History store enhancer .
237254 */
238- export const ActionCreators = {
239- reset ( ) {
240- return { type : ActionTypes . RESET , timestamp : Date . now ( ) } ;
241- } ,
242-
243- rollback ( ) {
244- return { type : ActionTypes . ROLLBACK , timestamp : Date . now ( ) } ;
245- } ,
246-
247- commit ( ) {
248- return { type : ActionTypes . COMMIT , timestamp : Date . now ( ) } ;
249- } ,
250-
251- sweep ( ) {
252- return { type : ActionTypes . SWEEP } ;
253- } ,
254-
255- toggleAction ( index ) {
256- return { type : ActionTypes . TOGGLE_ACTION , index } ;
257- } ,
258-
259- jumpToState ( index ) {
260- return { type : ActionTypes . JUMP_TO_STATE , index } ;
261- }
262- } ;
255+ export default function instrument ( monitorReducer = ( ) => null ) {
256+ return createStore => ( reducer , initialState ) => {
257+ function instrumentReducer ( r ) {
258+ const historyReducer = createHistoryReducer ( r , initialState ) ;
259+ return ( { historyState, monitorState } = { } , action ) => ( {
260+ historyState : historyReducer ( historyState , action ) ,
261+ monitorState : monitorReducer ( monitorState , action )
262+ } ) ;
263+ }
263264
264- /**
265- * Redux DevTools store enhancer.
266- */
267- export default function enhance ( monitorReducer = ( ) => null ) {
268- return next => ( reducer , initialState ) => {
269- const wrapReducer = ( r ) => combineReducers ( {
270- devToolsState : createDevToolsStateReducer ( r , initialState ) ,
271- monitorState : monitorReducer
272- } ) ;
273-
274- const devToolsStore = next ( wrapReducer ( reducer ) ) ;
275- return mapToComputedStateStore ( devToolsStore , wrapReducer ) ;
265+ const instrumentedStore = createStore ( instrumentReducer ( reducer ) ) ;
266+ return selectAppStore ( instrumentedStore , instrumentReducer ) ;
276267 } ;
277268}
0 commit comments