Skip to content

Commit df55778

Browse files
committed
Update for 0.12 and remove Respondable
1 parent c2388a8 commit df55778

File tree

8 files changed

+182
-267
lines changed

8 files changed

+182
-267
lines changed

bower.json

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,21 @@
2323
"package.json"
2424
],
2525
"dependencies": {
26-
"purescript-aff": "^4.0.0",
27-
"purescript-argonaut-core": "^3.0.0",
28-
"purescript-arraybuffer-types": "^1.0.0",
29-
"purescript-dom": "^4.0.0",
30-
"purescript-foreign": "^4.0.0",
31-
"purescript-form-urlencoded": "^3.0.0",
32-
"purescript-http-methods": "^3.0.0",
33-
"purescript-integers": "^3.0.0",
34-
"purescript-math": "^2.0.0",
35-
"purescript-media-types": "^3.0.0",
36-
"purescript-nullable": "^3.0.0",
37-
"purescript-refs": "^3.0.0",
38-
"purescript-unsafe-coerce": "^3.0.0"
26+
"purescript-aff": "^5.0.0",
27+
"purescript-argonaut-core": "^4.0.0",
28+
"purescript-arraybuffer-types": "^2.0.0",
29+
"purescript-web-xhr": "^2.0.0",
30+
"purescript-foreign": "^5.0.0",
31+
"purescript-form-urlencoded": "^4.0.0",
32+
"purescript-http-methods": "^4.0.0",
33+
"purescript-integers": "^4.0.0",
34+
"purescript-math": "^2.1.1",
35+
"purescript-media-types": "^4.0.0",
36+
"purescript-nullable": "^4.0.0",
37+
"purescript-refs": "^4.1.0",
38+
"purescript-unsafe-coerce": "^4.0.0"
3939
},
4040
"devDependencies": {
41-
"purescript-console": "^3.0.0"
41+
"purescript-console": "^4.1.0"
4242
}
4343
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"express": "^4.14.0",
1212
"pulp": "^11.0.0",
1313
"purescript-psa": "^0.5.0",
14-
"purescript": "^0.11.0",
14+
"purescript": "slamdata/node-purescript#0.12",
1515
"rimraf": "^2.5.4",
1616
"xhr2": "^0.1.3"
1717
}

src/Network/HTTP/Affjax.purs

