Skip to content

v0.2.0

Latest
Compare
Choose a tag to compare
@JonasKruckenberg JonasKruckenberg released this 23 May 13:41
· 194 commits to main since this release

馃敠 Highlights

New IPC Router

As part of the ongoing IPC improvements for Tauri, we're working on a new IPC router that is faster, simpler, offers a better developer experience than the current one and brings new features to the table that weren't possible before.

This release let's you play with a preview WIP version of this router (re-exported as tauri_bindgen_host::ipc_router_wip).
Defining commands looks like this now:

use tauri_bindgen_host::ipc_router_wip::{Router, BuilderExt};

fn main() {
    // notice that router is generic, this is the so called "Context"
    // for this simple example we don't need to worry about it
    let mut router = Router::new(());

    router.func_wrap("app", "foo", || -> tauri_bindgen_host::Result<()> {
        println!("foo");

        Ok(())
    });

    router.func_wrap("app", "add", |a: u32, b: u32| -> tauri_bindgen_host::Result<u32> {
        Ok(a + b)
    });

    tauri::Builder::default()
        .ipc_router(router)
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

The Router keeps track of all the commands defined within it, as well as maintaining "Context" data that your commands can access:

use tauri_bindgen_host::ipc_router_wip::{Router, Caller, BuilderExt};

fn main() {
    #[derive(Default)]
    struct Context {
        ch: Option<char>
    }

    let mut router = Router::new(Context::default());

    router.func_wrap("app", "take_char", |ctx:: Caller<Context>, ch: char| -> tauri_bindgen_host::Result<()> {
        ctx.data_mut().ch = Some(ch);

        Ok(())
    })

    router.func_wrap("app", "return_char", |ctx:: Caller<Context>| -> tauri_bindgen_host::Result<Option<ch>> {
        Ok(ctx.data_mut().ch.take())
    })

    tauri::Builder::default()
        .ipc_router(router)
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

When using tauri-bindgens code generation, the generated module exports an add_to_router function that takes care of defining your commands for you:

use tauri_bindgen_host::ipc_router_wip::{Router, Caller, BuilderExt};

tauri_bindgen_host::generate!({
    path: "example/chars.wit"
});

#[derive(Default)]
struct CharsCtx {
    ch: Option<char>
}

impl chars::Chars for CharsCtx {
    fn take_char(&mut self, ch: char) -> tauri_bindgen_host::Result<()> {
        self.ch = Some(ch);
        Ok(())
    }

    fn return_char(&mut self) -> tauri_bindgen_host::Result<Option<char>> {
        Ok(self.ch.take())
    }
}

fn main() {
    #[derive(Default)]
    struct Context {
        chars_ctx: CharsCtx
    }

    let mut router = Router::new(Context::default());

    chars::add_to_router(&mut router, |ctx| ctx.chars_ctx)

    tauri::Builder::default()
        .ipc_router(router)
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

Note All of this is subject to change over time, feel free to give feedback!

This WIP IPC router implementation also packs another cool punch: It uses a custom protocol to transmit messages between the Webview and Core. This means that performance will be much better and we finally have support for sending arbitrary binary payloads something we make use of for the next feature:

New Data Serialization Format

One bottleneck we identified is that dues to web view limitations the current IPC system is limited to sending JSON. This caused many problems, for one JSON can't encode arbitrary binary data, so sending bytes across the IPC boundary was a big performance issue. Another problem is the the overly simplistic type system of JSON, we would love to send Option<T> or Result<T, E> values across the IPC boundary and have them be preserved correctly, but not with JSON.

That's why this release also switches to a new data serialisation format: postcard. This means IPC messages are much smaller, support sending binary data without overhead and allow more expressive types.

Stabilized host, guest rust, guest javascript, and guest typescript Codegen Targets

All these changes means that almost all of this project is now in a state where I would consider it usable. So all targets except for markdown doc generation will be enabled by default now.

Known issues with guest javascript and guest typescript

Currently the javascript targets have a couple known issues pertaining to the encoding and decoding:

  1. u64 and s64 JavaScript's number type can't represent u64 and s64 numbers, so sending them across the IPC boundary currently results in wrong data. We are still discussing a way forward here (BigInt would be the suitable type for u64, but for s64?), take a look at #122
  2. nested option Currently we decode option<T> types as T | null but that means that means nested options aren't preserved. If you have ideas around this take a look at #123