From e9d9e1ec794ab97b056a68b13f05254573fa1562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Sun, 3 Aug 2025 10:37:28 +0200 Subject: [PATCH 1/4] Add `state_after` to `/sync` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per MSC4222. Signed-off-by: Kévin Commaille --- data/api/client-server/sync.yaml | 85 ++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 4 deletions(-) diff --git a/data/api/client-server/sync.yaml b/data/api/client-server/sync.yaml index e6fd7883..1338d5f3 100644 --- a/data/api/client-server/sync.yaml +++ b/data/api/client-server/sync.yaml @@ -117,6 +117,30 @@ paths: example: 30000 schema: type: integer + - in: query + name: use_state_after + x-addedInMatrixVersion: "1.16" + description: |- + Controls whether to receive state changes between the previous sync + and the **start** of the timeline, or between the previous sync and + the **end** of the timeline. + + If this is set to `true`, servers MUST respond with the state + between the previous sync and the **end** of the timeline in + `state_after` and MUST omit `state`. + + If `false`, servers MUST respond with the state between the previous + sync and the **start** of the timeline in `state` and MUST omit + `state_after`. + + Even if this is set to `true`, clients MUST update their local state + with events in `state` and `timeline` if `state_after` is missing in + the response, for servers that don't support this parameter. + + By default, this is `false`. + example: false + schema: + type: boolean responses: "200": description: The initial snapshot or delta for the client to use to update their @@ -197,16 +221,49 @@ paths: type: object description: |- Updates to the state, between the time indicated by - the `since` parameter, and the start of the - `timeline` (or all state up to the start of the + the `since` parameter, and the **start** of the + `timeline` (or all state up to the **start** of the `timeline`, if `since` is not given, or `full_state` is true). - N.B. state updates for `m.room.member` events will + {{% boxes/note %}} + State updates for `m.room.member` events will be incomplete if `lazy_load_members` is enabled in the `/sync` filter, and only return the member events required to display the senders of the timeline events in this response. + {{% /boxes/note %}} + + MUST be omitted if `use_state_after` was set to `true` + in the request. + allOf: + - $ref: definitions/state_event_batch.yaml + state_after: + title: State + type: object + x-addedInMatrixVersion: "1.16" + description: |- + Updates to the state, between the time indicated by + the `since` parameter, and the **end** of the + `timeline` (or all state up to the **end** of the + `timeline`, if `since` is not given, or + `full_state` is true). + + {{% boxes/note %}} + State updates for `m.room.member` events will + be incomplete if `lazy_load_members` is enabled in + the `/sync` filter, and only return the member events + required to display the senders of the timeline events + in this response. + {{% /boxes/note %}} + + If this field is set, even if it is empty, clients MUST + only update their local state with events in this list. + If this field is not set, clients MUST update their local + state with events in `state` and `timeline`. + + **Required** if `use_state_after` was set to `true` in the + request, even if it is empty. allOf: - $ref: definitions/state_event_batch.yaml timeline: @@ -353,7 +410,27 @@ paths: state: title: State type: object - description: The state updates for the room up to the start of the timeline. + description: |- + The state updates for the room up to the **start** of the timeline. + + MUST be omitted if `use_state_after` was set to `true` in the + request. + allOf: + - $ref: definitions/state_event_batch.yaml + state_after: + title: State + type: object + x-addedInMatrixVersion: "1.16" + description: |- + The state updates for the room up to the **end** of the timeline. + + If this field is set, even if it is empty, clients MUST only + update their local state with events in this list. If this field + is not set, clients MUST update their local state with events in + `state` and `timeline`. + + **Required** if `use_state_after` was set to `true` in the + request, even if it is empty. allOf: - $ref: definitions/state_event_batch.yaml timeline: From 2f7988f5d2e7bc9d5b5fe2893dabedf87bbe9cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Sun, 3 Aug 2025 10:47:54 +0200 Subject: [PATCH 2/4] Add changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- changelogs/client_server/newsfragments/2187.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/2187.feature diff --git a/changelogs/client_server/newsfragments/2187.feature b/changelogs/client_server/newsfragments/2187.feature new file mode 100644 index 00000000..8eff7582 --- /dev/null +++ b/changelogs/client_server/newsfragments/2187.feature @@ -0,0 +1 @@ +Add the `use_state_after` query parameter and `state_after` response property to `GET /sync`, as per [MSC4222](https://github.com/matrix-org/matrix-spec-proposals/issues/4222). From 802403edd9d966694fffac81dfebc680bc9dc1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Sun, 3 Aug 2025 10:52:20 +0200 Subject: [PATCH 3/4] Improve wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- data/api/client-server/sync.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/api/client-server/sync.yaml b/data/api/client-server/sync.yaml index 1338d5f3..7d34353c 100644 --- a/data/api/client-server/sync.yaml +++ b/data/api/client-server/sync.yaml @@ -135,7 +135,8 @@ paths: Even if this is set to `true`, clients MUST update their local state with events in `state` and `timeline` if `state_after` is missing in - the response, for servers that don't support this parameter. + the response, for compatibility with servers that don't support this + parameter. By default, this is `false`. example: false From bed1abaff580f3a290fb10e0a6fa0e8c14a8f6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Wed, 6 Aug 2025 11:24:12 +0200 Subject: [PATCH 4/4] Clarify to not use timeline with state_after MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Kévin Commaille --- data/api/client-server/sync.yaml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/data/api/client-server/sync.yaml b/data/api/client-server/sync.yaml index 7d34353c..96680180 100644 --- a/data/api/client-server/sync.yaml +++ b/data/api/client-server/sync.yaml @@ -259,9 +259,10 @@ paths: {{% /boxes/note %}} If this field is set, even if it is empty, clients MUST - only update their local state with events in this list. - If this field is not set, clients MUST update their local - state with events in `state` and `timeline`. + only update their local state with events in this list, + and MUST NOT update their local state with events in + `timeline`. If this field is not set, clients MUST update + their local state with events in `state` and `timeline`. **Required** if `use_state_after` was set to `true` in the request, even if it is empty. @@ -426,7 +427,8 @@ paths: The state updates for the room up to the **end** of the timeline. If this field is set, even if it is empty, clients MUST only - update their local state with events in this list. If this field + update their local state with events in this list, and MUST NOT + update their local state with events in `timeline`. If this field is not set, clients MUST update their local state with events in `state` and `timeline`.