jmop

A safe JavaScript interop tool.

js
ffi
web
moon add Yoorkin/jmop@0.1.1
Download zip
Author
Version
0.1.1
License
Apache-2.0
Last updated
10 months ago
Downloads
46
README

#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