streaming-events (empty) → 1.0.0
raw patch · 5 files changed
+177/−0 lines, 5 filesdep +attoparsecdep +basedep +binary
Dependencies added: attoparsec, base, binary, bytestring, http-client, streaming, streaming-attoparsec, streaming-bytestring, wai-extra
Files
- ChangeLog.md +5/−0
- LICENSE +30/−0
- README.md +4/−0
- lib/Network/Wai/EventSource/Streaming.hs +104/−0
- streaming-events.cabal +34/−0
+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Changelog for `streaming-events`++## 1.0.0++- Initial release.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Kadena LLC (c) 2019++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,4 @@+# streaming-events++Client-side consumption of the `ServerEvent` type from `wai-extra` via the+`streaming` ecosystem.
+ lib/Network/Wai/EventSource/Streaming.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module: Network.Wai.EventSource.Streaming+-- Copyright: Copyright © 2019 Kadena LLC.+-- License: BSD-3-Clause+-- Maintainer: Colin Woodbury <colin@kadena.io>+--+-- Client-side consumption of the `ServerEvent` type from @wai-extra@ via the+-- @streaming@ ecosystem.+--+module Network.Wai.EventSource.Streaming+ ( -- * `ServerEvent` Stream+ withEvents+ -- * Attoparsec Parser+ , event+ ) where++import Control.Applicative (many, optional)+import Control.Monad (unless)+import Data.Attoparsec.ByteString.Char8+import qualified Data.Attoparsec.ByteString.Streaming as SA+import Data.Binary.Builder (Builder, fromByteString)+import qualified Data.ByteString as B+import qualified Data.ByteString.Streaming.Char8 as SB+import Network.HTTP.Client+import Network.Wai.EventSource (ServerEvent(..))+import Prelude hiding (takeWhile)+import Streaming+import qualified Streaming.Prelude as SP++---++-- | A low-level wrapper around `withResponse`. Provides a simple, unending+-- source of `ServerEvent`s, presumably from an endpoint served via+-- `Network.Wai.EventSource.eventSourceAppIO` or otherwise.+--+-- @since 1.0.0+withEvents :: Request -> Manager -> (Stream (Of ServerEvent) IO () -> IO a) -> IO a+withEvents r m f = withResponse r m $ f . g . responseBody+ where+ g :: BodyReader -> Stream (Of ServerEvent) IO ()+ g = void . SA.parsed event . SB.fromChunks . fromBodyReader++fromBodyReader :: BodyReader -> Stream (Of B.ByteString) IO ()+fromBodyReader br = do+ bs <- liftIO $ brRead br+ unless (B.null bs) $ SP.yield bs >> fromBodyReader br++--------------------------------------------------------------------------------+-- Parser++-- NOTE: This currently ignores:+-- * windows support for now, w.r.t. end-of-line characters+-- * the optional starting byte-order-mark+-- * `CloseEvent`++{- EXAMPLES++ServerEvent+-----------+event:New Event+id:id+data:data1+data:data2+data:data3++CommentEvent+------------+:this is a comment++RetryEvent+----------+retry:100++CloseEvent+----------+No output - the connection is severed.++-}++-- | The underlying attoparsec `Parser`.+--+-- @since 1.0.0+event :: Parser ServerEvent+event = (sevent <|> comment <|> retry) <* eol++sevent :: Parser ServerEvent+sevent = ServerEvent+ <$> optional (string "event" *> char ':' *> chars <* eol)+ <*> optional (string "id" *> char ':' *> chars <* eol)+ <*> many (string "data" *> char ':' *> chars <* eol)++comment :: Parser ServerEvent+comment = CommentEvent <$> (char ':' *> chars <* eol)++retry :: Parser ServerEvent+retry = RetryEvent <$> (string "retry:" *> decimal <* eol)++chars :: Parser Builder+chars = fromByteString <$> takeTill (== '\n')++eol :: Parser Char+eol = char '\n'
+ streaming-events.cabal view
@@ -0,0 +1,34 @@+cabal-version: 2.2+name: streaming-events+version: 1.0.0+synopsis: Client-side consumption of a ServerEvent.+description: Client-side consumption of a ServerEvent.+homepage: https://github.com/kadena-io/streaming-events+author: Colin Woodbury+maintainer: colin@kadena.io+copyright: 2019 Kadena LLC+license: BSD-3-Clause+license-file: LICENSE+build-type: Simple+extra-source-files:+ README.md+ ChangeLog.md++library+ default-language: Haskell2010+ hs-source-dirs: lib+ exposed-modules: Network.Wai.EventSource.Streaming+ ghc-options:+ -Wall -Wcompat -Wpartial-fields -Wincomplete-record-updates+ -Wincomplete-uni-patterns -Widentities++ build-depends:+ , attoparsec ^>=0.13+ , base >=4.9 && <5+ , binary ^>=0.8+ , bytestring ^>=0.10+ , http-client >= 0.5 && < 0.7+ , streaming ^>=0.2+ , streaming-attoparsec ^>=1.0+ , streaming-bytestring ^>=0.1+ , wai-extra ^>=3.0