tauri-apps/tauri

[feat]

Closed this issue · 4 comments

Describe the problem

Somewhat similar to #1514. I couldn't tell from that if the focus was simply on defining types for invoke commands, or if they also meant to have automatic wrappers generated as well. Accept my apologies for being unoriginal if that's the case.

One thing I find inconvenient about Tauri is that I have to call commands through "invoke" instead of having "javascript" functions.
I find myself writing wrappers for every command and they all look exactly the same, except for the name of the command. That's a perfect candidate for automation.

Describe the solution you'd like

When I write a command in Rust I want to be able to do this from the front end:

import { myCommand } from "@tauri-apps/commands" // I don't care what this module is called or even if it's under the @tauri-apps namespace

const res = await myCommand();

There's benefit in code organization to minimize the namespace impact of the import. And with strong typing from Typescript, this improves development experience and minimizes errors. Also, this would make commands more discoverable which is important if you're working on something with a team, or contributing to a more complex project.

It's also a time saver. Yes, I'm very very lazy. That's also why I'm a successful developer ;)

Alternatives considered

No response

Additional context

Rust's Macro capability is very powerful. Generating the code is probably the easy part. Deciding where to put the module and how to get the front end to discover it might be more of a challenge.

I couldn't tell from that if the focus was simply on defining types for invoke commands, or if they also meant to have automatic wrappers generated as well

Well, both i guess. Try tauri-specta as mentioned in #1514 (comment) - it generates types and functions.

I couldn't tell from that if the focus was simply on defining types for invoke commands, or if they also meant to have automatic wrappers generated as well

Well, both i guess. Try tauri-specta as mentioned in #1514 (comment) - it generates types and functions.

Thanks, it's 80% of what I'd like.
One inconvenience is, I'm tagging everything twice:

#[tauri::command]
#[specta::specta]

I won't say that's ideal, but it's certainly better than me writing everything manually.

Also, the import is:

import { commands, events } from "./bindings";

Which is not quite as smooth as I would hope for. I still wind up doing this:

const {myCommand} = commands;

I could create two different modules that re-export commands and events respectively, and that would be a one-time cost, so I can get my project to where I want it to be. (but I have to do that for every project)

I'm just thinking about it from a pure DX experience. Any time I see code where I have to take multiple steps, and there's only one right way to take them, my mind goes to automating or wrapping it so I never have to think about that again.

One inconvenience is, I'm tagging everything twice:

Yeah, no way around that until specta is integrated into tauri. At least i think there's no way around it, afaik you can't call the command macro from inside the specta macro.

Also, the import is:....

Is it not possible to do that in the imports directly like this?

import { myCommands } from "./bindings/commands";

Edit: Neither used TS nor specta lately so don't mind me if that was stupid and fully interpreted as file paths

I think it's file paths, but I don't know for sure. It may depend on how specta generates their modules too, so even if it's not generally possible, it might be practically possible with a backward compatible change in specta.

Thanks for the discussion!