/
Store.purs
76 lines (65 loc) · 2.11 KB
/
Store.purs
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
module Radox.Internal.Store (update, getState) where
import Prelude (Unit, bind, discard, pure, unit)
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Effect.Ref (Ref, read, write)
import Data.Traversable (traverse)
import Radox.Internal.Types
-- | This takes our action runs it through the reducers, updates listeners with the result
-- | And then updates the ref with the new value
-- | Note actionType must have have been `lift`-ed into the Variant for use here
update
:: forall stateType actionType
. Ref stateType
-> Listeners stateType
-> Effect stateType
-> CombinedReducer actionType stateType
-> actionType
-> Effect Unit
update stateRef listeners getState' reducers action = do
-- read current state
oldState <- read stateRef
--- create effect functions for the reducers to use
let passedFuncs = { dispatch: update stateRef listeners getState' reducers
, getState: getState'
, state: oldState
}
-- calculate new state
let return = reducers passedFuncs oldState action
newState = stateFromResponse oldState return
aff = affFromResponse return
-- announce new state to listeners
_ <- traverse (\f -> f newState) listeners
-- save new state
write newState stateRef
-- launch side effects
launchAff_ aff
-- | calculate new state from response
stateFromResponse
:: forall stateType
. stateType
-> ReducerReturn stateType
-> stateType
stateFromResponse oldState return
= case return of
NoOp -> oldState
UpdateState state -> state
UpdateStateAndRunEffect state _ -> state
RunEffect _ -> oldState
-- | calculate which effects to fire from the response
affFromResponse
:: forall stateType
. ReducerReturn stateType
-> Aff Unit
affFromResponse return
= case return of
NoOp -> pure unit
UpdateState _ -> pure unit
UpdateStateAndRunEffect _ a -> a
RunEffect a -> a
-- | Read the current state this is saved in the mutable Ref and returns it
getState
:: forall stateType
. Ref stateType
-> Effect stateType
getState stateRef = read stateRef