You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							145 lines
						
					
					
						
							4.2 KiB
						
					
					
				
			
		
		
	
	
							145 lines
						
					
					
						
							4.2 KiB
						
					
					
				/* | 
						|
	MIT License http://www.opensource.org/licenses/mit-license.php | 
						|
	Author Tobias Koppers @sokra | 
						|
*/ | 
						|
"use strict"; | 
						|
 | 
						|
var watcherManager = require("./watcherManager"); | 
						|
var EventEmitter = require("events").EventEmitter; | 
						|
 | 
						|
function Watchpack(options) { | 
						|
	EventEmitter.call(this); | 
						|
	if(!options) options = {}; | 
						|
	if(!options.aggregateTimeout) options.aggregateTimeout = 200; | 
						|
	this.options = options; | 
						|
	this.watcherOptions = { | 
						|
		ignored: options.ignored, | 
						|
		poll: options.poll | 
						|
	}; | 
						|
	this.fileWatchers = []; | 
						|
	this.dirWatchers = []; | 
						|
	this.mtimes = Object.create(null); | 
						|
	this.paused = false; | 
						|
	this.aggregatedChanges = []; | 
						|
	this.aggregatedRemovals = []; | 
						|
	this.aggregateTimeout = 0; | 
						|
	this._onTimeout = this._onTimeout.bind(this); | 
						|
} | 
						|
 | 
						|
module.exports = Watchpack; | 
						|
 | 
						|
Watchpack.prototype = Object.create(EventEmitter.prototype); | 
						|
 | 
						|
Watchpack.prototype.watch = function watch(files, directories, startTime) { | 
						|
	this.paused = false; | 
						|
	var oldFileWatchers = this.fileWatchers; | 
						|
	var oldDirWatchers = this.dirWatchers; | 
						|
	this.fileWatchers = files.map(function(file) { | 
						|
		return this._fileWatcher(file, watcherManager.watchFile(file, this.watcherOptions, startTime)); | 
						|
	}, this); | 
						|
	this.dirWatchers = directories.map(function(dir) { | 
						|
		return this._dirWatcher(dir, watcherManager.watchDirectory(dir, this.watcherOptions, startTime)); | 
						|
	}, this); | 
						|
	oldFileWatchers.forEach(function(w) { | 
						|
		w.close(); | 
						|
	}, this); | 
						|
	oldDirWatchers.forEach(function(w) { | 
						|
		w.close(); | 
						|
	}, this); | 
						|
}; | 
						|
 | 
						|
Watchpack.prototype.close = function resume() { | 
						|
	this.paused = true; | 
						|
	if(this.aggregateTimeout) | 
						|
		clearTimeout(this.aggregateTimeout); | 
						|
	this.fileWatchers.forEach(function(w) { | 
						|
		w.close(); | 
						|
	}, this); | 
						|
	this.dirWatchers.forEach(function(w) { | 
						|
		w.close(); | 
						|
	}, this); | 
						|
	this.fileWatchers.length = 0; | 
						|
	this.dirWatchers.length = 0; | 
						|
}; | 
						|
 | 
						|
Watchpack.prototype.pause = function pause() { | 
						|
	this.paused = true; | 
						|
	if(this.aggregateTimeout) | 
						|
		clearTimeout(this.aggregateTimeout); | 
						|
}; | 
						|
 | 
						|
function addWatchersToArray(watchers, array) { | 
						|
	watchers.forEach(function(w) { | 
						|
		if(array.indexOf(w.directoryWatcher) < 0) { | 
						|
			array.push(w.directoryWatcher); | 
						|
			addWatchersToArray(Object.keys(w.directoryWatcher.directories).reduce(function(a, dir) { | 
						|
				if(w.directoryWatcher.directories[dir] !== true) | 
						|
					a.push(w.directoryWatcher.directories[dir]); | 
						|
				return a; | 
						|
			}, []), array); | 
						|
		} | 
						|
	}); | 
						|
} | 
						|
 | 
						|
Watchpack.prototype.getTimes = function() { | 
						|
	var directoryWatchers = []; | 
						|
	addWatchersToArray(this.fileWatchers.concat(this.dirWatchers), directoryWatchers); | 
						|
	var obj = Object.create(null); | 
						|
	directoryWatchers.forEach(function(w) { | 
						|
		var times = w.getTimes(); | 
						|
		Object.keys(times).forEach(function(file) { | 
						|
			obj[file] = times[file]; | 
						|
		}); | 
						|
	}); | 
						|
	return obj; | 
						|
}; | 
						|
 | 
						|
Watchpack.prototype._fileWatcher = function _fileWatcher(file, watcher) { | 
						|
	watcher.on("change", function(mtime, type) { | 
						|
		this._onChange(file, mtime, file, type); | 
						|
	}.bind(this)); | 
						|
	watcher.on("remove", function(type) { | 
						|
		this._onRemove(file, file, type); | 
						|
	}.bind(this)); | 
						|
	return watcher; | 
						|
}; | 
						|
 | 
						|
Watchpack.prototype._dirWatcher = function _dirWatcher(item, watcher) { | 
						|
	watcher.on("change", function(file, mtime, type) { | 
						|
		this._onChange(item, mtime, file, type); | 
						|
	}.bind(this)); | 
						|
	return watcher; | 
						|
}; | 
						|
 | 
						|
Watchpack.prototype._onChange = function _onChange(item, mtime, file) { | 
						|
	file = file || item; | 
						|
	this.mtimes[file] = mtime; | 
						|
	if(this.paused) return; | 
						|
	this.emit("change", file, mtime); | 
						|
	if(this.aggregateTimeout) | 
						|
		clearTimeout(this.aggregateTimeout); | 
						|
	if(this.aggregatedChanges.indexOf(item) < 0) | 
						|
		this.aggregatedChanges.push(item); | 
						|
	this.aggregateTimeout = setTimeout(this._onTimeout, this.options.aggregateTimeout); | 
						|
}; | 
						|
 | 
						|
Watchpack.prototype._onRemove = function _onRemove(item, file) { | 
						|
	file = file || item; | 
						|
	delete this.mtimes[item]; | 
						|
	if(this.paused) return; | 
						|
	this.emit("remove", item); | 
						|
	if(this.aggregateTimeout) | 
						|
		clearTimeout(this.aggregateTimeout); | 
						|
	if(this.aggregatedRemovals.indexOf(item) < 0) | 
						|
		this.aggregatedRemovals.push(item); | 
						|
	this.aggregateTimeout = setTimeout(this._onTimeout, this.options.aggregateTimeout); | 
						|
}; | 
						|
 | 
						|
Watchpack.prototype._onTimeout = function _onTimeout() { | 
						|
	this.aggregateTimeout = 0; | 
						|
	var changes = this.aggregatedChanges; | 
						|
	var removals = this.aggregatedRemovals; | 
						|
	this.aggregatedChanges = []; | 
						|
	this.aggregatedRemovals = []; | 
						|
	this.emit("aggregated", changes, removals); | 
						|
};
 | 
						|
 |