-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommand-dispatcher.js
133 lines (121 loc) · 2.96 KB
/
command-dispatcher.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/**
* @module command-dispatcher
*
*/
const { nope } = require('./index');
/**
* Routes to a named handler of some object, otherwise routes to the default handler
*/
class Dispatcher {
/**
* Builds a new handler which by directs all messages to the default handler.
* @param defaultHandler {Function} default handler
*/
constructor( defaultHandler = nope ) {
/**
* @private
*/
this.handlers = {};
/**
* @public
* @type {Function}
*/
this.defaultHandler = defaultHandler
}
/**
* Registers dispatching to a specific handler for the given command.
* @param name command to be dispatched
* @param handler {Function} the handler to dispatch too
*/
register( name, handler ) {
this.handlers[name] = handler
}
/**
* Removes the handler for the specific command
* @param name command to be removed
*/
unregister( name ){
this.handlers[name] = undefined
}
/**
* Dispatches the given message to the registered handler, otherwise dispatches to the default handler if the
* handler can not be found.
*
* @param targetName target to be dispatched too
* @param message message to extract the handler name from and encapsulating the request
* @param context invocation context
*/
dispatch( targetName, message, context ){
const handler = this.handlers[targetName] || this.defaultHandler;
return handler( message, context );
}
/**
* Registers a handler to receive a single message before unsubscribing.
*
* @param name command to be bound too
* @param handler the handler to be invoked
* @returns {*} the name of the handler
*/
once( name, handler ) {
this.register( name, ( message, context ) => {
this.unregister( name );
handler( message, context )
});
return name
}
/**
* Resets all handlers.
*/
reset(){
this.handlers = {};
}
}
/**
* Routes a given message to a specific command handler.
*/
class CommandDispatcher extends Dispatcher {
/**
* Builds a new handler which by directs all messages to the default handler.
* @param defaultHandler {Function} default handler
*/
constructor( defaultHandler = nope ) {
super(defaultHandler);
}
/**
* Dispatches the given message to the registered handler, otherwise dispatches to the default handler if the
* handler can not be found.
*
* @param message message to extract the handler name from and encapsulating the request
* @param context invocation context
*/
dispatch( message, context ){
const targetName = message.command;
super.dispatch(targetName, message, context);
}
}
/**
* Monotonically incrementing base 36 radix text.
*/
class Base36Namer {
/**
* Initializes a new namer with the default value or 0
* @param start base number to begin with
*/
constructor( start = 0 ) {
this.id = start;
}
/**
* Generate the next value in the series
* @returns {string}
*/
next() {
const id = this.id;
this.id++;
return id.toString(36);
}
}
module.exports = {
Base36Namer,
CommandDispatcher,
Dispatcher
};