Comparing version 4.3.0 to 4.4.0
# Changelog | ||
## 4.4.0 | ||
- When executed continuously, at 120 frames per second, `volley` will | ||
allow a change event to slip through every frame. This should better | ||
support streaming change events for animation. | ||
``` | ||
Compressed : 592 bytes | ||
Gzipped : 348 bytes | ||
``` | ||
## 4.3.0 | ||
@@ -4,0 +15,0 @@ |
{ | ||
"name": "diode", | ||
"version": "4.3.0", | ||
"version": "4.4.0", | ||
"description": "A simple event emitter with tools for eventual consistency", | ||
@@ -8,2 +8,3 @@ "main": "src/diode.js", | ||
"test": "karma start --single-run", | ||
"test:watch": "karma start", | ||
"coveralls": "CONTINUOUS_INTEGRATION=true npm test && coveralls < coverage/report-lcov/lcov.info" | ||
@@ -10,0 +11,0 @@ }, |
@@ -49,12 +49,29 @@ var Diode = require('../diode') | ||
for (var i = 1000; i > 0; i--) { | ||
Diode.volley() | ||
for (var i = 0; i <= 100; i++) { | ||
Diode.volley(i) | ||
} | ||
requestAnimationFrame(() => { | ||
setTimeout(function() { | ||
stub.should.have.been.calledOnce | ||
stub.should.have.been.calledWith(100) | ||
done() | ||
}) | ||
}, 50) | ||
}) | ||
it ('allows high-frequency subscriptions to pass through cancellation', function(done) { | ||
let stub = sinon.stub() | ||
let time = Date.now() | ||
Diode.listen(stub) | ||
while (Date.now() - time < Diode.FRAMES * 2) { | ||
Diode.volley() | ||
} | ||
setTimeout(function() { | ||
stub.should.have.been.calledTwice | ||
done() | ||
}, 50) | ||
}) | ||
it ('does not volley if no callbacks exist', function() { | ||
@@ -86,8 +103,4 @@ let emitter = Diode.decorate({}) | ||
for (var i in Diode) { | ||
if (i !== 'decorate') { | ||
target.should.have.property(i) | ||
} | ||
} | ||
target.should.have.property('publish') | ||
target.should.have.property('subscribe') | ||
target.should.have.property('prop', 'test') | ||
@@ -94,0 +107,0 @@ }) |
@@ -7,5 +7,12 @@ /** | ||
/** | ||
* Important: 120 FPS is granular enough to get around differences | ||
* in the animation and time clock | ||
*/ | ||
var FRAMES = 1000 / 120 | ||
function Diode(target) { | ||
var _callbacks = [] | ||
var _tick = target | ||
var _lastFire = null | ||
@@ -22,3 +29,3 @@ if (this instanceof Diode) { | ||
*/ | ||
var _flush = function() { | ||
var _flush = function(args) { | ||
/** | ||
@@ -30,6 +37,17 @@ * Important: do not cache the length of _callbacks | ||
for (var i = 0; i < _callbacks.length; i++) { | ||
_callbacks[i].apply(target, arguments) | ||
_callbacks[i].apply(target, args) | ||
} | ||
} | ||
var _cancel = function() { | ||
var now = +new Date() // IE8 love | ||
if (_lastFire && now - _lastFire < 10) { | ||
cancelAnimationFrame(_tick) | ||
} else { | ||
_lastFire = now | ||
} | ||
} | ||
/** | ||
@@ -60,4 +78,3 @@ * Given a CALLBACK function, add it to the Set of all callbacks. | ||
target.emit = target.publish = function() { | ||
_flush.apply(target, arguments) | ||
_flush(arguments) | ||
return target | ||
@@ -70,9 +87,5 @@ } | ||
target.volley = function() { | ||
var args = arguments | ||
if (_callbacks.length > 0) { | ||
cancelAnimationFrame(_tick) | ||
_tick = requestAnimationFrame(function() { | ||
_flush.apply(target, args) | ||
}) | ||
_cancel() | ||
_tick = requestAnimationFrame(_flush.bind(undefined, arguments)) | ||
} | ||
@@ -86,3 +99,4 @@ | ||
module.exports = Diode(Diode) | ||
module.exports = Diode(Diode) | ||
module.exports.decorate = Diode | ||
module.exports.FRAMES = FRAMES |
16977
319