lib/watcher.js
function DirWatcher(inputPath, persistent) {
    assert.ok(this instanceof DirWatcher);

    var self = this;
    var absPath = path.resolve(inputPath);

    if (!fs.statSync(absPath).isDirectory()) {
        throw new Error(inputPath + "is not a directory!");
    }

    EventEmitter.call(self);

    self.ready = false;
    self.on("ready", function(){
        self.ready = true;
    });

    Object.defineProperties(self, {
        // Map of absDirPaths to fs.FSWatcher objects from fs.watch().
        watchers: { value: {} },
        dirContents: { value: {} },
        rootPath: { value: absPath },
        persistent: { value: !!persistent }
    });

    process.nextTick(function() {
        self.add(absPath);
        self.emit("ready");
    });
}
function DirWatcher(inputPath, persistent) {
    assert.ok(this instanceof DirWatcher);

    var self = this;
    var absPath = path.resolve(inputPath);

    if (!fs.statSync(absPath).isDirectory()) {
        throw new Error(inputPath + "is not a directory!");
    }

    EventEmitter.call(self);

    self.ready = false;
    self.on("ready", function(){
        self.ready = true;
    });

    Object.defineProperties(self, {
        // Map of absDirPaths to fs.FSWatcher objects from fs.watch().
        watchers: { value: {} },
        dirContents: { value: {} },
        rootPath: { value: absPath },
        persistent: { value: !!persistent }
    });

    process.nextTick(function() {
        self.add(absPath);
        self.emit("ready");
    });
}
function DirWatcher ( inputPath , persistent ) { assert . ok ( this instanceof DirWatcher ) ; var self = this ; var absPath = path . resolve ( inputPath ) ; if ( ! fs . statSync ( absPath ) . isDirectory ( ) ) { throw new Error ( inputPath + "is not a directory!" ) ; } EventEmitter . call ( self ) ; self . ready = false ; self . on ( "ready" , function ( ) { self . ready = true ; } ) ; Object . defineProperties ( self , { // Map of absDirPaths to fs.FSWatcher objects from fs.watch(). watchers : { value : { } } , dirContents : { value : { } } , rootPath : { value : absPath } , persistent : { value : ! ! persistent } } ) ; process . nextTick ( function ( ) { self . add ( absPath ) ; self . emit ( "ready" ) ; } ) ; }
DirWatcher code adapted from Jeffrey Lin's original implementation:
https://github.com/jeffreylin/jsx_transformer_fun/blob/master/dirWatcher.js

Invariant: this only watches the dir inode, not the actual path.
That means the dir can't be renamed and swapped with another dir.
DirWatcher code adapted from Jeffrey Lin s original implementation : https : // github . com / jeffreylin / jsx_transformer_fun / blob / master / dirWatcher . js