Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

radar_client

Package Overview
Dependencies
Maintainers
7
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

radar_client - npm Package Compare versions

Comparing version 0.14.5 to 0.15.0

.gitattributes

8

Changelog.md

@@ -0,1 +1,9 @@

### 0.15.0
* Use radar message library
- significant refactor that changes most of the code underlying the public
APIs, which have *not* been changed
- explicitly extracted the message "library" code in the refactor above to a
separate radar_message library
- pin radar_message version (we'll specify versions of package moving forward)
### 0.14.5

@@ -2,0 +10,0 @@ * Presence resource can set online and include client data (to be broadcasted

378

dist/radar_client.js

@@ -31,3 +31,3 @@ (function(){function require(e,t){for(var n=[],r=e.split("/"),i,s,o=0;s=r[o++];)".."==s?n.pop():"."!=s&&n.push(s);n=n.join("/"),o=require,s=o.m[t||0],i=s[n+".js"]||s[n+"/index.js"]||s[n];if(s=i.c)i=o.m[t=s][e=i.m];return i.exports||i(i,i.exports={},function(n){return o("."!=n.charAt(0)?n:e+"/../"+n,t)}),i.exports};

function getClientVersion() { return '0.14.5'; };
function getClientVersion() { return '0.15.0'; };

@@ -53,3 +53,5 @@ module.exports = getClientVersion;},

function(fn) { setTimeout(fn, 1); },
getClientVersion = require('./client_version.js');
getClientVersion = require('./client_version.js'),
Request = require('radar_message').Request,
Response = require('radar_message').Response;

@@ -65,3 +67,3 @@ function Client(backend) {

this._restoreRequired = false;
this._queuedMessages = [];
this._queuedRequests = [];
this._isConfigured = false;

@@ -162,200 +164,196 @@

// Return the chainable scope object for a given message type
Client.prototype.message = function(scope) {
return new Scope('message:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('message', scope, this);
};
// Access the "presence" chainable operations
Client.prototype.presence = function(scope) {
return new Scope('presence:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('presence', scope, this);
};
// Access the "status" chainable operations
Client.prototype.status = function(scope) {
return new Scope('status:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('status', scope, this);
};
Client.prototype.stream = function(scope) {
return new Scope('stream:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('stream', scope, this);
};
// Access the "control" chainable operations
Client.prototype.control = function(scope) {
return new Scope('control:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('control', scope, this);
};
// Operations
Client.prototype.nameSync = function(scope, options, callback) {
var message = { op: 'nameSync', to: scope };
if (typeof options == 'function') {
callback = options;
} else {
message.options = options;
}
return this._write(message, callback);
var request = Request.buildNameSync(scope, options);
return this._write(request, callback);
};
Client.prototype.push = function(scope, resource, action, value, callback) {
return this._write({
op: 'push',
to: scope,
resource: resource,
action: action,
value: value
}, callback);
var request = Request.buildPush(scope, resource, action, value);
return this._write(request, callback);
};
Client.prototype.set = function(scope, value, clientData, callback) {
var message = {
op: 'set',
to: scope,
value: value,
key: this._configuration.userId,
type: this._configuration.userType
};
var request;
if (typeof(clientData) === 'function') {
callback = clientData;
} else {
message.clientData = clientData;
}
callback = _chooseFunction(clientData, callback);
clientData = _nullIfFunction(clientData);
return this._write(message, callback);
request = Request.buildSet(scope, value,
this._configuration.userId, this._configuration.userType,
clientData);
return this._write(request, callback);
};
Client.prototype.publish = function(scope, value, callback) {
return this._write({
op: 'publish',
to: scope,
value: value
}, callback);
var request = Request.buildPublish(scope, value);
return this._write(request, callback);
};
Client.prototype.subscribe = function(scope, options, callback) {
var message = { op: 'subscribe', to: scope };
if (typeof options == 'function') {
callback = options;
} else {
message.options = options;
}
return this._write(message, callback);
callback = _chooseFunction(options, callback);
options = _nullIfFunction(options);
var request = Request.buildSubscribe(scope, options);
return this._write(request, callback);
};
Client.prototype.unsubscribe = function(scope, callback) {
return this._write({ op: 'unsubscribe', to: scope }, callback);
var request = Request.buildUnsubscribe(scope);
return this._write(request, callback);
};
// Sync and get return the actual value of the operation
var init = function(propertyName) {
Client.prototype[propertyName] = function(scope, options, callback) {
var message = { op: propertyName, to: scope };
// options is an optional argument
if (typeof options == 'function') {
callback = options;
} else {
message.options = options;
// sync returns the actual value of the operation
Client.prototype.sync = function (scope, options, callback) {
var request, onResponse, v1Presence;
callback = _chooseFunction(options, callback);
options = _nullIfFunction(options);
request = Request.buildSync(scope, options);
v1Presence = !options && request.isPresence();
onResponse = function (message) {
var response = new Response(message);
if (response && response.isFor(request)) {
if (v1Presence) {
response.forceV1Response();
}
if (callback) {
callback(response.getMessage());
}
return true;
}
// Sync v1 for presence scopes acts inconsistently. The result should be a
// "get" message, but it is actually a "online" message.
// So force v2 and translate the result to v1 format.
if (propertyName == 'sync' && !message.options && scope.match(/^presence.+/)) {
message.options = { version: 2 };
this.when('get', function(message) {
var value = {}, userId;
if (!message || !message.to || message.to != scope) {
return false;
}
return false;
};
for (userId in message.value) {
if (message.value.hasOwnProperty(userId)) {
// Skip when not defined; causes exception in FF for 'Work Offline'
if (!message.value[userId]) { continue; }
value[userId] = message.value[userId].userType;
}
}
message.value = value;
message.op = 'online';
if (callback) {
callback(message);
}
return true;
});
} else {
this.when('get', function(message) {
if (!message || !message.to || message.to != scope) {
return false;
}
if (callback) {
callback(message);
}
return true;
});
this.when('get', onResponse);
// sync does not return ACK (it sends back a data message)
return this._write(request);
};
// get returns the actual value of the operation
Client.prototype.get = function (scope, options, callback) {
var request;
callback = _chooseFunction(options, callback);
options = _nullIfFunction(options);
request = Request.buildGet(scope, options);
var onResponse = function (message) {
var response = new Response(message);
if (response && response.isFor(request)) {
if (callback) {
callback(response.getMessage());
}
return true;
}
// sync/get never register or return acks (since they always send back a
// data message)
return this._write(message);
return false;
};
this.when('get', onResponse);
// get does not return ACK (it sends back a data message)
return this._write(request);
};
var props = ['get', 'sync'];
for(var i = 0; i < props.length; i++){
init(props[i]);
}
// Private API
var _chooseFunction = function (options, callback) {
return typeof(options) === 'function' ? options : callback;
};
var _nullIfFunction = function (options) {
if (typeof(options) === 'function') {
return null;
}
return options;
};
Client.prototype._addListeners = function () {
// Add authentication data to a message; _write() emits authenticateMessage
// Add authentication data to a request message; _write() emits authenticateMessage
this.on('authenticateMessage', function(message) {
if (this._configuration) {
message.userData = this._configuration.userData;
if (this._configuration.auth) {
message.auth = this._configuration.auth;
message.userId = this._configuration.userId;
message.userType = this._configuration.userType;
message.accountName = this._configuration.accountName;
}
}
this.emit('messageAuthenticated', message);
var request = new Request(message);
request.setAuthData(this._configuration);
this.emit('messageAuthenticated', request.getMessage());
});
// Once the message is authenticated, send it to the server
// Once the request is authenticated, send it to the server
this.on('messageAuthenticated', function(message) {
this._sendMessage(message);
var request = new Request(message);
this._sendMessage(request);
});
};
Client.prototype._write = function(message, callback) {
var client = this;
Client.prototype._write = function(request, callback) {
var self = this;
if (callback) {
message.ack = this._ackCounter++;
request.setAttr('ack', this._ackCounter++);
// Wait ack
this.when('ack', function(m) {
client.logger().debug('ack', m);
if (!m || !m.value || m.value != message.ack) {
return false;
}
callback(message);
this.when('ack', function(message) {
var response = new Response(message);
self.logger().debug('ack', response);
if (!response.isAckFor(request)) { return false; }
callback(request.getMessage());
return true;
});
}
this.emit('authenticateMessage', message);
this.emit('authenticateMessage', request.getMessage());
return this;
};
Client.prototype._batch = function(message) {
if (!(message.to && message.value && message.time)) {
Client.prototype._batch = function(response) {
var to = response.getAttr('to'),
value = response.getAttr('value'),
time = response.getAttr('time');
if (!response.isValid()) {
this.logger().info('response is invalid:', response.getMessage());
return false;
}
var index = 0, data, time,
length = message.value.length,
newest = message.time,
current = this._channelSyncTimes[message.to] || 0;
var index = 0, data,
length = value.length,
newest = time,
current = this._channelSyncTimes[to] || 0;
for (; index < length; index = index + 2) {
data = JSON.parse(message.value[index]);
time = message.value[index + 1];
data = JSON.parse(value[index]);
time = value[index + 1];
if (time > current) {
this.emitNext(message.to, data);
this.emitNext(to, data);
}

@@ -366,21 +364,21 @@ if (time > newest) {

}
this._channelSyncTimes[message.to] = newest;
this._channelSyncTimes[to] = newest;
};
Client.prototype._createManager = function() {
var client = this, manager = this.manager = StateMachine.create();
var self = this, manager = this.manager = StateMachine.create();
manager.on('enterState', function(state) {
client.emit(state);
self.emit(state);
});
manager.on('event', function(event) {
client.emit(event);
self.emit(event);
});
manager.on('connect', function(data) {
var socket = client._socket = new client.backend.Socket(client._configuration);
var socket = self._socket = new self.backend.Socket(self._configuration);
socket.once('open', function() {
client.logger().debug("socket open", socket.id);
self.logger().debug("socket open", socket.id);
manager.established();

@@ -390,5 +388,5 @@ });

socket.once('close', function(reason, description) {
client.logger().debug('socket closed', socket.id, reason, description);
self.logger().debug('socket closed', socket.id, reason, description);
socket.removeAllListeners('message');
client._socket = null;
self._socket = null;

@@ -408,4 +406,4 @@ // Patch for polling-xhr continuing to poll after socket close (HTTP:POST

socket.on('message', function(message) {
client._messageReceived(message);
socket.on('message', function (message) {
self._messageReceived(message);
});

@@ -420,5 +418,5 @@

manager.on('activate', function() {
client._identitySet();
client._restore();
client.emit('ready');
self._identitySet();
self._restore();
self.emit('ready');
});

@@ -432,3 +430,3 @@

manager.on('disconnect', function() {
client._restoreRequired = true;
self._restoreRequired = true;
});

@@ -439,22 +437,30 @@ };

// adds to the memorized subscriptions or presences
Client.prototype._memorize = function(message) {
switch(message.op) {
Client.prototype._memorize = function(request) {
var op = request.getAttr('op'),
to = request.getAttr('to'),
value = request.getAttr('value');
switch(op) {
case 'unsubscribe':
// Remove from queue
if (this._subscriptions[message.to]) {
delete this._subscriptions[message.to];
if (this._subscriptions[to]) {
delete this._subscriptions[to];
}
return true;
case 'sync':
case 'subscribe':
if (this._subscriptions[message.to] != 'sync') {
this._subscriptions[message.to] = message.op;
// A catch for when *subscribe* is called after *sync*
if (this._subscriptions[to] != 'sync') {
this._subscriptions[to] = op;
}
return true;
case 'set':
if (message.to.substr(0, 'presence:/'.length) == 'presence:/') {
this._presences[message.to] = message.value;
if (request.isPresence()) {
this._presences[to] = value;
return true;
}
}
return false;

@@ -464,7 +470,6 @@ };

Client.prototype._restore = function() {
var item, i, to, message, counts = { subscriptions: 0, presences: 0, messages: 0 };
var item, to, counts = { subscriptions: 0, presences: 0, messages: 0 };
if (this._restoreRequired) {
this._restoreRequired = false;
for (to in this._subscriptions) {

@@ -485,4 +490,4 @@ if (this._subscriptions.hasOwnProperty(to)) {

while (this._queuedMessages.length) {
this._write(this._queuedMessages.shift());
while (this._queuedRequests.length) {
this._write(this._queuedRequests.shift());
counts.messages += 1;

@@ -495,12 +500,14 @@ }

Client.prototype._sendMessage = function(message) {
var memorized = this._memorize(message);
this.emit('message:out', message);
Client.prototype._sendMessage = function(request) {
var memorized = this._memorize(request),
ack = request.getAttr('ack');
this.emit('message:out', request.getMessage());
if (this._socket && this.manager.is('activated')) {
this._socket.sendPacket('message', JSON.stringify(message));
this._socket.sendPacket('message', request.payload());
} else if (this._isConfigured) {
this._restoreRequired = true;
if (!memorized || message.ack) {
this._queuedMessages.push(message);
if (!memorized || ack) {
this._queuedRequests.push(request);
}

@@ -512,15 +519,21 @@ this.manager.connectWhenAble();

Client.prototype._messageReceived = function (msg) {
var message = JSON.parse(msg);
this.emit('message:in', message);
switch (message.op) {
var response = new Response(JSON.parse(msg)),
op = response.getAttr('op'),
to = response.getAttr('to');
this.emit('message:in', response.getMessage());
switch (op) {
case 'err':
case 'ack':
case 'get':
this.emitNext(message.op, message);
this.emitNext(op, response.getMessage());
break;
case 'sync':
this._batch(message);
this._batch(response);
break;
default:
this.emitNext(message.to, message);
this.emitNext(to, response.getMessage());
}

@@ -530,4 +543,4 @@ };

Client.prototype.emitNext = function() {
var args = Array.prototype.slice.call(arguments), client = this;
immediate(function(){ client.emit.apply(client, args); });
var args = Array.prototype.slice.call(arguments), self = this;
immediate(function(){ self.emit.apply(self, args); });
};

@@ -544,4 +557,7 @@

var options = { association: association, clientVersion: clientVersion };
var self = this;
this.control('clientName').nameSync(options);
this.control('clientName').nameSync(options, function (message) {
self.logger('nameSync message: ' + JSON.stringify(message));
});
};

@@ -566,5 +582,5 @@

},
"lib/scope.js": function(module, exports, require){function Scope(prefix, client) {
this.prefix = prefix;
"lib/scope.js": function(module, exports, require){function Scope(typeName, scope, client) {
this.client = client;
this.prefix = this._buildScopePrefix(typeName, scope, client.configuration('accountName'));
}

@@ -575,3 +591,3 @@

var init = function(name) {
var init = function (name) {
Scope.prototype[name] = function () {

@@ -585,6 +601,10 @@ var args = Array.prototype.slice.apply(arguments);

for(var i = 0; i < props.length; i++){
for (var i = 0; i < props.length; i++) {
init(props[i]);
}
Scope.prototype._buildScopePrefix = function (typeName, scope, accountName) {
return typeName + ':/' + accountName + '/' + scope;
};
module.exports = Scope;

@@ -591,0 +611,0 @@ },

// Auto-generated file, overwritten by scripts/add_package_version.js
function getClientVersion() { return '0.14.5'; };
function getClientVersion() { return '0.15.0'; };
module.exports = getClientVersion;

@@ -8,3 +8,5 @@ /* globals setImmediate */

function(fn) { setTimeout(fn, 1); },
getClientVersion = require('./client_version.js');
getClientVersion = require('./client_version.js'),
Request = require('radar_message').Request,
Response = require('radar_message').Response;

@@ -20,3 +22,3 @@ function Client(backend) {

this._restoreRequired = false;
this._queuedMessages = [];
this._queuedRequests = [];
this._isConfigured = false;

@@ -117,200 +119,196 @@

// Return the chainable scope object for a given message type
Client.prototype.message = function(scope) {
return new Scope('message:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('message', scope, this);
};
// Access the "presence" chainable operations
Client.prototype.presence = function(scope) {
return new Scope('presence:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('presence', scope, this);
};
// Access the "status" chainable operations
Client.prototype.status = function(scope) {
return new Scope('status:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('status', scope, this);
};
Client.prototype.stream = function(scope) {
return new Scope('stream:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('stream', scope, this);
};
// Access the "control" chainable operations
Client.prototype.control = function(scope) {
return new Scope('control:/'+this._configuration.accountName+'/'+scope, this);
return new Scope('control', scope, this);
};
// Operations
Client.prototype.nameSync = function(scope, options, callback) {
var message = { op: 'nameSync', to: scope };
if (typeof options == 'function') {
callback = options;
} else {
message.options = options;
}
return this._write(message, callback);
var request = Request.buildNameSync(scope, options);
return this._write(request, callback);
};
Client.prototype.push = function(scope, resource, action, value, callback) {
return this._write({
op: 'push',
to: scope,
resource: resource,
action: action,
value: value
}, callback);
var request = Request.buildPush(scope, resource, action, value);
return this._write(request, callback);
};
Client.prototype.set = function(scope, value, clientData, callback) {
var message = {
op: 'set',
to: scope,
value: value,
key: this._configuration.userId,
type: this._configuration.userType
};
var request;
if (typeof(clientData) === 'function') {
callback = clientData;
} else {
message.clientData = clientData;
}
callback = _chooseFunction(clientData, callback);
clientData = _nullIfFunction(clientData);
return this._write(message, callback);
request = Request.buildSet(scope, value,
this._configuration.userId, this._configuration.userType,
clientData);
return this._write(request, callback);
};
Client.prototype.publish = function(scope, value, callback) {
return this._write({
op: 'publish',
to: scope,
value: value
}, callback);
var request = Request.buildPublish(scope, value);
return this._write(request, callback);
};
Client.prototype.subscribe = function(scope, options, callback) {
var message = { op: 'subscribe', to: scope };
if (typeof options == 'function') {
callback = options;
} else {
message.options = options;
}
return this._write(message, callback);
callback = _chooseFunction(options, callback);
options = _nullIfFunction(options);
var request = Request.buildSubscribe(scope, options);
return this._write(request, callback);
};
Client.prototype.unsubscribe = function(scope, callback) {
return this._write({ op: 'unsubscribe', to: scope }, callback);
var request = Request.buildUnsubscribe(scope);
return this._write(request, callback);
};
// Sync and get return the actual value of the operation
var init = function(propertyName) {
Client.prototype[propertyName] = function(scope, options, callback) {
var message = { op: propertyName, to: scope };
// options is an optional argument
if (typeof options == 'function') {
callback = options;
} else {
message.options = options;
// sync returns the actual value of the operation
Client.prototype.sync = function (scope, options, callback) {
var request, onResponse, v1Presence;
callback = _chooseFunction(options, callback);
options = _nullIfFunction(options);
request = Request.buildSync(scope, options);
v1Presence = !options && request.isPresence();
onResponse = function (message) {
var response = new Response(message);
if (response && response.isFor(request)) {
if (v1Presence) {
response.forceV1Response();
}
if (callback) {
callback(response.getMessage());
}
return true;
}
// Sync v1 for presence scopes acts inconsistently. The result should be a
// "get" message, but it is actually a "online" message.
// So force v2 and translate the result to v1 format.
if (propertyName == 'sync' && !message.options && scope.match(/^presence.+/)) {
message.options = { version: 2 };
this.when('get', function(message) {
var value = {}, userId;
if (!message || !message.to || message.to != scope) {
return false;
}
return false;
};
for (userId in message.value) {
if (message.value.hasOwnProperty(userId)) {
// Skip when not defined; causes exception in FF for 'Work Offline'
if (!message.value[userId]) { continue; }
value[userId] = message.value[userId].userType;
}
}
message.value = value;
message.op = 'online';
if (callback) {
callback(message);
}
return true;
});
} else {
this.when('get', function(message) {
if (!message || !message.to || message.to != scope) {
return false;
}
if (callback) {
callback(message);
}
return true;
});
this.when('get', onResponse);
// sync does not return ACK (it sends back a data message)
return this._write(request);
};
// get returns the actual value of the operation
Client.prototype.get = function (scope, options, callback) {
var request;
callback = _chooseFunction(options, callback);
options = _nullIfFunction(options);
request = Request.buildGet(scope, options);
var onResponse = function (message) {
var response = new Response(message);
if (response && response.isFor(request)) {
if (callback) {
callback(response.getMessage());
}
return true;
}
// sync/get never register or return acks (since they always send back a
// data message)
return this._write(message);
return false;
};
this.when('get', onResponse);
// get does not return ACK (it sends back a data message)
return this._write(request);
};
var props = ['get', 'sync'];
for(var i = 0; i < props.length; i++){
init(props[i]);
}
// Private API
var _chooseFunction = function (options, callback) {
return typeof(options) === 'function' ? options : callback;
};
var _nullIfFunction = function (options) {
if (typeof(options) === 'function') {
return null;
}
return options;
};
Client.prototype._addListeners = function () {
// Add authentication data to a message; _write() emits authenticateMessage
// Add authentication data to a request message; _write() emits authenticateMessage
this.on('authenticateMessage', function(message) {
if (this._configuration) {
message.userData = this._configuration.userData;
if (this._configuration.auth) {
message.auth = this._configuration.auth;
message.userId = this._configuration.userId;
message.userType = this._configuration.userType;
message.accountName = this._configuration.accountName;
}
}
this.emit('messageAuthenticated', message);
var request = new Request(message);
request.setAuthData(this._configuration);
this.emit('messageAuthenticated', request.getMessage());
});
// Once the message is authenticated, send it to the server
// Once the request is authenticated, send it to the server
this.on('messageAuthenticated', function(message) {
this._sendMessage(message);
var request = new Request(message);
this._sendMessage(request);
});
};
Client.prototype._write = function(message, callback) {
var client = this;
Client.prototype._write = function(request, callback) {
var self = this;
if (callback) {
message.ack = this._ackCounter++;
request.setAttr('ack', this._ackCounter++);
// Wait ack
this.when('ack', function(m) {
client.logger().debug('ack', m);
if (!m || !m.value || m.value != message.ack) {
return false;
}
callback(message);
this.when('ack', function(message) {
var response = new Response(message);
self.logger().debug('ack', response);
if (!response.isAckFor(request)) { return false; }
callback(request.getMessage());
return true;
});
}
this.emit('authenticateMessage', message);
this.emit('authenticateMessage', request.getMessage());
return this;
};
Client.prototype._batch = function(message) {
if (!(message.to && message.value && message.time)) {
Client.prototype._batch = function(response) {
var to = response.getAttr('to'),
value = response.getAttr('value'),
time = response.getAttr('time');
if (!response.isValid()) {
this.logger().info('response is invalid:', response.getMessage());
return false;
}
var index = 0, data, time,
length = message.value.length,
newest = message.time,
current = this._channelSyncTimes[message.to] || 0;
var index = 0, data,
length = value.length,
newest = time,
current = this._channelSyncTimes[to] || 0;
for (; index < length; index = index + 2) {
data = JSON.parse(message.value[index]);
time = message.value[index + 1];
data = JSON.parse(value[index]);
time = value[index + 1];
if (time > current) {
this.emitNext(message.to, data);
this.emitNext(to, data);
}

@@ -321,21 +319,21 @@ if (time > newest) {

}
this._channelSyncTimes[message.to] = newest;
this._channelSyncTimes[to] = newest;
};
Client.prototype._createManager = function() {
var client = this, manager = this.manager = StateMachine.create();
var self = this, manager = this.manager = StateMachine.create();
manager.on('enterState', function(state) {
client.emit(state);
self.emit(state);
});
manager.on('event', function(event) {
client.emit(event);
self.emit(event);
});
manager.on('connect', function(data) {
var socket = client._socket = new client.backend.Socket(client._configuration);
var socket = self._socket = new self.backend.Socket(self._configuration);
socket.once('open', function() {
client.logger().debug("socket open", socket.id);
self.logger().debug("socket open", socket.id);
manager.established();

@@ -345,5 +343,5 @@ });

socket.once('close', function(reason, description) {
client.logger().debug('socket closed', socket.id, reason, description);
self.logger().debug('socket closed', socket.id, reason, description);
socket.removeAllListeners('message');
client._socket = null;
self._socket = null;

@@ -363,4 +361,4 @@ // Patch for polling-xhr continuing to poll after socket close (HTTP:POST

socket.on('message', function(message) {
client._messageReceived(message);
socket.on('message', function (message) {
self._messageReceived(message);
});

@@ -375,5 +373,5 @@

manager.on('activate', function() {
client._identitySet();
client._restore();
client.emit('ready');
self._identitySet();
self._restore();
self.emit('ready');
});

@@ -387,3 +385,3 @@

manager.on('disconnect', function() {
client._restoreRequired = true;
self._restoreRequired = true;
});

@@ -394,22 +392,30 @@ };

// adds to the memorized subscriptions or presences
Client.prototype._memorize = function(message) {
switch(message.op) {
Client.prototype._memorize = function(request) {
var op = request.getAttr('op'),
to = request.getAttr('to'),
value = request.getAttr('value');
switch(op) {
case 'unsubscribe':
// Remove from queue
if (this._subscriptions[message.to]) {
delete this._subscriptions[message.to];
if (this._subscriptions[to]) {
delete this._subscriptions[to];
}
return true;
case 'sync':
case 'subscribe':
if (this._subscriptions[message.to] != 'sync') {
this._subscriptions[message.to] = message.op;
// A catch for when *subscribe* is called after *sync*
if (this._subscriptions[to] != 'sync') {
this._subscriptions[to] = op;
}
return true;
case 'set':
if (message.to.substr(0, 'presence:/'.length) == 'presence:/') {
this._presences[message.to] = message.value;
if (request.isPresence()) {
this._presences[to] = value;
return true;
}
}
return false;

@@ -419,7 +425,6 @@ };

Client.prototype._restore = function() {
var item, i, to, message, counts = { subscriptions: 0, presences: 0, messages: 0 };
var item, to, counts = { subscriptions: 0, presences: 0, messages: 0 };
if (this._restoreRequired) {
this._restoreRequired = false;
for (to in this._subscriptions) {

@@ -440,4 +445,4 @@ if (this._subscriptions.hasOwnProperty(to)) {

while (this._queuedMessages.length) {
this._write(this._queuedMessages.shift());
while (this._queuedRequests.length) {
this._write(this._queuedRequests.shift());
counts.messages += 1;

@@ -450,12 +455,14 @@ }

Client.prototype._sendMessage = function(message) {
var memorized = this._memorize(message);
this.emit('message:out', message);
Client.prototype._sendMessage = function(request) {
var memorized = this._memorize(request),
ack = request.getAttr('ack');
this.emit('message:out', request.getMessage());
if (this._socket && this.manager.is('activated')) {
this._socket.sendPacket('message', JSON.stringify(message));
this._socket.sendPacket('message', request.payload());
} else if (this._isConfigured) {
this._restoreRequired = true;
if (!memorized || message.ack) {
this._queuedMessages.push(message);
if (!memorized || ack) {
this._queuedRequests.push(request);
}

@@ -467,15 +474,21 @@ this.manager.connectWhenAble();

Client.prototype._messageReceived = function (msg) {
var message = JSON.parse(msg);
this.emit('message:in', message);
switch (message.op) {
var response = new Response(JSON.parse(msg)),
op = response.getAttr('op'),
to = response.getAttr('to');
this.emit('message:in', response.getMessage());
switch (op) {
case 'err':
case 'ack':
case 'get':
this.emitNext(message.op, message);
this.emitNext(op, response.getMessage());
break;
case 'sync':
this._batch(message);
this._batch(response);
break;
default:
this.emitNext(message.to, message);
this.emitNext(to, response.getMessage());
}

@@ -485,4 +498,4 @@ };

Client.prototype.emitNext = function() {
var args = Array.prototype.slice.call(arguments), client = this;
immediate(function(){ client.emit.apply(client, args); });
var args = Array.prototype.slice.call(arguments), self = this;
immediate(function(){ self.emit.apply(self, args); });
};

@@ -499,4 +512,7 @@

var options = { association: association, clientVersion: clientVersion };
var self = this;
this.control('clientName').nameSync(options);
this.control('clientName').nameSync(options, function (message) {
self.logger('nameSync message: ' + JSON.stringify(message));
});
};

@@ -503,0 +519,0 @@

@@ -1,4 +0,4 @@

function Scope(prefix, client) {
this.prefix = prefix;
function Scope(typeName, scope, client) {
this.client = client;
this.prefix = this._buildScopePrefix(typeName, scope, client.configuration('accountName'));
}

@@ -9,3 +9,3 @@

var init = function(name) {
var init = function (name) {
Scope.prototype[name] = function () {

@@ -19,6 +19,10 @@ var args = Array.prototype.slice.apply(arguments);

for(var i = 0; i < props.length; i++){
for (var i = 0; i < props.length; i++) {
init(props[i]);
}
Scope.prototype._buildScopePrefix = function (typeName, scope, accountName) {
return typeName + ':/' + accountName + '/' + scope;
};
module.exports = Scope;
{
"name": "radar_client",
"description": "Realtime apps with a high level API based on engine.io",
"version": "0.14.5",
"version": "0.15.0",
"author": "Mikito Takada <mikito.takada@gmail.com>",

@@ -36,3 +36,4 @@ "contributors": [

"engine.io-client": "1.4.2",
"sfsm": "0.0.4"
"sfsm": "0.0.4",
"radar_message": "1.0.1"
},

@@ -39,0 +40,0 @@ "devDependencies": {

var assert = require('assert'),
RadarClient = require('../lib/radar_client.js'),
MockEngine = require('./lib/engine.js'),
Response = require('radar_message').Response,
client;

@@ -75,4 +76,4 @@

assert.equal(MockEngine.current._written.length, 1);
assert.equal(client._queuedMessages.length, 1);
assert.deepEqual(client._queuedMessages[0], {
assert.equal(client._queuedRequests.length, 1);
assert.deepEqual(client._queuedRequests[0].message, {
op: 'set',

@@ -83,4 +84,3 @@ to: 'status:/test/tickets/21',

type: 2,
userData: undefined,
clientData: undefined
userData: undefined
});

@@ -91,3 +91,3 @@ });

assert.ok(connected);
assert.equal(client._queuedMessages.length, 0);
assert.equal(client._queuedRequests.length, 0);
assert.ok(

@@ -304,3 +304,3 @@ MockEngine.current._written.some(function(message) {

'if a authentication token is set, it gets sent on each operation': function(done) {
client.configure({ userId: 123, accountName: 'dev', auth: 'AUTH'});
client.configure({ userId: 123, accountName: 'dev', auth: 'AUTH', userType: 2 });
client.message('user/123').publish('hello world');

@@ -323,7 +323,9 @@

'synchronization batch filters out duplicate messages to the same channel by time': function(done) {
var received = [];
var received = [],
msg1, msg2, response1, response2;
client.on('foo', function(msg) {
received.push(msg);
});
client._batch({
msg1 = {
op: 'subscribe',
to: 'foo',

@@ -339,4 +341,8 @@ value: [

time: 1
});
client._batch({
};
response1 = new Response(msg1);
client._batch(response1);
msg2 = {
op: 'subscribe',
to: 'foo',

@@ -352,3 +358,6 @@ value: [

time: 2
});
};
response2 = new Response(msg2);
client._batch(response2);
setTimeout(function() {

@@ -355,0 +364,0 @@ assert.equal(4, received.length);

var assert = require('assert'),
RadarClient = require('../lib/radar_client.js'),
MockEngine = require('./lib/engine.js'),
Request = require('radar_message').Request,
Response = require('radar_message').Response,
HOUR = 1000 * 60 * 60,

@@ -127,5 +129,5 @@ client;

client._write = function(hash, fn) {
client._write = function(request, fn) {
called = true;
assert.deepEqual(hash, {
assert.deepEqual(request.getMessage(), {
op: 'set',

@@ -151,3 +153,3 @@ to: 'status:/test/account/1',

assert.ok(!client.manager.is('activated'));
assert.equal(client._queuedMessages.length, 0);
assert.equal(client._queuedRequests.length, 0);
assert.deepEqual(client._presences, { 'presence:/test/account/1': 'online' });

@@ -162,3 +164,3 @@ },

assert.ok(!client.manager.is('activated'));
assert.equal(client._queuedMessages.length, 1);
assert.equal(client._queuedRequests.length, 1);
assert.deepEqual(client._presences, { 'presence:/test/account/1': 'online' });

@@ -172,7 +174,7 @@ }

client._write = function(hash, fn) {
client._write = function(request, fn) {
called = true;
assert.deepEqual(hash, {
assert.deepEqual(request.getMessage(), {
op: 'publish',
to: 'status:/test/account/1',
to: 'message:/test/account/1',
value: 'whatever'

@@ -184,3 +186,3 @@ });

client.configure({ accountName: 'test', userId: 123, userType: 0 });
client.publish('status:/test/account/1', 'whatever', callback);
client.publish('message:/test/account/1', 'whatever', callback);
assert.ok(called);

@@ -194,7 +196,7 @@ }

client._write = function(hash, fn) {
client._write = function(request, fn) {
called = true;
assert.deepEqual(hash, {
assert.deepEqual(request.getMessage(), {
op: 'subscribe',
to: 'status:/test/account/1',
to: 'status:/test/account/1'
});

@@ -215,3 +217,3 @@ assert.equal(fn, callback);

assert.ok(!client.manager.is('activated'));
assert.equal(client._queuedMessages.length, 0);
assert.equal(client._queuedRequests.length, 0);
assert.deepEqual(client._subscriptions, { 'status:/test/account/1': 'subscribe' });

@@ -226,3 +228,3 @@ },

assert.ok(!client.manager.is('activated'));
assert.equal(client._queuedMessages.length, 1);
assert.equal(client._queuedRequests.length, 1);
assert.deepEqual(client._subscriptions, { 'status:/test/account/1': 'subscribe' });

@@ -237,3 +239,3 @@ },

assert.ok(!client.manager.is('activated'));
assert.equal(client._queuedMessages.length, 0);
assert.equal(client._queuedRequests.length, 0);
assert.deepEqual(client._subscriptions, { 'presence:/test/account/1': 'sync' });

@@ -247,5 +249,5 @@ }

client._write = function(hash, fn) {
client._write = function(request, fn) {
called = true;
assert.deepEqual(hash, {
assert.deepEqual(request.getMessage(), {
op: 'unsubscribe',

@@ -268,3 +270,3 @@ to: 'status:/test/account/1',

assert.ok(!client.manager.is('activated'));
assert.equal(client._queuedMessages.length, 0);
assert.equal(client._queuedRequests.length, 0);
assert.deepEqual(client._subscriptions, {});

@@ -279,3 +281,3 @@ },

assert.ok(!client.manager.is('activated'));
assert.equal(client._queuedMessages.length, 1);
assert.equal(client._queuedRequests.length, 1);
assert.deepEqual(client._subscriptions, {});

@@ -289,8 +291,7 @@ }

client._write = function(hash) {
client._write = function(request) {
called = true;
assert.deepEqual(hash, {
assert.deepEqual(request.getMessage(), {
op: 'get',
to: 'status:/test/account/1',
options: undefined
to: 'status:/test/account/1'
});

@@ -319,3 +320,3 @@ };

scope = 'status:/test/account/1',
message = { to: scope },
message = { op: 'get', to: scope },
callback = function(msg) {

@@ -339,3 +340,3 @@ passed = true;

passed = true,
message = { to: 'status:/test/account/2' },
message = { op: 'get', to: 'status:/test/account/2' },
callback = function(msg) {

@@ -360,8 +361,7 @@ passed = false;

client._write = function(hash) {
client._write = function(request) {
called = true;
assert.deepEqual(hash, {
assert.deepEqual(request.getMessage(), {
op: 'sync',
to: 'status:/test/account/1',
options: undefined
to: 'status:/test/account/1'
});

@@ -391,3 +391,3 @@ };

scope = 'presence:/test/account/1',
message = { to: scope },
message = { op: 'sync', to: scope },
callback = function(msg) {

@@ -411,3 +411,4 @@ passed = true;

passed = true,
message = { to: 'presence:/test/account/2' },
message = { op: 'sync', to: 'presence:/test/account/2' },
response = new Response(message),
callback = function(msg) {

@@ -419,3 +420,3 @@ passed = false;

called = true;
fn(message);
fn(response);
};

@@ -448,3 +449,3 @@

client.emit('get', {
var message = {
op: 'get', to: scope,

@@ -455,3 +456,5 @@ value: {

}
});
};
client.emit('get', message);
}

@@ -461,14 +464,18 @@ }

'internal methods': {
'_memorize' : {
'memorizing a sync/subscribe should work': function(done) {
var request;
assert.equal(0, Object.keys(client._subscriptions).length);
client._memorize({ op: 'subscribe', to: 'foo'});
request = Request.buildSubscribe('presence:/test/ticket/1');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
client._memorize({ op: 'sync', to: 'bar'});
request = Request.buildSync('status:/test/ticket/1');
client._memorize(request);
assert.equal(2, Object.keys(client._subscriptions).length);
client._memorize({ op: 'get', to: 'bar' });
request = Request.buildGet('status:/test/ticket/1');
client._memorize(request);
// Should be a no-op

@@ -481,11 +488,15 @@ assert.equal(2, Object.keys(client._subscriptions).length);

'memorizing a set(online) and unmemorizing a set(offline) should work': function(done) {
var request;
assert.equal(0, Object.keys(client._presences).length);
client._memorize({ op: 'set', to: 'presence:/foo/bar', value: 'online' });
request = Request.buildSet('presence:/foo/bar', 'online');
client._memorize(request);
assert.equal('online', client._presences['presence:/foo/bar']);
assert.equal(1, Object.keys(client._presences).length);
// Duplicate should be ignored
client._memorize({ op: 'set', to: 'presence:/foo/bar', value: 'online' });
client._memorize(request);
assert.equal(1, Object.keys(client._presences).length);
client._memorize({ op: 'set', to: 'presence:/foo/bar', value: 'offline' });
request = Request.buildSet('presence:/foo/bar', 'offline');
client._memorize(request);
assert.equal(1, Object.keys(client._presences).length);

@@ -498,9 +509,14 @@ assert.equal('offline', client._presences['presence:/foo/bar']);

// Set up
client._memorize({ op: 'subscribe', to: 'foo'});
client._memorize({ op: 'sync', to: 'bar'});
var request = Request.buildSubscribe('status:/test/ticket/1');
client._memorize(request);
request = Request.buildSync('status:/test/ticket/2');
client._memorize(request);
assert.equal(2, Object.keys(client._subscriptions).length);
// Unsubscribe
client._memorize({ op: 'unsubscribe', to: 'foo'});
request = Request.buildUnsubscribe('status:/test/ticket/1');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
client._memorize({ op: 'unsubscribe', to: 'bar'});
request = Request.buildUnsubscribe('status:/test/ticket/2');
client._memorize(request);
assert.equal(0, Object.keys(client._subscriptions).length);

@@ -512,5 +528,6 @@ done();

// Simple duplicates
client._memorize({ op: 'subscribe', to: 'foo'});
var request = Request.buildSubscribe('status:/test/ticket/1');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
client._memorize({ op: 'subscribe', to: 'foo'});
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);

@@ -521,5 +538,6 @@

// Simple duplicates
client._memorize({ op: 'sync', to: 'abc'});
request = Request.buildSync('status:/test/ticket/2');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
client._memorize({ op: 'sync', to: 'abc'});
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);

@@ -529,17 +547,21 @@

// Sync after subscribe
client._memorize({ op: 'sync', to: 'bar'});
request = Request.buildSubscribe('status:/test/ticket/3');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
client._memorize({ op: 'sync', to: 'bar'});
request = Request.buildSync('status:/test/ticket/3');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
assert.equal('sync', client._subscriptions.bar);
assert.equal('sync', client._subscriptions['status:/test/ticket/3']);
client._subscriptions = {};
// Subscribe after sync
client._memorize({ op: 'sync', to: 'baz'});
request = Request.buildSync('status:/test/ticket/4');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
assert.equal('sync', client._subscriptions.baz);
assert.equal('sync', client._subscriptions['status:/test/ticket/4']);
// When we sync and subscribe, it means just sync
client._memorize({ op: 'subscribe', to: 'baz'});
request = Request.buildSubscribe('status:/test/ticket/4');
client._memorize(request);
assert.equal(1, Object.keys(client._subscriptions).length);
assert.equal('sync', client._subscriptions.baz);
assert.equal('sync', client._subscriptions['status:/test/ticket/4']);

@@ -549,7 +571,10 @@ done();

},
'_restore' : {
'restore presences' : function(done){
MockEngine.current._written = [];
client._memorize({ op: 'set', to: 'presence:/foo/bar', value: 'online' });
client._memorize({ op: 'set', to: 'presence:/foo/bar2', value: 'offline' });
var request = Request.buildSet('presence:/foo/bar', 'online');
client._memorize(request);
request = Request.buildSet('presence:/foo/bar2', 'offline');
client._memorize(request);
client._restoreRequired = true;

@@ -572,6 +597,9 @@ client.configure({ accountName: 'foo', userId: 123, userType: 2 });

},
'restore subscriptions' : function(done){
MockEngine.current._written = [];
client._memorize({ op: 'subscribe', to: 'status:/foo/bar' });
client._memorize({ op: 'subscribe', to: 'message:/foo/bar2' });
var request = Request.buildSubscribe('status:/foo/bar');
client._memorize(request);
request = Request.buildSubscribe('message:/foo/bar2');
client._memorize(request);
client._restoreRequired = true;

@@ -596,3 +624,4 @@ client.configure({ accountName: 'foo', userId: 123, userType: 2 });

var called = false,
message = { op: 'something', to: 'wherever:/account/scope/1' };
message = { op: 'subscribe', to: 'status:/account/scope/1'},
request = Request.buildSubscribe(message.to);

@@ -605,3 +634,4 @@ client.emit = function(name, data) {

client._write(message);
//client._write(request.getMessage());
client._write(request);
assert.ok(called);

@@ -613,7 +643,7 @@ },

passed = false,
message = { op: 'something', to: 'wherever:/account/scope/1' },
request = Request.buildSubscribe('status:/account/scope/1'),
ackMessage = { value: -2 },
callback = function(msg) {
passed = true;
assert.deepEqual(msg, message);
assert.deepEqual(msg, request.getMessage());
};

@@ -624,7 +654,8 @@

assert.equal(name, 'ack');
ackMessage.value = message.ack;
ackMessage.op = 'ack';
ackMessage.value = request.getAttr('ack');
fn(ackMessage);
};
client._write(message, callback);
client._write(request, callback);
assert.ok(called);

@@ -637,4 +668,5 @@ assert.ok(passed);

passed = true,
message = { op: 'something', to: 'wherever:/account/scope/1' },
ackMessage = { value: -2 },
request = Request.buildSubscribe('status:/account/scope/1'),
ackMessage = { op: 'ack', value: -2 },
response = new Response(ackMessage),
callback = function(msg) { passed = false; };

@@ -645,6 +677,6 @@

assert.equal(name, 'ack');
fn(message);
fn(response);
};
client._write(message, callback);
client._write(request, callback);
assert.ok(called);

@@ -657,4 +689,15 @@ assert.ok(passed);

'should ignore messages without the appropriate properties': {
'op': function() {
var message = { to: 'status:/dev/ticket/1', value: 'x', time: new Date() / 1000 },
response;
response = new Response(message);
assert.deepEqual(client._channelSyncTimes, {});
},
'to': function() {
assert.ok(!client._batch({ value: 'x', time: new Date() / 1000 }));
var message = { op: 'subscribe', value: 'x', time: new Date() / 1000 },
response;
response = new Response(message);
assert.deepEqual(client._channelSyncTimes, {});

@@ -664,4 +707,7 @@ },

'value': function() {
var message = { op: 'subscribe', to: 'you', value: 'x'},
response = new Response(message);
assert.equal(client._channelSyncTimes.you, undefined);
assert.ok(!client._batch({ value: 'x', to: 'you' }));
assert.ok(!client._batch(response));
assert.equal(client._channelSyncTimes.you, undefined);

@@ -671,4 +717,7 @@ },

'time': function() {
var message = { op: 'subscribe', to: 'you', value: 'x' },
response = new Response(message);
assert.equal(client._channelSyncTimes.you, undefined);
assert.ok(!client._batch({ value: 'x', to: 'you' }));
assert.ok(!client._batch(response));
assert.equal(client._channelSyncTimes.you, undefined);

@@ -681,9 +730,11 @@ }

message = {
op: 'subscribe',
to: 'you',
value: [ '{}', now ],
time: now
};
},
response = new Response(message);
assert.equal(client._channelSyncTimes.you, undefined);
assert.notEqual(client._batch(message), false);
assert.notEqual(client._batch(response), false);
assert.equal(client._channelSyncTimes.you, now);

@@ -696,6 +747,8 @@ },

message = {
op: 'subscribe',
to: 'you',
value: [ '{ "something": 1 }', now ],
time: now
};
},
response = new Response(message);

@@ -706,7 +759,7 @@ client._channelSyncTimes.you = now - HOUR;

called = true;
assert.equal(name, message.to);
assert.deepEqual(data, JSON.parse(message.value[0]));
assert.equal(name, response.getAttr('to'));
assert.deepEqual(data, JSON.parse(response.getAttr('value')[0]));
};
assert.notEqual(client._batch(message), false);
assert.notEqual(client._batch(response), false);
assert.equal(client._channelSyncTimes.you, now);

@@ -874,3 +927,3 @@ assert.ok(called);

while (count < 10) {
client._queuedMessages.push({ test: count++ });
client._queuedRequests.push({ test: count++ });
}

@@ -911,3 +964,3 @@

var called = false,
message = { test: 1 };
request = Request.buildSubscribe('status:/test/ticket/1');

@@ -920,7 +973,7 @@ client.manager.is = function(state) { return state == 'activated'; };

assert.equal(name, 'message');
assert.equal(data, JSON.stringify(message));
assert.equal(data, JSON.stringify(request.getMessage()));
}
};
client._sendMessage(message);
client._sendMessage(request);
assert.ok(called);

@@ -930,15 +983,15 @@ },

'should queue the message if the client has been configured, but is not activated': function() {
var message = { test: 1 };
var request = Request.buildSet('status:/test/ticket/1', 'any_value');
client.configure({});
client._sendMessage(message);
assert.deepEqual(message, client._queuedMessages[0]);
client._sendMessage(request);
assert.deepEqual(request, client._queuedRequests[0]);
},
'should ignore the message if the client has not been configured': function() {
var message = { test: 1 };
var request = Request.buildSet('status:/test/ticket/1', 'any_value');
assert.ok(!client._isConfigured);
client._sendMessage(message);
assert.equal(client._queuedMessages.length, 0);
client._sendMessage(request);
assert.equal(client._queuedRequests.length, 0);
}

@@ -971,2 +1024,3 @@ },

op: 'ack',
value: 1
},

@@ -990,2 +1044,3 @@ json = JSON.stringify(message);

op: 'get',
to: 'staus:/test/ticket/1'
},

@@ -1009,2 +1064,3 @@ json = JSON.stringify(message);

op: 'sync',
to: 'staus:/test/ticket/1'
},

@@ -1015,3 +1071,3 @@ json = JSON.stringify(message);

called = true;
assert.deepEqual(msg, message);
assert.deepEqual(msg.message, message);
};

@@ -1018,0 +1074,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc