Comparing version 0.8.41 to 0.8.42
{ | ||
"name": "Ably", | ||
"version": "0.8.41", | ||
"version": "0.8.42", | ||
"homepage": "https://www.ably.io/", | ||
@@ -5,0 +5,0 @@ "authors": [ |
/** | ||
* @license Copyright 2016, Ably | ||
* @license Copyright 2017, Ably | ||
* | ||
* Ably JavaScript Library v0.8.41 | ||
* Ably JavaScript Library v0.8.42 | ||
* https://github.com/ably/ably-js | ||
@@ -6,0 +6,0 @@ * |
@@ -359,2 +359,18 @@ var RealtimePresence = (function() { | ||
function newerThan(item, existing) { | ||
/* RTP2b1: if either is synthesised, compare by timestamp */ | ||
if(item.isSynthesized() || existing.isSynthesized()) { | ||
return item.timestamp > existing.timestamp; | ||
} | ||
/* RTP2b2 */ | ||
var itemOrderings = item.parseId(), | ||
existingOrderings = existing.parseId(); | ||
if(itemOrderings.msgSerial === existingOrderings.msgSerial) { | ||
return itemOrderings.index > existingOrderings.index; | ||
} else { | ||
return itemOrderings.msgSerial > existingOrderings.msgSerial; | ||
} | ||
} | ||
PresenceMap.prototype.put = function(item) { | ||
@@ -372,7 +388,4 @@ if(item.action === 'enter' || item.action === 'update') { | ||
var existingItem = map[key]; | ||
if(existingItem) { | ||
/* no item supersedes a newer item with the same key */ | ||
if(item.id <= existingItem.id) { | ||
return false; | ||
} | ||
if(existingItem && !newerThan(item, existingItem)) { | ||
return false; | ||
} | ||
@@ -379,0 +392,0 @@ map[key] = item; |
@@ -26,2 +26,22 @@ var PresenceMessage = (function() { | ||
/* Returns whether this presenceMessage is synthesized, i.e. was not actually | ||
* sent by the connection (usually means a leave event sent 15s after a | ||
* disconnection). This is useful because synthesized messages cannot be | ||
* compared for newness by id lexicographically - RTP2b1 | ||
*/ | ||
PresenceMessage.prototype.isSynthesized = function() { | ||
return this.id.substring(this.connectionId.length, 0) !== this.connectionId; | ||
}; | ||
/* RTP2b2 */ | ||
PresenceMessage.prototype.parseId = function() { | ||
var parts = this.id.split(':'); | ||
return { | ||
connectionId: parts[0], | ||
msgSerial: parseInt(parts[1], 10), | ||
index: parseInt(parts[2], 10) | ||
}; | ||
}; | ||
/** | ||
@@ -28,0 +48,0 @@ * Overload toJSON() to intercept JSON.stringify() |
@@ -22,3 +22,3 @@ Defaults.protocolVersion = 1; | ||
Defaults.version = '0.8.41'; | ||
Defaults.version = '0.8.42'; | ||
Defaults.libstring = 'js-' + Defaults.version; | ||
@@ -25,0 +25,0 @@ Defaults.apiVersion = '0.8'; |
@@ -137,21 +137,24 @@ var EventEmitter = (function() { | ||
var eventThis = {event:event}; | ||
var listeners = []; | ||
if(this.anyOnce.length) { | ||
var listeners = this.anyOnce; | ||
Array.prototype.push.apply(listeners, this.anyOnce); | ||
this.anyOnce = []; | ||
for(var i = 0; i < listeners.length; i++) | ||
callListener(eventThis, listeners[i], args); | ||
} | ||
for(var i = 0; i < this.any.length; i++) | ||
this.any[i].apply(eventThis, args); | ||
var listeners = this.eventsOnce[event]; | ||
if(listeners) { | ||
if(this.any.length) { | ||
Array.prototype.push.apply(listeners, this.any); | ||
} | ||
var eventsOnceListeners = this.eventsOnce[event]; | ||
if(eventsOnceListeners) { | ||
Array.prototype.push.apply(listeners, eventsOnceListeners); | ||
delete this.eventsOnce[event]; | ||
for(var i = 0; i < listeners.length; i++) | ||
callListener(eventThis, listeners[i], args); | ||
} | ||
var listeners = this.events[event]; | ||
if(listeners) | ||
for(var i = 0; i < listeners.length; i++) | ||
callListener(eventThis, listeners[i], args); | ||
var eventsListeners = this.events[event]; | ||
if(eventsListeners) { | ||
Array.prototype.push.apply(listeners, eventsListeners); | ||
} | ||
Utils.arrForEach(listeners, function(listener) { | ||
callListener(eventThis, listener, args); | ||
}); | ||
}; | ||
@@ -158,0 +161,0 @@ |
{ | ||
"name": "ably", | ||
"description": "Realtime client library for Ably.io, the realtime messaging service", | ||
"version": "0.8.41", | ||
"version": "0.8.42", | ||
"main": "./nodejs/index.js", | ||
@@ -6,0 +6,0 @@ "dependencies": { |
# [Ably](https://www.ably.io) | ||
## Version: 0.8.41 | ||
A Javascript client library for [Ably Realtime](https://www.ably.io), a realtime data delivery platform. | ||
This repo contains the Ably javascript client library, for the browser (including IE8+), Nodejs, React Native, and Cordova. | ||
## Version: 0.8.42 | ||
For complete API documentation, see the [ably documentation](https://ably.io/documentation). | ||
This repo contains the Ably Javascript client library, for the browser (including IE8+), Nodejs, React Native, NativeScript and Cordova. | ||
# For node.js | ||
For complete API documentation, see the [Ably documentation](https://www.ably.io/documentation). | ||
## For node.js | ||
### Installation from npm | ||
@@ -29,3 +31,3 @@ | ||
### For browsers | ||
## For browsers | ||
@@ -68,2 +70,10 @@ Include the Ably library in your HTML: | ||
## For React Native | ||
See the [ably-js-react-native repo](https://github.com/ably/ably-js-react-native) for React Native usage details. | ||
## For NativeScript | ||
See the [ably-js-nativescript repo](https://github.com/ably/ably-js-nativescript) for NativeScript usage details. | ||
## Using the Realtime API | ||
@@ -501,2 +511,2 @@ | ||
Copyright (c) 2015 Ably Real-time Ltd, Licensed under the Apache License, Version 2.0. Refer to [LICENSE](LICENSE) for the license terms. | ||
Copyright (c) 2016 Ably Real-time Ltd, Licensed under the Apache License, Version 2.0. Refer to [LICENSE](LICENSE) for the license terms. |
@@ -258,3 +258,65 @@ "use strict"; | ||
/* check that listeners added in a listener cb are not called during that | ||
* emit instance */ | ||
exports.listenerAddedInListenerCb = function(test) { | ||
var realtime = helper.AblyRealtime({ autoConnect: false }), | ||
eventEmitter = realtime.connection, | ||
firstCbCalled = false, | ||
secondCbCalled = false; | ||
eventEmitter.on('a', function() { | ||
firstCbCalled = true; | ||
eventEmitter.on('a', function() { | ||
secondCbCalled = true; | ||
}); | ||
}); | ||
eventEmitter.emit('a'); | ||
test.ok(firstCbCalled, 'check first callback called'); | ||
test.ok(!secondCbCalled, 'check second callback not called'); | ||
closeAndFinish(test, realtime); | ||
}; | ||
/* check that listeners removed in a listener cb are still called in that | ||
* emit instance (but only once) */ | ||
exports.listenerRemovedInListenerCb = function(test) { | ||
var realtime = helper.AblyRealtime({ autoConnect: false }), | ||
eventEmitter = realtime.connection, | ||
onCbCalledTimes = 0, | ||
onceCbCalledTimes = 0, | ||
anyCbCalledTimes = 0, | ||
anyOnceCbCalledTimes = 0; | ||
eventEmitter.on('a', function() { | ||
onCbCalledTimes++; | ||
eventEmitter.off('a'); | ||
}); | ||
eventEmitter.once('a', function() { | ||
onceCbCalledTimes++; | ||
eventEmitter.off('a'); | ||
}); | ||
eventEmitter.on(function() { | ||
anyCbCalledTimes++; | ||
eventEmitter.off(); | ||
}); | ||
eventEmitter.once(function() { | ||
anyOnceCbCalledTimes++; | ||
eventEmitter.off(); | ||
}); | ||
eventEmitter.emit('a'); | ||
test.equal(onCbCalledTimes, 1, 'check on callback called exactly once'); | ||
test.equal(onceCbCalledTimes, 1, 'check once callback called exactly once'); | ||
test.equal(anyCbCalledTimes, 1, 'check any callback called exactly once'); | ||
test.equal(anyOnceCbCalledTimes, 1, 'check anyOnce callback called exactly once'); | ||
closeAndFinish(test, realtime); | ||
} | ||
return module.exports = helper.withTimeout(exports); | ||
}); |
@@ -1491,3 +1491,39 @@ "use strict"; | ||
/* | ||
* Send >10 presence updates, check they were all broadcast. Point of this is | ||
* to check for a bug in the original 0.8 spec re presence membersmap | ||
* comparisons. | ||
*/ | ||
exports.presence_many_updates = function(test) { | ||
var client = helper.AblyRealtime({ clientId: testClientId }); | ||
test.expect(1); | ||
var channel = client.channels.get('presence_many_updates'), | ||
presence = channel.presence, | ||
numUpdates = 0; | ||
channel.attach(function(err) { | ||
if(err) { | ||
test.ok(false, displayError(err)); | ||
closeAndFinish(test, client); | ||
} | ||
presence.subscribe(function(presMsg) { | ||
numUpdates++; | ||
}); | ||
async.timesSeries(15, function(i, cb) { | ||
presence.update(i.toString(), cb); | ||
}, function(err) { | ||
if(err) { test.ok(false, displayError(err)); } | ||
// Wait to make sure everything has been received | ||
setTimeout(function() { | ||
test.equal(numUpdates, 15, 'Check got all the results'); | ||
client.close(); | ||
test.done(); | ||
}, 1000); | ||
}); | ||
}) | ||
}; | ||
return module.exports = helper.withTimeout(exports); | ||
}); |
"use strict"; | ||
define(['ably', 'shared_helper', 'async'], function(Ably, helper, async) { | ||
var currentTime, exports = {}, | ||
var currentTime, rest, exports = {}, | ||
_exports = {}, | ||
testClientId = 'clientId', | ||
utils = helper.Utils, | ||
i = utils.inspect, | ||
displayError = helper.displayError, | ||
@@ -20,2 +22,3 @@ closeAndFinish = helper.closeAndFinish, | ||
noop = function() {}, | ||
createPM = Ably.Realtime.ProtocolMessage.fromDeserialized, | ||
simulateDroppedConnection = helper.simulateDroppedConnection, | ||
@@ -33,3 +36,3 @@ availableTransports = helper.availableTransports; | ||
var rest = helper.AblyRest(); | ||
rest = helper.AblyRest(); | ||
rest.time(function(err, time) { | ||
@@ -47,2 +50,9 @@ if(err) { | ||
function requestSync(realtime, channelName) { | ||
realtime.connection.connectionManager.activeProtocol.transport.send({ | ||
action: 16, | ||
channel: channelName | ||
}); | ||
} | ||
function attachChannels(channels, callback) { | ||
@@ -170,59 +180,41 @@ async.map(channels, function(channel, cb) { channel.attach(cb); }, callback); | ||
testOnAllTransports(exports, 'reauth_tokendetails', function(realtimeOpts) { return function(test) { | ||
test.expect(2); | ||
var rest = helper.AblyRest(), | ||
realtime, | ||
channel, | ||
clientId = 'testClientId'; | ||
/***************************************************/ | ||
var getFirstToken = function(callback) { | ||
rest.auth.requestToken({clientId: clientId, capability: {'wrongchannel': ['*']}}, null, function(err, tokenDetails) { | ||
callback(err, tokenDetails); | ||
}); | ||
}, | ||
/* | ||
* Send >10 presence updates, check they were all broadcast. Point of this is | ||
* to check for a bug in the original 0.8 spec re presence membersmap | ||
* comparisons. | ||
*/ | ||
exports.presence_many_updates = function(test) { | ||
var client = helper.AblyRealtime({ clientId: testClientId }); | ||
connect = function(tokenDetails, callback) { | ||
realtime = helper.AblyRealtime(mixin(realtimeOpts, {tokenDetails: tokenDetails})); | ||
realtime.connection.once('connected', function() { callback() }); | ||
}, | ||
test.expect(1); | ||
var channel = client.channels.get('presence_many_updates'), | ||
presence = channel.presence, | ||
numUpdates = 0; | ||
checkCantAttach = function(callback) { | ||
channel = realtime.channels.get('rightchannel'); | ||
channel.attach(function(err) { | ||
test.ok(err && err.code === 40160, 'check channel is denied access') | ||
callback(); | ||
channel.attach(function(err) { | ||
if(err) { | ||
test.ok(false, displayError(err)); | ||
closeAndFinish(test, client); | ||
} | ||
presence.subscribe(function(presMsg) { | ||
numUpdates++; | ||
}); | ||
}, | ||
getSecondToken = function(callback) { | ||
rest.auth.requestToken({clientId: clientId, capability: {'wrongchannel': ['*'], 'rightchannel': ['*']}}, null, function(err, tokenDetails) { | ||
callback(err, tokenDetails); | ||
async.timesSeries(15, function(i, cb) { | ||
presence.update(i.toString(), cb); | ||
}, function(err) { | ||
if(err) { test.ok(false, displayError(err)); } | ||
// Wait to make sure everything has been received | ||
setTimeout(function() { | ||
test.equal(numUpdates, 15, 'Check got all the results'); | ||
client.close(); | ||
test.done(); | ||
}, 1000); | ||
}); | ||
}, | ||
}) | ||
}; | ||
reAuth = function(tokenDetails, callback) { | ||
realtime.auth.authorise(null, {force: true, tokenDetails: tokenDetails}, callback); | ||
}, | ||
checkCanNowAttach = function(stateChange, callback) { | ||
channel.attach(function(err) { | ||
callback(err); | ||
}); | ||
}; | ||
async.waterfall([ | ||
getFirstToken, | ||
connect, | ||
checkCantAttach, | ||
getSecondToken, | ||
reAuth, | ||
checkCanNowAttach, | ||
], function(err) { | ||
test.ok(!err, err && displayError(err)); | ||
closeAndFinish(test, realtime); | ||
}); | ||
}}); | ||
return module.exports = helper.withTimeout(exports); | ||
}); |
@@ -7,12 +7,12 @@ "use strict"; | ||
rest, | ||
publishIntervalHelper = function(currentMessageNum, channel, dataFn, onPublish){ | ||
return function(currentMessageNum) { | ||
channel.publish('event0', dataFn(), function() { | ||
onPublish(); | ||
}); | ||
}; | ||
}, | ||
publishAtIntervals = function(numMessages, channel, dataFn, onPublish){ | ||
for(var i = numMessages; i > 0; i--) { | ||
var helper = function(currentMessageNum) { | ||
console.log('sending: ' + currentMessageNum); | ||
channel.publish('event0', dataFn(), function(err) { | ||
console.log('publish callback called'); | ||
onPublish(); | ||
}); | ||
}; | ||
setTimeout(helper(i), 20*i); | ||
setTimeout(publishIntervalHelper(i, channel, dataFn, onPublish), 2*i); | ||
} | ||
@@ -19,0 +19,0 @@ }, |
window.__karma__ = { base: '../' }; | ||
window.__karma__.files = {"browser/static/ably-commonjs.js":true,"browser/static/ably-commonjs.noencryption.js":true,"browser/static/ably.js":true,"browser/static/ably.min.js":true,"browser/static/ably.noencryption.js":true,"browser/static/ably.noencryption.min.js":true,"browser/lib/util/base64.js":true,"node_modules/async/lib/async.js":true,"spec/common/globals/environment.js":true,"spec/common/globals/named_dependencies.js":true,"spec/common/modules/client_module.js":true,"spec/common/modules/shared_helper.js":true,"spec/common/modules/testapp_manager.js":true,"spec/common/modules/testapp_module.js":true,"spec/common/ably-common/test-resources/crypto-data-128.json":true,"spec/common/ably-common/test-resources/crypto-data-256.json":true,"spec/common/ably-common/test-resources/test-app-setup.json":true,"spec/support/browser_file_list.js":true,"spec/support/browser_setup.js":true,"spec/support/environment.vars.js":true,"spec/support/modules_helper.js":true,"spec/support/tear_down.js":true,"spec/support/test_helper.js":true,"spec/realtime/auth.test.js":true,"spec/realtime/channel.test.js":true,"spec/realtime/connection.test.js":true,"spec/realtime/connectivity.test.js":true,"spec/realtime/crypto.test.js":true,"spec/realtime/event_emitter.test.js":true,"spec/realtime/failure.test.js":true,"spec/realtime/history.test.js":true,"spec/realtime/init.test.js":true,"spec/realtime/message.test.js":true,"spec/realtime/presence.test.js":true,"spec/realtime/resume.test.js":true,"spec/realtime/tmp.test.js":true,"spec/realtime/upgrade.test.js":true,"spec/rest/auth.test.js":true,"spec/rest/capability.test.js":true,"spec/rest/defaults.test.js":true,"spec/rest/history.test.js":true,"spec/rest/http.test.js":true,"spec/rest/init.test.js":true,"spec/rest/message.test.js":true,"spec/rest/presence.test.js":true,"spec/rest/stats.test.js":true,"spec/rest/time.test.js":true,"spec/browser/connection.test.js":true,"spec/browser/simple.test.js":true}; | ||
window.__karma__.files = {"browser/static/ably-commonjs.js":true,"browser/static/ably-commonjs.noencryption.js":true,"browser/static/ably.js":true,"browser/static/ably.min.js":true,"browser/static/ably.noencryption.js":true,"browser/static/ably.noencryption.min.js":true,"browser/lib/util/base64.js":true,"node_modules/async/lib/async.js":true,"spec/common/globals/environment.js":true,"spec/common/globals/named_dependencies.js":true,"spec/common/modules/client_module.js":true,"spec/common/modules/shared_helper.js":true,"spec/common/modules/testapp_manager.js":true,"spec/common/modules/testapp_module.js":true,"spec/common/ably-common/test-resources/crypto-data-128.json":true,"spec/common/ably-common/test-resources/crypto-data-256.json":true,"spec/common/ably-common/test-resources/messages-encoding.json":true,"spec/common/ably-common/test-resources/test-app-setup.json":true,"spec/support/browser_file_list.js":true,"spec/support/browser_setup.js":true,"spec/support/environment.vars.js":true,"spec/support/modules_helper.js":true,"spec/support/tear_down.js":true,"spec/support/test_helper.js":true,"spec/realtime/auth.test.js":true,"spec/realtime/channel.test.js":true,"spec/realtime/connection.test.js":true,"spec/realtime/connectivity.test.js":true,"spec/realtime/crypto.test.js":true,"spec/realtime/event_emitter.test.js":true,"spec/realtime/failure.test.js":true,"spec/realtime/history.test.js":true,"spec/realtime/init.test.js":true,"spec/realtime/message.test.js":true,"spec/realtime/presence.test.js":true,"spec/realtime/resume.test.js":true,"spec/realtime/tmp.test.js":true,"spec/realtime/upgrade.test.js":true,"spec/rest/auth.test.js":true,"spec/rest/capability.test.js":true,"spec/rest/defaults.test.js":true,"spec/rest/history.test.js":true,"spec/rest/http.test.js":true,"spec/rest/init.test.js":true,"spec/rest/message.test.js":true,"spec/rest/presence.test.js":true,"spec/rest/stats.test.js":true,"spec/rest/time.test.js":true,"spec/browser/connection.test.js":true,"spec/browser/simple.test.js":true}; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2745302
57004
510