Actually using Type Guards in queries received by WA.
This commit is contained in:
parent
0aa93543bc
commit
86fa869b20
@ -1,3 +1,4 @@
|
||||
import * as tg from "generic-type-guard";
|
||||
import type { GameStateEvent } from "./GameStateEvent";
|
||||
import type { ButtonClickedEvent } from "./ButtonClickedEvent";
|
||||
import type { ChatEvent } from "./ChatEvent";
|
||||
@ -19,6 +20,9 @@ import type { MenuItemRegisterEvent } from "./ui/MenuItemRegisterEvent";
|
||||
import type { HasPlayerMovedEvent } from "./HasPlayerMovedEvent";
|
||||
import type { SetTilesEvent } from "./SetTilesEvent";
|
||||
import type { SetVariableEvent } from "./SetVariableEvent";
|
||||
import {isGameStateEvent} from "./GameStateEvent";
|
||||
import {isMapDataEvent} from "./MapDataEvent";
|
||||
import {isSetVariableEvent} from "./SetVariableEvent";
|
||||
|
||||
export interface TypedMessageEvent<T> extends MessageEvent {
|
||||
data: T;
|
||||
@ -81,20 +85,32 @@ export const isIframeResponseEventWrapper = (event: {
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
||||
* Types are defined using Type guards that will actually bused to enforce and check types.
|
||||
*/
|
||||
export type IframeQueryMap = {
|
||||
export const iframeQueryMapTypeGuards = {
|
||||
getState: {
|
||||
query: undefined,
|
||||
answer: GameStateEvent,
|
||||
query: tg.isUndefined,
|
||||
answer: isGameStateEvent,
|
||||
},
|
||||
getMapData: {
|
||||
query: undefined,
|
||||
answer: MapDataEvent,
|
||||
query: tg.isUndefined,
|
||||
answer: isMapDataEvent,
|
||||
},
|
||||
setVariable: {
|
||||
query: SetVariableEvent,
|
||||
answer: void
|
||||
query: isSetVariableEvent,
|
||||
answer: tg.isUndefined,
|
||||
},
|
||||
}
|
||||
|
||||
type GuardedType<T> = T extends (x: unknown) => x is (infer T) ? T : never;
|
||||
type IframeQueryMapTypeGuardsType = typeof iframeQueryMapTypeGuards;
|
||||
type UnknownToVoid<T> = undefined extends T ? void : T;
|
||||
|
||||
export type IframeQueryMap = {
|
||||
[key in keyof IframeQueryMapTypeGuardsType]: {
|
||||
query: GuardedType<IframeQueryMapTypeGuardsType[key]['query']>
|
||||
answer: UnknownToVoid<GuardedType<IframeQueryMapTypeGuardsType[key]['answer']>>
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,8 +124,21 @@ export interface IframeQueryWrapper<T extends keyof IframeQueryMap> {
|
||||
query: IframeQuery<T>;
|
||||
}
|
||||
|
||||
export const isIframeQueryKey = (type: string): type is keyof IframeQueryMap => {
|
||||
return type in iframeQueryMapTypeGuards;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export const isIframeQuery = (event: any): event is IframeQuery<keyof IframeQueryMap> => typeof event.type === 'string';
|
||||
export const isIframeQuery = (event: any): event is IframeQuery<keyof IframeQueryMap> => {
|
||||
const type = event.type;
|
||||
if (typeof type !== 'string') {
|
||||
return false;
|
||||
}
|
||||
if (!isIframeQueryKey(type)) {
|
||||
return false;
|
||||
}
|
||||
return iframeQueryMapTypeGuards[type].query(event.data);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
@ -168,13 +168,15 @@ class IframeListener {
|
||||
return;
|
||||
}
|
||||
|
||||
const errorHandler = (reason: any) => {
|
||||
const errorHandler = (reason: unknown) => {
|
||||
console.error('An error occurred while responding to an iFrame query.', reason);
|
||||
let reasonMsg: string;
|
||||
let reasonMsg: string = '';
|
||||
if (reason instanceof Error) {
|
||||
reasonMsg = reason.message;
|
||||
} else {
|
||||
reasonMsg = reason.toString();
|
||||
} else if (typeof reason === 'object') {
|
||||
reasonMsg = reason ? reason.toString() : '';
|
||||
} else if (typeof reason === 'string') {
|
||||
reasonMsg = reason;
|
||||
}
|
||||
|
||||
iframe?.contentWindow?.postMessage({
|
||||
|
@ -14,24 +14,6 @@
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
"height":10,
|
||||
"id":6,
|
||||
"name":"triggerZone",
|
||||
"opacity":1,
|
||||
"properties":[
|
||||
{
|
||||
"name":"zone",
|
||||
"type":"string",
|
||||
"value":"myTrigger"
|
||||
}],
|
||||
"type":"tilelayer",
|
||||
"visible":true,
|
||||
"width":10,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
{
|
||||
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
"height":10,
|
||||
@ -58,7 +40,7 @@
|
||||
{
|
||||
"fontfamily":"Sans Serif",
|
||||
"pixelsize":11,
|
||||
"text":"Test:\nTODO",
|
||||
"text":"Test:\nOpen your console\n\nResult:\nYou should see a list of tests performed and results associated.",
|
||||
"wrap":true
|
||||
},
|
||||
"type":"",
|
||||
|
Loading…
Reference in New Issue
Block a user