@@ -19,26 +19,28 @@ module Network.HTTP.Affjax
1919
2020import Prelude hiding (max )
2121
22- import Control.Monad.Aff (Aff , makeAff , makeAff' , Canceler (..), attempt , later' , forkAff , cancel )
22+ import Control.Monad.Aff (Aff , makeAff , makeAff' , Canceler (..), attempt , delay , forkAff , cancel )
2323import Control.Monad.Aff.AVar (AVAR , makeVar , takeVar , putVar )
24- import Control.Monad.Eff (Eff )
24+ import Control.Monad.Eff (kind Effect , Eff )
2525import Control.Monad.Eff.Class (liftEff )
2626import Control.Monad.Eff.Exception (Error , error )
2727import Control.Monad.Eff.Ref (REF , newRef , readRef , writeRef )
2828import Control.Monad.Except (runExcept , throwError )
2929
30+ import Data.Argonaut.Parser (jsonParser )
3031import Data.Array as Arr
3132import Data.Either (Either (..), either )
3233import Data.Foldable (any )
33- import Data.Foreign (Foreign , F , parseJSON , readString )
34+ import Data.Foreign (F , Foreign , ForeignError (JSONError), fail , readString , toForeign )
3435import Data.Function (on )
3536import Data.Function.Uncurried (Fn5 , runFn5 , Fn4 , runFn4 )
3637import Data.HTTP.Method (Method (..), CustomMethod )
3738import Data.HTTP.Method as Method
38- import Data.Int (toNumber , round )
39+ import Data.Int (toNumber )
3940import Data.Maybe (Maybe (..))
4041import Data.MediaType (MediaType )
4142import Data.Nullable (Nullable , toNullable )
43+ import Data.Time.Duration (Milliseconds (..))
4244import Data.Tuple (Tuple (..), fst , snd )
4345
4446import Math (max , pow )
@@ -52,7 +54,7 @@ import Network.HTTP.ResponseHeader (ResponseHeader, responseHeader)
5254import Network.HTTP.StatusCode (StatusCode (..))
5355
5456-- | The effect type for AJAX requests made with Affjax.
55- foreign import data AJAX :: !
57+ foreign import data AJAX :: Effect
5658
5759-- | The type for Affjax requests.
5860type Affjax e a = Aff (ajax :: AJAX | e ) (AffjaxResponse a )
@@ -89,81 +91,81 @@ type AffjaxResponse a =
8991type URL = String
9092
9193-- | Makes an `Affjax` request.
92- affjax :: forall e a b . ( Requestable a , Respondable b ) => AffjaxRequest a -> Affjax e b
94+ affjax :: forall e a b . Requestable a => Respondable b => AffjaxRequest a -> Affjax e b
9395affjax = makeAff' <<< affjax'
9496
9597-- | Makes a `GET` request to the specified URL.
96- get :: forall e a . ( Respondable a ) => URL -> Affjax e a
98+ get :: forall e a . Respondable a => URL -> Affjax e a
9799get u = affjax $ defaultRequest { url = u }
98100
99101-- | Makes a `POST` request to the specified URL, sending data.
100- post :: forall e a b . ( Requestable a , Respondable b ) => URL -> a -> Affjax e b
102+ post :: forall e a b . Requestable a => Respondable b => URL -> a -> Affjax e b
101103post u c = affjax $ defaultRequest { method = Left POST , url = u, content = Just c }
102104
103105-- | Makes a `POST` request to the specified URL with the option to send data.
104- post' :: forall e a b . ( Requestable a , Respondable b ) => URL -> Maybe a -> Affjax e b
106+ post' :: forall e a b . Requestable a => Respondable b => URL -> Maybe a -> Affjax e b
105107post' u c = affjax $ defaultRequest { method = Left POST , url = u, content = c }
106108
107109-- | Makes a `POST` request to the specified URL, sending data and ignoring the
108110-- | response.
109- post_ :: forall e a . ( Requestable a ) => URL -> a -> Affjax e Unit
111+ post_ :: forall e a . Requestable a => URL -> a -> Affjax e Unit
110112post_ = post
111113
112114-- | Makes a `POST` request to the specified URL with the option to send data,
113115-- | and ignores the response.
114- post_' :: forall e a . ( Requestable a ) => URL -> Maybe a -> Affjax e Unit
116+ post_' :: forall e a . Requestable a => URL -> Maybe a -> Affjax e Unit
115117post_' = post'
116118
117119-- | Makes a `PUT` request to the specified URL, sending data.
118- put :: forall e a b . ( Requestable a , Respondable b ) => URL -> a -> Affjax e b
120+ put :: forall e a b . Requestable a => Respondable b => URL -> a -> Affjax e b
119121put u c = affjax $ defaultRequest { method = Left PUT , url = u, content = Just c }
120122
121123-- | Makes a `PUT` request to the specified URL with the option to send data.
122- put' :: forall e a b . ( Requestable a , Respondable b ) => URL -> Maybe a -> Affjax e b
124+ put' :: forall e a b . Requestable a => Respondable b => URL -> Maybe a -> Affjax e b
123125put' u c = affjax $ defaultRequest { method = Left PUT , url = u, content = c }
124126
125127-- | Makes a `PUT` request to the specified URL, sending data and ignoring the
126128-- | response.
127- put_ :: forall e a . ( Requestable a ) => URL -> a -> Affjax e Unit
129+ put_ :: forall e a . Requestable a => URL -> a -> Affjax e Unit
128130put_ = put
129131
130132-- | Makes a `PUT` request to the specified URL with the option to send data,
131133-- | and ignores the response.
132- put_' :: forall e a . ( Requestable a ) => URL -> Maybe a -> Affjax e Unit
134+ put_' :: forall e a . Requestable a => URL -> Maybe a -> Affjax e Unit
133135put_' = put'
134136
135137-- | Makes a `DELETE` request to the specified URL.
136- delete :: forall e a . ( Respondable a ) => URL -> Affjax e a
138+ delete :: forall e a . Respondable a => URL -> Affjax e a
137139delete u = affjax $ defaultRequest { method = Left DELETE , url = u }
138140
139141-- | Makes a `DELETE` request to the specified URL and ignores the response.
140142delete_ :: forall e . URL -> Affjax e Unit
141143delete_ = delete
142144
143145-- | Makes a `PATCH` request to the specified URL, sending data.
144- patch :: forall e a b . ( Requestable a , Respondable b ) => URL -> a -> Affjax e b
146+ patch :: forall e a b . Requestable a => Respondable b => URL -> a -> Affjax e b
145147patch u c = affjax $ defaultRequest { method = Left PATCH , url = u, content = Just c }
146148
147149-- | Makes a `PATCH` request to the specified URL with the option to send data.
148- patch' :: forall e a b . ( Requestable a , Respondable b ) => URL -> Maybe a -> Affjax e b
150+ patch' :: forall e a b . Requestable a => Respondable b => URL -> Maybe a -> Affjax e b
149151patch' u c = affjax $ defaultRequest { method = Left PATCH , url = u, content = c }
150152
151153-- | Makes a `PATCH` request to the specified URL, sending data and ignoring the
152154-- | response.
153- patch_ :: forall e a . ( Requestable a ) => URL -> a -> Affjax e Unit
155+ patch_ :: forall e a . Requestable a => URL -> a -> Affjax e Unit
154156patch_ = patch
155157
156158-- | Makes a `PATCH` request to the specified URL with the option to send data,
157159-- | and ignores the response.
158- patch_' :: forall e a . ( Requestable a ) => URL -> Maybe a -> Affjax e Unit
160+ patch_' :: forall e a . Requestable a => URL -> Maybe a -> Affjax e Unit
159161patch_' = patch'
160162
161163-- | A sequence of retry delays, in milliseconds.
162- type RetryDelayCurve = Int -> Int
164+ type RetryDelayCurve = Int -> Milliseconds
163165
164166-- | Expresses a policy for retrying Affjax requests with backoff.
165167type RetryPolicy =
166- { timeout :: Maybe Int -- ^ the timeout in milliseconds, optional
168+ { timeout :: Maybe Milliseconds -- ^ the timeout in milliseconds, optional
167169 , delayCurve :: RetryDelayCurve
168170 , shouldRetryWithStatusCode :: StatusCode -> Boolean -- ^ whether a non-200 status code should trigger a retry
169171 }
@@ -172,7 +174,7 @@ type RetryPolicy =
172174defaultRetryPolicy :: RetryPolicy
173175defaultRetryPolicy =
174176 { timeout : Nothing
175- , delayCurve : \n -> round $ max (30.0 * 1000.0 ) $ 100.0 * (pow 2.0 $ toNumber (n - 1 ))
177+ , delayCurve : \n -> Milliseconds $ max (30.0 * 1000.0 ) $ 100.0 * (pow 2.0 $ toNumber (n - 1 ))
176178 , shouldRetryWithStatusCode : const false
177179 }
178180
@@ -182,7 +184,7 @@ type RetryState e a = Either (Either e a) a
182184-- | Retry a request using a `RetryPolicy`. After the timeout, the last received response is returned; if it was not possible to communicate with the server due to an error, then this is bubbled up.
183185retry
184186 :: forall e a b
185- . ( Requestable a )
187+ . Requestable a
186188 => RetryPolicy
187189 -> (AffjaxRequest a -> Affjax (avar :: AVAR , ref :: REF | e ) b )
188190 -> (AffjaxRequest a -> Affjax (avar :: AVAR , ref :: REF | e ) b )
@@ -196,7 +198,8 @@ retry policy run req = do
196198 respVar <- makeVar
197199 loopHandle <- forkAff $ loop 1 >>= putVar respVar <<< Just
198200 timeoutHandle <-
199- forkAff <<< later' timeout $ do
201+ forkAff $ do
202+ delay timeout
200203 putVar respVar Nothing
201204 loopHandle `cancel` error " Cancel"
202205 result <- takeVar respVar
@@ -226,13 +229,15 @@ retry policy run req = do
226229 case result of
227230 Left err -> do
228231 liftEff $ writeRef failureRef $ Just err
229- later' (policy.delayCurve n) $ go failureRef (n + 1 )
232+ delay (policy.delayCurve n)
233+ go failureRef (n + 1 )
230234 Right resp -> pure resp
231235
232236-- | Run a request directly without using `Aff`.
233237affjax'
234238 :: forall e a b
235- . (Requestable a , Respondable b )
239+ . Requestable a
240+ => Respondable b
236241 => AffjaxRequest a
237242 -> (Error -> Eff (ajax :: AJAX | e ) Unit )
238243 -> (AffjaxResponse b -> Eff (ajax :: AJAX | e ) Unit )
@@ -277,6 +282,9 @@ affjax' req eb cb =
277282 Left err -> eb $ error (show err )
278283 Right res' -> cb res'
279284
285+ parseJSON :: String -> F Foreign
286+ parseJSON = either (fail <<< JSONError ) (pure <<< toForeign ) <<< jsonParser
287+
280288 fromResponse' :: ResponseContent -> F b
281289 fromResponse' = case snd responseSettings of
282290 JSONResponse -> fromResponse <= < parseJSON <= < readString
0 commit comments