UNPKG

4.53 kBJavaScriptView Raw
1(function() {
2 var Messenger, RequestMiddleware, crema, dolce;
3
4 dolce = require("dolce");
5
6 RequestMiddleware = require("./middleware");
7
8 crema = require("crema");
9
10 Messenger = require("./messenger");
11
12 /*
13
14 Director process:
15 */
16
17 module.exports = (function() {
18 /*
19 some directors are passive, meaning errors aren't returned if a route does not exist. This goes for collectors,
20 emitters, etc.
21 */
22 _Class.prototype.passive = false;
23
24 /*
25 constructor
26 */
27
28 function _Class(name, router) {
29 this.name = name;
30 this.router = router;
31 this._collection = dolce.collection();
32 }
33
34 /*
35 returns number of listeners based on channel given
36 */
37
38 _Class.prototype.numListeners = function(channel, ops) {
39 return this._collection.get(channel, ops).chains.length;
40 };
41
42 /*
43 dispatches a request
44 */
45
46 _Class.prototype.dispatch = function(messageWriter) {
47 var chain, chains, messageReader, messanger, middleware, numChains, numRunning, oldAck, _i, _len;
48 chains = this.getListeners(messageWriter);
49 numChains = chains.length;
50 numRunning = numChains;
51 oldAck = messageWriter.callback;
52 messageWriter.running = !!numChains;
53 messageWriter.callback = function() {
54 messageWriter.running = !!(--numRunning);
55 if (oldAck) {
56 return oldAck.apply(this, Array.apply(null, arguments).concat([numRunning, numChains]));
57 }
58 };
59 if (!!!chains.length && !this.passive) {
60 messageWriter.callback(new Error("Route \"" + (crema.stringifyPaths(messageWriter.channel.paths)) + "\" does not exist"));
61 return this;
62 }
63 for (_i = 0, _len = chains.length; _i < _len; _i++) {
64 chain = chains[_i];
65 messageReader = messageWriter.reader();
66 middleware = RequestMiddleware.wrap(chain, messageWriter.pre, messageWriter.next, this);
67 messanger = this._newMessenger(messageReader, middleware);
68 messanger.start();
69 }
70 return this;
71 };
72
73 /*
74 adds a route listener to the collection tree
75 */
76
77 _Class.prototype.addListener = function(route, callback) {
78 disposable;
79 var disposable, oldCallback;
80 if (route.tags.one) {
81 oldCallback = callback;
82 callback = function() {
83 oldCallback.apply(this, arguments);
84 return disposable.dispose();
85 };
86 }
87 this._validateListener(route, callback);
88 return disposable = this._collection.add(route, callback);
89 };
90
91 /*
92 */
93
94 _Class.prototype.channels = function(ops) {
95 var channels, listener, _i, _len, _ref, _results;
96 channels = [];
97 _ref = this._collection.find(ops);
98 _results = [];
99 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
100 listener = _ref[_i];
101 _results.push({
102 tags: listener.tags,
103 type: this.name,
104 path: listener.path
105 });
106 }
107 return _results;
108 };
109
110 /*
111 */
112
113 _Class.prototype.listenerQuery = function(ops) {
114 var search, tag, tagName, tags;
115 tags = [];
116 tag = {};
117 for (tagName in ops.tags) {
118 if (ops.tags[tagName] === true) {
119 ops.tags[tagName] = {
120 $exists: true
121 };
122 }
123 tag = {};
124 tag[tagName] = ops.tags[tagName];
125 tags.push(tag);
126 }
127 search = {
128 $or: [
129 {
130 $and: tags
131 }, {
132 unfilterable: {
133 $exists: true
134 }
135 }
136 ]
137 };
138 return search;
139 };
140
141 /*
142 */
143
144 _Class.prototype.getListeners = function(route, search) {
145 return this._collection.get(route.channel, {
146 siftTags: this.listenerQuery(search || route)
147 }).chains;
148 };
149
150 /*
151 */
152
153 _Class.prototype.routeExists = function(route) {
154 return this._collection.contains(route.channel, {
155 siftTags: this.listenerQuery(route)
156 });
157 };
158
159 /*
160 returns a new request
161 */
162
163 _Class.prototype._newMessenger = function(message, middleware) {
164 return new Messenger(message, middleware, this);
165 };
166
167 /*
168 */
169
170 _Class.prototype._validateListener = function(route) {
171 var listeners;
172 if (this.passive) return;
173 listeners = this._collection.get(route.channel, route.tags);
174 if (!!listeners.length) {
175 throw new Error("Route \"" + route.channel.value + "\" already exists");
176 }
177 };
178
179 return _Class;
180
181 })();
182
183}).call(this);