1 |
|
2 |
|
3 |
|
4 |
|
5 | var watcherManager = require("./watcherManager");
|
6 | var EventEmitter = require("events").EventEmitter;
|
7 |
|
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 | 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 |
|
25 | module.exports = Watchpack;
|
26 |
|
27 | Watchpack.prototype = Object.create(EventEmitter.prototype);
|
28 |
|
29 | Watchpack.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 |
|
47 | Watchpack.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 |
|
61 | Watchpack.prototype.pause = function pause() {
|
62 | this.paused = true;
|
63 | if(this.aggregateTimeout)
|
64 | clearTimeout(this.aggregateTimeout);
|
65 | };
|
66 |
|
67 | function 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 |
|
80 | Watchpack.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 |
|
93 | Watchpack.prototype._fileWatcher = function _fileWatcher(file, watcher) {
|
94 | watcher.on("change", this._onChange.bind(this, file));
|
95 | return watcher;
|
96 | };
|
97 |
|
98 | Watchpack.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 |
|
105 | Watchpack.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 |
|
117 | Watchpack.prototype._onTimeout = function _onTimeout() {
|
118 | this.aggregateTimeout = 0;
|
119 | var changes = this.aggregatedChanges;
|
120 | this.aggregatedChanges = [];
|
121 | this.emit("aggregated", changes);
|
122 | };
|