Skip to content

Commit b14a81a

Browse files
committed
Integrating middleware enhancer
1 parent 27e13ec commit b14a81a

File tree

2 files changed

+136
-37
lines changed

2 files changed

+136
-37
lines changed

src/React/Redux.js

Lines changed: 107 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,123 @@ var Redux = require('redux');
44

55
var ReactRedux = require('react-redux');
66

7-
function createStore_(reducer, state, enhancer) {
7+
function makeActionForeign(action) {
8+
var actionForeign = {
9+
type: '@@purescript',
10+
action: action
11+
};
12+
13+
return actionForeign;
14+
}
15+
16+
exports.createStore_ = function createStore_(reducer, state, enhancer){
817
return function(){
9-
function reducer_(state, action){
10-
var action_ = action.action;
11-
return action_ === undefined ? state : reducer(action_)(state);
12-
};
18+
function reducerForeign(stateReducerForeign, actionForeign){
19+
var action = actionForeign.action;
20+
21+
var result = action === undefined ? stateReducerForeign : reducer(action)(stateReducerForeign);
22+
23+
return result;
24+
}
25+
26+
function enhancerForeign(createStoreForeign){
27+
return function(reducerEnhancerForeign, stateEnhancerForeign){
28+
function createStore(reducerCreateStore){
29+
return function(stateCreateStore){
30+
return function(){
31+
var result = createStoreForeign(reducerCreateStore, stateCreateStore);
1332

14-
return Redux.createStore(reducer_, state, enhancer);
33+
return result;
34+
};
35+
};
36+
}
37+
38+
return enhancer(createStore)(reducerEnhancerForeign)(stateEnhancerForeign)();
39+
};
40+
}
41+
42+
return Redux.createStore(reducerForeign, state, enhancerForeign);
1543
};
16-
}
17-
exports.createStore_ = createStore_;
44+
};
1845

19-
function connect(stateToProps) {
46+
exports.connect = function connect(stateToProps){
2047
return ReactRedux.connect(stateToProps);
21-
}
22-
exports.connect = connect;
48+
};
2349

