Add new "query/answer" utility functions for the scripting API
So far, the scripting API was using events to communicate between WA and the iFrame. But often, the scripting API might actually want to "ask" WA a question and wait for an answer. We dealt with this by using 2 unrelated events (in a mostly painful way). This commit adds a "queryWorkadventure" utility function in the iFrame API that allows us to send a query, and to wait for an answer. The query and answer events have a unique ID to be sure the answer matches the correct query. On the WA side, a new `IframeListener.registerAnswerer` method can be used to register a possible answer.
This commit is contained in:
parent
d29c0cc99f
commit
5b4a72ea1f
7 changed files with 248 additions and 113 deletions
|
@ -23,6 +23,9 @@ export interface TypedMessageEvent<T> extends MessageEvent {
|
|||
data: T;
|
||||
}
|
||||
|
||||
/**
|
||||
* List event types sent from an iFrame to WorkAdventure
|
||||
*/
|
||||
export type IframeEventMap = {
|
||||
loadPage: LoadPageEvent;
|
||||
chat: ChatEvent;
|
||||
|
@ -62,7 +65,6 @@ export interface IframeResponseEventMap {
|
|||
enterEvent: EnterLeaveEvent;
|
||||
leaveEvent: EnterLeaveEvent;
|
||||
buttonClickedEvent: ButtonClickedEvent;
|
||||
gameState: GameStateEvent;
|
||||
hasPlayerMoved: HasPlayerMovedEvent;
|
||||
dataLayer: DataLayerEvent;
|
||||
menuItemClicked: MenuItemClickedEvent;
|
||||
|
@ -76,3 +78,46 @@ export interface IframeResponseEvent<T extends keyof IframeResponseEventMap> {
|
|||
export const isIframeResponseEventWrapper = (event: {
|
||||
type?: string;
|
||||
}): event is IframeResponseEvent<keyof IframeResponseEventMap> => typeof event.type === "string";
|
||||
|
||||
|
||||
/**
|
||||
* List event types sent from an iFrame to WorkAdventure that expect a unique answer from WorkAdventure along the type for the answer from WorkAdventure to the iFrame
|
||||
*/
|
||||
export type IframeQueryMap = {
|
||||
getState: {
|
||||
query: undefined,
|
||||
answer: GameStateEvent
|
||||
},
|
||||
}
|
||||
|
||||
export interface IframeQuery<T extends keyof IframeQueryMap> {
|
||||
type: T;
|
||||
data: IframeQueryMap[T]['query'];
|
||||
}
|
||||
|
||||
export interface IframeQueryWrapper<T extends keyof IframeQueryMap> {
|
||||
id: number;
|
||||
query: IframeQuery<T>;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const isIframeQuery = (event: any): event is IframeQuery<keyof IframeQueryMap> => typeof event.type === 'string';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const isIframeQueryWrapper = (event: any): event is IframeQueryWrapper<keyof IframeQueryMap> => typeof event.id === 'number' && isIframeQuery(event.query);
|
||||
|
||||
export interface IframeAnswerEvent<T extends keyof IframeQueryMap> {
|
||||
id: number;
|
||||
type: T;
|
||||
data: IframeQueryMap[T]['answer'];
|
||||
}
|
||||
|
||||
export const isIframeAnswerEvent = (event: { type?: string, id?: number }): event is IframeAnswerEvent<keyof IframeQueryMap> => typeof event.type === 'string' && typeof event.id === 'number';
|
||||
|
||||
export interface IframeErrorAnswerEvent {
|
||||
id: number;
|
||||
type: keyof IframeQueryMap;
|
||||
error: string;
|
||||
}
|
||||
|
||||
export const isIframeErrorAnswerEvent = (event: { type?: string, id?: number, error?: string }): event is IframeErrorAnswerEvent => typeof event.type === 'string' && typeof event.id === 'number' && typeof event.error === 'string';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue