Skip to content

Commit

Permalink
Initial purs-tidy format
Browse files Browse the repository at this point in the history
  • Loading branch information
OwenGraves committed Oct 22, 2024
1 parent 3263c9a commit dfcb73f
Show file tree
Hide file tree
Showing 23 changed files with 739 additions and 541 deletions.
119 changes: 65 additions & 54 deletions src/DOM/Erumu/App.purs
Original file line number Diff line number Diff line change
Expand Up @@ -46,100 +46,111 @@ type RenderFn model msg = model -> HTML msg
-- * Dispatching a message is always "safe"
-- - e.g. you can save a dispatch function for later call it at any time.
--
newApp :: forall m model msg.
(model -> HTML msg)
-> UpdateFn m model msg
-> model
-> (m Unit -> Effect Unit)
-> (Effect Unit -> m Unit)
-> Effect (App m model msg)
newApp ::
forall m model msg.
(model -> HTML msg) ->
UpdateFn m model msg ->
model ->
(m Unit -> Effect Unit) ->
(Effect Unit -> m Unit) ->
Effect (App m model msg)
newApp render update init execM liftM = do
virtualApp <- Virtual.newApp (node "div" [] [])
stRef <- Ref.new { model: init
, messages: Nil
, processing: false
}
stRef <- Ref.new
{ model: init
, messages: Nil
, processing: false
}

let app = App { update, render, stRef, virtualApp, execM, liftM }

renderApp app
pure app

mountApp :: forall m model msg.
String
-> App m model msg
-> Effect (Maybe String)
mountApp ::
forall m model msg.
String ->
App m model msg ->
Effect (Maybe String)
mountApp containerId (App { virtualApp }) =
Virtual.mountApp containerId virtualApp


dispatch :: forall m model msg.
App m model msg
-> msg
-> Effect Unit
dispatch ::
forall m model msg.
App m model msg ->
msg ->
Effect Unit
dispatch app@(App { stRef }) msg = do
pushMessage stRef msg
processMessages app

renderApp :: forall m model msg.
App m model msg
-> Effect Unit
renderApp ::
forall m model msg.
App m model msg ->
Effect Unit
renderApp app@(App { virtualApp, render, stRef }) = do
st <- Ref.read stRef
Virtual.rerenderApp (toVTree (render st.model) (dispatch app))
virtualApp
virtualApp

