Projekt

Obecné

Profil

Stáhnout (4.16 KB) Statistiky
| Větev: | Revize:
1
/*
2
	MIT License http://www.opensource.org/licenses/mit-license.php
3
	Author Tobias Koppers @sokra
4
*/
5
"use strict";
6

    
7
var watcherManager = require("./watcherManager");
8
var EventEmitter = require("events").EventEmitter;
9

    
10
function Watchpack(options) {
11
	EventEmitter.call(this);
12
	if(!options) options = {};
13
	if(!options.aggregateTimeout) options.aggregateTimeout = 200;
14
	this.options = options;
15
	this.watcherOptions = {
16
		ignored: options.ignored,
17
		poll: options.poll
18
	};
19
	this.fileWatchers = [];
20
	this.dirWatchers = [];
21
	this.mtimes = Object.create(null);
22
	this.paused = false;
23
	this.aggregatedChanges = [];
24
	this.aggregatedRemovals = [];
25
	this.aggregateTimeout = 0;
26
	this._onTimeout = this._onTimeout.bind(this);
27
}
28

    
29
module.exports = Watchpack;
30

    
31
Watchpack.prototype = Object.create(EventEmitter.prototype);
32

    
33
Watchpack.prototype.watch = function watch(files, directories, startTime) {
34
	this.paused = false;
35
	var oldFileWatchers = this.fileWatchers;
36
	var oldDirWatchers = this.dirWatchers;
37
	this.fileWatchers = files.map(function(file) {
38
		return this._fileWatcher(file, watcherManager.watchFile(file, this.watcherOptions, startTime));
39
	}, this);
40
	this.dirWatchers = directories.map(function(dir) {
41
		return this._dirWatcher(dir, watcherManager.watchDirectory(dir, this.watcherOptions, startTime));
42
	}, this);
43
	oldFileWatchers.forEach(function(w) {
44
		w.close();
45
	}, this);
46
	oldDirWatchers.forEach(function(w) {
47
		w.close();
48
	}, this);
49
};
50

    
51
Watchpack.prototype.close = function resume() {
52
	this.paused = true;
53
	if(this.aggregateTimeout)
54
		clearTimeout(this.aggregateTimeout);
55
	this.fileWatchers.forEach(function(w) {
56
		w.close();
57
	}, this);
58
	this.dirWatchers.forEach(function(w) {
59
		w.close();
60
	}, this);
61
	this.fileWatchers.length = 0;
62
	this.dirWatchers.length = 0;
63
};
64

    
65
Watchpack.prototype.pause = function pause() {
66
	this.paused = true;
67
	if(this.aggregateTimeout)
68
		clearTimeout(this.aggregateTimeout);
69
};
70

    
71
function addWatchersToArray(watchers, array) {
72
	watchers.forEach(function(w) {
73
		if(array.indexOf(w.directoryWatcher) < 0) {
74
			array.push(w.directoryWatcher);
75
			addWatchersToArray(Object.keys(w.directoryWatcher.directories).reduce(function(a, dir) {
76
				if(w.directoryWatcher.directories[dir] !== true)
77
					a.push(w.directoryWatcher.directories[dir]);
78
				return a;
79
			}, []), array);
80
		}
81
	});
82
}
83

    
84
Watchpack.prototype.getTimes = function() {
85
	var directoryWatchers = [];
86
	addWatchersToArray(this.fileWatchers.concat(this.dirWatchers), directoryWatchers);
87
	var obj = Object.create(null);
88
	directoryWatchers.forEach(function(w) {
89
		var times = w.getTimes();
90
		Object.keys(times).forEach(function(file) {
91
			obj[file] = times[file];
92
		});
93
	});
94
	return obj;
95
};
96

    
97
Watchpack.prototype._fileWatcher = function _fileWatcher(file, watcher) {
98
	watcher.on("change", function(mtime, type) {
99
		this._onChange(file, mtime, file, type);
100
	}.bind(this));
101
	watcher.on("remove", function(type) {
102
		this._onRemove(file, file, type);
103
	}.bind(this));
104
	return watcher;
105
};
106

    
107
Watchpack.prototype._dirWatcher = function _dirWatcher(item, watcher) {
108
	watcher.on("change", function(file, mtime, type) {
109
		this._onChange(item, mtime, file, type);
110
	}.bind(this));
111
	return watcher;
112
};
113

    
114
Watchpack.prototype._onChange = function _onChange(item, mtime, file) {
115
	file = file || item;
116
	this.mtimes[file] = mtime;
117
	if(this.paused) return;
118
	this.emit("change", file, mtime);
119
	if(this.aggregateTimeout)
120
		clearTimeout(this.aggregateTimeout);
121
	if(this.aggregatedChanges.indexOf(item) < 0)
122
		this.aggregatedChanges.push(item);
123
	this.aggregateTimeout = setTimeout(this._onTimeout, this.options.aggregateTimeout);
124
};
125

    
126
Watchpack.prototype._onRemove = function _onRemove(item, file) {
127
	file = file || item;
128
	delete this.mtimes[item];
129
	if(this.paused) return;
130
	this.emit("remove", item);
131
	if(this.aggregateTimeout)
132
		clearTimeout(this.aggregateTimeout);
133
	if(this.aggregatedRemovals.indexOf(item) < 0)
134
		this.aggregatedRemovals.push(item);
135
	this.aggregateTimeout = setTimeout(this._onTimeout, this.options.aggregateTimeout);
136
};
137

    
138
Watchpack.prototype._onTimeout = function _onTimeout() {
139
	this.aggregateTimeout = 0;
140
	var changes = this.aggregatedChanges;
141
	var removals = this.aggregatedRemovals;
142
	this.aggregatedChanges = [];
143
	this.aggregatedRemovals = [];
144
	this.emit("aggregated", changes, removals);
145
};
(3-3/3)