#ts bindings

132 messages · Page 1 of 1 (latest)

cobalt dock
#

i'm using ts_rs to add typing to the frontend out of my backend.
unfortunately it only produces the type files when running cargo test.
is there a way i can run a test when detecting a change in the rust code?

(if there is a better crate for this, please tell me. i have heard of typescript-definitions but it confused me)

distant zodiac
cobalt dock
#

i read over it.

#

i don't really like the fact that the bindings file actualy allows you to do bindings.command.
i think i could get used to it, it just seams weird

cobalt dock
#

i tried using it. it paniced.

#

smth about a bigint or such

distant zodiac
#

Can you share the full error and the code that produced it?

cobalt dock
#

@distant zodiac

thread 'main' panicked at USER.cargo\registry\src\index.crates.io-6f17d22bba15001f\tauri-specta-2.0.0-rc.4\src\lib.rs:382:70:
called `Result::unwrap()` on an `Err` value: BigIntForbidden(src\message.rs:18:35::ListMessage.src_size -> u64)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
#

i'm assuming because i'm using u64?

#

*this is the size of a file, fs returns a u64.

cobalt dock
#

ok, i'm using a string now and parsing it in frontent :? (if better way pls tell.

#

one of my types isn't being put into a ts type.

#

my error type only used to return from my command is not turned into a ts type.
my code uses it though

#
  • also is there a way to config it to do this:
enum Type {a="A", b="B"}
const Thing = {typ:Type.a, ...} | {typ:Typ.b, ...}

instead of

const Thing = {typ:"A", ...} | {typ:"B", ...}

because i use the enums.

distant zodiac
cobalt dock
#

i found that

distant zodiac
cobalt dock
#

yes

distant zodiac
#

All the way down to the standard library types?

cobalt dock
#

it works, but it doesn't make it a seperate ts type

#

also, i can't seem to get config working.

#

i don't get what i'm suppost to instatiate

#

@distant zodiac

cobalt dock
#

halo?

distant zodiac
#

Sorry, I've been trying to replicate your issue.

#

With the code you've provided, I get the expected types:

#[derive(serde::Deserialize, serde::Serialize, specta::Type)]
pub enum ErrorMessage { NonExistingDirectory { passed: String } }
export type ErrorMessage = { NonExistingDirectory: { passed: string } }
cobalt dock
#

do i need deserialize?

distant zodiac
#

Only if you're taking it as a command input.

cobalt dock
#

it might be (for some reason) because it is only used as a type once as the result from a command.
all the other types that work are used as results for multiple backend functions.

distant zodiac
#

It's easy enough to go through the code and clean out any unnecessary traits when adding the final polish.

cobalt dock
#

?

#

while your here, how do i use the config? like for bigint.

#

the most docs there are on it is:
.config() adds a config to the builder

distant zodiac
#
    #[cfg(debug_assertions)]
    tauri_specta::ts::Exporter::new(specta::collect_types![greet], "../src/bindings.ts")
        .with_cfg(
            specta::ts::ExportConfiguration::new()
                .bigint(specta::ts::BigIntExportBehavior::BigInt)
            )
        .export()
        .expect("error while exporting typescript bindings");
cobalt dock
#

this is currently how i have it:

let specta_builder = {
    let specta_builder = tauri_specta::ts::builder()
        .commands(tauri_specta::collect_commands![run_check, open_path]);
    
    #[cfg(debug_assertions)]
    let specta_builder = specta_builder.path("../src/bindings.ts");

    specta_builder.into_plugin()
};

tauri::Builder::default()
  .plugin(specta_builder)
  ...
distant zodiac
#

You can do it that way too.

cobalt dock
#

what's the difference? do commands still work?

distant zodiac
#

I'm pretty sure it's just v1 and v2 differences.

cobalt dock
#

which ones v2?

distant zodiac
#

The one you posted.

cobalt dock
#

*its just renamed to ExportConfig

distant zodiac
#

What do you have in your Cargo.toml under [dependencies] for Tauri and Specta?

cobalt dock
#
tauri-specta = { version = "=2.0.0-rc.4", features = ["typescript"] }
specta = "=2.0.0-rc.7"
distant zodiac
#

Are you also using Tauri v2?

cobalt dock
#

:/ no.

distant zodiac
#

Good, because it's not ready for that yet.

cobalt dock
#

i didn't even know that existed

distant zodiac
#

I'll switch to the release candidates. I figured most people weren't using them yet.

cobalt dock
#

well i'm special

#

yeah, my ErrorMessage type still doesn't show

distant zodiac
#

Specta v2:

    let specta_builder = {
        let specta_builder = tauri_specta::ts::builder()
            .commands(tauri_specta::collect_commands![greet4, greet5])
            .config(
                specta::ts::ExportConfig::new()
                .bigint(specta::ts::BigIntExportBehavior::BigInt)
            );

        #[cfg(debug_assertions)]
        let specta_builder = specta_builder.path("../src/bindings.ts");
    
        specta_builder.into_plugin()
    };
cobalt dock
#

yeah, i got that

distant zodiac
#

You can then import it like: import { commands, ErrorMessage } from "./bindings";

cobalt dock
#
  • is there a way to shorten it like:
let specta_builder = tauri_specta::ts::builder()
    .commands(tauri_specta::collect_commands![run_check, open_path])
    .config(specta::ts::ExportConfig::new()
      .bigint(BigIntExportBehavior::Number))
    .path("../src/bindings.ts")
    .into_plugin();

but still have cfg debug assertions?

distant zodiac
#

If you've got the file, you probably don't need to use the plugin option.

cobalt dock
#

what file?

distant zodiac
#

../src/bindings.ts

cobalt dock
#

wdym got it?

distant zodiac
#

Well, it's in your front-end src.

cobalt dock
#

yes, should i track it on git?

distant zodiac
#

I don't think it matters either way.

cobalt dock
#

well, if i don't then the file won't exsist if people clone the repo

distant zodiac
#

It will be generated when the app is run with debug assertions.

#

You can track it for reference purposes.

cobalt dock
#

if i use the non-plugin version

  1. it creates the file still?
  2. does it update when i change code, or just when first run
distant zodiac
#

As for the plugin, I'm pretty sure all that does is inject the JS code at runtime instead of baking it into the app.

cobalt dock
#

but i'm using ts

distant zodiac
#

Which gets converted to JS.

#

No web engine can run TypeScript.

cobalt dock
#

yes, but all my other ts gets converted to js automagicly

distant zodiac
cobalt dock
#

to restate q2.
i don't have to close and re run npm run tauri dev to retranspile the bindings?

distant zodiac
#

No, it will restart the app automatically whenver you change the Rust files.

#

I'll take a closer look at the plugin code to see whether it's necessary. I'm not very familiar with specta v2.

cobalt dock
#

🧠

#

i'm using #[serde(tag = "typ")] to add the type of the enum into it.
is it possible for tauri_specta to create a seperate ts enum for the type? like this #1199215868693991484 message

distant zodiac
#

Not to my knowledge but you might be better off asking the maintainers.

cobalt dock
#

for now, last thing. the errormessage type still doesn't show

distant zodiac
#

Can you share the file it generates? You can drag-and-drop it into Discord and it will allow you to preview most text files in the app.

cobalt dock
distant zodiac
#

It's including it in-line as the return for runCheck. It seems to be an optimisation of some kind.

cobalt dock
#

yes, but i need to use it somewere else in my frontend.

distant zodiac
#

How do you reference it in Rust?

cobalt dock
#

once, in the result from a command

distant zodiac
#

Similar to fn greet(name: &str) -> Result<(), ErrorMessage> {?

cobalt dock
#

i refrence it other places like ErrorMessage::MyType {}

distant zodiac
#

Ah, I'm having the same problem now.

cobalt dock
#

what?

distant zodiac
#

It's optimising away the reference when I make it a Result<T, E>. When the command returns the type directly, it exports as expected.

cobalt dock
#

why?

distant zodiac
#

Not entirely sure. Taking a look at the source code now.

cobalt dock
#

what have you found?

distant zodiac
#

I think it's Rust that's inlining it.

cobalt dock
#

what is inline?

#

the enum is?

#

could it be because it's a single value?

distant zodiac
#

Maybe. It didn't have the same behaviour when I had two options in it.

cobalt dock
#

maybe

#

i'll try

#

it didn't work.

#

i added another unused varient to it

distant zodiac
#

Wrapping it in a struct seemed to have done the trick.

cobalt dock
#

wdym?

#

yeah, my other ones all have a parent struct (and the parent struct is returned from a function)

distant zodiac
#
#[derive(serde::Deserialize, serde::Serialize, specta::Type)]
pub struct ErrorMessageStruct {
    error: ErrorMessage
}

#[derive(serde::Deserialize, serde::Serialize, specta::Type)]
#[serde(tag = "typ")]
pub enum ErrorMessage {
    NonExistingDirectory { passed: String }
}
cobalt dock
#

huh

distant zodiac
#

Yes, it's weird.

cobalt dock
#

is it rust or specta or tauri_specta?

distant zodiac
#

I think it's Rust or Specta.

#

Not entirely sure which.

cobalt dock
#

is there anything you know of which could lead to one of them?

#

do you know its not tauri_specta?

distant zodiac
#

It's rather unlikely to be tauri_specta as that's just a thin wrapper to bring commands and events into the scope.

cobalt dock
#

yeah

#

i'm going to make an issue on specta.

#

you know what i think it is:
it might be that for some reason specta inlines the result value and error.
look: it's inlining both

#

that's why my other return type (the tree:folder list:Listmessage[]) is not showing.

#

even though they have specta::Type on it

distant zodiac
#

That might be related. I'm not entirely sure how the types are parsed.

cobalt dock
#

i'll look

#

these prs are bad. they don't explain anything.

#

eh, i'll make a new issue, if it's a dupe it'll close

#

thanks, you helped alot.

distant zodiac
#

I certainly did my best. I'd never used it before so I've learned a lot in the process.

cobalt dock
#

well we both learned :)