Skip to content

Conversation

mcmah309
Copy link
Contributor

@mcmah309 mcmah309 commented Jun 22, 2025

This macro does compile time validation and creates rust bindings to javascript functions. Works like a regular use import statement. See example: https://github.com/DioxusLabs/dioxus/blob/40e21cb221754665c68473890360512ac23821f5/examples/use_js_macro.rs

example statement:

use_js!("examples/assets/example.js"::greeting);
// use_js!("examples/assets/example.js"::{ greeting, });
// use_js!("examples/assets/example.js"::*);

example macro expansion:

// Recursive expansion of use_js! macro
// =====================================

#[doc = " "]
#[doc = " This is a doc comment"]
#[doc = " second line"]
pub async fn greeting(
    from: impl serde::Serialize,
    to: impl serde::Serialize,
) -> Result<serde_json::Value, document::EvalError> {
    const MODULE: Asset = {
        const __ASSET_SOURCE_PATH: &'static str = "/workspaces/dioxus/examples/assets/example.js";
        const __ASSET_OPTIONS: manganis::AssetOptions =
            manganis::AssetOptions::Unknown.into_asset_options();
        const __ASSET_HASH: &'static str = "de4b2e9e300415dc";
        const __ASSET: manganis::BundledAsset =
            manganis::macro_helpers::create_bundled_asset(__ASSET_SOURCE_PATH, __ASSET_OPTIONS);
        const __BUFFER: manganis::macro_helpers::const_serialize::ConstVec<u8> =
            manganis::macro_helpers::serialize_asset(&__ASSET);
        const __BYTES: &[u8] = __BUFFER.as_ref();
        const __LEN: usize = __BYTES.len();
        #[unsafe(export_name = "__MANGANIS__de4b2e9e300415dc")]
        static __LINK_SECTION: [u8; __LEN] = manganis::macro_helpers::copy_bytes(__BYTES);
        static __REFERENCE_TO_LINK_SECTION: &'static [u8] = &__LINK_SECTION;
        manganis::Asset::new(__REFERENCE_TO_LINK_SECTION)
    };
    let js = alloc::__export::must_use({
        let res = alloc::fmt::format(alloc::__export::format_args!("const {{ greeting }} = await import(\"{}\");\nlet from = await dioxus.recv();\nlet to = await dioxus.recv();\nreturn greeting(from, to);",MODULE));
        res
    });
    let eval = document::eval(js.as_str());
    eval.send(from)?;
    eval.send(to)?;
    eval.await
}

closes #4302

@mcmah309 mcmah309 requested a review from a team as a code owner June 22, 2025 10:29
@jkelleyrtp
Copy link
Member

Thanks for the PR! We definitely need a better FFI solution in dioxus, but I want to wait until 0.7 is shipped before we start exploring the design space. So, sadly this PR might sit for a while.

We want a similar solution for:

  • Java
  • Kotlin
  • Swift
  • Objective C
  • C/C++
  • TypeScript

It would be ideal to wrap all this under a single interface and build system (ie maybe through buck2/bazel ?) and then integrated with dx. We probably aren't going to accept any adhoc system until then.

@jkelleyrtp jkelleyrtp added this to the 0.8.0 milestone Jul 1, 2025
@mcmah309
Copy link
Contributor Author

mcmah309 commented Jul 1, 2025

Thanks for the feedback. Do you think this might be a better fit in the sdk in the meantime or as a standalone repo/crate I own? I definitely will be using it until something comparable is implemented

mcmah309 added a commit to mcmah309/dioxus-use-js that referenced this pull request Jul 3, 2025
@mcmah309
Copy link
Contributor Author

mcmah309 commented Jul 10, 2025

Created a crate for this in the meantime.

github: https://github.com/mcmah309/dioxus-use-js

crates.io: https://crates.io/crates/dioxus-use-js

Any updates/features will go there unless we decide to go ahead with the design in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

More Seamless JS Interop

2 participants