content: {-# LANGUAGE OverloadedStrings #-}
  
  module Web.Apiary.EventSource 
      ( eventSourceIO, eventSourceChan
      , module Network.Wai.EventSource.EventStream
      ) where
  
  import Web.Apiary(MonadIO(..), status200)
  import Network.Wai.EventSource.EventStream (ServerEvent(..))
  import qualified Network.Wai.EventSource.EventStream as E
  
  import Control.Concurrent.Chan (Chan, dupChan, readChan)
  import Control.Monad.Apiary.Action
      (ActionT, status, contentType, stream, StreamingBody)
  
  import Data.Function(fix)
  
  ioToSource :: IO ServerEvent -> StreamingBody
  ioToSource src send flush = fix $ \loop -> do
      se <- src
      case E.eventToBuilder se of
          Nothing -> return ()
          Just b  -> send b >> flush >> loop
  
  -- | eventsource with io action. since 0.11.3.
  eventSourceIO :: Monad m => IO ServerEvent -> ActionT exts prms m ()
  eventSourceIO io = do
      status status200
      contentType "text/event-stream"
      stream $ ioToSource io
  
  -- | eventsource with chan. since 0.11.3.
  eventSourceChan :: MonadIO m => Chan ServerEvent -> ActionT exts prms m ()
  eventSourceChan chan = do
      chan' <- liftIO $ dupChan chan
      eventSourceIO (readChan chan')
  