From 4900f07f186d6795cba0d68e815dc3969508e6d3 Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 12:01:16 +0200 Subject: [PATCH 1/8] fix: add native desktop capture to Tauri example --- README.md | 2 +- .../.gitignore | 5 + .../README.md | 132 +++- .../src/index.html | 41 +- .../src/src-tauri/Cargo.lock | 693 +++++++++++++++++- .../src/src-tauri/Cargo.toml | 1 + .../src/src-tauri/Info.plist | 10 + .../src/src-tauri/icons/icon.png | Bin 0 -> 3375 bytes .../src/src-tauri/icons/icon.svg | 4 + .../src/src-tauri/src/main.rs | 288 ++++++-- .../src/src/main.ts | 139 ++-- .../tests/test_example.py | 158 ++-- 12 files changed, 1167 insertions(+), 306 deletions(-) create mode 100644 examples/340-tauri-live-transcription-rust-ts/.gitignore create mode 100644 examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist create mode 100644 examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png create mode 100644 examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg diff --git a/README.md b/README.md index bb9e7c1d..73047713 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ A collection of working examples showing how to use Deepgram SDKs with popular p | [290](examples/290-aws-lambda-python-transcription/) | AWS Lambda Serverless Audio Transcription | Python | AWS Lambda | | [300](examples/300-spring-boot-live-transcription-java/) | Spring Boot Real-Time Transcription with Deepgram | Java | Spring Boot | | [310](examples/310-crewai-voice-agents-python/) | CrewAI Voice-Enabled Multi-Agent System with Deepgram | Python | CrewAI | -| [340](examples/340-tauri-live-transcription-rust-ts/) | Tauri Desktop Live Transcription | Python | Tauri | +| [340](examples/340-tauri-live-transcription-rust-ts/) | Tauri Desktop Live Transcription | Rust | Tauri | | [350](examples/350-asterisk-freeswitch-deepgram-stt-python/) | Asterisk / FreeSWITCH PBX to Deepgram Streaming STT | Python | Asterisk/FreeSWITCH | | [360](examples/360-kotlin-android-live-transcription/) | Kotlin Android Live Transcription | Kotlin | Jetpack Compose | | [370](examples/370-swift-ios-live-transcription/) | Swift iOS Live Transcription | Swift | SwiftUI | diff --git a/examples/340-tauri-live-transcription-rust-ts/.gitignore b/examples/340-tauri-live-transcription-rust-ts/.gitignore new file mode 100644 index 00000000..a9c8dc83 --- /dev/null +++ b/examples/340-tauri-live-transcription-rust-ts/.gitignore @@ -0,0 +1,5 @@ +.env +src/dist/ +src/node_modules/ +src/src-tauri/gen/ +src/src-tauri/target/ diff --git a/examples/340-tauri-live-transcription-rust-ts/README.md b/examples/340-tauri-live-transcription-rust-ts/README.md index 3d049603..2363787a 100644 --- a/examples/340-tauri-live-transcription-rust-ts/README.md +++ b/examples/340-tauri-live-transcription-rust-ts/README.md @@ -1,57 +1,115 @@ -# Tauri Desktop Live Transcription +# Tauri desktop live transcription -A cross-platform desktop app built with Tauri v2 that captures microphone audio, streams it to Deepgram via WebSocket for real-time transcription, and displays live captions. Tauri's Rust backend handles the Deepgram connection using the official Rust SDK, while the TypeScript frontend captures audio and renders the UI. +Build a Tauri 2 desktop application that transcribes a running application, +all system audio, or a microphone with Deepgram Nova-3. PocketStation captures +audio in Rust on macOS, Windows, and Linux. The TypeScript frontend selects the +source and displays interim and final transcripts with speaker labels. -## What you'll build - -A Tauri desktop application with a Rust backend that connects to Deepgram's live STT WebSocket using the Deepgram Rust SDK and a TypeScript frontend that captures microphone audio at 16 kHz, streams it to the backend via Tauri commands, and displays rolling live captions with interim and final results. +The application does not open a microphone unless you select **Default +microphone**. ## Prerequisites -- [Rust](https://www.rust-lang.org/tools/install) 1.70+ -- [Node.js](https://nodejs.org/) 18+ -- System WebView (WebKitGTK on Linux, WebView2 on Windows, WebKit on macOS) — see [Tauri prerequisites](https://v2.tauri.app/start/prerequisites/) -- Deepgram account — [get a free API key](https://console.deepgram.com/) - -## Environment variables +- [Rust](https://www.rust-lang.org/tools/install) 1.85 or later +- [Node.js](https://nodejs.org/) 18 or later +- The [Tauri 2 prerequisites](https://v2.tauri.app/start/prerequisites/) for your operating system +- A [Deepgram API key](https://console.deepgram.com/) -| Variable | Where to find it | -|----------|-----------------| -| `DEEPGRAM_API_KEY` | [Deepgram console](https://console.deepgram.com/) | +## Run the application -## Install and run +Create the local environment file and set your Deepgram API key: ```bash cp .env.example .env -# Add your DEEPGRAM_API_KEY to .env +``` +```text +DEEPGRAM_API_KEY=your_api_key +``` + +Install the frontend packages and start Tauri: + +```bash cd src -npm install -npm run tauri dev +pnpm install +pnpm tauri dev +``` + +Choose one source in the application: + +- **Running application** captures the application name or identifier you + enter, such as `Zoom`. +- **All system audio** captures the complete desktop mix. +- **Default microphone** asks for microphone access and captures the current + default input device. + +Start the application you want to capture before clicking **Start**. If more +than one application matches the value you entered, PocketStation reports the +ambiguity instead of choosing one silently. + +## Permissions + +macOS asks separately for microphone access and for Screen & System Audio +Recording. Grant only the permission required by the source you selected, then +restart the example if macOS requests it. + +Windows uses native process-loopback or system-loopback capture. Linux uses +PipeWire and may display a desktop portal depending on the compositor. + +## How audio reaches Deepgram + +```text +selected native source + ↓ +PocketStation 10 ms mono frames at 48 kHz + ↓ +linear16 conversion in a PocketStation Connector + ↓ +Deepgram streaming transcription + ↓ +interim and final transcript events in Tauri ``` -## Key parameters +Audio stays in the Rust process. Only source selections and transcript events +cross Tauri IPC. PocketStation continues native capture while the Deepgram +worker sends frames over the network, and it reports delivery failure if the +network worker cannot keep up. + +The Deepgram request uses these settings: -| Parameter | Value | Description | -|-----------|-------|-------------| -| `model` | `nova-3` | Deepgram's latest and most accurate STT model | -| `encoding` | `linear16` | 16-bit PCM audio from the microphone | -| `sample_rate` | `16000` | 16 kHz — good balance of quality and bandwidth | -| `interim_results` | `true` | Show partial transcripts as the user speaks | -| `smart_format` | `true` | Auto-capitalisation, numbers, and punctuation | -| `utterance_end_ms` | `1500` | Detect end of speech after 1.5 s of silence | +| Setting | Value | +|---|---| +| Model | `nova-3` | +| Encoding | `linear16` | +| Sample rate | `48000` | +| Channels | `1` | +| Frame duration | `10 ms` | +| Interim results | Enabled | +| Speaker diarization | Enabled | +| Smart formatting | Enabled | +| Utterance end | `1500 ms` | -## How it works +## Verify the example + +Run the source checks: + +```bash +DEEPGRAM_API_KEY=test python tests/test_example.py +``` + +Build both halves of the application: + +```bash +cd src +pnpm build +cargo test --manifest-path src-tauri/Cargo.toml --locked +``` -1. The Tauri app starts with a Rust backend and a web-based frontend rendered in the system WebView -2. When you click **Start**, the TypeScript frontend requests microphone access via `getUserMedia` at 16 kHz -3. A `ScriptProcessorNode` captures raw PCM audio and converts float32 samples to signed 16-bit linear PCM -4. Audio chunks are sent to the Rust backend via Tauri's `invoke("send_audio", ...)` IPC -5. The Rust backend connects to Deepgram's live STT WebSocket using the official `deepgram` Rust crate with `transcription().stream_request_with_options(...).handle()` -6. A `tokio::select!` loop multiplexes audio forwarding and transcript receiving on the same `WebsocketHandle` -7. Transcript events (interim and final) are emitted back to the frontend via Tauri's event system (`app.emit("transcript", ...)`) -8. The frontend renders rolling captions with final text in white and interim text in grey +For the real service check, run the application with a valid Deepgram API key, +play speech in the selected source, and confirm that interim and final text +appears before stopping the session. ## Starter templates -[deepgram-starters](https://github.com/orgs/deepgram-starters/repositories) +See the [Deepgram starter repositories](https://github.com/orgs/deepgram-starters/repositories) +for additional application templates. diff --git a/examples/340-tauri-live-transcription-rust-ts/src/index.html b/examples/340-tauri-live-transcription-rust-ts/src/index.html index a3b3b272..fe47dfcd 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/index.html +++ b/examples/340-tauri-live-transcription-rust-ts/src/index.html @@ -60,6 +60,29 @@ align-items: center; } + #source-controls { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; + width: 100%; + max-width: 640px; + margin-bottom: 20px; + } + + label { display: grid; gap: 6px; font-size: 13px; } + + select, input { + width: 100%; + background: rgba(255, 255, 255, 0.08); + border: 1px solid rgba(255, 255, 255, 0.18); + border-radius: 8px; + color: #fff; + padding: 10px 12px; + font: inherit; + } + + [hidden] { display: none !important; } + button { background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.2); @@ -98,7 +121,22 @@ -

Tauri + Rust + Deepgram Nova-3

+

PocketStation + Tauri + Rust + Deepgram Nova-3

+ +
+ + +
Click Start to begin transcription...
@@ -107,6 +145,7 @@

Deepgram Live Transcription

