-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprimusServer.js
149 lines (119 loc) · 3.32 KB
/
primusServer.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
'use strict';
/**
* Expose `resource`.
*/
module.exports = function resource(primus, options) {
/**
* List of resources.
*
* @type {object}
* @api private
*/
primus.resources = {};
/**
* Define the global $ namespace if its
* not yet defined.
*
* @type {object}
* @api private
*/
primus.$ = primus.$ || {};
/**
* Register Resource under $ as a plugin
* for other plugins to be aware of it.
*
* @type {Object}
* @api private
*/
primus.$.resource = {};
primus.$.resource.resource = createResource;
/**
* Create a new resource.
*
* @param {String} name Namespace id
* @returns {Resource}
* @api private
*/
primus.resource = function create(name, resource, multiplex) {
return this.resources[name] || createResource(name, resource, multiplex);
};
/**
* Create a resource object to be used.
*
* @param {String} name Resource name
* @param {Object} resource The resource object
* @param {Boolean} multiplex
* @return {Resource}
* @api public
*/
var createResource = function(name, resource) {
resource = resource || {};
// Validate resource definitions
if (!name) {
throw new Error('Resource should be specified with a name');
}
if ('string' !== typeof name) {
throw new Error('Resource names should be a `String`');
}
if (!/^(object|function)$/.test(typeof resource)) {
throw new Error('Resource should be an `Object` or `Function`');
}
/**
* Blacklisted event methods.
*/
var blacklistedEvents = [
'constructor',
'init',
'ready',
'connection',
'disconnection'
];
var slice = [].slice;
/**
* Add resource name.
*
* @type {String}
* @api private
*/
resource.resourceName = name;
/**
* Add resource channel.
*
* @type {Channel}
* @api private
*/
resource.channel = primus.channel(name);
/**
* Broadcast a message to all resource clients.
*
* @param {String} event
* @param {Mixed} data
* @api public
*/
resource.broadcast = function brodcast(event, data) {
var args = slice.call(arguments, 1);
resource.channel.forEach(function each(spark, id, connections) {
spark.send.apply(spark, [event].concat(args));
});
};
/**
* Bind connection event.
*
* @param {Spark} spark
* @api private
*/
resource.channel.on('connection', function connection(spark) {
var key, events = [];
for (key in resource) {
if (typeof resource[key] === 'function' && blacklistedEvents.indexOf(key) === -1) {
spark.on(key, resource[key].bind(resource, spark));
events.push(key);
}
}
spark.send('ready', events);
});
// Add resource to resource collection
primus.resources[name] = resource;
return resource;
};
};