Sign in

    #nostd - Lightweight JS Interop

    @core は @js.JsImpl trait のオーバーヘッドを削減するための軽量な JS インターロップパッケージです。

    #使い方

    // Zero-cost type conversion
    let js_val : @core.Any = @core.any(moonbit_value)
    let back : MyType = js_val.cast()

    // Property access
    js_val["key"] = @core.any(value)
    let prop = js_val["key"]

    // Method call
    let result = js_val._call("method", [@core.any(arg1), @core.any(arg2)])

    #--nostd ビルドについて

    現在、このパッケージは標準ライブラリの Array 型に依存しているため、moon build --nostd ではビルドできません。

    将来的に --nostd でビルドできるようにするため、以下に必要な Array 型の実装をコメントとして残しています。 --nostd ビルドが必要な場合は、nostd_for_nostd.mbt.txt の内容を有効にしてください。

    #参考: --nostd 用の Array 実装

    nostd_for_nostd.mbt.txt に、--nostd ビルドに必要な Array 型の最小実装を保存しています。 これは ~/.moon/lib/core/builtin/arraycore_js.mbt をベースにした実装です。

    JsError

    pub suberror JsError String

    Generic JS error type

    Any

    #external
    pub type Any

    Opaque type for JavaScript values
    impl Eq for Any
    impl Show for Any

    Any::_call

    fn Any::_call(self : Any, key : String, args : Array[Any]) -> Any

    Call method: obj._call("method", [arg1, arg2])

    Any::_get

    #alias("_[_]")
    fn Any::_get(self : Any, key : String) -> Any

    JS: value[key] Enables syntax: obj["key"]

    Any::_get_by_index

    fn Any::_get_by_index(self : Any, key : Int) -> Any

    JS: value[key] Enables syntax: obj[index]

    Any::_invoke

    fn Any::_invoke(self : Any, args : Array[Any]) -> Any

    Call function: func._invoke([arg1, arg2])

    Any::_set

    #alias("_[_]=_")
    fn Any::_set(self : Any, key : String, value : Any) -> Unit

    Set property: obj["key"] = value Enables syntax: obj["key"] = val

    Any::cast

    fn[T] Any::cast(self : Any) -> T

    Any::to_string

    fn Any::to_string(self : Any) -> String

    Convert Any to string representation

    Nullable

    #external
    pub type Nullable[T]

    null or T

    Nullable::is_null

    fn[T] Nullable::is_null(self : Nullable[T]) -> Bool

    Nullable::to_option

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

    Nullish

    #external
    pub type Nullish[T]

    null | undefined | T

    Nullish::to_option

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

    Promise

    #external
    pub type Promise[T]

    JavaScript Promise[T] https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise

    Promise::all

    fn[A] Promise::all(promises : Array[Promise[A]]) -> Promise[Array[A]]

    JS: Promise.all(promises) https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
    let results = Promise::all([
    Promise::from_async(async fn() { fetch_user() }),
    Promise::from_async(async fn() { fetch_posts() }),
    ]).wait()

    Promise::allSettled

    fn[A] Promise::allSettled(promises : Array[Promise[A]]) -> Promise[Array[SettledResult[A]]]

    JS: Promise.allSettled(promises) https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
    let results = Promise::allSettled([
    Promise::from_async(async fn() { 1 }),
    Promise::from_async(async fn() { fail("error") }),
    ]).wait()
    // results[0].status == "fulfilled", results[0].value == Some(1)
    // results[1].status == "rejected", results[1].reason != null

    Promise::any

    fn[T] Promise::any(promises : Array[Promise[T]]) -> Promise[T]

    JS: Promise.any(promises) https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/any
    let first_success = Promise::any([
    Promise::from_async(async fn() { fetch_from_mirror1() }),
    Promise::from_async(async fn() { fetch_from_mirror2() }),
    ]).wait()

    Promise::catch_

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

    Promise::finally_

    fn[A] Promise::finally_(self : Promise[A], f : () -> Unit) -> Promise[A]

    JS: promise.finally(() => { ... })

    Promise::from_async

    fn[A] Promise::from_async(f : async () -> A) -> Promise[A]

    Convert an async function to a Promise.
    let p : Promise[Int] = Promise::from_async(async fn() {
    let result = some_async_operation()
    result
    })

    Promise::new

    fn[A] Promise::new(f : async ((A) -> Unit, (Error) -> Unit) -> Unit) -> Promise[A]

    JS: new Promise((resolve, reject) => { ... }) Create a Promise from an async executor function with resolve/reject callbacks.
    let p : Promise[Int] = Promise::new(async fn(resolve, _reject) {
    let result = some_async_operation()
    resolve(result)
    })

    Promise::race

    fn[T] Promise::race(promises : Array[Promise[T]]) -> Promise[T]

    JS: Promise.race(promises) https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
    let first = Promise::race([
    Promise::from_async(async fn() {
    sleep(100)
    "slow"
    }),
    Promise::from_async(async fn() {
    sleep(10)
    "fast"
    }),
    ]).wait() // "fast"

    Promise::reject

    fn Promise::reject(x : Any) -> Promise[Any]

    js: Promise.reject(error) https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject

    Promise::resolve

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

    js: Promise.resolve(value) https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve

    Promise::then

    fn[A, B] Promise::then(self : Promise[A], resolve : (A) -> Promise[B] raise) -> Promise[B]

    Promise::to_any

    fn[T] Promise::to_any(self : Promise[T]) -> Any

    Promise::wait

    async fn[T] Promise::wait(self : Promise[T]) -> T

    JS: await promise Waits for the Promise to be resolved or rejected.

    Promise::withResolvers

    fn[T] Promise::withResolvers() -> PromiseResolvers[T]

    JS: Promise.withResolvers() https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/withPromiseResolvers

    PromiseResolvers

    pub(all) struct PromiseResolvers[T] {
    promise : Promise[T]
    resolve : (T) -> Unit
    reject : (Error) -> Unit
    }

    JS: Promise.withResolvers() https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/withPromiseResolvers

    PromiseResolvers::reject

    fn[T] PromiseResolvers::reject(self : PromiseResolvers[T], error : Error) -> Unit

    JS: resolvers.reject(error)

    PromiseResolvers::resolve

    fn[T] PromiseResolvers::resolve(self : PromiseResolvers[T], value : T) -> Unit

    JS: resolvers.resolve(value)

    SettledResult

    pub(all) struct SettledResult[T] {
    status : String
    value : T?
    reason : Nullable[Any]
    }

    Result type for Promise.allSettled

    SettledResult::to_any

    fn[T] SettledResult::to_any(self : SettledResult[T]) -> Any

    Union2

    #external
    pub type Union2[A, B]

    TS: A | B

    Union2::from

    fn[A, B] Union2::from(x : Any) -> Union2[A, B]

    Union2::to0

    fn[A, B] Union2::to0(self : Union2[A, B]) -> A

    Union2::to1

    fn[A, B] Union2::to1(self : Union2[A, B]) -> B

    Union2::to_any

    fn[A, B] Union2::to_any(self : Union2[A, B]) -> Any

    Union3

    #external
    pub type Union3[A, B, C]

    TS: A | B | C

    Union3::from

    fn[A, B, C] Union3::from(x : Any) -> Union3[A, B, C]

    Union3::to0

    fn[A, B, C] Union3::to0(self : Union3[A, B, C]) -> A

    Union3::to1

    fn[A, B, C] Union3::to1(self : Union3[A, B, C]) -> B

    Union3::to2

    fn[A, B, C] Union3::to2(self : Union3[A, B, C]) -> C

    TS: A | B | C

    Union3::to_any

    fn[A, B, C] Union3::to_any(self : Union3[A, B, C]) -> Any

    Union4

    #external
    pub type Union4[A, B, C, D]

    TS: A | B | C | D

    Union4::from

    fn[A, B, C, D] Union4::from(x : Any) -> Union4[A, B, C, D]

    Union4::to0

    fn[A, B, C, D] Union4::to0(self : Union4[A, B, C, D]) -> A

    Union4::to1

    fn[A, B, C, D] Union4::to1(self : Union4[A, B, C, D]) -> B

    Union4::to2

    fn[A, B, C, D] Union4::to2(self : Union4[A, B, C, D]) -> C

    Union4::to3

    fn[A, B, C, D] Union4::to3(self : Union4[A, B, C, D]) -> D

    Union4::to_any

    fn[A, B, C, D] Union4::to_any(self : Union4[A, B, C, D]) -> Any

    Union5

    #external
    pub type Union5[A, B, C, D, E]

    TS: A | B | C | D | E

    Union5::from

    fn[A, B, C, D, E] Union5::from(x : Any) -> Union5[A, B, C, D, E]

    Union5::to0

    fn[A, B, C, D, E] Union5::to0(self : Union5[A, B, C, D, E]) -> A

    Union5::to1

    fn[A, B, C, D, E] Union5::to1(self : Union5[A, B, C, D, E]) -> B

    Union5::to2

    fn[A, B, C, D, E] Union5::to2(self : Union5[A, B, C, D, E]) -> C

    Union5::to3

    fn[A, B, C, D, E] Union5::to3(self : Union5[A, B, C, D, E]) -> D

    Union5::to4

    fn[A, B, C, D, E] Union5::to4(self : Union5[A, B, C, D, E]) -> E

    Union5::to_any

    fn[A, B, C, D, E] Union5::to_any(self : Union5[A, B, C, D, E]) -> Any

    any

    fn[T] any(value : T) -> Any

    array_from

    fn array_from(v : Any) -> Array[Any]

    Array.from(v)

    as_any

    fn as_any(opt : Any?) -> Any

    Convert Option[Any] to Any (None becomes undefined) Note: Any? is boxed, so we need FFI to extract the value

    assert_throws

    fn assert_throws(op : () -> Any) -> String raise JsError

    Test helper: assert that op throws a JS exception Returns the error message if thrown, fails if no exception

    assert_throws_with

    fn assert_throws_with(op : () -> Any, expected_msg : String) -> Unit

    Test helper: assert that op throws with specific message (contains check)

    equal

    fn equal(a : Any, b : Any) -> Bool

    Check if value is null or undefined

    export_sync

    fn[E : Show + Error] export_sync(op : () -> Any raise E) -> Any

    Wrap a MoonBit operation that may raise, converting errors to JS exceptions Usage: export_sync(fn() { may_raise_error() })

    ffi_wrap_sync

    fn ffi_wrap_sync(op : () -> Any, on_ok : (Any) -> Unit, on_error : (Any) -> Unit) -> Unit

    JS operation wrapper with try-catch

    from_entries

    fn from_entries(entries : Array[(String, Any)]) -> Any

    Convert Array of tuples to JS Object using Object.fromEntries Tuples compile to {_0, _1} objects, which are converted to [key, value] in FFI

    from_fn0

    fn[A] from_fn0(f : () -> A) -> Any

    Wrap MoonBit function as JS function (0 args)

    from_fn1

    fn[A, B] from_fn1(f : (A) -> B) -> Any

    Wrap MoonBit function as JS function (1 arg)

    from_fn2

    fn[A, B, C] from_fn2(f : (A, B) -> C) -> Any

    Wrap MoonBit function as JS function (2 args)

    from_fn3

    fn[A, B, C, D] from_fn3(f : (A, B, C) -> D) -> Any

    Wrap MoonBit function as JS function (3 args)

    from_option

    fn[A] from_option(opt : A?) -> Any

    Convert an Option to Any, mapping None to null and Some(v) to v.

    This is the inverse of identity_option. Use this when you need to pass MoonBit Option values back to JavaScript APIs.

    Usage

    • Some(42) |> from_option returns Js(42)
    • None |> from_option returns Js(null)
    • Use with match to set optional properties on objects

    See Also

    • identity_option(Js) -> A? - Inverse conversion (Js to Option)

    global_this

    fn global_this() -> Any

    identity

    fn[A, B] identity(value : A) -> B

    identity_option

    fn[T] identity_option(v : Any) -> T?

    Safely convert a JavaScript value to an Option type.

    Converts JavaScript null or undefined to None, otherwise returns Some(value). This is essential for FFI because accessing properties on null/undefined will crash.

    Common Patterns

    • DOM API nullable returns: node._get("parentNode") |> identity_option()
    • Optional object properties: obj._get("name") |> identity_option()
    • Converting back to Js: use from_option(opt)

    Related Functions

    • from_option(A?) -> Js - Inverse conversion (Option to Js)
    • @js.Nullable[T] - For FFI struct fields that need explicit null handling

    instanceof_

    fn instanceof_(v : Any, cls : Any) -> Bool

    is_array

    fn is_array(v : Any) -> Bool

    Check if value is an array

    is_null

    fn is_null(v : Any) -> Bool

    Check if value is null

    is_nullish

    fn is_nullish(v : Any) -> Bool

    Check if value is null or undefined

    is_object

    fn is_object(v : Any) -> Bool

    is_undefined

    fn is_undefined(v : Any) -> Bool

    Check if value is null

    json_parse

    fn json_parse(text : String) -> Any

    JS: JSON.parse(text)

    json_stringify

    fn json_stringify(value : Any) -> String

    JS: JSON.stringify(value)

    json_stringify_pretty

    fn json_stringify_pretty(value : Any, space : Int) -> String

    JS: JSON.stringify(value, null, space)

    log

    fn log(message : Any) -> Unit

    new

    fn new(cls : Any, args : Array[Any]) -> Any

    JS: new cls(...args)

    new_array

    fn new_array() -> Any

    new_object

    fn new_object() -> Any

    null

    fn null() -> Any

    nullable

    fn[T] nullable(opt : T?) -> Any

    Convert Option[T] to Any (None becomes undefined) Zero-cost: concrete Option[T] compiles to T | undefined in JS Usage: from_entries([("key", nullable(maybe_value))])

    object_assign

    fn object_assign(target : Any, source : Any) -> Any

    JS: Object.assign(target, ...sources)

    object_has_own

    fn object_has_own(obj : Any, key : String) -> Bool

    JS: Object.hasOwn(obj, key) or obj.hasOwnProperty(key)

    object_keys

    fn object_keys(obj : Any) -> Array[String]

    object_values

    fn object_values(obj : Any) -> Array[Any]

    promisify0

    fn[R] promisify0(f : async () -> R) -> (() -> Promise[R])

    promisify1

    fn[A, R] promisify1(f : async (A) -> R) -> ((A) -> Promise[R])

    Moonbit Async Function to JS Promise Function

    promisify2

    fn[A, B, R] promisify2(f : async (A, B) -> R) -> ((A, B) -> Promise[R])

    Moonbit Async Function to JS Promise Function

    promisify3

    fn[A, B, C, R] promisify3(f : async (A, B, C) -> R) -> ((A, B, C) -> Promise[R])

    Moonbit Async Function to JS Promise Function

    run_async

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

    MoonBit builtin %async.run

    sleep

    async fn sleep(ms : Int) -> Unit noraise

    suspend

    async fn[T, E : Error] suspend(f : ((T) -> Unit, (E) -> Unit) -> Unit) -> T raise E

    MoonBit builtin %async.suspend

    throw_

    fn throw_(value : Any) -> Unit

    throw_error

    fn throw_error(msg : String) -> Unit

    Throw a JS Error with the given message

    try_sync

    fn try_sync(op : () -> Any) -> Any raise JsError

    Safe wrapper that converts JS exceptions to MoonBit errors

    typeof_

    fn typeof_(v : Any) -> String

    JS: typeof v

    undefined

    fn undefined() -> Any