UNPKG

3.63 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5var watcherManager = require("./watcherManager");
6var EventEmitter = require("events").EventEmitter;
7
8function 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 poll: options.poll
15 };
16 this.fileWatchers = [];
17 this.dirWatchers = [];
18 this.mtimes = {};
19 this.paused = false;
20 this.aggregatedChanges = [];
21 this.aggregateTimeout = 0;
22 this._onTimeout = this._onTimeout.bind(this);
23}
24
25module.exports = Watchpack;
26
27Watchpack.prototype = Object.create(EventEmitter.prototype);
28
29Watchpack.prototype.watch = function watch(files, directories, startTime) {
30 this.paused = false;
31 var oldFileWatchers = this.fileWatchers;
32 var oldDirWatchers = this.dirWatchers;
33 this.fileWatchers = files.map(function(file) {
34 return this._fileWatcher(file, watcherManager.watchFile(file, this.watcherOptions, startTime));
35 }, this);
36 this.dirWatchers = directories.map(function(dir) {
37 return this._dirWatcher(dir, watcherManager.watchDirectory(dir, this.watcherOptions, startTime));
38 }, this);
39 oldFileWatchers.forEach(function(w) {
40 w.close();
41 }, this);
42 oldDirWatchers.forEach(function(w) {
43 w.close();
44 }, this);
45};
46
47Watchpack.prototype.close = function resume() {
48 this.paused = true;
49 if(this.aggregateTimeout)
50 clearTimeout(this.aggregateTimeout);
51 this.fileWatchers.forEach(function(w) {
52 w.close();
53 }, this);
54 this.dirWatchers.forEach(function(w) {
55 w.close();
56 }, this);
57 this.fileWatchers.length = 0;
58 this.dirWatchers.length = 0;
59};
60
61Watchpack.prototype.pause = function pause() {
62 this.paused = true;
63 if(this.aggregateTimeout)
64 clearTimeout(this.aggregateTimeout);
65};
66
67function addWatchersToArray(watchers, array) {
68 watchers.forEach(function(w) {
69 if(array.indexOf(w.directoryWatcher) < 0) {
70 array.push(w.directoryWatcher);
71 addWatchersToArray(Object.keys(w.directoryWatcher.directories).reduce(function(a, dir) {
72 if(w.directoryWatcher.directories[dir] !== true)
73 a.push(w.directoryWatcher.directories[dir]);
74 return a;
75 }, []), array);
76 }
77 });
78}
79
80Watchpack.prototype.getTimes = function() {
81 var directoryWatchers = [];
82 addWatchersToArray(this.fileWatchers.concat(this.dirWatchers), directoryWatchers);
83 var obj = {};
84 directoryWatchers.forEach(function(w) {
85 var times = w.getTimes();
86 Object.keys(times).forEach(function(file) {
87 obj[file] = times[file];
88 });
89 });
90 return obj;
91};
92
93Watchpack.prototype._fileWatcher = function _fileWatcher(file, watcher) {
94 watcher.on("change", this._onChange.bind(this, file));
95 return watcher;
96};
97
98Watchpack.prototype._dirWatcher = function _dirWatcher(item, watcher) {
99 watcher.on("change", function(file, mtime) {
100 this._onChange(item, mtime, file);
101 }.bind(this));
102 return watcher;
103};
104
105Watchpack.prototype._onChange = function _onChange(item, mtime, file) {
106 file = file || item;
107 this.mtimes[file] = mtime;
108 if(this.paused) return;
109 this.emit("change", file, mtime);
110 if(this.aggregateTimeout)
111 clearTimeout(this.aggregateTimeout);
112 if(this.aggregatedChanges.indexOf(item) < 0)
113 this.aggregatedChanges.push(item);
114 this.aggregateTimeout = setTimeout(this._onTimeout, this.options.aggregateTimeout);
115};
116
117Watchpack.prototype._onTimeout = function _onTimeout() {
118 this.aggregateTimeout = 0;
119 var changes = this.aggregatedChanges;
120 this.aggregatedChanges = [];
121 this.emit("aggregated", changes);
122};