{-# LANGUAGE OverloadedStrings #-} module Network.Wai.EventSource ( ServerEvent(..), eventSourceApp ) where import Blaze.ByteString.Builder (Builder) import Control.Concurrent.Chan (Chan, dupChan, readChan) import Control.Monad.IO.Class (liftIO) import qualified Data.Conduit as C import Network.HTTP.Types (statusOK) import Network.Wai (Application, Response(..)) import Network.Wai.EventSource.EventStream -- | Make a new WAI EventSource application reading events from -- the given channel. eventSourceApp :: Chan ServerEvent -> Application eventSourceApp chan _ = do chan' <- liftIO $ dupChan chan return $ res chan' res :: Chan ServerEvent -> Response res chan = ResponseSource statusOK [("Content-Type", "text/event-stream")] $ resE chan resE :: Chan ServerEvent -> C.Source IO (C.Flush Builder) resE chan = C.sourceState Nothing pull where pull Nothing = do x <- liftIO $ readChan chan return $ case eventToBuilder x of Nothing -> C.StateClosed Just y -> C.StateOpen (Just C.Flush) (C.Chunk y) pull (Just x) = return $ C.StateOpen Nothing x