UNPKG

3.52 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.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
22module.exports = Watchpack;
23
24Watchpack.prototype = Object.create(EventEmitter.prototype);
25
26Watchpack.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
44Watchpack.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
58Watchpack.prototype.pause = function pause() {
59 this.paused = true;
60 if(this.aggregateTimeout)
61 clearTimeout(this.aggregateTimeout);
62};
63
64function 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
76Watchpack.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
89Watchpack.prototype._fileWatcher = function _fileWatcher(file, watcher) {
90 watcher.on("change", this._onChange.bind(this, file));
91 return watcher;
92};
93
94Watchpack.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
101Watchpack.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
113Watchpack.prototype._onTimeout = function _onTimeout() {
114 this.aggregateTimeout = 0;
115 var changes = this.aggregatedChanges;
116 this.aggregatedChanges = [];
117 this.emit("aggregated", changes);
118};