1 | var fs = require('fs');
|
2 | var readdirp = require('readdirp');
|
3 | var is_windows = process.platform === 'win32';
|
4 |
|
5 | module.exports = function() {
|
6 | var watched_files = {};
|
7 | var watched_directories = {};
|
8 | var check_dir_pause = 1000;
|
9 | var checkInterval = undefined;
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 | function watchDirectory(args) {
|
21 | readdirp({ root: args.root, fileFilter: args.fileFilter, directoryFilter: args.directoryFilter }, function(err, res) {
|
22 | res.files.forEach(function(file) {
|
23 | watchFile(file, args.listener, args.partial);
|
24 | });
|
25 | typeof args.complete == "function" && args.complete();
|
26 | });
|
27 |
|
28 | !args.partial && (checkInterval = setInterval(function() {checkDirectory(args)}, check_dir_pause));
|
29 | }
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | function watchFiles(args) {
|
38 | args.files.forEach(function(file) {
|
39 | var o = {
|
40 | fullPath: fs.realpathSync(file),
|
41 | name: fs.realpathSync(file).split('/').pop()
|
42 | };
|
43 | o.fullParentDir = o.fullPath.split('/').slice(0, o.fullPath.split('/').length - 1).join('/')
|
44 |
|
45 | watchFile(o, args.listener);
|
46 | });
|
47 |
|
48 | typeof args.complete == "function" && args.complete();
|
49 | }
|
50 |
|
51 | function unwatchAll() {
|
52 | if (is_windows) {
|
53 | Object.keys(watched_files).forEach(function(key) {
|
54 | watched_files[key].close();
|
55 | });
|
56 | } else {
|
57 | Object.keys(watched_files).forEach(function(key) {
|
58 | fs.unwatchFile(key);
|
59 | });
|
60 | }
|
61 |
|
62 | clearInterval(checkInterval);
|
63 | watched_files = {};
|
64 | watched_directories = {};
|
65 | }
|
66 |
|
67 |
|
68 | function checkDirectory(args) {
|
69 | Object.keys(watched_directories).forEach(function(path) {
|
70 | var lastModified = watched_directories[path];
|
71 | fs.stat(path, function(err, stats) {
|
72 | var stats_stamp = (new Date(stats.mtime)).getTime();
|
73 | if (stats_stamp != lastModified) {
|
74 | watched_directories[path] = stats_stamp;
|
75 | watchDirectory({
|
76 | root: path,
|
77 | listener: args.listener,
|
78 | fileFilter: args.fileFilter,
|
79 | directoryFilter: args.directoryFilter,
|
80 | partial: true
|
81 | });
|
82 | }
|
83 | });
|
84 | });
|
85 | }
|
86 |
|
87 |
|
88 |
|
89 | function watchFile(file, cb, partial) {
|
90 | storeDirectory(file);
|
91 | if (!watched_files[file.fullPath]) {
|
92 | if (is_windows) {
|
93 | (function() {
|
94 | watched_files[file.fullPath] = fs.watch(file.fullPath, function() {
|
95 | typeof cb === "function" && cb(file);
|
96 | });
|
97 | partial && cb(file);
|
98 | })(file, cb);
|
99 | } else {
|
100 | (function(file, cb) {
|
101 | watched_files[file.fullPath] = true;
|
102 | fs.watchFile(file.fullPath, {interval: 150}, function() {
|
103 | typeof cb === "function" && cb(file);
|
104 | });
|
105 | partial && cb(file);
|
106 | })(file, cb);
|
107 | }
|
108 | }
|
109 | }
|
110 |
|
111 |
|
112 |
|
113 | function storeDirectory(file) {
|
114 | var directory = file.fullParentDir;
|
115 | if (!watched_directories[directory]) {
|
116 | fs.stat(directory, function(err, stats) {
|
117 | watched_directories[directory] = (new Date(stats.mtime)).getTime();
|
118 | });
|
119 | }
|
120 | }
|
121 |
|
122 | return {
|
123 | watchDirectory: watchDirectory,
|
124 | watchFiles: watchFiles,
|
125 | unwatchAll: unwatchAll
|
126 | };
|
127 | }
|