From 4b3bbecddd776f2419696af5ac42df2cd4049236 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 16 Oct 2026 14:35:14 +0000 Subject: [PATCH] Let the client event filter peek, and expose the event fields sliding sync reads filter_events_for_client takes is_peeking, which v2 passes as false and sliding sync sets for rooms the user is not joined to. Events gain instance_name, and unsigned data gains invite_room_state and knock_room_state accessors. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01L51DoxB8VnH8UjXJFDgpNG --- rust/src/events/internal_metadata.rs | 7 +++++++ rust/src/events/unsigned.rs | 10 ++++++++++ rust/src/sync/client_events.rs | 10 ++++++---- rust/src/sync/room.rs | 1 + rust/src/sync/rooms.rs | 2 +- rust/src/sync/timeline.rs | 1 + 6 files changed, 26 insertions(+), 5 deletions(-) diff --git a/rust/src/events/internal_metadata.rs b/rust/src/events/internal_metadata.rs index 90e07946e0..04a7e00afd 100644 --- a/rust/src/events/internal_metadata.rs +++ b/rust/src/events/internal_metadata.rs @@ -588,6 +588,13 @@ impl EventInternalMetadata { .ok() .and_then(|inner| inner.stream_ordering) } + + /// The writer that persisted the event, if known. + pub fn instance_name(&self) -> Option { + self.read_inner() + .ok() + .and_then(|inner| inner.instance_name.clone()) + } } /// Helper to convert `None` to an `AttributeError` for a property getter. diff --git a/rust/src/events/unsigned.rs b/rust/src/events/unsigned.rs index 85881303a4..b9955ff563 100644 --- a/rust/src/events/unsigned.rs +++ b/rust/src/events/unsigned.rs @@ -310,6 +310,16 @@ impl Unsigned { Ok(self.py_read()?.persisted_fields.replaces_state.clone()) } + /// The `invite_room_state` field: the stripped state an invite carries. + pub fn invite_room_state(&self) -> PyResult>> { + Ok(self.py_read()?.persisted_fields.invite_room_state.clone()) + } + + /// The `knock_room_state` field: the stripped state a knock carries. + pub fn knock_room_state(&self) -> PyResult>> { + Ok(self.py_read()?.persisted_fields.knock_room_state.clone()) + } + /// Whether both `prev_content` and `prev_sender` are set. pub fn has_prev_content_and_sender(&self) -> PyResult { let unsigned = self.py_read()?; diff --git a/rust/src/sync/client_events.rs b/rust/src/sync/client_events.rs index 7f8826c0bb..7a99d57d42 100644 --- a/rust/src/sync/client_events.rs +++ b/rust/src/sync/client_events.rs @@ -47,9 +47,10 @@ pub struct ClientFilterContext { pub msc4354_enabled: bool, } -/// `filter_and_transform_events_for_client` with `filter_send_to_client` -/// and not peeking: the events the user may see, in order, each pruned if -/// its sender was erased and with the user's membership at it. +/// `filter_and_transform_events_for_client` with `filter_send_to_client`: +/// the events the user may see, in order, each pruned if its sender was +/// erased and with the user's membership at it. `is_peeking` is for a user +/// who is not in the room. /// /// `now_ms` is the time the sticky and retention checks compare with. pub async fn filter_events_for_client( @@ -57,6 +58,7 @@ pub async fn filter_events_for_client( context: &ClientFilterContext, events: &[Arc], always_include_ids: &HashSet>, + is_peeking: bool, now_ms: i64, ) -> anyhow::Result> { if events.is_empty() { @@ -165,7 +167,7 @@ pub async fn filter_events_for_client( now_ms, msc4354_enabled: context.msc4354_enabled, filter_send_to_client: true, - is_peeking: false, + is_peeking, always_include_ids, sender_ignored: context.ignored_users.contains(event.sender()), retention_max_lifetime: retention[event.room_id()], diff --git a/rust/src/sync/room.rs b/rust/src/sync/room.rs index 07d38e01e0..ab8acd58f5 100644 --- a/rust/src/sync/room.rs +++ b/rust/src/sync/room.rs @@ -297,6 +297,7 @@ pub async fn generate_room_entry( &context.client_filter, &events, &HashSet::new(), + false, context.now_ms(), ) .await?; diff --git a/rust/src/sync/rooms.rs b/rust/src/sync/rooms.rs index 5f268c85fd..2fe6d16644 100644 --- a/rust/src/sync/rooms.rs +++ b/rust/src/sync/rooms.rs @@ -651,7 +651,7 @@ async fn room_entry( } /// The message of a panic's payload. -fn panic_message(panic: &(dyn std::any::Any + Send)) -> &str { +pub(crate) fn panic_message(panic: &(dyn std::any::Any + Send)) -> &str { if let Some(message) = panic.downcast_ref::<&str>() { message } else if let Some(message) = panic.downcast_ref::() { diff --git a/rust/src/sync/timeline.rs b/rust/src/sync/timeline.rs index 961bd0cd03..95cd585ac8 100644 --- a/rust/src/sync/timeline.rs +++ b/rust/src/sync/timeline.rs @@ -103,6 +103,7 @@ async fn filter_recents( &context.client_filter, &recents, ¤t_state_ids, + false, context.now_ms(), ) .await