import * as plugins from './smartuniverse.plugins.js'; import { UniverseChannel } from './smartuniverse.classes.universechannel.js'; import { ClientUniverseChannel } from './smartuniverse.classes.client.universechannel.js'; import { ReactionResult } from './smartuniverse.classes.event.reactionresult.js'; import { UniverseMessage } from './smartuniverse.classes.universemessage.js'; import { ClientUniverseMessage } from './smartuniverse.classes.client.universemessage.js'; export interface IReactionRequestConstructorOptions< T extends plugins.typedrequestInterfaces.ITypedRequest > { method: T['method']; } export interface ICombinatorPayload { /** * needed for tying responses to requests */ id: string; typedRequestPayload: { method: T['method']; request: T['request']; response: T['response']; }; } export class ReactionRequest { public method: T['method']; constructor(optionsArg: IReactionRequestConstructorOptions) { this.method = optionsArg.method; } public async fire( channelsArg: Array, requestDataArg: T['request'], timeoutMillisArg = 5000 ) { const subscriptionMap = new plugins.lik.ObjectMap(); const reactionResult = new ReactionResult(); const requestId = plugins.isounique.uni(); for (const channel of channelsArg) { subscriptionMap.add( channel.subscribe( ( messageArg: | UniverseMessage> | ClientUniverseMessage> ) => { if ( messageArg.messageText === 'reactionResponse' && messageArg.payload.typedRequestPayload.method === this.method ) { const payload: ICombinatorPayload = messageArg.payload; if (payload.id !== requestId) { return; } reactionResult.pushReactionResponse(payload.typedRequestPayload.response); } } ) ); const payload: ICombinatorPayload = { id: requestId, typedRequestPayload: { method: this.method, request: requestDataArg, response: null, }, }; channel.postMessage({ messageText: 'reactionRequest', payload, }); } plugins.smartdelay.delayFor(timeoutMillisArg).then(async () => { await subscriptionMap.forEach((subscriptionArg) => { subscriptionArg.unsubscribe(); }); reactionResult.complete(); }); return reactionResult; } }