packages feed

reflex-gadt-api 0.2.1.0 → 0.2.2.0

raw patch · 6 files changed

+50/−37 lines, 6 filesdep +dependent-sumdep −constraintsdep ~basedep ~reflex-dom-corePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: dependent-sum

Dependencies removed: constraints

Dependency ranges changed: base, reflex-dom-core

API changes (from Hackage documentation)

+ Reflex.Dom.GadtApi.WebSocket: TaggedRequest :: Int -> Value -> TaggedRequest
+ Reflex.Dom.GadtApi.WebSocket: TaggedResponse :: Int -> Value -> TaggedResponse
- Reflex.Dom.GadtApi.WebSocket: performWebSocketRequests :: forall req js t m. (Prerender js t m, Applicative m, FromJSON (Some req), forall a. ToJSON (req a), ForallF ToJSON req, Has FromJSON req) => WebSocketEndpoint -> Event t (RequesterData req) -> m (Event t (RequesterData (Either Text)))
+ Reflex.Dom.GadtApi.WebSocket: performWebSocketRequests :: forall req t m. (Prerender t m, Applicative m, FromJSON (Some req), forall a. ToJSON (req a), Has FromJSON req) => WebSocketEndpoint -> Event t (RequesterData req) -> m (Event t (RequesterData (Either Text)))
- Reflex.Dom.GadtApi.WebSocket: tagRequests :: forall req t m. (Applicative m, FromJSON (Some req), forall a. ToJSON (req a), ForallF ToJSON req, Has FromJSON req, Monad m, MonadFix m, Reflex t, MonadHold t m) => Event t (RequesterData req) -> Event t TaggedResponse -> m (Event t [TaggedRequest], Event t (RequesterData (Either Text)))
+ Reflex.Dom.GadtApi.WebSocket: tagRequests :: forall req t m. (Applicative m, FromJSON (Some req), forall a. ToJSON (req a), Has FromJSON req, Monad m, MonadFix m, Reflex t, MonadHold t m) => Event t (RequesterData req) -> Event t TaggedResponse -> m (Event t [TaggedRequest], Event t (RequesterData (Either Text)))
- Reflex.Dom.GadtApi.XHR: apiRequestXhr :: forall api m. (MonadIO m, HasJSContext m, MonadJSM m, Has FromJSON api, forall a. ToJSON (api a)) => ApiEndpoint -> RequesterData api -> m (RequesterData (Either Text))
+ Reflex.Dom.GadtApi.XHR: apiRequestXhr :: forall api m. (MonadIO m, MonadJSM m, Has FromJSON api, forall a. ToJSON (api a)) => ApiEndpoint -> RequesterData api -> m (RequesterData (Either Text))
- Reflex.Dom.GadtApi.XHR: performXhrRequests :: forall t m api js. (Has FromJSON api, forall a. ToJSON (api a), Prerender js t m, Applicative m) => ApiEndpoint -> Event t (RequesterData api) -> m (Event t (RequesterData (Either Text)))
+ Reflex.Dom.GadtApi.XHR: performXhrRequests :: forall t m api. (Has FromJSON api, forall a. ToJSON (api a), Prerender t m, Applicative m) => ApiEndpoint -> Event t (RequesterData api) -> m (Event t (RequesterData (Either Text)))

Files

ChangeLog.md view
@@ -1,5 +1,14 @@ # Revision history for reflex-gadt-api +## 0.2.2.0++* Support GHC 8.10+* Make xhr requests non-blocking++## 0.2.1.1++* Expose `Tagged`* constructors+ ## 0.2.1.0  * Use "some" instead of "dependent-sum" package
Readme.lhs view
@@ -119,8 +119,8 @@ ```haskell  > startCatnet->   :: forall js t m.->      ( Prerender js t m, MonadHold t m+>   :: forall t m.+>      ( Prerender t m, MonadHold t m >      , MonadIO (Performable m), MonadFix m >      , DomBuilder t m, PostBuild t m >      , TriggerEvent t m, PerformEvent t m@@ -143,7 +143,7 @@  ``` -The `Event` of responses comes, in this case, from a functoin that will take the requests emitted on the previous line and fetch responses to those requests. It produces an `Event` of responses. We can use either `Reflex.Dom.GadtApi.XHR.performXhrRequests` if we want to send requests using XHR or `Reflex.Dom.GadtApi.WebSocket.performWebSocketRequests` to use WebSockets.+The `Event` of responses comes, in this case, from a function that will take the requests emitted on the previous line and fetch responses to those requests. It produces an `Event` of responses. We can use either `Reflex.Dom.GadtApi.XHR.performXhrRequests` if we want to send requests using XHR or `Reflex.Dom.GadtApi.WebSocket.performWebSocketRequests` to use WebSockets. ```haskell  >       responses <- case endpoint of@@ -185,7 +185,7 @@ ```haskell  > requestingJs->   :: (Reflex t, MonadFix m, Prerender js t m)+>   :: (Reflex t, MonadFix m, Prerender t m) >   => Event t (Request (Client (Catnet t m)) a) >   -> Catnet t m (Event t (Response (Client (Catnet t m)) a)) > requestingJs r = fmap (switch . current) $ prerender (pure never) $ requesting r@@ -200,7 +200,7 @@ ```haskell  > login->   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender js t m)+>   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender t m) >   => Catnet t m (Event t Token) > login = do >   el "h1" $ text "Identify Yourself"@@ -221,7 +221,7 @@ ```haskell  > catnet->   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender js t m)+>   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender t m) >   => Token >   -> Catnet t m (Event t ()) > catnet token = do@@ -275,7 +275,7 @@ ```haskell  > dogSighting->   :: (DomBuilder t m, MonadHold t m, PostBuild t m, Prerender js t m, MonadFix m)+>   :: (DomBuilder t m, MonadHold t m, PostBuild t m, Prerender t m, MonadFix m) >   => Token >   -> Catnet t m (Event t (Either Text ())) > dogSighting token = do@@ -303,7 +303,7 @@  ``` -Once we've got those three values, we can apply them to the `DogApi_ReportSighting` constructor. We're using some infix functoins from [Control.Applicative](https://hackage.haskell.org/package/base/docs/Control-Applicative.html) to apply the constructor to `Dynamic` values, and, as a result, we get a `Dynamic` `DogApi` request. When the submit `Event` fires, we take the `current` value of that `Dynamic` and send it.+Once we've got those three values, we can apply them to the `DogApi_ReportSighting` constructor. We're using some infix functions from [Control.Applicative](https://hackage.haskell.org/package/base/docs/Control-Applicative.html) to apply the constructor to `Dynamic` values, and, as a result, we get a `Dynamic` `DogApi` request. When the submit `Event` fires, we take the `current` value of that `Dynamic` and send it.  ```haskell 
Readme.md view
@@ -119,8 +119,8 @@ ```haskell  > startCatnet->   :: forall js t m.->      ( Prerender js t m, MonadHold t m+>   :: forall t m.+>      ( Prerender t m, MonadHold t m >      , MonadIO (Performable m), MonadFix m >      , DomBuilder t m, PostBuild t m >      , TriggerEvent t m, PerformEvent t m@@ -143,7 +143,7 @@  ``` -The `Event` of responses comes, in this case, from a functoin that will take the requests emitted on the previous line and fetch responses to those requests. It produces an `Event` of responses. We can use either `Reflex.Dom.GadtApi.XHR.performXhrRequests` if we want to send requests using XHR or `Reflex.Dom.GadtApi.WebSocket.performWebSocketRequests` to use WebSockets.+The `Event` of responses comes, in this case, from a function that will take the requests emitted on the previous line and fetch responses to those requests. It produces an `Event` of responses. We can use either `Reflex.Dom.GadtApi.XHR.performXhrRequests` if we want to send requests using XHR or `Reflex.Dom.GadtApi.WebSocket.performWebSocketRequests` to use WebSockets. ```haskell  >       responses <- case endpoint of@@ -185,7 +185,7 @@ ```haskell  > requestingJs->   :: (Reflex t, MonadFix m, Prerender js t m)+>   :: (Reflex t, MonadFix m, Prerender t m) >   => Event t (Request (Client (Catnet t m)) a) >   -> Catnet t m (Event t (Response (Client (Catnet t m)) a)) > requestingJs r = fmap (switch . current) $ prerender (pure never) $ requesting r@@ -200,7 +200,7 @@ ```haskell  > login->   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender js t m)+>   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender t m) >   => Catnet t m (Event t Token) > login = do >   el "h1" $ text "Identify Yourself"@@ -221,7 +221,7 @@ ```haskell  > catnet->   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender js t m)+>   :: (DomBuilder t m, MonadHold t m, MonadFix m, Prerender t m) >   => Token >   -> Catnet t m (Event t ()) > catnet token = do@@ -275,7 +275,7 @@ ```haskell  > dogSighting->   :: (DomBuilder t m, MonadHold t m, PostBuild t m, Prerender js t m, MonadFix m)+>   :: (DomBuilder t m, MonadHold t m, PostBuild t m, Prerender t m, MonadFix m) >   => Token >   -> Catnet t m (Event t (Either Text ())) > dogSighting token = do@@ -303,7 +303,7 @@  ``` -Once we've got those three values, we can apply them to the `DogApi_ReportSighting` constructor. We're using some infix functoins from [Control.Applicative](https://hackage.haskell.org/package/base/docs/Control-Applicative.html) to apply the constructor to `Dynamic` values, and, as a result, we get a `Dynamic` `DogApi` request. When the submit `Event` fires, we take the `current` value of that `Dynamic` and send it.+Once we've got those three values, we can apply them to the `DogApi_ReportSighting` constructor. We're using some infix functions from [Control.Applicative](https://hackage.haskell.org/package/base/docs/Control-Applicative.html) to apply the constructor to `Dynamic` values, and, as a result, we get a `Dynamic` `DogApi` request. When the submit `Event` fires, we take the `current` value of that `Dynamic` and send it.  ```haskell 
reflex-gadt-api.cabal view
@@ -1,6 +1,6 @@ cabal-version:      >=1.10 name:               reflex-gadt-api-version:            0.2.1.0+version:            0.2.2.0 synopsis:           Interact with a GADT API in your reflex-dom application. description:   This package is designed to be used in full-stack Haskell applications where the API is defined as a GADT and the frontend is using reflex-dom.@@ -17,22 +17,21 @@   ChangeLog.md   Readme.md -tested-with:        GHC ==8.6.5 || ==8.8.1+tested-with:        GHC ==8.6.5 || ==8.8.1 || ==8.10.2  library   hs-source-dirs:   src   build-depends:       aeson               >=1.4.4  && <1.5     , aeson-gadt-th       >=0.2.4  && <0.3-    , base                >=4.12   && <4.14+    , base                >=4.12   && <4.16     , bytestring          >=0.10.8 && <0.11-    , constraints         >=0.10.1 && <0.11     , constraints-extras  >=0.3.0  && <0.4     , containers          >=0.6    && <0.7     , data-default        >=0.6    && <0.8     , jsaddle             >=0.9.7  && <0.10     , reflex              >=0.7    && <0.9-    , reflex-dom-core     >=0.6.0  && <0.7+    , reflex-dom-core     >=0.7.0  && <0.8     , some                >=1      && <1.1     , text                >=1.2    && <1.3     , time                >=1.6.0  && <2@@ -55,6 +54,11 @@     , reflex-gadt-api     , text     , time+    -- We don't actually need this dependency, but omitting it can cause issues+    -- when an older dependent-sum is used (from before the some package was+    -- split out). Since this is already a transitive dependency, this seems+    -- like the simplest solution.+    , dependent-sum       >=0.7    && <0.8    default-language: Haskell2010   main-is:          Readme.lhs
src/Reflex/Dom/GadtApi/WebSocket.hs view
@@ -10,8 +10,8 @@ {-# LANGUAGE UndecidableInstances #-} module Reflex.Dom.GadtApi.WebSocket   ( performWebSocketRequests-  , TaggedRequest-  , TaggedResponse+  , TaggedRequest (..)+  , TaggedResponse (..)   , mkTaggedResponse   , WebSocketEndpoint   , tagRequests@@ -19,7 +19,6 @@  import Control.Monad.Fix (MonadFix) import Data.Constraint.Extras-import Data.Constraint.Forall import Data.Aeson import Data.Default import qualified Data.Text as T@@ -59,11 +58,10 @@ -- @ -- performWebSocketRequests-  :: forall req js t m.-     ( Prerender js t m, Applicative m+  :: forall req t m.+     ( Prerender t m, Applicative m      , FromJSON (Some req)      , forall a. ToJSON (req a)-     , ForallF ToJSON req      , Has FromJSON req      )   => WebSocketEndpoint@@ -115,7 +113,6 @@      ( Applicative m      , FromJSON (Some req)      , forall a. ToJSON (req a)-     , ForallF ToJSON req      , Has FromJSON req      , Monad m      , MonadFix m@@ -137,7 +134,7 @@   where     enc :: forall a. req a -> (Value, Value -> Either Text a)     enc r =-      ( whichever @ToJSON @req @a $ toJSON r+      ( toJSON r       , \x -> case has @FromJSON r $ fromJSON x of         Success s-> Right s         Error e -> Left $ T.pack e
src/Reflex/Dom/GadtApi/XHR.hs view
@@ -6,14 +6,16 @@ {-# LANGUAGE TypeApplications #-} module Reflex.Dom.GadtApi.XHR where -import Control.Concurrent (newEmptyMVar, putMVar, takeMVar)+import Control.Concurrent (forkIO, newEmptyMVar, putMVar, takeMVar) import Control.Monad.IO.Class (MonadIO, liftIO) import Data.Aeson import qualified Data.ByteString.Lazy as LBS import Data.Constraint.Extras (Has, has)+import Data.Functor (void) import Data.Text (Text) import qualified Data.Text.Encoding as T import Language.Javascript.JSaddle (MonadJSM)+import Language.Javascript.JSaddle.Monad (runJSM, askJSM) import Reflex.Dom.Core  type ApiEndpoint = Text@@ -28,25 +30,26 @@ -- @ -- performXhrRequests-  :: forall t m api js.+  :: forall t m api.      ( Has FromJSON api      , forall a. ToJSON (api a)-     , Prerender js t m+     , Prerender t m      , Applicative m      )   => ApiEndpoint   -> Event t (RequesterData api)   -> m (Event t (RequesterData (Either Text)))-performXhrRequests apiUrl req = fmap switchPromptlyDyn $ prerender (pure never) $-  performEventAsync $ ffor req $ \r yield ->-    liftIO . yield =<< apiRequestXhr apiUrl r+performXhrRequests apiUrl req = fmap switchPromptlyDyn $ prerender (pure never) $ do+  performEventAsync $ ffor req $ \r yield -> do+    ctx <- askJSM+    void $ liftIO $ forkIO $ flip runJSM ctx $+      liftIO . yield =<< apiRequestXhr apiUrl r  -- | Encodes an API request as JSON and issues an 'XhrRequest', -- and attempts to decode the response. apiRequestXhr   :: forall api m.      ( MonadIO m-     , HasJSContext m      , MonadJSM m      , Has FromJSON api      , forall a. ToJSON (api a)@@ -58,7 +61,7 @@   has @FromJSON @api x $ mkRequest x   where     mkRequest-      :: (HasJSContext m, MonadJSM m, FromJSON b)+      :: (MonadJSM m, FromJSON b)       => api b       -> m (Either Text b)     mkRequest req = do