engine.io-client
Advanced tools
Comparing version 0.5.0 to 0.6.0
{ | ||
"name": "engine.io", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"dependencies": { | ||
"component/emitter": "1.0.0", | ||
"component/indexof": "*", | ||
"LearnBoost/engine.io-protocol": "0.3.0", | ||
@@ -7,0 +8,0 @@ "visionmedia/debug": "*" |
439
engine.io.js
;(function(){ | ||
/** | ||
@@ -10,23 +11,28 @@ * Require the given path. | ||
function require(p, parent, orig){ | ||
var path = require.resolve(p) | ||
, mod = require.modules[path]; | ||
function require(path, parent, orig) { | ||
var resolved = require.resolve(path); | ||
// lookup failed | ||
if (null == path) { | ||
orig = orig || p; | ||
if (null == resolved) { | ||
orig = orig || path; | ||
parent = parent || 'root'; | ||
throw new Error('failed to require "' + orig + '" from "' + parent + '"'); | ||
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"'); | ||
err.path = orig; | ||
err.parent = parent; | ||
err.require = true; | ||
throw err; | ||
} | ||
var module = require.modules[resolved]; | ||
// perform real require() | ||
// by invoking the module's | ||
// registered function | ||
if (!mod.exports) { | ||
mod.exports = {}; | ||
mod.client = mod.component = true; | ||
mod.call(this, mod, mod.exports, require.relative(path)); | ||
if (!module.exports) { | ||
module.exports = {}; | ||
module.client = module.component = true; | ||
module.call(this, module.exports, require.relative(resolved), module); | ||
} | ||
return mod.exports; | ||
return module.exports; | ||
} | ||
@@ -60,15 +66,22 @@ | ||
require.resolve = function(path){ | ||
var orig = path | ||
, reg = path + '.js' | ||
, regJSON = path + '.json' | ||
, index = path + '/index.js' | ||
, indexJSON = path + '/index.json'; | ||
require.resolve = function(path) { | ||
if (path.charAt(0) === '/') path = path.slice(1); | ||
var index = path + '/index.js'; | ||
return require.modules[reg] && reg | ||
|| require.modules[regJSON] && regJSON | ||
|| require.modules[index] && index | ||
|| require.modules[indexJSON] && indexJSON | ||
|| require.modules[orig] && orig | ||
|| require.aliases[index]; | ||
var paths = [ | ||
path, | ||
path + '.js', | ||
path + '.json', | ||
path + '/index.js', | ||
path + '/index.json' | ||
]; | ||
for (var i = 0; i < paths.length; i++) { | ||
var path = paths[i]; | ||
if (require.modules.hasOwnProperty(path)) return path; | ||
} | ||
if (require.aliases.hasOwnProperty(index)) { | ||
return require.aliases[index]; | ||
} | ||
}; | ||
@@ -105,11 +118,11 @@ | ||
/** | ||
* Register module at `path` with callback `fn`. | ||
* Register module at `path` with callback `definition`. | ||
* | ||
* @param {String} path | ||
* @param {Function} fn | ||
* @param {Function} definition | ||
* @api private | ||
*/ | ||
require.register = function(path, fn){ | ||
require.modules[path] = fn; | ||
require.register = function(path, definition) { | ||
require.modules[path] = definition; | ||
}; | ||
@@ -125,5 +138,6 @@ | ||
require.alias = function(from, to){ | ||
var fn = require.modules[from]; | ||
if (!fn) throw new Error('failed to alias "' + from + '", it does not exist'); | ||
require.alias = function(from, to) { | ||
if (!require.modules.hasOwnProperty(from)) { | ||
throw new Error('Failed to alias "' + from + '", it does not exist'); | ||
} | ||
require.aliases[to] = from; | ||
@@ -147,3 +161,3 @@ }; | ||
function lastIndexOf(arr, obj){ | ||
function lastIndexOf(arr, obj) { | ||
var i = arr.length; | ||
@@ -160,6 +174,5 @@ while (i--) { | ||
function fn(path){ | ||
var orig = path; | ||
path = fn.resolve(path); | ||
return require(path, parent, orig); | ||
function localRequire(path) { | ||
var resolved = localRequire.resolve(path); | ||
return require(resolved, parent, path); | ||
} | ||
@@ -171,14 +184,15 @@ | ||
fn.resolve = function(path){ | ||
localRequire.resolve = function(path) { | ||
var c = path.charAt(0); | ||
if ('/' == c) return path.slice(1); | ||
if ('.' == c) return require.normalize(p, path); | ||
// resolve deps by returning | ||
// the dep in the nearest "deps" | ||
// directory | ||
if ('.' != path.charAt(0)) { | ||
var segs = parent.split('/'); | ||
var i = lastIndexOf(segs, 'deps') + 1; | ||
if (!i) i = 0; | ||
path = segs.slice(0, i + 1).join('/') + '/deps/' + path; | ||
return path; | ||
} | ||
return require.normalize(p, path); | ||
var segs = parent.split('/'); | ||
var i = lastIndexOf(segs, 'deps') + 1; | ||
if (!i) i = 0; | ||
path = segs.slice(0, i + 1).join('/') + '/deps/' + path; | ||
return path; | ||
}; | ||
@@ -190,8 +204,9 @@ | ||
fn.exists = function(path){ | ||
return !! require.modules[fn.resolve(path)]; | ||
localRequire.exists = function(path) { | ||
return require.modules.hasOwnProperty(localRequire.resolve(path)); | ||
}; | ||
return fn; | ||
};require.register("component-emitter/index.js", function(module, exports, require){ | ||
return localRequire; | ||
}; | ||
require.register("component-emitter/index.js", function(exports, require, module){ | ||
@@ -346,3 +361,15 @@ /** | ||
}); | ||
require.register("LearnBoost-engine.io-protocol/lib/index.js", function(module, exports, require){ | ||
require.register("component-indexof/index.js", function(exports, require, module){ | ||
var indexOf = [].indexOf; | ||
module.exports = function(arr, obj){ | ||
if (indexOf) return arr.indexOf(obj); | ||
for (var i = 0; i < arr.length; ++i) { | ||
if (arr[i] === obj) return i; | ||
} | ||
return -1; | ||
}; | ||
}); | ||
require.register("LearnBoost-engine.io-protocol/lib/index.js", function(exports, require, module){ | ||
/** | ||
@@ -513,3 +540,3 @@ * Module dependencies. | ||
}); | ||
require.register("LearnBoost-engine.io-protocol/lib/keys.js", function(module, exports, require){ | ||
require.register("LearnBoost-engine.io-protocol/lib/keys.js", function(exports, require, module){ | ||
@@ -536,3 +563,3 @@ /** | ||
}); | ||
require.register("visionmedia-debug/index.js", function(module, exports, require){ | ||
require.register("visionmedia-debug/index.js", function(exports, require, module){ | ||
if ('undefined' == typeof window) { | ||
@@ -545,3 +572,3 @@ module.exports = require('./lib/debug'); | ||
}); | ||
require.register("visionmedia-debug/debug.js", function(module, exports, require){ | ||
require.register("visionmedia-debug/debug.js", function(exports, require, module){ | ||
@@ -670,3 +697,3 @@ /** | ||
}); | ||
require.register("engine.io/lib/index.js", function(module, exports, require){ | ||
require.register("engine.io/lib/index.js", function(exports, require, module){ | ||
@@ -684,3 +711,3 @@ module.exports = require('./socket'); | ||
}); | ||
require.register("engine.io/lib/socket.js", function(module, exports, require){ | ||
require.register("engine.io/lib/socket.js", function(exports, require, module){ | ||
/** | ||
@@ -693,3 +720,5 @@ * Module dependencies. | ||
, Emitter = require('./emitter') | ||
, debug = require('debug')('engine-client:socket'); | ||
, debug = require('debug')('engine-client:socket') | ||
, index = require('indexof') | ||
, parser = require('engine.io-parser'); | ||
@@ -709,2 +738,10 @@ /** | ||
/** | ||
* Noop function. | ||
* | ||
* @api private | ||
*/ | ||
function noop () {}; | ||
/** | ||
* Socket constructor. | ||
@@ -732,2 +769,3 @@ * | ||
opts.port = uri.port; | ||
if (uri.query) opts.query = uri.query; | ||
} | ||
@@ -750,2 +788,3 @@ | ||
this.query = opts.query || {}; | ||
if ('string' == typeof this.query) this.query = util.qsParse(this.query); | ||
this.upgrade = false !== opts.upgrade; | ||
@@ -760,2 +799,3 @@ this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/'; | ||
this.writeBuffer = []; | ||
this.callbackBuffer = []; | ||
this.policyPort = opts.policyPort || 843; | ||
@@ -780,3 +820,3 @@ this.open(); | ||
Socket.protocol = 1; | ||
Socket.protocol = parser.protocol; // this is an int | ||
@@ -813,7 +853,11 @@ /** | ||
var query = clone(this.query); | ||
// append engine.io protocol identifier | ||
query.EIO = parser.protocol; | ||
// transport name | ||
query.transport = name; | ||
if (this.id) { | ||
query.sid = this.id; | ||
} | ||
// session id if we already have one | ||
if (this.id) query.sid = this.id; | ||
@@ -879,3 +923,3 @@ var transport = new transports[name]({ | ||
.on('drain', function () { | ||
self.flush(); | ||
self.onDrain(); | ||
}) | ||
@@ -1024,3 +1068,3 @@ .on('packet', function (packet) { | ||
case 'pong': | ||
this.ping(); | ||
this.setPing(); | ||
break; | ||
@@ -1064,3 +1108,3 @@ | ||
this.onOpen(); | ||
this.ping(); | ||
this.setPing(); | ||
@@ -1094,3 +1138,3 @@ // Prolong liveness of socket on heartbeat | ||
Socket.prototype.ping = function () { | ||
Socket.prototype.setPing = function () { | ||
var self = this; | ||
@@ -1100,3 +1144,3 @@ clearTimeout(self.pingIntervalTimer); | ||
debug('writing ping packet - expecting pong within %sms', self.pingTimeout); | ||
self.sendPacket('ping'); | ||
self.ping(); | ||
self.onHeartbeat(self.pingTimeout); | ||
@@ -1107,2 +1151,47 @@ }, self.pingInterval); | ||
/** | ||
* Sends a ping packet | ||
* | ||
* @api public | ||
*/ | ||
Socket.prototype.ping = function () { | ||
this.sendPacket('ping'); | ||
}; | ||
/** | ||
* Called on `drain` event | ||
* | ||
* @api private | ||
*/ | ||
Socket.prototype.onDrain = function() { | ||
this.callbacks(); | ||
this.writeBuffer.splice(0, this.prevBufferLen); | ||
this.callbackBuffer.splice(0, this.prevBufferLen); | ||
// setting prevBufferLen = 0 is very important | ||
// for example, when upgrading, upgrade packet is sent over, | ||
// and a nonzero prevBufferLen could cause problems on `drain` | ||
this.prevBufferLen = 0; | ||
if (this.writeBuffer.length == 0) { | ||
this.emit('drain'); | ||
} else { | ||
this.flush(); | ||
} | ||
} | ||
/** | ||
* Calls all the callback functions associated with sending packets | ||
* | ||
* @api private | ||
*/ | ||
Socket.prototype.callbacks = function() { | ||
for (var i = 0; i < this.prevBufferLen; i++) { | ||
if (this.callbackBuffer[i]) { | ||
this.callbackBuffer[i](); | ||
} | ||
} | ||
} | ||
/** | ||
* Flush write buffers. | ||
@@ -1118,3 +1207,6 @@ * | ||
this.transport.send(this.writeBuffer); | ||
this.writeBuffer = []; | ||
// keep track of current length of writeBuffer | ||
// splice writeBuffer and callbackBuffer on `drain` | ||
this.prevBufferLen = this.writeBuffer.length; | ||
this.emit('flush'); | ||
} | ||
@@ -1127,2 +1219,3 @@ }; | ||
* @param {String} message. | ||
* @param {Function} callback function. | ||
* @return {Socket} for chaining. | ||
@@ -1133,4 +1226,4 @@ * @api public | ||
Socket.prototype.write = | ||
Socket.prototype.send = function (msg) { | ||
this.sendPacket('message', msg); | ||
Socket.prototype.send = function (msg, fn) { | ||
this.sendPacket('message', msg, fn); | ||
return this; | ||
@@ -1144,9 +1237,11 @@ }; | ||
* @param {String} data. | ||
* @param {Function} callback function. | ||
* @api private | ||
*/ | ||
Socket.prototype.sendPacket = function (type, data) { | ||
Socket.prototype.sendPacket = function (type, data, fn) { | ||
var packet = { type: type, data: data }; | ||
this.emit('packetCreate', packet); | ||
this.writeBuffer.push(packet); | ||
this.callbackBuffer.push(fn); | ||
this.flush(); | ||
@@ -1193,6 +1288,16 @@ }; | ||
debug('socket close with reason: "%s"', reason); | ||
var self = this; | ||
clearTimeout(this.pingIntervalTimer); | ||
clearTimeout(this.pingTimeoutTimer); | ||
// clean buffers in next tick, so developers can still | ||
// grab the buffers on `close` event | ||
setTimeout(function() { | ||
self.writeBuffer = []; | ||
self.callbackBuffer = []; | ||
}, 0); | ||
var prev = this.readyState; | ||
this.readyState = 'closed'; | ||
this.emit('close', reason, desc); | ||
if (prev == 'open') { | ||
this.emit('close', reason, desc); | ||
} | ||
this.onclose && this.onclose.call(this); | ||
@@ -1205,3 +1310,3 @@ this.id = null; | ||
* Filters upgrades, returning only those matching client transports. | ||
* | ||
* | ||
* @param {Array} server upgrades | ||
@@ -1215,3 +1320,3 @@ * @api private | ||
for (var i = 0, j = upgrades.length; i<j; i++) { | ||
if (~this.transports.indexOf(upgrades[i])) filteredUpgrades.push(upgrades[i]); | ||
if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]); | ||
} | ||
@@ -1222,3 +1327,3 @@ return filteredUpgrades; | ||
}); | ||
require.register("engine.io/lib/transport.js", function(module, exports, require){ | ||
require.register("engine.io/lib/transport.js", function(exports, require, module){ | ||
@@ -1367,3 +1472,3 @@ /** | ||
}); | ||
require.register("engine.io/lib/emitter.js", function(module, exports, require){ | ||
require.register("engine.io/lib/emitter.js", function(exports, require, module){ | ||
@@ -1374,10 +1479,4 @@ /** | ||
var Emitter; | ||
var Emitter = require('emitter'); | ||
try { | ||
Emitter = require('emitter'); | ||
} catch(e){ | ||
Emitter = require('emitter-component'); | ||
} | ||
/** | ||
@@ -1413,14 +1512,4 @@ * Module exports. | ||
/** | ||
* Node-compatible `EventEmitter#removeAllListeners` | ||
* | ||
* @api public | ||
*/ | ||
Emitter.prototype.removeAllListeners = function(){ | ||
this._callbacks = {}; | ||
}; | ||
}); | ||
require.register("engine.io/lib/util.js", function(module, exports, require){ | ||
require.register("engine.io/lib/util.js", function(exports, require, module){ | ||
/** | ||
@@ -1536,8 +1625,8 @@ * Status of page load. | ||
var rvalidchars = /^[\],:{}\s]*$/ | ||
, rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g | ||
, rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g | ||
, rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g | ||
, rtrimLeft = /^\s+/ | ||
, rtrimRight = /\s+$/ | ||
var rvalidchars = /^[\],:{}\s]*$/; | ||
var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g; | ||
var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g; | ||
var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g; | ||
var rtrimLeft = /^\s+/; | ||
var rtrimRight = /\s+$/; | ||
@@ -1580,4 +1669,5 @@ exports.parseJSON = function (data) { | ||
exports.ua.hasCORS = 'undefined' != typeof XMLHttpRequest && (function () { | ||
var a; | ||
try { | ||
var a = new XMLHttpRequest(); | ||
a = new XMLHttpRequest(); | ||
} catch (e) { | ||
@@ -1631,6 +1721,6 @@ return false; | ||
exports.request = function request (xdomain) { | ||
if ('undefined' == typeof window) { | ||
try { | ||
var _XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; | ||
return new _XMLHttpRequest(); | ||
} | ||
} catch (e) {} | ||
@@ -1694,3 +1784,3 @@ if (xdomain && 'undefined' != typeof XDomainRequest && !exports.ua.hasCORS) { | ||
if (str.length) str += '&'; | ||
str += i + '=' + encodeURIComponent(obj[i]); | ||
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]); | ||
} | ||
@@ -1702,4 +1792,21 @@ } | ||
/** | ||
* Parses a simple querystring. | ||
* | ||
* @param {String} qs | ||
* @api private | ||
*/ | ||
exports.qsParse = function(qs){ | ||
var qry = {}; | ||
var pairs = qs.split('&'); | ||
for (var i = 0, l = pairs.length; i < l; i++) { | ||
var pair = pairs[i].split('='); | ||
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); | ||
} | ||
return qry; | ||
}; | ||
}); | ||
require.register("engine.io/lib/transports/index.js", function(module, exports, require){ | ||
require.register("engine.io/lib/transports/index.js", function(exports, require, module){ | ||
@@ -1747,7 +1854,7 @@ /** | ||
// some user agents have empty `location.port` | ||
if (Number(port) != port) { | ||
if (Number(port) !== port) { | ||
port = isSSL ? 443 : 80; | ||
} | ||
xd = opts.host != location.hostname || port != opts.port; | ||
xd = opts.hostname != location.hostname || port != opts.port; | ||
isXProtocol = opts.secure != isSSL; | ||
@@ -1770,3 +1877,3 @@ } | ||
}); | ||
require.register("engine.io/lib/transports/polling.js", function(module, exports, require){ | ||
require.register("engine.io/lib/transports/polling.js", function(exports, require, module){ | ||
/** | ||
@@ -1891,30 +1998,33 @@ * Module dependencies. | ||
Polling.prototype.onData = function(data){ | ||
var self = this; | ||
debug('polling got data %s', data); | ||
// decode payload | ||
var packets = parser.decodePayload(data); | ||
for (var i = 0, l = packets.length; i < l; i++) { | ||
// if its the first message we consider the trnasport open | ||
if ('opening' == this.readyState) { | ||
this.onOpen(); | ||
parser.decodePayload(data, function(packet, index, total) { | ||
// if its the first message we consider the transport open | ||
if ('opening' == self.readyState) { | ||
self.onOpen(); | ||
} | ||
// if its a close packet, we close the ongoing requests | ||
if ('close' == packets[i].type) { | ||
this.onClose(); | ||
return; | ||
if ('close' == packet.type) { | ||
self.onClose(); | ||
return false; | ||
} | ||
// otherwise bypass onData and handle the message | ||
this.onPacket(packets[i]); | ||
} | ||
self.onPacket(packet); | ||
}); | ||
// if we got data we're not polling | ||
this.polling = false; | ||
this.emit('pollComplete'); | ||
// if an event did not trigger closing | ||
if ('closed' != this.readyState) { | ||
// if we got data we're not polling | ||
this.polling = false; | ||
this.emit('pollComplete'); | ||
if ('open' == this.readyState) { | ||
this.poll(); | ||
} else { | ||
debug('ignoring poll - transport state "%s"', this.readyState); | ||
if ('open' == this.readyState) { | ||
this.poll(); | ||
} else { | ||
debug('ignoring poll - transport state "%s"', this.readyState); | ||
} | ||
} | ||
@@ -1985,3 +2095,3 @@ }; | ||
}); | ||
require.register("engine.io/lib/transports/polling-xhr.js", function(module, exports, require){ | ||
require.register("engine.io/lib/transports/polling-xhr.js", function(exports, require, module){ | ||
/** | ||
@@ -2033,4 +2143,12 @@ * Module requirements. | ||
if (global.location) { | ||
this.xd = opts.host != global.location.hostname || | ||
global.location.port != opts.port; | ||
var isSSL = 'https:' == location.protocol; | ||
var port = location.port; | ||
// some user agents have empty `location.port` | ||
if (Number(port) !== port) { | ||
port = isSSL ? 443 : 80; | ||
} | ||
this.xd = opts.hostname != global.location.hostname || | ||
port != opts.port; | ||
} | ||
@@ -2238,2 +2356,5 @@ }; | ||
Request.prototype.cleanup = function(){ | ||
if ('undefined' == typeof this.xhr ) { | ||
return; | ||
} | ||
// xmlhttprequest | ||
@@ -2280,3 +2401,3 @@ this.xhr.onreadystatechange = empty; | ||
}); | ||
require.register("engine.io/lib/transports/polling-jsonp.js", function(module, exports, require){ | ||
require.register("engine.io/lib/transports/polling-jsonp.js", function(exports, require, module){ | ||
@@ -2403,2 +2524,3 @@ /** | ||
JSONPPolling.prototype.doPoll = function () { | ||
var self = this; | ||
var script = document.createElement('script'); | ||
@@ -2413,2 +2535,5 @@ | ||
script.src = this.uri(); | ||
script.onerror = function(e){ | ||
self.onError('jsonp poll error',e); | ||
} | ||
@@ -2419,2 +2544,3 @@ var insertAt = document.getElementsByTagName('script')[0]; | ||
if (util.ua.gecko) { | ||
@@ -2514,4 +2640,3 @@ setTimeout(function () { | ||
}); | ||
require.register("engine.io/lib/transports/websocket.js", function(module, exports, require){ | ||
require.register("engine.io/lib/transports/websocket.js", function(exports, require, module){ | ||
/** | ||
@@ -2600,8 +2725,41 @@ * Module dependencies. | ||
WS.prototype.write = function(packets){ | ||
var self = this; | ||
this.writable = false; | ||
// encodePacket efficient as it uses WS framing | ||
// no need for encodePayload | ||
for (var i = 0, l = packets.length; i < l; i++) { | ||
this.socket.send(parser.encodePacket(packets[i])); | ||
} | ||
function ondrain() { | ||
self.writable = true; | ||
self.emit('drain'); | ||
} | ||
// check periodically if we're done sending | ||
if ('bufferedAmount' in this.socket) { | ||
this.bufferedAmountId = setInterval(function() { | ||
if (self.socket.bufferedAmount == 0) { | ||
clearInterval(self.bufferedAmountId); | ||
ondrain(); | ||
} | ||
}, 50); | ||
} else { | ||
// fake drain | ||
// defer to next tick to allow Socket to clear writeBuffer | ||
setTimeout(ondrain, 0); | ||
} | ||
}; | ||
/** | ||
* Called upon close | ||
* | ||
* @api private | ||
*/ | ||
WS.prototype.onClose = function(){ | ||
// stop checking to see if websocket is done sending buffer | ||
clearInterval(this.bufferedAmountId); | ||
Transport.prototype.onClose.call(this); | ||
} | ||
/** | ||
* Closes socket. | ||
@@ -2677,3 +2835,3 @@ * | ||
}); | ||
require.register("engine.io/lib/transports/flashsocket.js", function(module, exports, require){ | ||
require.register("engine.io/lib/transports/flashsocket.js", function(exports, require, module){ | ||
/** | ||
@@ -2941,16 +3099,25 @@ * Module dependencies. | ||
require.alias("component-emitter/index.js", "engine.io/deps/emitter/index.js"); | ||
require.alias("component-emitter/index.js", "emitter/index.js"); | ||
require.alias("component-indexof/index.js", "engine.io/deps/indexof/index.js"); | ||
require.alias("component-indexof/index.js", "indexof/index.js"); | ||
require.alias("LearnBoost-engine.io-protocol/lib/index.js", "engine.io/deps/engine.io-parser/lib/index.js"); | ||
require.alias("LearnBoost-engine.io-protocol/lib/keys.js", "engine.io/deps/engine.io-parser/lib/keys.js"); | ||
require.alias("LearnBoost-engine.io-protocol/lib/index.js", "engine.io/deps/engine.io-parser/index.js"); | ||
require.alias("LearnBoost-engine.io-protocol/lib/index.js", "engine.io-parser/index.js"); | ||
require.alias("LearnBoost-engine.io-protocol/lib/index.js", "LearnBoost-engine.io-protocol/index.js"); | ||
require.alias("visionmedia-debug/index.js", "engine.io/deps/debug/index.js"); | ||
require.alias("visionmedia-debug/debug.js", "engine.io/deps/debug/debug.js"); | ||
require.alias("visionmedia-debug/index.js", "debug/index.js"); | ||
require.alias("engine.io/lib/index.js", "engine.io/index.js"); | ||
if ("undefined" == typeof module) { | ||
window.eio = require("engine.io"); | ||
} else { | ||
module.exports = require("engine.io"); | ||
} | ||
})(); | ||
if (typeof exports == "object") { | ||
module.exports = require("engine.io"); | ||
} else if (typeof define == "function" && define.amd) { | ||
define(function(){ return require("engine.io"); }); | ||
} else { | ||
this["eio"] = require("engine.io"); | ||
}})(); |
0.6.0 / 2013-05-31 | ||
================== | ||
* does not emit close on incorrect socket connection | ||
* use indexof component for ie8 and below | ||
* improved x-domain handling | ||
* introduce public `ping` api | ||
* added drain event | ||
* fix `flush` and `flushComplete` events | ||
* fixed `drain` bug splicing with upgrading | ||
* add support for callbacks with socket.send() | ||
0.5.0 / 2013-03-16 | ||
@@ -3,0 +15,0 @@ ================== |
@@ -9,2 +9,3 @@ /** | ||
, debug = require('debug')('engine-client:socket') | ||
, index = require('indexof') | ||
, parser = require('engine.io-parser'); | ||
@@ -25,2 +26,10 @@ | ||
/** | ||
* Noop function. | ||
* | ||
* @api private | ||
*/ | ||
function noop () {}; | ||
/** | ||
* Socket constructor. | ||
@@ -76,2 +85,3 @@ * | ||
this.writeBuffer = []; | ||
this.callbackBuffer = []; | ||
this.policyPort = opts.policyPort || 843; | ||
@@ -197,3 +207,3 @@ this.open(); | ||
.on('drain', function () { | ||
self.flush(); | ||
self.onDrain(); | ||
}) | ||
@@ -342,3 +352,3 @@ .on('packet', function (packet) { | ||
case 'pong': | ||
this.ping(); | ||
this.setPing(); | ||
break; | ||
@@ -382,3 +392,3 @@ | ||
this.onOpen(); | ||
this.ping(); | ||
this.setPing(); | ||
@@ -412,3 +422,3 @@ // Prolong liveness of socket on heartbeat | ||
Socket.prototype.ping = function () { | ||
Socket.prototype.setPing = function () { | ||
var self = this; | ||
@@ -418,3 +428,3 @@ clearTimeout(self.pingIntervalTimer); | ||
debug('writing ping packet - expecting pong within %sms', self.pingTimeout); | ||
self.sendPacket('ping'); | ||
self.ping(); | ||
self.onHeartbeat(self.pingTimeout); | ||
@@ -425,2 +435,47 @@ }, self.pingInterval); | ||
/** | ||
* Sends a ping packet | ||
* | ||
* @api public | ||
*/ | ||
Socket.prototype.ping = function () { | ||
this.sendPacket('ping'); | ||
}; | ||
/** | ||
* Called on `drain` event | ||
* | ||
* @api private | ||
*/ | ||
Socket.prototype.onDrain = function() { | ||
this.callbacks(); | ||
this.writeBuffer.splice(0, this.prevBufferLen); | ||
this.callbackBuffer.splice(0, this.prevBufferLen); | ||
// setting prevBufferLen = 0 is very important | ||
// for example, when upgrading, upgrade packet is sent over, | ||
// and a nonzero prevBufferLen could cause problems on `drain` | ||
this.prevBufferLen = 0; | ||
if (this.writeBuffer.length == 0) { | ||
this.emit('drain'); | ||
} else { | ||
this.flush(); | ||
} | ||
} | ||
/** | ||
* Calls all the callback functions associated with sending packets | ||
* | ||
* @api private | ||
*/ | ||
Socket.prototype.callbacks = function() { | ||
for (var i = 0; i < this.prevBufferLen; i++) { | ||
if (this.callbackBuffer[i]) { | ||
this.callbackBuffer[i](); | ||
} | ||
} | ||
} | ||
/** | ||
* Flush write buffers. | ||
@@ -436,3 +491,6 @@ * | ||
this.transport.send(this.writeBuffer); | ||
this.writeBuffer = []; | ||
// keep track of current length of writeBuffer | ||
// splice writeBuffer and callbackBuffer on `drain` | ||
this.prevBufferLen = this.writeBuffer.length; | ||
this.emit('flush'); | ||
} | ||
@@ -445,2 +503,3 @@ }; | ||
* @param {String} message. | ||
* @param {Function} callback function. | ||
* @return {Socket} for chaining. | ||
@@ -451,4 +510,4 @@ * @api public | ||
Socket.prototype.write = | ||
Socket.prototype.send = function (msg) { | ||
this.sendPacket('message', msg); | ||
Socket.prototype.send = function (msg, fn) { | ||
this.sendPacket('message', msg, fn); | ||
return this; | ||
@@ -462,9 +521,11 @@ }; | ||
* @param {String} data. | ||
* @param {Function} callback function. | ||
* @api private | ||
*/ | ||
Socket.prototype.sendPacket = function (type, data) { | ||
Socket.prototype.sendPacket = function (type, data, fn) { | ||
var packet = { type: type, data: data }; | ||
this.emit('packetCreate', packet); | ||
this.writeBuffer.push(packet); | ||
this.callbackBuffer.push(fn); | ||
this.flush(); | ||
@@ -511,6 +572,16 @@ }; | ||
debug('socket close with reason: "%s"', reason); | ||
var self = this; | ||
clearTimeout(this.pingIntervalTimer); | ||
clearTimeout(this.pingTimeoutTimer); | ||
// clean buffers in next tick, so developers can still | ||
// grab the buffers on `close` event | ||
setTimeout(function() { | ||
self.writeBuffer = []; | ||
self.callbackBuffer = []; | ||
}, 0); | ||
var prev = this.readyState; | ||
this.readyState = 'closed'; | ||
this.emit('close', reason, desc); | ||
if (prev == 'open') { | ||
this.emit('close', reason, desc); | ||
} | ||
this.onclose && this.onclose.call(this); | ||
@@ -532,5 +603,5 @@ this.id = null; | ||
for (var i = 0, j = upgrades.length; i<j; i++) { | ||
if (~this.transports.indexOf(upgrades[i])) filteredUpgrades.push(upgrades[i]); | ||
if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]); | ||
} | ||
return filteredUpgrades; | ||
}; |
@@ -43,7 +43,7 @@ | ||
// some user agents have empty `location.port` | ||
if (Number(port) != port) { | ||
if (Number(port) !== port) { | ||
port = isSSL ? 443 : 80; | ||
} | ||
xd = opts.host != location.hostname || port != opts.port; | ||
xd = opts.hostname != location.hostname || port != opts.port; | ||
isXProtocol = opts.secure != isSSL; | ||
@@ -50,0 +50,0 @@ } |
@@ -47,4 +47,12 @@ /** | ||
if (global.location) { | ||
this.xd = opts.host != global.location.hostname || | ||
global.location.port != opts.port; | ||
var isSSL = 'https:' == location.protocol; | ||
var port = location.port; | ||
// some user agents have empty `location.port` | ||
if (Number(port) !== port) { | ||
port = isSSL ? 443 : 80; | ||
} | ||
this.xd = opts.hostname != global.location.hostname || | ||
port != opts.port; | ||
} | ||
@@ -51,0 +59,0 @@ }; |
@@ -1,2 +0,1 @@ | ||
/** | ||
@@ -85,8 +84,41 @@ * Module dependencies. | ||
WS.prototype.write = function(packets){ | ||
var self = this; | ||
this.writable = false; | ||
// encodePacket efficient as it uses WS framing | ||
// no need for encodePayload | ||
for (var i = 0, l = packets.length; i < l; i++) { | ||
this.socket.send(parser.encodePacket(packets[i])); | ||
} | ||
function ondrain() { | ||
self.writable = true; | ||
self.emit('drain'); | ||
} | ||
// check periodically if we're done sending | ||
if ('bufferedAmount' in this.socket) { | ||
this.bufferedAmountId = setInterval(function() { | ||
if (self.socket.bufferedAmount == 0) { | ||
clearInterval(self.bufferedAmountId); | ||
ondrain(); | ||
} | ||
}, 50); | ||
} else { | ||
// fake drain | ||
// defer to next tick to allow Socket to clear writeBuffer | ||
setTimeout(ondrain, 0); | ||
} | ||
}; | ||
/** | ||
* Called upon close | ||
* | ||
* @api private | ||
*/ | ||
WS.prototype.onClose = function(){ | ||
// stop checking to see if websocket is done sending buffer | ||
clearInterval(this.bufferedAmountId); | ||
Transport.prototype.onClose.call(this); | ||
} | ||
/** | ||
* Closes socket. | ||
@@ -93,0 +125,0 @@ * |
@@ -205,6 +205,6 @@ /** | ||
exports.request = function request (xdomain) { | ||
if ('undefined' == typeof window) { | ||
try { | ||
var _XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; | ||
return new _XMLHttpRequest(); | ||
} | ||
} catch (e) {} | ||
@@ -211,0 +211,0 @@ if (xdomain && 'undefined' != typeof XDomainRequest && !exports.ua.hasCORS) { |
{ | ||
"name": "engine.io-client", | ||
"description": "Client for the realtime Engine", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"homepage": "https://github.com/LearnBoost/engine.io-client", | ||
@@ -15,2 +15,3 @@ "contributors": [ | ||
"emitter": "git://github.com/component/emitter#1.0.0", | ||
"indexof": "0.0.1", | ||
"engine.io-parser": "0.3.0", | ||
@@ -17,0 +18,0 @@ "debug": "0.7.2" |
# Engine.IO client | ||
[![Build Status](https://secure.travis-ci.org/LearnBoost/engine.io-client.png)](http://travis-ci.org/LearnBoost/engine.io-client) | ||
[![NPM version](https://badge.fury.io/js/engine.io-client.png)](http://badge.fury.io/js/engine.io-client) | ||
@@ -98,2 +99,6 @@ This is the client for [Engine](http://github.com/learnboost/engine.io), the | ||
- Fired when an error occurs. | ||
- `flush` | ||
- Fired upon completing a buffer flush | ||
- `drain` | ||
- Fired after `drain` event of transport if writeBuffer is empty | ||
@@ -125,2 +130,3 @@ #### Methods | ||
- `String`: data to send | ||
- `Function`: optional, callback upon `drain` | ||
- `close` | ||
@@ -127,0 +133,0 @@ - Disconnects the client. |
@@ -11,2 +11,18 @@ | ||
describe('socketClosing', function () { | ||
it('should not emit close on incorrect connection', function (done) { | ||
var socket = new eio.Socket('ws://localhost:8080'); | ||
var closed = false; | ||
socket.on('close', function () { | ||
closed = true; | ||
}); | ||
setTimeout(function() { | ||
expect(closed).to.be(false); | ||
done(); | ||
}, 200); | ||
}); | ||
}); | ||
}); |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
394893
39
12784
213
6
+ Addedindexof@0.0.1
+ Addedindexof@0.0.1(transitive)