@@ -0,0 +1,82 @@
1+{-# LANGUAGE OverloadedStrings #-}
4+ A Snap adapter to the HTML5 Server-Sent Events API. Push-mode and
5+ pull-mode interfaces are both available.
12+import Blaze.ByteString.Builder
13+import Blaze.ByteString.Builder.Char8
14+import Control.Monad.Trans
15+import Control.Concurrent
17+import Data.Enumerator hiding (map)
18+import Data.Enumerator.List (generateM)
21+ Type representing a communication over an event stream. This can be an
22+ actual event, a comment, a modification to the retry timer, or a special
23+ "close" event indicating the server should close the connection.
27+ eventName :: Maybe Builder,
28+ eventId :: Maybe Builder,
29+ eventData :: [Builder]
32+ eventComment :: Builder
41+ Newline as a Builder.
47+ Field names as Builder
49+nameField = fromString "event:"
50+idField = fromString "id:"
51+dataField = fromString "data:"
52+retryField = fromString "retry:"
53+commentField = fromChar ':'
57+ Wraps the text as a labeled field of an event stream.
59+field l b = l `mappend` b `mappend` nl
63+ Appends a buffer flush to the end of a Builder.
65+flushAfter b = b `mappend` flush
69+ Converts a 'ServerEvent' to its wire representation as specified by the
70+ @text/event-stream@ content type.
72+eventToBuilder :: ServerEvent -> Maybe Builder
73+eventToBuilder (CommentEvent txt) = Just $ flushAfter $ field commentField txt
74+eventToBuilder (RetryEvent n) = Just $ flushAfter $ field retryField (fromShow n)
75+eventToBuilder (CloseEvent) = Nothing
76+eventToBuilder (ServerEvent n i d)= Just $ flushAfter $
77+ (name n $ evid i $ mconcat (map (field dataField) d)) `mappend` nl
80+ name (Just n) = mappend (field nameField n)
82+ evid (Just i) = mappend (field idField i)