-
Notifications
You must be signed in to change notification settings - Fork 38
/
Watcher.js
83 lines (70 loc) · 2.11 KB
/
Watcher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
var fs = require('fs')
, path = require('path');
exports.Watcher = Watcher;
function Watcher(webDirectory, rewrite) {
this.webDirectory = webDirectory;
// array of VogueClient objects
this.clients = [];
// filename -> number_of_clients_watching
this.fileWatcherCount = {};
if (rewrite) {
this.rewriteUrlToPath = createRewriter(rewrite);
}
function createRewriter(rewrite) {
var parts = rewrite.split(':');
if (parts.length === 2) {
var regex = new RegExp(parts[0]);
var replacement = parts[1];
return function (str) {
return str.replace(regex, replacement);
}
} else {
throw new Error('Rewrite must be of the form "regex:replacement".');
}
}
}
Watcher.prototype.addClient = function(client) {
this.clients.push(client);
};
Watcher.prototype.removeClient = function(client) {
this.clients.splice(this.clients.indexOf(client), 1);
};
Watcher.prototype.getFilenameForHref = function(href) {
if (this.rewriteUrlToPath) {
href = this.rewriteUrlToPath(href);
}
// Remove any querystring junk.
// e.g. "foo/bar.css?abc=123" --> "foo/bar.css"
href = href.split('?')[0];
var filename = path.join(this.webDirectory, href);
return filename;
};
Watcher.prototype.startWatching = function(filename) {
console.log('Watching file: ' + filename);
if (filename in this.fileWatcherCount) {
// already watching this file, so just increment the client count.
this.fileWatcherCount[filename]++;
} else {
fs.watchFile(
filename,
{ persistent: true, interval: 50 },
fileChanged.bind(this)
);
this.fileWatcherCount[filename] = 1;
}
function fileChanged() {
console.log('File changed: ' + filename);
this.clients.forEach(function(client) {
client.updateFile(filename);
});
}
};
Watcher.prototype.stopWatching = function(filename) {
if (!(filename in this.fileWatcherCount)) return;
var watcherCount = --this.fileWatcherCount[filename];
if (watcherCount == 0) {
delete this.fileWatcherCount[filename];
fs.unwatchFile(filename);
console.log('Stopped watching file: ' + filename);
}
}