mm_machine 2.5.4 → 2.5.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.
Files changed (4) hide show
  1. package/drive.js +17 -55
  2. package/index.js +34 -20
  3. package/mod.js +117 -29
  4. package/package.json +1 -1
package/drive.js CHANGED
@@ -19,7 +19,6 @@ if (!$.prettyCode) {
19
19
  * @class
20
20
  */
21
21
  class Drive extends Mod {
22
-
23
22
  // 配置项
24
23
  static config = {
25
24
  // 名称, 由中英文和下"_"组成, 用于卸载接口 例如: demo
@@ -109,7 +108,6 @@ Drive.prototype._loadConfig = function (file) {
109
108
  /**
110
109
  * 加载配置
111
110
  * @param {string} file 配置文件路径
112
- * @returns {object} 配置项
113
111
  */
114
112
  Drive.prototype.loadConfig = function (file) {
115
113
  this._loadConfig(file);
@@ -177,51 +175,6 @@ Drive.prototype._getTplDir = function () {
177
175
  return this.getParent().getTplDir();
178
176
  };
179
177
 
180
- /**
181
- * 获取脚本模板
182
- * @param {string} tpl_dir 模板文件路径
183
- * @returns {string} 脚本模板内容
184
- */
185
- Drive.prototype._getScriptTpl = function () {
186
- var f = './script.tpl.js'.fullname(this._getTplDir());
187
- if (f.hasFile()) {
188
- return f.loadText();
189
- } else {
190
- return `module.exports = {
191
- /**
192
- * 初始化
193
- */
194
- async _init() {
195
- this.log('debug', \`初始化!\`);
196
- },
197
- /**
198
- * 启动
199
- */
200
- async _start() {
201
- this.log('debug', \`启动!\`);
202
- },
203
- /**
204
- * 停止
205
- */
206
- async _stop() {
207
- this.log('debug', \`停止!\`);
208
- },
209
- /**
210
- * 销毁
211
- */
212
- async _destroy(...args) {
213
- this.log('debug', \`销毁!\`);
214
- },
215
- /**
216
- * 主要逻辑
217
- */
218
- async main(...args) {
219
- // 主要代码写在这
220
- }
221
- }`;
222
- }
223
- };
224
-
225
178
  /**
226
179
  * 移除加载的脚本模块
227
180
  */
@@ -301,7 +254,6 @@ Drive.prototype.newScript = function (file) {
301
254
  /**
302
255
  * 创建脚本
303
256
  * @param {string} file 文件路径
304
- * @param {object} model 模板数据
305
257
  * @returns {boolean} 创建是否成功
306
258
  */
307
259
  Drive.prototype._createScriptFile = function (file) {
@@ -317,7 +269,6 @@ Drive.prototype._createScriptFile = function (file) {
317
269
 
318
270
  /**
319
271
  * 获取脚本模板
320
- * @param {string} tpl_dir 模板文件路径
321
272
  * @returns {string} 脚本模板内容
322
273
  */
323
274
  Drive.prototype._getScriptTpl = function () {
@@ -332,6 +283,18 @@ Drive.prototype._getScriptTpl = function () {
332
283
  async _init() {
333
284
  this.log('debug', \`初始化!\`);
334
285
  },
286
+ /**
287
+ * 启动
288
+ */
289
+ async _start() {
290
+ this.log('debug', \`启动!\`);
291
+ },
292
+ /**
293
+ * 停止
294
+ */
295
+ async _stop() {
296
+ this.log('debug', \`停止!\`);
297
+ },
335
298
  /**
336
299
  * 销毁
337
300
  */
@@ -346,6 +309,7 @@ Drive.prototype._getScriptTpl = function () {
346
309
  }
347
310
  }`;
348
311
  }
312
+
349
313
  };
350
314
 
351
315
  /**
@@ -381,17 +345,15 @@ Drive.prototype._setMainMethod = function (mod) {
381
345
  if (name && mod[name]) {
382
346
  this.main = mod[name];
383
347
  }
384
-
385
348
  for (let key in mod) {
386
349
  let obj = mod[key];
387
350
  if (typeof obj === 'function') {
388
- this._methods[key] = obj;
351
+ this.setMethod(key, obj);
389
352
  }
390
353
  else {
391
- this._datas[key] = obj;
354
+ this.setData(key, obj);
392
355
  }
393
356
  }
394
- Object.assign(this, mod);
395
357
  this.is_loaded = true;
396
358
  };
397
359
 
@@ -451,7 +413,7 @@ Drive.prototype.prettyCode = function (code, type = 'json5') {
451
413
  */
452
414
  Drive.prototype.getModel = function (type) {
453
415
  return this.config;
454
- }
416
+ };
455
417
 
456
418
  /**
457
419
  * 创建配置文件
@@ -718,7 +680,7 @@ Drive.prototype.emitEvent = function (event, ...args) {
718
680
  /**
719
681
  * 注册事件监听
720
682
  * @param {string} event 事件名
721
- * @param {function} callback 事件回调函数
683
+ * @param {Function} callback 事件回调函数
722
684
  */
723
685
  Drive.prototype.onEvent = function (event, callback) {
724
686
  this.getEventer()?.on(event, callback);
package/index.js CHANGED
@@ -39,12 +39,12 @@ class Manager extends Mod {
39
39
  * 基础目录,加载模块内置资源
40
40
  * @type {string}
41
41
  */
42
- base_dir: '../common/manager'.fullname(__dirname),
42
+ base_dir: '', // '../common/manager'.fullname(__dirname),
43
43
  /**
44
44
  * 自定义目录,加载项目自定义资源
45
45
  * @type {string}
46
46
  */
47
- dir: './ai/manager'.fullname(),
47
+ dir: '', // './ai/manager'.fullname(),
48
48
  /**
49
49
  * 搜索模式 dir按目录搜索 | file按文件名搜索
50
50
  * @type {string}
@@ -204,8 +204,9 @@ Manager.prototype.Drive = Drive;
204
204
  */
205
205
  Manager.prototype.updateInfo = function () {
206
206
  this.infos = [];
207
- for (let name in this.mods) {
208
- let o = this.mods[name];
207
+ let mods = this.getMods();
208
+ for (let name in mods) {
209
+ let o = mods[name];
209
210
  let info = this.newInfo(name, o.config.sort, o.config.state, o.config_file);
210
211
  this.infos.push(info);
211
212
  }
@@ -232,6 +233,13 @@ Manager.prototype.sort = function () {
232
233
  };
233
234
 
234
235
  // ==== 模块管理接口 ====
236
+ /**
237
+ * 清除所有模块
238
+ */
239
+ Manager.prototype.clearMods = function () {
240
+ $.clear(this.mods);
241
+ };
242
+
235
243
  /**
236
244
  * 删除模块
237
245
  * @param {string} name 模块名
@@ -392,8 +400,9 @@ Manager.prototype.registerMods = function (files, config = {}, script = {}) {
392
400
  */
393
401
  Manager.prototype.loadMods = async function () {
394
402
  var promises = [];
395
- for (let name in this.mods) {
396
- let mod = this.mods[name];
403
+ let mods = this.getMods();
404
+ for (let name in mods) {
405
+ let mod = mods[name];
397
406
  promises.push(mod.do('load'));
398
407
  }
399
408
  await Promise.all(promises);
@@ -458,8 +467,9 @@ Manager.prototype._findFiles = function (dir) {
458
467
  */
459
468
  Manager.prototype.loadScripts = async function () {
460
469
  var promises = [];
461
- for (let name in this.mods) {
462
- let mod = this.mods[name];
470
+ let mods = this.getMods();
471
+ for (let name in mods) {
472
+ let mod = mods[name];
463
473
  promises.push(mod.call('loadScript'));
464
474
  }
465
475
  await Promise.all(promises);
@@ -486,8 +496,7 @@ Manager.prototype.updateAfter = function () {
486
496
  */
487
497
  Manager.prototype.update = async function (dir, clear = true) {
488
498
  if (clear) {
489
- // 初始化方法
490
- this.mods = {};
499
+ this.clearMods();
491
500
  }
492
501
 
493
502
  // 查找所有json文件
@@ -623,10 +632,11 @@ Manager.prototype._initCore = async function () {
623
632
  };
624
633
 
625
634
  /**
626
- * 执行方法
635
+ * 执行方法 - 内部方法
636
+ * @param {string} mod 模块对象
627
637
  * @param {string} method 方法名称
628
- * @param {...object} params 参数列表
629
- * @returns {object} 返回执行结果
638
+ * @param {...any} params 参数列表
639
+ * @returns {any} 返回执行结果
630
640
  */
631
641
  Manager.prototype._exec = async function (mod, method, ...params) {
632
642
  if (mod[method]) {
@@ -639,14 +649,18 @@ Manager.prototype._exec = async function (mod, method, ...params) {
639
649
 
640
650
  /**
641
651
  * 执行方法
652
+ * @param {string} name 模块名
642
653
  * @param {string} method 方法名称
643
- * @param {...any} params 参数列表
644
- * @returns {object} 返回执行结果
654
+ * @param {...any} params 参数列表
655
+ * @returns {any} 返回执行结果
645
656
  */
646
657
  Manager.prototype.exec = async function (name, method, ...params) {
647
658
  let ret;
648
659
  try {
649
660
  let mod = this.getMod(name);
661
+ if (!mod) {
662
+ throw new Error(`模块${name}不存在`);
663
+ }
650
664
  ret = await this._exec(mod, method, ...params);
651
665
  }
652
666
  catch (error) {
@@ -659,7 +673,7 @@ Manager.prototype.exec = async function (name, method, ...params) {
659
673
  * 确保所有模块都已加载
660
674
  * @returns {Promise} 加载完成
661
675
  */
662
- Manager.prototype._ensureAllModulesLoaded = async function () {
676
+ Manager.prototype._ensureAllLoaded = async function () {
663
677
  let infos = this.getInfos();
664
678
 
665
679
  for (let i = 0; i < infos.length; i++) {
@@ -733,7 +747,7 @@ Manager.prototype.runAsync = async function (method, ...params) {
733
747
  }
734
748
 
735
749
  // 确保所有模块都已加载
736
- await this._ensureAllModulesLoaded();
750
+ await this._ensureAllLoaded();
737
751
 
738
752
  let infos = this.getInfos();
739
753
 
@@ -764,7 +778,7 @@ Manager.prototype.runAll = async function (method, ...params) {
764
778
  }
765
779
 
766
780
  // 确保所有模块都已加载
767
- await this._ensureAllModulesLoaded();
781
+ await this._ensureAllLoaded();
768
782
 
769
783
  const promises = [];
770
784
  let infos = this.getInfos();
@@ -797,7 +811,7 @@ Manager.prototype.runRace = async function (method, ...params) {
797
811
  }
798
812
 
799
813
  // 确保所有模块都已加载
800
- await this._ensureAllModulesLoaded();
814
+ await this._ensureAllLoaded();
801
815
 
802
816
  const promises = [];
803
817
  let infos = this.getInfos();
@@ -872,7 +886,7 @@ Manager.prototype.emitEvent = function (event, ...args) {
872
886
  /**
873
887
  * 注册事件监听
874
888
  * @param {string} event 事件名
875
- * @param {function} callback 事件回调函数
889
+ * @param {Function} callback 事件回调函数
876
890
  */
877
891
  Manager.prototype.onEvent = function (event, callback) {
878
892
  this.getEventer()?.on(event, callback);
package/mod.js CHANGED
@@ -12,11 +12,11 @@ require('mm_hot_reload');
12
12
  $.require = function (file, func) {
13
13
  // 参数校验
14
14
  if (typeof file !== 'string') {
15
- throw new TypeError('文件路径必须是字符串');
15
+ throw new TypeError('第一个参数(file)必须是字符串');
16
16
  }
17
17
 
18
18
  if (func && typeof func !== 'function') {
19
- throw new TypeError('回调函数必须是函数');
19
+ throw new TypeError('第二个参数(func)必须是函数');
20
20
  }
21
21
 
22
22
  // 确保文件是.js文件
@@ -38,11 +38,11 @@ $.require = function (file, func) {
38
38
  $.loadJson = function (file, func) {
39
39
  // 参数校验
40
40
  if (typeof file !== 'string') {
41
- throw new TypeError('文件路径必须是字符串');
41
+ throw new TypeError('第一个参数(file)必须是字符串');
42
42
  }
43
43
 
44
44
  if (func && typeof func !== 'function') {
45
- throw new TypeError('回调函数必须是函数');
45
+ throw new TypeError('第二个参数(func)必须是函数');
46
46
  }
47
47
 
48
48
  // 确保文件是.json文件
@@ -65,7 +65,11 @@ class Mod extends Base {
65
65
  // 模块描述
66
66
  description: '',
67
67
  // 状态, 可选值: 1-启用, 0-禁用
68
- state: 1
68
+ state: 1,
69
+ // 是否需要缓存数据
70
+ need_cache: false,
71
+ // 缓存文件路径
72
+ cache_file: ''
69
73
  };
70
74
 
71
75
  /**
@@ -244,30 +248,36 @@ Mod.prototype._onDestroy = async function (ctx) {
244
248
 
245
249
  /**
246
250
  * 加载 - 内部方法
251
+ * @param {...any} args 加载参数
252
+ * @returns {object} 模块对象
247
253
  * @private
248
254
  */
249
- Mod.prototype._load = async function () {
255
+ Mod.prototype._load = async function (...args) {
250
256
  return this;
251
257
  };
252
258
 
253
259
  /**
254
260
  * 加载
261
+ * @param {...any} args 加载参数
262
+ * @returns {object} 模块对象
255
263
  */
256
- Mod.prototype.load = async function () {
257
- return await this._load();
264
+ Mod.prototype.load = async function (...args) {
265
+ return await this._load(...args);
258
266
  };
259
267
 
260
268
  /**
261
269
  * 加载核心
270
+ * @private
271
+ * @param {...any} args 加载参数
262
272
  */
263
- Mod.prototype._loadCore = async function () {
264
-
273
+ Mod.prototype._loadCore = async function (...args) {
265
274
  };
266
275
 
267
276
  /**
268
277
  * 启动 - 内部方法
269
278
  * @private
270
279
  * @param {...any} args 初始化参数
280
+ * @returns {object} 模块对象
271
281
  */
272
282
  Mod.prototype._start = async function (...args) {
273
283
  return this;
@@ -275,6 +285,8 @@ Mod.prototype._start = async function (...args) {
275
285
 
276
286
  /**
277
287
  * 启动
288
+ * @param {...any} args 初始化参数
289
+ * @returns {object} 模块对象
278
290
  */
279
291
  Mod.prototype.start = async function (...args) {
280
292
  return await this._start(...args);
@@ -283,14 +295,16 @@ Mod.prototype.start = async function (...args) {
283
295
  /**
284
296
  * 启动核心
285
297
  * @private
298
+ * @param {...any} args 初始化参数
286
299
  */
287
- Mod.prototype._startCore = async function () {
300
+ Mod.prototype._startCore = async function (...args) {
288
301
 
289
302
  };
290
303
 
291
304
  /**
292
305
  * 停止 - 内部方法
293
306
  * @private
307
+ * @returns {object} 模块对象
294
308
  */
295
309
  Mod.prototype._stop = async function () {
296
310
  return this;
@@ -298,6 +312,7 @@ Mod.prototype._stop = async function () {
298
312
 
299
313
  /**
300
314
  * 停止
315
+ * @returns {object} 模块对象
301
316
  */
302
317
  Mod.prototype.stop = async function () {
303
318
  return await this._stop();
@@ -314,6 +329,7 @@ Mod.prototype._stopCore = async function () {
314
329
  /**
315
330
  * 卸载 - 内部方法
316
331
  * @private
332
+ * @returns {object} 模块对象
317
333
  */
318
334
  Mod.prototype._unload = async function () {
319
335
  return this;
@@ -321,6 +337,7 @@ Mod.prototype._unload = async function () {
321
337
 
322
338
  /**
323
339
  * 卸载
340
+ * @returns {object} 模块对象
324
341
  */
325
342
  Mod.prototype.unload = async function () {
326
343
  return await this._unload();
@@ -379,7 +396,7 @@ Mod.prototype.end = async function () {
379
396
 
380
397
  /**
381
398
  * 获取事件管理器
382
- * @returns {Eventer|null} 事件管理器
399
+ * @returns {object} 事件管理器
383
400
  */
384
401
  Mod.prototype.getEventer = function () {
385
402
  return this._eventer || $.eventer;
@@ -387,7 +404,7 @@ Mod.prototype.getEventer = function () {
387
404
 
388
405
  /**
389
406
  * 设置事件管理器
390
- * @param {Eventer} eventer 事件管理器
407
+ * @param {object} eventer 事件管理器
391
408
  */
392
409
  Mod.prototype.setEventer = function (eventer) {
393
410
  this._eventer = eventer;
@@ -422,13 +439,15 @@ Mod.prototype.main = async function (...args) {
422
439
  * @param {object} methods 脚本方法对象
423
440
  */
424
441
  Mod.prototype.setMethods = function (methods) {
442
+ if (typeof methods !== 'object') {
443
+ throw new Error(`参数(methods)必须是对象`);
444
+ }
425
445
  if (!methods) return;
426
446
  if (!this._methods) {
427
447
  this._methods = {};
428
448
  }
429
- Object.assign(this._methods, methods);
430
- for (let key in this._methods) {
431
- this[key] = this._methods[key];
449
+ for (let key in methods) {
450
+ this.setMethod(key, methods[key]);
432
451
  }
433
452
  };
434
453
 
@@ -438,25 +457,36 @@ Mod.prototype.setMethods = function (methods) {
438
457
  * @param {Function} func 方法函数
439
458
  */
440
459
  Mod.prototype.setMethod = function (method, func) {
441
- if (!func) throw new Error(`函数(func)不能为空`);
460
+ if (typeof method !== 'string') {
461
+ throw new Error(`第一个参数(method)必须是字符串`);
462
+ }
463
+ if (method === '_datas') {
464
+ throw new Error(`第一个参数(method)不能为_datas键`);
465
+ }
466
+ if (method === '_methods') {
467
+ throw new Error(`第一个参数(method)不能为_methods键`);
468
+ }
469
+ if (!func) throw new Error(`第二个参数(func)不能为空`);
470
+ if (typeof func !== 'function') {
471
+ throw new Error(`第二个参数(func)必须是函数`);
472
+ }
442
473
  if (!this._methods) {
443
474
  this._methods = {};
444
475
  }
445
- this._methods[method] = func;
446
- this[method] = this._methods[method];
476
+ this._methods[method] = true;
477
+ this[method] = func;
447
478
  };
448
479
 
449
480
  /**
450
481
  * 获取方法函数
451
482
  * @param {string} method 方法名
452
- * @returns {Function|null} 方法函数
483
+ * @returns {Function} 方法函数
453
484
  */
454
485
  Mod.prototype.getMethod = function (method) {
455
- let func = this._methods[method];
456
- if (!func) {
457
- func = this[method];
486
+ if (typeof method !== 'string') {
487
+ throw new Error(`第一个参数(method)必须是字符串`);
458
488
  }
459
- return func;
489
+ return this[method];
460
490
  };
461
491
 
462
492
  /**
@@ -464,7 +494,20 @@ Mod.prototype.getMethod = function (method) {
464
494
  * @returns {object} 数据对象
465
495
  */
466
496
  Mod.prototype.getDatas = function () {
467
- return this._datas;
497
+ let datas = this._datas;
498
+ let result = {};
499
+ for (let key in datas) {
500
+ result[key] = this[key];
501
+ }
502
+ return result;
503
+ };
504
+
505
+ /**
506
+ * 获取数据
507
+ * @returns {object} 数据对象
508
+ */
509
+ Mod.prototype.getData = function (key) {
510
+ return this[key];
468
511
  };
469
512
 
470
513
  /**
@@ -472,12 +515,14 @@ Mod.prototype.getDatas = function () {
472
515
  * @param {object} datas 数据对象
473
516
  */
474
517
  Mod.prototype.setDatas = function (datas) {
518
+ if (typeof datas !== 'object') {
519
+ throw new Error(`参数(datas)必须是对象`);
520
+ }
475
521
  if (!this._datas) {
476
522
  this._datas = {};
477
523
  }
478
- Object.assign(this._datas, datas);
479
- for (let key in this._datas) {
480
- this[key] = this._datas[key];
524
+ for (let key in datas) {
525
+ this.setData(key, datas[key]);
481
526
  }
482
527
  };
483
528
 
@@ -487,10 +532,41 @@ Mod.prototype.setDatas = function (datas) {
487
532
  * @param {*} value 数据值
488
533
  */
489
534
  Mod.prototype.setData = function (key, value) {
490
- this._datas[key] = value;
535
+ if (typeof key !== 'string') {
536
+ throw new Error(`第一个参数(key)必须是字符串`);
537
+ }
538
+ if (key === '_datas') {
539
+ throw new Error(`第一个参数(key)不能为_datas键`);
540
+ }
541
+ if (key === '_methods') {
542
+ throw new Error(`第一个参数(key)不能为_methods键`);
543
+ }
544
+ if (value === undefined || value === null) throw new Error(`第二个参数(value)不能为undefined或null`);
545
+ if (typeof value == 'function') {
546
+ throw new Error(`第二个参数(value)不能为函数`);
547
+ }
548
+ this._datas[key] = typeof (value);
491
549
  this[key] = value;
492
550
  };
493
551
 
552
+ /**
553
+ * 保存数据
554
+ */
555
+ Mod.prototype.saveDatas = function () {
556
+ let datas = this.getDatas();
557
+ let file = this.config.cache_file || './cache.json'.fullname(__dirname);
558
+ file.saveJson(datas);
559
+ };
560
+
561
+ /**
562
+ * 加载数据
563
+ */
564
+ Mod.prototype.loadDatas = function () {
565
+ let file = this.config.cache_file || './cache.json'.fullname(__dirname);
566
+ let datas = file.loadJson();
567
+ this.setDatas(datas);
568
+ };
569
+
494
570
  /**
495
571
  * 调用函数(核心执行方法)
496
572
  * @param {string} method 函数名
@@ -572,6 +648,18 @@ Mod.prototype._callAfter = async function (method, params, result) {
572
648
  }
573
649
  };
574
650
 
651
+ /**
652
+ * 销毁核心
653
+ * @returns {object} 返回当前对象
654
+ */
655
+ Mod.prototype._destroyCore = async function () {
656
+ if(this.config.save_cache) {
657
+ this.saveDatas();
658
+ }
659
+ this._datas = {};
660
+ this._methods = {};
661
+ };
662
+
575
663
  module.exports = {
576
664
  Mod
577
665
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_machine",
3
- "version": "2.5.4",
3
+ "version": "2.5.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": {