on master help sign in
Merge pull request #30 from BardurArantsson/add-library-interface
bd340ffGreg Weber
wai-eventsource/src/Main.hs+2−19
@@ -2,41 +2,24 @@
2module Main where
2module Main where
3
3
4import Control.Monad
4import Control.Monad
5−import Control.Monad.Trans
6import Control.Concurrent (forkIO, threadDelay)
5import Control.Concurrent (forkIO, threadDelay)
7import Control.Concurrent.Chan
6import Control.Concurrent.Chan
8import Network.Wai.Handler.Warp (run)
7import Network.Wai.Handler.Warp (run)
9import Network.Wai
8import Network.Wai
10import Network.HTTP.Types (statusOK)
9import Network.HTTP.Types (statusOK)
11−import Data.Enumerator (run_, ($$))
12−import Data.Enumerator.List (generateM)
13import Data.Time.Clock.POSIX
10import Data.Time.Clock.POSIX
14import Blaze.ByteString.Builder.Char.Utf8 (fromString)
11import Blaze.ByteString.Builder.Char.Utf8 (fromString)
15
12
16−import EventStream
13+import Network.Wai.EventSource
17−
18
14
19app :: Chan ServerEvent -> Application
15app :: Chan ServerEvent -> Application
20app chan req =
16app chan req =
21 case pathInfo req of
17 case pathInfo req of
22 [] -> return $ ResponseFile statusOK [("Content-Type", "text/html")] "static/index.html" Nothing
18 [] -> return $ ResponseFile statusOK [("Content-Type", "text/html")] "static/index.html" Nothing
23− ["es"] -> do
19+ ["es"] -> eventSourceApp chan req
24− chan' <- liftIO $ dupChan chan
25− return $ res chan'
26 _ -> error "unexpected pathInfo"
20 _ -> error "unexpected pathInfo"
27
21
28
22
29−res :: Chan ServerEvent -> Response
30−res chan = ResponseEnumerator (resE chan)
31−
32−
33−resE :: Chan ServerEvent -> ResponseEnumerator a
34−resE chan genIter =
35− run_ $ generateM (fmap eventToBuilder $ readChan chan) $$ iter
36− where
37− iter = genIter statusOK [("Content-Type", "text/event-stream")]
38−
39−
40source :: Chan ServerEvent -> IO ()
23source :: Chan ServerEvent -> IO ()
41source chan = forever $ do
24source chan = forever $ do
42 threadDelay 1000000
25 threadDelay 1000000
wai-eventsource/src/Network/Wai/EventSource.hsnew file+32
@@ -0,0 +1,32 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module Network.Wai.EventSource (
3+ ServerEvent(..),
4+ eventSourceApp
5+ ) where
6+
7+import Blaze.ByteString.Builder (Builder)
8+import Control.Concurrent.Chan (Chan, dupChan, readChan)
9+import Control.Monad.Trans (liftIO)
10+import qualified Data.Conduit as C
11+import Network.HTTP.Types (statusOK)
12+import Network.Wai (Application, Response(..))
13+
14+import Network.Wai.EventSource.EventStream
15+
16+-- | Make a new WAI EventSource application reading events from
17+-- the given channel.
18+eventSourceApp :: Chan ServerEvent -> Application
19+eventSourceApp chan _ = do
20+ chan' <- liftIO $ dupChan chan
21+ return $ res chan'
22+
23+res :: Chan ServerEvent -> Response
24+res chan = ResponseSource statusOK [("Content-Type", "text/event-stream")] $ resE chan
25+
26+resE :: Chan ServerEvent -> C.Source IO Builder
27+resE chan =
28+ C.sourceIO ign (const ign) (const $ fmap (f . eventToBuilder) $ readChan chan)
29+ where
30+ ign = return ()
31+ f Nothing = C.Closed
32+ f (Just b) = C.Open b
wai-eventsource/src/EventStream.hs → wai-eventsource/src/Network/Wai/EventSource/EventStream.hsrenamed+1−1
@@ -5,7 +5,7 @@
5 A WAI adapter to the HTML5 Server-Sent Events API. Push-mode and
5 A WAI adapter to the HTML5 Server-Sent Events API. Push-mode and
6 pull-mode interfaces are both available.
6 pull-mode interfaces are both available.
7-}
7-}
8−module EventStream (
8+module Network.Wai.EventSource.EventStream (
9 ServerEvent(..),
9 ServerEvent(..),
10 eventToBuilder
10 eventToBuilder
11 ) where
11 ) where
wai-eventsource/wai-eventsource.cabal+18−2
@@ -12,7 +12,23 @@ Cabal-version: >=1.2
12
12
13flag example
13flag example
14
14
15+
15−-- TODO: Library interface
16+Library
17+ Build-depends:
18+ base >= 4.3 && < 5
19+ , bytestring >= 0.9.1.4 && < 0.10
20+ , blaze-builder >= 0.3 && < 0.4
21+ , conduit >= 0.0 && < 0.1
22+ , MonadCatchIO-transformers >= 0.2.1 && < 0.3
23+ , mtl >= 2 && < 3
24+ , http-types >= 0.6 && < 0.7
25+ , wai >= 0.4
26+ , warp >= 0.4
27+
28+ ghc-options: -Wall
29+ hs-source-dirs: src
30+ exposed-modules: Network.Wai.EventSource
31+ other-modules: Network.Wai.EventSource.EventStream
16
32
17Executable wai-eventsource
33Executable wai-eventsource
18 if flag(example)
34 if flag(example)
@@ -27,10 +43,10 @@ Executable wai-eventsource
27 base >= 4.3 && < 5
43 base >= 4.3 && < 5
28 , bytestring >= 0.9.1.4 && < 0.10
44 , bytestring >= 0.9.1.4 && < 0.10
29 , blaze-builder >= 0.3 && < 0.4
45 , blaze-builder >= 0.3 && < 0.4
46+ , conduit >= 0.0 && < 0.1
30 , MonadCatchIO-transformers >= 0.2.1 && < 0.3
47 , MonadCatchIO-transformers >= 0.2.1 && < 0.3
31 , mtl >= 2 && < 3
48 , mtl >= 2 && < 3
32 , http-types >= 0.6 && < 0.7
49 , http-types >= 0.6 && < 0.7
33− , enumerator >= 0.4.8 && < 0.5
34 , time >= 1.2 && < 1.4
50 , time >= 1.2 && < 1.4
35 , wai >= 0.4
51 , wai >= 0.4
36 , warp >= 0.4
52 , warp >= 0.4