2
MIT License http://www.opensource.org/licenses/mit-license.php
3
Author Tobias Koppers @sokra
5
var watcherManager = require("./watcherManager");
6
var EventEmitter = require("events").EventEmitter;
8
function Watchpack(options) {
9
EventEmitter.call(this);
10
if(!options) options = {};
11
if(!options.aggregateTimeout) options.aggregateTimeout = 200;
12
this.options = options;
13
this.watcherOptions = {
14
ignored: options.ignored,
17
this.fileWatchers = [];
18
this.dirWatchers = [];
19
this.mtimes = Object.create(null);
21
this.aggregatedChanges = [];
22
this.aggregatedRemovals = [];
23
this.aggregateTimeout = 0;
24
this._onTimeout = this._onTimeout.bind(this);
27
module.exports = Watchpack;
29
Watchpack.prototype = Object.create(EventEmitter.prototype);
31
Watchpack.prototype.watch = function watch(files, directories, startTime) {
33
var oldFileWatchers = this.fileWatchers;
34
var oldDirWatchers = this.dirWatchers;
35
this.fileWatchers = files.map(function(file) {
36
return this._fileWatcher(file, watcherManager.watchFile(file, this.watcherOptions, startTime));
38
this.dirWatchers = directories.map(function(dir) {
39
return this._dirWatcher(dir, watcherManager.watchDirectory(dir, this.watcherOptions, startTime));
41
oldFileWatchers.forEach(function(w) {
44
oldDirWatchers.forEach(function(w) {
49
Watchpack.prototype.close = function resume() {
51
if(this.aggregateTimeout)
52
clearTimeout(this.aggregateTimeout);
53
this.fileWatchers.forEach(function(w) {
56
this.dirWatchers.forEach(function(w) {
59
this.fileWatchers.length = 0;
60
this.dirWatchers.length = 0;
63
Watchpack.prototype.pause = function pause() {
65
if(this.aggregateTimeout)
66
clearTimeout(this.aggregateTimeout);
69
function addWatchersToArray(watchers, array) {
70
watchers.forEach(function(w) {
71
if(array.indexOf(w.directoryWatcher) < 0) {
72
array.push(w.directoryWatcher);
73
addWatchersToArray(Object.keys(w.directoryWatcher.directories).reduce(function(a, dir) {
74
if(w.directoryWatcher.directories[dir] !== true)
75
a.push(w.directoryWatcher.directories[dir]);
82
Watchpack.prototype.getTimes = function() {
83
var directoryWatchers = [];
84
addWatchersToArray(this.fileWatchers.concat(this.dirWatchers), directoryWatchers);
85
var obj = Object.create(null);
86
directoryWatchers.forEach(function(w) {
87
var times = w.getTimes();
88
Object.keys(times).forEach(function(file) {
89
obj[file] = times[file];
95
Watchpack.prototype._fileWatcher = function _fileWatcher(file, watcher) {
96
watcher.on("change", function(mtime, type) {
97
this._onChange(file, mtime, file, type);
99
watcher.on("remove", function(type) {
100
this._onRemove(file, file, type);
105
Watchpack.prototype._dirWatcher = function _dirWatcher(item, watcher) {
106
watcher.on("change", function(file, mtime, type) {
107
this._onChange(item, mtime, file, type);
112
Watchpack.prototype._onChange = function _onChange(item, mtime, file) {
114
this.mtimes[file] = mtime;
115
if(this.paused) return;
116
this.emit("change", file, mtime);
117
if(this.aggregateTimeout)
118
clearTimeout(this.aggregateTimeout);
119
if(this.aggregatedChanges.indexOf(item) < 0)
120
this.aggregatedChanges.push(item);
121
this.aggregateTimeout = setTimeout(this._onTimeout, this.options.aggregateTimeout);
124
Watchpack.prototype._onRemove = function _onRemove(item, file) {
126
delete this.mtimes[item];
127
if(this.paused) return;
128
this.emit("remove", item);
129
if(this.aggregateTimeout)
130
clearTimeout(this.aggregateTimeout);
131
if(this.aggregatedRemovals.indexOf(item) < 0)
132
this.aggregatedRemovals.push(item);
133
this.aggregateTimeout = setTimeout(this._onTimeout, this.options.aggregateTimeout);
136
Watchpack.prototype._onTimeout = function _onTimeout() {
137
this.aggregateTimeout = 0;
138
var changes = this.aggregatedChanges;
139
var removals = this.aggregatedRemovals;
140
this.aggregatedChanges = [];
141
this.aggregatedRemovals = [];
142
this.emit("aggregated", changes, removals);