-----------------------------------------------------------------------------
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Miso.Fetch
-- Copyright   :  (C) 2016-2026 David M. Johnson
-- License     :  BSD3-style (see the file LICENSE)
-- Maintainer  :  David M. Johnson <code@dmj.io>
-- Stability   :  experimental
-- Portability :  non-portable
--
-- Interface to the browser's
-- <https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API Fetch API>
-- for making HTTP requests inside Miso's 'Effect' monad.
--
-- Each function accepts a URL, optional request headers, a success callback,
-- and an error callback of the form @'Response' x -> action@. The resulting
-- 'Effect' dispatches the appropriate action into the MVU loop when the
-- response arrives.
--
-- Functions are grouped by HTTP method and body\/response type:
--
-- * __JSON__        — 'getJSON', 'postJSON', 'postJSON'', 'putJSON'
-- * __Text__        — 'getText', 'postText', 'putText'
-- * __Blob__        — 'getBlob', 'postBlob', 'putBlob'
-- * __FormData__    — 'getFormData', 'postFormData', 'putFormData'
-- * __Uint8Array__  — 'getUint8Array', 'postUint8Array', 'putUint8Array'
-- * __ArrayBuffer__ — 'getArrayBuffer', 'postArrayBuffer', 'putArrayBuffer'
-- * __Image__       — 'postImage', 'putImage'
--
-- Use 'getJSON' or 'postJSON' for typical REST calls; use 'postJSON'' when
-- the server also returns a JSON response body.
--
-- Every function above has a synchronous counterpart suffixed with @_@
-- (e.g. 'getJSON_', 'postJSON_') that blocks the calling thread until the
-- browser resolves the underlying promise, returning @'Right' response@ on
-- success or @'Left' response@ on failure instead of dispatching an action.
-- These are best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid
-- blocking the scheduler thread.
--
-- For Servant-style typed client generation, see the miso README.
--
----------------------------------------------------------------------------
module Miso.Fetch
  ( -- ** JSON
    getJSON
  , postJSON
  , postJSON'
  , putJSON
  -- ** Text
  , getText
  , postText
  , putText
  -- ** Blob
  , getBlob
  , postBlob
  , putBlob
  -- ** FormData
  , getFormData
  , postFormData
  , putFormData
  -- ** Uint8Array
  , getUint8Array
  , postUint8Array
  , putUint8Array
  -- ** Image
  , postImage
  , putImage
  -- ** ArrayBuffer
  , getArrayBuffer
  , postArrayBuffer
  , putArrayBuffer
    -- ** Header helpers
  , accept
  , contentType
  , applicationJSON
  , textPlain
  , formData
    -- ** Types
  , Body
  , Response (..)
  , CONTENT_TYPE (..)
    -- ** Synchronous API variants
  , getJSON_
  , postJSON_
  , postJSON'_
  , putJSON_
  , getText_
  , postText_
  , putText_
  , getBlob_
  , postBlob_
  , putBlob_
  , getFormData_
  , postFormData_
  , putFormData_
  , getUint8Array_
  , postUint8Array_
  , putUint8Array_
  , postImage_
  , putImage_
  , getArrayBuffer_
  , postArrayBuffer_
  , putArrayBuffer_
    -- ** Internal
  , fetch
  ) where
