///|
extern "js" fn ffi_init(
convert_thrown_error : (String, Any, Any) -> Unit raise,
) =
#|(convert_thrown_error, ) => {
#| globalThis["MoonBit"] = {
#| Result: {
#| Ok: (x) => ({ $tag: 1, _0: x}),
#| Err: (x) => ({ $tag: 1, _0: x})
#| },
#| Error: {
#| // raise a special js error
#| raise: function(tag, payload0, payload1){
#| throw { jmop_error_tag: tag, _0: payload0, _1: payload1 }
#| },
#| // is special error
#| is_error: function(x) {
#| !!x && typeof x.jmop_error_tag === 'string'
#| },
#| // convert the special js error to moonbit error
#| convert: function(e) {
#| return this.is_error(e)
#| ? convert_thrown_error(e.jmop_error_tag, e['_0'], e['_1'])
#| : convert_thrown_error("unknown", e, undefined)
#| },
#| // get special error tag or payloads
#| tag: function(x) { x.jmop_error_tag },
#| payload0: function(x) { x['_0'] },
#| payload0: function(x) { x['_1'] },
#| // tags
#| InvalidNestedPromise: "InvalidNestedPromise",
#| },
#| Promise: {
#| is_promise: (p) => !!p && typeof p.then === 'function',
#| not_promise_or_throw: function(x, loc) {
#| if(MoonBit.Promise.is_promise(x)){
#| MoonBit.Error.raise(MoonBit.Error.InvalidNestedPromise, loc)
#| } else {
#| return x
#| }
#| },
#| handle_thrown: function(p) {
#| p.catch(e => MoonBit.Error.convert(e))
#| }
#| }
#| }
#|}
///|
fn init {
ffi_init(convert_thrown_error)
}
///|
fn convert_thrown_error(
x : String,
payload0 : Any,
payload1 : Any,
) -> Unit raise {
ignore(payload1)
match x {
"InvalidNestedPromise" =>
raise InvalidNestedPromise(identity(payload0.unwrap()))
_ => raise RuntimeError(identity(payload0))
}
}