| 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 |
| Safe Haskell | None |
| Language | Haskell2010 |
Miso.DSL
Description
Overview
Miso.DSL is the low-level JavaScript interop layer for miso. It provides the marshaling typeclasses, JS value types, and combinators needed to call browser APIs and exchange data with JavaScript from Haskell.
Most miso users never import this module directly — higher-level modules (Miso.FFI, Miso.Canvas, Miso.Fetch, etc.) build on top of it. Import it directly when writing custom FFI bindings or inline JS.
Marshaling
Two typeclasses handle the Haskell ↔ JavaScript boundary:
ToJSVal— converts a Haskell value into aJSVal. Instances exist for all primitive types, lists, tuples (up to 6),Maybe, andMapMisoString. Product record types can deriveToJSValviaGHC.Generics(sum types are not supported).FromJSVal— parses aJSValback into Haskell, returning(MaybeaNothingon type mismatch or missing field). UsefromJSValUncheckedwhen the shape is guaranteed by the caller. Product record types can deriveFromJSValviaGHC.Generics.
Two auxiliary classes support the calling convention:
ToArgs— marshals a Haskell value to a[argument list. Tuples up to arity 6 automatically produce the correct positional list.JSVal]ToObject— promotes a value to a JSObjectfor use as thethisreceiver in method calls.
Accessing the global scope
-- Read a global variable x <-jsg"innerWidth" -- globalThis.innerWidth -- Call a global functionjsg0"requestAnimationFrame" -- no argsjsg1"parseInt" ("42" ::MisoString) -- one argjsgf"encodeURIComponent" args -- arbitrary ToArgs
Property access and method calls
obj!"name" -- get obj.name :: IO JSVal obj!!3 -- get obj[3] :: IO JSVal obj#"push" [val] -- call obj.push(val) :: IO JSValsetFieldobj "x" 10 -- obj.x = 10getProp"x" obj -- obj.xsetProp"x" 10 obj -- obj.x = 10
Object creation
o <-create-- new empty object {} o <-createWith[("x", 1), ("y", 2)] -- { x: 1, y: 2 } v <-newconstructor args -- new Constructor(...args)
Callbacks
Wrap a Haskell IO action as a JS function. Variants ending in '
return the JSVal of the callback's return value.
cb 'syncCallback' action -- () - () cb1 'syncCallback1' (\x - …) -- (x) -> () cb2 'syncCallback2' (\x y - …) -- (x, y) -> ()
Always free callbacks when they are no longer needed to avoid leaks:
freeFunction cb
See also
- Miso.FFI — higher-level browser API wrappers built on this module
- Miso.FFI.QQ — the
[js| … |]quasi-quoter for inline JavaScript - Miso.Canvas — canvas 2D API using
ToArgsandToJSVal
Synopsis
- class ToJSVal a where
- class GToJSVal (f :: Type -> Type) where
- class FromJSVal a where
- class GFromJSVal (f :: Type -> Type) where
- gFromJSVal :: Object -> IO (Maybe (f a))
- class ToArgs args where
- class ToObject a where
- data JSVal
- newtype Object = Object {}
- newtype Function = Function {
- unFunction :: JSVal
- jsg :: MisoString -> IO JSVal
- jsg0 :: MisoString -> IO JSVal
- jsg1 :: ToJSVal arg => MisoString -> arg -> IO JSVal
- jsg2 :: (ToJSVal arg1, ToJSVal arg2) => MisoString -> arg1 -> arg2 -> IO JSVal
- jsg3 :: (ToJSVal arg1, ToJSVal arg2, ToJSVal arg3) => MisoString -> arg1 -> arg2 -> arg3 -> IO JSVal
- jsg4 :: (ToJSVal arg1, ToJSVal arg2, ToJSVal arg3, ToJSVal arg4) => MisoString -> arg1 -> arg2 -> arg3 -> arg4 -> IO JSVal
- jsg5 :: (ToJSVal arg1, ToJSVal arg2, ToJSVal arg3, ToJSVal arg4, ToJSVal arg5) => MisoString -> arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> IO JSVal
- jsgf :: ToArgs args => MisoString -> args -> IO JSVal
- global :: JSVal
- (#) :: (ToObject object, ToArgs args) => object -> MisoString -> args -> IO JSVal
- setField :: (ToObject o, ToJSVal v) => o -> MisoString -> v -> IO ()
- (<##) :: (ToObject o, ToJSVal v) => o -> Int -> v -> IO ()
- (!) :: ToObject o => o -> MisoString -> IO JSVal
- listProps :: Object -> IO [MisoString]
- call :: (ToObject obj, ToObject this, ToArgs args) => obj -> this -> args -> IO JSVal
- new :: (ToObject constructor, ToArgs args) => constructor -> args -> IO JSVal
- create :: IO Object
- createWith :: ToJSVal val => [(MisoString, val)] -> IO Object
- setProp :: ToJSVal val => MisoString -> val -> Object -> IO ()
- getProp :: ToObject o => MisoString -> o -> IO JSVal
- eval :: MisoString -> IO JSVal
- now_ffi :: IO Double
- requestAnimationFrame :: JSVal -> IO Int
- cancelAnimationFrame :: Int -> IO ()
- freeFunction :: Function -> IO ()
- freeJSVal :: JSVal -> IO ()
- (!!) :: ToObject object => object -> Int -> IO JSVal
- isUndefined :: ToJSVal val => val -> IO Bool
- isNull :: ToJSVal val => val -> IO Bool
- jsNull :: JSVal
- syncCallback :: IO () -> IO JSVal
- syncCallback1 :: (JSVal -> IO ()) -> IO JSVal
- syncCallback2 :: (JSVal -> JSVal -> IO ()) -> IO JSVal
- syncCallback3 :: (JSVal -> JSVal -> JSVal -> IO ()) -> IO JSVal
- syncCallback' :: IO JSVal -> IO JSVal
- syncCallback1' :: (JSVal -> IO JSVal) -> IO JSVal
- syncCallback2' :: (JSVal -> JSVal -> IO JSVal) -> IO JSVal
- syncCallback3' :: (JSVal -> JSVal -> JSVal -> IO JSVal) -> IO JSVal
- await :: JSVal -> IO JSVal
- asyncCallback :: IO () -> IO JSVal
- asyncCallback1 :: (JSVal -> IO ()) -> IO JSVal
- asyncCallback2 :: (JSVal -> JSVal -> IO ()) -> IO JSVal
- asyncCallback3 :: (JSVal -> JSVal -> JSVal -> IO ()) -> IO JSVal
- apply :: (FromJSVal a, ToArgs args) => Function -> args -> IO a
- data JSException
Classes
class ToJSVal a where Source #
A class for marshaling Haskell values into JS
Minimal complete definition
Nothing
Methods
Instances
class GToJSVal (f :: Type -> Type) where Source #
Internal: writes a Generic representation into a JS object
field by field. Backs the default ToJSVal implementation; you should not
need to write instances.
Instances
| GToJSVal (U1 :: Type -> Type) Source # | |
| GToJSVal (V1 :: Type -> Type) Source # | |
| (GToJSVal a, GToJSVal b) => GToJSVal (a :*: b) Source # | |
| (TypeError ('Text "Sum types unsupported") :: Constraint, GToJSVal a, GToJSVal b) => GToJSVal (a :+: b) Source # | |
| GToJSVal a => GToJSVal (C1 i a) Source # | |
| GToJSVal a => GToJSVal (D1 i a) Source # | |
| (ToJSVal a, Selector s) => GToJSVal (S1 s (K1 i a :: Type -> Type)) Source # | |
class FromJSVal a where Source #
A class for marshaling JS values into Haskell
Minimal complete definition
Nothing
Instances
class GFromJSVal (f :: Type -> Type) where Source #
Internal: rebuilds a Generic representation from a JS
object, yielding Nothing when a field is missing or ill-typed. Backs the
default FromJSVal implementation.
Instances
| GFromJSVal (U1 :: Type -> Type) Source # | |
| GFromJSVal (V1 :: Type -> Type) Source # | |
| (GFromJSVal a, GFromJSVal b) => GFromJSVal (a :*: b) Source # | |
| (TypeError ('Text "Sum types unsupported") :: Constraint, GFromJSVal a, GFromJSVal b) => GFromJSVal (a :+: b) Source # | |
| GFromJSVal a => GFromJSVal (C1 i a) Source # | |
| GFromJSVal a => GFromJSVal (D1 i a) Source # | |
| (FromJSVal a, Selector s) => GFromJSVal (S1 s (K1 i a :: Type -> Type)) Source # | |
class ToArgs args where Source #
A class for creating arguments to a JS function
Instances
class ToObject a where Source #
A class for creating JS objects.
Minimal complete definition
Nothing
Methods
Instances
| ToObject ImageData Source # | |
| ToObject Object Source # | |
| ToObject JSVal Source # | |
| ToObject Date Source # | |
| ToObject Date Source # | |
| ToObject File Source # | |
| ToObject FileReader Source # | |
Defined in Miso.FFI.Internal | |
| ToObject Image Source # | |
| ToObject URLSearchParams Source # | |
Defined in Miso.FFI.Internal | |
| ToObject URI Source # | |
| ToObject VTree Source # | |
| ToJSVal a => ToObject (IO a) Source # | |
| ToObject (Array value) Source # | |
| ToJSVal a => ToObject (Map MisoString a) Source # | |
Types
A type that represents any JS value
A JS Object
A JS Functionn
Constructors
| Function | |
Fields
| |
Utils
Arguments
| :: (ToJSVal arg1, ToJSVal arg2) | |
| => MisoString | Global function name on |
| -> arg1 | First argument |
| -> arg2 | Second argument |
| -> IO JSVal |
Invokes a function with 2 arguments
Arguments
| :: (ToJSVal arg1, ToJSVal arg2, ToJSVal arg3) | |
| => MisoString | Global function name on |
| -> arg1 | First argument |
| -> arg2 | Second argument |
| -> arg3 | Third argument |
| -> IO JSVal |
Invokes a function with 3 arguments
jsg4 :: (ToJSVal arg1, ToJSVal arg2, ToJSVal arg3, ToJSVal arg4) => MisoString -> arg1 -> arg2 -> arg3 -> arg4 -> IO JSVal Source #
Invokes a function with 4 arguments
jsg5 :: (ToJSVal arg1, ToJSVal arg2, ToJSVal arg3, ToJSVal arg4, ToJSVal arg5) => MisoString -> arg1 -> arg2 -> arg3 -> arg4 -> arg5 -> IO JSVal Source #
Invokes a function with 5 arguments
Arguments
| :: ToArgs args | |
| => MisoString | Global function name on |
| -> args | Arguments to pass to the function |
| -> IO JSVal |
Invokes a function with a specified argument list
(#) :: (ToObject object, ToArgs args) => object -> MisoString -> args -> IO JSVal infixr 2 Source #
Calls a JS function on an Object at a field with specified arguments.
Arguments
| :: (ToObject o, ToJSVal v) | |
| => o | JavaScript object to mutate |
| -> MisoString | Field name to set |
| -> v | Value to assign |
| -> IO () |
Sets a field on an Object at a specified field
(<##) :: (ToObject o, ToJSVal v) => o -> Int -> v -> IO () infixr 1 Source #
Sets a field on an Object at a specified index
Arguments
| :: (ToObject obj, ToObject this, ToArgs args) | |
| => obj | The function object to call |
| -> this | The |
| -> args | Arguments to pass to the function |
| -> IO JSVal |
Calls a JS function on an Object at a field with specified arguments.
Arguments
| :: (ToObject constructor, ToArgs args) | |
| => constructor | JavaScript constructor function (e.g. |
| -> args | Constructor arguments |
| -> IO JSVal |
Instantiates a new JS Object.
createWith :: ToJSVal val => [(MisoString, val)] -> IO Object Source #
Arguments
| :: ToJSVal val | |
| => MisoString | Property name to set |
| -> val | Value to assign |
| -> Object | Target JavaScript object |
| -> IO () |
Sets a property on a JS Object
Arguments
| :: ToObject o | |
| => MisoString | Property name to read |
| -> o | JavaScript object to read from |
| -> IO JSVal |
Retrieves a property from a JS Object
eval :: MisoString -> IO JSVal Source #
Dynamically evaluates a JS string. See eval
`eval()` is slower (not subject to JS engine optimizations) and also has security vulnerabilities (can alter other local variables).
Consider using the more performant and secure (isolated) inline function.
High-resolution timestamp where one exists, wall clock where it does not.
requestAnimationFrame :: JSVal -> IO Int Source #
Schedules a callback to run before the next repaint.
Since: 1.13.0.0
cancelAnimationFrame :: Int -> IO () Source #
Cancels a frame previously scheduled with requestAnimationFrame.
Since: 1.13.0.0
freeFunction :: Function -> IO () Source #
Frees references to a callback
freeJSVal :: JSVal -> IO () Source #
Eagerly release a JSVal handle.
On the WASM backend every JSVal carries a weak pointer and a C finalizer
so that the JavaScript value can be released once the handle is garbage
collected. The RTS must evacuate every such weak pointer on every GC (dead
or alive) before it can run the finalizer, so short-lived handles created
in bulk (e.g. while building a virtual DOM) make each GC pause scale with
the number of handles allocated since the last one. freeJSVal unlinks
the weak pointer and releases the JavaScript side immediately, so the
handle costs the GC nothing.
Only the Haskell handle is released: the JavaScript value itself stays alive for as long as something on the JavaScript side references it.
Using a JSVal after it has been freed is undefined behaviour, so only
free handles that no other Haskell code (including callbacks that close
over them) can reach. Note that on WASM a JSString is a JSVal, so
never free a handle obtained from toJSVal on a string you do not own.
No-op on the GHCJS and native backends.
syncCallback2 :: (JSVal -> JSVal -> IO ()) -> IO JSVal Source #
A synchronous callback with two arguments
syncCallback3 :: (JSVal -> JSVal -> JSVal -> IO ()) -> IO JSVal Source #
A synchronous callback with three arguments
syncCallback1' :: (JSVal -> IO JSVal) -> IO JSVal Source #
A synchronous callback that takes a single argument and returns a value
syncCallback2' :: (JSVal -> JSVal -> IO JSVal) -> IO JSVal Source #
A synchronous callback that takes two arguments and returns a value
syncCallback3' :: (JSVal -> JSVal -> JSVal -> IO JSVal) -> IO JSVal Source #
A synchronous callback that takes three arguments and returns a value
await :: JSVal -> IO JSVal Source #
Awaits a JS Promise. If the promise rejects, it throws a JSException.
Since: 1.13.0.0
asyncCallback2 :: (JSVal -> JSVal -> IO ()) -> IO JSVal Source #
A asynchronous callback with two arguments
asyncCallback3 :: (JSVal -> JSVal -> JSVal -> IO ()) -> IO JSVal Source #
A asynchronous callback with three arguments
Arguments
| :: (FromJSVal a, ToArgs args) | |
| => Function | JavaScript function to invoke |
| -> args | Arguments to pass to the function |
| -> IO a |
Calls a JavaScript Function with the given arguments and marshals
the result back into Haskell.
Since: 1.13.0.0
data JSException Source #
An exception raised by a rejected JavaScript Promise.
Since: 1.13.0.0
Instances
| Exception JSException Source # | |
Defined in Miso.DSL.FFI Methods toException :: JSException -> SomeException # fromException :: SomeException -> Maybe JSException # displayException :: JSException -> String # | |
| Show JSException Source # | |
Defined in Miso.DSL.FFI Methods showsPrec :: Int -> JSException -> ShowS # show :: JSException -> String # showList :: [JSException] -> ShowS # | |