Add SnakeSyncCache.sent_state: a per-room map of (event_type, state_key)
→ event_id recording which state events were last sent to the client.
Two new Service methods:
get_room_sent_state – read the cache for one room
update_room_sent_state – write the cache after each sync response
collect_required_state gains snake_key (None = connectionless/no cache)
and roomsince parameters:
- roomsince == 0 (initial sync): return all matching events and
populate the cache.
- roomsince != 0 and snake_key is Some (incremental, has connection):
only return events whose event_id differs from the cached value.
- roomsince != 0 and snake_key is None (connectionless incremental):
return all matching events (no cache to diff against).
Also export SnakeConnectionsKey from conduwuit-service::sync so the API
crate can reference it without duplicating the type definition.
Add extension_room_set helper that computes the qualifying room set for
an extension from its lists and rooms filter fields per MSC4186.
MSC3960 receipts: move collection out of process_rooms into
collect_receipts, gated on enabled + filters.
MSC3961 typing: replace the dead filter variables in collect_typing_events
with an extension_room_set call so only qualifying rooms get typing data.
MSC3959 account data: move per-room collection out of process_rooms into
collect_account_data using per-room roomsince values and filter.
Route handler: collect_receipts and collect_account_data now run after
todo_rooms is populated; e2ee and to_device still run in parallel join.
- Restore `_services: &Services` parameter on `collect_receipts`
- Add cheap pre-guard in `process_rooms` to skip `collect_required_state`
DB call when no state was requested and there is nothing else to send
- `handle_lists` now returns `BTreeMap<String, BTreeSet<OwnedRoomId>>`
(rooms visible per list window)
- `fetch_subscriptions` now returns `BTreeSet<OwnedRoomId>` (subscription
rooms); captured as `_rooms_by_list` / `_subscription_rooms` for use
in the upcoming extension-scoping changes
Rooms with pending required state events were incorrectly skipped on
incremental syncs when the timeline and receipts were empty. Move
collect_required_state before the early-continue and add its emptiness
as a guard condition.