GT2/GT2-Android/node_modules/sane/src/fsevents_watcher.js

127 lines
2.5 KiB
JavaScript
Raw Normal View History

'use strict';
var fs = require('fs');
var path = require('path');
var common = require('./common');
var EventEmitter = require('events').EventEmitter;
var fsevents;
try {
fsevents = require('fsevents');
} catch (e) {
// Ignore.
}
/**
* Constants
*/
var CHANGE_EVENT = common.CHANGE_EVENT;
var DELETE_EVENT = common.DELETE_EVENT;
var ADD_EVENT = common.ADD_EVENT;
var ALL_EVENT = common.ALL_EVENT;
/**
* Export `FSEventsWatcher` class.
*/
module.exports = FSEventsWatcher;
/**
* Watches `dir`.
*
* @class FSEventsWatcher
* @param String dir
* @param {Object} opts
* @public
*/
function FSEventsWatcher(dir, opts) {
if (!fsevents) {
throw new Error(
'`fsevents` unavailable (this watcher can only be used on Darwin)'
);
}
common.assignOptions(this, opts);
this.root = path.resolve(dir);
this.watcher = fsevents(this.root);
this.watcher.start().on('change', this.handleEvent.bind(this));
this._tracked = Object.create(null);
common.recReaddir(
this.root,
filepath => (this._tracked[filepath] = true),
filepath => (this._tracked[filepath] = true),
this.emit.bind(this, 'ready'),
this.emit.bind(this, 'error'),
this.ignored
);
}
FSEventsWatcher.prototype.__proto__ = EventEmitter.prototype;
FSEventsWatcher.prototype.handleEvent = function(filepath) {
var relativePath = path.relative(this.root, filepath);
if (
!common.isFileIncluded(this.globs, this.dot, this.doIgnore, relativePath)
) {
return;
}
fs.lstat(
filepath,
function(error, stat) {
if (error && error.code !== 'ENOENT') {
this.emit('error', error);
return;
}
if (error) {
// Ignore files that aren't tracked and don't exist.
if (!this._tracked[filepath]) {
return;
}
this._emit(DELETE_EVENT, relativePath);
delete this._tracked[filepath];
return;
}
if (this._tracked[filepath]) {
this._emit(CHANGE_EVENT, relativePath, stat);
} else {
this._tracked[filepath] = true;
this._emit(ADD_EVENT, relativePath, stat);
}
}.bind(this)
);
};
/**
* End watching.
*
* @public
*/
FSEventsWatcher.prototype.close = function(callback) {
this.watcher.stop();
this.removeAllListeners();
if (typeof callback === 'function') {
process.nextTick(callback.bind(null, null, true));
}
};
/**
* Emit events.
*
* @private
*/
FSEventsWatcher.prototype._emit = function(type, file, stat) {
this.emit(type, file, this.root, stat);
this.emit(ALL_EVENT, type, file, this.root, stat);
};