@@ -40,7 +40,7 @@ import {
4040 ISupportedVersionsActionRequest ,
4141 ISupportedVersionsActionResponseData ,
4242} from "./interfaces/SupportedVersionsAction" ;
43- import { CurrentApiVersions } from "./interfaces/ApiVersion" ;
43+ import { ApiVersion , CurrentApiVersions , UnstableApiVersion } from "./interfaces/ApiVersion" ;
4444import { IScreenshotActionResponseData } from "./interfaces/ScreenshotAction" ;
4545import { IVisibilityActionRequestData } from "./interfaces/VisibilityAction" ;
4646import { IWidgetApiAcknowledgeResponseData , IWidgetApiResponseData } from "./interfaces/IWidgetApiResponse" ;
@@ -138,6 +138,7 @@ import { IUpdateStateToWidgetRequestData } from "./interfaces/UpdateStateAction"
138138export class ClientWidgetApi extends EventEmitter {
139139 public readonly transport : ITransport ;
140140
141+ private cachedWidgetVersions : ApiVersion [ ] | null = null ;
141142 // contentLoadedActionSent is used to check that only one ContentLoaded request is send.
142143 private contentLoadedActionSent = false ;
143144 private allowedCapabilities = new Set < Capability > ( ) ;
@@ -227,6 +228,24 @@ export class ClientWidgetApi extends EventEmitter {
227228 this . transport . stop ( ) ;
228229 }
229230
231+ public async getWidgetVersions ( ) : Promise < ApiVersion [ ] > {
232+ if ( Array . isArray ( this . cachedWidgetVersions ) ) {
233+ return Promise . resolve ( this . cachedWidgetVersions ) ;
234+ }
235+
236+ try {
237+ const r = await this . transport . send < IWidgetApiRequestEmptyData , ISupportedVersionsActionResponseData > (
238+ WidgetApiToWidgetAction . SupportedApiVersions ,
239+ { } ,
240+ ) ;
241+ this . cachedWidgetVersions = r . supported_versions ;
242+ return r . supported_versions ;
243+ } catch ( e ) {
244+ console . warn ( "non-fatal error getting supported widget versions: " , e ) ;
245+ return [ ] ;
246+ }
247+ }
248+
230249 private beginCapabilities ( ) : void {
231250 // widget has loaded - tell all the listeners that
232251 this . emit ( "preparing" ) ;
@@ -1013,7 +1032,7 @@ export class ClientWidgetApi extends EventEmitter {
10131032 public async feedEvent ( rawEvent : IRoomEvent , currentViewedRoomId : string ) : Promise < void > ;
10141033 /**
10151034 * Feeds an event to the widget. As a client you are expected to call this
1016- * for every new event in every room to which you are joined or invited.
1035+ * for every new event (including state events) in every room to which you are joined or invited.
10171036 * @param {IRoomEvent } rawEvent The event to (try to) send to the widget.
10181037 * @returns {Promise<void> } Resolves when delivered or if the widget is not
10191038 * able to read the event due to permissions, rejects if the widget failed
@@ -1082,6 +1101,7 @@ export class ClientWidgetApi extends EventEmitter {
10821101 }
10831102
10841103 private async flushRoomState ( ) : Promise < void > {
1104+ const useUpdateState = ( await this . getWidgetVersions ( ) ) . includes ( UnstableApiVersion . MSC2762_UPDATE_STATE ) ;
10851105 try {
10861106 // Only send a single action once all concurrent tasks have completed
10871107 do await Promise . all ( [ ...this . pushRoomStateTasks ] ) ;
@@ -1093,9 +1113,11 @@ export class ClientWidgetApi extends EventEmitter {
10931113 events . push ( ...stateKeyMap . values ( ) ) ;
10941114 }
10951115 }
1096- await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1097- state : events ,
1098- } ) ;
1116+ if ( useUpdateState ) {
1117+ await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1118+ state : events ,
1119+ } ) ;
1120+ }
10991121 } finally {
11001122 this . flushRoomStateTask = null ;
11011123 }
@@ -1161,6 +1183,8 @@ export class ClientWidgetApi extends EventEmitter {
11611183 widget failed to handle the update.
11621184 */
11631185 public async feedStateUpdate ( rawEvent : IRoomEvent ) : Promise < void > {
1186+ const useUpdateState = ( await this . getWidgetVersions ( ) ) . includes ( UnstableApiVersion . MSC2762_UPDATE_STATE ) ;
1187+
11641188 if ( rawEvent . state_key === undefined ) throw new Error ( "Not a state event" ) ;
11651189 if (
11661190 ( rawEvent . room_id === this . viewedRoomId || this . canUseRoomTimeline ( rawEvent . room_id ) ) &&
@@ -1169,9 +1193,12 @@ export class ClientWidgetApi extends EventEmitter {
11691193 // Updates could race with the initial push of the room's state
11701194 if ( this . pushRoomStateTasks . size === 0 ) {
11711195 // No initial push tasks are pending; safe to send immediately
1172- await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1173- state : [ rawEvent ] ,
1174- } ) ;
1196+ if ( useUpdateState ) {
1197+ // Only send state updates when using UpdateState. Otherwise we will use SendEvent.
1198+ await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1199+ state : [ rawEvent ] ,
1200+ } ) ;
1201+ }
11751202 } else {
11761203 // Lump the update in with whatever data will be sent in the
11771204 // initial push later. Even if we set it to an "outdated" entry
0 commit comments