miso
Copyright(C) 2016-2025 David M. Johnson
LicenseBSD3-style (see the file LICENSE)
MaintainerDavid M. Johnson <code@dmj.io>
Stabilityexperimental
Portabilitynon-portable
Safe HaskellNone
LanguageHaskell2010

Miso.PubSub

Description

 
Synopsis

Publishers / Subscribers

subscribe :: FromJSON message => Topic message -> (message -> action) -> (MisoString -> action) -> Effect parent model action Source #

Subscribes to a Topic, provides callback function that writes to Component Sink

If a Topic message does not exist when calling subscribe it is generated dynamically. Each subscriber decodes the received Value using it's own FromJSON instance. This provides for loose-coupling between Component. As long as the underlying Value are identical Component can use their own types without serialization issues. Topic message should have their own JSON API specification when being distributed.

arithmetic :: Topic Message
arithmetic = topic "arithmetic"

clientComponent :: MisoString -> Component Int Action
clientComponent name = component 0 update_ $ m ->
  div_
  []
  [ br_ []
  , text (name <> " : " <> ms (m ^. _id))
  , button_ [ onClick Unsubscribe ] [ "unsubscribe" ]
  , button_ [ onClick Subscribe ] [ "subscribe" ]
  ] where
      update_ :: Action -> Effect Int Action
      update_ = case
        AddOne -> do
          _id += 1
        SubtractOne ->
          _id -= 1
        Unsubscribe ->
          unsubscribe arithmetic
        Subscribe ->
          subscribe arithmetic Notification
        Notification (Success Increment) -> do
          update_ AddOne
        Notification (Success Decrement) -> do
          update_ SubtractOne
        Notification (Error msg) ->
          io_ $ consoleError ("Decode failure: " <> ms msg)
        _ -> pure ()

Since: 1.9.0.0

unsubscribe :: Topic message -> Effect parent model action Source #

Unsubscribe to a Topic

Unsubscribes a Component from receiving messages from Topic message

See subscribe for more use.

Since: 1.9.0.0

publish :: ToJSON message => Topic message -> message -> Effect parent model action Source #

Publish to a Topic message

Topic message are generated dynamically if they do not exist. When using publish all subscribers are immediately notified of a new message. A message is distributed as a Value The underlying ToJSON instance is used to construct this Value.

We recommend documenting a public API for the JSON protocol message when distributing a Component downstream to end users for consumption (be it inside a single cabal project or across multiple cabal projects).

arithmetic :: Topic Message
arithmetic = topic "arithmetic"

server :: Component () Action
server = component () update_ $ () ->
  div_
  []
  [ "Server component"
  , button_ [ onClick AddOne ] [ "+" ]
  , button_ [ onClick SubtractOne ] [ "-" ]
  , component_ (client_ "client 1")
    [ onMountedWith Mount
    ]
  , component_ (client_ "client 2")
    [ onMountedWith Mount
    ]
  ] where
      update_ :: Action -> Effect () Action
      update_ = case
        AddOne ->
          publish arithmetic Increment
        SubtractOne ->
          publish arithemtic Decrement

Since: 1.9.0.0

data Topic a Source #

A Topic represents a place to send and receive messages. Topic is used to facilitate communication between Component. Component can subscribe to or publish to any Topic, within the same Component or across Component.

This requires creating a custom ToJSON / FromJSON. Any other Component can publish or subscribe to this Topic message. It is a way to provide loosely-coupled communication between Components.

See publish, subscribe, unsubscribe for more details.

When distributing Component for third-party use, it is recommended to export the Topic, where message is the JSON protocol.

Since: 1.9.0.0

Instances

Instances details
Show (Topic a) Source # 
Instance details

Defined in Miso.Runtime

Methods

showsPrec :: Int -> Topic a -> ShowS #

show :: Topic a -> String #

showList :: [Topic a] -> ShowS #

Eq (Topic a) Source # 
Instance details

Defined in Miso.Runtime

Methods

(==) :: Topic a -> Topic a -> Bool #

(/=) :: Topic a -> Topic a -> Bool #

Ord (Topic a) Source # 
Instance details

Defined in Miso.Runtime

Methods

compare :: Topic a -> Topic a -> Ordering #

(<) :: Topic a -> Topic a -> Bool #

(<=) :: Topic a -> Topic a -> Bool #

(>) :: Topic a -> Topic a -> Bool #

(>=) :: Topic a -> Topic a -> Bool #

max :: Topic a -> Topic a -> Topic a #

min :: Topic a -> Topic a -> Topic a #

ToMisoString (Topic a) Source # 
Instance details

Defined in Miso.Runtime

topic :: MisoString -> Topic a Source #

Smart constructor for creating a Topic message to write to

data Message
  = Increment
  | Decrement
  deriving (Show, Eq, Generic, ToJSON, FromJSON)

arithmetic :: Topic Message
arithmetic = topic "arithmetic"

data Action
  = Notification (Result Message)
  | Subscribe
  | Unsubscribe

update_ :: Action -> Effect Int Action
update_ = case
  Unsubscribe ->
    unsubscribe arithmetic
  Subscribe ->
    subscribe arithmetic Notification
  Notification (Success Increment) ->
    update_ AddOne
  Notification (Success Decrement) ->
    update_ SubtractOne
  Notification (Error msg) ->
    io_ $ consoleError ("Decode failure: " <> ms msg)

Since: 1.9.0.0