Skip to content

Commit

Permalink
Merge c33bbe2 into a11ab3a
Browse files Browse the repository at this point in the history
  • Loading branch information
nhunzaker committed Jul 9, 2015
2 parents a11ab3a + c33bbe2 commit b677fa2
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 126 deletions.
6 changes: 6 additions & 0 deletions .babelrc
@@ -0,0 +1,6 @@
{
"stage": 1,
"sourceMaps": "inline",
"optional" : [],
"plugins": []
}
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,3 +2,4 @@
node_modules
npm-debug.log
coverage
dist
35 changes: 35 additions & 0 deletions Makefile
@@ -0,0 +1,35 @@
SHELL := /bin/bash
PATH := node_modules/.bin:$(PATH)
DIST = dist
JS = $(shell find src -name '*.js*' ! -path '*/__tests__/*')

.PHONY: clean test test-watch release

all: package.json README.md LICENSE.md javascript

$(DIST):
@mkdir -p $(DIST)

%.md: $(DIST)
cp $@ $^

package.json: $(DIST)
@node -p 'p=require("./package");p.private=undefined;p.scripts=p.devDependencies=undefined;JSON.stringify(p,null,2)' > $(DIST)/package.json

javascript: $(DIST)
babel -d $^ $(JS)

release: clean all
npm publish $(DIST)

clean:
@rm -rf $(DIST)

test:
NODE_ENV=test karma start --single-run

test-watch:
NODE_ENV=test karma start

