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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L51DoxB8VnH8UjXJFDgpNG
This commit is contained in:
Erik JohnstonandClaude Opus 5.5 committed 2026-10-16 14:35:14 +00:00
1 parent 3ec052511e
commit 4b3bbecddd
6 files changed
+26 -5

No files matched your search

+7
View File
@@ -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<String> {
self.read_inner()
.ok()
.and_then(|inner| inner.instance_name.clone())
}
}
/// Helper to convert `None` to an `AttributeError` for a property getter.
+10
View File
@@ -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<Option<Vec<serde_json::Value>>> {
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<Option<Vec<serde_json::Value>>> {
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<bool> {
let unsigned = self.py_read()?;
+6 -4
View File
@@ -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<Event>],
always_include_ids: &HashSet<Arc<str>>,
is_peeking: bool,
now_ms: i64,
) -> anyhow::Result<Vec<FilteredEvent>> {
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()],
+1
View File
@@ -297,6 +297,7 @@ pub async fn generate_room_entry(
&context.client_filter,
&events,
&HashSet::new(),
false,
context.now_ms(),
)
.await?;
+1 -1
View File
@@ -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::<String>() {
+1
View File
@@ -103,6 +103,7 @@ async fn filter_recents(
&context.client_filter,
&recents,
&current_state_ids,
false,
context.now_ms(),
)
.await