1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const events_1 = require("events");
|
4 | const fs_1 = require("fs");
|
5 | const path_1 = require("path");
|
6 | const crypto_1 = require("crypto");
|
7 | const child_process_1 = require("child_process");
|
8 | class DirMonitor extends events_1.EventEmitter {
|
9 | constructor(path, isFile = false) {
|
10 | super();
|
11 | this._isFile = false;
|
12 | this._sub_file = new Map();
|
13 | this._sub_dri = new Map();
|
14 | this._path = path;
|
15 | this._isFile = isFile;
|
16 | }
|
17 | init() {
|
18 |
|
19 | if (this._isFile) {
|
20 | if (this._path.indexOf('.js') == -1) {
|
21 | this._path = this._path + '.js';
|
22 | }
|
23 | this._fsw = fs_1.watch(this._path);
|
24 | this._fsw.on("change", this._on_modify.bind(this));
|
25 | this._fsw.on("error", this._on_error.bind(this));
|
26 | if (fs_1.existsSync(this._path)) {
|
27 | let md5 = crypto_1.createHash("md5").update(fs_1.readFileSync(this._path)).digest("hex");
|
28 | this._sub_file.set(path_1.parse(this._path).base, md5);
|
29 | this.emit("new", this._path);
|
30 | }
|
31 | return;
|
32 | }
|
33 | else {
|
34 |
|
35 | if (!fs_1.existsSync(this._path)) {
|
36 | fs_1.mkdirSync(this._path);
|
37 | }
|
38 | let files = fs_1.readdirSync(this._path);
|
39 | for (let i = 0; i < files.length; i++) {
|
40 | let filename = files[i];
|
41 | let r_file = path_1.join(this._path, filename);
|
42 | let stat = fs_1.statSync(r_file);
|
43 | if (stat.isDirectory()) {
|
44 | let mot = new DirMonitor(r_file);
|
45 | mot.on("new", this._pip_event.bind(this, "new"));
|
46 | mot.on("change", this._pip_event.bind(this, "change"));
|
47 | mot.on("del", this._pip_event.bind(this, "del"));
|
48 | mot.init();
|
49 | this._sub_dri.set(filename, mot);
|
50 | }
|
51 | else {
|
52 | let md5 = crypto_1.createHash("md5").update(fs_1.readFileSync(r_file)).digest("hex");
|
53 | this._sub_file.set(filename, md5);
|
54 | this.emit("new", r_file);
|
55 | }
|
56 | }
|
57 | this._fsw = fs_1.watch(this._path);
|
58 | this._fsw.on("change", this._on_modify.bind(this));
|
59 | this._fsw.on("error", this._on_error.bind(this));
|
60 | }
|
61 | }
|
62 | on(event, listener) {
|
63 | return super.on(event, listener);
|
64 | }
|
65 | off(event, listener) {
|
66 | return super.off(event, listener);
|
67 | }
|
68 | _pip_event(event, ...args) {
|
69 | this.emit(event, ...args);
|
70 | }
|
71 | _on_error(error) {
|
72 |
|
73 |
|
74 | }
|
75 | _on_modify(event, filename) {
|
76 | let r_path = '';
|
77 | if (this._isFile) {
|
78 | r_path = this._path;
|
79 | }
|
80 | else {
|
81 | r_path = path_1.join(this._path, filename);
|
82 | }
|
83 |
|
84 | if (!fs_1.existsSync(r_path)) {
|
85 | if (this._sub_dri.has(filename)) {
|
86 |
|
87 | let dir = this._sub_dri.get(filename);
|
88 | dir && dir.destory();
|
89 | this._sub_dri.delete(filename);
|
90 | }
|
91 | else if (this._sub_file.has(filename)) {
|
92 | this.emit("del", r_path);
|
93 | this._sub_file.delete(filename);
|
94 | }
|
95 | }
|
96 | else {
|
97 |
|
98 | let stat = fs_1.statSync(r_path);
|
99 | if (stat.isDirectory()) {
|
100 |
|
101 | if (!this._sub_dri.has(filename)) {
|
102 | let mot = new DirMonitor(r_path);
|
103 | mot.on("new", this._pip_event.bind(this, "new"));
|
104 | mot.on("change", this._pip_event.bind(this, "change"));
|
105 | mot.on("del", this._pip_event.bind(this, "del"));
|
106 | mot.init();
|
107 | this._sub_dri.set(filename, mot);
|
108 | }
|
109 | }
|
110 | else {
|
111 |
|
112 | let md5 = crypto_1.createHash("md5").update(fs_1.readFileSync(r_path)).digest("hex");
|
113 | if (!this._sub_file.has(filename)) {
|
114 |
|
115 | this.emit("new", r_path);
|
116 | }
|
117 | else if (this._sub_file.get(filename) != md5) {
|
118 |
|
119 | this.emit("change", r_path);
|
120 | }
|
121 | this._sub_file.set(filename, md5);
|
122 | }
|
123 | }
|
124 | }
|
125 | destory() {
|
126 | this._sub_file.forEach((v, k, m) => {
|
127 | this.emit("del", path_1.join(this._path, k));
|
128 | });
|
129 | this._fsw && this._fsw.close();
|
130 | this.removeAllListeners("new");
|
131 | this.removeAllListeners("change");
|
132 | this.removeAllListeners("del");
|
133 | this._sub_dri.forEach((v, k, m) => {
|
134 | v.destory();
|
135 | });
|
136 | }
|
137 | }
|
138 | class AutoLoaderModule extends events_1.EventEmitter {
|
139 | constructor(dir, option) {
|
140 | super();
|
141 | this._ModuleCache_ = {};
|
142 | this._option = option || {};
|
143 | let md = new DirMonitor(dir, this._option.isFile ? true : false);
|
144 | md.on("new", this.addModule.bind(this));
|
145 | md.on("change", (f) => {
|
146 | this.delModule(f);
|
147 | this.addModule(f);
|
148 | });
|
149 | md.on("del", this.delModule.bind(this));
|
150 |
|
151 | this._md = md;
|
152 | AutoLoaderModule.cache[dir] = this;
|
153 | }
|
154 | |
155 |
|
156 |
|
157 |
|
158 | static watch(dir, option) {
|
159 | let tp = this.cache[dir];
|
160 | if (!tp) {
|
161 | tp = new AutoLoaderModule(dir, option);
|
162 | this.cache[dir] = tp;
|
163 | }
|
164 | return tp;
|
165 | }
|
166 | |
167 |
|
168 |
|
169 | load() {
|
170 | this._md.init();
|
171 | return this;
|
172 | }
|
173 | on(event, listener) {
|
174 | return super.on(event, listener);
|
175 | }
|
176 | off(event, listener) {
|
177 | return super.off(event, listener);
|
178 | }
|
179 | addModule(filename) {
|
180 |
|
181 | if (this._ModuleCache_.hasOwnProperty(filename)) {
|
182 |
|
183 | return;
|
184 | }
|
185 | let comp = false;
|
186 | let ext = path_1.parse(filename).ext;
|
187 | try {
|
188 | if (ext == '.js') {
|
189 | let __all = require(filename);
|
190 | let __pre_all = AutoLoaderModule.del_cache[filename];
|
191 |
|
192 | if (__pre_all) {
|
193 | for (let key in __all) {
|
194 | __pre_all.exports[key] = __all[key];
|
195 | }
|
196 | delete AutoLoaderModule.del_cache[filename];
|
197 | require.cache[filename] = __pre_all;
|
198 | }
|
199 | }
|
200 | else if (ext == '.ts') {
|
201 |
|
202 |
|
203 | if (this._option.tsc) {
|
204 | child_process_1.exec("tsc " + filename, (o) => {
|
205 |
|
206 | if (o)
|
207 | console.error(o);
|
208 | });
|
209 | }
|
210 | }
|
211 | comp = true;
|
212 | }
|
213 | catch (e) {
|
214 | console.error('load_module[%s]_error[%s]', filename, e);
|
215 | }
|
216 | if (ext == '.js') {
|
217 | this._ModuleCache_[filename] = comp;
|
218 | this.emit('add', filename, comp);
|
219 | }
|
220 | }
|
221 | delModule(filename) {
|
222 | AutoLoaderModule.del_cache[filename] = require.cache[filename];
|
223 | delete this._ModuleCache_[filename];
|
224 | delete require.cache[filename];
|
225 | this.emit("del", filename, true);
|
226 | }
|
227 | }
|
228 | exports.AutoLoaderModule = AutoLoaderModule;
|
229 | AutoLoaderModule.cache = {};
|
230 | AutoLoaderModule.del_cache = {};
|