packages feed

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 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