tryTakeMessages :: forall model msg.
Ref (DispatchState model msg)
-> Effect (Maybe (List msg))
tryTakeMessages ::
forall model msg.
Ref (DispatchState model msg) ->
Effect (Maybe (List msg))
tryTakeMessages stRef =
(flip Ref.modify') stRef $
\st ->
if st.processing
then { state: st, value: Nothing }
else { state: st { messages = Nil }
, value: Just (reverse st.messages)
}

setProcessing :: forall model msg.
Ref (DispatchState model msg)
-> Boolean
-> Effect Unit
if st.processing then { state: st, value: Nothing }
else
{ state: st { messages = Nil }
, value: Just (reverse st.messages)
}

setProcessing ::
forall model msg.
Ref (DispatchState model msg) ->
Boolean ->
Effect Unit
setProcessing stRef processing = void $
Ref.modify (_ { processing = processing }) stRef

pushMessage :: forall model msg.
Ref (DispatchState model msg)
-> msg
-> Effect Unit
pushMessage ::
forall model msg.
Ref (DispatchState model msg) ->
msg ->
Effect Unit
pushMessage stRef msg = void $
Ref.modify (\st -> st { messages = Cons msg st.messages }) stRef

processMessages :: forall m msg model.
App m model msg
-> Effect Unit
processMessages ::
forall m msg model.
App m model msg ->
Effect Unit
processMessages app@(App { stRef }) = void $ do
taken <- tryTakeMessages stRef

case taken of
Nothing -> pure unit -- messages are already being processed
Just Nil -> pure unit -- there are no messages to process
Nothing -> pure unit -- messages are already being processed
Just Nil -> pure unit -- there are no messages to process
Just msgs -> do
setProcessing stRef true
traverse_ (processMessage app) msgs
setProcessing stRef false
processMessages app

processMessage :: forall m msg model.
App m model msg
-> msg
-> Effect Unit
processMessage ::
forall m msg model.
App m model msg ->
msg ->
Effect Unit
processMessage app@(App { update, stRef, execM, liftM }) msg = void $ do
command <- (flip Ref.modify') stRef $ \st ->
let r = update msg st.model
in { state: st { model = r.model }
, value: r.command
}
let
r = update msg st.model
in
{ state: st { model = r.model }
, value: r.command
}

renderApp app
runcmd command (liftM <<< dispatch app) execM
Expand Down
100 changes: 55 additions & 45 deletions src/DOM/Erumu/Array.purs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ import DOM.Erumu.Types ((!), HTML, Return(..), UpdateResult, liftReturn, liftUpd

data Msg msg = Msg Int msg

render :: forall msg model.
(model -> HTML msg)
-> Array model
-> Array (HTML (Msg msg))
render ::
forall msg model.
(model -> HTML msg) ->
Array model ->
Array (HTML (Msg msg))
render renderItem items =
mapWithIndex renderIdx items
where
renderIdx idx item = (Msg idx) <$> renderItem item
where
renderIdx idx item = (Msg idx) <$> renderItem item

-- renderLift allows you to render items that may contain a mixture of
-- messages from parent a child (item) components. This can be useful in
Expand All @@ -51,60 +52,69 @@ render renderItem items =
-- into Array messages which will then need to be wrapped into parentMsgs using
-- the appropriate parent-specific constructor
-- The index of the item being rendered is provided for your convenience.
renderLift :: forall childMsg parentMsg model.
((childMsg -> Msg childMsg) -> Int -> model -> HTML parentMsg)
-> Array model
-> Array (HTML parentMsg)
renderLift ::
forall childMsg parentMsg model.
((childMsg -> Msg childMsg) -> Int -> model -> HTML parentMsg) ->
Array model ->
Array (HTML parentMsg)
renderLift renderItem items =
mapWithIndex renderIdx items
where
renderIdx idx item = renderItem (Msg idx) idx item

update :: forall m msg model.
Applicative m
=> (msg -> model -> UpdateResult m model msg)
-> Msg msg
-> Array model
-> Maybe (UpdateResult m (Array model) (Msg msg))
where
renderIdx idx item = renderItem (Msg idx) idx item

update ::
forall m msg model.
Applicative m =>
(msg -> model -> UpdateResult m model msg) ->
Msg msg ->
Array model ->
Maybe (UpdateResult m (Array model) (Msg msg))
update f msg items =
unwrap $ sequence $ updateF (Identity `compose2` f) msg items
where
compose2 :: forall a b c d.
(c -> d)
-> (a -> b -> c)
-> (a -> b -> d)
compose2 g h = \a b -> g (h a b)

updateF :: forall f m msg model.
Functor f
=> Applicative m
=> (msg -> model -> f (UpdateResult m model msg))
-> Msg msg
-> Array model
-> Maybe (f (UpdateResult m (Array model) (Msg msg)))
where
compose2 ::
forall a b c d.
(c -> d) ->
(a -> b -> c) ->
(a -> b -> d)
compose2 g h = \a b -> g (h a b)

updateF ::
forall f m msg model.
Functor f =>
Applicative m =>
(msg -> model -> f (UpdateResult m model msg)) ->
Msg msg ->
Array model ->
Maybe (f (UpdateResult m (Array model) (Msg msg)))
updateF updateItem (Msg idx msg) items =
case items !! idx of
Nothing -> Nothing
Just oldItem -> Just $
let liftItem newItem = fromMaybe items $ updateAt idx newItem items
in liftUpdate (Msg idx) (liftItem) <$>
updateItem msg oldItem
let
liftItem newItem = fromMaybe items $ updateAt idx newItem items
in
liftUpdate (Msg idx) (liftItem) <$>
updateItem msg oldItem

-- Return
updateArrayWith :: forall m signal childmodel childmsg.
Applicative m
=> (childmsg -> childmodel -> Return m childmodel childmsg signal)
-> Msg childmsg
-> Array childmodel
-> Return m (Array childmodel) (Msg childmsg) signal
updateArrayWith ::
forall m signal childmodel childmsg.
Applicative m =>
(childmsg -> childmodel -> Return m childmodel childmsg signal) ->
Msg childmsg ->
Array childmodel ->
Return m (Array childmodel) (Msg childmsg) signal
updateArrayWith updateFn (Msg idx msg) models =
case models !! idx of

-- When index isn't in list (how?!), just Continue
Nothing -> Continue $ models ! []

Just oldItem ->
let liftModel newM = fromMaybe models $ updateAt idx newM models
in liftReturn (Msg idx) liftModel
$ updateFn msg oldItem
let
liftModel newM = fromMaybe models $ updateAt idx newM models
in
liftReturn (Msg idx) liftModel
$ updateFn msg oldItem

40 changes: 24 additions & 16 deletions src/DOM/Erumu/Array/Dynamic.purs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
module DOM.Erumu.Array.Dynamic
( Msg
, Edit, add, remove, editMsg, updateMsg
, Edit
, add
, remove
, editMsg
, updateMsg
, render
, update
) where
Expand All @@ -13,8 +17,8 @@ import Data.Either (Either(..))
import DOM.Erumu.Array as Array
import DOM.Erumu.Types (UpdateResult, HTML, liftUpdate, (!))

data Edit model =
Add model
data Edit model
= Add model
| Remove Int

add :: forall model. model -> Edit model
Expand All @@ -32,20 +36,24 @@ updateMsg = Msg <<< Right
newtype Msg model msg =
Msg (Either (Edit model) (Array.Msg msg))

render :: forall model msg.
(Int -> model -> HTML (Either (Edit model) msg))
-> Array model
-> Array (HTML (Msg model msg))
render ::
forall model msg.
(Int -> model -> HTML (Either (Edit model) msg)) ->
Array model ->
Array (HTML (Msg model msg))
render renderItem items =
let renderItem' lifter idx model = Msg <<< map lifter <$> renderItem idx model
in Array.renderLift renderItem' items

update :: forall m msg model.
Applicative m
=> (msg -> model -> UpdateResult m model msg)
-> Msg model msg
-> Array model
-> Maybe (UpdateResult m (Array model) (Msg model msg))
let
renderItem' lifter idx model = Msg <<< map lifter <$> renderItem idx model
in
Array.renderLift renderItem' items

update ::
forall m msg model.
Applicative m =>
(msg -> model -> UpdateResult m model msg) ->
Msg model msg ->
Array model ->
Maybe (UpdateResult m (Array model) (Msg model msg))
update _ (Msg (Left (Add model))) items = Just $
(items `snoc` model) ! []

Expand Down
10 changes: 5 additions & 5 deletions src/DOM/Erumu/Decode.purs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ event = Decode $ \e -> pure (pure e)
domValue :: forall a b. (a -> Effect b) -> a -> Decode b
domValue f a = Decode $ \_ -> pure <$> f a

domEffect :: Effect Unit -> Decode Unit
domEffect :: Effect Unit -> Decode Unit
domEffect eff = Decode $ \_ -> pure <$> eff

crash :: forall a. String -> Decode a
Expand All @@ -51,10 +51,10 @@ instance applicativeDecode :: Applicative Decode where

instance bindDecode :: Bind Decode where
bind (Decode dA) f = Decode $ \e -> do
result <- dA e
case f <$> result of
Right (Decode dB) -> dB e
Left err -> pure (Left err)
result <- dA e
case f <$> result of
Right (Decode dB) -> dB e
Left err -> pure (Left err)

instance monadDecode :: Monad Decode

Loading

0 comments on commit dfcb73f

Please sign in to comment.