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