1
- module Control.Promise (fromAff , toAff , toAff' , toAffE , Promise ()) where
1
+ module Control.Promise
2
+ ( module Control.Promise
3
+ , module Web.Promise
4
+ ) where
2
5
3
6
import Prelude
4
7
5
8
import Control.Alt ((<|>))
6
9
import Control.Monad.Except (runExcept )
7
- import Data.Either (Either (..), either )
10
+ import Data.Either (Either (..), either , hush )
11
+ import Data.Maybe (fromMaybe' )
8
12
import Effect (Effect )
9
13
import Effect.Aff (Aff , makeAff , runAff_ )
10
14
import Effect.Class (liftEffect )
11
15
import Effect.Exception (Error , error )
12
- import Effect.Uncurried (EffectFn1 , mkEffectFn1 )
13
- import Foreign (Foreign , readString , unsafeReadTagged )
14
-
15
- -- | Type of JavaScript Promises (with particular return type)
16
- -- | Effects are not traced in the Promise type, as they form part of the Effect that
17
- -- | results in the promise.
18
- foreign import data Promise :: Type -> Type
19
-
20
- type role Promise representational
21
-
22
- foreign import promise :: forall a b .
23
- ((a -> Effect Unit ) -> (b -> Effect Unit ) -> Effect Unit ) -> Effect (Promise a )
24
- foreign import thenImpl :: forall a b .
25
- Promise a -> (EffectFn1 Foreign b ) -> (EffectFn1 a b ) -> Effect Unit
16
+ import Foreign (readString , unsafeToForeign )
17
+ import Web.Promise (Promise , Rejection )
18
+ import Web.Promise as Promise
19
+ import Web.Promise.Rejection as Rejection
26
20
27
21
-- | Convert an Aff into a Promise.
28
- fromAff :: forall a . Aff a -> Effect (Promise a )
29
- fromAff aff = promise (\succ err -> runAff_ (either err succ) aff)
22
+ fromAff :: forall a . Promise.Flatten a a ⇒ Aff a -> Effect (Promise a )
23
+ fromAff aff = Promise .new (\succ err -> runAff_ (either ( err <<< Rejection .fromError) succ) aff)
30
24
31
- coerce :: Foreign -> Error
32
- coerce fn =
33
- either (\_ -> error " Promise failed, couldn't extract JS Error or String " )
34
- identity
35
- (runExcept ((unsafeReadTagged " Error " fn) <|> ( error <$> readString fn )))
25
+ coerce :: Rejection -> Error
26
+ coerce rej =
27
+ fromMaybe'
28
+ (\_ → error " Promise failed, couldn't extract JS Error or String " )
29
+ ( Rejection .toError rej <|> map error (hush (runExcept ( readString (unsafeToForeign rej)) )))
36
30
37
31
-- | Convert a Promise into an Aff.
38
32
-- | When the promise rejects, we attempt to
@@ -44,12 +38,13 @@ toAff = toAff' coerce
44
38
-- | Convert a Promise into an Aff with custom Error coercion.
45
39
-- | When the promise rejects, we attempt to coerce the error value into an
46
40
-- | actual JavaScript Error object using the provided function.
47
- toAff' :: forall a . (Foreign -> Error ) -> Promise a -> Aff a
48
- toAff' customCoerce p = makeAff
49
- (\cb -> mempty <$ thenImpl
50
- p
51
- (mkEffectFn1 $ cb <<< Left <<< customCoerce)
52
- (mkEffectFn1 $ cb <<< Right ))
41
+ toAff' :: forall a . (Rejection -> Error ) -> Promise a -> Aff a
42
+ toAff' customCoerce p = makeAff \cb →
43
+ mempty <$
44
+ Promise .thenOrCatch
45
+ (\a -> Promise .resolve <$> cb (Right a))
46
+ (\e -> Promise .resolve <$> cb (Left (customCoerce e)))
47
+ p
53
48
54
49
-- | Utility to convert an Effect returning a Promise into an Aff (i.e. the inverse of fromAff)
55
50
toAffE :: forall a . Effect (Promise a ) -> Aff a
0 commit comments