smartuniverse/ts/smartuniverse.classes.reactionrequest.ts

84 lines
2.7 KiB
TypeScript
Raw Normal View History

2019-09-09 22:39:18 +00:00
import * as plugins from './smartuniverse.plugins';
2019-09-10 21:55:20 +00:00
import { UniverseChannel } from './smartuniverse.classes.universechannel';
import { ClientUniverseChannel } from './smartuniverse.classes.clientuniversechannel';
import { ReactionResult } from './smartuniverse.classes.reactionresult';
import { UniverseMessage } from './smartuniverse.classes.universemessage';
import { ClientUniverseMessage } from './smartuniverse.classes.clientuniversemessage';
2019-09-09 22:39:18 +00:00
2019-11-09 12:00:30 +00:00
export interface IReactionRequestConstructorOptions<
T extends plugins.typedrequestInterfaces.ITypedRequest
> {
2019-09-10 17:36:10 +00:00
method: T['method'];
}
export interface ICombinatorPayload<T extends plugins.typedrequestInterfaces.ITypedRequest> {
/**
* needed for tying responses to requests
*/
id: string;
2019-09-11 08:11:34 +00:00
typedRequestPayload: {
2019-11-09 12:00:30 +00:00
method: T['method'];
request: T['request'];
response: T['response'];
2019-09-11 08:11:34 +00:00
};
2019-09-10 17:36:10 +00:00
}
export class ReactionRequest<T extends plugins.typedrequestInterfaces.ITypedRequest> {
public method: T['method'];
constructor(optionsArg: IReactionRequestConstructorOptions<T>) {
this.method = optionsArg.method;
}
2019-11-09 12:00:30 +00:00
public async fire(
channelsArg: Array<UniverseChannel | ClientUniverseChannel>,
requestDataArg: T['request'],
timeoutMillisArg = 5000
) {
2019-09-10 21:55:20 +00:00
const subscriptionMap = new plugins.lik.Objectmap<plugins.smartrx.rxjs.Subscription>();
const reactionResult = new ReactionResult<T>();
const requestId = plugins.smartunique.shortId();
for (const channel of channelsArg) {
2019-11-09 12:00:30 +00:00
subscriptionMap.add(
channel.subscribe(
(
messageArg:
| UniverseMessage<ICombinatorPayload<T>>
| ClientUniverseMessage<ICombinatorPayload<T>>
) => {
if (
messageArg.messageText === 'reactionResponse' &&
messageArg.payload.typedRequestPayload.method === this.method
) {
const payload: ICombinatorPayload<T> = messageArg.payload;
if (payload.id !== requestId) {
return;
}
reactionResult.pushReactionResponse(payload.typedRequestPayload.response);
}
2019-09-10 21:55:20 +00:00
}
2019-11-09 12:00:30 +00:00
)
);
2019-09-11 12:57:36 +00:00
const payload: ICombinatorPayload<T> = {
id: requestId,
typedRequestPayload: {
method: this.method,
request: requestDataArg,
response: null
}
2019-09-17 10:46:35 +00:00
};
2019-09-11 12:57:36 +00:00
channel.sendMessage({
messageText: 'reactionRequest',
payload
});
2019-09-10 21:55:20 +00:00
}
plugins.smartdelay.delayFor(timeoutMillisArg).then(async () => {
await subscriptionMap.forEach(subscriptionArg => {
subscriptionArg.unsubscribe();
});
reactionResult.complete();
});
return reactionResult;
}
2019-09-10 17:36:10 +00:00
}