Comparing version 0.2.2 to 0.3.0
@@ -69,5 +69,3 @@ /* | ||
// Delay for events called in succession for the same file/event | ||
debounceDelay: 500, | ||
// Use a desired watch method over the other | ||
forceWatchMethod: false | ||
debounceDelay: 500 | ||
}); | ||
@@ -98,5 +96,3 @@ | ||
// Initialize the watch on files | ||
this.add(files, function() { | ||
_this._initWatched(done); | ||
}); | ||
this.add(files, done); | ||
@@ -161,3 +157,5 @@ return this; | ||
fs.unwatchFile(dir); | ||
_this._watched[dir].forEach(fs.unwatchFile); | ||
_this._watched[dir].forEach(function(uFile) { | ||
fs.unwatchFile(uFile); | ||
}); | ||
}); | ||
@@ -319,3 +317,3 @@ if (_reset) { | ||
this._patterns.forEach(function(pattern) { | ||
if (matched = minimatch(file, pattern)) { | ||
if (matched || (matched = minimatch(file, pattern)) ) { | ||
return false; | ||
@@ -327,35 +325,30 @@ } | ||
// Wrapper for fs.watch/fs.watchFile | ||
Gaze.prototype._watchFile = function(file, done) { | ||
Gaze.prototype._watchDir = function(dir, done) { | ||
var _this = this; | ||
var opts = Object.create(this.options); | ||
// TODO: Optimize this. Should kill the other func per event | ||
// then unwatch files to not even bother using the method | ||
var watchOne = function() { done(null, file); }; | ||
var watchTwo = function() { done(null, file); }; | ||
try { | ||
if (_this.options.forceWatchMethod === false || _this.options.forceWatchMethod === 'new') { | ||
_this._watchers[file] = fs.watch(file, opts, function(event) { | ||
if (typeof watchOne === 'function') { | ||
watchTwo = null; | ||
watchOne(); | ||
_this._watchers[dir] = fs.watch(dir, function(event) { | ||
// race condition. Let's give the fs a little time to settle down. so we | ||
// don't fire events on non existent files. | ||
setTimeout(function() { | ||
if (fs.existsSync(dir)) { | ||
done(null, dir); | ||
} | ||
}); | ||
} | ||
if (_this.options.forceWatchMethod === false || _this.options.forceWatchMethod === 'old') { | ||
}, delay + 100); | ||
}); | ||
} catch (err) { | ||
return this._handleError(err); | ||
} | ||
return this; | ||
}; | ||
Gaze.prototype._pollFile = function(file, done) { | ||
var _this = this; | ||
var opts = { persistent: true, interval: _this.options.interval }; | ||
try { | ||
fs.watchFile(file, opts, function(curr, prev) { | ||
if (curr.mtime.getTime() !== prev.mtime.getTime()) { | ||
if (typeof watchTwo === 'function') { | ||
watchOne = null; | ||
watchTwo(); | ||
} | ||
} | ||
done(null, file); | ||
}); | ||
} catch (err) { | ||
return this._handleError(err); | ||
} | ||
} catch (err) { | ||
if (err.code === 'EMFILE') { | ||
return this.emit('error', new Error('EMFILE: Too many opened files.')); | ||
} | ||
return this.emit('error', err); | ||
} | ||
return this; | ||
@@ -368,12 +361,26 @@ }; | ||
var cwd = this.options.cwd || process.cwd(); | ||
async.forEachSeries(Object.keys(_this._watched), function(dir, next) { | ||
var curWatched = Object.keys(_this._watched); | ||
async.forEachSeries(curWatched, function(dir, next) { | ||
var files = _this._watched[dir]; | ||
// Triggered when a watched dir has an event | ||
_this._watchFile(dir, function(event, dirpath) { | ||
_this._watchDir(dir, function(event, dirpath) { | ||
var relDir = cwd === dir ? '.' : path.relative(cwd, dir); | ||
return fs.readdir(dirpath, function(err, current) { | ||
fs.readdir(dirpath, function(err, current) { | ||
if (err) { return _this.emit('error', err); } | ||
if (!current) { return; } | ||
try { | ||
// append path.sep to directories so they match previous. | ||
current = current.map(function(curPath) { | ||
if (fs.existsSync(curPath) && fs.statSync(path.join(dir, curPath)).isDirectory()) { | ||
return curPath + path.sep; | ||
} else { | ||
return curPath; | ||
} | ||
}); | ||
} catch (err) { | ||
// race condition-- sometimes the file no longer exists | ||
} | ||
// Get watched files for this dir | ||
@@ -406,2 +413,3 @@ var previous = _this.relative(relDir); | ||
}); | ||
}); | ||
@@ -412,3 +420,4 @@ }); | ||
files.forEach(function(file) { | ||
_this._watchFile(file, function(err, filepath) { | ||
if (_this._isDir(file)) { return; } | ||
_this._pollFile(file, function(err, filepath) { | ||
// Only emit changed if the file still exists | ||
@@ -418,3 +427,3 @@ // Prevents changed/deleted duplicate events | ||
// When a file is added, a folder changed event emits first | ||
if (fs.existsSync(filepath) && !_this._isDir(file)) { | ||
if (fs.existsSync(filepath)) { | ||
_this.emit('changed', filepath); | ||
@@ -437,1 +446,9 @@ } | ||
}; | ||
// If an error, handle it here | ||
Gaze.prototype._handleError = function(err) { | ||
if (err.code === 'EMFILE') { | ||
return this.emit('error', new Error('EMFILE: Too many opened files.')); | ||
} | ||
return this.emit('error', err); | ||
}; |
{ | ||
"name": "gaze", | ||
"description": "A globbing fs.watch wrapper built from the best parts of other fine watch libs.", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"homepage": "https://github.com/shama/gaze", | ||
@@ -6,0 +6,0 @@ "author": { |
@@ -107,6 +107,2 @@ # gaze [![Build Status](https://secure.travis-ci.org/shama/gaze.png?branch=master)](http://travis-ci.org/shama/gaze) | ||
file/event | ||
* `forceWatchMethod` {'new'|'old'|false} Defaults to `false` to pick the first | ||
triggered watch method. Set to `'new'` to only use `fs.watch` or `'old'` to | ||
only use `fs.watchFile`. `'old'` is recommended if watch isn't firing or | ||
you're watching files over a network. | ||
@@ -150,6 +146,4 @@ #### Events | ||
This is because of your system's max opened file limit. For OSX the default is | ||
very low (256). Increase your limit with `ulimit -n 10480`, the number being the | ||
new max limit. If you're still running into issues then consider setting the | ||
option `forceWatchMethod: 'old'` to use the old and slower stat polling watch | ||
method. | ||
very low (256). Increase your limit temporarily with `ulimit -n 10480`, the | ||
number being the new max limit. | ||
@@ -162,2 +156,3 @@ ## Contributing | ||
## Release History | ||
* 0.3.0 - Handle safewrite events, `forceWatchMethod` option removed, bug fixes and watch optimizations (@rgaskill). | ||
* 0.2.2 - Fix issue where subsequent add calls dont get watched (@samcday). removeAllListeners on close. | ||
@@ -164,0 +159,0 @@ * 0.2.1 - Fix issue with invalid `added` events in current working dir. |
@@ -127,3 +127,7 @@ 'use strict'; | ||
}); | ||
fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js'), 'var one = true;'); | ||
setTimeout(function() { | ||
fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'one.js'), 'var one = true;'); | ||
}, 1000); | ||
}); | ||
@@ -197,25 +201,3 @@ }, | ||
}); | ||
}, | ||
forceWatchMethodOld: function(test) { | ||
test.expect(1); | ||
gaze('**/*', {forceWatchMethod:'old'}, function(err, watcher) { | ||
watcher.on('all', function(e, filepath) { | ||
test.ok(true); | ||
watcher.close(); | ||
test.done(); | ||
}); | ||
fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'two.js'), 'var two = true;'); | ||
}); | ||
}, | ||
forceWatchMethodNew: function(test) { | ||
test.expect(1); | ||
gaze('**/*', {forceWatchMethod:'new'}, function(err, watcher) { | ||
watcher.on('all', function(e, filepath) { | ||
test.ok(true); | ||
watcher.close(); | ||
test.done(); | ||
}); | ||
fs.writeFileSync(path.resolve(__dirname, 'fixtures', 'sub', 'two.js'), 'var two = true;'); | ||
}); | ||
} | ||
}; |
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
36542
25
921
169
5