Skip to content

Commit fedd32e

Browse files
authored
WASM bindings update (#1643)
* Update lint:clippy command * Update ListConversationsOptions * Add consent option to sync_all_conversations * Add get_sync_group * Add find_or_create_dm_by_inbox_id * Add create_group_by_inbox_ids * Return ConversationListItem from list methods * Remove get_sync_group * Refactor MessageDisappearingSettings * Clippy fix * Update version and changelog
1 parent c598672 commit fedd32e

File tree

4 files changed

+185
-37
lines changed

4 files changed

+185
-37
lines changed

bindings_wasm/CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# @xmtp/wasm-bindings
22

3+
## 0.0.15
4+
5+
- Added `consent_states`, `include_sync_groups`, and `include_duplicate_dms` to `ListConversationsOptions`
6+
- Added `allowed_states` to `GroupQueryArgs`
7+
- Refactored `MessageDisappearingSettings` struct
8+
- Added `consent_states` options to `sync_all_conversations`
9+
- Added `create_group_by_inbox_ids` method to `Conversations`
10+
- Added `find_or_create_dm_by_inbox_id` method to `Conversations`
11+
- Added `ConversationListItem` struct
12+
- Updated `Conversations.list()` method to return `Vec<ConversationListItem>`
13+
- Fixed invalid key package issues
14+
- Fixed rate limiting issues
15+
316
## 0.0.14
417

518
- Removed group pinned frame URL

bindings_wasm/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@xmtp/wasm-bindings",
3-
"version": "0.0.14",
3+
"version": "0.0.15",
44
"type": "module",
55
"license": "MIT",
66
"description": "WASM bindings for the libXMTP rust library",
@@ -30,7 +30,7 @@
3030
"clean:release": "rm -f ./dist/package.json",
3131
"clean": "rm -rf ./dist",
3232
"lint": "yarn lint:clippy && yarn lint:fmt",
33-
"lint:clippy": "cargo clippy --all-features --target wasm32-unknown-unknown --no-deps -- -Dwarnings",
33+
"lint:clippy": "cargo clippy --locked --all-features --target wasm32-unknown-unknown --no-deps -- -D warnings",
3434
"lint:fmt": "cargo fmt --check",
3535
"prepublishOnly": "yarn build",
3636
"test": "wasm-pack test --chrome --headless"

bindings_wasm/src/conversation.rs

+1-17
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,12 @@ use xmtp_mls::storage::group_message::{GroupMessageKind as XmtpGroupMessageKind,
1919
use xmtp_proto::xmtp::mls::message_contents::EncodedContent as XmtpEncodedContent;
2020

2121
use prost::Message as ProstMessage;
22-
use xmtp_mls::groups::group_mutable_metadata::MessageDisappearingSettings as XmtpMessageDisappearingSettings;
2322

2423
#[wasm_bindgen]
2524
pub struct GroupMetadata {
2625
inner: XmtpGroupMetadata,
2726
}
2827

29-
#[wasm_bindgen]
30-
#[derive(Clone)]
31-
pub struct MessageDisappearingSettings {
32-
#[allow(dead_code)]
33-
inner: XmtpMessageDisappearingSettings,
34-
}
35-
36-
impl From<MessageDisappearingSettings> for XmtpMessageDisappearingSettings {
37-
fn from(value: MessageDisappearingSettings) -> Self {
38-
Self {
39-
from_ns: value.inner.from_ns,
40-
in_ns: value.inner.in_ns,
41-
}
42-
}
43-
}
44-
4528
#[wasm_bindgen]
4629
impl GroupMetadata {
4730
#[wasm_bindgen(js_name = creatorInboxId)]
@@ -108,6 +91,7 @@ impl GroupMember {
10891
}
10992

11093
#[wasm_bindgen]
94+
#[derive(Clone)]
11195
pub struct Conversation {
11296
inner_client: Arc<RustXmtpClient>,
11397
group_id: Vec<u8>,

bindings_wasm/src/conversations.rs

+169-18
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,19 @@ use wasm_bindgen::{JsError, JsValue};
55
use xmtp_mls::groups::{
66
DMMetadataOptions, GroupMetadataOptions, HmacKey as XmtpHmacKey, PreconfiguredPolicies,
77
};
8+
use xmtp_mls::storage::consent_record::ConsentState as XmtpConsentState;
89
use xmtp_mls::storage::group::ConversationType as XmtpConversationType;
910
use xmtp_mls::storage::group::GroupMembershipState as XmtpGroupMembershipState;
1011
use xmtp_mls::storage::group::GroupQueryArgs;
1112

12-
use crate::conversation::MessageDisappearingSettings;
13+
use crate::consent_state::ConsentState;
1314
use crate::messages::Message;
1415
use crate::permissions::{GroupPermissionsOptions, PermissionPolicySet};
1516
use crate::streams::{StreamCallback, StreamCloser};
1617
use crate::{client::RustXmtpClient, conversation::Conversation};
1718

19+
use xmtp_mls::groups::group_mutable_metadata::MessageDisappearingSettings as XmtpMessageDisappearingSettings;
20+
1821
#[wasm_bindgen]
1922
#[derive(Debug, Clone)]
2023
pub enum ConversationType {
@@ -76,50 +79,91 @@ impl From<GroupMembershipState> for XmtpGroupMembershipState {
7679
pub struct ListConversationsOptions {
7780
#[wasm_bindgen(js_name = allowedStates)]
7881
pub allowed_states: Option<Vec<GroupMembershipState>>,
82+
#[wasm_bindgen(js_name = consentStates)]
83+
pub consent_states: Option<Vec<ConsentState>>,
7984
#[wasm_bindgen(js_name = conversationType)]
8085
pub conversation_type: Option<ConversationType>,
8186
#[wasm_bindgen(js_name = createdAfterNs)]
8287
pub created_after_ns: Option<i64>,
8388
#[wasm_bindgen(js_name = createdBeforeNs)]
8489
pub created_before_ns: Option<i64>,
90+
#[wasm_bindgen(js_name = includeDuplicateDms)]
91+
pub include_duplicate_dms: bool,
92+
#[wasm_bindgen(js_name = includeSyncGroups)]
93+
pub include_sync_groups: bool,
8594
pub limit: Option<i64>,
8695
}
8796

8897
impl From<ListConversationsOptions> for GroupQueryArgs {
8998
fn from(opts: ListConversationsOptions) -> GroupQueryArgs {
90-
GroupQueryArgs::default()
91-
.maybe_allowed_states(
92-
opts
93-
.allowed_states
94-
.map(|states| states.into_iter().map(From::from).collect()),
95-
)
96-
.maybe_conversation_type(opts.conversation_type.map(Into::into))
97-
.maybe_created_after_ns(opts.created_after_ns)
98-
.maybe_created_before_ns(opts.created_before_ns)
99-
.maybe_limit(opts.limit)
99+
GroupQueryArgs {
100+
allowed_states: opts
101+
.allowed_states
102+
.map(|states| states.into_iter().map(From::from).collect()),
103+
consent_states: opts
104+
.consent_states
105+
.map(|states| states.into_iter().map(From::from).collect()),
106+
conversation_type: opts.conversation_type.map(Into::into),
107+
created_after_ns: opts.created_after_ns,
108+
created_before_ns: opts.created_before_ns,
109+
include_duplicate_dms: opts.include_duplicate_dms,
110+
include_sync_groups: opts.include_sync_groups,
111+
limit: opts.limit,
112+
}
100113
}
101114
}
102115

103116
#[wasm_bindgen]
104117
impl ListConversationsOptions {
105118
#[wasm_bindgen(constructor)]
119+
#[allow(clippy::too_many_arguments)]
106120
pub fn new(
107121
allowed_states: Option<Vec<GroupMembershipState>>,
122+
consent_states: Option<Vec<ConsentState>>,
108123
conversation_type: Option<ConversationType>,
109124
created_after_ns: Option<i64>,
110125
created_before_ns: Option<i64>,
126+
include_duplicate_dms: bool,
127+
include_sync_groups: bool,
111128
limit: Option<i64>,
112129
) -> Self {
113130
Self {
114131
allowed_states,
132+
consent_states,
115133
conversation_type,
116134
created_after_ns,
117135
created_before_ns,
136+
include_duplicate_dms,
137+
include_sync_groups,
118138
limit,
119139
}
120140
}
121141
}
122142

143+
#[wasm_bindgen(getter_with_clone)]
144+
#[derive(Clone)]
145+
pub struct MessageDisappearingSettings {
146+
pub from_ns: i64,
147+
pub in_ns: i64,
148+
}
149+
150+
impl From<MessageDisappearingSettings> for XmtpMessageDisappearingSettings {
151+
fn from(value: MessageDisappearingSettings) -> Self {
152+
Self {
153+
from_ns: value.from_ns,
154+
in_ns: value.in_ns,
155+
}
156+
}
157+
}
158+
159+
#[wasm_bindgen]
160+
impl MessageDisappearingSettings {
161+
#[wasm_bindgen(constructor)]
162+
pub fn new(from_ns: i64, in_ns: i64) -> Self {
163+
Self { from_ns, in_ns }
164+
}
165+
}
166+
123167
#[wasm_bindgen(getter_with_clone)]
124168
#[derive(Clone)]
125169
pub struct CreateGroupOptions {
@@ -216,6 +260,24 @@ impl From<XmtpHmacKey> for HmacKey {
216260
}
217261
}
218262

263+
#[wasm_bindgen(getter_with_clone)]
264+
pub struct ConversationListItem {
265+
pub conversation: Conversation,
266+
#[wasm_bindgen(js_name = lastMessage)]
267+
pub last_message: Option<Message>,
268+
}
269+
270+
#[wasm_bindgen]
271+
impl ConversationListItem {
272+
#[wasm_bindgen(constructor)]
273+
pub fn new(conversation: Conversation, last_message: Option<Message>) -> Self {
274+
Self {
275+
conversation,
276+
last_message,
277+
}
278+
}
279+
}
280+
219281
#[wasm_bindgen]
220282
pub struct Conversations {
221283
inner_client: Arc<RustXmtpClient>,
@@ -296,6 +358,73 @@ impl Conversations {
296358
Ok(convo.into())
297359
}
298360

361+
#[wasm_bindgen(js_name = createGroupByInboxIds)]
362+
pub async fn create_group_by_inbox_ids(
363+
&self,
364+
inbox_ids: Vec<String>,
365+
options: Option<CreateGroupOptions>,
366+
) -> Result<Conversation, JsError> {
367+
let options = options.unwrap_or(CreateGroupOptions {
368+
permissions: None,
369+
group_name: None,
370+
group_image_url_square: None,
371+
group_description: None,
372+
custom_permission_policy_set: None,
373+
message_disappearing_settings: None,
374+
});
375+
376+
if let Some(GroupPermissionsOptions::CustomPolicy) = options.permissions {
377+
if options.custom_permission_policy_set.is_none() {
378+
return Err(JsError::new("CustomPolicy must include policy set"));
379+
}
380+
} else if options.custom_permission_policy_set.is_some() {
381+
return Err(JsError::new("Only CustomPolicy may specify a policy set"));
382+
}
383+
384+
let metadata_options = options.clone().into_group_metadata_options();
385+
386+
let group_permissions = match options.permissions {
387+
Some(GroupPermissionsOptions::Default) => {
388+
Some(PreconfiguredPolicies::Default.to_policy_set())
389+
}
390+
Some(GroupPermissionsOptions::AdminOnly) => {
391+
Some(PreconfiguredPolicies::AdminsOnly.to_policy_set())
392+
}
393+
Some(GroupPermissionsOptions::CustomPolicy) => {
394+
if let Some(policy_set) = options.custom_permission_policy_set {
395+
Some(
396+
policy_set
397+
.try_into()
398+
.map_err(|e| JsError::new(format!("{}", e).as_str()))?,
399+
)
400+
} else {
401+
None
402+
}
403+
}
404+
_ => None,
405+
};
406+
407+
let convo = if inbox_ids.is_empty() {
408+
let group = self
409+
.inner_client
410+
.create_group(group_permissions, metadata_options)
411+
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
412+
group
413+
.sync()
414+
.await
415+
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
416+
group
417+
} else {
418+
self
419+
.inner_client
420+
.create_group_with_inbox_ids(&inbox_ids, group_permissions, metadata_options)
421+
.await
422+
.map_err(|e| JsError::new(format!("{}", e).as_str()))?
423+
};
424+
425+
Ok(convo.into())
426+
}
427+
299428
#[wasm_bindgen(js_name = createDm)]
300429
pub async fn find_or_create_dm(
301430
&self,
@@ -314,6 +443,24 @@ impl Conversations {
314443
Ok(convo.into())
315444
}
316445

446+
#[wasm_bindgen(js_name = createDmByInboxId)]
447+
pub async fn find_or_create_dm_by_inbox_id(
448+
&self,
449+
inbox_id: String,
450+
options: Option<CreateDMOptions>,
451+
) -> Result<Conversation, JsError> {
452+
let convo = self
453+
.inner_client
454+
.find_or_create_dm_by_inbox_id(
455+
inbox_id,
456+
options.unwrap_or_default().into_dm_metadata_options(),
457+
)
458+
.await
459+
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
460+
461+
Ok(convo.into())
462+
}
463+
317464
#[wasm_bindgen(js_name = findGroupById)]
318465
pub fn find_group_by_id(&self, group_id: String) -> Result<Conversation, JsError> {
319466
let group_id = hex::decode(group_id).map_err(|e| JsError::new(format!("{}", e).as_str()))?;
@@ -368,15 +515,20 @@ impl Conversations {
368515
}
369516

370517
#[wasm_bindgen(js_name = syncAllConversations)]
371-
pub async fn sync_all_conversations(&self) -> Result<usize, JsError> {
518+
pub async fn sync_all_conversations(
519+
&self,
520+
consent_states: Option<Vec<ConsentState>>,
521+
) -> Result<usize, JsError> {
372522
let provider = self
373523
.inner_client
374524
.mls_provider()
375525
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
526+
let consents: Option<Vec<XmtpConsentState>> =
527+
consent_states.map(|states| states.into_iter().map(|state| state.into()).collect());
376528

377529
let num_groups_synced = self
378530
.inner_client
379-
.sync_all_welcomes_and_groups(&provider, None)
531+
.sync_all_welcomes_and_groups(&provider, consents)
380532
.await
381533
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
382534

@@ -387,14 +539,13 @@ impl Conversations {
387539
pub fn list(&self, opts: Option<ListConversationsOptions>) -> Result<js_sys::Array, JsError> {
388540
let convo_list: js_sys::Array = self
389541
.inner_client
390-
.find_groups(opts.unwrap_or_default().into())
542+
.list_conversations(opts.unwrap_or_default().into())
391543
.map_err(|e| JsError::new(format!("{}", e).as_str()))?
392544
.into_iter()
393545
.map(|group| {
394-
JsValue::from(Conversation::new(
395-
self.inner_client.clone(),
396-
group.group_id,
397-
group.created_at_ns,
546+
JsValue::from(ConversationListItem::new(
547+
group.group.into(),
548+
group.last_message.map(|m| m.into()),
398549
))
399550
})
400551
.collect();

0 commit comments

Comments
 (0)