+ disconnected
diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock index 7df7af2b..b6dd96d6 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock @@ -32,6 +32,28 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "alsa" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812947049edcd670a82cd5c73c3661d2e58468577ba8489de58e1a73c04cbd5d" +dependencies = [ + "alsa-sys", + "bitflags 2.11.0", + "cfg-if", + "libc", +] + +[[package]] +name = "alsa-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad7569085a265dd3f607ebecce7458eaab2132a84393534c95b18dcbc3f31e04" +dependencies = [ + "libc", + "pkg-config", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -41,6 +63,22 @@ dependencies = [ "libc", ] +[[package]] +name = "annotate-snippets" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" +dependencies = [ + "anstyle", + "unicode-width", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + [[package]] name = "anyhow" version = "1.0.102" @@ -78,7 +116,7 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -87,6 +125,17 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "audiopus_sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62314a1546a2064e033665d658e88c620a62904be945f8147e6b16c3db9f8651" +dependencies = [ + "cmake", + "log", + "pkg-config", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -127,6 +176,25 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "annotate-snippets", + "bitflags 2.11.0", + "cexpr", + "clang-sys", + "itertools", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.117", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -245,7 +313,7 @@ checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" dependencies = [ "glib-sys", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -308,6 +376,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + [[package]] name = "cfb" version = "0.7.3" @@ -326,7 +403,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", - "target-lexicon", + "target-lexicon 0.12.16", +] + +[[package]] +name = "cfg-expr" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4ece8474b5f766c63426647e7b4b316b67431ade1036a8313cee24a03ae917" +dependencies = [ + "smallvec", + "target-lexicon 0.13.5", ] [[package]] @@ -353,6 +440,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "clang-sys" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" +dependencies = [ + "glob", + "libc", + "libloading 0.8.9", +] + [[package]] name = "cmake" version = "0.1.58" @@ -388,6 +486,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "cookie-factory" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2" + [[package]] name = "core-foundation" version = "0.10.1" @@ -428,6 +532,50 @@ dependencies = [ "libc", ] +[[package]] +name = "coreaudio-rs" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5d7dca3ebcf65a035582c9ad4385371a9d9ee6537474d2a278f4e1e475bb58" +dependencies = [ + "bitflags 2.11.0", + "libc", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", +] + +[[package]] +name = "cpal" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f02e8d0327b42d3e2e4ab2119af397344eb9fc54a34bf0ddeaa1277af8681f1" +dependencies = [ + "alsa", + "block2", + "coreaudio-rs", + "dasp_sample", + "jni 0.22.4", + "js-sys", + "libc", + "mach2", + "ndk", + "ndk-context", + "num-derive", + "num-traits", + "objc2", + "objc2-audio-toolbox", + "objc2-avf-audio", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation", + "web-sys", + "windows 0.62.2", + "windows-core 0.62.2", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -555,6 +703,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "dasp_sample" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" + [[package]] name = "data-encoding" version = "2.10.0" @@ -594,6 +748,7 @@ version = "0.1.0" dependencies = [ "deepgram", "dotenvy", + "pocketstation", "serde", "serde_json", "tauri", @@ -779,6 +934,12 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "either" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" + [[package]] name = "embed-resource" version = "3.0.8" @@ -1072,7 +1233,7 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -1089,7 +1250,7 @@ dependencies = [ "libc", "pango-sys", "pkg-config", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -1103,7 +1264,7 @@ dependencies = [ "gobject-sys", "libc", "pkg-config", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -1129,7 +1290,7 @@ dependencies = [ "gdk-sys", "glib-sys", "libc", - "system-deps", + "system-deps 6.2.2", "x11", ] @@ -1222,7 +1383,7 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 6.2.2", "winapi", ] @@ -1270,7 +1431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" dependencies = [ "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -1287,7 +1448,7 @@ checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" dependencies = [ "glib-sys", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -1326,7 +1487,7 @@ dependencies = [ "gobject-sys", "libc", "pango-sys", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -1381,6 +1542,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hound" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" + [[package]] name = "html5ever" version = "0.29.1" @@ -1698,6 +1865,15 @@ dependencies = [ "serde", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -1724,7 +1900,7 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -1743,6 +1919,36 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + [[package]] name = "jni-sys" version = "0.3.1" @@ -1864,7 +2070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" dependencies = [ "gtk-sys", - "libloading", + "libloading 0.7.4", "once_cell", ] @@ -1884,6 +2090,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libredox" version = "0.1.15" @@ -1893,6 +2109,39 @@ dependencies = [ "libc", ] +[[package]] +name = "libspa" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "882f7427e7989dcc9d388b7f05c4630390a1d7696f9ffa469cd4a7a48f0b4c40" +dependencies = [ + "bitflags 2.11.0", + "cc", + "cookie-factory", + "libc", + "libspa-sys", + "nom 8.0.0", + "rustix", + "system-deps 7.0.8", +] + +[[package]] +name = "libspa-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6e17bdaf63ed0d5e4144022624032b41fd9733112e8c74ac26fc9bf1291924" +dependencies = [ + "bindgen", + "cc", + "system-deps 7.0.8", +] + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + [[package]] name = "litemap" version = "0.8.2" @@ -1926,6 +2175,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "mach2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" + [[package]] name = "markup5ever" version = "0.14.1" @@ -1989,6 +2244,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2073,12 +2334,51 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + [[package]] name = "num-conv" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -2133,6 +2433,55 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "objc2-audio-toolbox" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6948501a91121d6399b79abaa33a8aa4ea7857fe019f341b8c23ad6e81b79b08" +dependencies = [ + "bitflags 2.11.0", + "libc", + "objc2", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-avf-audio" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a380031deed8e99db00065c45937da434ca987c034e13b87e4441f9e4090be" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-audio" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1eebcea8b0dbff5f7c8504f3107c68fc061a3eb44932051c8cf8a68d969c3b2" +dependencies = [ + "dispatch2", + "objc2", + "objc2-core-audio-types", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-audio-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a89f2ec274a0cf4a32642b2991e8b351a404d290da87bb6a9a9d8632490bd1c" +dependencies = [ + "bitflags 2.11.0", + "objc2", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" @@ -2140,7 +2489,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.11.0", + "block2", "dispatch2", + "libc", "objc2", ] @@ -2180,6 +2531,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.11.0", "block2", + "libc", "objc2", "objc2-core-foundation", ] @@ -2251,6 +2603,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "opus" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3809943dff6fbad5f0484449ea26bdb9cb7d8efdf26ed50d3c7f227f69eb5c" +dependencies = [ + "audiopus_sys", +] + [[package]] name = "pango" version = "0.18.3" @@ -2273,7 +2634,7 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -2518,6 +2879,31 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pipewire" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde71084c4e25959d68f1ea54daa75e5ecdb338e5caf0b5510143b79baa32d5c" +dependencies = [ + "bitflags 2.11.0", + "libc", + "libspa", + "libspa-sys", + "pipewire-sys", + "rustix", +] + +[[package]] +name = "pipewire-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce653f53e63e5b93853218092ee9a8906a5d082c92f3f1db26316955dd63ce0" +dependencies = [ + "bindgen", + "libspa-sys", + "system-deps 7.0.8", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -2550,6 +2936,30 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "pocketstation" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5b0d839d6ab60633c337dd58646eb09d8a4e215415471bb4283802a073d634" +dependencies = [ + "alsa", + "cc", + "cpal", + "hound", + "libc", + "libloading 0.8.9", + "opus", + "pipewire", + "rtrb", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "wasapi", + "windows 0.58.0", + "windows-core 0.58.0", +] + [[package]] name = "potential_utf" version = "0.1.5" @@ -2984,6 +3394,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rtrb" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fae8ee26b0371a29a77d2b2d6b3ae13aa81def6f9bf1b1b92a32d279a5e709b7" + [[package]] name = "rustc-hash" version = "2.1.2" @@ -2999,6 +3415,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags 2.11.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + [[package]] name = "rustls" version = "0.23.37" @@ -3043,7 +3472,7 @@ checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" dependencies = [ "core-foundation", "core-foundation-sys", - "jni", + "jni 0.21.1", "log", "once_cell", "rustls", @@ -3467,6 +3896,22 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "0.3.11" @@ -3546,7 +3991,7 @@ dependencies = [ "glib-sys", "gobject-sys", "libc", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -3675,13 +4120,26 @@ version = "6.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ - "cfg-expr", + "cfg-expr 0.15.8", "heck 0.5.0", "pkg-config", "toml 0.8.2", "version-compare", ] +[[package]] +name = "system-deps" +version = "7.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7" +dependencies = [ + "cfg-expr 0.20.9", + "heck 0.5.0", + "pkg-config", + "toml 1.1.2+spec-1.1.0", + "version-compare", +] + [[package]] name = "tao" version = "0.34.8" @@ -3699,7 +4157,7 @@ dependencies = [ "gdkwayland-sys", "gdkx11-sys", "gtk", - "jni", + "jni 0.21.1", "libc", "log", "ndk", @@ -3714,7 +4172,7 @@ dependencies = [ "tao-macros", "unicode-segmentation", "url", - "windows", + "windows 0.61.3", "windows-core 0.61.2", "windows-version", "x11-dl", @@ -3737,6 +4195,12 @@ version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +[[package]] +name = "target-lexicon" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" + [[package]] name = "tauri" version = "2.10.3" @@ -3754,7 +4218,7 @@ dependencies = [ "gtk", "heck 0.5.0", "http", - "jni", + "jni 0.21.1", "libc", "log", "mime", @@ -3785,7 +4249,7 @@ dependencies = [ "webkit2gtk", "webview2-com", "window-vibrancy", - "windows", + "windows 0.61.3", ] [[package]] @@ -3861,7 +4325,7 @@ dependencies = [ "dpi", "gtk", "http", - "jni", + "jni 0.21.1", "objc2", "objc2-ui-kit", "objc2-web-kit", @@ -3873,7 +4337,7 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows", + "windows 0.61.3", ] [[package]] @@ -3884,7 +4348,7 @@ checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" dependencies = [ "gtk", "http", - "jni", + "jni 0.21.1", "log", "objc2", "objc2-app-kit", @@ -3898,7 +4362,7 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows", + "windows 0.61.3", "wry", ] @@ -4173,6 +4637,21 @@ dependencies = [ "winnow 0.7.15", ] +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap 2.13.1", + "serde_core", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.1", +] + [[package]] name = "toml_datetime" version = "0.6.3" @@ -4439,6 +4918,12 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -4551,6 +5036,19 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasapi" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80c3aa5d6b0e7acc3ea10cb19c334df0c8d825060f14a30d9e3b03385e6e5175" +dependencies = [ + "log", + "num-integer", + "thiserror 2.0.18", + "windows 0.62.2", + "windows-core 0.62.2", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -4756,7 +5254,7 @@ dependencies = [ "libc", "pkg-config", "soup3-sys", - "system-deps", + "system-deps 6.2.2", ] [[package]] @@ -4794,10 +5292,10 @@ checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows", + "windows 0.61.3", "windows-core 0.61.2", - "windows-implement", - "windows-interface", + "windows-implement 0.60.2", + "windows-interface 0.59.3", ] [[package]] @@ -4818,7 +5316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" dependencies = [ "thiserror 2.0.18", - "windows", + "windows 0.61.3", "windows-core 0.61.2", ] @@ -4868,17 +5366,39 @@ dependencies = [ "windows-version", ] +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-collections", + "windows-collections 0.2.0", "windows-core 0.61.2", - "windows-future", + "windows-future 0.2.1", "windows-link 0.1.3", - "windows-numerics", + "windows-numerics 0.2.0", +] + +[[package]] +name = "windows" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" +dependencies = [ + "windows-collections 0.3.2", + "windows-core 0.62.2", + "windows-future 0.3.2", + "windows-numerics 0.3.1", ] [[package]] @@ -4890,14 +5410,36 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "windows-collections" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" +dependencies = [ + "windows-core 0.62.2", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.2", + "windows-interface 0.59.3", "windows-link 0.1.3", "windows-result 0.3.4", "windows-strings 0.4.2", @@ -4909,8 +5451,8 @@ version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.60.2", + "windows-interface 0.59.3", "windows-link 0.2.1", "windows-result 0.4.1", "windows-strings 0.5.1", @@ -4924,7 +5466,29 @@ checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", "windows-link 0.1.3", - "windows-threading", + "windows-threading 0.1.0", +] + +[[package]] +name = "windows-future" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", + "windows-threading 0.2.1", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -4938,6 +5502,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "windows-interface" version = "0.59.3" @@ -4971,6 +5546,25 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-numerics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" +dependencies = [ + "windows-core 0.62.2", + "windows-link 0.2.1", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -4989,6 +5583,16 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.4.2" @@ -5109,6 +5713,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link 0.2.1", +] + [[package]] name = "windows-version" version = "0.1.7" @@ -5402,7 +6015,7 @@ dependencies = [ "gtk", "http", "javascriptcore-rs", - "jni", + "jni 0.21.1", "libc", "ndk", "objc2", @@ -5422,7 +6035,7 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows", + "windows 0.61.3", "windows-core 0.61.2", "windows-version", "x11-dl", diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml index d9fa963b..aeae75ae 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] deepgram = "=0.9.2" dotenvy = "=0.15.7" +pocketstation = "=1.1.9" serde = { version = "=1.0.228", features = ["derive"] } serde_json = "=1.0.149" tauri = { version = "=2.10.3", features = [] } diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist new file mode 100644 index 00000000..5ff5d9a4 --- /dev/null +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist @@ -0,0 +1,10 @@ + + + + + NSMicrophoneUsageDescription + Capture microphone audio for live transcription. + NSScreenCaptureUsageDescription + Capture application or system audio for live transcription. + + diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0808302cfc8e91826ce0aee3e72051a1eac00b5b GIT binary patch literal 3375 zcmWkxc{tSj7yf)_j4{@+jCC;5Wh%Gn0TBLZZE?aOrf{jqJxJ;ufy0}tU2<1oM6cE2AoK-+ zF1+3WDC@3SRf^gPk@O6QZ24>xhb8la*`)QFbCd5)O2leV!TT&1%(KhmFaNlAmk)KK z&p-3NMCmJ7<&|uhmWK~R#yF4>AF6!ioeLv+W5U?j)A+&U+iM&BMRhv#Vxzf<2!DZ* zw*w&DxiKkFTtCiy&n!&3A-sUmlBo}vDV+wF>ej(E-0mG zER-EkI&(~eZyO@D;7FIxwn9SrU|v?7?iCmJ-SK1RIY~Vn@+`{tBst3%Fx8=Z<->VE zF(50&)WAR{K`m3xCV#oJm#V0!SfiuE#gGyNY5D(L$2zy|r(jjZHx{R-r>#E}J;UJd zs4EeYL{ZLi-M>$%8GNtMYfJT=I+5qT|dgTbfPIE$^Sf)O`wSNQyIGej|8?TUzD zc}D_8_x`+B+5~FAtKt$w4KIrL`q#yCKdnUa24!wpcp%5s|G66?p z%2 zwQ^4mqIEmH70q8|EoZ1?Q_C)(^SrH*1W)(JD~(>p(Pnd6G%fF%4IW<9Q|)yge-EXDkK; z&bqm6H(Pv-XVruYZE)1tSE8MEZY!@~d4rzBhVHWsI$fjh#v9r+=WBzhY z6|uhCC54%aOSB77n31ku)W2F#w5xd?k2-EE5EMCvXCZy8zZ9ajuj$9Bs!9}vxJ}DP zS7+%z6lsxWyYkx?j9qwc7ARYjw7g1aHS=(kWrZkJHpEwy8T{ft|sr_cfEN%jkw zWc0wt20{o$aGCx<JPG&gsORkNoKMBhD#`zm@9LL_zyaT?YT?XBjIZLY55!0Pp7?@w{Z^YI``U1dTm{?wb9 zcxY71^UP5>ig@ug@MaQa)*2f**og&Kc>GL%rFSb~z6t{qkD3*>bP3<DsOnjipG=J9W?g!hA`!!`Z* z)qQcY*q95TK3J1!w)_0Vi$Fd6V9Z8Iz7#X2db#9FeDfdC7-n>xYx@&?K-CPo$F&`a z>giJ;#DL%JBYBqd527wFNd*Go&CTgTSRF$d8y@Gy#daD}s`wEJlU}}KTY>XlmYbeI z3|Z`u6lg1sKut)(Pqwj$5;ji`(%|@q!*hJd;_lpLW+!xC4T0p@0{>t)Cae z;Sdp6+(bcQBL~PPZsbY9`$cI7w@h;xcQ?ig;W9qT*t?_)dDZ7~J0U?!(v0c#Z?of{ z8Mf^6tsT|d#gnZzL`uOYCCbYYtgRDWHFZ)OS`lE|e)qI`W=Q!3BUKzHx>nKFV-S~x zi?ITJk9nAQ*-nVn^-&L)Q3{(y!xJnLh|0dG32{pLvNG&NL_Y3fyS@!u{(Sd|vv!s= zF9JDF?WQ{XfzC>Xw`(ELadk_RvrBPoAv@Fg&seBAe*i z(3u^<>mhcq8vY)dcgHsC}F$ zFg;$#)8gbhsL|Y9VxHbEzF(=Fl+iOZ&Z~;2=wp9OI?~48FT_ubVb+%Yw@j}|T?Qex zP`jk3QWf38^=R!2DrNnctcsssaD2$ab(B{5ECUn%Q_UhYA?tQ49cQ}_H25gStkty% zBjo42t5P$d0?Xtc8(kka>j{Ov=5sWgxfHJ(wOZ68yT?hB5BH1O+dw^hq#p!r$ogQw z`cPXOUDA z@A|&ra`+Se(q(0Ew+~Y8S@}IO)TxCZaZ{>ZYni^uap>a{PCC7zDa8LQjmaf86=P13 zqj;9wZNXW{cm!g-4g?lgq`B3-pQ`*&EGKEFXT!E0?XFPa%b-iqfaI}zaZSI|5Ds<> z%l-K-(WNDzZr&+Rvb>(Uw|sDs51(|g&uI*a>JFKPa5HRzxoZh26P>2cMxvuE_k_FO zw&~)T`5?Btg_n@GaC*CbN1846k}qK-UxO7AdditwvIv&Yri`cwZ;&7(8#4I3egfg5b3mW zI#jcOeA3*y6pY&`k2>)uVTb_`eI@(!EqS1-TX{WTGkJ%7UhlJE$1MuTQ8AG%uR&K} z?HQupf`hHxFfG%6=T#QmfL<5$uO6@}Ps3E7L223{?%$kxRv-HlG$U@mkfzv$vq#(H zVVm+^oP7xtG^vlcv>bII8khM#k{n_Inu#dB?3YbC#YhrSUb(BxSdkCA`dg>&$%t29C_W!-ryGGs9tBpn+uIPBmum_m?ZaxwPO3 z2JWEuM&WsRjF+P}^v~Mu!iq+*rq!FEein{sCj^3n8#U(?_rFU0;werSpy-Hd-AC1? zEEK}xKIgZ7VD8KaK>-}-{-#g1Ejw(|=jUG&T_QUwV7?Q2v=Y(WAK1;uJ-Z^Zn>C{V zkvY)KIS{ZOtS{O9nKZFGG~OaQtqgrXID|vtb1R2{te3VVJ~V!zqLF9AwE~qWDLTp?yD{+MH1KM$;#X)1U4ygS z(;y=Xr#Czt*adkgZXe+|p+MTZUxr+r7=Kb}C$C;^<$J29A4BxSxS zrx;YCchq52XA~}Hz3fjaGCI=k!~4WtmZmAl=Tn-;d5IL@O7=zNa*i8sdhRKGlzb7j zF0n(v@ga#Zp_KQ@t#R)Y%r*AoVg82OI?pXg!0xNOf0)o8of&Vz{c-)02~rhDZrtm> z_tTGL_zFuC7j{z$edGP(gQ%TT$+#2iglBxtuSu$A@xRnU7yg$c{;H`;8WnU?z+Y}| z#+@aC3&X0c>O%p0WrIT$q^8KTUm_2_2EC}r-rztKagGcd@dJw;%iMHam~7YTJ|Hz& z`nObSlrXe!`jH*f|7*s7cStv34&|4^jR1wh zE92iMwYGj_Oja+ypLYIPShUgK36{i9vpQ47vh1)&+(x*ED8hyzj_`Tm2_wyQfSqtyQD1bweM4p zma+??Exn%>tU#mQb?#9AKmnB#jgpbBNi`tj6uR~Gy+iS0+@#b-qEbcV8e}eZS6$vN z2wF^Cba`O`}v8s+NRNgT(#$g0_ET+?kgT99m8SPnOpAN^P)L(_^?|Sg zVetgXbgKula*ZSEp)L4eF?$ + + + diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs index 446f9f8d..7546500b 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs @@ -3,28 +3,154 @@ use deepgram::common::options::{Encoding, Model, Options}; use deepgram::common::stream_response::StreamResponse; use deepgram::Deepgram; +use pocketstation::connector::{ + Connector, ConnectorError, ConnectorErrorCode, ConnectorErrorStage, ConnectorRetryability, +}; +use pocketstation::{AudioFrameDuration, Session, SessionEventKind, SessionEventReceive, Source}; +use serde::Deserialize; use std::env; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; +use std::time::Duration; use tauri::{AppHandle, Emitter, State}; -use tokio::sync::{mpsc, Mutex}; +use tokio::sync::{mpsc, oneshot, Mutex}; struct AppState { - // Channel for sending audio bytes to the Deepgram worker task. - // None when no transcription session is active. - audio_tx: Arc>>>>, + active_stop: Mutex>>, +} + +#[derive(Clone, Deserialize)] +#[serde(rename_all = "snake_case")] +enum CaptureSource { + Application, + SystemAudio, + Microphone, +} + +#[derive(Clone, Deserialize)] +struct CaptureRequest { + source: CaptureSource, + application: Option, +} + +impl CaptureRequest { + fn source(&self) -> Result { + match self.source { + CaptureSource::Application => { + let application = self + .application + .as_deref() + .map(str::trim) + .filter(|value| !value.is_empty()) + .ok_or_else(|| "Enter a running application name or identifier".to_string())?; + Ok(Source::application(application)) + } + CaptureSource::SystemAudio => Ok(Source::system_audio()), + CaptureSource::Microphone => Ok(Source::microphone_default()), + } + } + + fn label(&self) -> &'static str { + match self.source { + CaptureSource::Application => "application", + CaptureSource::SystemAudio => "system audio", + CaptureSource::Microphone => "microphone", + } + } +} + +fn pcm16(samples: &[f32]) -> Vec { + let mut output = Vec::with_capacity(samples.len() * 2); + for sample in samples { + let sample = sample.clamp(-1.0, 1.0); + let value = if sample < 0.0 { + (sample * 32_768.0) as i16 + } else { + (sample * 32_767.0) as i16 + }; + output.extend_from_slice(&value.to_le_bytes()); + } + output +} + +fn delivery_error(message: impl Into) -> ConnectorError { + ConnectorError::new( + ConnectorErrorCode::new("deepgram.audio_queue_unavailable") + .expect("the example error code is valid"), + ConnectorErrorStage::Delivery, + ConnectorRetryability::Retryable, + message, + ) + .expect("the example error message is valid") +} + +fn run_capture( + app: AppHandle, + request: CaptureRequest, + audio_tx: mpsc::Sender>, + stop: Arc, +) -> Result<(), String> { + let session = Session::builder() + .audio_frame_duration(AudioFrameDuration::Ms10) + .build(); + let destination = session + .destination( + Connector::from_audio_fn(move |frame| { + audio_tx + .try_send(pcm16(frame.samples())) + .map_err(|error| delivery_error(error.to_string())) + }) + .map_err(|error| error.to_string())?, + ) + .map_err(|error| error.to_string())?; + session + .capture(request.source()?) + .map_err(|error| error.to_string())? + .send(destination) + .map_err(|error| error.to_string())?; + + let mut running = session.start().map_err(|error| error.to_string())?; + let _ = app.emit("capture-status", format!("capturing {}", request.label())); + let mut runtime_error = None; + while !stop.load(Ordering::Acquire) { + if let SessionEventReceive::Event(event) = running.try_recv_event() { + match event.kind() { + SessionEventKind::Source(_) + | SessionEventKind::Endpoint(_) + | SessionEventKind::Rollback(_) + | SessionEventKind::Finalization(_) => { + runtime_error = Some(format!( + "PocketStation reported {kind:?}", + kind = event.kind() + )); + break; + } + SessionEventKind::Lifecycle(_) | SessionEventKind::Terminal(_) => {} + } + } + std::thread::sleep(Duration::from_millis(20)); + } + + let outcome = running.stop(); + if let Some(error) = runtime_error { + Err(error) + } else if !outcome.is_success() { + Err(format!("PocketStation did not stop cleanly: {outcome:?}")) + } else { + Ok(()) + } } -// Runs the Deepgram WebSocket session: forwards audio from the mpsc channel -// to Deepgram and emits transcript events back to the Tauri frontend. async fn run_session( app: AppHandle, api_key: String, - mut audio_rx: mpsc::Receiver>, + request: CaptureRequest, + stop: Arc, ) { let dg = match Deepgram::new(&api_key) { - Ok(d) => d, - Err(e) => { - let _ = app.emit("dg-error", e.to_string()); + Ok(deepgram) => deepgram, + Err(error) => { + let _ = app.emit("dg-error", error.to_string()); return; } }; @@ -33,14 +159,15 @@ async fn run_session( .model(Model::Nova3) .smart_format(true) .punctuate(true) - .tag(["deepgram-examples"]) // <- THIS tags usage for Deepgram console tracking + .diarize(true) + .tag(["deepgram-examples"]) .build(); let mut handle = match dg .transcription() .stream_request_with_options(options) .encoding(Encoding::Linear16) - .sample_rate(16000) + .sample_rate(48000) .channels(1) .interim_results(true) .utterance_end_ms(1500) @@ -48,31 +175,53 @@ async fn run_session( .handle() .await { - Ok(h) => h, - Err(e) => { - let _ = app.emit("dg-error", e.to_string()); + Ok(handle) => handle, + Err(error) => { + let _ = app.emit("dg-error", error.to_string()); return; } }; + let (audio_tx, mut audio_rx) = mpsc::channel::>(32); + let (capture_done_tx, mut capture_done_rx) = oneshot::channel(); + let capture_app = app.clone(); + let capture_stop = Arc::clone(&stop); + tokio::task::spawn_blocking(move || { + let result = run_capture(capture_app, request, audio_tx, capture_stop); + let _ = capture_done_tx.send(result); + }); + let _ = app.emit("dg-status", "connected"); + let mut capture_finished = false; - // Single loop that multiplexes audio sending and response receiving. - // tokio::select! lets us await both the audio channel and the Deepgram - // WebSocket concurrently without needing to split the handle. loop { tokio::select! { biased; + capture = &mut capture_done_rx => { + capture_finished = true; + match capture { + Ok(Ok(())) => { + let _ = handle.close_stream().await; + } + Ok(Err(error)) => { + let _ = app.emit("dg-error", error); + } + Err(error) => { + let _ = app.emit("dg-error", error.to_string()); + } + } + break; + } + audio = audio_rx.recv() => { match audio { Some(data) => { - if let Err(e) = handle.send_data(data).await { - let _ = app.emit("dg-error", e.to_string()); + if let Err(error) = handle.send_data(data).await { + let _ = app.emit("dg-error", error.to_string()); break; } } - // Frontend closed the channel — finalize None => { let _ = handle.close_stream().await; break; @@ -80,24 +229,24 @@ async fn run_session( } } - resp = handle.receive() => { - match resp { + response = handle.receive() => { + match response { Some(Ok(StreamResponse::TranscriptResponse { channel, is_final, speech_final, .. })) => { - // channel.alternatives[0].transcript holds the text - if let Some(alt) = channel.alternatives.first() { - if !alt.transcript.is_empty() { + if let Some(alternative) = channel.alternatives.first() { + if !alternative.transcript.is_empty() { let _ = app.emit( "transcript", serde_json::json!({ - "text": alt.transcript, + "text": alternative.transcript, "is_final": is_final, "speech_final": speech_final, - "confidence": alt.confidence, + "confidence": alternative.confidence, + "speaker": alternative.words.first().and_then(|word| word.speaker), }), ); } @@ -111,8 +260,8 @@ async fn run_session( let _ = app.emit("utterance-end", ""); } Some(Ok(_)) => {} - Some(Err(e)) => { - let _ = app.emit("dg-error", e.to_string()); + Some(Err(error)) => { + let _ = app.emit("dg-error", error.to_string()); break; } None => { @@ -124,6 +273,12 @@ async fn run_session( } } + stop.store(true, Ordering::Release); + if !capture_finished { + if let Ok(Err(error)) = capture_done_rx.await { + let _ = app.emit("dg-error", error); + } + } let _ = app.emit("dg-status", "disconnected"); } @@ -131,65 +286,64 @@ async fn run_session( async fn start_transcription( app: AppHandle, state: State<'_, AppState>, + request: CaptureRequest, ) -> Result<(), String> { - let api_key = env::var("DEEPGRAM_API_KEY") - .map_err(|_| "DEEPGRAM_API_KEY not set".to_string())?; + let api_key = + env::var("DEEPGRAM_API_KEY").map_err(|_| "DEEPGRAM_API_KEY is not set".to_string())?; - // Stop any existing session first + let stop = Arc::new(AtomicBool::new(false)); { - let mut tx_guard = state.audio_tx.lock().await; - tx_guard.take(); - } - - // Buffered channel — frontend sends audio chunks here; the worker - // forwards them to Deepgram's WebSocket. - let (audio_tx, audio_rx) = mpsc::channel::>(512); - - { - let mut tx_guard = state.audio_tx.lock().await; - *tx_guard = Some(audio_tx); + let mut active = state.active_stop.lock().await; + if let Some(previous) = active.replace(Arc::clone(&stop)) { + previous.store(true, Ordering::Release); + } } - tokio::spawn(run_session(app, api_key, audio_rx)); - + tokio::spawn(run_session(app, api_key, request, stop)); Ok(()) } #[tauri::command] -async fn send_audio( - state: State<'_, AppState>, - audio: Vec, -) -> Result<(), String> { - let tx_guard = state.audio_tx.lock().await; - if let Some(tx) = tx_guard.as_ref() { - tx.send(audio).await.map_err(|e| e.to_string())?; +async fn stop_transcription(state: State<'_, AppState>) -> Result<(), String> { + if let Some(stop) = state.active_stop.lock().await.take() { + stop.store(true, Ordering::Release); } Ok(()) } -#[tauri::command] -async fn stop_transcription( - state: State<'_, AppState>, -) -> Result<(), String> { - let mut tx_guard = state.audio_tx.lock().await; - // Dropping the sender closes the channel, which signals the worker - // to finalize and disconnect from Deepgram. - tx_guard.take(); - Ok(()) -} - fn main() { dotenvy::dotenv().ok(); tauri::Builder::default() .manage(AppState { - audio_tx: Arc::new(Mutex::new(None)), + active_stop: Mutex::new(None), }) .invoke_handler(tauri::generate_handler![ start_transcription, - send_audio, stop_transcription, ]) .run(tauri::generate_context!()) - .expect("error while running tauri application"); + .expect("error while running Tauri application"); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pcm_conversion_clamps_and_encodes_little_endian_samples() { + assert_eq!( + pcm16(&[-2.0, -1.0, 0.0, 1.0, 2.0]), + vec![0, 128, 0, 128, 0, 0, 255, 127, 255, 127] + ); + } + + #[test] + fn application_capture_requires_a_name() { + let request = CaptureRequest { + source: CaptureSource::Application, + application: Some(" ".to_string()), + }; + assert!(request.source().is_err()); + } } diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts b/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts index ba55be80..27321a9d 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts +++ b/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts @@ -4,110 +4,122 @@ import { listen } from "@tauri-apps/api/event"; const transcriptEl = document.getElementById("transcript")!; const btnStart = document.getElementById("btn-start") as HTMLButtonElement; const btnStop = document.getElementById("btn-stop") as HTMLButtonElement; +const btnCopy = document.getElementById("btn-copy") as HTMLButtonElement; const statusEl = document.getElementById("status")!; +const sourceEl = document.getElementById("capture-source") as HTMLSelectElement; +const applicationRow = document.getElementById("application-row")!; +const applicationEl = document.getElementById("application") as HTMLInputElement; const MAX_LINES = 6; const finalLines: string[] = []; let currentInterim = ""; -let mediaStream: MediaStream | null = null; -let audioContext: AudioContext | null = null; -let processorNode: ScriptProcessorNode | null = null; - -function renderTranscript() { - const visible = finalLines.slice(-MAX_LINES); - let html = visible.map((l) => `${l}`).join("
"); - if (currentInterim) { - html += `
${currentInterim}`; +function appendLine(text: string, className?: string) { + const line = document.createElement("span"); + line.textContent = text; + if (className) line.className = className; + if (transcriptEl.childNodes.length > 0) { + transcriptEl.append(document.createElement("br")); } - transcriptEl.innerHTML = html || "Listening..."; + transcriptEl.append(line); } -// Capture microphone at 16 kHz, convert float32 to linear16 PCM, -// and forward each chunk to the Rust backend via Tauri command. -async function startAudioCapture() { - mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true }); - - // 16 kHz matches the Deepgram encoding config exactly - audioContext = new AudioContext({ sampleRate: 16000 }); - const source = audioContext.createMediaStreamSource(mediaStream); - - // ScriptProcessorNode is deprecated but universally supported in - // WebView contexts. AudioWorklet is the modern alternative but adds - // file complexity not warranted for this example. - processorNode = audioContext.createScriptProcessor(4096, 1, 1); - - processorNode.onaudioprocess = (event: AudioProcessingEvent) => { - const float32 = event.inputBuffer.getChannelData(0); - - // Convert float32 [-1, 1] → signed 16-bit PCM - const int16 = new Int16Array(float32.length); - for (let i = 0; i < float32.length; i++) { - const s = Math.max(-1, Math.min(1, float32[i])); - int16[i] = s < 0 ? s * 0x8000 : s * 0x7fff; - } +function renderTranscript() { + transcriptEl.replaceChildren(); + for (const line of finalLines.slice(-MAX_LINES)) appendLine(line); + if (currentInterim) appendLine(currentInterim, "interim"); + if (transcriptEl.childNodes.length === 0) transcriptEl.textContent = "Listening..."; +} - invoke("send_audio", { audio: Array.from(new Uint8Array(int16.buffer)) }); - }; +function updateApplicationInput() { + const capturesApplication = sourceEl.value === "application"; + applicationRow.hidden = !capturesApplication; + applicationEl.required = capturesApplication; +} - source.connect(processorNode); - processorNode.connect(audioContext.destination); +function resetControls() { + btnStart.disabled = false; + btnStop.disabled = true; + btnStart.classList.remove("active"); + btnStop.classList.remove("active"); + sourceEl.disabled = false; + applicationEl.disabled = false; } -function stopAudioCapture() { - if (processorNode) { - processorNode.disconnect(); - processorNode = null; - } - if (audioContext) { - audioContext.close(); - audioContext = null; - } - if (mediaStream) { - mediaStream.getTracks().forEach((t) => t.stop()); - mediaStream = null; - } +function displayText(text: string, speaker: number | null) { + return speaker === null ? text : `Speaker ${speaker + 1}: ${text}`; } +sourceEl.addEventListener("change", updateApplicationInput); +updateApplicationInput(); + btnStart.addEventListener("click", async () => { + if (sourceEl.value === "application" && !applicationEl.value.trim()) { + applicationEl.focus(); + applicationEl.reportValidity(); + return; + } + btnStart.disabled = true; btnStop.disabled = false; btnStart.classList.add("active"); - btnStop.classList.remove("active"); - + sourceEl.disabled = true; + applicationEl.disabled = true; finalLines.length = 0; currentInterim = ""; transcriptEl.textContent = "Connecting..."; - await invoke("start_transcription"); - await startAudioCapture(); + try { + await invoke("start_transcription", { + request: { + source: sourceEl.value, + application: applicationEl.value.trim() || null, + }, + }); + } catch (error) { + statusEl.textContent = `error: ${String(error)}`; + statusEl.className = "status error"; + resetControls(); + } }); btnStop.addEventListener("click", async () => { btnStop.disabled = true; - btnStart.disabled = false; - btnStop.classList.remove("active"); - btnStart.classList.remove("active"); - - stopAudioCapture(); await invoke("stop_transcription"); + resetControls(); statusEl.textContent = "disconnected"; statusEl.className = "status"; }); -listen<{ text: string; is_final: boolean; speech_final: boolean; confidence: number }>( +btnCopy.addEventListener("click", async () => { + const transcript = finalLines.join("\n"); + if (transcript) await navigator.clipboard.writeText(transcript); +}); + +listen<{ + text: string; + is_final: boolean; + speech_final: boolean; + confidence: number; + speaker: number | null; +}>( "transcript", (event) => { if (event.payload.is_final) { - finalLines.push(event.payload.text); + finalLines.push(displayText(event.payload.text, event.payload.speaker)); currentInterim = ""; } else { - currentInterim = event.payload.text; + currentInterim = displayText(event.payload.text, event.payload.speaker); } renderTranscript(); - } + }, ); +listen("capture-status", (event) => { + statusEl.textContent = event.payload; + statusEl.className = "status connected"; +}); + listen("dg-status", (event) => { statusEl.textContent = event.payload; statusEl.className = `status ${event.payload}`; @@ -116,6 +128,7 @@ listen("dg-status", (event) => { listen("dg-error", (event) => { statusEl.textContent = `error: ${event.payload}`; statusEl.className = "status error"; + resetControls(); }); listen("utterance-end", () => { diff --git a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py index b3586076..e09a4097 100644 --- a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py +++ b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py @@ -1,32 +1,25 @@ """Test the Tauri desktop live transcription example. -The Tauri desktop app requires a full build toolchain (Rust, system WebView, -and a display). This test verifies the example's correctness by inspecting -source files directly — the Rust backend, Tauri configuration, and TypeScript -frontend — without building or running the app. +These tests inspect the Rust backend, Tauri configuration, and TypeScript +frontend without starting a desktop window. Run the application for the real +Deepgram and native capture check described in the README. """ +import json import os import sys -import json from pathlib import Path -# ── Credential check ──────────────────────────────────────────────────────── -# Exit code convention across all examples in this repo: -# 0 = all tests passed -# 1 = real test failure (code bug, assertion error, unexpected API response) -# 2 = missing credentials (expected in CI until secrets are configured) env_example = Path(__file__).parent.parent / ".env.example" required = [ line.split("=")[0].strip() for line in env_example.read_text().splitlines() if line and not line.startswith("#") and "=" in line and line[0].isupper() ] -missing = [k for k in required if not os.environ.get(k)] +missing = [key for key in required if not os.environ.get(key)] if missing: print(f"MISSING_CREDENTIALS: {','.join(missing)}", file=sys.stderr) sys.exit(2) -# ──────────────────────────────────────────────────────────────────────────── ROOT = Path(__file__).parent.parent @@ -38,116 +31,87 @@ def test_file_structure(): "README.md", "src/src-tauri/src/main.rs", "src/src-tauri/Cargo.toml", + "src/src-tauri/Info.plist", "src/src-tauri/tauri.conf.json", "src/src/main.ts", "src/index.html", "src/package.json", ] - for f in required_files: - full = ROOT / f - assert full.exists(), f"Missing required file: {f}" - print("File structure check passed") + for relative_path in required_files: + assert (ROOT / relative_path).exists(), f"Missing required file: {relative_path}" -def test_rust_source_uses_deepgram_sdk(): - """Verify the Rust source uses the Deepgram SDK correctly.""" +def test_rust_owns_capture_and_deepgram(): + """Verify Rust owns native capture and the Deepgram connection.""" main_rs = (ROOT / "src" / "src-tauri" / "src" / "main.rs").read_text() - assert "deepgram::Deepgram" in main_rs or "use deepgram" in main_rs, \ - "main.rs does not import the Deepgram SDK" - assert "deepgram-examples" in main_rs, \ - "main.rs missing required tag 'deepgram-examples'" - assert "Model::Nova3" in main_rs, \ - "main.rs should use Nova3 model" - assert "DEEPGRAM_API_KEY" in main_rs, \ - "main.rs should read DEEPGRAM_API_KEY from environment" - assert "send_audio" in main_rs, \ - "main.rs should expose send_audio Tauri command" - assert "start_transcription" in main_rs, \ - "main.rs should expose start_transcription Tauri command" - - print("Rust source validation passed") - - -def test_cargo_toml_pins_deepgram(): - """Verify Cargo.toml declares the deepgram crate dependency.""" + assert "deepgram::Deepgram" in main_rs or "use deepgram" in main_rs + assert "deepgram-examples" in main_rs + assert "Model::Nova3" in main_rs + assert ".diarize(true)" in main_rs + assert "DEEPGRAM_API_KEY" in main_rs + assert "start_transcription" in main_rs + assert "pocketstation" in main_rs + assert "Source::application" in main_rs + assert "Source::system_audio" in main_rs + assert "Source::microphone_default" in main_rs + assert "Connector::from_audio_fn" in main_rs + + +def test_cargo_dependencies_are_pinned(): + """Verify the example uses released Deepgram and PocketStation crates.""" cargo_toml = (ROOT / "src" / "src-tauri" / "Cargo.toml").read_text() - assert "deepgram" in cargo_toml, \ - "Cargo.toml must declare the deepgram crate as a dependency" - assert "0.9.2" in cargo_toml, \ - "Cargo.toml should pin deepgram at version 0.9.2" - assert "tauri" in cargo_toml, \ - "Cargo.toml must declare the tauri crate as a dependency" - - print("Cargo.toml declares deepgram and tauri dependencies") - + assert 'deepgram = "=0.9.2"' in cargo_toml + assert 'pocketstation = "=1.1.9"' in cargo_toml + assert "tauri" in cargo_toml -def test_tauri_conf_settings(): - """Verify tauri.conf.json has the expected app configuration.""" - conf_path = ROOT / "src" / "src-tauri" / "tauri.conf.json" - conf = json.loads(conf_path.read_text()) +def test_tauri_configuration(): + """Verify the desktop window and application identity.""" + conf = json.loads((ROOT / "src" / "src-tauri" / "tauri.conf.json").read_text()) product_name = conf.get("productName", "") - assert "deepgram" in product_name.lower() or "transcription" in product_name.lower(), \ - f"tauri.conf.json productName should reference Deepgram or Transcription, got: {product_name}" - - # App identifier should follow reverse-domain convention identifier = conf.get("identifier", "") - assert "deepgram" in identifier.lower(), \ - f"tauri.conf.json identifier should include 'deepgram', got: {identifier}" - - # Must define at least one window windows = conf.get("app", {}).get("windows", []) - assert len(windows) > 0, \ - "tauri.conf.json must define at least one window" - - assert windows[0].get("width", 0) > 0, "Window width must be positive" - assert windows[0].get("height", 0) > 0, "Window height must be positive" - print(f"tauri.conf.json settings valid:") - print(f" productName: {product_name}") - print(f" identifier: {identifier}") - print(f" window: {windows[0].get('width')}x{windows[0].get('height')}") + assert "deepgram" in product_name.lower() or "transcription" in product_name.lower() + assert "deepgram" in identifier.lower() + assert windows + assert windows[0].get("width", 0) > 0 + assert windows[0].get("height", 0) > 0 -def test_typescript_frontend_uses_tauri_invoke(): - """Verify the TypeScript frontend calls the Rust backend via Tauri's invoke().""" +def test_frontend_selects_native_capture(): + """Verify the frontend requests one explicit native source.""" main_ts = (ROOT / "src" / "src" / "main.ts").read_text() + index_html = (ROOT / "src" / "index.html").read_text() - assert 'from "@tauri-apps/api/core"' in main_ts or \ - 'from "@tauri-apps/api"' in main_ts, \ - "main.ts must import from @tauri-apps/api" - assert "invoke" in main_ts, \ - "main.ts must call invoke() to communicate with the Rust backend" - assert "start_transcription" in main_ts, \ - "main.ts must invoke start_transcription Tauri command" - assert "send_audio" in main_ts, \ - "main.ts must invoke send_audio Tauri command" - assert "stop_transcription" in main_ts, \ - "main.ts must invoke stop_transcription Tauri command" + assert 'from "@tauri-apps/api/core"' in main_ts + assert "start_transcription" in main_ts + assert "stop_transcription" in main_ts + assert "getUserMedia" not in main_ts + assert "send_audio" not in main_ts + assert "capture-source" in main_ts + assert 'value="application"' in index_html + assert 'value="system_audio"' in index_html + assert 'value="microphone"' in index_html + assert 'id="application"' in index_html + assert 'id="btn-copy"' in index_html - print("TypeScript frontend correctly uses Tauri invoke() for backend communication") - - -def test_typescript_frontend_audio_capture(): - """Verify the TypeScript frontend captures microphone audio for Deepgram.""" - main_ts = (ROOT / "src" / "src" / "main.ts").read_text() - assert "getUserMedia" in main_ts, \ - "main.ts must use getUserMedia to capture microphone audio" - # 16000 Hz matches the Deepgram linear16 encoding config in main.rs - assert "16000" in main_ts, \ - "main.ts should configure audio at 16000 Hz to match Deepgram encoding" +def test_macos_permission_descriptions(): + """Verify packaged macOS builds explain both permission requests.""" + info_plist = (ROOT / "src" / "src-tauri" / "Info.plist").read_text() - print("TypeScript frontend captures microphone audio at 16 kHz for Deepgram") + assert "NSMicrophoneUsageDescription" in info_plist + assert "NSScreenCaptureUsageDescription" in info_plist if __name__ == "__main__": test_file_structure() - test_rust_source_uses_deepgram_sdk() - test_cargo_toml_pins_deepgram() - test_tauri_conf_settings() - test_typescript_frontend_uses_tauri_invoke() - test_typescript_frontend_audio_capture() - print("\nAll tests passed") + test_rust_owns_capture_and_deepgram() + test_cargo_dependencies_are_pinned() + test_tauri_configuration() + test_frontend_selects_native_capture() + test_macos_permission_descriptions() + print("All tests passed") From 734980cd12422b8ed9934a8817c59690d49b835a Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 14:52:39 +0200 Subject: [PATCH 2/8] fix: qualify native capture example --- .../README.md | 16 +-- .../src/index.html | 1 + .../src/src-tauri/Cargo.lock | 33 +----- .../src/src-tauri/Cargo.toml | 11 +- .../src/src-tauri/src/main.rs | 101 +++++++++++++----- .../src/src/main.ts | 24 +++++ .../tests/test_example.py | 8 +- 7 files changed, 127 insertions(+), 67 deletions(-) diff --git a/examples/340-tauri-live-transcription-rust-ts/README.md b/examples/340-tauri-live-transcription-rust-ts/README.md index 2363787a..228a451b 100644 --- a/examples/340-tauri-live-transcription-rust-ts/README.md +++ b/examples/340-tauri-live-transcription-rust-ts/README.md @@ -17,14 +17,10 @@ microphone**. ## Run the application -Create the local environment file and set your Deepgram API key: +Set your Deepgram API key in the shell that will start Tauri: ```bash -cp .env.example .env -``` - -```text -DEEPGRAM_API_KEY=your_api_key +export DEEPGRAM_API_KEY="your_api_key" ``` Install the frontend packages and start Tauri: @@ -47,6 +43,10 @@ Start the application you want to capture before clicking **Start**. If more than one application matches the value you entered, PocketStation reports the ambiguity instead of choosing one silently. +Use **Pause** to stop sending audio to Deepgram while keeping the selected +native source open. **Resume** continues with new audio; audio produced while +paused is intentionally not transcribed. + ## Permissions macOS asks separately for microphone access and for Screen & System Audio @@ -61,9 +61,9 @@ PipeWire and may display a desktop portal depending on the compositor. ```text selected native source ↓ -PocketStation 10 ms mono frames at 48 kHz +PocketStation 10 ms frames at 48 kHz ↓ -linear16 conversion in a PocketStation Connector +mono downmix and linear16 conversion in a PocketStation Connector ↓ Deepgram streaming transcription ↓ diff --git a/examples/340-tauri-live-transcription-rust-ts/src/index.html b/examples/340-tauri-live-transcription-rust-ts/src/index.html index fe47dfcd..571a9da6 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/index.html +++ b/examples/340-tauri-live-transcription-rust-ts/src/index.html @@ -144,6 +144,7 @@

Deepgram Live Transcription

+ disconnected diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock index b6dd96d6..38e1d0dc 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock @@ -125,17 +125,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "audiopus_sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62314a1546a2064e033665d658e88c620a62904be945f8147e6b16c3db9f8651" -dependencies = [ - "cmake", - "log", - "pkg-config", -] - [[package]] name = "autocfg" version = "1.5.0" @@ -747,7 +736,6 @@ name = "deepgram-tauri-live-transcription" version = "0.1.0" dependencies = [ "deepgram", - "dotenvy", "pocketstation", "serde", "serde_json", @@ -892,12 +880,6 @@ dependencies = [ "tendril 0.5.0", ] -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - [[package]] name = "dpi" version = "0.1.2" @@ -2603,15 +2585,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "opus" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d3809943dff6fbad5f0484449ea26bdb9cb7d8efdf26ed50d3c7f227f69eb5c" -dependencies = [ - "audiopus_sys", -] - [[package]] name = "pango" version = "0.18.3" @@ -2938,17 +2911,15 @@ dependencies = [ [[package]] name = "pocketstation" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5b0d839d6ab60633c337dd58646eb09d8a4e215415471bb4283802a073d634" +checksum = "eeb23694072ba182d17175e966fe75c67a18632de517e7d78d6197af3d23a127" dependencies = [ - "alsa", "cc", "cpal", "hound", "libc", "libloading 0.8.9", - "opus", "pipewire", "rtrb", "serde", diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml index aeae75ae..81d8a7fe 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml @@ -5,8 +5,6 @@ edition = "2021" [dependencies] deepgram = "=0.9.2" -dotenvy = "=0.15.7" -pocketstation = "=1.1.9" serde = { version = "=1.0.228", features = ["derive"] } serde_json = "=1.0.149" tauri = { version = "=2.10.3", features = [] } @@ -14,3 +12,12 @@ tokio = { version = "=1.51.0", features = ["full"] } [build-dependencies] tauri-build = { version = "=2.5.6", features = [] } + +[target.'cfg(target_os = "macos")'.dependencies] +pocketstation = { version = "=1.1.10", default-features = false, features = ["coreaudio-capture"] } + +[target.'cfg(target_os = "windows")'.dependencies] +pocketstation = { version = "=1.1.10", default-features = false, features = ["wasapi-capture"] } + +[target.'cfg(target_os = "linux")'.dependencies] +pocketstation = { version = "=1.1.10", default-features = false, features = ["pipewire-capture"] } diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs index 7546500b..fe7a0675 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs @@ -16,7 +16,12 @@ use tauri::{AppHandle, Emitter, State}; use tokio::sync::{mpsc, oneshot, Mutex}; struct AppState { - active_stop: Mutex>>, + active: Mutex>, +} + +struct ActiveTranscription { + stop: Arc, + paused: Arc, } #[derive(Clone, Deserialize)] @@ -59,9 +64,20 @@ impl CaptureRequest { } } -fn pcm16(samples: &[f32]) -> Vec { - let mut output = Vec::with_capacity(samples.len() * 2); - for sample in samples { +fn pcm16_mono(samples: &[f32], channels: u8) -> Result, &'static str> { + let channels = usize::from(channels); + if channels == 0 { + return Err("PocketStation returned an invalid channel layout"); + } + + let frames = samples.chunks_exact(channels); + if !frames.remainder().is_empty() { + return Err("PocketStation returned an invalid channel layout"); + } + + let mut output = Vec::with_capacity(samples.len() / channels * 2); + for frame in frames { + let sample = frame.iter().copied().sum::() / channels as f32; let sample = sample.clamp(-1.0, 1.0); let value = if sample < 0.0 { (sample * 32_768.0) as i16 @@ -70,7 +86,7 @@ fn pcm16(samples: &[f32]) -> Vec { }; output.extend_from_slice(&value.to_le_bytes()); } - output + Ok(output) } fn delivery_error(message: impl Into) -> ConnectorError { @@ -89,6 +105,7 @@ fn run_capture( request: CaptureRequest, audio_tx: mpsc::Sender>, stop: Arc, + paused: Arc, ) -> Result<(), String> { let session = Session::builder() .audio_frame_duration(AudioFrameDuration::Ms10) @@ -96,8 +113,18 @@ fn run_capture( let destination = session .destination( Connector::from_audio_fn(move |frame| { + if paused.load(Ordering::Acquire) { + return Ok(()); + } + if frame.sample_rate_hz() != 48_000 { + return Err(delivery_error(format!( + "Deepgram expects 48000 Hz audio; PocketStation returned {} Hz", + frame.sample_rate_hz() + ))); + } + let data = pcm16_mono(frame.samples(), frame.channels()).map_err(delivery_error)?; audio_tx - .try_send(pcm16(frame.samples())) + .try_send(data) .map_err(|error| delivery_error(error.to_string())) }) .map_err(|error| error.to_string())?, @@ -131,13 +158,22 @@ fn run_capture( std::thread::sleep(Duration::from_millis(20)); } - let outcome = running.stop(); if let Some(error) = runtime_error { - Err(error) - } else if !outcome.is_success() { - Err(format!("PocketStation did not stop cleanly: {outcome:?}")) + let outcome = running.cancel(); + if outcome.is_success() { + Err(error) + } else { + Err(format!( + "{error}; PocketStation cancellation failed: {outcome:?}" + )) + } } else { - Ok(()) + let outcome = running.stop(); + if !outcome.is_success() { + Err(format!("PocketStation did not stop cleanly: {outcome:?}")) + } else { + Ok(()) + } } } @@ -146,6 +182,7 @@ async fn run_session( api_key: String, request: CaptureRequest, stop: Arc, + paused: Arc, ) { let dg = match Deepgram::new(&api_key) { Ok(deepgram) => deepgram, @@ -186,8 +223,9 @@ async fn run_session( let (capture_done_tx, mut capture_done_rx) = oneshot::channel(); let capture_app = app.clone(); let capture_stop = Arc::clone(&stop); + let capture_paused = Arc::clone(&paused); tokio::task::spawn_blocking(move || { - let result = run_capture(capture_app, request, audio_tx, capture_stop); + let result = run_capture(capture_app, request, audio_tx, capture_stop, capture_paused); let _ = capture_done_tx.send(result); }); @@ -292,35 +330,48 @@ async fn start_transcription( env::var("DEEPGRAM_API_KEY").map_err(|_| "DEEPGRAM_API_KEY is not set".to_string())?; let stop = Arc::new(AtomicBool::new(false)); + let paused = Arc::new(AtomicBool::new(false)); { - let mut active = state.active_stop.lock().await; - if let Some(previous) = active.replace(Arc::clone(&stop)) { - previous.store(true, Ordering::Release); + let mut active = state.active.lock().await; + if let Some(previous) = active.replace(ActiveTranscription { + stop: Arc::clone(&stop), + paused: Arc::clone(&paused), + }) { + previous.stop.store(true, Ordering::Release); } } - tokio::spawn(run_session(app, api_key, request, stop)); + tokio::spawn(run_session(app, api_key, request, stop, paused)); Ok(()) } #[tauri::command] async fn stop_transcription(state: State<'_, AppState>) -> Result<(), String> { - if let Some(stop) = state.active_stop.lock().await.take() { - stop.store(true, Ordering::Release); + if let Some(active) = state.active.lock().await.take() { + active.stop.store(true, Ordering::Release); } Ok(()) } -fn main() { - dotenvy::dotenv().ok(); +#[tauri::command] +async fn set_transcription_paused(state: State<'_, AppState>, paused: bool) -> Result<(), String> { + let active = state.active.lock().await; + let transcription = active + .as_ref() + .ok_or_else(|| "No transcription is running".to_string())?; + transcription.paused.store(paused, Ordering::Release); + Ok(()) +} +fn main() { tauri::Builder::default() .manage(AppState { - active_stop: Mutex::new(None), + active: Mutex::new(None), }) .invoke_handler(tauri::generate_handler![ start_transcription, stop_transcription, + set_transcription_paused, ]) .run(tauri::generate_context!()) .expect("error while running Tauri application"); @@ -331,15 +382,15 @@ mod tests { use super::*; #[test] - fn pcm_conversion_clamps_and_encodes_little_endian_samples() { + fn given_stereo_samples_when_converted_then_pcm_is_downmixed_and_clamped() { assert_eq!( - pcm16(&[-2.0, -1.0, 0.0, 1.0, 2.0]), - vec![0, 128, 0, 128, 0, 0, 255, 127, 255, 127] + pcm16_mono(&[-2.0, -2.0, 0.0, 0.0, 2.0, 2.0], 2), + Ok(vec![0, 128, 0, 0, 255, 127]) ); } #[test] - fn application_capture_requires_a_name() { + fn given_blank_application_when_selected_then_configuration_is_rejected() { let request = CaptureRequest { source: CaptureSource::Application, application: Some(" ".to_string()), diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts b/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts index 27321a9d..8100a4e9 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts +++ b/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts @@ -4,6 +4,7 @@ import { listen } from "@tauri-apps/api/event"; const transcriptEl = document.getElementById("transcript")!; const btnStart = document.getElementById("btn-start") as HTMLButtonElement; const btnStop = document.getElementById("btn-stop") as HTMLButtonElement; +const btnPause = document.getElementById("btn-pause") as HTMLButtonElement; const btnCopy = document.getElementById("btn-copy") as HTMLButtonElement; const statusEl = document.getElementById("status")!; const sourceEl = document.getElementById("capture-source") as HTMLSelectElement; @@ -13,6 +14,7 @@ const applicationEl = document.getElementById("application") as HTMLInputElement const MAX_LINES = 6; const finalLines: string[] = []; let currentInterim = ""; +let paused = false; function appendLine(text: string, className?: string) { const line = document.createElement("span"); @@ -40,6 +42,10 @@ function updateApplicationInput() { function resetControls() { btnStart.disabled = false; btnStop.disabled = true; + btnPause.disabled = true; + btnPause.textContent = "Pause"; + btnPause.classList.remove("active"); + paused = false; btnStart.classList.remove("active"); btnStop.classList.remove("active"); sourceEl.disabled = false; @@ -62,6 +68,7 @@ btnStart.addEventListener("click", async () => { btnStart.disabled = true; btnStop.disabled = false; + btnPause.disabled = false; btnStart.classList.add("active"); sourceEl.disabled = true; applicationEl.disabled = true; @@ -85,12 +92,28 @@ btnStart.addEventListener("click", async () => { btnStop.addEventListener("click", async () => { btnStop.disabled = true; + btnPause.disabled = true; await invoke("stop_transcription"); resetControls(); statusEl.textContent = "disconnected"; statusEl.className = "status"; }); +btnPause.addEventListener("click", async () => { + const nextPaused = !paused; + try { + await invoke("set_transcription_paused", { paused: nextPaused }); + paused = nextPaused; + btnPause.textContent = paused ? "Resume" : "Pause"; + btnPause.classList.toggle("active", paused); + statusEl.textContent = paused ? "paused" : "connected"; + statusEl.className = paused ? "status" : "status connected"; + } catch (error) { + statusEl.textContent = `error: ${String(error)}`; + statusEl.className = "status error"; + } +}); + btnCopy.addEventListener("click", async () => { const transcript = finalLines.join("\n"); if (transcript) await navigator.clipboard.writeText(transcript); @@ -123,6 +146,7 @@ listen("capture-status", (event) => { listen("dg-status", (event) => { statusEl.textContent = event.payload; statusEl.className = `status ${event.payload}`; + if (event.payload === "disconnected") resetControls(); }); listen("dg-error", (event) => { diff --git a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py index e09a4097..984201de 100644 --- a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py +++ b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py @@ -51,6 +51,7 @@ def test_rust_owns_capture_and_deepgram(): assert ".diarize(true)" in main_rs assert "DEEPGRAM_API_KEY" in main_rs assert "start_transcription" in main_rs + assert "set_transcription_paused" in main_rs assert "pocketstation" in main_rs assert "Source::application" in main_rs assert "Source::system_audio" in main_rs @@ -63,7 +64,10 @@ def test_cargo_dependencies_are_pinned(): cargo_toml = (ROOT / "src" / "src-tauri" / "Cargo.toml").read_text() assert 'deepgram = "=0.9.2"' in cargo_toml - assert 'pocketstation = "=1.1.9"' in cargo_toml + assert cargo_toml.count('pocketstation = { version = "=1.1.10"') == 3 + assert 'features = ["coreaudio-capture"]' in cargo_toml + assert 'features = ["wasapi-capture"]' in cargo_toml + assert 'features = ["pipewire-capture"]' in cargo_toml assert "tauri" in cargo_toml @@ -89,6 +93,7 @@ def test_frontend_selects_native_capture(): assert 'from "@tauri-apps/api/core"' in main_ts assert "start_transcription" in main_ts assert "stop_transcription" in main_ts + assert "set_transcription_paused" in main_ts assert "getUserMedia" not in main_ts assert "send_audio" not in main_ts assert "capture-source" in main_ts @@ -97,6 +102,7 @@ def test_frontend_selects_native_capture(): assert 'value="microphone"' in index_html assert 'id="application"' in index_html assert 'id="btn-copy"' in index_html + assert 'id="btn-pause"' in index_html def test_macos_permission_descriptions(): From cc1822867ebfc7830edc7199e03a18c6c6d5669e Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 15:08:14 +0200 Subject: [PATCH 3/8] chore: use current Deepgram and Tauri releases --- .../README.md | 2 +- .../src/package.json | 4 +- .../src/pnpm-lock.yaml | 111 +-- .../src/src-tauri/Cargo.lock | 716 +++++------------- .../src/src-tauri/Cargo.toml | 6 +- .../tests/test_example.py | 3 +- 6 files changed, 275 insertions(+), 567 deletions(-) diff --git a/examples/340-tauri-live-transcription-rust-ts/README.md b/examples/340-tauri-live-transcription-rust-ts/README.md index 228a451b..5aadb8cc 100644 --- a/examples/340-tauri-live-transcription-rust-ts/README.md +++ b/examples/340-tauri-live-transcription-rust-ts/README.md @@ -10,7 +10,7 @@ microphone**. ## Prerequisites -- [Rust](https://www.rust-lang.org/tools/install) 1.85 or later +- The current stable [Rust toolchain](https://www.rust-lang.org/tools/install) - [Node.js](https://nodejs.org/) 18 or later - The [Tauri 2 prerequisites](https://v2.tauri.app/start/prerequisites/) for your operating system - A [Deepgram API key](https://console.deepgram.com/) diff --git a/examples/340-tauri-live-transcription-rust-ts/src/package.json b/examples/340-tauri-live-transcription-rust-ts/src/package.json index 2cc7b1db..f465a89d 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/package.json +++ b/examples/340-tauri-live-transcription-rust-ts/src/package.json @@ -10,10 +10,10 @@ "tauri": "tauri" }, "dependencies": { - "@tauri-apps/api": "2.2.0" + "@tauri-apps/api": "2.11.1" }, "devDependencies": { - "@tauri-apps/cli": "2.2.0", + "@tauri-apps/cli": "2.11.4", "typescript": "5.7.3", "vite": "6.4.2" } diff --git a/examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml b/examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml index bdc43537..7704fa96 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml +++ b/examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml @@ -9,12 +9,12 @@ importers: .: dependencies: '@tauri-apps/api': - specifier: 2.2.0 - version: 2.2.0 + specifier: 2.11.1 + version: 2.11.1 devDependencies: '@tauri-apps/cli': - specifier: 2.2.0 - version: 2.2.0 + specifier: 2.11.4 + version: 2.11.4 typescript: specifier: 5.7.3 version: 5.7.3 @@ -318,75 +318,82 @@ packages: cpu: [x64] os: [win32] - '@tauri-apps/api@2.2.0': - resolution: {integrity: sha512-R8epOeZl1eJEl603aUMIGb4RXlhPjpgxbGVEaqY+0G5JG9vzV/clNlzTeqc+NLYXVqXcn8mb4c5b9pJIUDEyAg==} + '@tauri-apps/api@2.11.1': + resolution: {integrity: sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==} - '@tauri-apps/cli-darwin-arm64@2.2.0': - resolution: {integrity: sha512-Paxq9JUj1uxV/CDr8hNnr88GcjXLmmX1yBcclQldeUoAoSgsXN1eLLS4e0CHXIzYATmcsSbcl6Zgquo4wW4e9w==} + '@tauri-apps/cli-darwin-arm64@2.11.4': + resolution: {integrity: sha512-1ryOF3ZhpZ/nemHV5zVwBQBz9jDGKmKPvWPADOhc83ig0P4bMc2iER4NbC6r9sjeIZ6RVQ4g3RZIYvezhcl4TQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tauri-apps/cli-darwin-x64@2.2.0': - resolution: {integrity: sha512-BpIQxYQmg+vyS4Z4hxnAcrR95Kn2cnQbkA37NZDW0x7nnx+IFTNremU0cxATJQ3vk1PPVi3PQgrnAX5HE5aXKA==} + '@tauri-apps/cli-darwin-x64@2.11.4': + resolution: {integrity: sha512-uFsGQAAfuyz1k/yGLmkWfkBlgKAqZfxqlHmLWx81QU27RJWfmbNHCIq8T8w1e+VClleIuZUjpHWfoE4E3DLo3A==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tauri-apps/cli-linux-arm-gnueabihf@2.2.0': - resolution: {integrity: sha512-JDYwiELRKKOStSA2QKpGiOZL4si+9ZZcwYCh7DRxnk0csM42vIv0bgcG+ucK5A/gltyDyavZgHNToxFGXaLKXA==} + '@tauri-apps/cli-linux-arm-gnueabihf@2.11.4': + resolution: {integrity: sha512-IaHZn5CdBL21oUmjiVOS1ctw6Ip1O0pjp70FwOWmYz1myWe0SY96ZIj2FYf7pT0m8bI2h/hrs5ZbEXXh44/MkQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tauri-apps/cli-linux-arm64-gnu@2.2.0': - resolution: {integrity: sha512-ITpT44YDMrg3l0ZQMTeFjj+mRzjCZAGyD3GuJ414aL5X1GWO2CHMdAHYQT9gYtH2OHlixaWq9nRJXDL7W9998w==} + '@tauri-apps/cli-linux-arm64-gnu@2.11.4': + resolution: {integrity: sha512-N41/ukTRVe6XSuUTESuFdGeOW2i7k62tK+6gHK5Kd5/q5RPvvi19GaWAVPPb9u95HSGmTChSolBfzynUsssFaA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@tauri-apps/cli-linux-arm64-musl@2.2.0': - resolution: {integrity: sha512-sj/NR2O99XeatAh4UgM4MltNipoi4A8ZbMhTb1/FaGEvs/ZVrushIX69hFIyxcHu8Nbe/OkZb5b+N80A/V30jA==} + '@tauri-apps/cli-linux-arm64-musl@2.11.4': + resolution: {integrity: sha512-v277UnT/fB64xAfSroL5N3Km3tLmvATWqJJw/wRI+g6o+HkeD0slyE7gOhNs1MbjE41R7bQOTxMVoL3aomUJmw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@tauri-apps/cli-linux-x64-gnu@2.2.0': - resolution: {integrity: sha512-mwX7EzQLKbHZ/VzSksiOLS0uqJUVDqY58cqCj2puiGaPVgCE7bxbKcO6P3PmqYX9P8XWR2K8t922k7K44dScqA==} + '@tauri-apps/cli-linux-riscv64-gnu@2.11.4': + resolution: {integrity: sha512-qqgNkQ2u1yZHxjhxsZaxUtRDW8dIqIYm33rx/mzwQv0SfY9x1B+iraj8vWeFiXjjSVVhEMepXSOts1TqPzvXNQ==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@tauri-apps/cli-linux-x64-gnu@2.11.4': + resolution: {integrity: sha512-2VRNWl84FOH0m2giiDkO2h0QXlcMJeX+zJDpI5kDIQAx6s+geF3v48F4DXfJez4GS/FdoDGnPnw1C2iYGbQ7bQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@tauri-apps/cli-linux-x64-musl@2.2.0': - resolution: {integrity: sha512-9C8lVjVJPEjMZaOQdKA5SZV1NpjLP690Y9GodRMum5cIDE3T1AVrp9w6vjrsciQN42agTsO8UaREppF6OjxYnA==} + '@tauri-apps/cli-linux-x64-musl@2.11.4': + resolution: {integrity: sha512-o9GyhYor/nc7xarmwDE3ka2szuW3uuZzXjHWh64Q8YX5AtSgxdQkFWzrY4O8KiGtVNvFBI14H3Q49Qj5TOIP/A==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@tauri-apps/cli-win32-arm64-msvc@2.2.0': - resolution: {integrity: sha512-lbXYsLlvyanx1S/VSiylc6fMsDh1wnBpBid4VxscSfSPyyIOPC/p9uJvcEFWR5Caaet6vUwyJ3iKUaT5yqfsUA==} + '@tauri-apps/cli-win32-arm64-msvc@2.11.4': + resolution: {integrity: sha512-ld5Ehb598m0VkYyylRPNeCFsBe/km0jxis6KgMpl3IGY6I/i1RwQXO05I1AsXUXO2WC6AvB/Lw4qTf/asiuEiQ==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tauri-apps/cli-win32-ia32-msvc@2.2.0': - resolution: {integrity: sha512-nlQ2iRFJTuZw5YelO2HNIsrkcZdqlt7HxdMkHJtCQkFReclpSupjbn6CrupIXHYO8NO6LcoDXiteOYhdWh0fJg==} + '@tauri-apps/cli-win32-ia32-msvc@2.11.4': + resolution: {integrity: sha512-12Hxi0XX/H5VFxO/bGgHkFWhml9VMgEOu9CidjeCeTNQ1l6fpUlbiGgSP7CLI3PFtW9/FfbeHieZ+kyWK5H7CA==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@tauri-apps/cli-win32-x64-msvc@2.2.0': - resolution: {integrity: sha512-MupuZwaJqJv3YsNCGD0H/98S+7106E6HChGoobuPmN87eCniSL/mSsOaa0cVmxdIAwVcSi0fuDzDBRMt8wOhHw==} + '@tauri-apps/cli-win32-x64-msvc@2.11.4': + resolution: {integrity: sha512-+vDiqBIU5dMISg/wNvX3sF+ZHfgJGJ5T0AcO+EHNXV9GGAG+P5fzodlDXD3QdKCRgZxMoCm5PPvj3BqLNjBthw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tauri-apps/cli@2.2.0': - resolution: {integrity: sha512-8sA4LBU4kA73SZcL/mLjXvrpJjDqLFLQymg39FDlf3SVWyzbQxCyHBrokCLhUXLenG4qWVCl91oAImC/s47vzA==} + '@tauri-apps/cli@2.11.4': + resolution: {integrity: sha512-R8xGtMpwyetawSqm9kYOuMmEqkhUbvcUy8n0aNXIxollKBLESUu5f4Fx+64hgASYm1H+jSWq6jCW6zqTnH6hqQ==} engines: {node: '>= 10'} hasBin: true @@ -641,50 +648,54 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.60.1': optional: true - '@tauri-apps/api@2.2.0': {} + '@tauri-apps/api@2.11.1': {} + + '@tauri-apps/cli-darwin-arm64@2.11.4': + optional: true - '@tauri-apps/cli-darwin-arm64@2.2.0': + '@tauri-apps/cli-darwin-x64@2.11.4': optional: true - '@tauri-apps/cli-darwin-x64@2.2.0': + '@tauri-apps/cli-linux-arm-gnueabihf@2.11.4': optional: true - '@tauri-apps/cli-linux-arm-gnueabihf@2.2.0': + '@tauri-apps/cli-linux-arm64-gnu@2.11.4': optional: true - '@tauri-apps/cli-linux-arm64-gnu@2.2.0': + '@tauri-apps/cli-linux-arm64-musl@2.11.4': optional: true - '@tauri-apps/cli-linux-arm64-musl@2.2.0': + '@tauri-apps/cli-linux-riscv64-gnu@2.11.4': optional: true - '@tauri-apps/cli-linux-x64-gnu@2.2.0': + '@tauri-apps/cli-linux-x64-gnu@2.11.4': optional: true - '@tauri-apps/cli-linux-x64-musl@2.2.0': + '@tauri-apps/cli-linux-x64-musl@2.11.4': optional: true - '@tauri-apps/cli-win32-arm64-msvc@2.2.0': + '@tauri-apps/cli-win32-arm64-msvc@2.11.4': optional: true - '@tauri-apps/cli-win32-ia32-msvc@2.2.0': + '@tauri-apps/cli-win32-ia32-msvc@2.11.4': optional: true - '@tauri-apps/cli-win32-x64-msvc@2.2.0': + '@tauri-apps/cli-win32-x64-msvc@2.11.4': optional: true - '@tauri-apps/cli@2.2.0': + '@tauri-apps/cli@2.11.4': optionalDependencies: - '@tauri-apps/cli-darwin-arm64': 2.2.0 - '@tauri-apps/cli-darwin-x64': 2.2.0 - '@tauri-apps/cli-linux-arm-gnueabihf': 2.2.0 - '@tauri-apps/cli-linux-arm64-gnu': 2.2.0 - '@tauri-apps/cli-linux-arm64-musl': 2.2.0 - '@tauri-apps/cli-linux-x64-gnu': 2.2.0 - '@tauri-apps/cli-linux-x64-musl': 2.2.0 - '@tauri-apps/cli-win32-arm64-msvc': 2.2.0 - '@tauri-apps/cli-win32-ia32-msvc': 2.2.0 - '@tauri-apps/cli-win32-x64-msvc': 2.2.0 + '@tauri-apps/cli-darwin-arm64': 2.11.4 + '@tauri-apps/cli-darwin-x64': 2.11.4 + '@tauri-apps/cli-linux-arm-gnueabihf': 2.11.4 + '@tauri-apps/cli-linux-arm64-gnu': 2.11.4 + '@tauri-apps/cli-linux-arm64-musl': 2.11.4 + '@tauri-apps/cli-linux-riscv64-gnu': 2.11.4 + '@tauri-apps/cli-linux-x64-gnu': 2.11.4 + '@tauri-apps/cli-linux-x64-musl': 2.11.4 + '@tauri-apps/cli-win32-arm64-msvc': 2.11.4 + '@tauri-apps/cli-win32-ia32-msvc': 2.11.4 + '@tauri-apps/cli-win32-x64-msvc': 2.11.4 '@types/estree@1.0.8': {} diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock index 38e1d0dc..1b2aaa86 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock @@ -459,12 +459,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "cookie" version = "0.18.1" @@ -608,23 +602,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cssparser" -version = "0.29.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa", - "matches", - "phf 0.10.1", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - [[package]] name = "cssparser" version = "0.36.0" @@ -634,7 +611,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "phf 0.13.1", + "phf", "smallvec", ] @@ -650,14 +627,20 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.9" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" dependencies = [ - "quote", - "syn 2.0.117", + "ctor-proc-macro", + "dtor", ] +[[package]] +name = "ctor-proc-macro" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" + [[package]] name = "darling" version = "0.23.0" @@ -704,11 +687,22 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +[[package]] +name = "dbus" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab69f03cc8c4340c9c8e315114e1658e6775a9b16a04357973aa21cec22b32e" +dependencies = [ + "libc", + "libdbus-sys", + "windows-sys 0.61.2", +] + [[package]] name = "deepgram" -version = "0.9.2" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b4b3ba8223aa3a88fad716198d988ff87b50b564b99ba1933afac2f9f08d829" +checksum = "12466522a157634afeed95a738f129f5f0fc2e1af855d9550921eeec1182e1a1" dependencies = [ "anyhow", "bytes", @@ -754,19 +748,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.117", -] - [[package]] name = "derive_more" version = "2.1.1" @@ -816,7 +797,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -872,12 +853,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" dependencies = [ "bit-set", - "cssparser 0.36.0", + "cssparser", "foldhash 0.2.0", - "html5ever 0.38.0", + "html5ever", "precomputed-hash", - "selectors 0.36.1", - "tendril 0.5.0", + "selectors", + "tendril", ] [[package]] @@ -904,6 +885,21 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dtor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + [[package]] name = "dunce" version = "1.0.5" @@ -966,7 +962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -1070,16 +1066,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "futf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] - [[package]] name = "futures" version = "0.3.32" @@ -1168,15 +1154,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "gdk" version = "0.18.2" @@ -1286,17 +1263,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.17" @@ -1306,7 +1272,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -1530,18 +1496,6 @@ version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" -[[package]] -name = "html5ever" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" -dependencies = [ - "log", - "mac", - "markup5ever 0.14.1", - "match_token", -] - [[package]] name = "html5ever" version = "0.38.0" @@ -1549,7 +1503,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" dependencies = [ "log", - "markup5ever 0.38.0", + "markup5ever", ] [[package]] @@ -1662,7 +1616,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.61.2", ] [[package]] @@ -1681,7 +1635,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" dependencies = [ "byteorder", - "png", + "png 0.17.16", ] [[package]] @@ -2014,18 +1968,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "kuchikiki" -version = "0.8.8-speedreader" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" -dependencies = [ - "cssparser 0.29.6", - "html5ever 0.29.1", - "indexmap 2.13.1", - "selectors 0.24.0", -] - [[package]] name = "leb128fmt" version = "0.1.0" @@ -2062,6 +2004,15 @@ version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +[[package]] +name = "libdbus-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" +dependencies = [ + "pkg-config", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2151,32 +2102,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - [[package]] name = "mach2" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b" -[[package]] -name = "markup5ever" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" -dependencies = [ - "log", - "phf 0.11.3", - "phf_codegen 0.11.3", - "string_cache 0.8.9", - "string_cache_codegen 0.5.4", - "tendril 0.4.3", -] - [[package]] name = "markup5ever" version = "0.38.0" @@ -2184,27 +2115,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" dependencies = [ "log", - "tendril 0.5.0", + "tendril", "web_atoms", ] -[[package]] -name = "match_token" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" version = "2.8.0" @@ -2249,15 +2163,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "windows-sys 0.61.2", ] [[package]] name = "muda" -version = "0.17.2" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9fec5a4e89860383d778d10563a605838f8f0b2f9303868937e5ff32e86177" +checksum = "1dd04e60bc0b07438a6771710ee1698f98f6ebbc7f89b61264af1563b8aeb878" dependencies = [ "crossbeam-channel", "dpi", @@ -2268,7 +2182,7 @@ dependencies = [ "objc2-core-foundation", "objc2-foundation", "once_cell", - "png", + "png 0.18.1", "serde", "thiserror 2.0.18", "windows-sys 0.60.2", @@ -2310,12 +2224,6 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "nom" version = "7.1.3" @@ -2441,6 +2349,17 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-foundation", +] + [[package]] name = "objc2-core-audio" version = "0.3.2" @@ -2464,6 +2383,16 @@ dependencies = [ "objc2", ] +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "objc2", + "objc2-foundation", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" @@ -2490,6 +2419,38 @@ dependencies = [ "objc2-io-surface", ] +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-location" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.11.0", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", +] + [[package]] name = "objc2-encode" version = "4.1.0" @@ -2548,8 +2509,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ "bitflags 2.11.0", + "block2", "objc2", + "objc2-cloud-kit", + "objc2-core-data", "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-location", + "objc2-core-text", + "objc2-foundation", + "objc2-quartz-core", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" +dependencies = [ + "objc2", "objc2-foundation", ] @@ -2639,105 +2619,25 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_shared 0.8.0", -] - -[[package]] -name = "phf" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" -dependencies = [ - "phf_macros 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", -] - -[[package]] -name = "phf" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros 0.11.3", - "phf_shared 0.11.3", -] - [[package]] name = "phf" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ - "phf_macros 0.13.1", - "phf_shared 0.13.1", + "phf_macros", + "phf_shared", "serde", ] -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", -] - -[[package]] -name = "phf_codegen" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", -] - [[package]] name = "phf_codegen" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" dependencies = [ - "phf_generator 0.13.1", - "phf_shared 0.13.1", -] - -[[package]] -name = "phf_generator" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" -dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", -] - -[[package]] -name = "phf_generator" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" -dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.5", -] - -[[package]] -name = "phf_generator" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared 0.11.3", - "rand 0.8.5", + "phf_generator", + "phf_shared", ] [[package]] @@ -2747,34 +2647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ "fastrand", - "phf_shared 0.13.1", -] - -[[package]] -name = "phf_macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "phf_macros" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", - "syn 2.0.117", + "phf_shared", ] [[package]] @@ -2783,47 +2656,20 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "phf_generator 0.13.1", - "phf_shared 0.13.1", + "phf_generator", + "phf_shared", "proc-macro2", "quote", "syn 2.0.117", ] -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher 0.3.11", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher 0.3.11", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher 1.0.2", -] - [[package]] name = "phf_shared" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ - "siphasher 1.0.2", + "siphasher", ] [[package]] @@ -2909,6 +2755,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.11.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "pocketstation" version = "1.1.10" @@ -3024,12 +2883,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" - [[package]] name = "proc-macro2" version = "1.0.106" @@ -3078,7 +2931,7 @@ dependencies = [ "bytes", "getrandom 0.3.4", "lru-slab", - "rand 0.9.2", + "rand", "ring", "rustc-hash", "rustls", @@ -3125,59 +2978,14 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", ] [[package]] @@ -3187,25 +2995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", + "rand_core", ] [[package]] @@ -3217,24 +3007,6 @@ dependencies = [ "getrandom 0.3.4", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "raw-window-handle" version = "0.6.2" @@ -3396,7 +3168,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3453,7 +3225,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3584,24 +3356,6 @@ dependencies = [ "libc", ] -[[package]] -name = "selectors" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" -dependencies = [ - "bitflags 1.3.2", - "cssparser 0.29.6", - "derive_more 0.99.20", - "fxhash", - "log", - "phf 0.8.0", - "phf_codegen 0.8.0", - "precomputed-hash", - "servo_arc 0.2.0", - "smallvec", -] - [[package]] name = "selectors" version = "0.36.1" @@ -3609,15 +3363,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" dependencies = [ "bitflags 2.11.0", - "cssparser 0.36.0", - "derive_more 2.1.1", + "cssparser", + "derive_more", "log", "new_debug_unreachable", - "phf 0.13.1", - "phf_codegen 0.13.1", + "phf", + "phf_codegen", "precomputed-hash", "rustc-hash", - "servo_arc 0.4.3", + "servo_arc", "smallvec", ] @@ -3791,16 +3545,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "servo_arc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" -dependencies = [ - "nodrop", - "stable_deref_trait", -] - [[package]] name = "servo_arc" version = "0.4.3" @@ -3883,12 +3627,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - [[package]] name = "siphasher" version = "1.0.2" @@ -3914,7 +3652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -3971,19 +3709,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" -[[package]] -name = "string_cache" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared 0.11.3", - "precomputed-hash", - "serde", -] - [[package]] name = "string_cache" version = "0.9.0" @@ -3992,30 +3717,18 @@ checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" dependencies = [ "new_debug_unreachable", "parking_lot", - "phf_shared 0.13.1", + "phf_shared", "precomputed-hash", ] -[[package]] -name = "string_cache_codegen" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", -] - [[package]] name = "string_cache_codegen" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" dependencies = [ - "phf_generator 0.13.1", - "phf_shared 0.13.1", + "phf_generator", + "phf_shared", "proc-macro2", "quote", ] @@ -4050,7 +3763,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote", "unicode-ident", ] @@ -4113,15 +3825,16 @@ dependencies = [ [[package]] name = "tao" -version = "0.34.8" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9103edf55f2da3c82aea4c7fab7c4241032bfeea0e71fa557d98e00e7ce7cc20" +checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" dependencies = [ "bitflags 2.11.0", "block2", "core-foundation", "core-graphics", "crossbeam-channel", + "dbus", "dispatch2", "dlopen2", "dpi", @@ -4132,13 +3845,14 @@ dependencies = [ "libc", "log", "ndk", - "ndk-context", "ndk-sys", "objc2", "objc2-app-kit", "objc2-foundation", + "objc2-ui-kit", "once_cell", "parking_lot", + "percent-encoding", "raw-window-handle", "tao-macros", "unicode-segmentation", @@ -4174,9 +3888,9 @@ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "tauri" -version = "2.10.3" +version = "2.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da77cc00fb9028caf5b5d4650f75e31f1ef3693459dfca7f7e506d1ecef0ba2d" +checksum = "667b20e2726d572dea2de7370da16e188eb06008faf9a92fab7cdc46791190b5" dependencies = [ "anyhow", "bytes", @@ -4225,9 +3939,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.5.6" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bbc990d1dbf57a8e1c7fa2327f2a614d8b757805603c1b9ba5c81bade09fd4d" +checksum = "bc9ce40b16101cb6ea63d3e221567affd1c3a9205f95d7bc574941a10636b632" dependencies = [ "anyhow", "cargo_toml", @@ -4241,22 +3955,21 @@ dependencies = [ "serde_json", "tauri-utils", "tauri-winres", - "toml 0.9.12+spec-1.1.0", "walkdir", ] [[package]] name = "tauri-codegen" -version = "2.5.5" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a24476afd977c5d5d169f72425868613d82747916dd29e0a357c84c4bd6d29" +checksum = "08279169ff42f8fc45a1dbc9dcae888893ba95288142e5880c59b93a26d2cfc5" dependencies = [ "base64 0.22.1", "brotli", "ico", "json-patch", "plist", - "png", + "png 0.17.16", "proc-macro2", "quote", "semver", @@ -4274,9 +3987,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.5.5" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39b349a98dadaffebb73f0a40dcd1f23c999211e5a2e744403db384d0c33de7" +checksum = "e8b394794f399a421811d06966343e7933fcae92d59f5180b9388d1174497a45" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -4288,9 +4001,9 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.10.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2826d79a3297ed08cd6ea7f412644ef58e32969504bc4fbd8d7dbeabc4445ea2" +checksum = "b0b4bc95aed361b0019067d189a1174a603d460d0f6c72606512d59fc9c12ec8" dependencies = [ "cookie", "dpi", @@ -4313,9 +4026,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.10.1" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" +checksum = "4e6fac707727b7a2f48e4ded90976324267371073edbb415ffb73bb0458d203f" dependencies = [ "gtk", "http", @@ -4339,24 +4052,24 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.8.3" +version = "2.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219a1f983a2af3653f75b5747f76733b0da7ff03069c7a41901a5eb3ace4557d" +checksum = "3e176a18e67764923c4f1ce66f25ae4abe5f688384d5eb1a0fa6c77f3d90f887" dependencies = [ "anyhow", "brotli", "cargo_metadata", "ctor", + "dom_query", "dunce", "glob", - "html5ever 0.29.1", "http", "infer", "json-patch", - "kuchikiki", "log", "memchr", - "phf 0.11.3", + "phf", + "plist", "proc-macro2", "quote", "regex", @@ -4368,7 +4081,7 @@ dependencies = [ "serde_with", "swift-rs", "thiserror 2.0.18", - "toml 0.9.12+spec-1.1.0", + "toml 1.1.2+spec-1.1.0", "url", "urlpattern", "uuid", @@ -4386,17 +4099,6 @@ dependencies = [ "toml 0.9.12+spec-1.1.0", ] -[[package]] -name = "tendril" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" -dependencies = [ - "futf", - "mac", - "utf-8", -] - [[package]] name = "tendril" version = "0.5.0" @@ -4779,9 +4481,9 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.21.3" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e85aa143ceb072062fc4d6356c1b520a51d636e7bc8e77ec94be3608e5e80c" +checksum = "045979e3f037cd18ad1cb2a419dfda133c5c29c9f3453370079f2255d46c257e" dependencies = [ "crossbeam-channel", "dirs", @@ -4793,7 +4495,7 @@ dependencies = [ "objc2-core-graphics", "objc2-foundation", "once_cell", - "png", + "png 0.18.1", "serde", "thiserror 2.0.18", "windows-sys 0.60.2", @@ -4816,7 +4518,7 @@ dependencies = [ "http", "httparse", "log", - "rand 0.9.2", + "rand", "rustls", "rustls-pki-types", "sha1", @@ -5020,12 +4722,6 @@ dependencies = [ "windows-core 0.62.2", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -5178,10 +4874,10 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57a9779e9f04d2ac1ce317aee707aa2f6b773afba7b931222bff6983843b1576" dependencies = [ - "phf 0.13.1", - "phf_codegen 0.13.1", - "string_cache 0.9.0", - "string_cache_codegen 0.6.1", + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", ] [[package]] @@ -5313,7 +5009,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -5970,9 +5666,9 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wry" -version = "0.54.4" +version = "0.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a8135d8676225e5744de000d4dff5a082501bf7db6a1c1495034f8c314edbc" +checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" dependencies = [ "base64 0.22.1", "block2", diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml index 81d8a7fe..88fa79c1 100644 --- a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml +++ b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml @@ -4,14 +4,14 @@ version = "0.1.0" edition = "2021" [dependencies] -deepgram = "=0.9.2" +deepgram = "=0.10.1" serde = { version = "=1.0.228", features = ["derive"] } serde_json = "=1.0.149" -tauri = { version = "=2.10.3", features = [] } +tauri = { version = "=2.11.5", features = [] } tokio = { version = "=1.51.0", features = ["full"] } [build-dependencies] -tauri-build = { version = "=2.5.6", features = [] } +tauri-build = { version = "=2.6.3", features = [] } [target.'cfg(target_os = "macos")'.dependencies] pocketstation = { version = "=1.1.10", default-features = false, features = ["coreaudio-capture"] } diff --git a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py index 984201de..e6a837a4 100644 --- a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py +++ b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py @@ -63,7 +63,8 @@ def test_cargo_dependencies_are_pinned(): """Verify the example uses released Deepgram and PocketStation crates.""" cargo_toml = (ROOT / "src" / "src-tauri" / "Cargo.toml").read_text() - assert 'deepgram = "=0.9.2"' in cargo_toml + assert 'deepgram = "=0.10.1"' in cargo_toml + assert 'tauri = { version = "=2.11.5"' in cargo_toml assert cargo_toml.count('pocketstation = { version = "=1.1.10"') == 3 assert 'features = ["coreaudio-capture"]' in cargo_toml assert 'features = ["wasapi-capture"]' in cargo_toml From e248e2650758a6ac4072d11005448f083e845411 Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 15:20:08 +0200 Subject: [PATCH 4/8] fix: finalize Tauri transcription example --- .../.env.example | 0 .../.gitignore | 0 .../README.md | 0 .../requirements.txt | 0 .../src/.npmrc | 0 .../src/index.html | 0 .../src/package.json | 0 .../src/pnpm-lock.yaml | 0 .../src/src-tauri/Cargo.lock | 0 .../src/src-tauri/Cargo.toml | 0 .../src/src-tauri/Info.plist | 0 .../src/src-tauri/build.rs | 0 .../src/src-tauri/capabilities/default.json | 0 .../src/src-tauri/icons/icon.png | Bin .../src/src-tauri/icons/icon.svg | 0 .../src/src-tauri/src/main.rs | 0 .../src/src-tauri/tauri.conf.json | 0 .../src/src/main.ts | 0 .../src/tsconfig.json | 0 .../src/vite.config.ts | 0 .../tests/test_example.py | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/.env.example (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/.gitignore (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/README.md (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/requirements.txt (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/.npmrc (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/index.html (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/package.json (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/pnpm-lock.yaml (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/Cargo.lock (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/Cargo.toml (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/Info.plist (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/build.rs (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/capabilities/default.json (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/icons/icon.png (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/icons/icon.svg (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/src/main.rs (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src-tauri/tauri.conf.json (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/src/main.ts (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/tsconfig.json (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/src/vite.config.ts (100%) rename examples/{340-tauri-live-transcription-rust-ts => 540-tauri-live-transcription-rust-ts}/tests/test_example.py (100%) diff --git a/examples/340-tauri-live-transcription-rust-ts/.env.example b/examples/540-tauri-live-transcription-rust-ts/.env.example similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/.env.example rename to examples/540-tauri-live-transcription-rust-ts/.env.example diff --git a/examples/340-tauri-live-transcription-rust-ts/.gitignore b/examples/540-tauri-live-transcription-rust-ts/.gitignore similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/.gitignore rename to examples/540-tauri-live-transcription-rust-ts/.gitignore diff --git a/examples/340-tauri-live-transcription-rust-ts/README.md b/examples/540-tauri-live-transcription-rust-ts/README.md similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/README.md rename to examples/540-tauri-live-transcription-rust-ts/README.md diff --git a/examples/340-tauri-live-transcription-rust-ts/requirements.txt b/examples/540-tauri-live-transcription-rust-ts/requirements.txt similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/requirements.txt rename to examples/540-tauri-live-transcription-rust-ts/requirements.txt diff --git a/examples/340-tauri-live-transcription-rust-ts/src/.npmrc b/examples/540-tauri-live-transcription-rust-ts/src/.npmrc similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/.npmrc rename to examples/540-tauri-live-transcription-rust-ts/src/.npmrc diff --git a/examples/340-tauri-live-transcription-rust-ts/src/index.html b/examples/540-tauri-live-transcription-rust-ts/src/index.html similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/index.html rename to examples/540-tauri-live-transcription-rust-ts/src/index.html diff --git a/examples/340-tauri-live-transcription-rust-ts/src/package.json b/examples/540-tauri-live-transcription-rust-ts/src/package.json similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/package.json rename to examples/540-tauri-live-transcription-rust-ts/src/package.json diff --git a/examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml b/examples/540-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml rename to examples/540-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/build.rs b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/build.rs similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/build.rs rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/build.rs diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json rename to examples/540-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts b/examples/540-tauri-live-transcription-rust-ts/src/src/main.ts similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/src/main.ts rename to examples/540-tauri-live-transcription-rust-ts/src/src/main.ts diff --git a/examples/340-tauri-live-transcription-rust-ts/src/tsconfig.json b/examples/540-tauri-live-transcription-rust-ts/src/tsconfig.json similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/tsconfig.json rename to examples/540-tauri-live-transcription-rust-ts/src/tsconfig.json diff --git a/examples/340-tauri-live-transcription-rust-ts/src/vite.config.ts b/examples/540-tauri-live-transcription-rust-ts/src/vite.config.ts similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/src/vite.config.ts rename to examples/540-tauri-live-transcription-rust-ts/src/vite.config.ts diff --git a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py b/examples/540-tauri-live-transcription-rust-ts/tests/test_example.py similarity index 100% rename from examples/340-tauri-live-transcription-rust-ts/tests/test_example.py rename to examples/540-tauri-live-transcription-rust-ts/tests/test_example.py From bd355ac669d40061b69ad64d18cfcadc6036ab33 Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 15:20:19 +0200 Subject: [PATCH 5/8] fix: use current provider releases --- README.md | 2 +- .../src/src-tauri/Cargo.lock | 94 ++----------------- .../src/src-tauri/Cargo.toml | 2 +- .../tests/test_example.py | 3 +- 4 files changed, 14 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index 73047713..383de3ae 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,6 @@ A collection of working examples showing how to use Deepgram SDKs with popular p | [290](examples/290-aws-lambda-python-transcription/) | AWS Lambda Serverless Audio Transcription | Python | AWS Lambda | | [300](examples/300-spring-boot-live-transcription-java/) | Spring Boot Real-Time Transcription with Deepgram | Java | Spring Boot | | [310](examples/310-crewai-voice-agents-python/) | CrewAI Voice-Enabled Multi-Agent System with Deepgram | Python | CrewAI | -| [340](examples/340-tauri-live-transcription-rust-ts/) | Tauri Desktop Live Transcription | Rust | Tauri | | [350](examples/350-asterisk-freeswitch-deepgram-stt-python/) | Asterisk / FreeSWITCH PBX to Deepgram Streaming STT | Python | Asterisk/FreeSWITCH | | [360](examples/360-kotlin-android-live-transcription/) | Kotlin Android Live Transcription | Kotlin | Jetpack Compose | | [370](examples/370-swift-ios-live-transcription/) | Swift iOS Live Transcription | Swift | SwiftUI | @@ -57,6 +56,7 @@ A collection of working examples showing how to use Deepgram SDKs with popular p | [500](examples/500-semantic-kernel-voice-plugin-dotnet/) | Semantic Kernel Voice Plugin with Deepgram (.NET) | JavaScript | Semantic Kernel | | [510](examples/510-gin-live-transcription-go/) | Gin Real-Time WebSocket Transcription Server | Go | Gin | | [520](examples/520-node-deepgram-proxy/) | Deepgram Proxy Server (Node.js) | Node.js | Deepgram SDK | +| [540](examples/540-tauri-live-transcription-rust-ts/) | Tauri Desktop Live Transcription | Rust | Tauri | ## CI / testing diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock index 1b2aaa86..7137cdea 100644 --- a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock +++ b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock @@ -797,7 +797,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -962,7 +962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2185,7 +2185,7 @@ dependencies = [ "png 0.18.1", "serde", "thiserror 2.0.18", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2954,7 +2954,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -3168,7 +3168,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3225,7 +3225,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3652,7 +3652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -4498,7 +4498,7 @@ dependencies = [ "png 0.18.1", "serde", "thiserror 2.0.18", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5009,7 +5009,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5305,15 +5305,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -5347,30 +5338,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link 0.2.1", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows-threading" version = "0.1.0" @@ -5410,12 +5384,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -5428,12 +5396,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -5446,24 +5408,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -5476,12 +5426,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -5494,12 +5438,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -5512,12 +5450,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -5530,12 +5462,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" version = "0.5.40" diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml index 88fa79c1..ec6abe63 100644 --- a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml +++ b/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -deepgram = "=0.10.1" +deepgram = { version = "=0.10.1", default-features = false, features = ["listen"] } serde = { version = "=1.0.228", features = ["derive"] } serde_json = "=1.0.149" tauri = { version = "=2.11.5", features = [] } diff --git a/examples/540-tauri-live-transcription-rust-ts/tests/test_example.py b/examples/540-tauri-live-transcription-rust-ts/tests/test_example.py index e6a837a4..9a8b1e37 100644 --- a/examples/540-tauri-live-transcription-rust-ts/tests/test_example.py +++ b/examples/540-tauri-live-transcription-rust-ts/tests/test_example.py @@ -63,7 +63,8 @@ def test_cargo_dependencies_are_pinned(): """Verify the example uses released Deepgram and PocketStation crates.""" cargo_toml = (ROOT / "src" / "src-tauri" / "Cargo.toml").read_text() - assert 'deepgram = "=0.10.1"' in cargo_toml + assert 'deepgram = { version = "=0.10.1"' in cargo_toml + assert 'features = ["listen"]' in cargo_toml assert 'tauri = { version = "=2.11.5"' in cargo_toml assert cargo_toml.count('pocketstation = { version = "=1.1.10"') == 3 assert 'features = ["coreaudio-capture"]' in cargo_toml From 58a82a655e1a4e8e5810b6bec8751985e82e17de Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 15:27:41 +0200 Subject: [PATCH 6/8] fix: update the existing Tauri example --- .../.env.example | 0 .../.gitignore | 0 .../README.md | 0 .../requirements.txt | 0 .../src/.npmrc | 0 .../src/index.html | 0 .../src/package.json | 0 .../src/pnpm-lock.yaml | 0 .../src/src-tauri/Cargo.lock | 0 .../src/src-tauri/Cargo.toml | 0 .../src/src-tauri/Info.plist | 0 .../src/src-tauri/build.rs | 0 .../src/src-tauri/capabilities/default.json | 0 .../src/src-tauri/icons/icon.png | Bin .../src/src-tauri/icons/icon.svg | 0 .../src/src-tauri/src/main.rs | 0 .../src/src-tauri/tauri.conf.json | 0 .../src/src/main.ts | 0 .../src/tsconfig.json | 0 .../src/vite.config.ts | 0 .../tests/test_example.py | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/.env.example (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/.gitignore (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/README.md (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/requirements.txt (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/.npmrc (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/index.html (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/package.json (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/pnpm-lock.yaml (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/Cargo.lock (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/Cargo.toml (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/Info.plist (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/build.rs (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/capabilities/default.json (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/icons/icon.png (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/icons/icon.svg (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/src/main.rs (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src-tauri/tauri.conf.json (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/src/main.ts (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/tsconfig.json (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/src/vite.config.ts (100%) rename examples/{540-tauri-live-transcription-rust-ts => 340-tauri-live-transcription-rust-ts}/tests/test_example.py (100%) diff --git a/examples/540-tauri-live-transcription-rust-ts/.env.example b/examples/340-tauri-live-transcription-rust-ts/.env.example similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/.env.example rename to examples/340-tauri-live-transcription-rust-ts/.env.example diff --git a/examples/540-tauri-live-transcription-rust-ts/.gitignore b/examples/340-tauri-live-transcription-rust-ts/.gitignore similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/.gitignore rename to examples/340-tauri-live-transcription-rust-ts/.gitignore diff --git a/examples/540-tauri-live-transcription-rust-ts/README.md b/examples/340-tauri-live-transcription-rust-ts/README.md similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/README.md rename to examples/340-tauri-live-transcription-rust-ts/README.md diff --git a/examples/540-tauri-live-transcription-rust-ts/requirements.txt b/examples/340-tauri-live-transcription-rust-ts/requirements.txt similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/requirements.txt rename to examples/340-tauri-live-transcription-rust-ts/requirements.txt diff --git a/examples/540-tauri-live-transcription-rust-ts/src/.npmrc b/examples/340-tauri-live-transcription-rust-ts/src/.npmrc similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/.npmrc rename to examples/340-tauri-live-transcription-rust-ts/src/.npmrc diff --git a/examples/540-tauri-live-transcription-rust-ts/src/index.html b/examples/340-tauri-live-transcription-rust-ts/src/index.html similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/index.html rename to examples/340-tauri-live-transcription-rust-ts/src/index.html diff --git a/examples/540-tauri-live-transcription-rust-ts/src/package.json b/examples/340-tauri-live-transcription-rust-ts/src/package.json similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/package.json rename to examples/340-tauri-live-transcription-rust-ts/src/package.json diff --git a/examples/540-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml b/examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml rename to examples/340-tauri-live-transcription-rust-ts/src/pnpm-lock.yaml diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.lock diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Cargo.toml diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/Info.plist diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/build.rs b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/build.rs similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/build.rs rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/build.rs diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/capabilities/default.json diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.png diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.svg diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/src/main.rs diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json rename to examples/340-tauri-live-transcription-rust-ts/src/src-tauri/tauri.conf.json diff --git a/examples/540-tauri-live-transcription-rust-ts/src/src/main.ts b/examples/340-tauri-live-transcription-rust-ts/src/src/main.ts similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/src/main.ts rename to examples/340-tauri-live-transcription-rust-ts/src/src/main.ts diff --git a/examples/540-tauri-live-transcription-rust-ts/src/tsconfig.json b/examples/340-tauri-live-transcription-rust-ts/src/tsconfig.json similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/tsconfig.json rename to examples/340-tauri-live-transcription-rust-ts/src/tsconfig.json diff --git a/examples/540-tauri-live-transcription-rust-ts/src/vite.config.ts b/examples/340-tauri-live-transcription-rust-ts/src/vite.config.ts similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/src/vite.config.ts rename to examples/340-tauri-live-transcription-rust-ts/src/vite.config.ts diff --git a/examples/540-tauri-live-transcription-rust-ts/tests/test_example.py b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py similarity index 100% rename from examples/540-tauri-live-transcription-rust-ts/tests/test_example.py rename to examples/340-tauri-live-transcription-rust-ts/tests/test_example.py From fb64e18f189002572881c35bf173ce5742255115 Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 15:27:52 +0200 Subject: [PATCH 7/8] docs: identify the Tauri example as Rust --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 383de3ae..73047713 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ A collection of working examples showing how to use Deepgram SDKs with popular p | [290](examples/290-aws-lambda-python-transcription/) | AWS Lambda Serverless Audio Transcription | Python | AWS Lambda | | [300](examples/300-spring-boot-live-transcription-java/) | Spring Boot Real-Time Transcription with Deepgram | Java | Spring Boot | | [310](examples/310-crewai-voice-agents-python/) | CrewAI Voice-Enabled Multi-Agent System with Deepgram | Python | CrewAI | +| [340](examples/340-tauri-live-transcription-rust-ts/) | Tauri Desktop Live Transcription | Rust | Tauri | | [350](examples/350-asterisk-freeswitch-deepgram-stt-python/) | Asterisk / FreeSWITCH PBX to Deepgram Streaming STT | Python | Asterisk/FreeSWITCH | | [360](examples/360-kotlin-android-live-transcription/) | Kotlin Android Live Transcription | Kotlin | Jetpack Compose | | [370](examples/370-swift-ios-live-transcription/) | Swift iOS Live Transcription | Swift | SwiftUI | @@ -56,7 +57,6 @@ A collection of working examples showing how to use Deepgram SDKs with popular p | [500](examples/500-semantic-kernel-voice-plugin-dotnet/) | Semantic Kernel Voice Plugin with Deepgram (.NET) | JavaScript | Semantic Kernel | | [510](examples/510-gin-live-transcription-go/) | Gin Real-Time WebSocket Transcription Server | Go | Gin | | [520](examples/520-node-deepgram-proxy/) | Deepgram Proxy Server (Node.js) | Node.js | Deepgram SDK | -| [540](examples/540-tauri-live-transcription-rust-ts/) | Tauri Desktop Live Transcription | Rust | Tauri | ## CI / testing From fa0a0ed3d74f92b8913cda444a6c8eb280ec7019 Mon Sep 17 00:00:00 2001 From: Raphael Avocegamou Date: Fri, 4 Sep 2026 16:05:31 +0200 Subject: [PATCH 8/8] fix: add the Windows application icon --- .../src/src-tauri/icons/icon.ico | Bin 0 -> 69694 bytes .../tests/test_example.py | 1 + 2 files changed, 1 insertion(+) create mode 100644 examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.ico diff --git a/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.ico b/examples/340-tauri-live-transcription-rust-ts/src/src-tauri/icons/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9790e7abbef10ef69973807378e03075ba5d05d9 GIT binary patch literal 69694 zcmeI5Z>$_u6~KqIKCpCmW_R}W*=;q?ws~!eu|P|U1plSThnAMUDjFb-DMX?rAdk`n zXpH@5p+;$6HNvAr2~i`B@I~X_4_3fWgi7=iDz8)%q5o6p2jI(c&c2@Z?l3d=+?lz% zJ2Qu7-kqJ9z4y-foqNu?cg`%1a|!(0w#|XR!_Fe_5@(jDw~1jzC}D3<}WX*R*7sCxkV zxEA_&5VkY031d4lI1RFWwo$9C0ahPL!7G!mRw@-AxbJ{Ioe<_-*ZJch`)$=~wVnw~ zgG!ps<_zC;cLDQvgnQSy2W{)yI0om=o%>M(go!Uj+XKws5biza9@K-$Mzy*+F<8wP z7dXzPzUPe#_rBvE)Po6RrNL=*y3uGff%_}MzVF$SF1*~BF=Mt7A9z{)y|-v{o;gnho)E4+>Y!x0wjz(r{D+d5=t9!qvgO8fGiH1!3; zj&m94&|yW7gp++vHf8*>NlXab9~btywfUiX1ar6j0TUnk5w5#g*cXfa1)iGqf%EHn zM=o5SZ<`l74oZG+M~8-nE)N~}aB$Fdcb8l~#n%~FD-Pq|ewHKa`Nik&y62jeN+YNP z;P-dR*e|Hx5BhOpbA_-k9ebMREQQ>m`-Oi=`A_8)9}xZ}+V+P4`c2xS!K8^lnc3-7|U5 znd7$ZeZJQE(HXyE!((_(aayISHkq65X$fprf@ zkA2dC+kaRW{t4o#JdByUex~QY^B=zOFDU=5f2(WlKiYvSt}Ukh%flG8)yG+Nx3%}J z&X}KUez5%VcO?$A#erLI*7Ng`EA_D-=>ggaZa?L^Y;C2j`T6x<;qym5n14mK_a%D5 zlc%luIVbj~@sH)|`(z&2ZJo6_Kj*~$D*w&D7a!1V{$JgppP!9xO%|JRV}H_t@e_XQ z6T>{4)onQywY@EW*2m|YeqlZ?O=5rIkL3+_h!5zNuFW2DTlSfVn-H-Rf@%_Z-s+DGT*);a2 zcCf^GV?WBPXno@Ne&Vv~9-&kzgNOKIGHL8jZDG0eM)3hQ`J4EDrxBq~z zZ#Lyr)VfW4KXF;SjAxUR#{Sd}mb?BbIRUnG&(!x5moI*u7Xze;{i!W1B`1J4-c0qx z)b|sUTOZ}|PZRr7TUbg?fF1s(zMq(k{f6h0IkEpEuj%I=k`rKue-hu1I)L*sovq=< z{%g1J)&~}R%8m?l_fgdINqs-rfO#YFJUFpG&Lx_&-PU9O*FSrZoPcpFLHVz|Q~!);{3PTA zd@|cHP*(PM-${Kx@&DG(_8)y{ia+LhV9p2C9aTzBKsNfH*7qZy?T6#}b7Ft> z`5xwcMRBL&n|>AFW|_yc$-Srb{m3IO7l0f4k1V;kwtv%@-UpN=CxG(rzqY&9GTHE* zdd~awX?;J9$E#O{+ap%&5ATDZo{-*R&NtN?SAOHCe3@|NL4D|T8I^w@Cy%gmy7%eR z`hIFNDi?s0?;p0N!|@r^wn?dzN3Xe4`*HdACijciM!iqp_Wg`pKb)KC+T8efxIZ?D z{psGZ#C2X>n@P_{$wO_wm;0Rjd((Rl%hg)GO7CYe7xcz&>RCMW*Kq!ve1FuDpuF)p zkLf*{T;I>XFR*5_o{P!7;ST+0qRNpS`@=h->i1|Le*;3-X43Qh%-@Fn zM>#G1(nUFQeLwmL*kg%4OV?)7^Zji9@!qqH|42rv58(QK)D!Fv z#&=XtRC(*3P9Kvr_E&Ylh8+4m{=@svYW}CPQhfl|_Y(`8->G$l?FVxKlE(hjrVTmd zW&TGpp!J`157t_78|FraF$o?cAHenf)DK+W3Dy<-yyx}KT!5spKeefrTscI^C~xaO z>b-OJF}Bsl@`~EOWqW5VkMdvt9ld>_TmX}tA7QI!%asww2ShPf zkE_0)+P-eR-o8*SKo+q-wJRlGKkywnm1C0qFyD_1<}cFE0Vo&1Bvj_RXU9~>Ja|5>4+!)9)W+Cv^)cY8Z`WAA@u}wgQ2kP-*PFCH zAk6m@m)pLtj{zU}gI-74&kL2DAF5x<^!(8WaNeZ~v*S^|pSa*Np0Mw!$M&Dn`v~+8 zRHu~bnFnQ<)Ca`*er#j$a(xV_>O#~$<@*QwEuXW|g`_?p&i5l5ZZ1F+cREh_{=z#O z-a$Dgod?AEern_47xey}I7gLHIX~2fl_D|23ctn+^K0xRD zsU4i(MU89Daf$uyvqx5@K0xRDiT~9%q+4U8cYUcoDedWli4WlTeq_bX1&Fc*68qcZ z9UM#CXTn_HPxa&PKS%M^9S_U*r+TH#RyVjlfb08-&!%4{=P$8;wv35MRLSuHT;ES^ zaB=~n?104n-Q~}DpTIO9{<`(a<^cHrepBD|C4G|8u1?&2Fxp-x$%mh}Fxfh=toz&L z95s%j-X}Jkt{d>co^n&u}v&e_X_dSAqb)O~n?=64QgDgr;E3 z|CJlfV?c@hi^JbE7eLnii^CrMhiNW=tos*>Kk9%Wg_~ zmqnjBzY9?C*#8j7@u@6ina4WtHy?uQyur@}kNqbap0_!V?6TN%T1U0vmtRex>d7i85p z%k`WA_S0Z<23_}g%Wd_&Ze*EXkP}%RME3Zf?|JKU(&xU{quj{R^VUw$Z~q+t8*nl= zeeZINP(Zny0O|t@e+SlqzE{Be6nhaiRy=RJ${zPCm5LAi-w_???);+%@;=wBR2o74 z_!)e_qdn-4jM1<$YUvo*`CVb`@mRCjoKfcI0VUA=qeDYOmq+o(<1iN(ErA@$X>)3| zHF50e9PpnI9Vk{DFz9(dCce6I*l{ic{;!G-6h;SLS>QOA>bR@teczuWu|OgC|F2%J ze_UnD-S;b%MPLJtiyg?V9vo{_DkEIpVb{%a-TA=(KcWM<(}6dD{lYM&rpLg3%mw}u z4_KO$TNqo18;wTOlyltm!w?g~+;H4NU&}ccv!zR(_YAJ%#Ia0s4s>80=)iwP5Bkm@ z90fKvr(w(e?%?3y%=2r-=R^;Bt_SCU#ctiY9+$1jbsw8Ka}d{)<=JufbpT}!<9%n; zvm6tS8C*L6eHn#5VII-jViTaor#dN<~U2#6I_yD|L@B-+= zBy6W)dtY=zs~h+}9?A;e%|O{5Kv|+p0nqfUAW1zU0g-@6KqMd%5DAC`L;@lKk$^}* NBp?zH36w_y9{_}8Y(M}2 literal 0 HcmV?d00001 diff --git a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py index 9a8b1e37..56f8e3da 100644 --- a/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py +++ b/examples/340-tauri-live-transcription-rust-ts/tests/test_example.py @@ -32,6 +32,7 @@ def test_file_structure(): "src/src-tauri/src/main.rs", "src/src-tauri/Cargo.toml", "src/src-tauri/Info.plist", + "src/src-tauri/icons/icon.ico", "src/src-tauri/tauri.conf.json", "src/src/main.ts", "src/index.html",