From d1cf98b1770d0282224e80bc9303609f6c156d3a Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Fri, 31 Mar 2023 13:51:10 +0100 Subject: [PATCH] Allow via_servers property in findPredecessor (update to MSC3946) (#3240) --- spec/unit/room.spec.ts | 13 ++++++++++--- src/models/room-state.ts | 19 ++++++++++++++++--- src/models/room.ts | 12 ++++++++++-- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/spec/unit/room.spec.ts b/spec/unit/room.spec.ts index b21c11bb5c1..d256bf758b4 100644 --- a/spec/unit/room.spec.ts +++ b/spec/unit/room.spec.ts @@ -3343,11 +3343,16 @@ describe("Room", function () { newRoomId: string, predecessorRoomId: string, tombstoneEventId: string | null = null, + viaServers: string[] = [], ): MatrixEvent { const content = tombstoneEventId === null - ? { predecessor_room_id: predecessorRoomId } - : { predecessor_room_id: predecessorRoomId, last_known_event_id: tombstoneEventId }; + ? { predecessor_room_id: predecessorRoomId, via_servers: viaServers } + : { + predecessor_room_id: predecessorRoomId, + last_known_event_id: tombstoneEventId, + via_servers: viaServers, + }; return new MatrixEvent({ content, @@ -3387,6 +3392,7 @@ describe("Room", function () { expect(room.findPredecessor(useMsc3946)).toEqual({ roomId: "otherreplacedroomid", eventId: undefined, // m.predecessor did not include an event_id + viaServers: [], }); }); @@ -3394,12 +3400,13 @@ describe("Room", function () { const room = new Room("roomid", client!, "@u:example.com"); room.addLiveEvents([ roomCreateEvent("roomid", "replacedroomid"), - predecessorEvent("roomid", "otherreplacedroomid", "lstevtid"), + predecessorEvent("roomid", "otherreplacedroomid", "lstevtid", ["one.example.com", "two.example.com"]), ]); const useMsc3946 = true; expect(room.findPredecessor(useMsc3946)).toEqual({ roomId: "otherreplacedroomid", eventId: "lstevtid", + viaServers: ["one.example.com", "two.example.com"], }); }); diff --git a/src/models/room-state.ts b/src/models/room-state.ts index 40dc35b9198..f975b9cbdce 100644 --- a/src/models/room-state.ts +++ b/src/models/room-state.ts @@ -972,13 +972,21 @@ export class RoomState extends TypedEventEmitter * @param msc3946ProcessDynamicPredecessor - if true, look for an * m.room.predecessor state event and use it if found (MSC3946). * @returns null if this room has no predecessor. Otherwise, returns - * the roomId and last eventId of the predecessor room. + * the roomId, last eventId and viaServers of the predecessor room. + * * If msc3946ProcessDynamicPredecessor is true, use m.predecessor events * as well as m.room.create events to find predecessors. + * * Note: if an m.predecessor event is used, eventId may be undefined * since last_known_event_id is optional. + * + * Note: viaServers may be undefined, and will definitely be undefined if + * this predecessor comes from a RoomCreate event (rather than a + * RoomPredecessor, which has the optional via_servers property). */ - public findPredecessor(msc3946ProcessDynamicPredecessor = false): { roomId: string; eventId?: string } | null { + public findPredecessor( + msc3946ProcessDynamicPredecessor = false, + ): { roomId: string; eventId?: string; viaServers?: string[] } | null { // Note: the tests for this function are against Room.findPredecessor, // which just calls through to here. @@ -988,14 +996,19 @@ export class RoomState extends TypedEventEmitter const content = predecessorEvent.getContent<{ predecessor_room_id: string; last_known_event_id?: string; + via_servers?: string[]; }>(); const roomId = content.predecessor_room_id; let eventId = content.last_known_event_id; if (typeof eventId !== "string") { eventId = undefined; } + let viaServers = content.via_servers; + if (!Array.isArray(viaServers)) { + viaServers = undefined; + } if (typeof roomId === "string") { - return { roomId, eventId }; + return { roomId, eventId, viaServers }; } } } diff --git a/src/models/room.ts b/src/models/room.ts index f6517250098..133b210439d 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -3057,13 +3057,21 @@ export class Room extends ReadReceipt { * @param msc3946ProcessDynamicPredecessor - if true, look for an * m.room.predecessor state event and use it if found (MSC3946). * @returns null if this room has no predecessor. Otherwise, returns - * the roomId and last eventId of the predecessor room. + * the roomId, last eventId and viaServers of the predecessor room. + * * If msc3946ProcessDynamicPredecessor is true, use m.predecessor events * as well as m.room.create events to find predecessors. + * * Note: if an m.predecessor event is used, eventId may be undefined * since last_known_event_id is optional. + * + * Note: viaServers may be undefined, and will definitely be undefined if + * this predecessor comes from a RoomCreate event (rather than a + * RoomPredecessor, which has the optional via_servers property). */ - public findPredecessor(msc3946ProcessDynamicPredecessor = false): { roomId: string; eventId?: string } | null { + public findPredecessor( + msc3946ProcessDynamicPredecessor = false, + ): { roomId: string; eventId?: string; viaServers?: string[] } | null { const currentState = this.getLiveTimeline().getState(EventTimeline.FORWARDS); if (!currentState) { return null;