----------------------------------------------------------------------------
import           Control.Concurrent (MVar, newEmptyMVar, putMVar, takeMVar)
import           Miso.JSON
import qualified Data.Map.Strict as M
----------------------------------------------------------------------------
import           Miso.DSL (toJSVal, FromJSVal(..), JSVal)
import qualified Miso.FFI.Internal as FFI
import           Miso.Effect (Effect, withSink)
import           Miso.String (MisoString, ms)
import           Miso.Util ((=:))
import           Miso.FFI.Internal (Response(..), Blob, FormData, ArrayBuffer, Uint8Array, Image, fetch, CONTENT_TYPE(..))
----------------------------------------------------------------------------
-- | Retrieve a JSON resource via GET.
--
-- @
-- data Action
--  = FetchGitHub
--  | SetGitHub GitHub
--  | ErrorHandler MisoString
--  deriving (Show, Eq)
--
-- updateModel :: Action -> Effect Model Action
-- updateModel = \case
--   FetchGitHub -> getJSON "https://api.github.com" [] SetGitHub ErrorHandler
--   SetGitHub apiInfo -> info ?= apiInfo
--   ErrorHandler msg -> io_ (consoleError msg)
-- @
--
getJSON
  :: (FromJSON body, FromJSVal error)
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers
  -> (Response body -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
getJSON :: forall body error action context props model.
(FromJSON body, FromJSVal error) =>
MisoString
-> [(MisoString, MisoString)]
-> (Response body -> action)
-> (Response error -> action)
-> Effect context props model action
getJSON MisoString
url [(MisoString, MisoString)]
headers_ Response body -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink ->
    MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response JSVal -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
forall success error.
(FromJSVal success, FromJSVal error) =>
MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response success -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
FFI.fetch MisoString
url MisoString
"GET" Maybe JSVal
forall a. Maybe a
Nothing [(MisoString, MisoString)]
jsonHeaders
      (Sink action -> Response JSVal -> IO ()
forall {b}. (action -> IO b) -> Response JSVal -> IO b
handleJSON Sink action
sink)
      (Sink action
sink Sink action
-> (Response error -> action) -> Response error -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response error -> action
errorful)
      CONTENT_TYPE
JSON -- dmj: expected return type
  where
    jsonHeaders :: [(MisoString, MisoString)]
jsonHeaders = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
    handleJSON :: (action -> IO b) -> Response JSVal -> IO b
handleJSON action -> IO b
sink resp :: Response JSVal
resp@Response {Maybe Int
Maybe MisoString
Map MisoString MisoString
JSVal
status :: Maybe Int
headers :: Map MisoString MisoString
errorMessage :: Maybe MisoString
body :: JSVal
body :: forall body. Response body -> body
errorMessage :: forall body. Response body -> Maybe MisoString
headers :: forall body. Response body -> Map MisoString MisoString
status :: forall body. Response body -> Maybe Int
..} =
      (Value -> Result body) -> Maybe Value -> Maybe (Result body)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Value -> Result body
forall a. FromJSON a => Value -> Result a
fromJSON (Maybe Value -> Maybe (Result body))
-> IO (Maybe Value) -> IO (Maybe (Result body))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JSVal -> IO (Maybe Value)
forall a. FromJSVal a => JSVal -> IO (Maybe a)
fromJSVal JSVal
body IO (Maybe (Result body)) -> (Maybe (Result body) -> IO b) -> IO b
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (Result body)
Nothing -> do
          err <- JSVal -> IO error
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          sink $ errorful $ Response
            { body = err
            , errorMessage = Just "Not a valid JSON object"
            , ..
            }
        Just (Success body
result) ->
          action -> IO b
sink (action -> IO b) -> action -> IO b
forall a b. (a -> b) -> a -> b
$ Response body -> action
successful Response JSVal
resp { body = result }
        Just (Error MisoString
msg) -> do
          err <- JSVal -> IO error
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          sink $ errorful $ Response
            { body = err
            , errorMessage = Just (ms msg)
            , ..
            }
----------------------------------------------------------------------------
-- | Send a POST request with a JSON-encoded body; ignores the response body.
--
-- Sets @Content-Type: application\/json@ automatically. Use 'postJSON'' when
-- you also need to parse a JSON response body.
postJSON
  :: (FromJSVal error, ToJSON body)
  => MisoString
  -- ^ url
  -> body
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
postJSON :: forall error body action context props model.
(FromJSVal error, ToJSON body) =>
MisoString
-> body
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
postJSON MisoString
url body
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- MisoString -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal (body -> MisoString
forall a. ToJSON a => a -> MisoString
encode body
body_)
    FFI.fetch url "POST" (Just bodyVal) jsonHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    jsonHeaders_ :: [(MisoString, MisoString)]
jsonHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
----------------------------------------------------------------------------
-- | Send a POST request with a JSON-encoded body and parse a JSON response.
--
-- Sets both @Content-Type: application\/json@ and @Accept: application\/json@
-- automatically. Use 'postJSON' when the response body is not needed.
postJSON'
  :: (FromJSVal error, ToJSON body, FromJSON return)
  => MisoString
  -- ^ url
  -> body
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response return -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
postJSON' :: forall error body return action context props model.
(FromJSVal error, ToJSON body, FromJSON return) =>
MisoString
-> body
-> [(MisoString, MisoString)]
-> (Response return -> action)
-> (Response error -> action)
-> Effect context props model action
postJSON' MisoString
url body
body_ [(MisoString, MisoString)]
headers_ Response return -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- MisoString -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal (body -> MisoString
forall a. ToJSON a => a -> MisoString
encode body
body_)
    FFI.fetch url "POST" (Just bodyVal) jsonHeaders_
      (handleJSON sink)
      (sink . errorful)
      JSON
  where
    jsonHeaders_ :: [(MisoString, MisoString)]
jsonHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON, MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
    handleJSON :: (action -> IO b) -> Response JSVal -> IO b
handleJSON action -> IO b
sink resp :: Response JSVal
resp@Response {Maybe Int
Maybe MisoString
Map MisoString MisoString
JSVal
body :: forall body. Response body -> body
errorMessage :: forall body. Response body -> Maybe MisoString
headers :: forall body. Response body -> Map MisoString MisoString
status :: forall body. Response body -> Maybe Int
status :: Maybe Int
headers :: Map MisoString MisoString
errorMessage :: Maybe MisoString
body :: JSVal
..} =
      (Value -> Result return) -> Maybe Value -> Maybe (Result return)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Value -> Result return
forall a. FromJSON a => Value -> Result a
fromJSON (Maybe Value -> Maybe (Result return))
-> IO (Maybe Value) -> IO (Maybe (Result return))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JSVal -> IO (Maybe Value)
forall a. FromJSVal a => JSVal -> IO (Maybe a)
fromJSVal JSVal
body IO (Maybe (Result return))
-> (Maybe (Result return) -> IO b) -> IO b
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (Result return)
Nothing -> do
          err <- JSVal -> IO error
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          sink $ errorful $ Response
            { body = err
            , errorMessage = Just "Not a valid JSON object"
            , ..
            }
        Just (Success return
result) ->
          action -> IO b
sink (action -> IO b) -> action -> IO b
forall a b. (a -> b) -> a -> b
$ Response return -> action
successful Response JSVal
resp { body = result }
        Just (Error MisoString
msg) -> do
          err <- JSVal -> IO error
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          sink $ errorful $ Response
            { body = err
            , errorMessage = Just (ms msg)
            , ..
            }
----------------------------------------------------------------------------
-- | Send a PUT request with a JSON-encoded body; ignores the response body.
--
-- Sets @Content-Type: application\/json@ automatically.
putJSON
  :: (FromJSVal error, ToJSON body)
  => MisoString
  -- ^ url
  -> body
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
putJSON :: forall error body action context props model.
(FromJSVal error, ToJSON body) =>
MisoString
-> body
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
putJSON MisoString
url body
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- MisoString -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal (body -> MisoString
forall a. ToJSON a => a -> MisoString
encode body
body_)
    FFI.fetch url "PUT" (Just bodyVal) jsonHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    jsonHeaders_ :: [(MisoString, MisoString)]
jsonHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
----------------------------------------------------------------------------
-- | Retrieve a plain-text resource via GET.
--
-- Sets @Accept: text\/plain@ automatically. The response body is delivered as
-- a 'MisoString'.
getText
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response MisoString -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
getText :: forall error action context props model.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> (Response MisoString -> action)
-> (Response error -> action)
-> Effect context props model action
getText MisoString
url [(MisoString, MisoString)]
headers_ Response MisoString -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink ->
    MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response MisoString -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
forall success error.
(FromJSVal success, FromJSVal error) =>
MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response success -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
FFI.fetch MisoString
url MisoString
"GET" Maybe JSVal
forall a. Maybe a
Nothing [(MisoString, MisoString)]
textHeaders_
      (Sink action
sink Sink action
-> (Response MisoString -> action) -> Response MisoString -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response MisoString -> action
successful)
      (Sink action
sink Sink action
-> (Response error -> action) -> Response error -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response error -> action
errorful)
      CONTENT_TYPE
TEXT -- dmj: expected return type
  where
    textHeaders_ :: [(MisoString, MisoString)]
textHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
textPlain]
----------------------------------------------------------------------------
-- | Send a POST request with a plain-text body; ignores the response body.
--
-- Sets @Content-Type: text\/plain@ automatically.
postText
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> MisoString
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
postText :: forall error action context props model.
FromJSVal error =>
MisoString
-> MisoString
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
postText MisoString
url MisoString
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- MisoString -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal (MisoString -> MisoString
forall a. ToJSON a => a -> MisoString
encode MisoString
body_)
    FFI.fetch url "POST" (Just bodyVal) textHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    textHeaders_ :: [(MisoString, MisoString)]
textHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
textPlain]
----------------------------------------------------------------------------
-- | Send a PUT request with a plain-text body; ignores the response body.
--
-- Sets @Content-Type: text\/plain@ automatically.
putText
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> MisoString
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
putText :: forall error action context props model.
FromJSVal error =>
MisoString
-> MisoString
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
putText MisoString
url MisoString
imageBody [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    body_ <- MisoString -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal MisoString
imageBody
    FFI.fetch url "PUT" (Just body_) textHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    textHeaders_ :: [(MisoString, MisoString)]
textHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
textPlain]
----------------------------------------------------------------------------
-- | Retrieve a binary resource as a 'Blob' via GET.
--
-- Sets @Accept: application\/octet-stream@ automatically.
getBlob
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response Blob -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
getBlob :: forall error action context props model.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> (Response Blob -> action)
-> (Response error -> action)
-> Effect context props model action
getBlob MisoString
url [(MisoString, MisoString)]
headers_ Response Blob -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink ->
    MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response Blob -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
forall success error.
(FromJSVal success, FromJSVal error) =>
MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response success -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
FFI.fetch MisoString
url MisoString
"GET" Maybe JSVal
forall a. Maybe a
Nothing [(MisoString, MisoString)]
blobHeaders_
      (Sink action
sink Sink action -> (Response Blob -> action) -> Response Blob -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response Blob -> action
successful)
      (Sink action
sink Sink action
-> (Response error -> action) -> Response error -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response error -> action
errorful)
      CONTENT_TYPE
BLOB -- dmj: expected return type
  where
    blobHeaders_ :: [(MisoString, MisoString)]
blobHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Send a POST request with a 'Blob' body; ignores the response body.
--
-- Sets @Content-Type: application\/octet-stream@ automatically.
postBlob
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Blob
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
postBlob :: forall error action context props model.
FromJSVal error =>
MisoString
-> Blob
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
postBlob MisoString
url Blob
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- Blob -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal Blob
body_
    FFI.fetch url "POST" (Just bodyVal) blobHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    blobHeaders_ :: [(MisoString, MisoString)]
blobHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Send a PUT request with a 'Blob' body; ignores the response body.
--
-- Sets @Content-Type: application\/octet-stream@ automatically.
putBlob
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Blob
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
putBlob :: forall error action context props model.
FromJSVal error =>
MisoString
-> Blob
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
putBlob MisoString
url Blob
imageBody [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    body_ <- Blob -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal Blob
imageBody
    FFI.fetch url "PUT" (Just body_) blobHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    blobHeaders_ :: [(MisoString, MisoString)]
blobHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Retrieve a multipart resource as 'FormData' via GET.
--
-- Sets @Accept: multipart\/form-data@ automatically.
getFormData
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response FormData -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
getFormData :: forall error action context props model.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> (Response FormData -> action)
-> (Response error -> action)
-> Effect context props model action
getFormData MisoString
url [(MisoString, MisoString)]
headers_ Response FormData -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink ->
    MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response FormData -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
forall success error.
(FromJSVal success, FromJSVal error) =>
MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response success -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
FFI.fetch MisoString
url MisoString
"GET" Maybe JSVal
forall a. Maybe a
Nothing [(MisoString, MisoString)]
formDataHeaders_
      (Sink action
sink Sink action
-> (Response FormData -> action) -> Response FormData -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response FormData -> action
successful)
      (Sink action
sink Sink action
-> (Response error -> action) -> Response error -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response error -> action
errorful)
      CONTENT_TYPE
FORM_DATA -- dmj: expected return type
  where
    formDataHeaders_ :: [(MisoString, MisoString)]
formDataHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
formData]
----------------------------------------------------------------------------
-- | Send a POST request with a 'FormData' body; ignores the response body.
--
-- Sets @Content-Type: multipart\/form-data@ automatically.
postFormData
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> FormData
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action 
postFormData :: forall error action context props model.
FromJSVal error =>
MisoString
-> FormData
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
postFormData MisoString
url FormData
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- FormData -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal FormData
body_
    FFI.fetch url "POST" (Just bodyVal) formDataHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    formDataHeaders_ :: [(MisoString, MisoString)]
formDataHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
formData]
----------------------------------------------------------------------------
-- | Send a PUT request with a 'FormData' body; ignores the response body.
--
-- Sets @Content-Type: multipart\/form-data@ automatically.
putFormData
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> FormData
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error  -> action)
  -- ^ errorful callback
  -> Effect context props model action
putFormData :: forall error action context props model.
FromJSVal error =>
MisoString
-> FormData
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
putFormData MisoString
url FormData
imageBody [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    body_ <- FormData -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal FormData
imageBody
    FFI.fetch url "PUT" (Just body_) formDataHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    formDataHeaders_ :: [(MisoString, MisoString)]
formDataHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
formData]
----------------------------------------------------------------------------
-- | Retrieve a binary resource as an 'ArrayBuffer' via GET.
--
-- Sets @Accept: application\/octet-stream@ automatically.
getArrayBuffer
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response ArrayBuffer -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
getArrayBuffer :: forall error action context props model.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> (Response ArrayBuffer -> action)
-> (Response error -> action)
-> Effect context props model action
getArrayBuffer MisoString
url [(MisoString, MisoString)]
headers_ Response ArrayBuffer -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink ->
    MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response ArrayBuffer -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
forall success error.
(FromJSVal success, FromJSVal error) =>
MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response success -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
FFI.fetch MisoString
url MisoString
"GET" Maybe JSVal
forall a. Maybe a
Nothing [(MisoString, MisoString)]
arrayBufferHeaders_
      (Sink action
sink Sink action
-> (Response ArrayBuffer -> action)
-> Response ArrayBuffer
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response ArrayBuffer -> action
successful)
      (Sink action
sink Sink action
-> (Response error -> action) -> Response error -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response error -> action
errorful)
      CONTENT_TYPE
ARRAY_BUFFER -- dmj: expected return type
  where
    arrayBufferHeaders_ :: [(MisoString, MisoString)]
arrayBufferHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Send a POST request with an 'ArrayBuffer' body; ignores the response body.
--
-- Sets @Content-Type: application\/octet-stream@ automatically.
postArrayBuffer
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> ArrayBuffer
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
postArrayBuffer :: forall error action context props model.
FromJSVal error =>
MisoString
-> ArrayBuffer
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
postArrayBuffer MisoString
url ArrayBuffer
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- ArrayBuffer -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal ArrayBuffer
body_
    FFI.fetch url "POST" (Just bodyVal) arrayBufferHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    arrayBufferHeaders_ :: [(MisoString, MisoString)]
arrayBufferHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Send a PUT request with an 'ArrayBuffer' body; ignores the response body.
--
-- Sets @Content-Type: application\/octet-stream@ automatically.
putArrayBuffer
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> ArrayBuffer
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
putArrayBuffer :: forall error action context props model.
FromJSVal error =>
MisoString
-> ArrayBuffer
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
putArrayBuffer MisoString
url ArrayBuffer
arrayBuffer_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    body_ <- ArrayBuffer -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal ArrayBuffer
arrayBuffer_
    FFI.fetch url "PUT" (Just body_) arrayBufferHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    arrayBufferHeaders_ :: [(MisoString, MisoString)]
arrayBufferHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Retrieve a binary resource as a 'Uint8Array' via GET.
--
-- Sets @Accept: application\/octet-stream@ automatically.
getUint8Array
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response Uint8Array -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
getUint8Array :: forall error action context props model.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> (Response Uint8Array -> action)
-> (Response error -> action)
-> Effect context props model action
getUint8Array MisoString
url [(MisoString, MisoString)]
headers_ Response Uint8Array -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink ->
    MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response Uint8Array -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
forall success error.
(FromJSVal success, FromJSVal error) =>
MisoString
-> MisoString
-> Maybe JSVal
-> [(MisoString, MisoString)]
-> (Response success -> IO ())
-> (Response error -> IO ())
-> CONTENT_TYPE
-> IO ()
FFI.fetch MisoString
url MisoString
"GET" Maybe JSVal
forall a. Maybe a
Nothing [(MisoString, MisoString)]
uint8ArrayHeaders_
      (Sink action
sink Sink action
-> (Response Uint8Array -> action) -> Response Uint8Array -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response Uint8Array -> action
successful)
      (Sink action
sink Sink action
-> (Response error -> action) -> Response error -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Response error -> action
errorful)
      CONTENT_TYPE
