-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
99 lines (89 loc) · 2.3 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
'use strict';
const EventEmitter = require('eventemitter3');
/**
* Creates new RqrsEmitter object instance, it uses EventEmitter
* as a parent
*/
function RqrsEmitter() {
EventEmitter.call(this);
this.handlersMap = {};
}
// Build prototype
RqrsEmitter.prototype = Object.create(EventEmitter.prototype);
// Returns internal event name based on incoming event
function rqrsEvent(event) {
return '_rqrs_' + event;
}
// Returns random string
function rndstr() {
return Math.random().toString(36).substring(2, 15);
}
/**
* Send new request
* @param event - Event name
* @param data - Request data
*/
RqrsEmitter.prototype.request = async function(event, data) {
return new Promise((function(resolve, reject) {
const reqId = rndstr() + rndstr();
const respEvent = reqId + rqrsEvent(event);
this.once(respEvent, function(res) {
if (!res.isError) {
resolve(res.data);
} else {
reject(res.data);
}
});
const r = this.emit(rqrsEvent(event), {
id: reqId,
data: data
});
// r = true | false -- had listeners
if (!r) {
this.removeListener(respEvent);
reject(new Error(`no handler found for [${event}]`));
}
}).bind(this));
}
/**
* Add request handler
* @param event - Event name
* @param handlerFn - Request handler function (must be async)
*/
RqrsEmitter.prototype.addRequestHandler = function(event, handlerFn) {
if (this.handlersMap[event]) {
throw new Error(`handler already exists for [${event}]`);
}
const r = this.on(rqrsEvent(event), async function(req) {
try {
const res = await handlerFn(req.data);
this.emit(req.id + rqrsEvent(event), {
data: res,
isError: false
});
} catch (e) {
this.emit(req.id + rqrsEvent(event), {
data: e,
isError: true
});
}
});
this.handlersMap[event] = true;
return r;
}
/**
* Remove request handler
* @param event - Event name
*/
RqrsEmitter.prototype.removeRequestHandler = function(event) {
const r = this.removeListener(rqrsEvent(event));
delete this.handlersMap[event];
return r;
}
//
// Aliases
//
RqrsEmitter.prototype.handler = RqrsEmitter.prototype.addRequestHandler;
RqrsEmitter.prototype.removeHandler = RqrsEmitter.prototype.removeRequestHandler;
// Export
module.exports = RqrsEmitter;