| Copyright | (C) 2016-2026 David M. Johnson |
|---|---|
| License | BSD3-style (see the file LICENSE) |
| Maintainer | David M. Johnson <code@dmj.io> |
| Stability | experimental |
| Portability | non-portable |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Miso.Effect
Description
Synopsis
- type Effect parent props model action = RWS (ComponentInfo parent props) [Schedule action] model ()
- type Sub action = Sink action -> IO ()
- type Sink action = action -> IO ()
- type DOMRef = JSVal
- data ComponentInfo parent props = ComponentInfo {}
- type ComponentId = Int
- mkComponentInfo :: ComponentId -> ComponentId -> DOMRef -> props -> ComponentInfo parent props
- data Schedule action = Schedule Synchronicity (Sink action -> IO ())
- data Synchronicity
- (<#) :: model -> IO action -> Effect parent props model action
- (#>) :: IO action -> model -> Effect parent props model action
- batch :: [IO action] -> Effect parent props model action
- batch_ :: [IO ()] -> Effect parent props model action
- io :: IO action -> Effect parent props model action
- io_ :: IO () -> Effect parent props model action
- sync :: IO action -> Effect parent props model action
- sync_ :: IO () -> Effect parent props model action
- for :: Foldable f => IO (f action) -> Effect parent props model action
- issue :: action -> Effect parent props model action
- withSink :: (Sink action -> IO ()) -> Effect parent props model action
- mapSub :: (a -> b) -> Sub a -> Sub b
- noop :: action -> Effect parent props model action
- beforeAll :: IO () -> Effect parent props model action -> Effect parent props model action
- afterAll :: IO () -> Effect parent props model action -> Effect parent props model action
- modifyAllIO :: (IO () -> IO ()) -> Effect parent props model action -> Effect parent props model action
- componentInfoDOMRef :: Lens (ComponentInfo parent props) DOMRef
- componentInfoParentId :: Lens (ComponentInfo parent props) ComponentId
- componentInfoId :: Lens (ComponentInfo parent props) ComponentId
- runEffect :: Effect parent props model action -> ComponentInfo parent props -> model -> (model, [Schedule action])
- componentInfoProps :: Lens (ComponentInfo parent props) props
- props :: Lens (ComponentInfo parent props) props
- getProps :: MonadReader (ComponentInfo parent props) m => m props
Effect
Types
type Effect parent props model action = RWS (ComponentInfo parent props) [Schedule action] model () Source #
A monad for succinctly expressing model transitions in the update function.
Effect is a RWS, where the State allows modification to model.
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 asynchronous 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 Miso.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
consoleLog "Hello"
consoleLog "World!"
, ...
}
type Sub action = Sink action -> IO () Source #
Type synonym for constructing subscriptions.
For example usage see Miso.Subscription
The Sink function is used to write to the global event queue.
type Sink action = action -> IO () Source #
Function to write to the global event queue for processing by the scheduler.
data ComponentInfo parent props 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. It gives access to Component metadata such as the DOMRef the
Component was mounted on and the ComponentId associated with it.
Constructors
| ComponentInfo | |
Fields | |
type ComponentId = Int Source #
ComponentId of the current Component
Arguments
| :: ComponentId | |
| -> ComponentId |
|
| -> DOMRef | |
| -> props | |
| -> ComponentInfo parent props |
Smart constructor for ComponentInfo
IO
Represents a scheduled Effect that is executed either synchronously
or asynchronously.
All IO is by default asynchronous, use the sync function for synchronous
execution. Beware sync can block the render thread for a specific
Component.
N.B. During Component unmounting, all effects are evaluated
synchronously.
Since: 1.9.0.0
Constructors
| Schedule Synchronicity (Sink action -> IO ()) |
data Synchronicity Source #
Type to indicate if effects should be handled asynchronously or synchronously.
Instances
| Show Synchronicity Source # | |
Defined in Miso.Effect Methods showsPrec :: Int -> Synchronicity -> ShowS # show :: Synchronicity -> String # showList :: [Synchronicity] -> ShowS # | |
| Eq Synchronicity Source # | |
Defined in Miso.Effect Methods (==) :: Synchronicity -> Synchronicity -> Bool # (/=) :: Synchronicity -> Synchronicity -> Bool # | |
Combinators
(<#) :: model -> IO action -> Effect parent props model action infixl 0 Source #
Smart constructor for an Effect with exactly one action.
(#>) :: IO action -> model -> Effect parent props model action infixr 0 Source #
Effect smart constructor, flipped
batch_ :: [IO ()] -> Effect parent props model action Source #
Like batch but actions are discarded
Since: 1.9.0.0
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.
Note: The result of IO a is discarded.
Since: 1.9.0.0
Like sync, except discards the result.
Since: 1.9.0.0
Arguments
| :: action |
|
| -> Effect parent props model action |
Arguments
| :: (Sink action -> IO ()) | Callback function that provides access to the underlying |
| -> Effect parent props model action |
withSink allows users to write to the global event queue. 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.
updateFetchJSON =withSink$ \sink -> getJSON (sink . ReceivedJSON) (sink . HandleError)
Since: 1.9.0.0
beforeAll :: IO () -> Effect parent props model action -> Effect parent props model action Source #
Performs the given IO action before all IO actions collected by the given
effect.
-- delays connecting a websocket by 100000 microseconds beforeAll (liftIO $ threadDelay 100000) $ websocketConnectJSON OnConnect OnClose OnOpen OnError
Since: 1.9.0.0
afterAll :: IO () -> Effect parent props model action -> Effect parent props model action Source #
Performs the given IO action after all IO 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
modifyAllIO :: (IO () -> IO ()) -> Effect parent props model action -> Effect parent props model action Source #
Lens
componentInfoDOMRef :: Lens (ComponentInfo parent props) DOMRef Source #
componentInfoParentId :: Lens (ComponentInfo parent props) ComponentId Source #
Lens for accessing the parents's ComponentId from ComponentInfo.
update = case
SomeAction -> do
compParentId <- view componentParentId
someAction compParentId
Since: 1.9.0.0
componentInfoId :: Lens (ComponentInfo parent props) ComponentId Source #
Lens for accessing the ComponentId from ComponentInfo.
update = case
SomeAction -> do
compId <- view componentInfoId
someAction compId
Since: 1.9.0.0
Internal
runEffect :: Effect parent props model action -> ComponentInfo parent props -> model -> (model, [Schedule action]) Source #
Internal function used to unwrap an Effect
Props
componentInfoProps :: Lens (ComponentInfo parent props) props Source #
Lens for accessing the underlying Component props.
update = case
SomeAction -> do
props <- view componentInfoProps
someAction props
Since: 1.9.0.0
props :: Lens (ComponentInfo parent props) props Source #
Lens for accessing the underlying Component props.
This is a shorter convenience lens that is a synonynm for componentInfoProps.
See getProps for usage in the Effect monad.
update = case
SomeAction ->
someAction =<< view props
getProps :: MonadReader (ComponentInfo parent props) m => m props Source #
props retrieval from within the Effect monad.
update = case
SomeAction -> do
props <- getProps
someAction props