test-cov:
CONTINUOUS_INTEGRATION=true make test && coveralls < coverage/report-lcov/lcov.info
8 changes: 5 additions & 3 deletions karma.conf.js
Expand Up @@ -4,7 +4,7 @@ module.exports = function(config) {

config.set({

browsers: [ 'Firefox' ],
browsers: isIntegration ? [ 'Firefox' ] : [ 'Chrome' ],

singleRun: isIntegration,

Expand All @@ -17,7 +17,7 @@ module.exports = function(config) {
reporters: [ 'nyan', 'coverage' ],

preprocessors: {
'src/__tests__/*.js*': [ 'webpack' ]
'src/__tests__/*.js*': [ 'webpack', 'sourcemap' ]
},

coverageReporter: {
Expand All @@ -28,6 +28,8 @@ module.exports = function(config) {
},

webpack: {
devtool: 'inline-source-map',

resolve: {
extensions: ['', '.js', '.jsx'],
modulesDirectories: [ 'web_modules', 'node_modules', __dirname ]
Expand All @@ -38,7 +40,7 @@ module.exports = function(config) {
{
test : /\.jsx*$/,
exclude : /node_modules/,
loader : 'babel?stage=1&loose'
loader : 'babel'
}
],
postLoaders: [
Expand Down
46 changes: 25 additions & 21 deletions package.json
@@ -1,12 +1,13 @@
{
"name": "diode",
"private": true,
"version": "4.4.0",
"description": "A simple event emitter with tools for eventual consistency",
"description": "A simple event emitter.",
"main": "src/diode.js",
"scripts": {
"test": "karma start --single-run",
"test:watch": "karma start",
"coveralls": "CONTINUOUS_INTEGRATION=true npm test && coveralls < coverage/report-lcov/lcov.info"
"test": "make test",
"test:watch": "make test-watch",
"coveralls": "make test-cov"
},
"repository": {
"type": "git",
Expand All @@ -24,23 +25,26 @@
"bugs": "https://github.com/vigetlabs/diode/issues",
"homepage": "https://github.com/vigetlabs/diode",
"devDependencies": {
"babel-core": "^5.x.x",
"babel-loader": "^5.x.x",
"chai": "^2.2.0",
"coveralls": "^2.11.2",
"istanbul": "^0.3.5",
"istanbul-instrumenter-loader": "^0.1.2",
"karma": "^0.12.32",
"karma-cli": "0.0.4",
"karma-coverage": "^0.3.1",
"karma-firefox-launcher": "^0.1.4",
"karma-mocha": "^0.1.10",
"karma-nyan-reporter": "0.0.60",
"karma-sinon-chai": "^0.3.0",
"karma-webpack": "^1.5.0",
"mocha": "^2.2.1",
"babel": "~5.6",
"babel-core": "~5",
"babel-loader": "~5",
"chai": "~3.0",
"coveralls": "~2.11",
"istanbul": "~0.3",
"istanbul-instrumenter-loader": "~0.1",
"karma": "~0.12",
"karma-chrome-launcher": "~0.2",
"karma-cli": "~0.1",
"karma-coverage": "~0.4",
"karma-firefox-launcher": "~0.1",
"karma-mocha": "~0.2",
"karma-nyan-reporter": "~0.1",
"karma-sinon-chai": "~1.0",
"karma-sourcemap-loader": "~0.3",
"karma-webpack": "~1.5",
"mocha": "~2.2",
"react": ">= 0.12.1",
"sinon": "^1.14.1",
"webpack": "^1.x.x"
"sinon": "~1.14",
"webpack": "~1.10"
}
}
52 changes: 3 additions & 49 deletions src/__tests__/diode-test.js
Expand Up @@ -41,59 +41,14 @@ describe('Diode', function() {
Diode.emit()
})

it ('batches subscriptions on volley', function(done) {
let stub = sinon.stub()

Diode.listen(stub)

for (var i = 0; i <= 100; i++) {
Diode.volley(i)
}

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() {
let emitter = Diode.decorate({})
let spy = sinon.spy(window, 'requestAnimationFrame')

emitter.volley()

spy.should.not.have.been.called
spy.restore()
})

it ('can ignore callbacks', function(done) {
it ('can ignore callbacks', function() {
let stub = sinon.stub()

Diode.listen(stub)
Diode.ignore(stub)
Diode.volley()
Diode.emit()

requestAnimationFrame(() => {
stub.should.not.have.been.called
done()
})
stub.should.not.have.been.called
})

it ('can decorate other objects', function() {
Expand Down Expand Up @@ -124,7 +79,6 @@ describe('Diode', function() {
target.listen(mock).should.equal(target)
target.ignore(mock).should.equal(target)
target.emit().should.equal(target)
target.volley().should.equal(target)
})
})

Expand Down
67 changes: 14 additions & 53 deletions src/diode.js
Expand Up @@ -4,54 +4,20 @@
* that state has changed.
*/

/**
* Important: 120 FPS is granular enough to get around differences
* in the animation and time clock
*/
var FRAMES = 1000 / 120

function Diode(target) {
function Diode (target) {
var _callbacks = []
var _tick = target
var _lastFire = null

if (this instanceof Diode) {
target = this
} else {
target = target || {}
}

/**
* Callbacks are eventually executed, Diode does not promise
* immediate consistency so that state propagation can be batched
*/
var _flush = function(args) {
/**
* Important: do not cache the length of _callbacks
* in the event a callback causes later subscriptions
* to disappear
*/
for (var i = 0; i < _callbacks.length; i++) {
_callbacks[i].apply(target, args)
}
}

var _cancel = function() {
var now = +new Date() // IE8 love

if (_lastFire && now - _lastFire < 10) {
cancelAnimationFrame(_tick)
} else {
_lastFire = now
}

}

/**
* Given a CALLBACK function, add it to the Set of all callbacks.
*/
target.listen = target.subscribe = function(callback) {
_callbacks = _callbacks.concat(callback)
target.listen = target.subscribe = function (callback) {
_callbacks.push(callback)

return target
}
Expand All @@ -60,8 +26,8 @@ function Diode(target) {
* Given a CALLBACK function, remove it from the set of callbacks.
* Throws an error if the callback is not included in the Set.
*/
target.ignore = target.unsubscribe = function(callback) {
_callbacks = _callbacks.filter(function(i) {
target.ignore = target.unsubscribe = function (callback) {
_callbacks = _callbacks.filter(function (i) {
return i !== callback
})

Expand All @@ -71,18 +37,14 @@ function Diode(target) {
/**
* Immediately trigger every callback
*/
target.emit = target.publish = function() {
_flush(arguments)
return target
}

/**
* Lazy trigger Trigger every callback
*/
target.volley = function() {
if (_callbacks.length > 0) {
_cancel()
_tick = requestAnimationFrame(_flush.bind(undefined, arguments))
target.emit = target.publish = function (...args) {
/**
* Important: do not cache the length of _callbacks
* in the event a callback causes later subscriptions
* to disappear
*/
for (var i = 0; i < _callbacks.length; i++) {
_callbacks[i].apply(target, args)
}

return target
Expand All @@ -91,6 +53,5 @@ function Diode(target) {
return target
}

module.exports = Diode(Diode)
module.exports = Diode(Diode)
module.exports.decorate = Diode
module.exports.FRAMES = FRAMES

0 comments on commit b677fa2

Please sign in to comment.