-- | High-level client implementation for JetStream.
module JetStream.Client
  ( newJetStream
  , JetStream
  , JetStreamOption
  , JetStreamRequestOption
  , JetStreamConfigError (..)
  , withDomain
  , withRequestTimeout
  , withRequestTimeoutMicros
  ) where

import qualified API                        as Nats
import           JetStream.API              (JetStream)
import qualified JetStream.Consumer         as Consumer
import qualified JetStream.Message          as Message
import           JetStream.Options
    ( JetStream (..)
    , JetStreamConfigError (..)
    , JetStreamOption
    , tryNewJetStreamContext
    , withDomain
    , withRequestTimeout
    , withRequestTimeoutMicros
    )
import qualified JetStream.Protocol.Request as Request
import qualified JetStream.Protocol.Subject as Subject
import qualified JetStream.Publish          as Publish
import qualified JetStream.Stream           as Stream
import           JetStream.Types            (JetStreamRequestOption)

-- | Build JetStream capabilities from an existing NATS client.
newJetStream :: Nats.Client -> [JetStreamOption] -> Either JetStreamConfigError JetStream
newJetStream :: Client
-> [JetStreamOption] -> Either JetStreamConfigError JetStream
newJetStream Client
client [JetStreamOption]
options = do
  JetStreamContext
ctx <- Client
-> [JetStreamOption]
-> Either JetStreamConfigError JetStreamContext
tryNewJetStreamContext Client
client [JetStreamOption]
options
  let consumerAPI :: ConsumerAPI
consumerAPI = JetStreamContext -> ConsumerAPI
Consumer.consumerAPI JetStreamContext
ctx
  JetStream -> Either JetStreamConfigError JetStream
forall a. a -> Either JetStreamConfigError a
forall (f :: * -> *) a. Applicative f => a -> f a
pure JetStream
    { streams :: StreamAPI
streams = JetStreamContext -> StreamAPI
Stream.streamAPI JetStreamContext
ctx
    , consumers :: ConsumerAPI
consumers = ConsumerAPI
consumerAPI
    , publisher :: PublishAPI
publisher = JetStreamContext -> PublishAPI
Publish.publishAPI JetStreamContext
ctx
    , messages :: MessageAPI
messages = JetStreamContext -> ConsumerAPI -> MessageAPI
Message.messageAPI JetStreamContext
ctx ConsumerAPI
consumerAPI
    , accountInfo :: [JetStreamRequestOption] -> IO (Either JetStreamError AccountInfo)
accountInfo =
        JetStreamContext
-> Subject
-> Maybe Value
-> [JetStreamRequestOption]
-> IO (Either JetStreamError AccountInfo)
forall a.
FromJSON a =>
JetStreamContext
-> Subject
-> Maybe Value
-> [JetStreamRequestOption]
-> IO (Either JetStreamError a)
Request.requestJSON JetStreamContext
ctx (JetStreamContext -> Subject
Subject.accountInfoSubject JetStreamContext
ctx) Maybe Value
forall a. Maybe a
Nothing
    }