BYTES -- expected return type
  where
    uint8ArrayHeaders_ :: [(MisoString, MisoString)]
uint8ArrayHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Send a POST request with a 'Uint8Array' body; ignores the response body.
--
-- Sets @Content-Type: application\/octet-stream@ automatically.
postUint8Array
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Uint8Array
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
postUint8Array :: forall error action context props model.
FromJSVal error =>
MisoString
-> Uint8Array
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
postUint8Array MisoString
url Uint8Array
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- Uint8Array -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal Uint8Array
body_
    FFI.fetch url "POST" (Just bodyVal) uint8ArrayHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    uint8ArrayHeaders_ :: [(MisoString, MisoString)]
uint8ArrayHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Send a PUT request with a 'Uint8Array' body; ignores the response body.
--
-- Sets @Content-Type: application\/octet-stream@ automatically.
putUint8Array
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Uint8Array
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
putUint8Array :: forall error action context props model.
FromJSVal error =>
MisoString
-> Uint8Array
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
putUint8Array MisoString
url Uint8Array
uint8Array_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    body_ <- Uint8Array -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal Uint8Array
uint8Array_
    FFI.fetch url "PUT" (Just body_) uint8ArrayHeaders_
      (sink . successful)
      (sink . errorful)
      NONE
  where
    uint8ArrayHeaders_ :: [(MisoString, MisoString)]
uint8ArrayHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
----------------------------------------------------------------------------
-- | Send a POST request with an 'Image' body; ignores the response body.
postImage
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Image
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
postImage :: forall error action context props model.
FromJSVal error =>
MisoString
-> Image
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
postImage MisoString
url Image
body_ [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    bodyVal <- Image -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal Image
body_
    FFI.fetch url "POST" (Just bodyVal) headers_
      (sink . successful)
      (sink . errorful)
      NONE
----------------------------------------------------------------------------
-- | Send a PUT request with an 'Image' body; ignores the response body.
putImage
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Image
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> (Response () -> action)
  -- ^ successful callback
  -> (Response error -> action)
  -- ^ errorful callback
  -> Effect context props model action
putImage :: forall error action context props model.
FromJSVal error =>
MisoString
-> Image
-> [(MisoString, MisoString)]
-> (Response () -> action)
-> (Response error -> action)
-> Effect context props model action
putImage MisoString
url Image
imageBody [(MisoString, MisoString)]
headers_ Response () -> action
successful Response error -> action
errorful =
  (Sink action -> IO ()) -> Effect context props model action
forall action context props model.
(Sink action -> IO ()) -> Effect context props model action
withSink ((Sink action -> IO ()) -> Effect context props model action)
-> (Sink action -> IO ()) -> Effect context props model action
forall a b. (a -> b) -> a -> b
$ \Sink action
sink -> do
    body_ <- Image -> IO JSVal
forall a. ToJSVal a => a -> IO JSVal
toJSVal Image
imageBody
    FFI.fetch url "PUT" (Just body_) headers_
      (sink . successful)
      (sink . errorful)
      NONE
----------------------------------------------------------------------------
-- | Type synonym for a raw JavaScript request body.
type Body = JSVal
----------------------------------------------------------------------------
-- | HTTP header name @\"Accept\"@.
-- Use with '=:' to build request headers, e.g. @accept =: applicationJSON@.
accept :: MisoString
accept :: MisoString
accept = MisoString
"Accept"
----------------------------------------------------------------------------
-- | HTTP header name @\"Content-Type\"@.
-- Use with '=:' to build request headers, e.g. @contentType =: textPlain@.
contentType :: MisoString
contentType :: MisoString
contentType = MisoString
"Content-Type"
----------------------------------------------------------------------------
-- | MIME type @\"application\/json\"@.
applicationJSON :: MisoString
applicationJSON :: MisoString
applicationJSON = MisoString
"application/json"
----------------------------------------------------------------------------
-- | MIME type @\"text\/plain\"@.
textPlain :: MisoString
textPlain :: MisoString
textPlain = MisoString
"text/plain"
----------------------------------------------------------------------------
-- | MIME type @\"application\/octet-stream\"@. Used for binary payloads.
octetStream :: MisoString
octetStream :: MisoString
octetStream = MisoString
"application/octet-stream"
----------------------------------------------------------------------------
-- | MIME type @\"multipart\/form-data\"@.
formData :: MisoString
formData :: MisoString
formData = MisoString
"multipart/form-data"
----------------------------------------------------------------------------
-- | Merge two header lists, giving precedence to the first (user-supplied) list.
--
-- Duplicate keys in @contentSpecific@ are dropped when the same key already
-- appears in @userDefined@, allowing callers to override the library's default
-- @Content-Type@ and @Accept@ headers.
biasHeaders :: Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders :: forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(k, a)]
userDefined [(k, a)]
contentSpecific
  = Map k a -> [(k, a)]
forall k a. Map k a -> [(k, a)]
M.toList
  (Map k a -> [(k, a)]) -> Map k a -> [(k, a)]
