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

watchr

Package Overview
Dependencies
Maintainers
1
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

watchr - npm Package Compare versions

Comparing version 2.2.1 to 2.3.0

16

History.md
## History
- v2.3.0 December 17, 2012
- This is a backwards compatiblity break, however updating is easy, read the notes below.
- We've updated the events we emit to be:
- `log` for debugging, receives the arguments `logLevel ,args...`
- `watching` for when watching of the path has completed, receives the arguments `err, isWatching`
- `change` for listening to change events, receives the arguments `changeType, fullPath, currentStat, previousStat`
- `error` for gracefully listening to error events, receives the arguments `err`
- read the README to learn how to bind to these new events
- The `changeType` argument for change listeners has been changed for better clarity and consitency:
- `change` is now `update`
- `new` is now `create`
- `unlink` is now `delete`
- We've updated the return arguments for `require('watchr).watch` for better consitency:
- if you send the `paths` option, you will receive the arguments `err, results` where `results` is an array of watcher instances
- if you send the `path` option, you receive the arguments `err, watcherInstance`
- v2.2.1 December 16, 2012

@@ -4,0 +20,0 @@ - Fixed sub directory scans ignoring our ignore patterns

30

out/bin/watchr.js

@@ -17,13 +17,27 @@ // Generated by CoffeeScript 1.4.0

path: watchPath,
listener: function() {
listeners: {
log: function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return console.log('a log message occured:', args);
},
error: function(err) {
return console.log('an error occured:', err);
},
watching: function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return console.log('a new watcher instance finished setting up', args);
},
change: function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return console.log('a change event occured:', args);
}
},
next: function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return console.log('a watch event occured:', ++changes, ':', args);
},
next: function(err, watcher) {
if (err) {
throw err;
}
return console.log('now watching:', watchPath);
return console.log('watching for all our paths has completed', args);
}
});
// Generated by CoffeeScript 1.4.0
/*
Watchr is used to be nofitied when a change happens to, or within a directory.
You will not be notified what file was changed, or how it was changed.
It will track new files and their changes too, and remove listeners for deleted files appropriatly.
The source code here is written as an experiment of literate programming
Which means you would be able to understand it, without knowing code
*/
var EventEmitter, Watcher, balUtil, createWatcher, debug, fsUtil, pathUtil, watch, watchers,
var EventEmitter, Watcher, balUtil, createWatcher, fsUtil, pathUtil, watch, watchers,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,

@@ -25,4 +17,15 @@ __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; },

debug = false;
/*
Now to make watching files more convient and managed, we'll create a class which we can use to attach to each file.
It'll provide us with the API and abstraction we need to accomplish difficult things like recursion.
We'll also store a global store of all the watchers and their paths so we don't have multiple watchers going at the same time
for the same file - as that would be quite ineffecient.
Events:
- `log` for debugging, receives the arguments `logLevel ,args...`
- `error` for gracefully listening to error events, receives the arguments `err`
- `watching` for when watching of the path has completed, receives the arguments `err, watcherInstance, isWatching`
- `change` for listening to change events, receives the arguments `changeType, fullPath, currentStat, previousStat`
*/
watchers = {};

@@ -51,62 +54,80 @@

function _Class(config, next) {
var applyStat, listener, watcher, _base, _base1, _base2, _base3, _base4, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6,
_this = this;
_ref = balUtil.extractOptsAndCallback(config, next), config = _ref[0], next = _ref[1];
watcher = this;
this.bubbler = __bind(this.bubbler, this);
this.bubble = __bind(this.bubble, this);
this.children = {};
applyStat = function(stat) {
_this.stat = stat;
_this.isDirectory = stat.isDirectory();
return _this.watch(function(err) {
return typeof next === "function" ? next(err, watcher) : void 0;
});
};
this.config = {};
if (config.next != null) {
if (next == null) {
next = config.next;
}
delete config.next;
}
if (config) {
this.setup(config);
}
if (next) {
this.watch(next);
}
this;
}
_Class.prototype.log = function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
this.emit.apply(this, ['log'].concat(__slice.call(args)));
return this;
};
/*
Setup our Instance
config =
- `path` a single path to watch
- `listener` (optional, detaults to null) single change listener, forwared to @listen
- `listeners` (optional, defaults to null) multiple event listeners, forwarded to @listen
- `stat` (optional, defaults to `null`) a file stat object to use for the path, instead of fetching a new one
- `ignoreHiddenFiles` (optional, defaults to `false`) whether or not to ignored files which filename starts with a `.`
- `ignoreCommonPatterns` (optional, defaults to `true`) whether or not to ignore common undesirable file patterns (e.g. `.svn`, `.git`, `.DS_Store`, `thumbs.db`, etc)
- `ignoreCustomPatterns` (optional, defaults to `null`) any custom ignore patterns that you would also like to ignore along with the common patterns
- `interval` (optional, defaults to `100`) for systems that poll to detect file changes, how often should it poll in millseconds
- `persistent` (optional, defaults to `true`) whether or not we should keep the node process alive for as long as files are still being watched
*/
_Class.prototype.setup = function(config) {
var _base, _base1, _base2, _base3, _base4, _ref, _ref1, _ref2, _ref3, _ref4;
this.path = config.path;
this.config = config;
if ((_ref1 = (_base = this.config).ignoreHiddenFiles) == null) {
if ((_ref = (_base = this.config).ignoreHiddenFiles) == null) {
_base.ignoreHiddenFiles = false;
}
if ((_ref2 = (_base1 = this.config).ignoreCommonPatterns) == null) {
if ((_ref1 = (_base1 = this.config).ignoreCommonPatterns) == null) {
_base1.ignoreCommonPatterns = true;
}
if ((_ref3 = (_base2 = this.config).ignoreCustomPatterns) == null) {
if ((_ref2 = (_base2 = this.config).ignoreCustomPatterns) == null) {
_base2.ignoreCustomPatterns = null;
}
if ((_ref4 = (_base3 = this.config).interval) == null) {
if ((_ref3 = (_base3 = this.config).interval) == null) {
_base3.interval = 100;
}
if ((_ref5 = (_base4 = this.config).persistent) == null) {
if ((_ref4 = (_base4 = this.config).persistent) == null) {
_base4.persistent = true;
}
if (config.listener) {
this.listen(config.listener);
if (this.config.stat) {
this.stat = this.config.stat;
this.isDirectory = this.stat.isDirectory();
delete this.config.stat;
}
if (config.listeners) {
_ref6 = config.listeners;
for (_i = 0, _len = _ref6.length; _i < _len; _i++) {
listener = _ref6[_i];
this.listen(listener);
if (this.config.listener || this.config.listeners) {
this.removeAllListeners();
if (this.config.listener) {
this.listen(this.config.listener);
delete this.config.listener;
}
if (this.config.listeners) {
this.listen(this.config.listeners);
delete this.config.listeners;
}
}
if (config.stat) {
applyStat(config.stat);
} else {
balUtil.stat(config.path, function(err, stat) {
if (watcher.state !== 'pending') {
return;
}
if (err) {
throw err;
}
return applyStat(stat);
});
}
}
_Class.prototype.listen = function(listener) {
this.removeListener('changed', listener);
this.on('changed', listener);
if (debug) {
console.log("added a listener: on " + this.path);
}
return this;

@@ -116,13 +137,91 @@ };

_Class.prototype.bubble = function() {
var args, currentStat, eventName, filename, previousStat;
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
eventName = args[0], filename = args[1], currentStat = args[2], previousStat = args[3];
if (debug) {
console.log("bubble: " + eventName + ": " + filename + " on " + this.path);
this.log('debug', "bubble on " + this.path + " with the args:", args);
this.emit.apply(this, args);
return this;
};
_Class.prototype.bubbler = function(eventName) {
var _this = this;
return function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return _this.bubble.apply(_this, args);
};
};
/*
Listen
Add listeners to our watcher instance.
Overloaded to also accept the following:
- `changeListener` a single change listener
- `[changeListener]` an array of change listeners
- `{eventName:eventListener}` an object keyed with the event names and valued with a single event listener
- `{eventName:[eventListener]}` an object keyed with the event names and valued with an array of event listeners
*/
_Class.prototype.listen = function(eventName, listener) {
var listenerArray, listeners, _i, _j, _len, _len1;
if (listener == null) {
listeners = eventName;
if (balUtil.isArray(listeners)) {
for (_i = 0, _len = listeners.length; _i < _len; _i++) {
listener = listeners[_i];
this.listen('change', listener);
}
} else if (balUtil.isPlainObject(listeners)) {
for (eventName in listeners) {
if (!__hasProp.call(listeners, eventName)) continue;
listenerArray = listeners[eventName];
if (balUtil.isArray(listenerArray)) {
for (_j = 0, _len1 = listenerArray.length; _j < _len1; _j++) {
listener = listenerArray[_j];
this.listen(eventName, listener);
}
} else {
this.listen(eventName, listenerArray);
}
}
} else {
this.listen('change', listeners);
}
} else {
this.removeListener(eventName, listener);
this.on(eventName, listener);
this.log('debug', "added a listener: on " + this.path + " for event " + eventName);
}
this.emit('changed', eventName, filename, currentStat, previousStat);
return this;
};
_Class.prototype.changed = function() {
/*
Listener
A change event has fired
Things to note:
- watchFile:
- currentStat still exists even for deleted/renamed files
- for deleted and updated files, it will fire on the file
- for created files, it will fire on the directory
- fsWatcher:
- eventName is always 'change'
- 'rename' is not yet implemented by node
- currentStat still exists even for deleted/renamed files
- previousStat is accurate, however we already have this
- for deleted and changed files, it will fire on the file
- for new files, it will fire on the directory
Arguments for our change listener will be:
- for updated files the arguments will be: `'update', fullPath, currentStat, previousStat`
- for created files the arguments will be: `'create', fullPath, currentStat, null`
- for deleted files the arguments will be: `'delete', fullPath, null, previousStat`
In the future we will add:
- for renamed files: 'rename', fullPath, currentStat, previousStat, newFullPath
- rename is possible as the stat.ino is the same for the delete and create
*/
_Class.prototype.listener = function() {
var args, currentStat, determineTheChange, fileExists, fileFullPath, isTheSame, me, previousStat,

@@ -136,5 +235,3 @@ _this = this;

fileExists = null;
if (debug) {
console.log("watch event triggered on " + this.path + "\n", args);
}
this.log('debug', "watch event triggered on " + this.path + "\n", args);
isTheSame = function() {

@@ -150,11 +247,7 @@ if ((currentStat != null) && (previousStat != null)) {

if (!fileExists) {
if (debug) {
console.log('determined unlink:', fileFullPath);
}
return _this.close('unlink');
_this.log('debug', 'determined delete:', fileFullPath);
return _this.close('deleted');
} else {
if (isTheSame()) {
if (debug) {
return console.log("determined same:", fileFullPath);
}
return _this.log('debug', "determined same:", fileFullPath);
} else {

@@ -165,3 +258,3 @@ if (_this.isDirectory) {

if (err) {
throw err;
return _this.emit('error', err);
}

@@ -176,8 +269,6 @@ balUtil.each(newFileRelativePaths, function(newFileRelativePath) {

if (err) {
throw err;
return _this.emit('error', err);
}
if (debug) {
console.log('determined new:', newFileFullPath);
}
_this.emit('changed', 'new', newFileFullPath, newFileStat, null);
_this.log('debug', 'determined create:', newFileFullPath);
_this.emit('change', 'create', newFileFullPath, newFileStat, null);
return _this.watchChild(newFileFullPath, newFileRelativePath, newFileStat);

@@ -193,6 +284,4 @@ });

childFileFullPath = childFileWatcher.path;
if (debug) {
console.log('determined unlink:', childFileRelativePath);
}
return _this.closeChild(childFileRelativePath, 'unlink');
_this.log('debug', 'determined delete:', childFileRelativePath);
return _this.closeChild(childFileRelativePath, 'deleted');
}

@@ -203,6 +292,4 @@ });

} else {
if (debug) {
console.log('determined change:', fileFullPath);
}
return _this.emit('changed', 'change', fileFullPath, currentStat, previousStat);
_this.log('debug', 'determined update:', fileFullPath);
return _this.emit('change', 'update', fileFullPath, currentStat, previousStat);
}

@@ -217,3 +304,3 @@ }

if (err) {
throw err;
return this.emit('error', err);
}

@@ -231,14 +318,19 @@ currentStat = stat;

_Class.prototype.close = function(type) {
var childRelativePath, watchr, _ref;
/*
Close
We will need something to close our listener for removed or renamed files
As renamed files are a bit difficult we will want to close and delete all the watchers for all our children too
Essentially it is a self-destruct
*/
_Class.prototype.close = function(reason) {
var childRelativePath, _ref;
if (this.state !== 'active') {
return this;
}
if (debug) {
console.log("close: " + this.path + " ", new Error('trace').stack);
}
this.log('debug', "close: " + this.path, (new Error()).stack);
_ref = this.children;
for (childRelativePath in _ref) {
if (!__hasProp.call(_ref, childRelativePath)) continue;
watchr = _ref[childRelativePath];
this.closeChild(childRelativePath, type);

@@ -252,5 +344,5 @@ }

}
if (type === 'unlink') {
this.emit('changed', 'unlink', this.path, null, this.stat);
this.state = 'unlink';
if (reason === 'deleted') {
this.state = 'deleted';
this.emit('change', 'delete', this.path, null, this.stat);
} else {

@@ -265,8 +357,8 @@ this.state = 'closed';

_Class.prototype.closeChild = function(fileRelativePath, type) {
_Class.prototype.closeChild = function(fileRelativePath, reason) {
var watcher;
watcher = this.children[fileRelativePath];
if (watcher) {
watcher.close(type);
delete this.children[fileRelativePath];
watcher.close(reason);
}

@@ -276,16 +368,17 @@ return this;

/*
Watch Child
Setup watching for a child
Bubble events of the child into our instance
Also instantiate the child with our instance's configuration where applicable
*/
_Class.prototype.watchChild = function(fileFullPath, fileRelativePath, fileStat, next) {
var config, me;
var config, me, watcher,
_this = this;
me = this;
config = this.config;
return watch({
watcher = watch({
path: fileFullPath,
listener: function() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (args.length > 3 && args[0] === 'changed' && args[1] === 'unlink' && args[2] === fileFullPath) {
this.closeChild(fileRelativePath, 'unlink');
}
return me.bubble.apply(me, args);
},
stat: fileStat,

@@ -295,3 +388,18 @@ ignoreHiddenFiles: config.ignoreHiddenFiles,

ignoreCustomPatterns: config.ignoreCustomPatterns,
next: function(err, watcher) {
listeners: {
'change': function() {
var args, changeType, path;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
changeType = args[0], path = args[1];
if (changeType === 'delete' && path === fileFullPath) {
_this.closeChild(fileRelativePath, 'deleted');
}
return me.bubble.apply(me, ['change'].concat(__slice.call(args)));
},
'error': me.bubbler('error')
},
next: function() {
var args, err;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
err = args[0];
if (err) {

@@ -301,7 +409,19 @@ return typeof next === "function" ? next(err) : void 0;

me.children[fileRelativePath] = watcher;
return typeof next === "function" ? next() : void 0;
return typeof next === "function" ? next.apply(null, args) : void 0;
}
});
return watcher;
};
/*
Watch
Setup the native watching handlers for our path so we can receive updates on when things happen
If the next argument has been received, then add it is a once listener for the watching event
If we are already watching this path then let's start again (call close)
If we are a directory, let's recurse
If we are deleted, then don't error but return the isWatching argument of our completion callback as false
Once watching has completed for this directory and all children, then emit the watching event
*/
_Class.prototype.watch = function(next) {

@@ -312,10 +432,25 @@ var config, me, startWatching,

config = this.config;
if ((this.stat != null) === false) {
balUtil.stat(config.path, function(err, stat) {
if (err) {
return _this.emit('error', err);
}
_this.stat = stat;
_this.isDirectory = stat.isDirectory();
return _this.watch(next);
});
return this;
}
if (next != null) {
this.listen('watching', next);
}
this.close();
if (debug) {
console.log("watch: " + this.path, new Error('trace').stack);
}
this.log('debug', "watch: " + this.path);
startWatching = function() {
var tasks, watchFileOpts;
tasks = new balUtil.Group(function(err) {
return typeof next === "function" ? next(err) : void 0;
if (err) {
return _this.emit('watching', err, _this, false);
}
return _this.emit('watching', err, _this, true);
});

@@ -350,3 +485,3 @@ tasks.total = 2;

args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return me.changed.apply(me, args);
return me.listener.apply(me, args);
});

@@ -358,3 +493,3 @@ _this.method = 'watchFile';

args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return me.changed.apply(me, args);
return me.listener.apply(me, args);
});

@@ -368,4 +503,3 @@ _this.method = 'watch';

if (!exists) {
next();
return this;
return _this.emit('watching', null, _this, false);
}

@@ -381,10 +515,25 @@ return startWatching();

/*
Create Watcher
Checks to see if the path actually exists, if it doesn't then exit gracefully
If it does exist, then lets check our cache for an already existing watcher instance
If we have an already existing watching instance, then just add our listeners to that
If we don't, then create a watching instance
Fire the next callback once done
next(err,watcherInstance)
*/
createWatcher = function(opts, next) {
var listener, listeners, path, watcher, watchr, _i, _len, _listener, _ref;
_ref = balUtil.extractOptsAndCallback(opts, next), opts = _ref[0], next = _ref[1];
var listener, listeners, path, watcher;
path = opts.path, listener = opts.listener, listeners = opts.listeners;
watchr = null;
if (opts.next != null) {
if (next == null) {
next = opts.next;
}
delete opts.next;
}
if (!balUtil.existsSync(path)) {
if (typeof next === "function") {
next(null, watcher);
next(null, null);
}

@@ -399,6 +548,3 @@ return;

if (listeners) {
for (_i = 0, _len = listeners.length; _i < _len; _i++) {
_listener = listeners[_i];
watcher.listen(_listener);
}
watcher.listen(listeners);
}

@@ -409,3 +555,5 @@ if (typeof next === "function") {

} else {
watcher = new Watcher(opts);
watcher = new Watcher(opts, function(err) {
return typeof next === "function" ? next(err, watcher) : void 0;
});
watchers[path] = watcher;

@@ -416,29 +564,49 @@ }

/*
Watch
Provides an abstracted API that supports multiple paths
If you are passing in multiple paths then do not rely on the return result containing all of the watchers
you must rely on the result inside the completion callback instead
If you used the paths option, then your results will be an array of watcher instances, otherwise they will be a single watcher instance
next(err,results)
*/
watch = function(opts, next) {
var path, paths, result, tasks, _i, _len, _ref;
_ref = balUtil.extractOptsAndCallback(opts, next), opts = _ref[0], next = _ref[1];
paths = opts.paths;
result = null;
delete opts.paths;
if (paths instanceof Array) {
result = [];
tasks = new balUtil.Group(function(err) {
return typeof next === "function" ? next(err, result) : void 0;
});
for (_i = 0, _len = paths.length; _i < _len; _i++) {
path = paths[_i];
tasks.push({
path: path
}, function(complete) {
var localOpts, watchr;
localOpts = balUtil.extend({}, opts);
localOpts.path = this.path;
localOpts.next = complete;
watchr = createWatcher(localOpts);
if (watchr) {
return result.push(watchr);
}
var path, paths, result, tasks, _i, _len;
result = [];
if (opts.next != null) {
if (next == null) {
next = opts.next;
}
delete opts.next;
}
if (opts.paths) {
paths = opts.paths;
delete opts.paths;
if (balUtil.isArray(paths)) {
tasks = new balUtil.Group(function(err) {
return typeof next === "function" ? next(err, result) : void 0;
});
for (_i = 0, _len = paths.length; _i < _len; _i++) {
path = paths[_i];
tasks.push({
path: path
}, function(complete) {
var localOpts, watcher;
localOpts = balUtil.extend({}, opts);
localOpts.path = this.path;
watcher = createWatcher(localOpts, complete);
if (watcher) {
return result.push(watcher);
}
});
}
tasks.async();
} else {
opts.path = paths;
result.push(createWatcher(opts, function(err) {
return typeof next === "function" ? next(err, result) : void 0;
}));
}
tasks.async();
} else {

@@ -445,0 +613,0 @@ result = createWatcher(opts, next);

{
"name": "watchr",
"version": "2.2.1",
"version": "2.3.0",
"description": "Better file system watching for Node.js",

@@ -5,0 +5,0 @@ "homepage": "https://github.com/bevry/watchr",

@@ -1,12 +0,18 @@

## Watchr; better file system watching for Node.js
## Watchr: better file system watching for Node.js
Watchr provides a normalised API the file watching APIs of different node versions, nested/recursive file and directory watching, and accurate detailed events for file/directory changes, deletions and creations.
Watchr provides a normalised API the file watching APIs of different node versions, nested/recursive file and directory watching, and accurate detailed events for file/directory creations, updates, and deletions.
You install it via `npm istall watchr` and use it via `require('watchr').watch(config)`. Available configuration options are:
You install it via `npm install watchr` and use it via `require('watchr').watch(config)`. Available configuration options are:
- `path` a single path to watch
- `paths` an array of paths to watch
- `listener` a single listener to fire when a change occurs
- `listeners` an array of listeners to fire when a change occurs
- `next` (optional, defaults to `null`) a completion callback to fire once the watchers have been setup
- `listener` a single change listener to fire when a change occurs
- `listeners` an array of listeners to fire when a change occurs, overloaded to also accept
- `changeListener` a single change listener
- `[changeListener]` an array of change listeners
- `{eventName:eventListener}` an object keyed with the event names and valued with a single event listener
- `{eventName:[eventListener]}` an object keyed with the event names and valued with an array of event listeners
- `next` (optional, defaults to `null`) a completion callback to fire once the watchers have been setup, arguments are:
- when using the `path` configuration option: `err, watcherInstance`
- when using the `paths` configuration option: `err, [watcherInstance,...]`
- `stat` (optional, defaults to `null`) a file stat object to use for the path, instead of fetching a new one

@@ -19,9 +25,12 @@ - `ignoreHiddenFiles` (optional, defaults to `false`) whether or not to ignored files which filename starts with a `.`

Listeners will be triggered whenever a change is made on the directory or for anything inside it (including sub-directories and so on) and are in the following format `var listener = function(eventName,filePath,fileCurrentStat,filePreviousStat){}`
There are three types of events for your listeners at your disposal:
The following events are available to your via the listeners:
- `change`: a file has been modified
- `new`: a new file or directory has been created
- `unlink`: a file or a directory has been removed
- `log` for debugging, receives the arguments `logLevel ,args...`
- `error` for gracefully listening to error events, receives the arguments `err`
- `watching` for when watching of the path has completed, receives the arguments `err, isWatching`
- `change` for listening to change events, receives the arguments `changeType, fullPath, currentStat, previousStat`, received arguments will be:
- for updated files: `'update', fullPath, currentStat, previousStat`
- for created files: `'create', fullPath, currentStat, null`
- for deleted files: `'delete', fullPath, null, previousStat`

@@ -36,9 +45,19 @@ To wrap it all together, it would look like this:

watchr.watch({
path: path,
listener: function(eventName,filePath,fileCurrentStat,filePreviousStat){
console.log('a watch event occured:',arguments);
paths: ['path1','path2','path3'],
listeners: {
log: function(logLevel){
console.log('a log message occured:', arguments);
},
error: function(err){
console.log('an error occured:', err);
},
watching: function(err,watcherInstance,isWatching){
console.log('a new watcher instance finished setting up', arguments);
},
change: function(changeType,filePath,fileCurrentStat,filePreviousStat){
console.log('a change event occured:',arguments);
}
},
next: function(err,watcher){
if (err) throw err;
console.log('watching setup successfully');
next: function(err,watchers){
console.log('watching for all our paths has completed', arguments);
}

@@ -50,5 +69,3 @@ });

Thanks for using Watchr!
## Support

@@ -68,2 +85,2 @@

<br/>Copyright &copy; 2012 [Bevry Pty Ltd](http://bevry.me)
<br/>Copyright &copy; 2011 [Benjamin Lupton](http://balupton.com)
<br/>Copyright &copy; 2011 [Benjamin Lupton](http://balupton.com)
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