1 | 'use strict';
|
2 |
|
3 | const fs = require('fs');
|
4 | const path = require('path');
|
5 | const watch = require('@cnakazawa/watch');
|
6 | const common = require('./common');
|
7 | const EventEmitter = require('events').EventEmitter;
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | const DEFAULT_DELAY = common.DEFAULT_DELAY;
|
14 | const CHANGE_EVENT = common.CHANGE_EVENT;
|
15 | const DELETE_EVENT = common.DELETE_EVENT;
|
16 | const ADD_EVENT = common.ADD_EVENT;
|
17 | const ALL_EVENT = common.ALL_EVENT;
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | module.exports = class PollWatcher extends EventEmitter {
|
30 | constructor(dir, opts) {
|
31 | super();
|
32 |
|
33 | opts = common.assignOptions(this, opts);
|
34 |
|
35 | this.watched = Object.create(null);
|
36 | this.root = path.resolve(dir);
|
37 |
|
38 | watch.createMonitor(
|
39 | this.root,
|
40 | {
|
41 | interval: (opts.interval || DEFAULT_DELAY) / 1000,
|
42 | filter: this.filter.bind(this),
|
43 | },
|
44 | this.init.bind(this)
|
45 | );
|
46 | }
|
47 |
|
48 | |
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 | filter(filepath, stat) {
|
57 | return (
|
58 | stat.isDirectory() ||
|
59 | common.isFileIncluded(
|
60 | this.globs,
|
61 | this.dot,
|
62 | this.doIgnore,
|
63 | path.relative(this.root, filepath)
|
64 | )
|
65 | );
|
66 | }
|
67 |
|
68 | |
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 | init(monitor) {
|
77 | this.watched = monitor.files;
|
78 | monitor.on('changed', this.emitEvent.bind(this, CHANGE_EVENT));
|
79 | monitor.on('removed', this.emitEvent.bind(this, DELETE_EVENT));
|
80 | monitor.on('created', this.emitEvent.bind(this, ADD_EVENT));
|
81 |
|
82 | setTimeout(this.emit.bind(this, 'ready'), 1000);
|
83 | }
|
84 |
|
85 | |
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 | emitEvent(type, file, stat) {
|
93 | file = path.relative(this.root, file);
|
94 |
|
95 | if (type === DELETE_EVENT) {
|
96 |
|
97 | stat = null;
|
98 | }
|
99 |
|
100 | this.emit(type, file, this.root, stat);
|
101 | this.emit(ALL_EVENT, type, file, this.root, stat);
|
102 | }
|
103 |
|
104 | |
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 | close(callback) {
|
111 | Object.keys(this.watched).forEach(filepath => fs.unwatchFile(filepath));
|
112 | this.removeAllListeners();
|
113 | if (typeof callback === 'function') {
|
114 | setImmediate(callback.bind(null, null, true));
|
115 | }
|
116 | }
|
117 | };
|