From 29bd4d45ee9155bd80e61ce50ab34745be1fd8a4 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sun, 15 Nov 2015 23:40:41 +0000 Subject: [PATCH 1/4] Flatten the response to /sync Now that we don't expect there to be duplication betwen the 'timeline' and 'state' results, there's no point in having the state map. (That does mean the events themselves need event_id fields though). Also: - move the contents of the 'unsigned' dictionary into the events themselves - replace the state list with two layers of dictionary keyed on type and state_key - rename the children of the 'rooms' dict from "joined/invited/archived" to "join/invite/leave" to match the membership states --- .../v2_alpha/definitions/event.json | 45 +++--- .../definitions/room_event_batch.json | 12 -- .../v2_alpha/definitions/timeline_batch.json | 2 +- api/client-server/v2_alpha/sync.yaml | 134 +++++++----------- specification/events.rst | 17 +-- 5 files changed, 84 insertions(+), 126 deletions(-) delete mode 100644 api/client-server/v2_alpha/definitions/room_event_batch.json diff --git a/api/client-server/v2_alpha/definitions/event.json b/api/client-server/v2_alpha/definitions/event.json index 6a01c688..3a15357a 100644 --- a/api/client-server/v2_alpha/definitions/event.json +++ b/api/client-server/v2_alpha/definitions/event.json @@ -2,16 +2,34 @@ "type": "object", "title": "Event", "properties": { + "age": { + "type": "integer", + "format": "int64", + "description": "Time in milliseconds since the event was sent." + }, "content": { "type": "object", "title": "EventContent", "description": "The content of this event. The fields in this object will vary depending on the type of event." }, + "event_id": { + "type": "string", + "description": "Globally unique identifier for this event." + }, "origin_server_ts": { "type": "integer", "format": "int64", "description": "Timestamp in milliseconds on originating homeserver when this event was sent." }, + "prev_content": { + "title": "EventContent", + "type": "object", + "description": "Optional. The previous ``content`` for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing." + }, + "prev_sender": { + "type": "string", + "description": "Optional. The ``sender`` of the previous event for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there was no previous event for this state, this key will be missing." + }, "sender": { "type": "string", "description": "The MXID of the user who sent this event." @@ -24,30 +42,9 @@ "type": "string", "description": "The type of event." }, - "unsigned": { - "type": "object", - "title": "Unsigned", - "description": "Information about this event which was not sent by the originating homeserver", - "properties": { - "age": { - "type": "integer", - "format": "int64", - "description": "Time in milliseconds since the event was sent." - }, - "prev_content": { - "title": "EventContent", - "type": "object", - "description": "Optional. The previous ``content`` for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing." - }, - "replaces_state": { - "type": "string", - "description": "Optional. The event_id of the previous event for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing." - }, - "txn_id": { - "type": "string", - "description": "Optional. The transaction ID set when this message was sent. This key will only be present for message events sent by the device calling this API." - } - } + "txn_id": { + "type": "string", + "description": "Optional. The transaction ID set when this message was sent. This key will only be present for message events sent by the device calling this API." } } } diff --git a/api/client-server/v2_alpha/definitions/room_event_batch.json b/api/client-server/v2_alpha/definitions/room_event_batch.json deleted file mode 100644 index fcf148f3..00000000 --- a/api/client-server/v2_alpha/definitions/room_event_batch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "object", - "properties": { - "events": { - "type": "array", - "description": "List of event ids", - "items": { - "type": "string" - } - } - } -} diff --git a/api/client-server/v2_alpha/definitions/timeline_batch.json b/api/client-server/v2_alpha/definitions/timeline_batch.json index 15ca1ead..f27a5746 100644 --- a/api/client-server/v2_alpha/definitions/timeline_batch.json +++ b/api/client-server/v2_alpha/definitions/timeline_batch.json @@ -1,6 +1,6 @@ { "type": "object", - "allOf": [{"$ref":"definitions/room_event_batch.json"}], + "allOf": [{"$ref":"definitions/event_batch.json"}], "properties": { "limited": { "type": "boolean", diff --git a/api/client-server/v2_alpha/sync.yaml b/api/client-server/v2_alpha/sync.yaml index 2290b070..c63f3432 100644 --- a/api/client-server/v2_alpha/sync.yaml +++ b/api/client-server/v2_alpha/sync.yaml @@ -95,7 +95,7 @@ paths: description: |- Updates to rooms. properties: - joined: + join: title: Joined Rooms type: object description: |- @@ -104,19 +104,6 @@ paths: title: Joined Room type: object properties: - event_map: - title: EventMap - type: object - description: |- - A map from event ID to events for this room. The - events are referenced from the ``timeline`` and - ``state`` keys for this room. - additionalProperties: - title: Event - description: An event object. - type: object - allOf: - - $ref: "definitions/event.json" state: title: State type: object @@ -127,7 +114,7 @@ paths: ``timeline``, if ``since`` is not given, or ``full_state`` is true). allOf: - - $ref: "definitions/room_event_batch.json" + - $ref: "definitions/state_batch.json" timeline: title: Timeline type: object @@ -145,7 +132,7 @@ paths: e.g. typing. allOf: - $ref: "definitions/event_batch.json" - invited: + invite: title: Invited Rooms type: object description: |- @@ -171,36 +158,23 @@ paths: delta against the archived ``state`` not the ``invite_state``. allOf: - - $ref: "definitions/event_batch.json" - archived: - title: Archived rooms + - $ref: "definitions/state_batch.json" + leave: + title: Left rooms type: object description: |- The rooms that the user has left or been banned from. additionalProperties: - title: Archived Room + title: Left Room type: object properties: - event_map: - title: EventMap - type: object - description: |- - A map from event ID to events for this room. The - events are referenced from the ``timeline`` and - ``state`` keys for this room. - additionalProperties: - title: Event - description: An event object. - type: object - allOf: - - $ref: "definitions/event.json" state: title: State type: object description: |- The state updates for the room up to the start of the timeline. allOf: - - $ref: "definitions/room_event_batch.json" + - $ref: "definitions/state_batch.json" timeline: title: Timeline type: object @@ -230,46 +204,43 @@ paths: ] }, "rooms": { - "joined": { + "join": { "!726s6s6q:example.com": { - "event_map": { - "$66697273743031:example.com": { - "sender": "@alice:example.com", - "type": "m.room.member", - "state_key": "@alice:example.com", - "content": {"membership": "join"}, - "origin_server_ts": 1417731086795 - }, - "$7365636s6r6432:example.com": { - "sender": "@bob:example.com", - "type": "m.room.member", - "state_key": "@bob:example.com", - "content": {"membership": "join"}, - "unsigned": { - "prev_content": {"membership": "invite"} - }, - "origin_server_ts": 1417731086795 - }, - "$74686972643033:example.com": { - "sender": "@alice:example.com", - "type": "m.room.message", - "unsigned": {"age": 124524, "txn_id": "1234"}, - "content": { - "body": "I am a fish", - "msgtype": "m.text" - }, - "origin_server_ts": 1417731086797 - } - }, "state": { - "events": [ - "$66697273743031:example.com" - ] + "m.room.member": { + "@alice:example.com": { + "sender": "@alice:example.com", + "type": "m.room.member", + "state_key": "@alice:example.com", + "content": {"membership": "join"}, + "origin_server_ts": 1417731086795, + "event_id": "$66697273743031:example.com" + } + } }, "timeline": { "events": [ - "$7365636s6r6432:example.com", - "$74686972643033:example.com" + { + "sender": "@bob:example.com", + "type": "m.room.member", + "state_key": "@bob:example.com", + "content": {"membership": "join"}, + "prev_content": {"membership": "invite"}, + "origin_server_ts": 1417731086795, + "event_id": "$7365636s6r6432:example.com": + }, + { + "sender": "@alice:example.com", + "type": "m.room.message", + "age": 124524, + "txn_id": "1234", + "content": { + "body": "I am a fish", + "msgtype": "m.text" + }, + "origin_server_ts": 1417731086797, + "event_id": "$74686972643033:example.com" + } ], "limited": true, "prev_batch": "t34-23535_0_0" @@ -277,6 +248,7 @@ paths: "ephemeral": { "events": [ { + "room_id": "!726s6s6q:example.com", "type": "m.typing", "content": {"user_ids": ["@alice:example.com"]} } @@ -284,26 +256,30 @@ paths: } } }, - "invited": { + "invite": { "!696r7674:example.com": { "invite_state": { - "events": [ - { + "m.room.name": { + "": { "sender": "@alice:example.com", "type": "m.room.name", "state_key": "", - "content": {"name": "My Room Name"} - }, - { + "content": {"name": "My Room Name"}, + "event_id": "$asdkgjrsfg2314375:example.com", + + } + }, + "m.room.member": { + "@bob:example.com": { "sender": "@alice:example.com", "type": "m.room.member", "state_key": "@bob:example.com", - "content": {"membership": "invite"} - } - ] + "content": {"membership": "invite"}, + "event_id": "$257kasjdg315324akhg:example.com", + } } } }, - "archived": {} + "leave": {} } } diff --git a/specification/events.rst b/specification/events.rst index 7bf08012..3d069be8 100644 --- a/specification/events.rst +++ b/specification/events.rst @@ -28,22 +28,19 @@ formatted for federation by: * Removing the following keys: ``auth_events``, ``prev_events``, ``hashes``, ``signatures``, ``depth``, - ``origin``, ``prev_state``. -* Adding an ``age`` to the ``unsigned`` object which gives the time in + ``origin``, ``prev_state``, ``unsigned``. +* Adding an ``age`` to the event object which gives the time in milliseconds that has elapsed since the event was sent. -* Adding a ``prev_content`` to the ``unsigned`` object if the event is - a ``state event`` which gives previous content of that state key. -* Adding a ``redacted_because`` to the ``unsigned`` object if the event was +* Adding ``prev_content`` and ``prev_sender`` to the event object if the event + is a ``state event``, which give the previous content and previous sender of + that state key +* Adding a ``redacted_because`` to event object if the event was redacted which gives the event that redacted it. -* Adding a ``txn_id`` to the ``unsigned`` object if the event was sent by the - client requesting it. +* Adding a ``txn_id`` if the event was sent by the client requesting it. Events in responses for APIs with the /v1 prefix are generated from an event formatted for the /v2 prefix by: -* Moving the folling keys from the ``unsigned`` object to the top level event - object: ``age``, ``redacted_because``, ``replaces_state``, ``prev_content``. -* Removing the ``unsigned`` object. * Rename the ``sender`` key to ``user_id``. * If the event was an ``m.room.member`` with ``membership`` set to ``invite`` then adding a ``invite_room_state`` key to the top level event object. From e1b12a753ecd96227effef3612f70d9adf48c0a9 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 16 Nov 2015 00:17:22 +0000 Subject: [PATCH 2/4] Fix typos and missing file --- .../v2_alpha/definitions/state_batch.json | 12 ++++++++++++ api/client-server/v2_alpha/sync.yaml | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 api/client-server/v2_alpha/definitions/state_batch.json diff --git a/api/client-server/v2_alpha/definitions/state_batch.json b/api/client-server/v2_alpha/definitions/state_batch.json new file mode 100644 index 00000000..45728f40 --- /dev/null +++ b/api/client-server/v2_alpha/definitions/state_batch.json @@ -0,0 +1,12 @@ +{ + "type": "object", + "additionalProperties": { + "type": "object", + "x-pattern": "$EVENT_TYPE", + "additionalProperties": { + "type": "object", + "x-pattern": "$STATE_KEY", + "allOf": [{"$ref": "event.json" }] + } + } +} diff --git a/api/client-server/v2_alpha/sync.yaml b/api/client-server/v2_alpha/sync.yaml index c63f3432..198f4833 100644 --- a/api/client-server/v2_alpha/sync.yaml +++ b/api/client-server/v2_alpha/sync.yaml @@ -227,7 +227,7 @@ paths: "content": {"membership": "join"}, "prev_content": {"membership": "invite"}, "origin_server_ts": 1417731086795, - "event_id": "$7365636s6r6432:example.com": + "event_id": "$7365636s6r6432:example.com" }, { "sender": "@alice:example.com", @@ -265,8 +265,7 @@ paths: "type": "m.room.name", "state_key": "", "content": {"name": "My Room Name"}, - "event_id": "$asdkgjrsfg2314375:example.com", - + "event_id": "$asdkgjrsfg2314375:example.com" } }, "m.room.member": { @@ -275,7 +274,8 @@ paths: "type": "m.room.member", "state_key": "@bob:example.com", "content": {"membership": "invite"}, - "event_id": "$257kasjdg315324akhg:example.com", + "event_id": "$257kasjdg315324akhg:example.com" + } } } } From 6653362f315d1379d1dda248dfd299c8c3c8530d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 18 Nov 2015 15:15:21 +0000 Subject: [PATCH 3/4] Unflatten 'unsigned' It turns out that flattening 'unsigned' comes with too many downsides. Let's stick with the status quo. --- .../v2_alpha/definitions/event.json | 45 ++++++++++--------- specification/events.rst | 19 ++++---- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/api/client-server/v2_alpha/definitions/event.json b/api/client-server/v2_alpha/definitions/event.json index 3a15357a..5a8f52f6 100644 --- a/api/client-server/v2_alpha/definitions/event.json +++ b/api/client-server/v2_alpha/definitions/event.json @@ -2,34 +2,16 @@ "type": "object", "title": "Event", "properties": { - "age": { - "type": "integer", - "format": "int64", - "description": "Time in milliseconds since the event was sent." - }, "content": { "type": "object", "title": "EventContent", "description": "The content of this event. The fields in this object will vary depending on the type of event." }, - "event_id": { - "type": "string", - "description": "Globally unique identifier for this event." - }, "origin_server_ts": { "type": "integer", "format": "int64", "description": "Timestamp in milliseconds on originating homeserver when this event was sent." }, - "prev_content": { - "title": "EventContent", - "type": "object", - "description": "Optional. The previous ``content`` for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing." - }, - "prev_sender": { - "type": "string", - "description": "Optional. The ``sender`` of the previous event for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there was no previous event for this state, this key will be missing." - }, "sender": { "type": "string", "description": "The MXID of the user who sent this event." @@ -42,9 +24,30 @@ "type": "string", "description": "The type of event." }, - "txn_id": { - "type": "string", - "description": "Optional. The transaction ID set when this message was sent. This key will only be present for message events sent by the device calling this API." + "unsigned": { + "type": "object", + "title": "Unsigned", + "description": "Information about this event which was not sent by the originating homeserver", + "properties": { + "age": { + "type": "integer", + "format": "int64", + "description": "Time in milliseconds since the event was sent." + }, + "prev_content": { + "title": "EventContent", + "type": "object", + "description": "Optional. The previous ``content`` for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing." + }, + "replaces_state": { + "type": "string", + "description": "Optional. The event_id of the previous event for this state. This will be present only for state events appearing in the ``timeline``. If this is not a state event, or there is no previous content, this key will be missing." + }, + "transaction_id": { + "type": "string", + "description": "Optional. The transaction ID set when this message was sent. This key will only be present for message events sent by the device calling this API." + } + } } } } diff --git a/specification/events.rst b/specification/events.rst index eb48ca17..5a003115 100644 --- a/specification/events.rst +++ b/specification/events.rst @@ -28,20 +28,23 @@ formatted for federation by: * Removing the following keys: ``auth_events``, ``prev_events``, ``hashes``, ``signatures``, ``depth``, - ``origin``, ``prev_state``, ``unsigned``. -* Adding an ``age`` to the event object which gives the time in + ``origin``, ``prev_state``. +* Adding an ``age`` to the ``unsigned`` object which gives the time in milliseconds that has elapsed since the event was sent. -* Adding ``prev_content`` and ``prev_sender`` to the event object if the event - is a ``state event``, which give the previous content and previous sender of - that state key -* Adding a ``redacted_because`` to event object if the event was +* Adding ``prev_content`` and ``prev_sender`` to the ``unsigned`` object if the + event is a ``state event``, which give the previous content and previous + sender of that state key +* Adding a ``redacted_because`` to the ``unsigned`` object if the event was redacted which gives the event that redacted it. -* Adding a ``txn_id`` to the event object if the event was sent by the client - requesting it. +* Adding a ``transaction_id`` to the ``unsigned`` object if the event was sent + by the client requesting it. Events in responses for APIs with the /v1 prefix are generated from an event formatted for the /v2 prefix by: +* Moving the folling keys from the ``unsigned`` object to the top level event + object: ``age``, ``redacted_because``, ``replaces_state``, ``prev_content``. +* Removing the ``unsigned`` object. * Rename the ``sender`` key to ``user_id``. * If the event was an ``m.room.member`` with ``membership`` set to ``invite`` then adding a ``invite_room_state`` key to the top level event object. From d7d59d78e1dca06407dea20ad875f64569844ad3 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 18 Nov 2015 16:17:29 +0000 Subject: [PATCH 4/4] /sync: Put state dict back to being a list Turning the state into a dict-of-dicts caused more pain than it solved. Put it back to a list. --- .../v2_alpha/definitions/state_batch.json | 12 ------- api/client-server/v2_alpha/sync.yaml | 31 ++++++++----------- 2 files changed, 13 insertions(+), 30 deletions(-) delete mode 100644 api/client-server/v2_alpha/definitions/state_batch.json diff --git a/api/client-server/v2_alpha/definitions/state_batch.json b/api/client-server/v2_alpha/definitions/state_batch.json deleted file mode 100644 index 45728f40..00000000 --- a/api/client-server/v2_alpha/definitions/state_batch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "object", - "additionalProperties": { - "type": "object", - "x-pattern": "$EVENT_TYPE", - "additionalProperties": { - "type": "object", - "x-pattern": "$STATE_KEY", - "allOf": [{"$ref": "event.json" }] - } - } -} diff --git a/api/client-server/v2_alpha/sync.yaml b/api/client-server/v2_alpha/sync.yaml index 198f4833..0c9d6186 100644 --- a/api/client-server/v2_alpha/sync.yaml +++ b/api/client-server/v2_alpha/sync.yaml @@ -114,7 +114,7 @@ paths: ``timeline``, if ``since`` is not given, or ``full_state`` is true). allOf: - - $ref: "definitions/state_batch.json" + - $ref: "definitions/event_batch.json" timeline: title: Timeline type: object @@ -158,7 +158,7 @@ paths: delta against the archived ``state`` not the ``invite_state``. allOf: - - $ref: "definitions/state_batch.json" + - $ref: "definitions/event_batch.json" leave: title: Left rooms type: object @@ -174,7 +174,7 @@ paths: description: |- The state updates for the room up to the start of the timeline. allOf: - - $ref: "definitions/state_batch.json" + - $ref: "definitions/event_batch.json" timeline: title: Timeline type: object @@ -207,8 +207,8 @@ paths: "join": { "!726s6s6q:example.com": { "state": { - "m.room.member": { - "@alice:example.com": { + "events": [ + { "sender": "@alice:example.com", "type": "m.room.member", "state_key": "@alice:example.com", @@ -216,7 +216,7 @@ paths: "origin_server_ts": 1417731086795, "event_id": "$66697273743031:example.com" } - } + ] }, "timeline": { "events": [ @@ -248,7 +248,6 @@ paths: "ephemeral": { "events": [ { - "room_id": "!726s6s6q:example.com", "type": "m.typing", "content": {"user_ids": ["@alice:example.com"]} } @@ -259,24 +258,20 @@ paths: "invite": { "!696r7674:example.com": { "invite_state": { - "m.room.name": { - "": { + "events": [ + { "sender": "@alice:example.com", "type": "m.room.name", "state_key": "", - "content": {"name": "My Room Name"}, - "event_id": "$asdkgjrsfg2314375:example.com" - } - }, - "m.room.member": { - "@bob:example.com": { + "content": {"name": "My Room Name"} + }, + { "sender": "@alice:example.com", "type": "m.room.member", "state_key": "@bob:example.com", - "content": {"membership": "invite"}, - "event_id": "$257kasjdg315324akhg:example.com" + "content": {"membership": "invite"} } - } + ] } } },