@@ -58,8 +58,14 @@ module Language.Javascript.JSaddle.Types (
58 -- * Debugging
58 -- * Debugging
59 , JSadddleHasCallStack
59 , JSadddleHasCallStack
61− -- * JavaScript Context Commands
61+ -- * Sync JSM
62#ifndef ghcjs_HOST_OS
65#ifndef ghcjs_HOST_OS
68+ -- * JavaScript Context Commands
63 , MutabilityType(..)
69 , MutabilityType(..)
65 , Immutable
71 , Immutable
@@ -89,14 +95,14 @@ import GHCJS.Nullable (Nullable(..))
89import GHCJS.Prim.Internal (JSVal(..), JSValueRef)
95import GHCJS.Prim.Internal (JSVal(..), JSValueRef)
90import Data.JSString.Internal.Type (JSString(..))
96import Data.JSString.Internal.Type (JSString(..))
91import Control.DeepSeq (NFData(..))
97import Control.DeepSeq (NFData(..))
92−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
98+import Control.Monad.Catch (MonadThrow, MonadCatch(..), MonadMask(..))
93import Control.Monad.Trans.Cont (ContT(..))
99import Control.Monad.Trans.Cont (ContT(..))
94import Control.Monad.Trans.Error (Error(..), ErrorT(..))
100import Control.Monad.Trans.Error (Error(..), ErrorT(..))
95import Control.Monad.Trans.Except (ExceptT(..))
101import Control.Monad.Trans.Except (ExceptT(..))
96import Control.Monad.Trans.Identity (IdentityT(..))
102import Control.Monad.Trans.Identity (IdentityT(..))
97import Control.Monad.Trans.List (ListT(..))
103import Control.Monad.Trans.List (ListT(..))
98import Control.Monad.Trans.Maybe (MaybeT(..))
104import Control.Monad.Trans.Maybe (MaybeT(..))
99−import Control.Monad.Trans.Reader (ReaderT(..))
105+import Control.Monad.Trans.Reader (ReaderT(..), ask)
100import Control.Monad.Trans.RWS.Lazy as Lazy (RWST(..))
106import Control.Monad.Trans.RWS.Lazy as Lazy (RWST(..))
101import Control.Monad.Trans.RWS.Strict as Strict (RWST(..))
107import Control.Monad.Trans.RWS.Strict as Strict (RWST(..))
102import Control.Monad.Trans.State.Lazy as Lazy (StateT(..))
108import Control.Monad.Trans.State.Lazy as Lazy (StateT(..))
@@ -158,9 +164,48 @@ data JSContextRef = JSContextRef {
158type JSM = IO
164type JSM = IO
160newtype JSM a = JSM { unJSM :: ReaderT JSContextRef IO a }
166newtype JSM a = JSM { unJSM :: ReaderT JSContextRef IO a }
161− deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadCatch, MonadThrow, MonadMask)
167+ deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadThrow)
169+instance MonadCatch JSM where
170+ t `catch` c = JSM (unJSM (syncAfter t) `catch` \e -> unJSM (c e))
172+instance MonadMask JSM where
173+ mask a = JSM $ mask $ \unmask -> unJSM (a $ q unmask)
174+ where q :: (ReaderT JSContextRef IO a -> ReaderT JSContextRef IO a) -> JSM a -> JSM a
175+ q unmask (JSM b) = syncAfter . JSM $ unmask b
176+ uninterruptibleMask a =
177+ JSM $ uninterruptibleMask $ \unmask -> unJSM (a $ q unmask)
178+ where q :: (ReaderT JSContextRef IO a -> ReaderT JSContextRef IO a) -> JSM a -> JSM a
179+ q unmask (JSM b) = syncAfter . JSM $ unmask b
182+-- | Forces execution of pending asyncronous code
185+syncPoint = return ()
188+ SyncResult <- sendCommand Sync
192+-- | Forces execution of pending asyncronous code after performing `f`
193+syncAfter :: JSM a -> JSM a
203+#ifndef ghcjs_HOST_OS
204+sendCommand :: Command -> JSM Result
206+ s <- doSendCommand <$> JSM ask
165-- | Type we can give to functions that are pure when using ghcjs, but
210-- | Type we can give to functions that are pure when using ghcjs, but
166-- live in JSM when using jsaddle.
211-- live in JSM when using jsaddle.