forall a b. (a -> b) -> a -> b
$ [(k, a)] -> Map k a
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(k, a)]
userDefined Map k a -> Map k a -> Map k a
forall a. Semigroup a => a -> a -> a
<> [(k, a)] -> Map k a
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(k, a)]
contentSpecific
----------------------------------------------------------------------------
-- | Synchronous API variant of 'getJSON'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
getJSON_
  :: (FromJSON body, FromJSVal error)
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers
  -> IO (Either (Response error) (Response body))
getJSON_ :: forall body error.
(FromJSON body, FromJSVal error) =>
MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response body))
getJSON_ MisoString
url [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response body)))
forall a. IO (MVar a)
forall {error} {body}.
IO (MVar (Either (Response error) (Response body)))
newEmptyMVar :: IO (MVar (Either (Response error) (Response body)))
  FFI.fetch url "GET" Nothing jsonHeaders
    (handleJSON mvar)
    (putMVar mvar . Left)
    JSON
  takeMVar mvar
  where
    jsonHeaders :: [(MisoString, MisoString)]
jsonHeaders = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
    handleJSON :: MVar (Either (Response body) (Response body))
-> Response JSVal -> IO ()
handleJSON MVar (Either (Response body) (Response body))
mvar resp :: Response JSVal
resp@Response {Maybe Int
Maybe MisoString
Map MisoString MisoString
JSVal
body :: forall body. Response body -> body
errorMessage :: forall body. Response body -> Maybe MisoString
headers :: forall body. Response body -> Map MisoString MisoString
status :: forall body. Response body -> Maybe Int
status :: Maybe Int
headers :: Map MisoString MisoString
errorMessage :: Maybe MisoString
body :: JSVal
..} =
      (Value -> Result body) -> Maybe Value -> Maybe (Result body)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Value -> Result body
forall a. FromJSON a => Value -> Result a
fromJSON (Maybe Value -> Maybe (Result body))
-> IO (Maybe Value) -> IO (Maybe (Result body))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JSVal -> IO (Maybe Value)
forall a. FromJSVal a => JSVal -> IO (Maybe a)
fromJSVal JSVal
body IO (Maybe (Result body)) -> (Maybe (Result body) -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (Result body)
Nothing -> do
          err <- JSVal -> IO body
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          putMVar mvar $ Left $ Response
            { body = err
            , errorMessage = Just "Not a valid JSON object"
            , ..
            }
        Just (Success body
result) ->
          MVar (Either (Response body) (Response body))
-> Either (Response body) (Response body) -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Either (Response body) (Response body))
mvar (Either (Response body) (Response body) -> IO ())
-> Either (Response body) (Response body) -> IO ()
forall a b. (a -> b) -> a -> b
$ Response body -> Either (Response body) (Response body)
forall a b. b -> Either a b
Right Response JSVal
resp { body = result }
        Just (Error MisoString
msg) -> do
          err <- JSVal -> IO body
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          putMVar mvar $ Left $ Response
            { body = err
            , errorMessage = Just (ms msg)
            , ..
            }
{-# INLINE getJSON_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postJSON'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postJSON_
  :: (FromJSVal error, ToJSON body)
  => MisoString
  -- ^ url
  -> body
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
postJSON_ :: forall error body.
(FromJSVal error, ToJSON body) =>
MisoString
-> body
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
postJSON_ MisoString
url body
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal (encode body_)
  FFI.fetch url "POST" (Just bodyVal) jsonHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    jsonHeaders_ :: [(MisoString, MisoString)]
jsonHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
{-# INLINE postJSON_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postJSON''.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postJSON'_
  :: (FromJSVal error, ToJSON body, FromJSON return)
  => MisoString
  -- ^ url
  -> body
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response return))
postJSON'_ :: forall error body return.
(FromJSVal error, ToJSON body, FromJSON return) =>
MisoString
-> body
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response return))
postJSON'_ MisoString
url body
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response return)))
forall a. IO (MVar a)
forall {error} {body}.
IO (MVar (Either (Response error) (Response body)))
newEmptyMVar :: IO (MVar (Either (Response error) (Response return)))
  bodyVal <- toJSVal (encode body_)
  FFI.fetch url "POST" (Just bodyVal) jsonHeaders_
    (handleJSON mvar)
    (putMVar mvar . Left)
    JSON
  takeMVar mvar
  where
    jsonHeaders_ :: [(MisoString, MisoString)]
jsonHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON, MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
    handleJSON :: MVar (Either (Response body) (Response body))
-> Response JSVal -> IO ()
handleJSON MVar (Either (Response body) (Response body))
mvar resp :: Response JSVal
resp@Response {Maybe Int
Maybe MisoString
Map MisoString MisoString
JSVal
body :: forall body. Response body -> body
errorMessage :: forall body. Response body -> Maybe MisoString
headers :: forall body. Response body -> Map MisoString MisoString
status :: forall body. Response body -> Maybe Int
status :: Maybe Int
headers :: Map MisoString MisoString
errorMessage :: Maybe MisoString
body :: JSVal
..} =
      (Value -> Result body) -> Maybe Value -> Maybe (Result body)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Value -> Result body
