-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | When REST is not enough ...
--   
--   Please see Readme.md
@package servant-subscriber
@version 0.6.0.1

module Servant.Subscriber.Subscribable
data Subscribable

-- | You may use this type family to tell the type checker that your custom
--   type may be skipped as part of a link. This is useful for things like
--   <a>QueryParam</a> that are optional in a URI and are not part of a
--   subscription uri.
--   
--   <pre>
--   &gt;&gt;&gt; data CustomThing
--   
--   &gt;&gt;&gt; type instance IsSubscribable' e (CustomThing :&gt; sa) s = IsSubscribable e sa s
--   </pre>
--   
--   Note that <a>IsSubscribable</a> is called, which will mutually recurse
--   back to <a>IsSubscribable'</a> if it exhausts all other options again.
--   
--   Once you have written a HasSubscription instance for CustomThing you
--   are ready to go.

-- | Closed type family, check if <tt>endpoint</tt> is within <tt>api</tt>.
--   Uses <tt><a>IsElem'</a></tt> if it exhausts all other options.
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem ("hello" :&gt; Get '[JSON] Int) SampleAPI))
--   OK
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem ("bye" :&gt; Get '[JSON] Int) SampleAPI))
--   ...
--   ... Could not deduce...
--   ...
--   </pre>
--   
--   An endpoint is considered within an api even if it is missing
--   combinators that don't affect the URL:
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (Header "h" Bool :&gt; Get '[JSON] Int)))
--   OK
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (ReqBody '[JSON] Bool :&gt; Get '[JSON] Int)))
--   OK
--   </pre>
--   
--   <ul>
--   <li>N.B.:* <tt>IsElem a b</tt> can be seen as capturing the notion of
--   whether the URL represented by <tt>a</tt> would match the URL
--   represented by <tt>b</tt>, *not* whether a request represented by
--   <tt>a</tt> matches the endpoints serving <tt>b</tt> (for the latter,
--   use <a>IsIn</a>).</li>
--   </ul>

-- | A valid endpoint may only contain Symbols and captures &amp; for
--   convenince Subscribable:
instance Servant.Server.Internal.HasServer sublayout context => Servant.Server.Internal.HasServer (Servant.Subscriber.Subscribable.Subscribable Servant.API.Sub.:> sublayout) context
instance Servant.Foreign.Internal.HasForeign lang ftype sublayout => Servant.Foreign.Internal.HasForeign lang ftype (Servant.Subscriber.Subscribable.Subscribable Servant.API.Sub.:> sublayout)
instance Servant.Utils.Links.HasLink sub => Servant.Utils.Links.HasLink (Servant.Subscriber.Subscribable.Subscribable Servant.API.Sub.:> sub)

module Servant.Subscriber.Types
newtype Path
Path :: [Text] -> Path
type ReferenceCount = Int
type Revision = Int
type ResourceStatusMap = Map Path (TVar (RefCounted ResourceStatus))
data ResourceStatus
Modified :: Revision -> ResourceStatus

-- | &lt; Watching for <a>Modified</a> implies watching for <a>Deleted</a>
Deleted :: ResourceStatus
data RefCounted a
RefCounted :: ReferenceCount -> a -> RefCounted a
[refCount] :: RefCounted a -> ReferenceCount
[refValue] :: RefCounted a -> a
type LogRunner = forall m a. MonadIO m => LoggingT m a -> m a
data Subscriber api
Subscriber :: !(TVar ResourceStatusMap) -> !Path -> LogRunner -> Subscriber api
[subState] :: Subscriber api -> !(TVar ResourceStatusMap)
[entryPoint] :: Subscriber api -> !Path
[runLogging] :: Subscriber api -> LogRunner
data Event
DeleteEvent :: Event
ModifyEvent :: Event

-- | Notify the subscriber about a changed resource. You have to provide a
--   typesafe link to the changed resource. Only Symbols and Captures are
--   allowed in this link.
--   
--   You need to provide a proxy to the API too. This is needed to check
--   that the endpoint is valid and points to a <a>Subscribable</a>
--   resource.
--   
--   One piece is still missing - we have to fill out captures, that's what
--   the getLink parameter is for: You will typicall provide a lamda there
--   providing needed parameters.
--   
--   TODO: Example!
notify :: forall api endpoint. (IsElem endpoint api, HasLink endpoint, IsValidEndpoint endpoint, IsSubscribable endpoint api) => Subscriber api -> Event -> Proxy endpoint -> (MkLink endpoint -> URI) -> STM ()

-- | Version of notify that lives in <a>IO</a> - for your convenience.
notifyIO :: forall api endpoint. (IsElem endpoint api, HasLink endpoint, IsValidEndpoint endpoint, IsSubscribable endpoint api) => Subscriber api -> Event -> Proxy endpoint -> (MkLink endpoint -> URI) -> IO ()

-- | Subscribe to a ResourceStatus - it will be created when not present
subscribe :: Path -> Subscriber api -> STM (TVar (RefCounted ResourceStatus))

-- | Unget a previously got ResourceState - make sure you match every call
--   to subscribe with a call to unsubscribe!
unsubscribe :: Path -> TVar (RefCounted ResourceStatus) -> Subscriber api -> STM ()

-- | Modify a ResourceState if it is present in the map, otherwise do
--   nothing.
modifyState :: Event -> Path -> Subscriber api -> STM ()
eventHandler :: Event -> ResourceStatus -> ResourceStatus
doDelete :: ResourceStatus -> ResourceStatus
doModify :: ResourceStatus -> ResourceStatus
toSegments :: Path -> [Text]
instance GHC.Classes.Eq Servant.Subscriber.Types.Event
instance GHC.Show.Show Servant.Subscriber.Types.ResourceStatus
instance GHC.Classes.Eq Servant.Subscriber.Types.ResourceStatus
instance Data.Aeson.Types.FromJSON.FromJSON Servant.Subscriber.Types.Path
instance Data.Aeson.Types.ToJSON.ToJSON Servant.Subscriber.Types.Path
instance GHC.Show.Show Servant.Subscriber.Types.Path
instance GHC.Classes.Ord Servant.Subscriber.Types.Path
instance GHC.Generics.Generic Servant.Subscriber.Types.Path
instance GHC.Classes.Eq Servant.Subscriber.Types.Path
instance GHC.Base.Functor Servant.Subscriber.Types.RefCounted
instance Data.String.IsString Servant.Subscriber.Types.Path

module Servant.Subscriber.Request
type RequestHeader = (Text, Text)
type RequestHeaders = [RequestHeader]

-- | Any message from the client is a <a>Request</a>:
--   
--   <a>SetPongRequest</a>: A request that should be issued whenever a
--   websocket pong is received. In addition to every websocket pong the
--   request also gets issued immediately upon receival. Bot
--   <a>SetPongRequest</a> and <a>SetCloseRequest</a> will be confirmed
--   with a <tt>Subscribed</tt> response, but any return value of the
--   request won't be delivered.
--   
--   <a>SetCloseRequest</a>: A request that should be issued when the
--   websocket connection closes for whatever reason.
data Request
Subscribe :: !HttpRequest -> Request
Unsubscribe :: !HttpRequest -> Request
SetPongRequest :: !HttpRequest -> Request
SetCloseRequest :: !HttpRequest -> Request
data HttpRequest
HttpRequest :: !Text -> !Path -> RequestHeaders -> QueryText -> RequestBody -> HttpRequest
[httpMethod] :: HttpRequest -> !Text
[httpPath] :: HttpRequest -> !Path
[httpHeaders] :: HttpRequest -> RequestHeaders
[httpQuery] :: HttpRequest -> QueryText
[httpBody] :: HttpRequest -> RequestBody
newtype RequestBody
RequestBody :: Text -> RequestBody
runRequestBody :: RequestBody -> Text
toHTTPHeader :: RequestHeader -> Header
toHTTPHeaders :: RequestHeaders -> RequestHeaders
requestPath :: Request -> Path
instance GHC.Generics.Generic Servant.Subscriber.Request.Request
instance GHC.Show.Show Servant.Subscriber.Request.HttpRequest
instance GHC.Classes.Ord Servant.Subscriber.Request.HttpRequest
instance GHC.Classes.Eq Servant.Subscriber.Request.HttpRequest
instance GHC.Generics.Generic Servant.Subscriber.Request.HttpRequest
instance GHC.Show.Show Servant.Subscriber.Request.RequestBody
instance GHC.Classes.Ord Servant.Subscriber.Request.RequestBody
instance GHC.Classes.Eq Servant.Subscriber.Request.RequestBody
instance Data.Aeson.Types.FromJSON.FromJSON Servant.Subscriber.Request.RequestBody
instance Data.Aeson.Types.ToJSON.ToJSON Servant.Subscriber.Request.RequestBody
instance GHC.Generics.Generic Servant.Subscriber.Request.RequestBody
instance Data.Aeson.Types.FromJSON.FromJSON Servant.Subscriber.Request.Request
instance Data.Aeson.Types.ToJSON.ToJSON Servant.Subscriber.Request.Request
instance Data.Aeson.Types.FromJSON.FromJSON Servant.Subscriber.Request.HttpRequest
instance Data.Aeson.Types.ToJSON.ToJSON Servant.Subscriber.Request.HttpRequest

module Servant.Subscriber.Response
type ResponseHeader = RequestHeader
type ResponseHeaders = RequestHeaders

-- | Any message from the server is a Response.
--   
--   <a>Subscribed</a>: Resource was successfully subscribed
--   
--   <a>Modified</a>: Resource was modified (this message is also triggered
--   immediately after a subscription)
--   
--   <a>HttpRequestFailed</a>: The server replied with some none 2xx status
--   code. Thus your subscription failed or got removed.
--   
--   <a>ParseError</a>: Your request could not be parsed.
data Response
Subscribed :: !HttpRequest -> Response
Modified :: !HttpRequest -> !ResponseBody -> Response
Deleted :: !Path -> Response
Unsubscribed :: !HttpRequest -> Response
HttpRequestFailed :: !HttpRequest -> !HttpResponse -> Response
ParseError :: Response
data HttpResponse
HttpResponse :: !Status -> !ResponseHeaders -> !ResponseBody -> HttpResponse
[httpStatus] :: HttpResponse -> !Status
[httpHeaders] :: HttpResponse -> !ResponseHeaders
[httpBody] :: HttpResponse -> !ResponseBody
data Status
Status :: !Int -> !Text -> Status
[statusCode] :: Status -> !Int
[statusMessage] :: Status -> !Text
type ResponseBody = Text
fromHTTPHeader :: Header -> ResponseHeader
fromHTTPHeaders :: ResponseHeaders -> ResponseHeaders
fromHTTPStatus :: Status -> Status
fromServantError :: ServantErr -> HttpResponse
wrapInString :: Builder -> Builder
instance GHC.Generics.Generic Servant.Subscriber.Response.Response
instance GHC.Generics.Generic Servant.Subscriber.Response.HttpResponse
instance GHC.Show.Show Servant.Subscriber.Response.Status
instance GHC.Generics.Generic Servant.Subscriber.Response.Status
instance Data.Aeson.Types.ToJSON.ToJSON Servant.Subscriber.Response.Response
instance Data.Aeson.Types.ToJSON.ToJSON Servant.Subscriber.Response.HttpResponse
instance Data.Aeson.Types.ToJSON.ToJSON Servant.Subscriber.Response.Status


-- | A backend for subscriber allows us to query a server and get a
--   response. | We mimick Wai's interface but with <a>Request</a> and
--   <a>Response</a> types that match our needs. | Our only backend right
--   now actually is implemented via the WAI Application interface, see:
--   <a>Servant.Subscriber.Backend.Wai</a>.
module Servant.Subscriber.Backend
data ResponseReceived
ResponseReceived :: ResponseReceived
type Application = HttpRequest -> (HttpResponse -> IO ResponseReceived) -> IO ResponseReceived
class Backend a
requestResource :: Backend a => a -> Application

module Servant.Subscriber.Client
type ClientMonitors = Map HttpRequest StatusMonitor
data Client api
Client :: !(Subscriber api) -> !(TVar ClientMonitors) -> !(IO (Maybe Request)) -> !(Response -> IO ()) -> !(IORef (IO ())) -> !(TVar (IO ())) -> Client api
[subscriber] :: Client api -> !(Subscriber api)
[monitors] :: Client api -> !(TVar ClientMonitors)
[readRequest] :: Client api -> !(IO (Maybe Request))
[writeResponse] :: Client api -> !(Response -> IO ())
[pongCommandRef] :: Client api -> !(IORef (IO ()))
[closeCommandRef] :: Client api -> !(TVar (IO ()))
data StatusMonitor
StatusMonitor :: !HttpRequest -> !(TVar (RefCounted ResourceStatus)) -> !(Maybe ResourceStatus) -> StatusMonitor
[request] :: StatusMonitor -> !HttpRequest
[monitor] :: StatusMonitor -> !(TVar (RefCounted ResourceStatus))
[oldStatus] :: StatusMonitor -> !(Maybe ResourceStatus)
data Snapshot
Snapshot :: ResourceStatus -> StatusMonitor -> Snapshot
[snapshotCurrent] :: Snapshot -> ResourceStatus
[fullMonitor] :: Snapshot -> StatusMonitor
snapshotOld :: Snapshot -> Maybe ResourceStatus
monitorPath :: StatusMonitor -> Path
toSnapshot :: StatusMonitor -> STM Snapshot
snapshotRequest :: Snapshot -> HttpRequest
fromWebSocket :: Subscriber api -> IORef (IO ()) -> Connection -> STM (Client api)
run :: (MonadLogger m, MonadBaseControl IO m, MonadIO m, Backend backend) => backend -> Client api -> m ()
addRequest :: HttpRequest -> Client api -> STM ()

-- | Remove a Request, also unsubscribes from subscriber and deletes our
--   monitor if it was the last Request for the given path.
removeRequest :: Client api -> HttpRequest -> STM ()

-- | Does not remove the monitor - use removeRequest if you want this!
unsubscribeMonitor :: Subscriber api -> StatusMonitor -> STM ()
handleRequests :: Backend backend => backend -> Client api -> IO ()
handleSubscribe :: Client api -> HttpRequest -> IO ()
handleUnsubscribe :: Client api -> HttpRequest -> IO ()
runMonitor :: Backend backend => backend -> Client api -> IO ()
handleUpdates :: Backend backend => backend -> Client api -> (HttpRequest, ResourceStatus) -> IO ()
handleModified :: Backend backend => backend -> Client api -> HttpRequest -> IO ()
getServerResponse :: Backend backend => backend -> HttpRequest -> (Response -> IO ()) -> IO ()
monitorChanges :: Client api -> STM [(HttpRequest, ResourceStatus)]
getChanges :: [Snapshot] -> [(HttpRequest, ResourceStatus)]
monitorChanged :: Snapshot -> Bool
toChangeReport :: Snapshot -> (HttpRequest, ResourceStatus)
updateMonitors :: [Snapshot] -> [StatusMonitor]
updateOldStatus :: Snapshot -> StatusMonitor
monitorsFromList :: [StatusMonitor] -> ClientMonitors


-- | Backend of accessing a wai server:
module Servant.Subscriber.Backend.Wai
waiSendResponse :: (HttpResponse -> IO ResponseReceived) -> Response -> IO ResponseReceived
toWaiRequest :: HttpRequest -> IO Request
mkWaiRequestBody :: ByteString -> IO (IO ByteString)
fromWaiResponse :: Response -> HttpResponse
standardHeaders :: RequestHeaders
lengthHeader :: ByteString -> RequestHeader
instance Servant.Subscriber.Backend.Backend Network.Wai.Application

module Servant.Subscriber

-- | Notify the subscriber about a changed resource. You have to provide a
--   typesafe link to the changed resource. Only Symbols and Captures are
--   allowed in this link.
--   
--   You need to provide a proxy to the API too. This is needed to check
--   that the endpoint is valid and points to a <a>Subscribable</a>
--   resource.
--   
--   One piece is still missing - we have to fill out captures, that's what
--   the getLink parameter is for: You will typicall provide a lamda there
--   providing needed parameters.
--   
--   TODO: Example!
notify :: forall api endpoint. (IsElem endpoint api, HasLink endpoint, IsValidEndpoint endpoint, IsSubscribable endpoint api) => Subscriber api -> Event -> Proxy endpoint -> (MkLink endpoint -> URI) -> STM ()
makeSubscriber :: Path -> LogRunner -> STM (Subscriber api)
serveSubscriber :: forall api. (HasServer api '[]) => Subscriber api -> Server api -> Application
data Subscriber api
data Event
DeleteEvent :: Event
ModifyEvent :: Event

-- | Closed type family, check if <tt>endpoint</tt> is within <tt>api</tt>.
--   Uses <tt><a>IsElem'</a></tt> if it exhausts all other options.
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem ("hello" :&gt; Get '[JSON] Int) SampleAPI))
--   OK
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem ("bye" :&gt; Get '[JSON] Int) SampleAPI))
--   ...
--   ... Could not deduce...
--   ...
--   </pre>
--   
--   An endpoint is considered within an api even if it is missing
--   combinators that don't affect the URL:
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (Header "h" Bool :&gt; Get '[JSON] Int)))
--   OK
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (ReqBody '[JSON] Bool :&gt; Get '[JSON] Int)))
--   OK
--   </pre>
--   
--   <ul>
--   <li>N.B.:* <tt>IsElem a b</tt> can be seen as capturing the notion of
--   whether the URL represented by <tt>a</tt> would match the URL
--   represented by <tt>b</tt>, *not* whether a request represented by
--   <tt>a</tt> matches the endpoints serving <tt>b</tt> (for the latter,
--   use <a>IsIn</a>).</li>
--   </ul>

-- | Construct a toLink for an endpoint.
class HasLink k (endpoint :: k) where {
    type family MkLink k (endpoint :: k) :: *;
}

-- | A valid endpoint may only contain Symbols and captures &amp; for
--   convenince Subscribable:

-- | A concrete, poly-kinded proxy type
data Proxy k (t :: k) :: forall k. () => k -> *

-- | Represents a general universal resource identifier using its component
--   parts.
--   
--   For example, for the URI
--   
--   <pre>
--   foo://anonymous@www.haskell.org:42/ghc?query#frag
--   </pre>
--   
--   the components are:
data URI :: *

-- | A monad supporting atomic memory transactions.
data STM a :: * -> *