Lines changed: 81 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
module Network.HTTP.Affjax
2-
( AJAX
3-
, Affjax
2+
( Affjax
43
, AffjaxRequest, defaultRequest
5-
, AffjaxResponse
4+
, AffjaxResponseT
65
, URL
76
, affjax
87
, get
@@ -19,44 +18,39 @@ module Network.HTTP.Affjax
1918

2019
import Prelude
2120

22-
import Control.Monad.Aff (Aff, try, delay)
23-
import Control.Monad.Aff.Compat as AC
24-
import Control.Monad.Eff (kind Effect)
25-
import Control.Monad.Eff.Class (liftEff)
26-
import Control.Monad.Eff.Exception (Error, error)
27-
import Control.Monad.Eff.Ref (REF, newRef, readRef, writeRef)
2821
import Control.Monad.Except (runExcept, throwError)
2922
import Control.Parallel (parOneOf)
23+
import Data.Argonaut.Core (Json)
3024
import Data.Argonaut.Core as J
3125
import Data.Argonaut.Parser (jsonParser)
3226
import Data.Array as Arr
3327
import Data.Either (Either(..), either)
3428
import Data.Foldable (any)
35-
import Data.Foreign (F, Foreign, ForeignError(JSONError), fail, readString, toForeign)
3629
import Data.FormURLEncoded as FormURLEncoded
3730
import Data.Function (on)
3831
import Data.Function.Uncurried (Fn2, runFn2)
3932
import Data.HTTP.Method (Method(..), CustomMethod)
4033
import Data.HTTP.Method as Method
4134
import Data.Int (toNumber)
4235
import Data.Maybe (Maybe(..))
43-
import Data.MediaType (MediaType)
4436
import Data.Nullable (Nullable, toNullable)
4537
import Data.Time.Duration (Milliseconds(..))
46-
import Data.Tuple (Tuple, fst, snd)
38+
import Effect.Aff (Aff, try, delay)
39+
import Effect.Aff.Compat as AC
40+
import Effect.Class (liftEffect)
41+
import Effect.Exception (Error, error)
42+
import Effect.Ref as Ref
43+
import Foreign (F, Foreign, ForeignError(..), fail, unsafeReadTagged, unsafeToForeign)
4744
import Math as Math
48-
import Network.HTTP.Affjax.Request (RequestContent(..)) as Exports
4945
import Network.HTTP.Affjax.Request (RequestContent(..), defaultMediaType)
50-
import Network.HTTP.Affjax.Response (class Respondable, ResponseContent, ResponseType(..), fromResponse, responseType, responseTypeToString)
46+
import Network.HTTP.Affjax.Request (RequestContent(..)) as Exports
47+
import Network.HTTP.Affjax.Response (AffjaxResponse(..), responseTypeToMediaType, responseTypeToString)
5148
import Network.HTTP.RequestHeader (RequestHeader(..), requestHeaderName, requestHeaderValue)
5249
import Network.HTTP.ResponseHeader (ResponseHeader, responseHeader)
5350
import Network.HTTP.StatusCode (StatusCode(..))
5451

55-
-- | The effect type for AJAX requests made with Affjax.
56-
foreign import data AJAX :: Effect
57-
5852
-- | The result type for Affjax requests.
59-
type Affjax eff a = Aff (ajax :: AJAX | eff) (AffjaxResponse a)
53+
type Affjax a = Aff (AffjaxResponseT a)
6054

6155
type AffjaxRequest =
6256
{ method :: Either Method CustomMethod
@@ -80,7 +74,7 @@ defaultRequest =
8074
}
8175

8276
-- | The type of records that will be received as an Affjax response.
83-
type AffjaxResponse a =
77+
type AffjaxResponseT a =
8478
{ status :: StatusCode
8579
, headers :: Array ResponseHeader
8680
, response :: a
@@ -90,70 +84,70 @@ type AffjaxResponse a =
9084
type URL = String
9185

9286
-- | Makes a `GET` request to the specified URL.
93-
get :: forall e a. Respondable a => URL -> Affjax e a
94-
get u = affjax $ defaultRequest { url = u }
87+
get :: forall a. AffjaxResponse a -> URL -> Affjax a
88+
get rt u = affjax rt $ defaultRequest { url = u }
9589

9690
-- | Makes a `POST` request to the specified URL, sending data.
97-
post :: forall e a b. Respondable b => URL -> RequestContent -> Affjax e b
98-
post u c = affjax $ defaultRequest { method = Left POST, url = u, content = Just c }
91+
post :: forall a. AffjaxResponse a -> URL -> RequestContent -> Affjax a
92+
post rt u c = affjax rt $ defaultRequest { method = Left POST, url = u, content = Just c }
9993

10094
-- | Makes a `POST` request to the specified URL with the option to send data.
101-
post' :: forall e a b. Respondable b => URL -> Maybe RequestContent -> Affjax e b
102-
post' u c = affjax $ defaultRequest { method = Left POST, url = u, content = c }
95+
post' :: forall a. AffjaxResponse a -> URL -> Maybe RequestContent -> Affjax a
96+
post' rt u c = affjax rt $ defaultRequest { method = Left POST, url = u, content = c }
10397

10498
-- | Makes a `POST` request to the specified URL, sending data and ignoring the
10599
-- | response.
106-
post_ :: forall e a. URL -> RequestContent -> Affjax e Unit
107-
post_ = post
100+
post_ :: URL -> RequestContent -> Affjax Unit
101+
post_ = post (IgnoredResponse identity)
108102

109103
-- | Makes a `POST` request to the specified URL with the option to send data,
110104
-- | and ignores the response.
111-
post_' :: forall e a. URL -> Maybe RequestContent -> Affjax e Unit
112-
post_' = post'
105+
post_' :: URL -> Maybe RequestContent -> Affjax Unit
106+
post_' = post' (IgnoredResponse identity)
113107

114108
-- | Makes a `PUT` request to the specified URL, sending data.
115-
put :: forall e a b. Respondable b => URL -> RequestContent -> Affjax e b
116-
put u c = affjax $ defaultRequest { method = Left PUT, url = u, content = Just c }
109+
put :: forall a. AffjaxResponse a -> URL -> RequestContent -> Affjax a
110+
put rt u c = affjax rt $ defaultRequest { method = Left PUT, url = u, content = Just c }
117111

118112
-- | Makes a `PUT` request to the specified URL with the option to send data.
119-
put' :: forall e a b. Respondable b => URL -> Maybe RequestContent -> Affjax e b
120-
put' u c = affjax $ defaultRequest { method = Left PUT, url = u, content = c }
113+
put' :: forall a. AffjaxResponse a -> URL -> Maybe RequestContent -> Affjax a
114+
put' rt u c = affjax rt $ defaultRequest { method = Left PUT, url = u, content = c }
121115

122116
-- | Makes a `PUT` request to the specified URL, sending data and ignoring the
123117
-- | response.
124-
put_ :: forall e a. URL -> RequestContent -> Affjax e Unit
125-
put_ = put
118+
put_ :: URL -> RequestContent -> Affjax Unit
119+
put_ = put (IgnoredResponse identity)
126120

127121
-- | Makes a `PUT` request to the specified URL with the option to send data,
128122
-- | and ignores the response.
129-
put_' :: forall e a. URL -> Maybe RequestContent -> Affjax e Unit
130-
put_' = put'
123+
put_' :: URL -> Maybe RequestContent -> Affjax Unit
124+
put_' = put' (IgnoredResponse identity)
131125

132126
-- | Makes a `DELETE` request to the specified URL.
133-
delete :: forall e a. Respondable a => URL -> Affjax e a
134-
delete u = affjax $ defaultRequest { method = Left DELETE, url = u }
127+
delete :: forall a. AffjaxResponse a -> URL -> Affjax a
128+
delete rt u = affjax rt $ defaultRequest { method = Left DELETE, url = u }
135129

136130
-- | Makes a `DELETE` request to the specified URL and ignores the response.
137-
delete_ :: forall e. URL -> Affjax e Unit
138-
delete_ = delete
131+
delete_ :: URL -> Affjax Unit
132+
delete_ = delete (IgnoredResponse identity)
139133

140134
-- | Makes a `PATCH` request to the specified URL, sending data.
141-
patch :: forall e a b. Respondable b => URL -> RequestContent -> Affjax e b
142-
patch u c = affjax $ defaultRequest { method = Left PATCH, url = u, content = Just c }
135+
patch :: forall a. AffjaxResponse a -> URL -> RequestContent -> Affjax a
136+
patch rt u c = affjax rt $ defaultRequest { method = Left PATCH, url = u, content = Just c }
143137

144138
-- | Makes a `PATCH` request to the specified URL with the option to send data.
145-
patch' :: forall e a b. Respondable b => URL -> Maybe RequestContent -> Affjax e b
146-
patch' u c = affjax $ defaultRequest { method = Left PATCH, url = u, content = c }
139+
patch' :: forall a. AffjaxResponse a -> URL -> Maybe RequestContent -> Affjax a
140+
patch' rt u c = affjax rt $ defaultRequest { method = Left PATCH, url = u, content = c }
147141

148142
-- | Makes a `PATCH` request to the specified URL, sending data and ignoring the
149143
-- | response.
150-
patch_ :: forall e a. URL -> RequestContent -> Affjax e Unit
151-
patch_ = patch
144+
patch_ :: URL -> RequestContent -> Affjax Unit
145+
patch_ = patch (IgnoredResponse identity)
152146

153147
-- | Makes a `PATCH` request to the specified URL with the option to send data,
154148
-- | and ignores the response.
155-
patch_' :: forall e a. URL -> Maybe RequestContent -> Affjax e Unit
156-
patch_' = patch'
149+
patch_' :: URL -> Maybe RequestContent -> Affjax Unit
150+
patch_' = patch' (IgnoredResponse identity)
157151

158152
-- | A sequence of retry delays, in milliseconds.
159153
type RetryDelayCurve = Int -> Milliseconds
@@ -177,31 +171,26 @@ defaultRetryPolicy =
177171
type RetryState e a = Either (Either e a) a
178172

179173
-- | 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.
180-
retry
181-
:: forall e a b
182-
. RetryPolicy
183-
-> (AffjaxRequest -> Affjax (ref :: REF | e) b)
184-
-> AffjaxRequest
185-
-> Affjax (ref :: REF | e) b
174+
retry :: forall a. RetryPolicy -> (AffjaxRequest -> Affjax a) -> AffjaxRequest -> Affjax a
186175
retry policy run req = do
187176
-- failureRef is either an exception or a failed request
188-
failureRef <- liftEff $ newRef Nothing
177+
failureRef <- liftEffect $ Ref.new Nothing
189178
let loop = go failureRef
190179
case policy.timeout of
191180
Nothing -> loop 1
192181
Just timeout -> do
193182
result <- parOneOf [ Just <$> loop 1, Nothing <$ delay timeout ]
194183
case result of
195184
Nothing -> do
196-
failure <- liftEff $ readRef failureRef
185+
failure <- liftEffect $ Ref.read failureRef
197186
case failure of
198187
Nothing -> throwError $ error "Timeout"
199188
Just failure' -> either throwError pure failure'
200189
Just resp -> pure resp
201190
where
202191
retryState
203-
:: Either Error (AffjaxResponse b)
204-
-> RetryState Error (AffjaxResponse b)
192+
:: Either Error (AffjaxResponseT a)
193+
-> RetryState Error (AffjaxResponseT a)
205194
retryState (Left exn) = Left $ Left exn
206195
retryState (Right resp) =
207196
case resp.status of
@@ -216,77 +205,66 @@ retry policy run req = do
216205
result <- retryState <$> try (run req)
217206
case result of
218207
Left err -> do
219-
liftEff $ writeRef failureRef $ Just err
208+
liftEffect $ Ref.write (Just err) failureRef
220209
delay (policy.delayCurve n)
221210
go failureRef (n + 1)
222211
Right resp -> pure resp
223212

224213
-- | Makes an `Affjax` request.
225-
affjax
226-
:: forall e a b
227-
. Respondable b
228-
=> AffjaxRequest
229-
-> Affjax e b
230-
affjax req = do
231-
res <- AC.fromEffFnAff $ runFn2 _ajax responseHeader req'
232-
case res { response = _ } <$> runExcept (fromResponse' res.response) of
214+
affjax :: forall a. AffjaxResponse a -> AffjaxRequest -> Affjax a
215+
affjax rt req = do
216+
res <- AC.fromEffectFnAff $ runFn2 _ajax responseHeader req'
217+
case runExcept (fromResponse' res.response) of
233218
Left err -> throwError $ error (show err)
234-
Right res' -> pure res'
219+
Right res' -> pure (res { response = res' })
235220
where
236221

237-
req' :: AjaxRequest
222+
req' :: AjaxRequest a
238223
req' =
239224
{ method: Method.print req.method
240225
, url: req.url
241226
, headers: (\h -> { field: requestHeaderName h, value: requestHeaderValue h }) <$> headers req.content
242227
, content: toNullable (extractContent <$> req.content)
243-
, responseType: responseTypeToString (snd responseSettings)
228+
, responseType: responseTypeToString rt
244229
, username: toNullable req.username
245230
, password: toNullable req.password
246231
, withCredentials: req.withCredentials
247232
}
248233

249234
extractContent :: RequestContent -> Foreign
250235
extractContent = case _ of
251-
ArrayViewInt8Request x → toForeign x
252-
ArrayViewInt16Request x → toForeign x
253-
ArrayViewInt32Request x → toForeign x
254-
ArrayViewUint8Request x → toForeign x
255-
ArrayViewUint16Request x → toForeign x
256-
ArrayViewUint32Request x → toForeign x
257-
ArrayViewUint8ClampedRequest x → toForeign x
258-
ArrayViewFloat32Request x → toForeign x
259-
ArrayViewFloat64Request x → toForeign x
260-
BlobRequest x → toForeign x
261-
DocumentRequest x → toForeign x
262-
StringRequest x → toForeign x
263-
FormDataRequest x → toForeign x
264-
FormURLEncodedRequest x → toForeign (FormURLEncoded.encode x)
265-
JsonRequest x → toForeign (J.stringify x)
266-
267-
responseSettings :: Tuple (Maybe MediaType) (ResponseType b)
268-
responseSettings = responseType
236+
ArrayView f → f unsafeToForeign
237+
BlobRequest x → unsafeToForeign x
238+
DocumentRequest x → unsafeToForeign x
239+
StringRequest x → unsafeToForeign x
240+
FormDataRequest x → unsafeToForeign x
241+
FormURLEncodedRequest x → unsafeToForeign (FormURLEncoded.encode x)
242+
JsonRequest x → unsafeToForeign (J.stringify x)
269243

270244
headers :: Maybe RequestContent -> Array RequestHeader
271245
headers reqContent =
272246
addHeader (ContentType <$> (defaultMediaType =<< reqContent)) $
273-
addHeader (Accept <$> fst responseSettings)
247+
addHeader (Accept <$> responseTypeToMediaType rt)
274248
req.headers
275249

276250
addHeader :: Maybe RequestHeader -> Array RequestHeader -> Array RequestHeader
277251
addHeader mh hs = case mh of
278252
Just h | not $ any (on eq requestHeaderName h) hs -> hs `Arr.snoc` h
279253
_ -> hs
280254

281-
parseJSON :: String -> F Foreign
282-
parseJSON = either (fail <<< JSONError) (pure <<< toForeign) <<< jsonParser
255+
parseJSON :: String -> F Json
256+
parseJSON = either (fail <<< ForeignError) pure <<< jsonParser
283257

284-
fromResponse' :: ResponseContent -> F b
285-
fromResponse' = case snd responseSettings of
286-
JSONResponse -> fromResponse <=< parseJSON <=< readString
287-
_ -> fromResponse
258+
fromResponse' :: Foreign -> F a
259+
fromResponse' rc = case rt of
260+
ArrayBufferResponse coe -> unsafeReadTagged "ArrayBuffer" rc
261+
BlobResponse coe -> unsafeReadTagged "Blob" rc
262+
DocumentResponse coe -> unsafeReadTagged "Document" rc
263+
JSONResponse coe -> coe $ parseJSON =<< unsafeReadTagged "String" rc
264+
StringResponse coe -> unsafeReadTagged "String" rc
265+
IgnoredResponse coe -> coe $ pure unit
288266

289-
type AjaxRequest =
267+
type AjaxRequest a =
290268
{ method :: String
291269
, url :: URL
292270
, headers :: Array { field :: String, value :: String }
@@ -297,4 +275,9 @@ type AjaxRequest =
297275
, withCredentials :: Boolean
298276
}
299277

300-
foreign import _ajax :: forall e. Fn2 (String -> String -> ResponseHeader) AjaxRequest (AC.EffFnAff (ajax :: AJAX | e) (AffjaxResponse Foreign))
278+
foreign import _ajax
279+
:: forall a
280+
. Fn2
281+
(String -> String -> ResponseHeader)
282+
(AjaxRequest a)
283+
(AC.EffectFnAff (AffjaxResponseT Foreign))

0 commit comments

Comments
 (0)