mm_machine 1.9.1 → 1.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/item.js ADDED
@@ -0,0 +1,460 @@
1
+ const util = require('util');
2
+ const conf = require('mm_config');
3
+ const Mod = require('mm_hot_reload');
4
+ $.mod = new Mod();
5
+ $.require = function(file, func) {
6
+ return $.mod.load(file, func);
7
+ }
8
+ $.loadJson = function(file, func) {
9
+ return $.mod.load(file, func);
10
+ }
11
+
12
+ /**
13
+ * 驱动基础类
14
+ * @class
15
+ */
16
+ class Item {
17
+ /**
18
+ * 构造函数
19
+ * @param {String} dir 当前目录
20
+ * @param {String} dir_base 模块目录
21
+ * @constructor
22
+ */
23
+ constructor(dir, dir_base) {
24
+ /**
25
+ * 当前路径
26
+ */
27
+ this.dir = dir;
28
+
29
+ /**
30
+ * 默认文件
31
+ */
32
+ this.default_file = "./sys.json";
33
+
34
+ // 当前文件
35
+ this.filename;
36
+ /* 通用项 */
37
+ /**
38
+ * 配置参数
39
+ */
40
+ this.config = {
41
+ /**
42
+ * 名称, 由中英文和下“_”组成, 用于卸载接口 例如: demo
43
+ */
44
+ "name": "",
45
+ /**
46
+ * 标题, 介绍作用
47
+ */
48
+ "title": "",
49
+ /**
50
+ * 描述, 用于描述该有什么用的
51
+ */
52
+ "description": "",
53
+ /**
54
+ * 文件路径, 当调用函数不存在时,会先从文件中加载
55
+ */
56
+ "func_file": "./index.js",
57
+ /**
58
+ * 回调函数名 用于决定调用脚本的哪个函数
59
+ */
60
+ "func_name": "",
61
+ /**
62
+ * 排序
63
+ */
64
+ "sort": 10,
65
+ /**
66
+ * 状态, 0表示未启用, 1表示启用
67
+ */
68
+ "state": 1,
69
+ /**
70
+ * 显示, 0表示不显示, 1表示显示
71
+ */
72
+ "show": 0
73
+ };
74
+
75
+ /**
76
+ * 模块目录
77
+ */
78
+ this.dir_base = dir_base;
79
+
80
+ /**
81
+ * 模式
82
+ * 1.生产模式,改变文件不会重新加载
83
+ * 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
84
+ * 3.热重载模式,改变配置文件都会加载配置和脚本
85
+ * 4.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
86
+ * 5.重载模式,执行完后重新加载脚本,避免变量污染
87
+ */
88
+ this.mode = 1;
89
+
90
+ // 加载完成
91
+ this.complete = false;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * 设置配置
97
+ * @param {Object} config 配置
98
+ */
99
+ Item.prototype.set_config = function(config) {
100
+ this.config = conf(Object.assign({}, this.config, config || {}), this.filename);
101
+ this.set_config_after();
102
+ }
103
+
104
+ /**
105
+ * 设置配置后
106
+ */
107
+ Item.prototype.set_config_after = function() {
108
+
109
+ };
110
+
111
+ /**
112
+ * 新建脚本
113
+ * @param {String} file
114
+ */
115
+ Item.prototype.new_script = function(file) {
116
+ var fl = this.dir_base + "/script.js";
117
+ if (fl.hasFile()) {
118
+ fl.copyFile(file);
119
+ }
120
+ };
121
+
122
+ /**
123
+ * 移除模块
124
+ * @param {Object} m
125
+ */
126
+ Item.prototype.remove_module = function(m) {
127
+ if (this.mode === 3 || this.mode === 4) {
128
+ // 移除模块和监听
129
+ $.mod.unload(m);
130
+ } else {
131
+ // 移除模块
132
+ var filename = require.resolve(m);
133
+ require.cache[filename] = null;
134
+ delete require.cache[filename];
135
+ }
136
+ };
137
+
138
+ /**
139
+ * 卸载脚本
140
+ * @param {String} file 文件
141
+ */
142
+ Item.prototype.unload_script = function(file) {
143
+ this.remove_module(file || this.config.func_file.fullname(this.dir));
144
+ this.complete = false;
145
+ }
146
+
147
+ /**
148
+ * 重载脚本
149
+ * @param {String} file 文件
150
+ */
151
+ Item.prototype.reload_script = function() {
152
+ this.unload_script();
153
+ this.load_script();
154
+ }
155
+
156
+ /**
157
+ * 卸载
158
+ */
159
+ Item.prototype.unload = async function() {
160
+
161
+ }
162
+
163
+ /**
164
+ * 卸载之后
165
+ * @param {Boolean} remove 是否删除文件
166
+ */
167
+ Item.prototype.unload_after = async function(remove) {
168
+ // 删除脚本
169
+ this.unload_script();
170
+ if (remove) {
171
+ this.remove_file();
172
+ }
173
+ }
174
+
175
+ /**
176
+ * 加载脚本
177
+ * @param {String} file 文件
178
+ * @param {String} name 函数名
179
+ * @returns {Object} 返回加载的模块对象
180
+ */
181
+ Item.prototype.load_script = function(file, name = "") {
182
+ if (!file) {
183
+ var f = this.config.func_file;
184
+ if (f) {
185
+ file = f.fullname(this.dir);
186
+ if (!file.hasFile()) {
187
+ this.new_script(file);
188
+ }
189
+ }
190
+ }
191
+ if (!name) {
192
+ name = this.config.func_name;
193
+ }
194
+ var cs;
195
+ if (this.mode === 3 || this.mode === 4) {
196
+ cs = $.require(file, (cs, way) => {
197
+ if (way == "change" && cs) {
198
+ if (name) {
199
+ this.main = cs[name];
200
+ } else {
201
+ $.push(this, cs, true);
202
+ }
203
+ }
204
+ });
205
+ } else {
206
+ cs = require(file);
207
+ }
208
+ if (cs) {
209
+ if (name) {
210
+ this.main = cs[name];
211
+ } else {
212
+ $.push(this, cs, true);
213
+ }
214
+ }
215
+ return cs;
216
+ }
217
+
218
+ /**
219
+ * 新建配置
220
+ * @param {String} file
221
+ */
222
+ Item.prototype.new_config = function(file) {
223
+ var fl = this.dir_base + "/config.tpl.json";
224
+ fl.copyFile(file);
225
+ };
226
+
227
+ /**
228
+ * 加载配置文件
229
+ * @param {String} file 文件路径
230
+ * @param {String} name 配置项名称
231
+ * @return {Object} 配置对象
232
+ */
233
+ Item.prototype.load_file = function(file, name) {
234
+ var config;
235
+ var f = file.fullname(this.dir);
236
+ var text = f.loadText();
237
+ if (!text) {
238
+ this.new_config(f);
239
+ }
240
+ if (text) {
241
+ if (this.mode === 2 || this.mode === 3 || this.mode === 4) {
242
+ config = $.loadJson(f, (conf, way) => {
243
+ if (way == "change" && conf) {
244
+ if (Array.isArray(conf)) {
245
+ var list = conf;
246
+ for (var i = 0; i < list.length; i++) {
247
+ var o = list[i];
248
+ if (this.config.name === o.name) {
249
+ this.set_config(o);
250
+ if (this.mode === 3 || this.mode === 4) {
251
+ this.reload_script();
252
+ }
253
+ break;
254
+ }
255
+ }
256
+ } else {
257
+ this.set_config(conf);
258
+ if (this.mode === 3 || this.mode === 4) {
259
+ this.reload_script();
260
+ }
261
+ }
262
+ }
263
+ });
264
+ } else {
265
+ config = f.loadJson();
266
+ }
267
+
268
+ if (name) {
269
+ if (Array.isArray(config)) {
270
+ var list = config;
271
+ for (var i = 0; i < list.length; i++) {
272
+ var o = list[i];
273
+ if (name === o.name) {
274
+ config = o;
275
+ break;
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+ this.dir = f.dirname();
282
+ this.filename = f;
283
+ return config;
284
+ };
285
+
286
+ /**
287
+ * 删除文件
288
+ */
289
+ Item.prototype.del_dir = function() {
290
+ var f = this.config.func_file;
291
+ if (f) {
292
+ $.dir.del(this.dir);
293
+ }
294
+ };
295
+
296
+ /**
297
+ * 删除配置和脚本文件
298
+ * @param {Object} item 项目
299
+ */
300
+ Item.prototype.remove_file = function() {
301
+ var name = this.config.name;
302
+ var file = this.filename;
303
+
304
+ var msg = null;
305
+ if (file.hasFile()) {
306
+ var text = file.loadText();
307
+ if (text) {
308
+ var jarr = text.toJson();
309
+ if (jarr.constructor == Array) {
310
+ for (var i = 0; i < jarr.length; i++) {
311
+ var o = jarr[i];
312
+ if (name === o.name) {
313
+ this.del_dir();
314
+ jarr.splice(i, 1);
315
+ break;
316
+ }
317
+ }
318
+ if (jarr.length) {
319
+ file.saveText(JSON.stringify(jarr, null, 4));
320
+ } else {
321
+ file.delFile();
322
+ }
323
+ } else {
324
+ this.del_dir();
325
+ }
326
+ } else {
327
+ this.del_dir();
328
+ }
329
+ } else {
330
+ msg = "配置文件不存在";
331
+ }
332
+ return msg;
333
+ };
334
+
335
+ /**
336
+ * 载入配置
337
+ * @param {Object|String} cg 配置对象或配置路径
338
+ * @param {String} name 配置名称
339
+ */
340
+ Item.prototype.load_config = function(cg, name) {
341
+ var config;
342
+ if (cg) {
343
+ if (typeof(cg) === "string") {
344
+ config = this.load_file(cg, name);
345
+ } else {
346
+ config = cg;
347
+ }
348
+ } else {
349
+ config = this.load_file(this.filename, name);
350
+ }
351
+ this.set_config(config);
352
+ };
353
+
354
+ /**
355
+ * 加载前
356
+ */
357
+ Item.prototype.load_before = async function() {
358
+ var cs = this.load_script();
359
+ if (cs) {
360
+ this.complete = true;
361
+ }
362
+ }
363
+
364
+ /**
365
+ * 加载
366
+ */
367
+ Item.prototype.load = async function() {
368
+ // 加载前
369
+ }
370
+
371
+ /**
372
+ * 重载配置和脚本
373
+ */
374
+ Item.prototype.reload = async function() {
375
+ await this.run('unload');
376
+ await this.run('load');
377
+ }
378
+
379
+ /**
380
+ * 保存配置
381
+ */
382
+ Item.prototype.save = function() {
383
+ var f = this.filename.fullname(this.dir);
384
+ var text = f.loadText();
385
+ if (text) {
386
+ if (text.trim().startsWith('[')) {
387
+ var jarr = text.toJson();
388
+ for (var i = 0; i < jarr.length; i++) {
389
+ if (jarr[i].name === this.config.name) {
390
+ jarr[i] = this.config;
391
+ break;
392
+ }
393
+ }
394
+ var txt = JSON.stringify(jarr, null, 4);
395
+ f.saveText(txt);
396
+ return;
397
+ }
398
+ }
399
+ var txt = JSON.stringify(this.config, null, 4);
400
+ f.saveText(txt);
401
+ };
402
+
403
+ /**
404
+ * 主要执行函数
405
+ * @param {Object} params 参数集合
406
+ */
407
+ Item.prototype.main = async function(...params) {
408
+ // console.log("未实现", params);
409
+ return null;
410
+ };
411
+
412
+ /**
413
+ * 调用函数
414
+ * @param {String} method 函数名
415
+ * @param {Object} params 参数集合
416
+ * @return {Object} 执行结果
417
+ */
418
+ Item.prototype.run = async function(method, ...params) {
419
+ if (this[method]) {
420
+ var ret;
421
+ if (this[method + "_before"]) {
422
+ try {
423
+ ret = this[method + "_before"](...params);
424
+ } catch (err) {
425
+ $.log.error("执行前失败!", err);
426
+ }
427
+ if (util.types.isPromise(ret)) {
428
+ ret = await ret;
429
+ }
430
+ }
431
+ try {
432
+ ret = this[method](...params);
433
+ } catch (err) {
434
+ $.log.error("执行时失败!", err);
435
+ }
436
+ if (util.types.isPromise(ret)) {
437
+ ret = await ret;
438
+ }
439
+ // console.log(this.config.name + "-" + method + "内容", ret);
440
+ if (this[method + "_after"]) {
441
+ try {
442
+ var result = this[method + "_after"](ret, ...params);
443
+ if (util.types.isPromise(result)) {
444
+ result = await result;
445
+ }
446
+ if (result) {
447
+ ret = result;
448
+ }
449
+ } catch (err) {
450
+ $.log.error("执行后失败!", err);
451
+ }
452
+ }
453
+ return ret
454
+ }
455
+ };
456
+
457
+ /**
458
+ * @module 导出Drive类
459
+ */
460
+ module.exports = Item;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_machine",
3
- "version": "1.9.1",
3
+ "version": "1.9.2",
4
4
  "description": "这是超级美眉框架机制构建辅助模块,用于快速构建一个机制",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -31,6 +31,6 @@
31
31
  "homepage": "https://github.com/qiuwenwu/mm_machine#readme",
32
32
  "dependencies": {
33
33
  "mm_config": "^1.1.4",
34
- "mm_hot_reload": "^1.0.5"
34
+ "mm_hot_reload": "^1.0.6"
35
35
  }
36
36
  }
package/test.js CHANGED
@@ -15,12 +15,13 @@ class Engine extends Index {
15
15
  super(scope, dir_base);
16
16
  /**
17
17
  * 模式
18
- * 1.不更新重载模式,改变文件不会重新加载,执行完后也不会重新加载
19
- * 2.热更新模式,改变文件重新加载
20
- * 3.重载模式,执行完后重新加载,避免变量污染
21
- * 4.热更新+重载模式,改变文件重新加载,执行完后重新加载
18
+ * 1.生产模式,改变文件不会重新加载
19
+ * 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
20
+ * 3.热重载模式,改变配置文件都会加载配置和脚本
21
+ * 4.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
22
+ * 5.重载模式,执行完后重新加载脚本,避免变量污染
22
23
  */
23
- this.mode = 0;
24
+ this.mode = 3;
24
25
  // 机制类型,必须填写,用于检索文件
25
26
  this.type = "demo";
26
27
  }
@@ -29,81 +30,91 @@ class Engine extends Index {
29
30
  Engine.prototype.Drive = Drive;
30
31
 
31
32
  async function demo() {
32
- var engine = new Engine();
33
+ var engine = new Engine('sys', __dirname);
33
34
  console.info("→ 加载mod");
34
35
  await engine.update("./".fullname(__dirname));
35
- await engine.run('demo1', 'init');
36
- await engine.exec('demo1', 'init');
36
+
37
+ console.log("模块数", engine.list.length);
38
+ // console.log("模块", engine.list);
39
+
40
+ await engine.run('demo1', 'init'); // 只有启动状态的插件才会执行
41
+ await engine.exec('demo1', 'init'); // 未启动也会执行,并且如果未加载脚本则会自动加载
37
42
  await engine.run(null, 'main');
38
43
  await engine.exec(null, 'main');
39
44
 
40
- var plug = engine.get('demo1');
41
- if (plug) {
42
- plug.loadFile(plug.filename);
43
- }
44
-
45
- var i = await engine.run('demo3', 'main');
46
- console.log("指明回调demo3", i);
45
+ var ret = await engine.run('demo3', 'main');
46
+ console.log("指明回调demo3", ret);
47
47
 
48
- // console.log("模块数", engine.list.length);
48
+ var ret = await engine.exec('demo1', 'main');
49
+ console.log("指明回调demo1", ret);
49
50
 
50
- // var i = 0;
51
- // var timer = setInterval(async () => {
52
- // await engine.run('demo1', 'main');
53
- // await engine.run('demo2', 'main');
54
- // i++;
55
- // if (i == 5) {
56
- // console.info("→ 重载mod");
57
- // engine.reload("demo1");
58
- // } else if (i == 8) {
59
- // console.info("→ 卸载mod");
60
- // engine.unload("demo2");
61
- // } else if (i == 13) {
62
- // console.info("→ 卸载并删除mod");
63
- // engine.unload("demo1", true);
64
- // } else if (i == 15) {
65
- // clearTimeout(timer);
66
- // process.exit(0);
67
- // }
68
- // }, 3000);
51
+ var i = 0;
52
+ var timer = setInterval(async () => {
53
+ await engine.run('demo1', 'main');
54
+ await engine.run('demo2', 'main');
55
+ i++;
56
+ if (i == 3) {
57
+ console.info("→ 重载mod");
58
+ await engine.reload("demo1");
59
+ } else if (i == 5) {
60
+ console.info("→ 卸载mod");
61
+ await engine.unload("demo2");
62
+ } else if (i == 16) {
63
+ console.info("→ 卸载并删除mod");
64
+ await engine.unload("demo1", true);
65
+ } else if (i == 18) {
66
+ clearTimeout(timer);
67
+ }
68
+ }, 3000);
69
69
 
70
- // setTimeout(() => {
71
- // var file = "./demo/test1/index.js";
72
- // var text = file.loadText();
73
- // text = text.replace("123", "1234567");
74
- // file.saveText(text);
75
- // }, 7000)
70
+ setTimeout(async() => {
71
+ var file = "./demo/test1/index.js";
72
+ var text = file.loadText();
73
+ text = text.replace("123", "1234567");
74
+ file.saveText(text);
75
+ var ret = await engine.exec("demo1", 'main');
76
+ console.log("这结果", ret);
77
+ }, 7000)
76
78
 
77
79
  // setTimeout(() => {
78
80
  // var file = "./demo/test2/index.js";
79
81
  // var text = file.loadText();
80
82
  // text = text.replace("123", "7654321");
81
83
  // file.saveText(text);
82
- // }, 20000)
83
-
84
- // setTimeout(() => {
85
- // // 让热重载失效
86
- // console.info("→ 热重载失效");
87
- // $.mod.config.watch = false;
88
- // // 失效后再加载的模块修改文件没有变化
89
- // var file = "./demo/test1/index.js";
90
- // var text = file.loadText();
91
- // text = text.replace("1234567", "7654321");
92
- // file.saveText(text);
93
- // }, 26000)
84
+ // }, 11000)
94
85
 
95
- // setInterval(() => {
96
- // var plug = engine.get("demo1");
97
- // console.log("查看变化1", plug.config);
98
- // var plug = engine.get("demo3");
99
- // console.log("查看变化3", plug.config);
100
- // }, 3000);
101
- setTimeout(async() => {
102
- await engine.update(null, false);
86
+ setTimeout(async () => {
87
+ // 让热重载失效
88
+ console.info("→ 热重载失效");
89
+ $.mod.config.watch = false;
90
+ // 失效后再加载的模块修改文件没有变化
91
+ var file = "./demo/test1/index.js";
92
+ var text = file.loadText();
93
+ text = text.replace("1234567", "7654321");
94
+ file.saveText(text);
95
+ var ret = await engine.exec("demo1", 'main');
96
+ console.log("这结果", ret);
97
+ }, 16000)
98
+
99
+ var n = 0;
100
+ var timer_2 = setInterval(async () => {
101
+ // await engine.update(null, false, false, false);
102
+ var ret = await engine.exec('demo1', 'main');
103
+ console.info("最后运行demo", ret);
103
104
  var plug = engine.get("demo1");
104
- console.log("查看变化1", plug.config);
105
- var plug = engine.get("demo3");
106
- console.log("查看变化3", plug.config);
105
+ if (plug) {
106
+ console.log("查看变化1", plug.config);
107
+ }
108
+ // var plug = engine.get("demo3");
109
+ // if (plug) {
110
+ // var ret = await plug.run('main');
111
+ // console.log("查看变化3", plug.config);
112
+ // }
113
+ n++;
114
+ if (n == 6) {
115
+ clearInterval(timer_2);
116
+ process.exit(0);
117
+ }
107
118
  }, 10000);
108
119
  }
109
120