forall a. FromJSON a => Value -> Result a
fromJSON (Maybe Value -> Maybe (Result body))
-> IO (Maybe Value) -> IO (Maybe (Result body))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JSVal -> IO (Maybe Value)
forall a. FromJSVal a => JSVal -> IO (Maybe a)
fromJSVal JSVal
body IO (Maybe (Result body)) -> (Maybe (Result body) -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe (Result body)
Nothing -> do
          err <- JSVal -> IO body
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          putMVar mvar $ Left $ Response
            { body = err
            , errorMessage = Just "Not a valid JSON object"
            , ..
            }
        Just (Success body
result) ->
          MVar (Either (Response body) (Response body))
-> Either (Response body) (Response body) -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Either (Response body) (Response body))
mvar (Either (Response body) (Response body) -> IO ())
-> Either (Response body) (Response body) -> IO ()
forall a b. (a -> b) -> a -> b
$ Response body -> Either (Response body) (Response body)
forall a b. b -> Either a b
Right Response JSVal
resp { body = result }
        Just (Error MisoString
msg) -> do
          err <- JSVal -> IO body
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked JSVal
body
          putMVar mvar $ Left $ Response
            { body = err
            , errorMessage = Just (ms msg)
            , ..
            }
{-# INLINE postJSON'_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'putJSON'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
putJSON_
  :: (FromJSVal error, ToJSON body)
  => MisoString
  -- ^ url
  -> body
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
putJSON_ :: forall error body.
(FromJSVal error, ToJSON body) =>
MisoString
-> body
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
putJSON_ MisoString
url body
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal (encode body_)
  FFI.fetch url "PUT" (Just bodyVal) jsonHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    jsonHeaders_ :: [(MisoString, MisoString)]
jsonHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
applicationJSON]
{-# INLINE putJSON_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'getText'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
getText_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response MisoString))
getText_ :: forall error.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response MisoString))
getText_ MisoString
url [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response MisoString)))
forall a. IO (MVar a)
forall {error}.
IO (MVar (Either (Response error) (Response MisoString)))
newEmptyMVar :: IO (MVar (Either (Response error) (Response MisoString)))
  FFI.fetch url "GET" Nothing textHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    TEXT
  takeMVar mvar
  where
    textHeaders_ :: [(MisoString, MisoString)]
textHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
textPlain]
{-# INLINE getText_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postText'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postText_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> MisoString
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
postText_ :: forall error.
FromJSVal error =>
MisoString
-> MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
postText_ MisoString
url MisoString
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal (encode body_)
  FFI.fetch url "POST" (Just bodyVal) textHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    textHeaders_ :: [(MisoString, MisoString)]
textHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
textPlain]
{-# INLINE postText_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'putText'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
putText_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> MisoString
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
putText_ :: forall error.
FromJSVal error =>
MisoString
-> MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
putText_ MisoString
url MisoString
imageBody [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  body_ <- toJSVal imageBody
  FFI.fetch url "PUT" (Just body_) textHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    textHeaders_ :: [(MisoString, MisoString)]
textHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
textPlain]
{-# INLINE putText_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'getBlob'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
getBlob_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response Blob))
getBlob_ :: forall error.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response Blob))
getBlob_ MisoString
url [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response Blob)))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response Blob)))
newEmptyMVar :: IO (MVar (Either (Response error) (Response Blob)))
  FFI.fetch url "GET" Nothing blobHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    BLOB
  takeMVar mvar
  where
    blobHeaders_ :: [(MisoString, MisoString)]
blobHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE getBlob_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postBlob'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postBlob_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Blob
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
postBlob_ :: forall error.
FromJSVal error =>
MisoString
-> Blob
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
postBlob_ MisoString
url Blob
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal body_
  FFI.fetch url "POST" (Just bodyVal) blobHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    blobHeaders_ :: [(MisoString, MisoString)]
blobHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE postBlob_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'putBlob'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
putBlob_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Blob
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
putBlob_ :: forall error.
FromJSVal error =>
MisoString
-> Blob
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
putBlob_ MisoString
url Blob
imageBody [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  body_ <- toJSVal imageBody
  FFI.fetch url "PUT" (Just body_) blobHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    blobHeaders_ :: [(MisoString, MisoString)]
blobHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE putBlob_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'getFormData'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
getFormData_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response FormData))
getFormData_ :: forall error.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response FormData))
getFormData_ MisoString
url [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response FormData)))
forall a. IO (MVar a)
forall {error}.
IO (MVar (Either (Response error) (Response FormData)))
newEmptyMVar :: IO (MVar (Either (Response error) (Response FormData)))
  FFI.fetch url "GET" Nothing formDataHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    FORM_DATA
  takeMVar mvar
  where
    formDataHeaders_ :: [(MisoString, MisoString)]
formDataHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
formData]
{-# INLINE getFormData_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postFormData'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postFormData_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> FormData
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
postFormData_ :: forall error.
FromJSVal error =>
MisoString
-> FormData
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
postFormData_ MisoString
url FormData
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal body_
  FFI.fetch url "POST" (Just bodyVal) formDataHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    formDataHeaders_ :: [(MisoString, MisoString)]
formDataHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
formData]
{-# INLINE postFormData_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'putFormData'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
putFormData_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> FormData
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
putFormData_ :: forall error.
FromJSVal error =>
MisoString
-> FormData
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
putFormData_ MisoString
url FormData
imageBody [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  body_ <- toJSVal imageBody
  FFI.fetch url "PUT" (Just body_) formDataHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    formDataHeaders_ :: [(MisoString, MisoString)]
formDataHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
formData]
{-# INLINE putFormData_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'getArrayBuffer'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
getArrayBuffer_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ArrayBuffer))
getArrayBuffer_ :: forall error.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ArrayBuffer))
getArrayBuffer_ MisoString
url [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ArrayBuffer)))
forall a. IO (MVar a)
forall {error}.
IO (MVar (Either (Response error) (Response ArrayBuffer)))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ArrayBuffer)))
  FFI.fetch url "GET" Nothing arrayBufferHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    ARRAY_BUFFER
  takeMVar mvar
  where
    arrayBufferHeaders_ :: [(MisoString, MisoString)]
arrayBufferHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE getArrayBuffer_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postArrayBuffer'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postArrayBuffer_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> ArrayBuffer
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
postArrayBuffer_ :: forall error.
FromJSVal error =>
MisoString
-> ArrayBuffer
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
postArrayBuffer_ MisoString
url ArrayBuffer
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal body_
  FFI.fetch url "POST" (Just bodyVal) arrayBufferHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    arrayBufferHeaders_ :: [(MisoString, MisoString)]
arrayBufferHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE postArrayBuffer_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'putArrayBuffer'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
putArrayBuffer_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> ArrayBuffer
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
putArrayBuffer_ :: forall error.
FromJSVal error =>
MisoString
-> ArrayBuffer
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
putArrayBuffer_ MisoString
url ArrayBuffer
arrayBuffer_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  body_ <- toJSVal arrayBuffer_
  FFI.fetch url "PUT" (Just body_) arrayBufferHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    arrayBufferHeaders_ :: [(MisoString, MisoString)]
arrayBufferHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE putArrayBuffer_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'getUint8Array'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
getUint8Array_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response Uint8Array))
getUint8Array_ :: forall error.
FromJSVal error =>
MisoString
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response Uint8Array))
getUint8Array_ MisoString
url [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response Uint8Array)))
forall a. IO (MVar a)
forall {error}.
IO (MVar (Either (Response error) (Response Uint8Array)))
newEmptyMVar :: IO (MVar (Either (Response error) (Response Uint8Array)))
  FFI.fetch url "GET" Nothing uint8ArrayHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    BYTES
  takeMVar mvar
  where
    uint8ArrayHeaders_ :: [(MisoString, MisoString)]
uint8ArrayHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
accept MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE getUint8Array_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postUint8Array'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postUint8Array_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Uint8Array
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
postUint8Array_ :: forall error.
FromJSVal error =>
MisoString
-> Uint8Array
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
postUint8Array_ MisoString
url Uint8Array
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal body_
  FFI.fetch url "POST" (Just bodyVal) uint8ArrayHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    uint8ArrayHeaders_ :: [(MisoString, MisoString)]
uint8ArrayHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE postUint8Array_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'putUint8Array'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
putUint8Array_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Uint8Array
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
putUint8Array_ :: forall error.
FromJSVal error =>
MisoString
-> Uint8Array
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
putUint8Array_ MisoString
url Uint8Array
uint8Array_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  body_ <- toJSVal uint8Array_
  FFI.fetch url "PUT" (Just body_) uint8ArrayHeaders_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
  where
    uint8ArrayHeaders_ :: [(MisoString, MisoString)]
uint8ArrayHeaders_ = [(MisoString, MisoString)]
-> [(MisoString, MisoString)] -> [(MisoString, MisoString)]
forall k a. Ord k => [(k, a)] -> [(k, a)] -> [(k, a)]
biasHeaders [(MisoString, MisoString)]
headers_ [MisoString
contentType MisoString -> MisoString -> (MisoString, MisoString)
forall k v. k -> v -> (k, v)
=: MisoString
octetStream]
{-# INLINE putUint8Array_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'postImage'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
postImage_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Image
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
postImage_ :: forall error.
FromJSVal error =>
MisoString
-> Image
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
postImage_ MisoString
url Image
body_ [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  bodyVal <- toJSVal body_
  FFI.fetch url "POST" (Just bodyVal) headers_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
{-# INLINE postImage_ #-}
----------------------------------------------------------------------------
-- | Synchronous API variant of 'putImage'.
--
-- Blocks the calling thread until the browser resolves the promise, returning
-- @'Right' response@ on success or @'Left' response@ on failure.
--
-- __Note:__ best used with 'Miso.Effect.io' or 'Miso.Effect.io_', to avoid blocking the scheduler thread.
putImage_
  :: FromJSVal error
  => MisoString
  -- ^ url
  -> Image
  -- ^ Body
  -> [(MisoString, MisoString)]
  -- ^ headers_
  -> IO (Either (Response error) (Response ()))
putImage_ :: forall error.
FromJSVal error =>
MisoString
-> Image
-> [(MisoString, MisoString)]
-> IO (Either (Response error) (Response ()))
putImage_ MisoString
url Image
imageBody [(MisoString, MisoString)]
headers_ = do
  mvar <- IO (MVar (Either (Response error) (Response ())))
forall a. IO (MVar a)
forall {error}. IO (MVar (Either (Response error) (Response ())))
newEmptyMVar :: IO (MVar (Either (Response error) (Response ())))
  body_ <- toJSVal imageBody
  FFI.fetch url "PUT" (Just body_) headers_
    (putMVar mvar . Right)
    (putMVar mvar . Left)
    NONE
  takeMVar mvar
{-# INLINE putImage_ #-}
----------------------------------------------------------------------------