24-
function dispatch_(this_, action){
50+
exports.dispatch_ = function dispatch_(thisForeign, action){
2551
return function(){
26-
var action_ = {
27-
type: '@@purescript',
28-
action: action
29-
};
52+
var actionForeign = makeActionForeign(action);
53+
54+
var actionForeignResult = thisForeign.props.dispatch(actionForeign);
55+
56+
return actionForeignResult.action;
57+
};
58+
};
3059

31-
var result = this_.props.dispatch(action_);
60+
exports.applyMiddleware = function applyMiddleware(middlewares){
61+
var middlewaresForeign = middlewares.map(function(middleware){
62+
return function(middlewareAPIForeign){
63+
return function(nextForeign){
64+
return function(actionForeign){
65+
function getState(){
66+
return middlewareAPIForeign.getState();
67+
}
3268

33-
return result.action;
69+
function dispatch(action){
70+
return function(){
71+
var actionForeignResult = makeActionForeign(action);
72+
73+
var result = middlewareAPIForeign.dispatch(actionForeignResult);
74+
75+
return result;
76+
};
77+
}
78+
79+
function next(action){
80+
return function(){
81+
var actionForeignResult = makeActionForeign(action);
82+
83+
var result = nextForeign(actionForeignResult);
84+
85+
return result;
86+
};
87+
}
88+
89+
var middlewareAPI = {getState: getState, dispatch: dispatch};
90+
91+
var action = actionForeign.action;
92+
93+
var result = middleware(middlewareAPI)(next)(action)();
94+
95+
return result;
96+
};
97+
};
98+
}
99+
});
100+
101+
var middlewareEnhancerForeign = Redux.applyMiddleware.apply(Redux, middlewaresForeign);
102+
103+
var result = exports.fromEnhancerForeign(middlewareEnhancerForeign);
104+
105+
return result;
106+
};
107+
108+
exports.fromEnhancerForeign = function fromEnhancerForeign(enhancerForeign){
109+
return function(createStore){
110+
return function(reducerForeign){
111+
return function(stateForeign){
112+
return function(){
113+
function createStoreForeign(reducer, state){
114+
var result = createStore(reducer)(state)();
115+
116+
return result;
117+
};
118+
119+
return enhancerForeign(createStoreForeign)(reducerForeign, stateForeign);
120+
};
121+
};
122+
};
34123
};
35124
}
36-
exports.dispatch_ = dispatch_;
37125

38126
exports.providerClass = ReactRedux.Provider;

src/React/Redux.purs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
module React.Redux
22
( ReduxReactClass
3-
, Effects
3+
, ReduxEffect
44
, REDUX
55
, Reducer
6+
, ReducerForeign
67
, Enhancer
7-
, Enhancer_
8+
, EnhancerForeign
9+
, Middleware
10+
, MiddlewareAPI
811
, Store
912
, Spec
1013
, Render
@@ -24,15 +27,17 @@ module React.Redux
2427
, reducerOptic
2528
, spec
2629
, spec'
30+
, applyMiddleware
31+
, fromEnhancerForeign
2732
) where
2833

29-
import Prelude (Unit, (<<<), (>>=), (<$), const, pure, id, unit)
34+
import Prelude (Unit, (>>=), (<$), const, pure, id, unit)
3035

3136
import Control.Monad.Eff (Eff)
3237
import Control.Monad.Eff.Class (class MonadEff, liftEff)
3338

3439
import Data.Either (Either, either)
35-
import Data.Function.Uncurried (Fn2, Fn3, mkFn2, runFn2, runFn3)
40+
import Data.Function.Uncurried (Fn2, Fn3, runFn2, runFn3)
3641
import Data.Lens (Getter', Lens', Prism', matching, set, view)
3742

3843
import Unsafe.Coerce (unsafeCoerce)
@@ -41,11 +46,17 @@ import React as React
4146

4247
type Reducer action state = action -> state -> state
4348

44-
type Enhancer eff action state = (Reducer action state -> state -> Eff (Effects eff) (Store action state)) -> (Reducer action state -> state -> Eff (Effects eff) (Store action state))
49+
type ReducerForeign action state = Fn2 action state state
4550

46-
type Enhancer_ eff action state = (Fn2 (Reducer action state) state (Eff (Effects eff) (Store action state))) -> (Fn2 (Reducer action state) state (Eff (Effects eff) (Store action state)))
51+
type Enhancer eff action state = (Reducer action state -> state -> Eff (ReduxEffect eff) (Store action state)) -> (Reducer action state -> state -> Eff (ReduxEffect eff) (Store action state))
4752

48-
type Effects eff = (redux :: REDUX | eff)
53+
type EnhancerForeign action state = (Fn2 (ReducerForeign action state) state (Store action state)) -> (Fn2 (ReducerForeign action state) state (Store action state))
54+
55+
type Middleware eff action state result = MiddlewareAPI eff action state result -> (action -> Eff (ReduxEffect eff) action) -> action -> Eff (ReduxEffect eff) result
56+
57+
type MiddlewareAPI eff action state result = { getState :: Eff (ReduxEffect eff) state, dispatch :: action -> Eff (ReduxEffect eff) result }
58+
59+
type ReduxEffect eff = (redux :: REDUX | eff)
4960

5061
type Render props state eff f action = (f action -> f action) -> React.Render props state eff
5162

@@ -78,11 +89,7 @@ type Spec props state eff f action =
7889
, componentWillUnmount :: ComponentWillUnmount props state eff f action
7990
}
8091

81-
spec ::
82-
forall props state eff f action.
83-
GetInitialState props state eff f action ->
84-
Render props state eff f action ->
85-
Spec props state eff f action
92+
spec :: forall props state eff f action. GetInitialState props state eff f action -> Render props state eff f action -> Spec props state eff f action
8693
spec getInitialState render =
8794
{ render: render
8895
, displayName: ""
@@ -99,7 +106,7 @@ spec getInitialState render =
99106
spec' :: forall props eff f action. Render props Unit eff f action -> Spec props Unit eff f action
100107
spec' = spec (\_ _ -> pure unit)
101108

102-
createClass :: forall props state eff f action action' state'. MonadEff (Effects eff) f => Getter' action' action -> Getter' state' props -> Spec props state eff f action' -> ReduxReactClass state' props
109+
createClass :: forall props state eff f action action' state'. MonadEff (ReduxEffect eff) f => Getter' action' action -> Getter' state' props -> Spec props state eff f action' -> ReduxReactClass state' props
103110
createClass actionLens stateLens spec_ = connect (view stateLens) reactClass
104111
where
105112
reactClass :: React.ReactClass props
@@ -125,11 +132,11 @@ createProviderElement store reduxClass = React.createElement providerClass { sto
125132
createElement :: forall props state'. ReduxReactClass state' props -> React.ReactElement
126133
createElement reduxClass = React.createElement (unsafeCoerce reduxClass) (unsafeCoerce unit) []
127134

128-
createStore :: forall eff action state. Reducer action state -> state -> Eff (Effects eff) (Store action state)
135+
createStore :: forall eff action state. Reducer action state -> state -> Eff (ReduxEffect eff) (Store action state)
129136
createStore reducer state = createStore' reducer state id
130137

131-
createStore' :: forall eff action state. Reducer action state -> state -> Enhancer eff action state -> Eff (Effects eff) (Store action state)
132-
createStore' reducer state enhancer = runFn3 createStore_ reducer state (mkFn2 <<< enhancer <<< runFn2)
138+
createStore' :: forall eff action state. Reducer action state -> state -> Enhancer eff action state -> Eff (ReduxEffect eff) (Store action state)
139+
createStore' = runFn3 createStore_
133140

134141
reducerOptic :: forall state state' action action'. Lens' state state' -> Prism' action action' -> Reducer action' state' -> Reducer action state
135142
reducerOptic lens prism k action state = either (const state) (\a -> set lens (k a state') state) action'
@@ -148,8 +155,12 @@ foreign import data ReduxReactClass :: * -> * -> *
148155

149156
foreign import connect :: forall state' props. (state' -> props) -> React.ReactClass props -> ReduxReactClass state' props
150157

151-
foreign import dispatch_ :: forall eff props action state. Fn2 (React.ReactThis props state) action (Eff (Effects eff) action)
158+
foreign import dispatch_ :: forall eff props action state. Fn2 (React.ReactThis props state) action (Eff (ReduxEffect eff) action)
152159

153160
foreign import providerClass :: forall action state'. React.ReactClass { store :: Store action state' }
154161

155-
foreign import createStore_ :: forall eff action state. Fn3 (Reducer action state) state (Enhancer_ eff action state) (Eff (Effects eff) (Store action state))
162+
foreign import createStore_ :: forall eff action state. Fn3 (Reducer action state) state (Enhancer eff action state) (Eff (ReduxEffect eff) (Store action state))
163+
164+
foreign import applyMiddleware :: forall eff action state result. Array (Middleware eff action state result) -> Enhancer eff action state
165+
166+
foreign import fromEnhancerForeign :: forall eff action state. EnhancerForeign action state -> Enhancer eff action state

0 commit comments

Comments
 (0)