{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE InstanceSigs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} module Data.Morpheus.Types.Resolver ( Pure , Resolver , MutResolver , SubResolver , ResolveT , SubResolveT , MutResolveT , SubRootRes , Event(..) , GQLRootResolver(..) , resolver , mutResolver , toMutResolver ) where import Control.Monad.Trans.Except (ExceptT (..), runExceptT) -- MORPHEUS -- import Data.Morpheus.Types.Internal.Stream (Event (..), PublishStream, StreamState (..), StreamT (..), SubscribeStream) import Data.Morpheus.Types.Internal.Validation (ResolveT) -- SubResolver m (Event [c1, c2] d) a ---------------------------------------------------------------------------------------- type MutResolveT m e c a = ResolveT (PublishStream m e c) a ------------------------------------------------------------------- type Resolver = ExceptT String type MutResolver m e c = Resolver (PublishStream m e c) type SubResolver m e c a = Event e (Event e c -> Resolver m a) type SubResolveT m e c a = ResolveT (SubscribeStream m e) (Event e c -> ResolveT m a) type SubRootRes m e sub = Resolver (SubscribeStream m e) sub ------------------------------------------------------------------- -- | Pure Resolver without effect type Pure = Either String -- | GraphQL Resolver resolver :: m (Either String a) -> Resolver m a resolver = ExceptT toMutResolver :: Monad m => [Event e c] -> Resolver m a -> MutResolver m e c a toMutResolver channels = ExceptT . StreamT . fmap (StreamState channels) . runExceptT -- | GraphQL Resolver for mutation or subscription resolver , adds effect to normal resolver mutResolver :: Monad m => [Event e c] -> (StreamT m (Event e c)) (Either String a) -> MutResolver m e c a mutResolver channels = ExceptT . StreamT . fmap effectPlus . runStreamT where effectPlus state = state {streamEvents = channels ++ streamEvents state} -- | GraphQL Root resolver, also the interpreter generates a GQL schema from it. -- -- 'queryResolver' is required, 'mutationResolver' and 'subscriptionResolver' are optional, -- if your schema does not supports __mutation__ or __subscription__ , you acn use __()__ for it. data GQLRootResolver m e c query mut sub = GQLRootResolver { queryResolver :: Resolver m query , mutationResolver :: Resolver (PublishStream m e c) mut , subscriptionResolver :: SubRootRes m e sub }