refactored to key based types

This commit is contained in:
jonny 2021-05-28 02:28:11 +02:00
parent dbb35d102f
commit 8a1376e966
2 changed files with 22 additions and 18 deletions

View File

@ -9,21 +9,28 @@ export function sendToWorkadventure(content: IframeEvent<keyof IframeEventMap>)
} }
type GuardedType<Guard extends tg.TypeGuard<unknown>> = Guard extends tg.TypeGuard<infer T> ? T : never type GuardedType<Guard extends tg.TypeGuard<unknown>> = Guard extends tg.TypeGuard<infer T> ? T : never
export function apiCallback<T extends tg.TypeGuard<unknown>>(callbackData: IframeCallbackContribution<T>) { export function apiCallback<T extends keyof IframeResponseEventMap>(callbackData: IframeCallbackContribution<T>): IframeCallbackContribution<keyof IframeResponseEventMap> {
registeredCallbacks[callbackData.type] = { const iframeCallback = {
typeChecker: callbackData.typeChecker, typeChecker: callbackData.typeChecker,
callback: callbackData.callback callback: callbackData.callback
} } as IframeCallback<T>;
return callbackData
const newCallback = { [callbackData.type]: iframeCallback };
Object.assign(registeredCallbacks, newCallback)
return callbackData as unknown as IframeCallbackContribution<keyof IframeResponseEventMap>;
} }
export interface IframeCallbackContribution<Guard extends tg.TypeGuard<unknown>, T = GuardedType<Guard>> { export interface IframeCallback<Key extends keyof IframeResponseEventMap, T = IframeResponseEventMap[Key], Guard = tg.TypeGuard<T>> {
type: keyof IframeResponseEventMap,
typeChecker: Guard, typeChecker: Guard,
callback: (payloadData: T) => void callback: (payloadData: T) => void
} }
export interface IframeCallbackContribution<Key extends keyof IframeResponseEventMap> extends IframeCallback<Key> {
type: Key
}
export type PossibleSubobjects = "zone" | "chat" | "ui" | "nav" | "sound" | "cowebsite" | "player" | "bubble" export type PossibleSubobjects = "zone" | "chat" | "ui" | "nav" | "sound" | "cowebsite" | "player" | "bubble"
/** /**
* !! be aware that the implemented attributes (addMethodsAtRoot and subObjectIdentifier) must be readonly * !! be aware that the implemented attributes (addMethodsAtRoot and subObjectIdentifier) must be readonly
@ -32,9 +39,7 @@ export type PossibleSubobjects = "zone" | "chat" | "ui" | "nav" | "sound" | "cow
*/ */
export abstract class IframeApiContribution<T extends { export abstract class IframeApiContribution<T extends {
// i think this is specific enough callbacks: Array<IframeCallbackContribution<keyof IframeResponseEventMap>>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callbacks: Array<IframeCallbackContribution<tg.TypeGuard<any>>>,
readonly subObjectIdentifier: PossibleSubobjects, readonly subObjectIdentifier: PossibleSubobjects,
readonly addMethodsAtRoot: boolean | undefined readonly addMethodsAtRoot: boolean | undefined
}> { }> {

View File

@ -1,10 +1,9 @@
import { IframeResponseEventMap, isIframeResponseEventWrapper } from "./Api/Events/IframeEvent"; import { IframeResponseEvent, IframeResponseEventMap, isIframeResponseEventWrapper, TypedMessageEvent } from "./Api/Events/IframeEvent";
import type { IframeCallback } from './Api/iframe/IframeApiContribution';
import type { WorkAdventureApi } from './iframe_api.d'; import type { WorkAdventureApi } from './iframe_api.d';
export const registeredCallbacks: { [K in keyof IframeResponseEventMap]?: {
typeChecker: Function export const registeredCallbacks: { [K in keyof IframeResponseEventMap]?: IframeCallback<K> } = {}
callback: Function
} } = {}
const importType = Promise.all([ const importType = Promise.all([
import("./Api/iframe/popup"), import("./Api/iframe/popup"),
@ -52,7 +51,7 @@ async function populateWa(): Promise<void> {
populateWa() populateWa()
window.addEventListener('message', message => { window.addEventListener('message', <T extends keyof IframeResponseEventMap>(message: TypedMessageEvent<IframeResponseEvent<T>>) => {
if (message.source !== window.parent) { if (message.source !== window.parent) {
return; // Skip message in this event listener return; // Skip message in this event listener
} }
@ -62,9 +61,9 @@ window.addEventListener('message', message => {
if (isIframeResponseEventWrapper(payload)) { if (isIframeResponseEventWrapper(payload)) {
const payloadData = payload.data; const payloadData = payload.data;
if (registeredCallbacks[payload.type] && registeredCallbacks[payload.type]?.typeChecker(payloadData)) { const callback = registeredCallbacks[payload.type] as IframeCallback<T> | undefined
registeredCallbacks[payload.type]?.callback(payloadData) if (callback?.typeChecker(payloadData)) {
return callback?.callback(payloadData)
} }
} }