pitwall-tauri

Crates.iopitwall-tauri
lib.rspitwall-tauri
version0.1.0
created_at2025-10-31 21:43:48.595697+00
updated_at2025-10-31 21:43:48.595697+00
descriptionTauri integration for Pitwall telemetry library
homepagehttps://werace.au/opensource/pitwall
repository
max_upload_size
id1910864
size139,398
Kevin O'Neill (kevinoneill)

documentation

README

pitwall-tauri

Tauri integration for Pitwall - stream iRacing telemetry to TypeScript frontends with compile-time type safety.

Features

  • Type-Safe IPC: Automatic TypeScript type generation from Rust structs
  • High Performance: <1% CPU overhead for 60Hz telemetry streaming
  • Stateless Design: Pure stream mirroring with no state management
  • Simple API: One function (to_channel) handles all streaming

Installation

# src-tauri/Cargo.toml
[dependencies]
pitwall = { version = "0.1", features = ["derive"] }
pitwall-tauri = "0.1"
tauri = "2"
tauri-specta = { version = "2.0.0-rc", features = ["typescript"] }
specta = { version = "2.0.0-rc", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }

Quick Start

1. Define Your Frame Type

use pitwall::PitwallFrame;
use serde::{Serialize, Deserialize};
use specta::Type;

#[derive(Debug, Clone, Serialize, Deserialize, Type, PitwallFrame)]
pub struct MyTelemetry {
    #[pitwall(name = "Speed")]
    pub speed: f32,

    #[pitwall(name = "RPM")]
    pub rpm: f32,
}

2. Create Tauri Command

use tauri::ipc::Channel;
use pitwall_tauri::{Pitwall, SessionInfo, to_channel};

#[tauri::command]
#[specta::specta]
pub async fn start_telemetry(
    telemetry: Channel<MyTelemetry>,
    session: Channel<SessionInfo>,
) -> Result<(), String> {
    let conn = Pitwall::connect().await.map_err(|e| e.to_string())?;

    // Stream telemetry frames (60Hz)
    tokio::spawn(to_channel(
        conn.subscribe::<MyTelemetry>(UpdateRate::Native),
        telemetry
    ));

    // Stream session updates
    tokio::spawn(to_channel(
        conn.session_updates(),
        session
    ));

    Ok(())
}

3. Generate TypeScript Bindings

// src-tauri/src/main.rs
#[cfg(debug_assertions)]
{
    tauri_specta::ts::export(
        specta::collect_types![start_telemetry],
        "../src/bindings.ts"
    ).expect("Failed to export bindings");
}

4. Use in TypeScript

import { invoke, Channel } from '@tauri-apps/api/core';
import type { MyTelemetry, SessionInfo } from './bindings';

const telemetryChannel = new Channel<MyTelemetry>();
telemetryChannel.onmessage = (data) => {
  console.log(`Speed: ${data.speed}, RPM: ${data.rpm}`);
};

const sessionChannel = new Channel<SessionInfo>();
sessionChannel.onmessage = (info) => {
  console.log(`Track: ${info.weekend_info.track_display_name}`);
};

await invoke('start_telemetry', {
  telemetry: telemetryChannel,
  session: sessionChannel,
});

License

Licensed under the MIT License.

Commit count: 0

cargo fmt