diff --git a/lib/build-response.js b/lib/build-response.js index 6e047b1..27d877b 100644 --- a/lib/build-response.js +++ b/lib/build-response.js @@ -5,6 +5,7 @@ var prepare = require('prepare-response'); var uglify = require('uglify-js'); var watchify = require('watchify'); var buildBundle = require('./build-bundle'); +var shouldPoll = require('./should-poll.js'); module.exports = function send(path, options) { var bundle = buildBundle(path, options); @@ -18,27 +19,38 @@ module.exports = function send(path, options) { } else if (options.cache === 'dynamic') { var response, resolve; var updatingTimeout; - bundle = watchify(bundle, {poll: true, delay: 0}); - bundle.on('update', function () { - if (resolve) { - clearTimeout(updatingTimeout); - } else { - response = new Promise(function (_resolve) { - resolve = _resolve; - }); - } - updatingTimeout = setTimeout(function rebuild() { - resolve(getResponse(bundle, options)); - resolve = undefined; - }, 600); + + var watchifyBundle = shouldPoll() + .then(function(poll) { + bundle = watchify(bundle, {poll: poll, delay: 0}); + bundle.on('update', function () { + if (resolve) { + clearTimeout(updatingTimeout); + } else { + response = new Promise(function (_resolve) { + resolve = _resolve; + }); + } + updatingTimeout = setTimeout(function rebuild() { + resolve(getResponse(bundle, options)); + resolve = undefined; + }, 600); + }); + return bundle; }); - response = Promise.resolve(getResponse(bundle, options)); + + response = watchifyBundle.then(function(bundle) { + return getResponse(bundle, options); + }); + return { send: function (req, res, next) { response.done(function (response) { response.send(req, res, next); }, next); }, dispose: function () { - bundle.close(); + watchifyBundle.then(function(bundle) { + bundle.close(); + }); } }; } else { diff --git a/lib/should-poll.js b/lib/should-poll.js new file mode 100644 index 0000000..913abb8 --- /dev/null +++ b/lib/should-poll.js @@ -0,0 +1,50 @@ +'use strict'; + +var Promise = require('promise'); +var buildBundle = require('./build-bundle'); +var fs = require('fs'); +var tmp = require('tmp'); +var watchify = require('watchify'); + +function shouldPoll() { + + return new Promise(function(resolve, reject) { + var file = tmp.fileSync(); + + var bundle = buildBundle(file.name, {}); + watchify(bundle, { poll: false, delay: 0 }); + + var resolved = false; + + function decide(pollEnabled) { + bundle.close(); + file.removeCallback(); + if (!resolved) { + resolved = true; + resolve(pollEnabled); + } + } + + bundle.once('bundle', function(b) { + b.once('error', reject); + // end event is never fired without having a data + b.once('data', function() {}); + b.once('end', function() { + + bundle.once('update', function() { + decide(true); + }); + + setTimeout(decide, 1000, false); + + fs.appendFileSync(file.name, 'var a = 1;'); + }); + }); + + bundle.once('error', reject); + bundle.bundle(); + }); + +} + +module.exports = shouldPoll; diff --git a/package.json b/package.json index ddeb8b9..67fa519 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "ms": "^0.7.1", "prepare-response": "^1.1.2", "promise": "^7.0.3", + "tmp": "0.0.28", "uglify-js": "^2.4.23", "watchify": "^3.3.0" } -} \ No newline at end of file +} diff --git a/test/should-poll-test.js b/test/should-poll-test.js new file mode 100644 index 0000000..cf884c3 --- /dev/null +++ b/test/should-poll-test.js @@ -0,0 +1,16 @@ +var shouldPoll = require('../lib/should-poll.js'); +var assert = require('assert'); + +describe('should-poll', function() { + it('should be a function', function() { + assert.equal(typeof shouldPoll, 'function'); + }); + it('should resolve to true or false', function(done) { + shouldPoll() + .then(function(pollingEnabled) { + assert(typeof pollingEnabled === 'boolean'); + }) + .then(done) + .catch(done); + }); +});