mm_machine 2.2.0 → 2.2.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/index.js +43 -42
- package/item.js +45 -25
- package/package.json +6 -1
package/index.js
CHANGED
|
@@ -93,7 +93,7 @@ Index.prototype._exec = async function (module, method, params = []) {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
// 执行方法
|
|
96
|
-
|
|
96
|
+
let ret = await module.exec(method, ...params);
|
|
97
97
|
|
|
98
98
|
// 根据模式决定是否重载
|
|
99
99
|
if (this.mode >= 4) {
|
|
@@ -105,7 +105,7 @@ Index.prototype._exec = async function (module, method, params = []) {
|
|
|
105
105
|
$.log.error(`[${this.type}] 执行模块方法失败: `, err);
|
|
106
106
|
return null;
|
|
107
107
|
}
|
|
108
|
-
}
|
|
108
|
+
};
|
|
109
109
|
|
|
110
110
|
/**
|
|
111
111
|
* 加载项
|
|
@@ -114,7 +114,7 @@ Index.prototype._exec = async function (module, method, params = []) {
|
|
|
114
114
|
* @param {string} file 配置文件
|
|
115
115
|
* @returns {Promise<object | null>} 加载的驱动或配置对象
|
|
116
116
|
*/
|
|
117
|
-
Index.prototype.
|
|
117
|
+
Index.prototype.loadDrive = async function (dir, cg, file) {
|
|
118
118
|
if (!dir || !file) {
|
|
119
119
|
$.log.error(`[${this.type}] load: 缺少必要参数`);
|
|
120
120
|
return null;
|
|
@@ -135,7 +135,7 @@ Index.prototype.loadItem = async function (dir, cg, file) {
|
|
|
135
135
|
} else {
|
|
136
136
|
let json = file.loadJson();
|
|
137
137
|
if (!json) {
|
|
138
|
-
|
|
138
|
+
let fl = './config.tpl.json'.fullname(this.dir_base);
|
|
139
139
|
if (fl.hasFile()) {
|
|
140
140
|
fl.copyFile(file);
|
|
141
141
|
json = file.loadJson();
|
|
@@ -176,8 +176,8 @@ Index.prototype.loads = async function (list) {
|
|
|
176
176
|
*/
|
|
177
177
|
Index.prototype.sort = function () {
|
|
178
178
|
this.list.sort((o1, o2) => {
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
let p1 = o1.config?.[this.sort_key] || 0;
|
|
180
|
+
let p2 = o2.config?.[this.sort_key] || 0;
|
|
181
181
|
return p2 - p1;
|
|
182
182
|
});
|
|
183
183
|
};
|
|
@@ -203,7 +203,7 @@ Index.prototype.updateAfter = async function (dir_path) {
|
|
|
203
203
|
* @param {string} search_path 检索路径
|
|
204
204
|
* @returns {string} 规范化后的路径
|
|
205
205
|
*/
|
|
206
|
-
Index.prototype.
|
|
206
|
+
Index.prototype._searchPath = function (search_path) {
|
|
207
207
|
if (!search_path) {
|
|
208
208
|
return './app/';
|
|
209
209
|
}
|
|
@@ -216,7 +216,7 @@ Index.prototype._normalizeSearchPath = function (search_path) {
|
|
|
216
216
|
* @param {string} norm_path 规范化路径
|
|
217
217
|
* @returns {Array} 目录列表
|
|
218
218
|
*/
|
|
219
|
-
Index.prototype.
|
|
219
|
+
Index.prototype._getDirList = function (norm_path) {
|
|
220
220
|
try {
|
|
221
221
|
// 使用精准模式总是获取所有目录
|
|
222
222
|
// 这样可以确保找到test1和test2目录
|
|
@@ -232,15 +232,15 @@ Index.prototype._getDirectoryList = function (norm_path) {
|
|
|
232
232
|
* @param {string} dir 目录路径
|
|
233
233
|
* @returns {Promise<void>}
|
|
234
234
|
*/
|
|
235
|
-
Index.prototype.
|
|
235
|
+
Index.prototype._runDirConfig = async function (dir) {
|
|
236
236
|
// 直接检查并加载demo.json文件
|
|
237
|
-
|
|
237
|
+
let config_file = `./${this.type}.json`.fullname(dir);
|
|
238
238
|
if (config_file && config_file.hasFile && config_file.hasFile()) {
|
|
239
239
|
await this.loadFile(config_file, true);
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
// 同时也检查config_demo.json文件
|
|
243
|
-
|
|
243
|
+
let config_file2 = `./config_${this.type}.json`.fullname(dir);
|
|
244
244
|
if (config_file2 && config_file2.hasFile && config_file2.hasFile()) {
|
|
245
245
|
await this.loadFile(config_file2, true);
|
|
246
246
|
}
|
|
@@ -255,15 +255,15 @@ Index.prototype._processDirectoryConfig = async function (dir) {
|
|
|
255
255
|
Index.prototype.updateConfigAll = async function (search_path, accurate) {
|
|
256
256
|
try {
|
|
257
257
|
// 规范化路径
|
|
258
|
-
|
|
258
|
+
let norm_path = this._searchPath(search_path);
|
|
259
259
|
|
|
260
260
|
// 获取目录列表
|
|
261
|
-
|
|
261
|
+
let list_scope = this._getDirList(norm_path);
|
|
262
262
|
|
|
263
263
|
// 使用函数式编程处理目录
|
|
264
264
|
await list_scope.reduce(async (prev_promise, dir) => {
|
|
265
265
|
await prev_promise;
|
|
266
|
-
return this.
|
|
266
|
+
return this._runDirConfig(dir);
|
|
267
267
|
}, Promise.resolve());
|
|
268
268
|
} catch (err) {
|
|
269
269
|
$.log.error(`[${this.type}] 更新所有配置失败: `, err);
|
|
@@ -276,7 +276,7 @@ Index.prototype.updateConfigAll = async function (search_path, accurate) {
|
|
|
276
276
|
* @returns {Promise<void>}
|
|
277
277
|
*/
|
|
278
278
|
Index.prototype.updateConfigHave = async function (dir_path) {
|
|
279
|
-
|
|
279
|
+
let list = this.list;
|
|
280
280
|
await list.reduce(async (prev_promise, o) => {
|
|
281
281
|
await prev_promise;
|
|
282
282
|
return this._updateSingleConfig(o);
|
|
@@ -288,14 +288,14 @@ Index.prototype.updateConfigHave = async function (dir_path) {
|
|
|
288
288
|
* @param {object} o 配置对象
|
|
289
289
|
*/
|
|
290
290
|
Index.prototype._updateSingleConfig = async function (o) {
|
|
291
|
-
|
|
291
|
+
let file = o.filename;
|
|
292
292
|
if (!file) return;
|
|
293
293
|
|
|
294
294
|
try {
|
|
295
|
-
|
|
295
|
+
let config = file.loadJson();
|
|
296
296
|
if (!config) return;
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
let target_config = this._findConfig(config, o.config.name);
|
|
299
299
|
if (target_config) {
|
|
300
300
|
await o.exec('setConfig', target_config);
|
|
301
301
|
}
|
|
@@ -344,7 +344,7 @@ Index.prototype.updateConfig = async function (dir, accurate = false, clear = fa
|
|
|
344
344
|
* @returns {Promise<void>}
|
|
345
345
|
*/
|
|
346
346
|
Index.prototype.updateScript = async function () {
|
|
347
|
-
|
|
347
|
+
let list = this.list;
|
|
348
348
|
await list.reduce(async (prev_promise, o) => {
|
|
349
349
|
await prev_promise;
|
|
350
350
|
if (o.config?.state === 1) {
|
|
@@ -400,7 +400,7 @@ Index.prototype.get = function (name) {
|
|
|
400
400
|
Index.prototype.set = function (name, cg) {
|
|
401
401
|
if (!name || !cg) return false;
|
|
402
402
|
|
|
403
|
-
|
|
403
|
+
let item = this.get(name);
|
|
404
404
|
if (item) {
|
|
405
405
|
// 使用Object.assign合并属性
|
|
406
406
|
Object.assign(item.config, cg);
|
|
@@ -414,7 +414,7 @@ Index.prototype.set = function (name, cg) {
|
|
|
414
414
|
* @returns {boolean} 是否保存成功
|
|
415
415
|
*/
|
|
416
416
|
Index.prototype.save = async function () {
|
|
417
|
-
|
|
417
|
+
let list = this.list;
|
|
418
418
|
await list.reduce(async (prev_promise, o) => {
|
|
419
419
|
await prev_promise;
|
|
420
420
|
if (o.config?.state === 1) {
|
|
@@ -436,7 +436,7 @@ Index.prototype.add = async function (config) {
|
|
|
436
436
|
|
|
437
437
|
try {
|
|
438
438
|
// 检查是否已存在
|
|
439
|
-
|
|
439
|
+
let existing = this.get(config.name);
|
|
440
440
|
if (existing) {
|
|
441
441
|
$.log.warn(`插件 ${config.name} 已存在`);
|
|
442
442
|
return existing;
|
|
@@ -460,11 +460,11 @@ Index.prototype.add = async function (config) {
|
|
|
460
460
|
Index.prototype.del = async function (name) {
|
|
461
461
|
if (!name) return false;
|
|
462
462
|
|
|
463
|
-
|
|
463
|
+
let index = this.list.findIndex((item) => item.config?.name === name);
|
|
464
464
|
if (index === -1) return false;
|
|
465
465
|
|
|
466
466
|
try {
|
|
467
|
-
|
|
467
|
+
let item = this.list[index];
|
|
468
468
|
await item.exec('unload');
|
|
469
469
|
this.list.splice(index, 1);
|
|
470
470
|
return true;
|
|
@@ -482,7 +482,7 @@ Index.prototype.del = async function (name) {
|
|
|
482
482
|
Index.prototype.load = async function (name) {
|
|
483
483
|
if (!name) return null;
|
|
484
484
|
|
|
485
|
-
|
|
485
|
+
let item = this.get(name);
|
|
486
486
|
if (!item) return null;
|
|
487
487
|
|
|
488
488
|
try {
|
|
@@ -504,7 +504,7 @@ Index.prototype.load = async function (name) {
|
|
|
504
504
|
Index.prototype.unload = async function (name) {
|
|
505
505
|
if (!name) return false;
|
|
506
506
|
|
|
507
|
-
|
|
507
|
+
let item = this.get(name);
|
|
508
508
|
if (!item) return false;
|
|
509
509
|
|
|
510
510
|
try {
|
|
@@ -524,7 +524,7 @@ Index.prototype.unload = async function (name) {
|
|
|
524
524
|
Index.prototype.reload = async function (name) {
|
|
525
525
|
if (!name) return null;
|
|
526
526
|
|
|
527
|
-
|
|
527
|
+
let item = this.get(name);
|
|
528
528
|
if (!item) return null;
|
|
529
529
|
|
|
530
530
|
try {
|
|
@@ -544,22 +544,22 @@ Index.prototype.reload = async function (name) {
|
|
|
544
544
|
*/
|
|
545
545
|
Index.prototype.loadFile = async function (file, create = false) {
|
|
546
546
|
try {
|
|
547
|
-
|
|
547
|
+
let dir = file.dirname();
|
|
548
548
|
// 载入文件
|
|
549
|
-
|
|
549
|
+
let obj = file.loadJson();
|
|
550
550
|
if (obj) {
|
|
551
551
|
if (Array.isArray(obj)) {
|
|
552
552
|
// 使用函数式编程处理数组
|
|
553
553
|
await obj.reduce(async (prev_promise, o) => {
|
|
554
554
|
await prev_promise;
|
|
555
555
|
// 实例化一个驱动
|
|
556
|
-
return this.
|
|
556
|
+
return this.loadDrive(dir, o, file);
|
|
557
557
|
}, Promise.resolve());
|
|
558
558
|
} else {
|
|
559
|
-
return await this.
|
|
559
|
+
return await this.loadDrive(dir, null, file);
|
|
560
560
|
}
|
|
561
561
|
} else if (create) {
|
|
562
|
-
return await this.
|
|
562
|
+
return await this.loadDrive(dir, null, file);
|
|
563
563
|
} else {
|
|
564
564
|
return `${file}文件不存在`;
|
|
565
565
|
}
|
|
@@ -579,22 +579,23 @@ Index.prototype.loadFile = async function (file, create = false) {
|
|
|
579
579
|
*/
|
|
580
580
|
Index.prototype.run = async function (name, method, ...params) {
|
|
581
581
|
if (name) {
|
|
582
|
-
|
|
582
|
+
let module = await this.get(name);
|
|
583
583
|
if (module && module.config?.state === 1) {
|
|
584
584
|
return await this._exec(module, method, params);
|
|
585
585
|
}
|
|
586
586
|
return null;
|
|
587
587
|
} else if (name === null) {
|
|
588
588
|
let result = null;
|
|
589
|
-
//
|
|
590
|
-
|
|
589
|
+
// 修复:使用for循环替代some,正确处理异步迭代
|
|
590
|
+
for (let module of this.list) {
|
|
591
591
|
if (module.config?.state === 1) {
|
|
592
592
|
result = await this._exec(module, method, params);
|
|
593
593
|
// 如果结果不为空且有结束标志,则停止迭代
|
|
594
|
-
|
|
594
|
+
if (result && module.config?.end) {
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
595
597
|
}
|
|
596
|
-
|
|
597
|
-
});
|
|
598
|
+
}
|
|
598
599
|
return result;
|
|
599
600
|
}
|
|
600
601
|
return null;
|
|
@@ -609,7 +610,7 @@ Index.prototype.run = async function (name, method, ...params) {
|
|
|
609
610
|
*/
|
|
610
611
|
Index.prototype.exec = async function (name, method, ...params) {
|
|
611
612
|
if (name) {
|
|
612
|
-
|
|
613
|
+
let module = await this.get(name);
|
|
613
614
|
if (module) {
|
|
614
615
|
return await this._exec(module, method, params);
|
|
615
616
|
}
|
|
@@ -623,9 +624,9 @@ Index.prototype.exec = async function (name, method, ...params) {
|
|
|
623
624
|
if (result && module.config?.end) {
|
|
624
625
|
return;
|
|
625
626
|
}
|
|
626
|
-
|
|
627
|
-
if (
|
|
628
|
-
result =
|
|
627
|
+
let current = await this._exec(module, method, params);
|
|
628
|
+
if (current) {
|
|
629
|
+
result = current;
|
|
629
630
|
}
|
|
630
631
|
}, Promise.resolve());
|
|
631
632
|
return result;
|
package/item.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
let util = require('util');
|
|
2
2
|
let { conf } = require('mm_config');
|
|
3
|
-
|
|
3
|
+
const Tpl = require('mm_tpl');
|
|
4
4
|
let { HotReload } = require('mm_hot_reload');
|
|
5
5
|
|
|
6
6
|
// 初始化全局对象
|
|
@@ -103,7 +103,6 @@ Item.prototype.log = function (level, message, ...args) {
|
|
|
103
103
|
/**
|
|
104
104
|
* 设置配置
|
|
105
105
|
* @param {object} config 配置对象
|
|
106
|
-
* @returns {Promise<void>}
|
|
107
106
|
*/
|
|
108
107
|
Item.prototype.setConfig = function (config) {
|
|
109
108
|
if (!config) return;
|
|
@@ -331,13 +330,23 @@ Item.prototype._setMainMethod = function (module, name) {
|
|
|
331
330
|
}
|
|
332
331
|
};
|
|
333
332
|
|
|
333
|
+
/**
|
|
334
|
+
* 获取配置文件作用域
|
|
335
|
+
* @param {object} file 文件对象
|
|
336
|
+
* @returns {string} 配置文件作用域
|
|
337
|
+
*/
|
|
338
|
+
Item.prototype._getScope = function (file) {
|
|
339
|
+
return file.replace(/\\/g, '/').between('app/', '/');
|
|
340
|
+
};
|
|
341
|
+
|
|
334
342
|
/**
|
|
335
343
|
* 新建配置文件
|
|
336
344
|
* @param {string} file 目标文件路径
|
|
337
345
|
*/
|
|
338
346
|
Item.prototype.newConfig = function (file) {
|
|
339
347
|
if (!this.config.name) {
|
|
340
|
-
this.config.name =
|
|
348
|
+
this.config.name = this._getName(file);
|
|
349
|
+
this.config.scope = this._getScope(file);
|
|
341
350
|
}
|
|
342
351
|
this._createConfigFile(file, this.config, this.dir_base);
|
|
343
352
|
};
|
|
@@ -511,7 +520,7 @@ Item.prototype._removeConfigFile = function (file, name) {
|
|
|
511
520
|
|
|
512
521
|
let config = text.toJson();
|
|
513
522
|
if (Array.isArray(config)) {
|
|
514
|
-
return this.
|
|
523
|
+
return this._removeArray(file, config, name);
|
|
515
524
|
}
|
|
516
525
|
|
|
517
526
|
this.delDir();
|
|
@@ -541,6 +550,15 @@ Item.prototype._removeArrayItem = function (file, config, name) {
|
|
|
541
550
|
return null;
|
|
542
551
|
};
|
|
543
552
|
|
|
553
|
+
/**
|
|
554
|
+
* 获取配置文件名称
|
|
555
|
+
* @param {object} file 文件对象
|
|
556
|
+
* @returns {string} 配置文件名称
|
|
557
|
+
*/
|
|
558
|
+
Item.prototype._getName = function (file) {
|
|
559
|
+
return file.dirname().basename();
|
|
560
|
+
};
|
|
561
|
+
|
|
544
562
|
/**
|
|
545
563
|
* 载入配置
|
|
546
564
|
* @param {object | string} config_data 配置对象或配置路径
|
|
@@ -608,17 +626,17 @@ Item.prototype.save = function () {
|
|
|
608
626
|
|
|
609
627
|
if (text && text.trim().startsWith('[')) {
|
|
610
628
|
// 数组格式配置
|
|
611
|
-
let
|
|
612
|
-
if (Array.isArray(
|
|
629
|
+
let config = text.toJson();
|
|
630
|
+
if (Array.isArray(config)) {
|
|
613
631
|
// 查找并更新现有配置项
|
|
614
|
-
let
|
|
615
|
-
if (
|
|
616
|
-
|
|
632
|
+
let index = config.findIndex((item) => item.name === this.config.name);
|
|
633
|
+
if (index !== -1) {
|
|
634
|
+
config[index] = this.config;
|
|
617
635
|
} else {
|
|
618
636
|
// 如果不存在,添加新配置项
|
|
619
|
-
|
|
637
|
+
config.push(this.config);
|
|
620
638
|
}
|
|
621
|
-
full_path.saveText(JSON.stringify(
|
|
639
|
+
full_path.saveText(JSON.stringify(config, null, 4));
|
|
622
640
|
return;
|
|
623
641
|
}
|
|
624
642
|
}
|
|
@@ -714,40 +732,42 @@ Item.prototype._execBefore = async function (method, params) {
|
|
|
714
732
|
* 执行主方法
|
|
715
733
|
* @param {Function} method_func 方法函数
|
|
716
734
|
* @param {Array} params 参数
|
|
717
|
-
* @param {any}
|
|
735
|
+
* @param {any} result 前置钩子结果
|
|
718
736
|
* @returns {Promise<any>} 主方法结果
|
|
719
737
|
*/
|
|
720
|
-
Item.prototype._execMain = async function (method_func, params,
|
|
738
|
+
Item.prototype._execMain = async function (method_func, params, result) {
|
|
721
739
|
let method_result = method_func.call(this._mod || this, ...params);
|
|
722
|
-
|
|
723
|
-
|
|
740
|
+
if (util.types.isPromise(method_result)) {
|
|
741
|
+
method_result = await method_result;
|
|
742
|
+
}
|
|
743
|
+
// 修复:如果主方法返回undefined,则使用前置钩子的结果
|
|
744
|
+
return method_result !== undefined ? method_result : result;
|
|
724
745
|
};
|
|
725
746
|
|
|
726
747
|
/**
|
|
727
748
|
* 执行后置钩子
|
|
728
749
|
* @param {string} method 方法名
|
|
729
750
|
* @param {Array} params 参数
|
|
730
|
-
* @param {any}
|
|
751
|
+
* @param {any} result 主方法结果
|
|
731
752
|
* @returns {Promise<any>} 后置钩子结果
|
|
732
753
|
*/
|
|
733
|
-
Item.prototype._execAfter = async function (method, params,
|
|
754
|
+
Item.prototype._execAfter = async function (method, params, result) {
|
|
734
755
|
let after_method = `${method}After`;
|
|
735
756
|
let after_func = this._getMethod(after_method);
|
|
736
757
|
|
|
737
|
-
if (!after_func) return
|
|
758
|
+
if (!after_func) return result;
|
|
738
759
|
|
|
739
760
|
try {
|
|
740
|
-
let
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
return resolved_result !== undefined ? resolved_result : main_result;
|
|
761
|
+
let after = after_func.call(this._mod || this, result, ...params);
|
|
762
|
+
if (util.types.isPromise(after)) {
|
|
763
|
+
let resolved = await after;
|
|
764
|
+
return resolved !== undefined ? resolved : result;
|
|
745
765
|
}
|
|
746
766
|
|
|
747
|
-
return
|
|
767
|
+
return after !== undefined ? after : result;
|
|
748
768
|
} catch (err) {
|
|
749
769
|
this.log('error', `执行后置钩子 ${after_method} 失败: `, err);
|
|
750
|
-
return
|
|
770
|
+
return result;
|
|
751
771
|
}
|
|
752
772
|
};
|
|
753
773
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_machine",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "A flexible Node.js plugin mechanism system for dynamic loading, management and execution of modules. Supports hot reload, lifecycle management, and modern JavaScript features.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -34,5 +34,10 @@
|
|
|
34
34
|
"mm_config": "^2.2.5",
|
|
35
35
|
"mm_hot_reload": "^1.2.0",
|
|
36
36
|
"mm_tpl": "^2.4.7"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"eslint": "^9.39.2",
|
|
40
|
+
"eslint-plugin-jsdoc": "^62.5.0",
|
|
41
|
+
"mm_eslint": "^1.6.6"
|
|
37
42
|
}
|
|
38
43
|
}
|