| Copyright | (C) 2016-2025 David M. Johnson |
|---|---|
| License | BSD3-style (see the file LICENSE) |
| Maintainer | David M. Johnson <code@dmj.io> |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | None |
| Language | Haskell2010 |
Miso.Effect
Description
Synopsis
- type Effect parent model action = RWS (ComponentInfo parent) [Sink action -> JSM ()] model ()
- type Sub action = Sink action -> JSM ()
- type Sink action = action -> JSM ()
- type DOMRef = JSVal
- data ComponentInfo parent = ComponentInfo {}
- type ComponentId = Int
- mkComponentInfo :: ComponentId -> ComponentId -> DOMRef -> ComponentInfo parent
- (<#) :: model -> JSM action -> Effect parent model action
- (#>) :: JSM action -> model -> Effect parent model action
- batch :: [JSM action] -> Effect parent model action
- batch_ :: [JSM ()] -> Effect parent model action
- io :: JSM action -> Effect parent model action
- io_ :: JSM () -> Effect parent model action
- for :: Foldable f => JSM (f action) -> Effect parent model action
- issue :: action -> Effect parent model action
- withSink :: (Sink action -> JSM ()) -> Effect parent model action
- mapSub :: (a -> b) -> Sub a -> Sub b
- noop :: action -> Effect parent model action
- beforeAll :: JSM () -> Effect parent model action -> Effect parent model action
- afterAll :: JSM () -> Effect parent model action -> Effect parent model action
- modifyAllJSM :: (JSM () -> JSM ()) -> Effect parent model action -> Effect parent model action
- runEffect :: Effect parent model action -> ComponentInfo parent -> model -> (model, [Sink action -> JSM ()])
- scheduleIO :: JSM action -> Effect parent model action
- scheduleIO_ :: JSM () -> Effect parent model action
- scheduleIOFor_ :: Foldable f => JSM (f action) -> Effect parent model action
- scheduleSub :: (Sink action -> JSM ()) -> Effect parent model action
- effectSub :: model -> (Sink action -> JSM ()) -> Effect parent model action
- batchEff :: model -> [JSM action] -> Effect parent model action
- noEff :: model -> Effect parent model action
Effect
Types
type Effect parent model action = RWS (ComponentInfo parent) [Sink action -> JSM ()] model () Source #
A monad for succinctly expressing model transitions in the update function.
Effect is a RWS, where the State abstracts over manually passing the model
around. It's also a Writer Monad, where the accumulator is a list of scheduled
IO actions. Multiple actions can be scheduled using tell
from the mtl library and a single action can be scheduled using io_.
An Effect represents the results of an update action.
It consists of the updated model and a list of subscriptions. Each Sub is
run in a new thread so there is no risk of accidentally blocking the
application.
Tip: use the Effect monad in combination with the stateful
lens
operators (all operators ending in "="). The following example assumes
the lenses field1, counter and field2 are in scope and that the
LambdaCase language extension is enabled:
myComponent = Component
{ update = \case
MyAction1 -> do
field1 .= value1
counter += 1
MyAction2 -> do
field2 %= f
io_ $ do
putStrLn "Hello"
putStrLn "World!"
, ...
}
type Sink action = action -> JSM () Source #
Function to asynchronously dispatch actions to the update function.
data ComponentInfo parent Source #
This is the 'Reader r' in Effect. Accessible via ask. It holds
a phantom type for parent. This is used as a witness when calling the
parent function, and using prop.
Constructors
| ComponentInfo | |
Fields | |
type ComponentId = Int Source #
ComponentId of the current Component
Arguments
| :: ComponentId | Component Id |
| -> ComponentId | Parent Component Id |
| -> DOMRef | DOM Reference |
| -> ComponentInfo parent |
Smart constructor for ComponentInfo
Combinators
(<#) :: model -> JSM action -> Effect parent model action infixl 0 Source #
Smart constructor for an Effect with exactly one action.
(#>) :: JSM action -> model -> Effect parent model action infixr 0 Source #
Effect smart constructor, flipped
batch :: [JSM action] -> Effect parent model action Source #
Smart constructor for an Effect with multiple actions.
Since: 1.9.0.0
batch_ :: [JSM ()] -> Effect parent model action Source #
Like batch but action are discarded
Since: 1.9.0.0
io_ :: JSM () -> Effect parent model action Source #
Like io_ but doesn't cause an action to be dispatched to
the update function.
This is handy for scheduling IO computations where you don't care
about their results or when they complete.
Since: 1.9.0.0
issue :: action -> Effect parent model action Source #
Issue a new action to be processed by update.
data Action = HelloWorld update :: Action -> Effect Model Action update = \case Click -> issue HelloWorld
Since: 1.9.0.0
withSink :: (Sink action -> JSM ()) -> Effect parent model action Source #
withSink allows users to access the sink of the Component or top-level
Component in their application. This is useful for introducing IO into the system.
A synonym for tell, specialized to Effect.
A use-case is scheduling an IO computation which creates a 3rd-party JS
widget which has an associated callback. The callback can then call the sink
to turn events into actions. To do this without accessing a sink requires
going via a which introduces a leaky-abstraction.Subscription
update FetchJSON = withSink $ \sink -> getJSON (sink . ReceivedJSON) (sink . HandleError)
Since: 1.9.0.0
beforeAll :: JSM () -> Effect parent model action -> Effect parent model action Source #
Performs the given JSM action before all JSM actions collected by the given effect.
Example usage:
-- delays connecting a websocket by 100000 microseconds beforeAll (liftIO $ threadDelay 100000) $ websocketConnectJSON OnConnect OnClose OnOpen OnError
afterAll :: JSM () -> Effect parent model action -> Effect parent model action Source #
Performs the given JSM action after all JSM actions collected by the given effect.
Example usage:
-- log that running the a websocket Effect completed afterAll (consoleLog "Done running websocket effect") $ websocketConnectJSON OnConnect OnClose OnOpen OnError
modifyAllJSM :: (JSM () -> JSM ()) -> Effect parent model action -> Effect parent model action Source #
Internal
runEffect :: Effect parent model action -> ComponentInfo parent -> model -> (model, [Sink action -> JSM ()]) Source #
Internal function used to unwrap an Effect
Deprecated
scheduleIO :: JSM action -> Effect parent model action Source #
scheduleIO_ :: JSM () -> Effect parent model action Source #