@@ -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" ) ;
@@ -287,7 +306,7 @@ export class ClientWidgetApi extends EventEmitter {
287306
288307 private onIframeLoad ( ev : Event ) : void {
289308 if ( this . widget . waitForIframeLoad ) {
290- // If the widget is set to waitForIframeLoad the capabilities immediatly get setup after load.
309+ // If the widget is set to waitForIframeLoad the capabilities immediately get setup after load.
291310 // The client does not wait for the ContentLoaded action.
292311 this . beginCapabilities ( ) ;
293312 } else {
@@ -1037,7 +1056,7 @@ export class ClientWidgetApi extends EventEmitter {
10371056 public async feedEvent ( rawEvent : IRoomEvent , currentViewedRoomId : string ) : Promise < void > ;
10381057 /**
10391058 * Feeds an event to the widget. As a client you are expected to call this
1040- * for every new event in every room to which you are joined or invited.
1059+ * for every new event (including state events) in every room to which you are joined or invited.
10411060 * @param {IRoomEvent } rawEvent The event to (try to) send to the widget.
10421061 * @returns {Promise<void> } Resolves when delivered or if the widget is not
10431062 * able to read the event due to permissions, rejects if the widget failed
@@ -1117,9 +1136,12 @@ export class ClientWidgetApi extends EventEmitter {
11171136 events . push ( ...stateKeyMap . values ( ) ) ;
11181137 }
11191138 }
1120- await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1121- state : events ,
1122- } ) ;
1139+ if ( ( await this . getWidgetVersions ( ) ) . includes ( UnstableApiVersion . MSC2762_UPDATE_STATE ) ) {
1140+ // Only send state updates when using UpdateState. Otherwise the SendEvent action will be responsible for state updates.
1141+ await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1142+ state : events ,
1143+ } ) ;
1144+ }
11231145 } finally {
11241146 this . flushRoomStateTask = null ;
11251147 }
@@ -1182,7 +1204,7 @@ export class ClientWidgetApi extends EventEmitter {
11821204 * room state entry.
11831205 * @returns {Promise<void> } Resolves when delivered or if the widget is not
11841206 * able to receive the room state due to permissions, rejects if the
1185- widget failed to handle the update.
1207+ * widget failed to handle the update.
11861208 */
11871209 public async feedStateUpdate ( rawEvent : IRoomEvent ) : Promise < void > {
11881210 if ( rawEvent . state_key === undefined ) throw new Error ( "Not a state event" ) ;
@@ -1193,9 +1215,12 @@ export class ClientWidgetApi extends EventEmitter {
11931215 // Updates could race with the initial push of the room's state
11941216 if ( this . pushRoomStateTasks . size === 0 ) {
11951217 // No initial push tasks are pending; safe to send immediately
1196- await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1197- state : [ rawEvent ] ,
1198- } ) ;
1218+ if ( ( await this . getWidgetVersions ( ) ) . includes ( UnstableApiVersion . MSC2762_UPDATE_STATE ) ) {
1219+ // Only send state updates when using UpdateState. Otherwise the SendEvent action will be responsible for state updates.
1220+ await this . transport . send < IUpdateStateToWidgetRequestData > ( WidgetApiToWidgetAction . UpdateState , {
1221+ state : [ rawEvent ] ,
1222+ } ) ;
1223+ }
11991224 } else {
12001225 // Lump the update in with whatever data will be sent in the
12011226 // initial push later. Even if we set it to an "outdated" entry
0 commit comments