Comparing version 0.2.6 to 0.3.0
@@ -0,1 +1,5 @@ | ||
# Chokidar 0.3.0 (June 24, 2012) | ||
* `unlink` event are no longer emitted for directories, for consistency | ||
with `add`. | ||
# Chokidar 0.2.6 (June 8, 2012) | ||
@@ -2,0 +6,0 @@ * Prevented creating of duplicate 'add' events. |
415
lib/index.js
@@ -1,245 +0,224 @@ | ||
'use strict'; | ||
// Generated by CoffeeScript 1.3.3 | ||
(function() { | ||
'use strict'; | ||
var EventEmitter = require('events').EventEmitter; | ||
var fs = require('fs'); | ||
var sysPath = require('path'); | ||
var EventEmitter, FSWatcher, fs, sysPath, | ||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
EventEmitter = require('events').EventEmitter; | ||
// Watches files & directories for changes. | ||
// | ||
// Emitted events: `add`, `change`, `unlink`, `error`. | ||
// | ||
// Examples | ||
// | ||
// var watcher = new FSWatcher() | ||
// .add(directories) | ||
// .on('add', function(path) {console.log('File', path, 'was added');}) | ||
// .on('change', function(path) {console.log('File', path, 'was changed');}) | ||
// .on('unlink', function(path) {console.log('File', path, 'was removed');}) | ||
// | ||
function FSWatcher(options) { | ||
this.options = options = options != null ? options : Object.create(null); | ||
this._handle = this._handle.bind(this); | ||
this.watched = Object.create(null); | ||
this.watchers = []; | ||
if (this.options.persistent == null) { | ||
this.options.persistent = false; | ||
} | ||
this._ignored = (function() { | ||
switch (toString.call(options.ignored)) { | ||
case '[object RegExp]': | ||
return function(string) { | ||
return options.ignored.test(string); | ||
}; | ||
case '[object Function]': | ||
return options.ignored; | ||
default: | ||
return function() { | ||
return false; | ||
}; | ||
} | ||
})(); | ||
} | ||
fs = require('fs'); | ||
// Inherit from EventEmitter. | ||
FSWatcher.prototype = Object.create(EventEmitter.prototype); | ||
sysPath = require('path'); | ||
FSWatcher.prototype._getWatchedDir = function(directory) { | ||
var dir = directory.replace(/[\\\/]$/, ''); | ||
if (this.watched[dir] == null) this.watched[dir] = []; | ||
return this.watched[dir]; | ||
}; | ||
exports.FSWatcher = FSWatcher = (function(_super) { | ||
FSWatcher.prototype._addToWatchedDir = function(directory, file) { | ||
var watchedFiles = this._getWatchedDir(directory); | ||
watchedFiles.push(file); | ||
}; | ||
__extends(FSWatcher, _super); | ||
FSWatcher.prototype._removeFromWatchedDir = function(directory, file) { | ||
var watchedFiles = this._getWatchedDir(directory); | ||
watchedFiles.some(function(watchedFile, index) { | ||
if (watchedFile === file) { | ||
watchedFiles.splice(index, 1); | ||
return true; | ||
} | ||
}); | ||
}; | ||
function FSWatcher(options) { | ||
var _base, _ref, | ||
_this = this; | ||
this.options = options != null ? options : {}; | ||
this.close = __bind(this.close, this); | ||
// Private: Handles emitting unlink events for | ||
// files and directories, and via recursion, for | ||
// files and directories within directories that are unlinked | ||
// | ||
// directory - string, directory within which the following item is located | ||
// item - string, base path of item/directory | ||
// | ||
// Returns nothing. | ||
FSWatcher.prototype._remove = function(directory, item) { | ||
var _this = this; | ||
this.add = __bind(this.add, this); | ||
// if what is being deleted is a directory, get that directory's paths | ||
// for recursive deleting and cleaning of watched object | ||
// if it is not a directory, nestedDirectoryChildren will be empty array | ||
var fullPath = sysPath.join(directory, item); | ||
var nestedDirectoryChildren = _this._getWatchedDir(fullPath).slice(); | ||
this._handle = __bind(this._handle, this); | ||
// Remove directory / file from watched list. | ||
_this._removeFromWatchedDir(directory, item); | ||
this._handleDir = __bind(this._handleDir, this); | ||
// Recursively remove children directories / files. | ||
nestedDirectoryChildren.forEach(function(nestedItem) { | ||
_this._remove(fullPath, nestedItem); | ||
}); | ||
_this.emit('unlink', fullPath); | ||
}; | ||
this._handleFile = __bind(this._handleFile, this); | ||
// Private: Watch file for changes with fs.watchFile or fs.watch. | ||
// | ||
// item - string, path to file or directory. | ||
// callback - function that will be executed on fs change. | ||
// | ||
// Returns nothing. | ||
FSWatcher.prototype._watch = function(item, itemType, callback) { | ||
var _this = this; | ||
var options, watcher; | ||
if (callback == null) callback = function() {}; | ||
var directory = sysPath.dirname(item) | ||
var basename = sysPath.basename(item); | ||
var parent = this._getWatchedDir(directory); | ||
this._watch = __bind(this._watch, this); | ||
// Prevent memory leaks. | ||
if (parent.indexOf(basename) >= 0) return; | ||
this._remove = __bind(this._remove, this); | ||
_this._addToWatchedDir(directory, basename); | ||
this._removeFromWatchedDir = __bind(this._removeFromWatchedDir, this); | ||
if (process.platform === 'win32') { | ||
watcher = fs.watch(item, { | ||
persistent: this.options.persistent | ||
}, function(event, path) { | ||
callback(item); | ||
}); | ||
this.watchers.push(watcher); | ||
} else { | ||
options = { | ||
persistent: this.options.persistent, | ||
interval: 100 | ||
this._addToWatchedDir = __bind(this._addToWatchedDir, this); | ||
this._getWatchedDir = __bind(this._getWatchedDir, this); | ||
this.watched = Object.create(null); | ||
this.watchers = []; | ||
if ((_ref = (_base = this.options).persistent) == null) { | ||
_base.persistent = false; | ||
} | ||
this._ignored = (function() { | ||
switch (toString.call(_this.options.ignored)) { | ||
case '[object RegExp]': | ||
return function(string) { | ||
return this.options.ignored.test(string); | ||
}; | ||
case '[object Function]': | ||
return _this.options.ignored; | ||
default: | ||
return function() { | ||
return false; | ||
}; | ||
} | ||
})(); | ||
} | ||
FSWatcher.prototype._getWatchedDir = function(directory) { | ||
var dir, _base, _ref; | ||
dir = directory.replace(/[\\\/]$/, ''); | ||
return (_ref = (_base = this.watched)[dir]) != null ? _ref : _base[dir] = []; | ||
}; | ||
fs.watchFile(item, options, function(curr, prev) { | ||
if (curr.mtime.getTime() !== prev.mtime.getTime()) { | ||
callback(item); | ||
FSWatcher.prototype._addToWatchedDir = function(directory, file) { | ||
var watchedFiles; | ||
watchedFiles = this._getWatchedDir(directory); | ||
return watchedFiles.push(file); | ||
}; | ||
FSWatcher.prototype._removeFromWatchedDir = function(directory, file) { | ||
var watchedFiles, | ||
_this = this; | ||
watchedFiles = this._getWatchedDir(directory); | ||
return watchedFiles.some(function(watchedFile, index) { | ||
if (watchedFile === file) { | ||
watchedFiles.splice(index, 1); | ||
return true; | ||
} | ||
}); | ||
}; | ||
FSWatcher.prototype._remove = function(directory, item) { | ||
var fullPath, nestedDirectoryChildren, | ||
_this = this; | ||
fullPath = sysPath.join(directory, item); | ||
nestedDirectoryChildren = this._getWatchedDir(fullPath).slice(); | ||
this._removeFromWatchedDir(directory, item); | ||
nestedDirectoryChildren.forEach(function(nestedItem) { | ||
return _this._remove(fullPath, nestedItem); | ||
}); | ||
return this.emit('unlink', fullPath); | ||
}; | ||
FSWatcher.prototype._watch = function(item, itemType, callback) { | ||
var basename, directory, options, parent, watcher, | ||
_this = this; | ||
if (callback == null) { | ||
callback = (function() {}); | ||
} | ||
}); | ||
} | ||
if (itemType === 'file') _this.emit('add', item); | ||
}; | ||
directory = sysPath.dirname(item); | ||
basename = sysPath.basename(item); | ||
parent = this._getWatchedDir(directory); | ||
options = { | ||
persistent: this.options.persistent | ||
}; | ||
if (parent.indexOf(basename) >= 0) { | ||
return; | ||
} | ||
this._addToWatchedDir(directory, basename); | ||
if (process.platform === 'win32') { | ||
watcher = fs.watch(item, options, function(event, path) { | ||
return callback(item); | ||
}); | ||
this.watchers.push(watcher); | ||
} else { | ||
options.interval = 100; | ||
fs.watchFile(item, options, function(curr, prev) { | ||
if (curr.mtime.getTime() !== prev.mtime.getTime()) { | ||
return callback(item); | ||
} | ||
}); | ||
} | ||
if (itemType === 'file') { | ||
return this.emit('add', item); | ||
} | ||
}; | ||
// Private: Emit `change` event once and watch file to emit it in the future | ||
// once the file is changed. | ||
// | ||
// file - string, fs path. | ||
// | ||
// Returns nothing. | ||
FSWatcher.prototype._handleFile = function(file) { | ||
var _this = this; | ||
_this._watch(file, 'file', function(file) { | ||
_this.emit('change', file); | ||
}); | ||
}; | ||
FSWatcher.prototype._handleFile = function(file) { | ||
var _this = this; | ||
return this._watch(file, 'file', function(file) { | ||
return _this.emit('change', file); | ||
}); | ||
}; | ||
// Private: Read directory to add / remove files from `@watched` list | ||
// and re-read it on change. | ||
// | ||
// directory - string, fs path. | ||
// | ||
// Returns nothing. | ||
FSWatcher.prototype._handleDir = function(directory) { | ||
var _this = this; | ||
var read = function(directory) { | ||
fs.readdir(directory, function(error, current) { | ||
var previous; | ||
if (error != null) return _this.emit('error', error); | ||
if (!current) return; | ||
previous = _this._getWatchedDir(directory); | ||
FSWatcher.prototype._handleDir = function(directory) { | ||
var read, | ||
_this = this; | ||
read = function(directory) { | ||
return fs.readdir(directory, function(error, current) { | ||
var previous; | ||
if (error != null) { | ||
return _this.emit('error', error); | ||
} | ||
if (!current) { | ||
return; | ||
} | ||
previous = _this._getWatchedDir(directory); | ||
previous.filter(function(file) { | ||
return current.indexOf(file) < 0; | ||
}).forEach(function(file) { | ||
return _this._remove(directory, file); | ||
}); | ||
return current.filter(function(file) { | ||
return previous.indexOf(file) < 0; | ||
}).forEach(function(file) { | ||
return _this._handle(sysPath.join(directory, file)); | ||
}); | ||
}); | ||
}; | ||
read(directory); | ||
return this._watch(directory, 'directory', read); | ||
}; | ||
// Files that absent in current directory snapshot | ||
// but present in previous emit `remove` event | ||
// and are removed from @watched[directory]. | ||
previous | ||
.filter(function(file) { | ||
return current.indexOf(file) < 0; | ||
}) | ||
.forEach(function(file) { | ||
_this._remove(directory,file); | ||
FSWatcher.prototype._handle = function(item) { | ||
var _this = this; | ||
if (this._ignored(item)) { | ||
return; | ||
} | ||
return fs.realpath(item, function(error, path) { | ||
if (error != null) { | ||
return _this.emit('error', error); | ||
} | ||
return fs.stat(item, function(error, stats) { | ||
if (error != null) { | ||
return _this.emit('error', error); | ||
} | ||
if (stats.isFile()) { | ||
_this._handleFile(item); | ||
} | ||
if (stats.isDirectory()) { | ||
return _this._handleDir(item); | ||
} | ||
}); | ||
}); | ||
}; | ||
// Files that present in current directory snapshot | ||
// but absent in previous are added to watch list and | ||
// emit `add` event. | ||
current | ||
.filter(function(file) { | ||
return previous.indexOf(file) < 0; | ||
}) | ||
.forEach(function(file) { | ||
_this._handle(sysPath.join(directory, file)); | ||
FSWatcher.prototype.add = function(files) { | ||
if (!Array.isArray(files)) { | ||
files = [files]; | ||
} | ||
files.forEach(this._handle); | ||
return this; | ||
}; | ||
FSWatcher.prototype.close = function() { | ||
var _this = this; | ||
this.watchers.forEach(function(watcher) { | ||
return watcher.close(); | ||
}); | ||
Object.keys(this.watched).forEach(function(directory) { | ||
return _this.watched[directory].forEach(function(file) { | ||
return fs.unwatchFile(sysPath.join(directory, file)); | ||
}); | ||
}); | ||
}; | ||
read(directory); | ||
this._watch(directory, 'directory', read); | ||
}; | ||
}); | ||
this.watched = Object.create(null); | ||
return this; | ||
}; | ||
// Private: Handle added file or directory. | ||
// Delegates call to _handleFile / _handleDir after checks. | ||
// | ||
// item - string, path to file or directory. | ||
// | ||
// Returns nothing. | ||
FSWatcher.prototype._handle = function(item) { | ||
var _this = this; | ||
// Don't handle invalid files, dotfiles etc. | ||
if (this._ignored(item)) return; | ||
// Get the canonicalized absolute pathname. | ||
fs.realpath(item, function(error, path) { | ||
if (error != null) return _this.emit('error', error); | ||
// Get file info, check is it file, directory or something else. | ||
fs.stat(item, function(error, stats) { | ||
if (error != null) return _this.emit('error', error); | ||
if (stats.isFile()) _this._handleFile(item); | ||
if (stats.isDirectory()) _this._handleDir(item); | ||
}); | ||
}); | ||
}; | ||
return FSWatcher; | ||
// Public: Adds directories / files for tracking. | ||
// | ||
// * files - array of strings (file paths). | ||
// | ||
// Examples | ||
// | ||
// add ['app', 'vendor'] | ||
// | ||
// Returns an instance of FSWatcher for chaning. | ||
FSWatcher.prototype.add = function(files) { | ||
if (!Array.isArray(files)) files = [files]; | ||
files.forEach(this._handle); | ||
return this; | ||
}; | ||
})(EventEmitter); | ||
// Public: Remove all listeners from watched files. | ||
// Returns an instance of FSWatcher for chaning. | ||
FSWatcher.prototype.close = function() { | ||
var _this = this; | ||
this.watchers.forEach(function(watcher) { | ||
watcher.close(); | ||
}); | ||
Object.keys(this.watched).forEach(function(directory) { | ||
_this.watched[directory].forEach(function(file) { | ||
fs.unwatchFile(sysPath.join(directory, file)); | ||
}); | ||
}); | ||
this.watched = Object.create(null); | ||
return this; | ||
}; | ||
exports.watch = function(files, options) { | ||
return new FSWatcher(options).add(files); | ||
}; | ||
exports.watch = function(files, options) { | ||
return new FSWatcher(options).add(files); | ||
}; | ||
}).call(this); |
{ | ||
"name": "chokidar", | ||
"description": "A neat wrapper around node.js fs.watch / fs.watchFile.", | ||
"version": "0.2.6", | ||
"version": "0.3.0", | ||
"keywords": ["fs", "watch", "watchFile", "watcher", "file"], | ||
@@ -23,2 +23,7 @@ "homepage": "https://github.com/paulmillr/chokidar", | ||
}, | ||
"scripts": { | ||
"prepublish": "coffee -o lib/ src/", | ||
"postinstall": "node setup.js postinstall", | ||
"test": "node setup.js test" | ||
}, | ||
"dependencies": {}, | ||
@@ -25,0 +30,0 @@ "devDependencies": { |
@@ -32,3 +32,3 @@ # Chokidar | ||
var watcher = chokidar.watch('file or dir', {ignored: /^\./}); | ||
var watcher = chokidar.watch('file or dir', {ignored: /^\./, persistent: true}); | ||
@@ -35,0 +35,0 @@ watcher |
Sorry, the diff of this file is not supported yet
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
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
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
18597
7
218
2
2
2