Sign in

    jmop

    A safe JavaScript interop tool.

    js
    ffi
    web
    Download zip
    Author
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    last year
    Downloads
    75

    No dependencies

    #jmop

    doc

    Note: This module is experimental and its API may change in future releases.

    jmop (JavaScript & MoonBit interoperation) is an FFI module for MoonBit's js backend that enables safe interaction with JavaScript objects and functions. It emphasizes null and undefined safety, helping you avoid common pitfalls when working with javascript.

    #Features

    • Null and undefined safety: Prevents accidental access to missing values.
    • Fail-fast behavior: Errors are detected and reported immediately.
    • Traceable runtime errors: Clear error messages make debugging easier.

    #Usage Examples

    ///|
    typealias @jmop.(Object, Promise, Function)

    ///|
    fn init {
    @jmop.global_this.set(
    "test",
    Object::new({
    "number1": 100,
    "number2": 50,
    "object": Object::new({
    "add": Function::new(fn(x : Int, y) { x + y }),
    "sub": Function::new(fn(x : Int, y) { x - y }),
    }),
    }),
    ) catch {
    e => println(e)
    }
    }

    ///|
    test "object and function" {
    let js_obj = @jmop.global_this.get_object("test")
    let n1 = js_obj.get_number("number1")
    let n2 = js_obj.get_number("number2")
    inspect(js_obj.get_object("object").call("add", [n1, n2]), content="150")
    inspect(js_obj.get_object("object").call("sub", [n1, n2]), content="50")
    inspect(js_obj.get_object("object").call("add", ["123", 1]), content="1231")
    }

    Try the following test by clicking the Test button:

    ///|
    test "promise" {
    @jmop.try_launch(() => {
    let js_promise = Promise::new(1)
    let r = js_promise
    .map(x => x + 1)
    .bind(x => Promise::new(x.to_string()))
    .wait()
    println(r) // 2
    })
    }

    ///|
    test "fail-fast: get undefined field" {
    global_this.get_object("test").get("undefined_obj") |> ignore
    }

    ///|
    test "fail-fast: create nested promise" {
    @jmop.try_launch(() => Promise::new(Promise::new(1)).wait() |> ignore)
    }

    DynCast

    pub(open) trait DynCast : IsValue {
    from_value(Value) -> Self raise
    }

    impl DynCast for Bool
    impl DynCast for Int
    impl DynCast for Double
    impl DynCast for String
    impl DynCast for Array[T]

    IsAny

    pub(open) trait IsAny {
    as_any(Self) -> Any = _
    }

    impl IsAny for Unit
    impl IsAny for Bool
    impl IsAny for Int
    impl IsAny for Double
    impl IsAny for String
    impl IsAny for Array[T]

    IsError

    pub trait IsError : IsObject {
    as_error(Self) -> Error_
    get_name(Self) -> String
    get_message(Self) -> String
    get_cause(Self) -> Any
    get_source_loc(Self) -> SourceLoc?
    set_source_loc(Self, SourceLoc) -> Unit
    }

    IsObject

    pub trait IsObject : IsValue {
    }

    IsString

    pub trait IsString : IsValue {
    }

    impl IsString for String

    IsStringOrFunctionOrObject

    pub trait IsStringOrFunctionOrObject : IsValue {
    }

    Function | Object

    IsStringOrSymbol

    pub trait IsStringOrSymbol : IsString + IsSymbol {
    }

    String | Symbol

    IsSymbol

    pub(open) trait IsSymbol {
    }

    IsValue

    pub(open) trait IsValue : IsAny {
    as_value(Self) -> Value = _
    }

    impl IsValue for Unit
    impl IsValue for Bool
    impl IsValue for Int
    impl IsValue for Double
    impl IsValue for String
    impl IsValue for Array[T]

    AggregateError

    pub suberror AggregateError Error_

    ArityMismatch

    pub suberror ArityMismatch ArityMismatchInfo

    DynCastFailed

    type DynCastFailed

    EvalError

    pub suberror EvalError Error_

    impl IsAny for EvalError
    impl Show for EvalError

    InternalError

    pub suberror InternalError Error_

    InvalidCast

    pub(all) suberror InvalidCast (SourceLoc, Value, String?)

    impl Show for InvalidCast

    InvalidField

    pub(all) suberror InvalidField (SourceLoc, Value, String)

    InvalidNestedPromise

    pub suberror InvalidNestedPromise SourceLoc

    RangeError

    pub suberror RangeError Error_

    impl IsAny for RangeError
    impl Show for RangeError

    ReferenceError

    pub suberror ReferenceError Error_

    RuntimeError

    pub suberror RuntimeError Value

    SyntaxError

    pub suberror SyntaxError Error_

    impl Show for SyntaxError

    TypeError

    pub suberror TypeError Error_

    impl IsAny for TypeError
    impl Show for TypeError

    URIError

    pub suberror URIError Error_

    impl IsAny for URIError
    impl IsError for URIError
    impl IsValue for URIError
    impl Show for URIError

    UnwrapNull

    pub suberror UnwrapNull SourceLoc

    UnwrapUndefined

    pub suberror UnwrapUndefined SourceLoc

    Any

    type Any

    Represent any value in js, including the null and undefined.
    impl IsAny for Any
    impl Show for Any

    Any::from

    fn[T] Any::from(x : T) -> Any

    Any::to_option

    fn[T : DynCast + IsValue + IsAny] Any::to_option(self : Any) -> T?

    Any::unwrap

    #callsite(autofill(loc))
    fn Any::unwrap(x : Any, loc~ : SourceLoc) -> Value raise

    Checks if the value is neither null nor undefined and returns it. Otherwise, raises an UnwrapUndefined or UnwrapNull error.

    ArityMismatchInfo

    pub struct ArityMismatchInfo {
    function : Function
    expected : Int
    provided : Int
    }

    Bigint

    type Bigint

    impl IsAny for Bigint
    impl IsValue for Bigint

    Error_

    type Error_

    Represents a JavaScript Error object.
    impl DynCast for Error_
    impl IsAny for Error_
    impl IsError for Error_
    impl IsObject for Error_
    impl IsValue for Error_
    impl Show for Error_

    Error_::new

    fn Error_::new(message : String, cause? : Any) -> Error_

    Error_::new_with_loc

    fn Error_::new_with_loc(message : String, loc : SourceLoc) -> Error_

    Function

    type Function

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
    impl IsAny for Function
    impl IsValue for Function
    impl Show for Function

    Function::apply

    fn Function::apply(f : Function, this : Value, args : Array[IsAny]) -> Any

    Function::bind

    fn Function::bind(f : Function, this : Value) -> Function

    Function::call

    fn Function::call(f : Function, args : Array[IsValue]) -> Value

    Function::from_code

    fn Function::from_code(args : Array[String], functionbody : String) -> Function

    Function::get_length

    fn Function::get_length(f : Function) -> Int

    Function::get_name

    fn Function::get_name(f : Function) -> String

    Function::new

    #callsite(autofill(loc))
    fn[F] Function::new(f : F, loc~ : SourceLoc) -> Function raise

    JsTypeError

    pub type JsTypeError

    Nullable

    type Nullable[T]

    A Value can be null.

    This value is not boxed, which means Nullable::some(Nullable::null()) is the same as Nullable::null().

    Nullable::from

    fn[T] Nullable::from(x : T) -> Nullable[T]

    Nullable::null

    fn[T] Nullable::null() -> Nullable[T]
    fnalias Nullable::null

    Nullable::to_option

    fn[T] Nullable::to_option(self : Nullable[T]) -> T?

    Convert Nullable to a boxed Option

    Nullable::unwrap

    #callsite(autofill(loc))
    fn[T] Nullable::unwrap(self : Nullable[T], loc~ : SourceLoc) -> T raise UnwrapNull

    Nullable::unwrap_value

    #callsite(autofill(loc))
    fn Nullable::unwrap_value(self : Nullable[Optional[Value]], loc~ : SourceLoc) -> Value raise

    Object

    pub type Object

    Object represents a non-null JavaScript object.

    Hint: if you are looking for object with null, use Nullable[Object].
    impl IsAny for Object
    impl IsValue for Object

    Object::assign

    fn Object::assign(self : Object, sources : Array[IsObject]) -> Unit

    Object::call

    #callsite(autofill(loc))
    fn Object::call(self : Object, method_ : IsStringOrSymbol, args : Array[IsAny], loc~ : SourceLoc) -> Any raise

    Object::empty

    fn Object::empty() -> Object

    Object::freeze

    fn Object::freeze(self : Object) -> Unit

    Object::get

    #callsite(autofill(loc))
    fn Object::get(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Value raise

    Object::get_array

    #callsite(autofill(loc))
    fn[T : DynCast + IsValue + IsAny] Object::get_array(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Array[T] raise

    Object::get_bigint

    #callsite(autofill(loc))
    fn Object::get_bigint(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Bigint raise

    Object::get_boolean

    #callsite(autofill(loc))
    fn Object::get_boolean(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Bool raise

    Object::get_function

    #callsite(autofill(loc))
    fn Object::get_function(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Function raise

    Object::get_method

    #callsite(autofill(loc))
    fn Object::get_method(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Function raise

    Object::get_number

    #callsite(autofill(loc))
    fn Object::get_number(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Double raise

    Object::get_object

    #callsite(autofill(loc))
    fn Object::get_object(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Object raise

    Object::get_string

    #callsite(autofill(loc))
    fn Object::get_string(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> String raise

    Object::get_symbol

    #callsite(autofill(loc))
    fn Object::get_symbol(self : Object, prop : IsStringOrSymbol, loc~ : SourceLoc) -> Symbol raise

    Object::has_own

    fn Object::has_own(self : Object, prop : IsStringOrSymbol) -> Bool

    Object::instance_of

    fn Object::instance_of(self : Object, ctor : IsStringOrFunctionOrObject) -> Bool

    Object::new

    #callsite(autofill(loc))
    fn Object::new(pairs : Map[String, IsValue], loc~ : SourceLoc) -> Object raise

    Object::seal

    fn Object::seal(self : Object) -> Unit

    Object::self

    fn Object::self(self : Object) -> Object

    Object::set

    #callsite(autofill(loc))
    fn Object::set(self : Object, k : IsStringOrSymbol, v : IsValue, loc~ : SourceLoc) -> Unit raise

    Optional

    type Optional[T]

    A Value can be undefined.

    This value is not boxed, which means Optional::some(Optional::undefined()) is the same as Optional::undefined().
    impl IsAny for Optional[T]

    Optional::from

    fn[T] Optional::from(x : T) -> Optional[T]

    Optional::from_option

    fn[T] Optional::from_option(opt : T?) -> Optional[T]

    Optional::to_option

    fn[T] Optional::to_option(self : Optional[T]) -> T?

    Optional::undefined

    fn[T] Optional::undefined() -> Optional[T]
    fnalias Optional::undefined

    Optional::unwrap

    #callsite(autofill(loc))
    fn[T] Optional::unwrap(self : Optional[T], loc~ : SourceLoc) -> T raise UnwrapUndefined

    Optional::unwrap_value

    #callsite(autofill(loc))
    fn Optional::unwrap_value(self : Optional[Nullable[Value]], loc~ : SourceLoc) -> Value raise

    Promise

    type Promise[T]

    impl IsAny for Promise[T]
    impl IsValue for Promise[T]

    Promise::bind

    fn[A, B] Promise::bind(x : Promise[A], resolve : (A) -> Promise[B] raise, reject? : (Error) -> Promise[B]) -> Promise[B]

    Promise::catch_

    fn[A, B] Promise::catch_(x : Promise[A], f : (Error) -> Promise[B]) -> Promise[B]

    Promise::map

    #callsite(autofill(loc))
    fn[A, B] Promise::map(x : Promise[A], resolve : (A) -> B raise, loc~ : SourceLoc) -> Promise[B]

    Promise::new

    #callsite(autofill(loc))
    fn[A] Promise::new(x : A, loc~ : SourceLoc) -> Promise[A]

    Promise::reject

    fn[A] Promise::reject(error : Error) -> Promise[A]

    Promise::resolve

    fn[A] Promise::resolve(x : A) -> Promise[A]

    Promise::then

    fn[A, B] Promise::then(x : Promise[A], resolve : (A) -> Promise[B] raise, reject? : (Error) -> Promise[B]) -> Promise[B]

    Promise::wait

    async fn[A] Promise::wait(x : Promise[A]) -> A

    Symbol

    type Symbol

    impl IsAny for Symbol
    impl IsSymbol for Symbol
    impl IsValue for Symbol

    Value

    pub type Value

    A value that is neither null nor undefined
    impl DynCast for Value
    impl IsAny for Value
    impl IsValue for Value
    impl Show for Value

    Value::as_any

    fn Value::as_any(self : Value) -> Any

    Value::as_value

    fn Value::as_value(self : Value) -> Value

    Value::get_type

    fn Value::get_type(self : Value) -> String

    Value::instance_of

    fn Value::instance_of(self : Value, ctor : IsStringOrFunctionOrObject) -> Bool

    Value::to_array

    #callsite(autofill(loc))
    fn[T : DynCast + IsValue + IsAny] Value::to_array(self : Value, loc~ : SourceLoc) -> Array[T] raise

    Value::to_bigint

    #callsite(autofill(loc))
    fn Value::to_bigint(self : Value, loc~ : SourceLoc) -> Bigint raise InvalidCast

    Value::to_boolean

    #callsite(autofill(loc))
    fn Value::to_boolean(self : Value, loc~ : SourceLoc) -> Bool raise InvalidCast

    Value::to_error

    #callsite(autofill(loc))
    fn Value::to_error(self : Value, loc~ : SourceLoc) -> Error_ raise InvalidCast

    Value::to_function

    #callsite(autofill(loc))
    fn Value::to_function(self : Value, loc~ : SourceLoc) -> Function raise InvalidCast

    Value::to_number

    #callsite(autofill(loc))
    fn Value::to_number(self : Value, loc~ : SourceLoc) -> Double raise InvalidCast

    Value::to_object

    #callsite(autofill(loc))
    fn Value::to_object(self : Value, loc~ : SourceLoc) -> Object raise InvalidCast

    Value::to_string

    #callsite(autofill(loc))
    fn Value::to_string(self : Value, loc~ : SourceLoc) -> String raise InvalidCast

    Value::to_symbol

    #callsite(autofill(loc))
    fn Value::to_symbol(self : Value, loc~ : SourceLoc) -> Symbol raise InvalidCast

    catch_error

    fn[T] catch_error(f : () -> T, on_error : (Error_) -> T raise?) -> T raise?

    convert_error

    fn[T] convert_error(loc : SourceLoc, f : () -> T) -> T raise

    for internal use only

    dyn_cast

    #callsite(autofill(loc))
    fn[T : DynCast + IsValue + IsAny] dyn_cast(x : IsValue, loc~ : SourceLoc) -> T raise

    fail_cast

    fn[T] fail_cast(target? : String) -> T raise DynCastFailed

    global_this

    let global_this : Object

    launch

    fn launch(f : async () -> Unit noraise) -> Unit

    new

    fn new(ctor : Function, args : Array[IsAny]) -> Object raise

    no_raise

    fn[T] no_raise(f : () -> T raise) -> T

    nullable

    fn[T] nullable(x : T) -> Nullable[T]

    optional

    fn[T] optional(x : T) -> Optional[T]

    try_launch

    fn try_launch(f : async () -> Unit) -> Unit