Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

chokidar

Package Overview
Dependencies
Maintainers
1
Versions
106
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chokidar - npm Package Compare versions

Comparing version 0.2.6 to 0.3.0

setup.js

4

CHANGELOG.md

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc