From cba384ca1ca19ddb9ee969b1805298118c97673f Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Tue, 20 Oct 2026 22:03:50 +0800 Subject: [PATCH 1/5] Replace livekit_uniffi with livekit_ffi ^0.13.0 The Rust core package moved to the livekit-ffi crate and is now published as livekit_ffi. Its build hook downloads prebuilt libraries from the livekit-ffi/v* releases. Co-Authored-By: Claude Opus 5.5 --- .changes/uniffi-rust-core-dev-wiring | 2 +- AGENTS.md | 12 ++++++------ lib/src/uniffi/uniffi.dart | 4 ++-- lib/src/uniffi/uniffi_io.dart | 2 +- lib/src/uniffi/uniffi_web.dart | 2 +- pubspec.lock | 8 ++++---- pubspec.yaml | 4 ++-- test/uniffi/uniffi_test.dart | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.changes/uniffi-rust-core-dev-wiring b/.changes/uniffi-rust-core-dev-wiring index bc9ac8dbc..1ddb01c27 100644 --- a/.changes/uniffi-rust-core-dev-wiring +++ b/.changes/uniffi-rust-core-dev-wiring @@ -1 +1 @@ -minor type="added" "Wire in the livekit_uniffi Rust core behind a native-only facade, delivered as a bundled cdylib via Native Assets" +minor type="added" "Wire in the livekit_ffi Rust core behind a native-only facade, delivered as a bundled cdylib via Native Assets" diff --git a/AGENTS.md b/AGENTS.md index d58fea1e8..44fc64ca3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,18 +32,18 @@ CI (`build.yaml`) runs all of the above plus example-app builds for every platfo Web/native divergence is handled with conditional imports (e.g. `track/processor_native.dart` vs `processor_web.dart`) — new platform-specific code should follow that pattern. -## The Rust core (`livekit_uniffi`) +## The Rust core (`livekit_ffi`) -`lib/src/uniffi/` wraps `livekit_uniffi`, a Dart package generated from the `livekit-uniffi` crate in the sibling `rust-sdks` repo. It reaches Rust through Dart's Native Assets: the package's `hook/build.dart` bundles a `cdylib` into the host app and the generated bindings call into it with `@Native`. This is why the SDK requires Flutter >= 3.38 / Dart >= 3.10. +`lib/src/uniffi/` wraps `livekit_ffi`, a Dart package generated from the `livekit-ffi` crate in the sibling `rust-sdks` repo. It reaches Rust through Dart's Native Assets: the package's `hook/build.dart` bundles a `cdylib` into the host app and the generated bindings call into it with `@Native`. This is why the SDK requires Flutter >= 3.38 / Dart >= 3.10. -There is no dynamic library to load on the web, so `uniffi.dart` splits native/web the same way the rest of the SDK does. **`uniffi_io.dart` is the only file allowed to import `package:livekit_uniffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitUniffi.isAvailable`. +There is no dynamic library to load on the web, so `uniffi.dart` splits native/web the same way the rest of the SDK does. **`uniffi_io.dart` is the only file allowed to import `package:livekit_ffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitUniffi.isAvailable`. ### Local development loop -`livekit_uniffi` is published on pub.dev and the normal dependency resolves it; its build hook downloads the matching prebuilt library from the `livekit-uniffi` GitHub release, so no Rust toolchain is needed. To develop against unreleased crate changes, point both `pubspec.yaml` and `example/pubspec.yaml` at a sibling `rust-sdks` checkout with a `dependency_overrides` entry (`path: ../rust-sdks/livekit-uniffi/packages/dart`, overrides do not propagate from a dependency, hence both) and produce or refresh the package with: +`livekit_ffi` is published on pub.dev and the normal dependency resolves it; its build hook downloads the matching prebuilt library from the `livekit-ffi` GitHub release, so no Rust toolchain is needed. To develop against unreleased crate changes, point both `pubspec.yaml` and `example/pubspec.yaml` at a sibling `rust-sdks` checkout with a `dependency_overrides` entry (`path: ../rust-sdks/livekit-ffi/packages/dart`, overrides do not propagate from a dependency, hence both) and produce or refresh the package with: ```sh -cd ../rust-sdks/livekit-uniffi +cd ../rust-sdks/livekit-ffi cargo make dart-package # generates packages/dart/: bindings, pubspec, build hook, host cdylib cd - flutter pub get @@ -52,7 +52,7 @@ flutter test test/uniffi/ # smoke test: calls buildVersion() across the FFI bou Requires `cargo-make`, `protoc` and `tera`. Re-run `cargo make dart-package` whenever the crate's exported surface changes — the build hook tracks the copied library, so a stale one won't be silently reused. -Two things to know about that hook: it picks the locally built library purely on target *OS*, not architecture, so a host build can be bundled into an iOS or Android build by mistake — verify the desktop target first when debugging. And its download mode (used when no local library is present) fetches `build-.zip` from the `livekit-uniffi` GitHub release matching the package version and verifies its SHA-256, so a version whose release lacks assets fails at build time rather than at runtime. +Two things to know about that hook: it picks the locally built library purely on target *OS*, not architecture, so a host build can be bundled into an iOS or Android build by mistake — verify the desktop target first when debugging. And its download mode (used when no local library is present) fetches `build-.zip` from the `livekit-ffi` GitHub release matching the package version and verifies its SHA-256, so a version whose release lacks assets fails at build time rather than at runtime. ## Common pitfalls (from issue history) diff --git a/lib/src/uniffi/uniffi.dart b/lib/src/uniffi/uniffi.dart index c25367087..ae4422552 100644 --- a/lib/src/uniffi/uniffi.dart +++ b/lib/src/uniffi/uniffi.dart @@ -16,9 +16,9 @@ import 'package:meta/meta.dart'; import 'uniffi_io.dart' if (dart.library.js_interop) 'uniffi_web.dart' as impl; -/// Facade over the Rust core exposed by the `livekit_uniffi` package. +/// Facade over the Rust core exposed by the `livekit_ffi` package. /// -/// `livekit_uniffi` reaches Rust through Dart's Native Assets: its build hook +/// `livekit_ffi` reaches Rust through Dart's Native Assets: its build hook /// bundles a `cdylib` into the host app and the generated bindings call into it /// with `@Native`. None of that exists on the web, where there is no dynamic /// library to load, so every entry point here is split native/web through the diff --git a/lib/src/uniffi/uniffi_io.dart b/lib/src/uniffi/uniffi_io.dart index 983c5aaf2..77450e49a 100644 --- a/lib/src/uniffi/uniffi_io.dart +++ b/lib/src/uniffi/uniffi_io.dart @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'package:livekit_uniffi/livekit_uniffi.dart' as uniffi; +import 'package:livekit_ffi/livekit_ffi.dart' as uniffi; /// Native implementation of [LiveKitUniffi]. See `uniffi.dart`. /// diff --git a/lib/src/uniffi/uniffi_web.dart b/lib/src/uniffi/uniffi_web.dart index db2ab1968..b170ff58c 100644 --- a/lib/src/uniffi/uniffi_web.dart +++ b/lib/src/uniffi/uniffi_web.dart @@ -16,7 +16,7 @@ /// /// Native Assets bundles a `cdylib`, which the web has no way to load, so the /// Rust core is simply absent here. This file deliberately does not import -/// `package:livekit_uniffi/...` -- doing so would pull `dart:ffi` into a web +/// `package:livekit_ffi/...` -- doing so would pull `dart:ffi` into a web /// compile and fail the build. const bool isAvailable = false; diff --git a/pubspec.lock b/pubspec.lock index f477e15ab..2f8c81e36 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -440,14 +440,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.0" - livekit_uniffi: + livekit_ffi: dependency: "direct main" description: - name: livekit_uniffi - sha256: "8ff1402ed684ce09899d77faeb828676030fff2ebf5449678484e665440c6e14" + name: livekit_ffi + sha256: "7b2a95698497b4c572c8da64588fc295e609aea235faf0552fc7e5c8c013c410" url: "https://pub.dev" source: hosted - version: "0.2.2" + version: "0.13.0" logger: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 85f0d6c57..4eed90cad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -57,9 +57,9 @@ dependencies: flutter_webrtc: 1.6.2+hotfix.4 dart_webrtc: ^1.8.0 - # Rust core (livekit-uniffi), delivered as a bundled cdylib via Native Assets. + # Rust core (livekit-ffi), delivered as a bundled cdylib via Native Assets. # Native platforms only, see lib/src/uniffi/. - livekit_uniffi: ^0.2.2 + livekit_ffi: ^0.13.0 dev_dependencies: flutter_test: diff --git a/test/uniffi/uniffi_test.dart b/test/uniffi/uniffi_test.dart index b0f6df841..a506c2a14 100644 --- a/test/uniffi/uniffi_test.dart +++ b/test/uniffi/uniffi_test.dart @@ -24,7 +24,7 @@ void main() { // build hook resolved a cdylib for this target, Native Assets bundled it, // `@Native` bound the symbol, and a value crossed back from Rust. If the // bindgen or the hook regresses, this is what fails first. - group('livekit_uniffi', () { + group('livekit_ffi', () { test('is available on native platforms', () { expect(LiveKitUniffi.isAvailable, isTrue); }); @@ -33,7 +33,7 @@ void main() { final version = LiveKitUniffi.buildVersion; expect(version, isNotEmpty); // The crate stamps its own semver, so assert the shape rather than a - // literal that would need bumping on every livekit-uniffi release. + // literal that would need bumping on every livekit-ffi release. expect(version, matches(RegExp(r'^\d+\.\d+\.\d+'))); }); }); From cba7defeb0a5f0d03e5b51de7ca9f14fc2a706df Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Tue, 20 Oct 2026 22:04:44 +0800 Subject: [PATCH 2/5] Rename the uniffi facade files to ffi Matches the livekit_ffi package name: lib/src/uniffi/ becomes lib/src/ffi/ and test/uniffi/ becomes test/ffi/. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 6 +++--- lib/livekit_client.dart | 2 +- lib/src/{uniffi/uniffi.dart => ffi/ffi.dart} | 2 +- lib/src/{uniffi/uniffi_io.dart => ffi/ffi_io.dart} | 8 ++++---- lib/src/{uniffi/uniffi_web.dart => ffi/ffi_web.dart} | 2 +- pubspec.yaml | 2 +- test/{uniffi/uniffi_test.dart => ffi/ffi_test.dart} | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) rename lib/src/{uniffi/uniffi.dart => ffi/ffi.dart} (96%) rename lib/src/{uniffi/uniffi_io.dart => ffi/ffi_io.dart} (74%) rename lib/src/{uniffi/uniffi_web.dart => ffi/ffi_web.dart} (94%) rename test/{uniffi/uniffi_test.dart => ffi/ffi_test.dart} (96%) diff --git a/AGENTS.md b/AGENTS.md index 44fc64ca3..7b74fc52d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,9 +34,9 @@ Web/native divergence is handled with conditional imports (e.g. `track/processor ## The Rust core (`livekit_ffi`) -`lib/src/uniffi/` wraps `livekit_ffi`, a Dart package generated from the `livekit-ffi` crate in the sibling `rust-sdks` repo. It reaches Rust through Dart's Native Assets: the package's `hook/build.dart` bundles a `cdylib` into the host app and the generated bindings call into it with `@Native`. This is why the SDK requires Flutter >= 3.38 / Dart >= 3.10. +`lib/src/ffi/` wraps `livekit_ffi`, a Dart package generated from the `livekit-ffi` crate in the sibling `rust-sdks` repo. It reaches Rust through Dart's Native Assets: the package's `hook/build.dart` bundles a `cdylib` into the host app and the generated bindings call into it with `@Native`. This is why the SDK requires Flutter >= 3.38 / Dart >= 3.10. -There is no dynamic library to load on the web, so `uniffi.dart` splits native/web the same way the rest of the SDK does. **`uniffi_io.dart` is the only file allowed to import `package:livekit_ffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitUniffi.isAvailable`. +There is no dynamic library to load on the web, so `ffi.dart` splits native/web the same way the rest of the SDK does. **`ffi_io.dart` is the only file allowed to import `package:livekit_ffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitUniffi.isAvailable`. ### Local development loop @@ -47,7 +47,7 @@ cd ../rust-sdks/livekit-ffi cargo make dart-package # generates packages/dart/: bindings, pubspec, build hook, host cdylib cd - flutter pub get -flutter test test/uniffi/ # smoke test: calls buildVersion() across the FFI boundary +flutter test test/ffi/ # smoke test: calls buildVersion() across the FFI boundary ``` Requires `cargo-make`, `protoc` and `tera`. Re-run `cargo make dart-package` whenever the crate's exported surface changes — the build hook tracks the copied library, so a stale one won't be silently reused. diff --git a/lib/livekit_client.dart b/lib/livekit_client.dart index e529ed165..5d57be5cd 100644 --- a/lib/livekit_client.dart +++ b/lib/livekit_client.dart @@ -90,7 +90,7 @@ export 'src/token_source/custom.dart'; export 'src/token_source/caching.dart'; export 'src/token_source/development.dart'; export 'src/token_source/jwt.dart'; -export 'src/uniffi/uniffi.dart'; +export 'src/ffi/ffi.dart'; /// Misspelled alias for [kRpcVersion]. Kept for backwards compatibility with code /// that referenced the original typo. diff --git a/lib/src/uniffi/uniffi.dart b/lib/src/ffi/ffi.dart similarity index 96% rename from lib/src/uniffi/uniffi.dart rename to lib/src/ffi/ffi.dart index ae4422552..fe4fab7e2 100644 --- a/lib/src/uniffi/uniffi.dart +++ b/lib/src/ffi/ffi.dart @@ -14,7 +14,7 @@ import 'package:meta/meta.dart'; -import 'uniffi_io.dart' if (dart.library.js_interop) 'uniffi_web.dart' as impl; +import 'ffi_io.dart' if (dart.library.js_interop) 'ffi_web.dart' as impl; /// Facade over the Rust core exposed by the `livekit_ffi` package. /// diff --git a/lib/src/uniffi/uniffi_io.dart b/lib/src/ffi/ffi_io.dart similarity index 74% rename from lib/src/uniffi/uniffi_io.dart rename to lib/src/ffi/ffi_io.dart index 77450e49a..dad5ee678 100644 --- a/lib/src/uniffi/uniffi_io.dart +++ b/lib/src/ffi/ffi_io.dart @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import 'package:livekit_ffi/livekit_ffi.dart' as uniffi; +import 'package:livekit_ffi/livekit_ffi.dart' as ffi; -/// Native implementation of [LiveKitUniffi]. See `uniffi.dart`. +/// Native implementation of [LiveKitUniffi]. See `ffi.dart`. /// /// This is the only file in the SDK that may import the generated bindings: -/// the conditional import in `uniffi.dart` keeps it out of web builds. +/// the conditional import in `ffi.dart` keeps it out of web builds. const bool isAvailable = true; -String buildVersion() => uniffi.buildVersion(); +String buildVersion() => ffi.buildVersion(); diff --git a/lib/src/uniffi/uniffi_web.dart b/lib/src/ffi/ffi_web.dart similarity index 94% rename from lib/src/uniffi/uniffi_web.dart rename to lib/src/ffi/ffi_web.dart index b170ff58c..391615145 100644 --- a/lib/src/uniffi/uniffi_web.dart +++ b/lib/src/ffi/ffi_web.dart @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// Web implementation of [LiveKitUniffi]. See `uniffi.dart`. +/// Web implementation of [LiveKitUniffi]. See `ffi.dart`. /// /// Native Assets bundles a `cdylib`, which the web has no way to load, so the /// Rust core is simply absent here. This file deliberately does not import diff --git a/pubspec.yaml b/pubspec.yaml index 4eed90cad..074180888 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,7 +58,7 @@ dependencies: dart_webrtc: ^1.8.0 # Rust core (livekit-ffi), delivered as a bundled cdylib via Native Assets. - # Native platforms only, see lib/src/uniffi/. + # Native platforms only, see lib/src/ffi/. livekit_ffi: ^0.13.0 dev_dependencies: diff --git a/test/uniffi/uniffi_test.dart b/test/ffi/ffi_test.dart similarity index 96% rename from test/uniffi/uniffi_test.dart rename to test/ffi/ffi_test.dart index a506c2a14..1e4e1e688 100644 --- a/test/uniffi/uniffi_test.dart +++ b/test/ffi/ffi_test.dart @@ -17,7 +17,7 @@ library; import 'package:flutter_test/flutter_test.dart'; -import 'package:livekit_client/src/uniffi/uniffi.dart'; +import 'package:livekit_client/src/ffi/ffi.dart'; void main() { // Exercises the whole delivery chain rather than any particular API: the From b546bb4f714e2e4e369d8e98ae4ead98340a5e76 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Tue, 20 Oct 2026 22:06:21 +0800 Subject: [PATCH 3/5] Rename LiveKitUniffi to LiveKitFfi The class has not shipped yet, so rename it along with the package and files. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 2 +- example/lib/utils.dart | 6 +++--- lib/src/ffi/ffi.dart | 2 +- lib/src/ffi/ffi_io.dart | 2 +- lib/src/ffi/ffi_web.dart | 6 +++--- test/ffi/ffi_test.dart | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7b74fc52d..17d825e27 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,7 +36,7 @@ Web/native divergence is handled with conditional imports (e.g. `track/processor `lib/src/ffi/` wraps `livekit_ffi`, a Dart package generated from the `livekit-ffi` crate in the sibling `rust-sdks` repo. It reaches Rust through Dart's Native Assets: the package's `hook/build.dart` bundles a `cdylib` into the host app and the generated bindings call into it with `@Native`. This is why the SDK requires Flutter >= 3.38 / Dart >= 3.10. -There is no dynamic library to load on the web, so `ffi.dart` splits native/web the same way the rest of the SDK does. **`ffi_io.dart` is the only file allowed to import `package:livekit_ffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitUniffi.isAvailable`. +There is no dynamic library to load on the web, so `ffi.dart` splits native/web the same way the rest of the SDK does. **`ffi_io.dart` is the only file allowed to import `package:livekit_ffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitFfi.isAvailable`. ### Local development loop diff --git a/example/lib/utils.dart b/example/lib/utils.dart index 2142b23cf..6052c17b0 100644 --- a/example/lib/utils.dart +++ b/example/lib/utils.dart @@ -6,15 +6,15 @@ import 'package:livekit_client/livekit_client.dart'; FutureOr Function()? onWindowShouldClose; -/// One synchronous call into the Rust core through the uniffi facade. The +/// One synchronous call into the Rust core through the ffi facade. The /// example shows the result at startup and on the connect page as a smoke /// test that the native library was bundled and loads on this platform. String rustCoreVersionLabel() { - if (!LiveKitUniffi.isAvailable) { + if (!LiveKitFfi.isAvailable) { return 'Rust core not available on this platform'; } try { - return 'Rust core ${LiveKitUniffi.buildVersion}'; + return 'Rust core ${LiveKitFfi.buildVersion}'; } catch (error) { return 'Rust core failed to load: $error'; } diff --git a/lib/src/ffi/ffi.dart b/lib/src/ffi/ffi.dart index fe4fab7e2..6e252e369 100644 --- a/lib/src/ffi/ffi.dart +++ b/lib/src/ffi/ffi.dart @@ -29,7 +29,7 @@ import 'ffi_io.dart' if (dart.library.js_interop) 'ffi_web.dart' as impl; /// Callers get [isAvailable] to branch on, and platform-specific code paths /// stay out of the public API surface. @experimental -abstract final class LiveKitUniffi { +abstract final class LiveKitFfi { /// Whether the Rust core can be called on this platform. /// /// False on web. Every other member throws [UnsupportedError] when this is diff --git a/lib/src/ffi/ffi_io.dart b/lib/src/ffi/ffi_io.dart index dad5ee678..c2dfddf0c 100644 --- a/lib/src/ffi/ffi_io.dart +++ b/lib/src/ffi/ffi_io.dart @@ -14,7 +14,7 @@ import 'package:livekit_ffi/livekit_ffi.dart' as ffi; -/// Native implementation of [LiveKitUniffi]. See `ffi.dart`. +/// Native implementation of [LiveKitFfi]. See `ffi.dart`. /// /// This is the only file in the SDK that may import the generated bindings: /// the conditional import in `ffi.dart` keeps it out of web builds. diff --git a/lib/src/ffi/ffi_web.dart b/lib/src/ffi/ffi_web.dart index 391615145..1b5f1d11a 100644 --- a/lib/src/ffi/ffi_web.dart +++ b/lib/src/ffi/ffi_web.dart @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// Web implementation of [LiveKitUniffi]. See `ffi.dart`. +/// Web implementation of [LiveKitFfi]. See `ffi.dart`. /// /// Native Assets bundles a `cdylib`, which the web has no way to load, so the /// Rust core is simply absent here. This file deliberately does not import @@ -21,7 +21,7 @@ const bool isAvailable = false; Never buildVersion() => throw UnsupportedError( - 'LiveKitUniffi.buildVersion is not available on web: the Rust core is ' + 'LiveKitFfi.buildVersion is not available on web: the Rust core is ' 'delivered as a native library. Guard calls with ' - 'LiveKitUniffi.isAvailable.', + 'LiveKitFfi.isAvailable.', ); diff --git a/test/ffi/ffi_test.dart b/test/ffi/ffi_test.dart index 1e4e1e688..7bbbfdf64 100644 --- a/test/ffi/ffi_test.dart +++ b/test/ffi/ffi_test.dart @@ -26,11 +26,11 @@ void main() { // bindgen or the hook regresses, this is what fails first. group('livekit_ffi', () { test('is available on native platforms', () { - expect(LiveKitUniffi.isAvailable, isTrue); + expect(LiveKitFfi.isAvailable, isTrue); }); test('buildVersion returns the Rust core version', () { - final version = LiveKitUniffi.buildVersion; + final version = LiveKitFfi.buildVersion; expect(version, isNotEmpty); // The crate stamps its own semver, so assert the shape rather than a // literal that would need bumping on every livekit-ffi release. From 3a6238a96b87fec76470100d8aa4464475aac9be Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Tue, 20 Oct 2026 22:10:55 +0800 Subject: [PATCH 4/5] Rename LiveKitFfi to LiveKitFFI Matches the all-caps acronym style of the existing public API, such as E2EEManager and LiveKitE2EEException. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 2 +- example/lib/utils.dart | 4 ++-- lib/src/ffi/ffi.dart | 2 +- lib/src/ffi/ffi_io.dart | 2 +- lib/src/ffi/ffi_web.dart | 6 +++--- test/ffi/ffi_test.dart | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 17d825e27..da50475ec 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,7 +36,7 @@ Web/native divergence is handled with conditional imports (e.g. `track/processor `lib/src/ffi/` wraps `livekit_ffi`, a Dart package generated from the `livekit-ffi` crate in the sibling `rust-sdks` repo. It reaches Rust through Dart's Native Assets: the package's `hook/build.dart` bundles a `cdylib` into the host app and the generated bindings call into it with `@Native`. This is why the SDK requires Flutter >= 3.38 / Dart >= 3.10. -There is no dynamic library to load on the web, so `ffi.dart` splits native/web the same way the rest of the SDK does. **`ffi_io.dart` is the only file allowed to import `package:livekit_ffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitFfi.isAvailable`. +There is no dynamic library to load on the web, so `ffi.dart` splits native/web the same way the rest of the SDK does. **`ffi_io.dart` is the only file allowed to import `package:livekit_ffi/...`** — importing it from anywhere reachable on web pulls `dart:ffi` into a web compile and breaks `flutter build web`/`--wasm`. Guard calls with `LiveKitFFI.isAvailable`. ### Local development loop diff --git a/example/lib/utils.dart b/example/lib/utils.dart index 6052c17b0..a85f6064a 100644 --- a/example/lib/utils.dart +++ b/example/lib/utils.dart @@ -10,11 +10,11 @@ FutureOr Function()? onWindowShouldClose; /// example shows the result at startup and on the connect page as a smoke /// test that the native library was bundled and loads on this platform. String rustCoreVersionLabel() { - if (!LiveKitFfi.isAvailable) { + if (!LiveKitFFI.isAvailable) { return 'Rust core not available on this platform'; } try { - return 'Rust core ${LiveKitFfi.buildVersion}'; + return 'Rust core ${LiveKitFFI.buildVersion}'; } catch (error) { return 'Rust core failed to load: $error'; } diff --git a/lib/src/ffi/ffi.dart b/lib/src/ffi/ffi.dart index 6e252e369..9de213e81 100644 --- a/lib/src/ffi/ffi.dart +++ b/lib/src/ffi/ffi.dart @@ -29,7 +29,7 @@ import 'ffi_io.dart' if (dart.library.js_interop) 'ffi_web.dart' as impl; /// Callers get [isAvailable] to branch on, and platform-specific code paths /// stay out of the public API surface. @experimental -abstract final class LiveKitFfi { +abstract final class LiveKitFFI { /// Whether the Rust core can be called on this platform. /// /// False on web. Every other member throws [UnsupportedError] when this is diff --git a/lib/src/ffi/ffi_io.dart b/lib/src/ffi/ffi_io.dart index c2dfddf0c..b486a6f31 100644 --- a/lib/src/ffi/ffi_io.dart +++ b/lib/src/ffi/ffi_io.dart @@ -14,7 +14,7 @@ import 'package:livekit_ffi/livekit_ffi.dart' as ffi; -/// Native implementation of [LiveKitFfi]. See `ffi.dart`. +/// Native implementation of [LiveKitFFI]. See `ffi.dart`. /// /// This is the only file in the SDK that may import the generated bindings: /// the conditional import in `ffi.dart` keeps it out of web builds. diff --git a/lib/src/ffi/ffi_web.dart b/lib/src/ffi/ffi_web.dart index 1b5f1d11a..3f5e06d7f 100644 --- a/lib/src/ffi/ffi_web.dart +++ b/lib/src/ffi/ffi_web.dart @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -/// Web implementation of [LiveKitFfi]. See `ffi.dart`. +/// Web implementation of [LiveKitFFI]. See `ffi.dart`. /// /// Native Assets bundles a `cdylib`, which the web has no way to load, so the /// Rust core is simply absent here. This file deliberately does not import @@ -21,7 +21,7 @@ const bool isAvailable = false; Never buildVersion() => throw UnsupportedError( - 'LiveKitFfi.buildVersion is not available on web: the Rust core is ' + 'LiveKitFFI.buildVersion is not available on web: the Rust core is ' 'delivered as a native library. Guard calls with ' - 'LiveKitFfi.isAvailable.', + 'LiveKitFFI.isAvailable.', ); diff --git a/test/ffi/ffi_test.dart b/test/ffi/ffi_test.dart index 7bbbfdf64..73e42d670 100644 --- a/test/ffi/ffi_test.dart +++ b/test/ffi/ffi_test.dart @@ -26,11 +26,11 @@ void main() { // bindgen or the hook regresses, this is what fails first. group('livekit_ffi', () { test('is available on native platforms', () { - expect(LiveKitFfi.isAvailable, isTrue); + expect(LiveKitFFI.isAvailable, isTrue); }); test('buildVersion returns the Rust core version', () { - final version = LiveKitFfi.buildVersion; + final version = LiveKitFFI.buildVersion; expect(version, isNotEmpty); // The crate stamps its own semver, so assert the shape rather than a // literal that would need bumping on every livekit-ffi release. From 568e61a95e765e3cea0e1f76ec6f31ed1ace53be Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Thu, 22 Oct 2026 08:07:22 +0800 Subject: [PATCH 5/5] Bump livekit_ffi to ^0.13.1 --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 2f8c81e36..8de48fd5f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -444,10 +444,10 @@ packages: dependency: "direct main" description: name: livekit_ffi - sha256: "7b2a95698497b4c572c8da64588fc295e609aea235faf0552fc7e5c8c013c410" + sha256: "98aa7389ac511481617966f2e26e87a29be54e004a97dc2923ffd7af0883c5f2" url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.13.1" logger: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 074180888..f9c0de441 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,7 +59,7 @@ dependencies: # Rust core (livekit-ffi), delivered as a bundled cdylib via Native Assets. # Native platforms only, see lib/src/ffi/. - livekit_ffi: ^0.13.0 + livekit_ffi: ^0.13.1 dev_dependencies: flutter_test: