mm_machine 2.3.5 → 2.3.6
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/drive.js +112 -34
- package/index.js +12 -13
- package/mod.js +13 -8
- package/package.json +2 -1
package/drive.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
const
|
|
2
|
-
Mod
|
|
3
|
-
} = require('./mod');
|
|
1
|
+
const prettier = require('@prettier/sync');
|
|
4
2
|
require('mm_tpl');
|
|
5
3
|
let {
|
|
6
4
|
conf
|
|
7
5
|
} = require('mm_config');
|
|
6
|
+
const {
|
|
7
|
+
Mod
|
|
8
|
+
} = require('./mod');
|
|
9
|
+
|
|
10
|
+
if (!$.prettyCode) {
|
|
11
|
+
$.prettyCode = function (code, options) {
|
|
12
|
+
return prettier.format(code, options);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
8
15
|
|
|
9
16
|
/**
|
|
10
17
|
* 驱动基础类
|
|
@@ -95,6 +102,7 @@ Drive.prototype.loadConfig = function (file) {
|
|
|
95
102
|
/**
|
|
96
103
|
* 设置配置
|
|
97
104
|
* @param {object} config 配置对象
|
|
105
|
+
* @returns {object} 配置项
|
|
98
106
|
*/
|
|
99
107
|
Drive.prototype.setConfig = function (config) {
|
|
100
108
|
if (config) {
|
|
@@ -153,27 +161,13 @@ Drive.prototype._getTplDir = function () {
|
|
|
153
161
|
return this.getParent().getTplDir();
|
|
154
162
|
};
|
|
155
163
|
|
|
156
|
-
/**
|
|
157
|
-
* 创建脚本
|
|
158
|
-
* @param {string} file 文件路径
|
|
159
|
-
* @param {object} model 模板数据
|
|
160
|
-
* @param {string} tpl_dir 模板文件路径
|
|
161
|
-
* @returns {boolean} 创建是否成功
|
|
162
|
-
*/
|
|
163
|
-
Drive.prototype._createScriptFile = function (file, model = {}, tpl_dir = '') {
|
|
164
|
-
var tpl = this.getScriptTpl(tpl_dir);
|
|
165
|
-
var content = $.tpl.render(tpl, model);
|
|
166
|
-
file.saveText(content);
|
|
167
|
-
return file;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
164
|
/**
|
|
171
165
|
* 获取脚本模板
|
|
172
166
|
* @param {string} tpl_dir 模板文件路径
|
|
173
167
|
* @returns {string} 脚本模板内容
|
|
174
168
|
*/
|
|
175
|
-
Drive.prototype.
|
|
176
|
-
var f = './script.tpl.js'.fullname(
|
|
169
|
+
Drive.prototype._getScriptTpl = function () {
|
|
170
|
+
var f = './script.tpl.js'.fullname(this._getTplDir());
|
|
177
171
|
if (f.hasFile()) {
|
|
178
172
|
return f.loadText();
|
|
179
173
|
} else {
|
|
@@ -201,7 +195,7 @@ Drive.prototype.getScriptTpl = function (tpl_dir = '') {
|
|
|
201
195
|
};
|
|
202
196
|
|
|
203
197
|
/**
|
|
204
|
-
*
|
|
198
|
+
* 移除加载的脚本模块
|
|
205
199
|
*/
|
|
206
200
|
Drive.prototype._remove = function () {
|
|
207
201
|
let file = this._getScriptFile();
|
|
@@ -220,7 +214,7 @@ Drive.prototype._remove = function () {
|
|
|
220
214
|
}
|
|
221
215
|
}
|
|
222
216
|
} catch (err) {
|
|
223
|
-
this.log('error',
|
|
217
|
+
this.log('error', `移除加载的脚本模块失败: `, err);
|
|
224
218
|
}
|
|
225
219
|
};
|
|
226
220
|
|
|
@@ -255,7 +249,6 @@ Drive.prototype.unloadCore = async function (remove) {
|
|
|
255
249
|
|
|
256
250
|
/**
|
|
257
251
|
* 获取脚本文件路径
|
|
258
|
-
* @param {string} file 文件路径
|
|
259
252
|
* @returns {string | null} 完整文件路径
|
|
260
253
|
*/
|
|
261
254
|
Drive.prototype._getScriptFile = function () {
|
|
@@ -266,10 +259,67 @@ Drive.prototype._getScriptFile = function () {
|
|
|
266
259
|
if (!filename.hasFile()) {
|
|
267
260
|
this.newScript(filename);
|
|
268
261
|
}
|
|
269
|
-
|
|
270
262
|
return filename;
|
|
271
263
|
};
|
|
272
264
|
|
|
265
|
+
/**
|
|
266
|
+
* 新建脚本文件
|
|
267
|
+
* @param {string} file 目标文件路径
|
|
268
|
+
*/
|
|
269
|
+
Drive.prototype.newScript = function (file) {
|
|
270
|
+
this._createScriptFile(file, this.config);
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* 创建脚本
|
|
275
|
+
* @param {string} file 文件路径
|
|
276
|
+
* @param {object} model 模板数据
|
|
277
|
+
* @returns {boolean} 创建是否成功
|
|
278
|
+
*/
|
|
279
|
+
Drive.prototype._createScriptFile = function (file, model = {}) {
|
|
280
|
+
var tpl = this._getScriptTpl();
|
|
281
|
+
var content = $.tpl.render(tpl, model);
|
|
282
|
+
if (!content) {
|
|
283
|
+
return '';
|
|
284
|
+
}
|
|
285
|
+
let code = this.prettyCode(content, 'js');
|
|
286
|
+
file.saveText(code);
|
|
287
|
+
return file;
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* 获取脚本模板
|
|
292
|
+
* @param {string} tpl_dir 模板文件路径
|
|
293
|
+
* @returns {string} 脚本模板内容
|
|
294
|
+
*/
|
|
295
|
+
Drive.prototype._getScriptTpl = function () {
|
|
296
|
+
var f = './script.tpl.js'.fullname(this._getTplDir());
|
|
297
|
+
if (f.hasFile()) {
|
|
298
|
+
return f.loadText();
|
|
299
|
+
} else {
|
|
300
|
+
return `module.exports = {
|
|
301
|
+
/**
|
|
302
|
+
* 初始化
|
|
303
|
+
*/
|
|
304
|
+
async _init() {
|
|
305
|
+
this.log('debug', \`初始化!\`);
|
|
306
|
+
},
|
|
307
|
+
/**
|
|
308
|
+
* 销毁
|
|
309
|
+
*/
|
|
310
|
+
async _destroy(...args) {
|
|
311
|
+
this.log('debug', \`销毁!\`);
|
|
312
|
+
},
|
|
313
|
+
/**
|
|
314
|
+
* 主要逻辑
|
|
315
|
+
*/
|
|
316
|
+
async main(...args) {
|
|
317
|
+
// 主要代码写在这
|
|
318
|
+
}
|
|
319
|
+
}`;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
273
323
|
/**
|
|
274
324
|
* 加载脚本文件,支持热重载模式
|
|
275
325
|
* 在开发模式(mode=3或4)下使用 $.require 进行热重载
|
|
@@ -333,25 +383,53 @@ Drive.prototype.newConfig = function (file) {
|
|
|
333
383
|
this._createConfigFile(file);
|
|
334
384
|
};
|
|
335
385
|
|
|
386
|
+
/**
|
|
387
|
+
* 预试代码
|
|
388
|
+
* @param {string} code 要预试的代码
|
|
389
|
+
* @param {string} type 预试类型,可选"json"或"js"
|
|
390
|
+
* @returns {string} 预试后的代码字符串
|
|
391
|
+
*/
|
|
392
|
+
Drive.prototype.prettyCode = function (code, type = 'json5') {
|
|
393
|
+
let options = {
|
|
394
|
+
tabWidth: 2
|
|
395
|
+
};
|
|
396
|
+
switch (type) {
|
|
397
|
+
case 'json5':
|
|
398
|
+
options.parser = 'json5';
|
|
399
|
+
break;
|
|
400
|
+
case 'js':
|
|
401
|
+
case 'javascript':
|
|
402
|
+
options.parser = 'babel';
|
|
403
|
+
options.semi = true; // 在语句末尾添加分号
|
|
404
|
+
options.singleQuote = true; // 使用单引号
|
|
405
|
+
break;
|
|
406
|
+
default:
|
|
407
|
+
options.parser = 'json';
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
let new_code = $.prettyCode(code, options);
|
|
411
|
+
return new_code;
|
|
412
|
+
};
|
|
413
|
+
|
|
336
414
|
/**
|
|
337
415
|
* 创建配置文件
|
|
338
416
|
* @param {string} file 目标文件路径
|
|
339
417
|
* @returns {string} 配置文件内容
|
|
340
418
|
*/
|
|
341
419
|
Drive.prototype._createConfigFile = function (file) {
|
|
342
|
-
var tpl = this.
|
|
420
|
+
var tpl = this._getConfigTpl();
|
|
343
421
|
var content = $.tpl.render(tpl, this.config);
|
|
344
|
-
|
|
422
|
+
let code = this.prettyCode(content, 'json');
|
|
423
|
+
file.saveText(code);
|
|
345
424
|
return file;
|
|
346
425
|
};
|
|
347
426
|
|
|
348
427
|
/**
|
|
349
428
|
* 获取配置模板
|
|
350
|
-
* @param {string} tpl_dir 模板文件路径
|
|
351
429
|
* @returns {string} 配置模板内容
|
|
352
430
|
*/
|
|
353
|
-
Drive.prototype.
|
|
354
|
-
var f = './config.tpl.json'.fullname(
|
|
431
|
+
Drive.prototype._getConfigTpl = function () {
|
|
432
|
+
var f = './config.tpl.json'.fullname(this._getTplDir());
|
|
355
433
|
if (f.hasFile()) {
|
|
356
434
|
return f.loadText();
|
|
357
435
|
} else {
|
|
@@ -370,8 +448,8 @@ Drive.prototype.getConfigTpl = function (tpl_dir = '') {
|
|
|
370
448
|
"state": \${state || 1},
|
|
371
449
|
// 模块排序,可选,默认100
|
|
372
450
|
"sort": \${sort || 100},
|
|
373
|
-
|
|
374
|
-
|
|
451
|
+
// 是否结束,可选,默认false
|
|
452
|
+
"end": \${end || false}
|
|
375
453
|
}`;
|
|
376
454
|
}
|
|
377
455
|
};
|
|
@@ -543,8 +621,8 @@ Drive.prototype.loadBefore = async function () {
|
|
|
543
621
|
* 加载处理
|
|
544
622
|
*/
|
|
545
623
|
Drive.prototype._loadCore = async function () {
|
|
546
|
-
this.loadConfig();
|
|
547
|
-
this.loadScript();
|
|
624
|
+
await this.loadConfig();
|
|
625
|
+
await this.loadScript();
|
|
548
626
|
};
|
|
549
627
|
|
|
550
628
|
/**
|
|
@@ -569,13 +647,13 @@ Drive.prototype.save = function () {
|
|
|
569
647
|
// 如果不存在,添加新配置项
|
|
570
648
|
config.push(this.config);
|
|
571
649
|
}
|
|
572
|
-
file.saveText(JSON.stringify(config, null,
|
|
650
|
+
file.saveText(JSON.stringify(config, null, 2));
|
|
573
651
|
return;
|
|
574
652
|
}
|
|
575
653
|
}
|
|
576
654
|
|
|
577
655
|
// 单对象格式配置,直接保存
|
|
578
|
-
file.saveText(JSON.stringify(this.config, null,
|
|
656
|
+
file.saveText(JSON.stringify(this.config, null, 2));
|
|
579
657
|
} catch (err) {
|
|
580
658
|
this.log('error', `保存配置失败: `, err);
|
|
581
659
|
}
|
package/index.js
CHANGED
|
@@ -46,17 +46,15 @@ class Manager extends Mod {
|
|
|
46
46
|
*/
|
|
47
47
|
dir: './ai/manager'.fullname(),
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* 搜索模式 dir按目录搜索 | file按文件名搜索
|
|
50
50
|
* @type {string}
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
search_way: 'file',
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
55
|
-
* dir 按目录搜索
|
|
56
|
-
* file 按文件名搜索
|
|
54
|
+
* 类型 script脚本 | json配置 | drive驱动
|
|
57
55
|
* @type {string}
|
|
58
56
|
*/
|
|
59
|
-
|
|
57
|
+
mod_type: 'drive',
|
|
60
58
|
/**
|
|
61
59
|
* 是否懒加载
|
|
62
60
|
* @type {boolean}
|
|
@@ -383,7 +381,7 @@ Manager.prototype._getDirName = function () {
|
|
|
383
381
|
// 后缀,为配置项名称
|
|
384
382
|
let name = this.config.name.toLowerCase();
|
|
385
383
|
// 目录名,为前缀加下划线加后缀
|
|
386
|
-
return prefix +
|
|
384
|
+
return prefix + '_' + name;
|
|
387
385
|
};
|
|
388
386
|
|
|
389
387
|
/**
|
|
@@ -394,10 +392,11 @@ Manager.prototype._getDirName = function () {
|
|
|
394
392
|
Manager.prototype._getAllDirFiles = function (dir) {
|
|
395
393
|
let files = [];
|
|
396
394
|
let dirs = $.dir.getAll(dir, this._getDirName());
|
|
397
|
-
for (let
|
|
398
|
-
let
|
|
399
|
-
|
|
400
|
-
|
|
395
|
+
for (let i = 0; i < dirs.length; i++) {
|
|
396
|
+
let d = dirs[i];
|
|
397
|
+
let lt = $.file.getAll(d, this.config.filename);
|
|
398
|
+
if (lt.length > 0) {
|
|
399
|
+
files.push(...lt);
|
|
401
400
|
}
|
|
402
401
|
}
|
|
403
402
|
return files;
|
|
@@ -465,7 +464,7 @@ Manager.prototype.update = async function (dir, clear = true) {
|
|
|
465
464
|
}
|
|
466
465
|
|
|
467
466
|
// 查找所有json文件
|
|
468
|
-
let files = this._findFiles(dir);
|
|
467
|
+
let files = this._findFiles(dir || this.config.dir);
|
|
469
468
|
// 批量注册模块
|
|
470
469
|
this.batchRegister(files);
|
|
471
470
|
// 更新配置信息
|
|
@@ -593,7 +592,7 @@ Manager.prototype._runSub = async function (mod, method, ...params) {
|
|
|
593
592
|
|
|
594
593
|
return ret;
|
|
595
594
|
} catch (err) {
|
|
596
|
-
$.log.error(
|
|
595
|
+
$.log.error(`执行模块方法失败: `, err);
|
|
597
596
|
return null;
|
|
598
597
|
}
|
|
599
598
|
};
|
package/mod.js
CHANGED
|
@@ -142,10 +142,8 @@ Mod.prototype._onDestroy = function () {
|
|
|
142
142
|
* @param {object} ctx 上下文对象
|
|
143
143
|
*/
|
|
144
144
|
Mod.prototype._onLoad = async function (ctx) {
|
|
145
|
-
let status_last = 'created';
|
|
146
145
|
// 1. 加载
|
|
147
146
|
this.on('load:before', async (ctx) => {
|
|
148
|
-
status_last = this.getState();
|
|
149
147
|
this.setState('loading');
|
|
150
148
|
await this._loadCore(...ctx.params);
|
|
151
149
|
});
|
|
@@ -222,13 +220,19 @@ Mod.prototype._onUnload = async function (ctx) {
|
|
|
222
220
|
};
|
|
223
221
|
|
|
224
222
|
/**
|
|
225
|
-
*
|
|
223
|
+
* 初始化监听事件
|
|
224
|
+
* @param {object} ctx 上下文对象
|
|
226
225
|
*/
|
|
227
226
|
Mod.prototype._onDestroy = async function (ctx) {
|
|
228
227
|
let status_last = 'unloaded';
|
|
228
|
+
// 6. 销毁
|
|
229
|
+
this.on('destroy:before', async (ctx) => {
|
|
230
|
+
status_last = this.getState();
|
|
231
|
+
this.setState('destroying');
|
|
232
|
+
});
|
|
229
233
|
this.on('destroy:check', (ctx) => {
|
|
230
234
|
if (status_last !== 'unloaded') {
|
|
231
|
-
|
|
235
|
+
this.setState(status_last);
|
|
232
236
|
ctx.error = new Error('销毁前必须先卸载');
|
|
233
237
|
}
|
|
234
238
|
});
|
|
@@ -354,7 +358,7 @@ Mod.prototype.main = async function (...args) {
|
|
|
354
358
|
throw new Error(`方法${method}不存在`);
|
|
355
359
|
}
|
|
356
360
|
let params = args.slice(1);
|
|
357
|
-
return await this.methods[method](...params);
|
|
361
|
+
return await this.methods[method](...params);
|
|
358
362
|
};
|
|
359
363
|
|
|
360
364
|
/**
|
|
@@ -371,7 +375,8 @@ Mod.prototype.setMethods = function (methods) {
|
|
|
371
375
|
|
|
372
376
|
/**
|
|
373
377
|
* 设置脚本方法
|
|
374
|
-
* @param {
|
|
378
|
+
* @param {string} method 方法名
|
|
379
|
+
* @param {Function} func 方法函数
|
|
375
380
|
*/
|
|
376
381
|
Mod.prototype.setMethod = function (method, func) {
|
|
377
382
|
if (!func) throw new Error(`函数(func)不能为空`);
|
|
@@ -448,9 +453,9 @@ Mod.prototype._callBefore = async function (method, params) {
|
|
|
448
453
|
* @returns {Promise<any>} 主方法结果
|
|
449
454
|
*/
|
|
450
455
|
Mod.prototype._callMain = async function (method_func, params, result) {
|
|
451
|
-
let
|
|
456
|
+
let ret = await method_func.call(this._mod || this, ...params);
|
|
452
457
|
// 修复:如果主方法返回undefined,则使用前置钩子的结果
|
|
453
|
-
return
|
|
458
|
+
return ret !== undefined ? ret : result;
|
|
454
459
|
};
|
|
455
460
|
|
|
456
461
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_machine",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
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": {
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"README.md"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"@prettier/sync": "^0.6.1",
|
|
36
37
|
"mm_config": "^2.3.0",
|
|
37
38
|
"mm_hot_reload": "^1.3.0",
|
|
38
39
|
"mm_tpl": "^2.4.9"
|