js_ffi

docs.rs docs

A foreign function interface(FFI) library for invoking Javascript functions from Web Assembly with Rust

This project has similaries to Javascript's <function>.call(<object>,a0,a1,...) but with the limitations of Web Assembly's function call restrictions.

Hello World!

toml [dependencies] js_ffi = "0.6" ```rust use js_ffi::*; ​

[no_mangle]

pub fn main() -> () { js!(console.log).invoke_1("Hello World"); } html

```

How it works

  1. Get a handle to some Javascript function using the js! macro. Re-use this handle as often as possible.
  2. If you are invoking this function as a regular function, use the appropriate invoke_* function based on the number of arguments you are passing (invoke_1,invoke_7,etc.).
  3. If you are invoking this function as a method of an object represented by a JSValue, use the appropriate call_* function based on the number of arguments you are passing (call_1,invoke_7,etc.) and make sure your object is the first paramter.

Event Listener

```rust use js_ffi::*;

[no_mangle]

fn main() { let btn = js!(document.querySelector).call1(DOCUMENT, "#button"); js!(Node.prototype.addEventListener).call2( btn, "click", createcallback0(|| { js!(window.alert).invoke_1("I was clicked"); }), ); } ```

Async Example

Using an executor library we can easily turn callbacks into futures and run behavior asynchronously.

```rust use js_ffi::*;

[no_mangle]

pub fn main() -> () { executor::spawn(async { let consolelog = js!(console.log); consolelog.invoke1("Hello"); sleep(1000).await; consolelog.invoke_1("world!"); }); }

fn sleep(millis: u32) -> impl core::future::Future { let settimeout = js!(window.setTimeout); let (future, cb) = createcallbackfuture0(); settimeout.invoke2(cb, millis); future } ```

Third Party

Wrap third party libraries. Anything function in global space should be able to be wrapped and invoked.

```rust use js_ffi::*;

[no_mangle]

fn main() { let jqueryhandle = js!($); let jqueryon_handle = js!(jQuery.prototype.on); let alert = js!((msg)=>window.alert(msg));

let body = jquery_handle.invoke_1("body");
jquery_on_handle.call_2(
    body,
    "click",
    create_callback_1(move |_event| {
        alert.invoke_1("I was clicked!");
    }),
);

} ```

```html

```

Don't like Rust?

The script js_ffi.js has nothing Rust specific.

License

This project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in js_ffi by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.