From 463589e69cdf2ea84daa4454c8a4c03bb8811cd7 Mon Sep 17 00:00:00 2001 From: MTRNord Date: Thu, 6 Nov 2025 11:43:45 +0100 Subject: [PATCH 1/4] fix(matrix-sdk-ffi): remove bundled-sqlite from default features sqlite does not compile on wasm platforms. Therefor we probably shouldn't have it as the default since indexeddb support was added. Instead enabling it on demand together with the sqlite feature seems like a better solution Signed-off-by: MTRNord --- bindings/matrix-sdk-ffi/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index ec69c1ddbc0..ba6663214fb 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -24,7 +24,7 @@ crate-type = [ ] [features] -default = ["bundled-sqlite", "unstable-msc4274", "experimental-element-recent-emojis"] +default = ["unstable-msc4274", "experimental-element-recent-emojis"] # Use SQLite for the session storage. sqlite = ["matrix-sdk/sqlite"] # Use an embedded version of SQLite. From b87c179bade176416c5f566dd30eeaf947b62feb Mon Sep 17 00:00:00 2001 From: MTRNord Date: Thu, 6 Nov 2025 11:44:52 +0100 Subject: [PATCH 2/4] fix(matrix-sdk-ffi): fix depenendencies for the wasm bindings wasm methods use futures-executor which was missing from the dependencies so far. Additionally as wasm isn't Send we need to tell uniffi about that when compiling for wasm. Signed-off-by: MTRNord --- bindings/matrix-sdk-ffi/Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index ba6663214fb..321e754080a 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -89,7 +89,8 @@ oauth2.workspace = true [target.'cfg(target_family = "wasm")'.dependencies] console_error_panic_hook = "0.1.7" tokio = { workspace = true, features = ["sync", "macros"] } -uniffi.workspace = true +uniffi = { workspace = true, features = ["wasm-unstable-single-threaded"] } +futures-executor.workspace = true [target.'cfg(not(target_family = "wasm"))'.dependencies] async-compat.workspace = true From a964f0932c433910ba944b3f5c70cd394ef98f68 Mon Sep 17 00:00:00 2001 From: MTRNord Date: Thu, 6 Nov 2025 11:46:46 +0100 Subject: [PATCH 3/4] fix(matrix-sdk-ffi): add missing wasm stubs This adds stubs for wasm Uniffi does not support cfg attributes like previously used here. If _any_ platform exports it will generate the skeleton for _all_ platforms every time. Using uniffi::method attributes also will not fix this where we have different exports based on platform. Therefor stubs sadly are the only way to handle this as of now. Signed-off-by: MTRNord --- bindings/matrix-sdk-ffi/src/client.rs | 121 +++++++++++------- bindings/matrix-sdk-ffi/src/client_builder.rs | 32 ++++- 2 files changed, 104 insertions(+), 49 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index ad39d52f011..abe87e8f45c 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -928,7 +928,6 @@ impl Client { } } -#[cfg(not(target_family = "wasm"))] #[matrix_sdk_ffi_macros::export] impl Client { /// Retrieves a media file from the media source @@ -942,22 +941,54 @@ impl Client { use_cache: bool, temp_dir: Option, ) -> Result, ClientError> { - let source = (*media_source).clone(); - let mime_type: mime::Mime = mime_type.parse()?; + #[cfg(not(target_family = "wasm"))] + { + let source = (*media_source).clone(); + let mime_type: mime::Mime = mime_type.parse()?; - let handle = self - .inner - .media() - .get_media_file( - &MediaRequestParameters { source: source.media_source, format: MediaFormat::File }, - filename, - &mime_type, - use_cache, - temp_dir, - ) - .await?; + let handle = self + .inner + .media() + .get_media_file( + &MediaRequestParameters { + source: source.media_source, + format: MediaFormat::File, + }, + filename, + &mime_type, + use_cache, + temp_dir, + ) + .await?; + + return Ok(Arc::new(MediaFileHandle::new(handle))); + } - Ok(Arc::new(MediaFileHandle::new(handle))) + #[cfg(target_family = "wasm")] + return Err(ClientError::Generic { + msg: "get_media_file is not supported on wasm platforms".to_owned(), + details: None, + }); + } + + pub async fn set_display_name(&self, name: String) -> Result<(), ClientError> { + #[cfg(not(target_family = "wasm"))] + { + self.inner + .account() + .set_display_name(Some(name.as_str())) + .await + .context("Unable to set display name")?; + return Ok(()); + } + + #[cfg(target_family = "wasm")] + { + Err(ClientError::Generic { + msg: "set_display_name is not supported on wasm platforms".to_owned(), + details: None, + }) + } } } @@ -1093,15 +1124,6 @@ impl Client { Ok(display_name) } - pub async fn set_display_name(&self, name: String) -> Result<(), ClientError> { - self.inner - .account() - .set_display_name(Some(name.as_str())) - .await - .context("Unable to set display name")?; - Ok(()) - } - pub async fn upload_avatar(&self, mime_type: String, data: Vec) -> Result<(), ClientError> { let mime: Mime = mime_type.parse()?; self.inner.account().upload_avatar(&mime, data).await?; @@ -2453,25 +2475,25 @@ fn gen_transaction_id() -> String { /// A file handle that takes ownership of a media file on disk. When the handle /// is dropped, the file will be removed from the disk. -#[cfg(not(target_family = "wasm"))] #[derive(uniffi::Object)] pub struct MediaFileHandle { + #[cfg(not(target_family = "wasm"))] inner: std::sync::RwLock>, } -#[cfg(not(target_family = "wasm"))] impl MediaFileHandle { + #[cfg(not(target_family = "wasm"))] fn new(handle: SdkMediaFileHandle) -> Self { Self { inner: std::sync::RwLock::new(Some(handle)) } } } -#[cfg(not(target_family = "wasm"))] #[matrix_sdk_ffi_macros::export] impl MediaFileHandle { /// Get the media file's path. pub fn path(&self) -> Result { - Ok(self + #[cfg(not(target_family = "wasm"))] + return Ok(self .inner .read() .unwrap() @@ -2480,24 +2502,37 @@ impl MediaFileHandle { .path() .to_str() .unwrap() - .to_owned()) + .to_owned()); + #[cfg(target_family = "wasm")] + return Err(ClientError::Generic { + msg: "MediaFileHandle.path() is not supported on WASM targets".to_string(), + details: None, + }); } pub fn persist(&self, path: String) -> Result { - let mut guard = self.inner.write().unwrap(); - Ok( - match guard - .take() - .context("MediaFileHandle was already persisted")? - .persist(path.as_ref()) - { - Ok(_) => true, - Err(e) => { - *guard = Some(e.file); - false - } - }, - ) + #[cfg(not(target_family = "wasm"))] + { + let mut guard = self.inner.write().unwrap(); + return Ok( + match guard + .take() + .context("MediaFileHandle was already persisted")? + .persist(path.as_ref()) + { + Ok(_) => true, + Err(e) => { + *guard = Some(e.file); + false + } + }, + ); + } + #[cfg(target_family = "wasm")] + return Err(ClientError::Generic { + msg: "MediaFileHandle.persist() is not supported on WASM targets".to_string(), + details: None, + }); } } diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index 8249c8775a6..826e11e5a0f 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -152,15 +152,20 @@ impl ClientBuilder { system_is_memory_constrained: false, username: None, homeserver_cfg: None, + #[cfg(not(target_family = "wasm"))] user_agent: None, sliding_sync_version_builder: SlidingSyncVersionBuilder::None, + #[cfg(not(target_family = "wasm"))] proxy: None, + #[cfg(not(target_family = "wasm"))] disable_ssl_verification: false, disable_automatic_token_refresh: false, cross_process_store_locks_holder_name: None, enable_oidc_refresh_lock: false, session_delegate: None, + #[cfg(not(target_family = "wasm"))] additional_root_certificates: Default::default(), + #[cfg(not(target_family = "wasm"))] disable_built_in_root_certificates: false, encryption_settings: EncryptionSettings { auto_enable_cross_signing: false, @@ -559,18 +564,23 @@ impl ClientBuilder { } } -#[cfg(not(target_family = "wasm"))] #[matrix_sdk_ffi_macros::export] impl ClientBuilder { pub fn proxy(self: Arc, url: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.proxy = Some(url); + #[cfg(not(target_family = "wasm"))] + { + builder.proxy = Some(url); + } Arc::new(builder) } pub fn disable_ssl_verification(self: Arc) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.disable_ssl_verification = true; + #[cfg(not(target_family = "wasm"))] + { + builder.disable_ssl_verification = true; + } Arc::new(builder) } @@ -579,7 +589,11 @@ impl ClientBuilder { certificates: Vec, ) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.additional_root_certificates = certificates; + + #[cfg(not(target_family = "wasm"))] + { + builder.additional_root_certificates = certificates; + } Arc::new(builder) } @@ -589,13 +603,19 @@ impl ClientBuilder { /// [`add_root_certificates`][ClientBuilder::add_root_certificates]. pub fn disable_built_in_root_certificates(self: Arc) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.disable_built_in_root_certificates = true; + #[cfg(not(target_family = "wasm"))] + { + builder.disable_built_in_root_certificates = true; + } Arc::new(builder) } pub fn user_agent(self: Arc, user_agent: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.user_agent = Some(user_agent); + #[cfg(not(target_family = "wasm"))] + { + builder.user_agent = Some(user_agent); + } Arc::new(builder) } } From fd93a0f2222adbd589bbd00b7f9d12481f730a7c Mon Sep 17 00:00:00 2001 From: MTRNord Date: Thu, 6 Nov 2025 12:08:01 +0100 Subject: [PATCH 4/4] chore: remove return keywords as per clippy warnings Signed-off-by: MTRNord --- bindings/matrix-sdk-ffi/src/client.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index abe87e8f45c..31c9e4e2667 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -961,14 +961,14 @@ impl Client { ) .await?; - return Ok(Arc::new(MediaFileHandle::new(handle))); + Ok(Arc::new(MediaFileHandle::new(handle))) } #[cfg(target_family = "wasm")] - return Err(ClientError::Generic { + Err(ClientError::Generic { msg: "get_media_file is not supported on wasm platforms".to_owned(), details: None, - }); + }) } pub async fn set_display_name(&self, name: String) -> Result<(), ClientError> { @@ -979,7 +979,7 @@ impl Client { .set_display_name(Some(name.as_str())) .await .context("Unable to set display name")?; - return Ok(()); + Ok(()) } #[cfg(target_family = "wasm")] @@ -2504,17 +2504,17 @@ impl MediaFileHandle { .unwrap() .to_owned()); #[cfg(target_family = "wasm")] - return Err(ClientError::Generic { + Err(ClientError::Generic { msg: "MediaFileHandle.path() is not supported on WASM targets".to_string(), details: None, - }); + }) } pub fn persist(&self, path: String) -> Result { #[cfg(not(target_family = "wasm"))] { let mut guard = self.inner.write().unwrap(); - return Ok( + Ok( match guard .take() .context("MediaFileHandle was already persisted")? @@ -2526,13 +2526,13 @@ impl MediaFileHandle { false } }, - ); + ) } #[cfg(target_family = "wasm")] - return Err(ClientError::Generic { + Err(ClientError::Generic { msg: "MediaFileHandle.persist() is not supported on WASM targets".to_string(), details: None, - }); + }) } }