module Miso.Types
( App (..)
, LogLevel (..)
, Effect
, Sub
, Transition
, mapAction
, fromTransition
, toTransition
, scheduleIO
, scheduleIO_
, scheduleIOFor_
, scheduleSub
) where
import Control.Monad.IO.Class
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.State.Strict (StateT(StateT), execStateT, mapStateT)
import Control.Monad.Trans.Writer.Strict (WriterT(WriterT), Writer, runWriter, tell, mapWriter)
import Data.Bifunctor (second)
import Data.Foldable (Foldable, for_)
import qualified Data.Map as M
import Miso.Effect
import Miso.FFI (JSM)
import Miso.Html.Types (View)
import Miso.String
data App model action = App
{ App model action -> model
model :: model
, App model action -> action -> model -> Effect action model
update :: action -> model -> Effect action model
, App model action -> model -> View action
view :: model -> View action
, App model action -> [Sub action]
subs :: [ Sub action ]
, App model action -> Map MisoString Bool
events :: M.Map MisoString Bool
, App model action -> action
initialAction :: action
, App model action -> Maybe MisoString
mountPoint :: Maybe MisoString
, App model action -> LogLevel
logLevel :: LogLevel
}
data LogLevel
= Off
| DebugPrerender
deriving (Int -> LogLevel -> ShowS
[LogLevel] -> ShowS
LogLevel -> String
(Int -> LogLevel -> ShowS)
-> (LogLevel -> String) -> ([LogLevel] -> ShowS) -> Show LogLevel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LogLevel] -> ShowS
$cshowList :: [LogLevel] -> ShowS
show :: LogLevel -> String
$cshow :: LogLevel -> String
showsPrec :: Int -> LogLevel -> ShowS
$cshowsPrec :: Int -> LogLevel -> ShowS
Show, LogLevel -> LogLevel -> Bool
(LogLevel -> LogLevel -> Bool)
-> (LogLevel -> LogLevel -> Bool) -> Eq LogLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LogLevel -> LogLevel -> Bool
$c/= :: LogLevel -> LogLevel -> Bool
== :: LogLevel -> LogLevel -> Bool
$c== :: LogLevel -> LogLevel -> Bool
Eq)
type Transition action model = StateT model (Writer [Sub action])
mapAction :: (actionA -> actionB) -> Transition actionA model r -> Transition actionB model r
mapAction :: (actionA -> actionB)
-> Transition actionA model r -> Transition actionB model r
mapAction = (WriterT [Sub actionA] Identity (r, model)
-> WriterT [Sub actionB] Identity (r, model))
-> Transition actionA model r -> Transition actionB model r
forall (m :: * -> *) a s (n :: * -> *) b.
(m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
mapStateT ((WriterT [Sub actionA] Identity (r, model)
-> WriterT [Sub actionB] Identity (r, model))
-> Transition actionA model r -> Transition actionB model r)
-> ((actionA -> actionB)
-> WriterT [Sub actionA] Identity (r, model)
-> WriterT [Sub actionB] Identity (r, model))
-> (actionA -> actionB)
-> Transition actionA model r
-> Transition actionB model r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (((r, model), [Sub actionA]) -> ((r, model), [Sub actionB]))
-> WriterT [Sub actionA] Identity (r, model)
-> WriterT [Sub actionB] Identity (r, model)
forall a w b w'. ((a, w) -> (b, w')) -> Writer w a -> Writer w' b
mapWriter ((((r, model), [Sub actionA]) -> ((r, model), [Sub actionB]))
-> WriterT [Sub actionA] Identity (r, model)
-> WriterT [Sub actionB] Identity (r, model))
-> ((actionA -> actionB)
-> ((r, model), [Sub actionA]) -> ((r, model), [Sub actionB]))
-> (actionA -> actionB)
-> WriterT [Sub actionA] Identity (r, model)
-> WriterT [Sub actionB] Identity (r, model)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Sub actionA] -> [Sub actionB])
-> ((r, model), [Sub actionA]) -> ((r, model), [Sub actionB])
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (([Sub actionA] -> [Sub actionB])
-> ((r, model), [Sub actionA]) -> ((r, model), [Sub actionB]))
-> ((actionA -> actionB) -> [Sub actionA] -> [Sub actionB])
-> (actionA -> actionB)
-> ((r, model), [Sub actionA])
-> ((r, model), [Sub actionB])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sub actionA -> Sub actionB) -> [Sub actionA] -> [Sub actionB]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Sub actionA -> Sub actionB) -> [Sub actionA] -> [Sub actionB])
-> ((actionA -> actionB) -> Sub actionA -> Sub actionB)
-> (actionA -> actionB)
-> [Sub actionA]
-> [Sub actionB]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (actionA -> actionB) -> Sub actionA -> Sub actionB
forall actionA actionB.
(actionA -> actionB) -> Sub actionA -> Sub actionB
mapSub
fromTransition
:: Transition action model ()
-> (model -> Effect action model)
fromTransition :: Transition action model () -> model -> Effect action model
fromTransition Transition action model ()
act = (model -> [Sub action] -> Effect action model)
-> (model, [Sub action]) -> Effect action model
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry model -> [Sub action] -> Effect action model
forall action model. model -> [Sub action] -> Effect action model
Effect ((model, [Sub action]) -> Effect action model)
-> (model -> (model, [Sub action])) -> model -> Effect action model
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Writer [Sub action] model -> (model, [Sub action])
forall w a. Writer w a -> (a, w)
runWriter (Writer [Sub action] model -> (model, [Sub action]))
-> (model -> Writer [Sub action] model)
-> model
-> (model, [Sub action])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transition action model () -> model -> Writer [Sub action] model
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT Transition action model ()
act
toTransition
:: (model -> Effect action model)
-> Transition action model ()
toTransition :: (model -> Effect action model) -> Transition action model ()
toTransition model -> Effect action model
f = (model -> WriterT [Sub action] Identity ((), model))
-> Transition action model ()
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((model -> WriterT [Sub action] Identity ((), model))
-> Transition action model ())
-> (model -> WriterT [Sub action] Identity ((), model))
-> Transition action model ()
forall a b. (a -> b) -> a -> b
$ \model
s ->
let Effect model
s' [Sub action]
ios = model -> Effect action model
f model
s
in Identity (((), model), [Sub action])
-> WriterT [Sub action] Identity ((), model)
forall w (m :: * -> *) a. m (a, w) -> WriterT w m a
WriterT (Identity (((), model), [Sub action])
-> WriterT [Sub action] Identity ((), model))
-> Identity (((), model), [Sub action])
-> WriterT [Sub action] Identity ((), model)
forall a b. (a -> b) -> a -> b
$ (((), model), [Sub action]) -> Identity (((), model), [Sub action])
forall (f :: * -> *) a. Applicative f => a -> f a
pure (((), model
s'), [Sub action]
ios)
scheduleIO :: JSM action -> Transition action model ()
scheduleIO :: JSM action -> Transition action model ()
scheduleIO JSM action
ioAction = Sub action -> Transition action model ()
forall action model. Sub action -> Transition action model ()
scheduleSub (Sub action -> Transition action model ())
-> Sub action -> Transition action model ()
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> JSM action
ioAction JSM action -> (action -> JSM ()) -> JSM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO () -> JSM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> JSM ()) -> Sink action -> action -> JSM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sink action
sink
scheduleIO_ :: JSM () -> Transition action model ()
scheduleIO_ :: JSM () -> Transition action model ()
scheduleIO_ JSM ()
ioAction = Sub action -> Transition action model ()
forall action model. Sub action -> Transition action model ()
scheduleSub (Sub action -> Transition action model ())
-> Sub action -> Transition action model ()
forall a b. (a -> b) -> a -> b
$ \Sink action
_sink -> JSM ()
ioAction
scheduleIOFor_ :: Foldable f => JSM (f action) -> Transition action model ()
scheduleIOFor_ :: JSM (f action) -> Transition action model ()
scheduleIOFor_ JSM (f action)
io = Sub action -> Transition action model ()
forall action model. Sub action -> Transition action model ()
scheduleSub (Sub action -> Transition action model ())
-> Sub action -> Transition action model ()
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> JSM (f action)
io JSM (f action) -> (f action -> JSM ()) -> JSM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \f action
m -> IO () -> JSM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (f action -> Sink action -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ f action
m Sink action
sink)
scheduleSub :: Sub action -> Transition action model ()
scheduleSub :: Sub action -> Transition action model ()
scheduleSub Sub action
sub = WriterT [Sub action] Identity () -> Transition action model ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (WriterT [Sub action] Identity () -> Transition action model ())
-> WriterT [Sub action] Identity () -> Transition action model ()
forall a b. (a -> b) -> a -> b
$ [Sub action] -> WriterT [Sub action] Identity ()
forall (m :: * -> *) w. Monad m => w -> WriterT w m ()
tell [ Sub action
sub ]