servant-subscriber 0.1.0.2 → 0.2.0.0
raw patch · 9 files changed
+84/−152 lines, 9 files
Files
- servant-subscriber.cabal +1/−1
- src/Servant/Subscriber.hs +23/−24
- src/Servant/Subscriber/Backend.hs +2/−22
- src/Servant/Subscriber/Backend/Wai.hs +8/−20
- src/Servant/Subscriber/Client.hs +15/−29
- src/Servant/Subscriber/Request.hs +7/−18
- src/Servant/Subscriber/Response.hs +2/−15
- src/Servant/Subscriber/Subscribable.hs +16/−6
- src/Servant/Subscriber/Types.hs +10/−17
servant-subscriber.cabal view
@@ -1,5 +1,5 @@ name: servant-subscriber-version: 0.1.0.2+version: 0.2.0.0 synopsis: When REST is not enough ... description: Please see Readme.md homepage: http://github.com/eskimor/servant-subscriber#readme
src/Servant/Subscriber.hs view
@@ -11,36 +11,35 @@ notify , makeSubscriber , serveSubscriber+, Subscriber+, Event(..)+, IsElem+, HasLink+, IsValidEndpoint+, IsSubscribable+, Proxy+, MkLink+, URI+, STM ) where -import Control.Concurrent.STM.TVar (TVar, readTVar, writeTVar, newTVar, modifyTVar')-import Data.Aeson-import GHC.Generics-import Data.Map (Map)-import qualified Data.Map as Map-import Debug.Trace (trace)-import Network.URI (URI(..), pathSegments)-import Data.Proxy-import Data.Text (Text)-import qualified Data.Text as T-import Data.Time++import Control.Concurrent.STM+import Control.Monad+import qualified Data.Map as Map+import Data.Proxy+import Network.URI (URI(..), pathSegments)+import Network.Wai+import Network.Wai.Handler.WebSockets import Network.WebSockets.Connection as WS import Servant.Server-import Servant.Utils.Links (IsElem, HasLink, MkLink, safeLink)-import Control.Monad-import Servant.Subscriber.Subscribable-import Control.Monad.Trans.Maybe-import Control.Monad.IO.Class-import Control.Concurrent.STM-import Control.Monad.Trans.Class-import GHC.Conc-import Network.Wai-import Network.Wai.Handler.WebSockets-import Data.Monoid ((<>))+import Servant.Subscriber.Subscribable+import Servant.Utils.Links (IsElem, HasLink, MkLink, safeLink) -import Servant.Subscriber.Types+import Servant.Subscriber.Backend.Wai () import qualified Servant.Subscriber.Client as Client-import Servant.Subscriber.Backend.Wai+import Servant.Subscriber.Types+ makeSubscriber :: Path -> LogRunner -> STM (Subscriber api) makeSubscriber entryPoint logRunner = do
src/Servant/Subscriber/Backend.hs view
@@ -3,28 +3,8 @@ -- | Our only backend right now actually is implemented via the WAI Application interface, see: "Servant.Subscriber.Backend.Wai". module Servant.Subscriber.Backend where -import qualified Blaze.ByteString.Builder as B-import Control.Concurrent.STM (STM, atomically, retry)-import Control.Concurrent.STM.TVar-import Control.Monad (void)-import Data.Aeson-import qualified Data.ByteString as BS-import qualified Data.CaseInsensitive as Case-import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap-import Data.Map (Map)-import Data.Text (Text)-import qualified Data.Text.Encoding as T-import Data.Time-import GHC.Generics-import qualified Network.HTTP.Types as H-import qualified Network.Wai as Wai-import qualified Network.Wai.Internal as Wai-import Network.WebSockets.Connection as WS-import Servant.Server--import Servant.Subscriber.Request-import Servant.Subscriber.Response+import Servant.Subscriber.Request+import Servant.Subscriber.Response data ResponseReceived = ResponseReceived
src/Servant/Subscriber/Backend/Wai.hs view
@@ -5,30 +5,18 @@ -- | Backend of accessing a wai server: module Servant.Subscriber.Backend.Wai where -import qualified Blaze.ByteString.Builder as B-import Control.Concurrent.STM (STM, atomically, retry)-import Control.Concurrent.STM.TVar-import Control.Monad (void)+import qualified Blaze.ByteString.Builder as B import Data.Aeson-import qualified Data.ByteString as BS-import qualified Data.CaseInsensitive as Case-import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap+import qualified Data.ByteString as BS import Data.IORef-import Data.Map (Map)-import Data.Text (Text)-import qualified Data.Text.Encoding as T-import Data.Time-import GHC.Generics-import qualified Network.HTTP.Types as H-import qualified Network.Wai as Wai-import qualified Network.Wai.Internal as Wai-import Network.WebSockets.Connection as WS-import Servant.Server+import qualified Data.Text.Encoding as T+import qualified Network.HTTP.Types as H+import qualified Network.Wai as Wai+import qualified Network.Wai.Internal as Wai import Servant.Subscriber.Backend-import Servant.Subscriber.Request as Req-import Servant.Subscriber.Response as Res+import Servant.Subscriber.Request as Req+import Servant.Subscriber.Response as Res import Servant.Subscriber.Types
src/Servant/Subscriber/Client.hs view
@@ -2,41 +2,27 @@ {-# LANGUAGE FlexibleContexts #-} module Servant.Subscriber.Client where -import qualified Blaze.ByteString.Builder as B+ import Control.Concurrent.Async-import Control.Concurrent.STM (STM, atomically, retry)+import Control.Concurrent.STM (STM, atomically, retry) import Control.Concurrent.STM.TVar-import Control.Monad.Logger (MonadLogger, logDebug,- logError, logInfo,- monadLoggerLog)-import Control.Exception.Lifted (finally, try)-import Control.Exception (displayException, SomeException)-import Control.Monad.Trans.Control (MonadBaseControl)+import Control.Exception (displayException, SomeException)+import Control.Exception.Lifted (finally, try)+import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.Logger (MonadLogger, logDebug, logError, logInfo, monadLoggerLog)+import Control.Monad.Trans.Control (MonadBaseControl) import Data.Aeson-import Data.Bifunctor-import qualified Data.ByteString as BS-import qualified Data.CaseInsensitive as Case-import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap-import Data.Map (Map)-import qualified Data.Map.Strict as Map-import Data.Text (Text)-import qualified Data.Text as T-import qualified Data.Text.Encoding as T-import Data.Time-import GHC.Generics-import qualified Network.HTTP.Types as H-import qualified Network.WebSockets as WS-import Network.WebSockets.Connection as WS-import Servant.Server+import Data.Map (Map)+import qualified Data.Map.Strict as Map+import qualified Data.Text as T+import qualified Network.WebSockets as WS+import Network.WebSockets.Connection as WS -import Control.Monad-import Control.Monad.IO.Class import Servant.Subscriber.Backend import Servant.Subscriber.Request-import Servant.Subscriber.Response as Resp-import Servant.Subscriber.Subscribable-import Servant.Subscriber.Types as S+import Servant.Subscriber.Response as Resp+import Servant.Subscriber.Types as S type ClientMonitors = Map Path StatusMonitor
src/Servant/Subscriber/Request.hs view
@@ -3,26 +3,15 @@ module Servant.Subscriber.Request where -import qualified Blaze.ByteString.Builder as B-import Control.Concurrent.STM.TVar (TVar)-import Data.Aeson--- import Data.Aeson.Encode.Builder as AesonBuilder-import qualified Data.ByteString as BS-import qualified Data.CaseInsensitive as Case-import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap-import Data.Map (Map)-import Data.Text (Text)-import qualified Data.Text.Encoding as T-import Data.Time-import GHC.Generics-import qualified Network.HTTP.Types as H-import qualified Network.Wai as Wai-import Network.WebSockets.Connection as WS-import Servant.Server ++import Data.Aeson import Data.Bifunctor-import Servant.Subscriber.Subscribable+import qualified Data.CaseInsensitive as Case+import Data.Text (Text)+import qualified Data.Text.Encoding as T+import GHC.Generics+import qualified Network.HTTP.Types as H import Servant.Subscriber.Types
src/Servant/Subscriber/Response.hs view
@@ -4,34 +4,21 @@ import qualified Blaze.ByteString.Builder as B import qualified Blaze.ByteString.Builder.Char8 as B-import Control.Concurrent.STM (STM, atomically, retry)-import Control.Concurrent.STM.TVar-import Control.Monad (void) import Data.Aeson import Data.Aeson.Parser (value) import Data.Aeson.Types (unsafeToEncoding)-import qualified Data.ByteString as BS+import Data.Attoparsec.ByteString (parseOnly)+import Data.Bifunctor import qualified Data.CaseInsensitive as Case-import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap-import Data.Map (Map) import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Encoding as T-import Data.Time import GHC.Generics import qualified Network.HTTP.Types as H-import qualified Network.Wai as Wai-import qualified Network.Wai.Internal as Wai-import Network.WebSockets.Connection as WS import Servant.Server -import Data.Attoparsec.ByteString (parseOnly)-import Data.Bifunctor- import qualified Servant.Subscriber.Request as R-import Servant.Subscriber.Subscribable import Servant.Subscriber.Types
src/Servant/Subscriber/Subscribable.hs view
@@ -12,18 +12,22 @@ -module Servant.Subscriber.Subscribable where+module Servant.Subscriber.Subscribable (+ Subscribable+ , IsSubscribable+ , IsSubscribable'+ , IsElem+ , IsValidEndpoint+ ) where import Control.Lens-import Data.Aeson (FromJSON, ToJSON) import Data.Proxy import GHC.Exts (Constraint)-import GHC.Generics import GHC.TypeLits+ import Servant import Servant.Foreign import Servant.Foreign.Internal (_FunctionName)-import Servant.Utils.Links data Subscribable@@ -58,12 +62,14 @@ IsSubscribable sa (QueryFlag x :> sb) = IsSubscribable sa sb IsSubscribable e a = IsSubscribable' e a -type instance IsElem' e (Subscribable :> s) = IsElem e s --- | A valid endpoint may only contain Symbols and captures:+type instance IsElem' (Subscribable :> e) (Subscribable :> s) = IsElem e s++-- | A valid endpoint may only contain Symbols and captures & for convenince Subscribable: type family IsValidEndpoint endpoint :: Constraint where IsValidEndpoint ((sym :: Symbol) :> sub) = IsValidEndpoint sub IsValidEndpoint (Capture z y :> sub) = IsValidEndpoint sub+ IsValidEndpoint (Subscribable :> sub) = IsValidEndpoint sub IsValidEndpoint (Verb (method :: k1) (statusCode :: Nat) (contentTypes :: [*]) (a :: *)) = () instance HasServer sublayout context => HasServer (Subscribable :> sublayout) context where@@ -76,6 +82,10 @@ -- foreignFor :: Proxy lang -> Proxy ftype -> Proxy layout -> Req ftype -> Foreign ftype layout foreignFor lang ftype _ req = foreignFor lang ftype (Proxy :: Proxy sublayout) $ req & reqFuncName . _FunctionName %~ ("" :) -- Prepend empty string for marking as subscribable.++instance HasLink sub => HasLink (Subscribable :> sub) where+ type MkLink (Subscribable :> sub) = MkLink sub+ toLink _ = toLink (Proxy :: Proxy sub) -------------- Copied from Servant.Util.Links (they are not exported) ----------
src/Servant/Subscriber/Types.hs view
@@ -7,29 +7,22 @@ module Servant.Subscriber.Types where import Control.Concurrent.STM-import Control.Concurrent.STM.TVar (TVar, modifyTVar', newTVar,- readTVar, writeTVar) import Control.Monad import Control.Monad.IO.Class-import Control.Monad.Logger-import Control.Monad.Trans.Class-import Control.Monad.Trans.Maybe+import Control.Monad.Logger import Data.Aeson-import Data.Aeson.Types-import Data.Map (Map)-import qualified Data.Map as Map+import Data.Map (Map)+import qualified Data.Map as Map import Data.Proxy-import Data.Text (Text)-import qualified Data.Text as T-import Data.Time-import GHC.Conc+import Data.String (IsString, fromString)+import Data.Text (Text)+import qualified Data.Text as T import GHC.Generics-import Network.URI (URI (..), pathSegments)-import Servant.Utils.Links (IsElem, HasLink, MkLink, safeLink)-import Data.String (IsString, fromString)-import System.FilePath.Posix (splitPath)+import Network.URI (URI (..), pathSegments)+import Servant.Utils.Links (IsElem, HasLink, MkLink, safeLink)+import System.FilePath.Posix (splitPath) -import Servant.Subscriber.Subscribable+import Servant.Subscriber.Subscribable newtype Path = Path [Text] deriving (Eq, Generic, Ord, Show, ToJSON, FromJSON)