mm_machine 2.2.5 → 2.2.7

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 (3) hide show
  1. package/index.js +19 -32
  2. package/package.json +3 -4
  3. package/item.js +0 -697
package/index.js CHANGED
@@ -1,10 +1,10 @@
1
- const { Drive } = require('./drive');
2
- const { Item } = require('./item.js');
1
+ const { Mod } = require('./mod');
2
+ const { Drive } = require('./drive.js');
3
3
 
4
4
  /**
5
5
  * 管理器类
6
6
  */
7
- class Manager extends Drive {
7
+ class Manager extends Mod {
8
8
  static config = {
9
9
  // 管理器名称
10
10
  name: 'manager',
@@ -67,13 +67,13 @@ Manager.prototype.newInfo = function (name, sort, state) {
67
67
  * @returns {string} 基础目录
68
68
  */
69
69
  Manager.prototype.getBaseDir = function () {
70
- return this.config.base_dir;
70
+ return this.config.base_dir || __dirname;
71
71
  };
72
72
 
73
73
  /**
74
74
  * 默认驱动
75
75
  */
76
- Manager.prototype.Drive = Item;
76
+ Manager.prototype.Drive = Drive;
77
77
 
78
78
  /**
79
79
  * 更新模块信息
@@ -94,8 +94,8 @@ Manager.prototype.updateInfo = function () {
94
94
  Manager.prototype.sort = function () {
95
95
  var sort_key = this.config.sort_key || 'sort';
96
96
  this.infos.sort((o1, o2) => {
97
- let p1 = o1[sort_key] || 0;
98
- let p2 = o2[sort_key] || 0;
97
+ let p1 = o1[sort_key] || 100;
98
+ let p2 = o2[sort_key] || 100;
99
99
  return p1 - p2;
100
100
  });
101
101
  };
@@ -153,7 +153,7 @@ Manager.prototype.newMod = function (config_file, config, script) {
153
153
  let mod;
154
154
  switch (this.config.type) {
155
155
  case 'script':
156
- mod = new Item(config, this);
156
+ mod = new Mod(config, this);
157
157
  break;
158
158
  default:
159
159
  // 创建模块
@@ -188,7 +188,7 @@ Manager.prototype.register = function (config_file, config = {}, script = {}) {
188
188
  Manager.prototype.load = async function (name) {
189
189
  let mod = this.getMod(name);
190
190
  if (mod) {
191
- return await mod.exec('load');
191
+ return await mod.do('load');
192
192
  }
193
193
  return null;
194
194
  };
@@ -201,7 +201,7 @@ Manager.prototype.load = async function (name) {
201
201
  Manager.prototype.unload = async function (name) {
202
202
  let mod = this.getMod(name);
203
203
  if (mod) {
204
- return await mod.exec('unload');
204
+ return await mod.do('unload');
205
205
  }
206
206
  return null;
207
207
  };
@@ -214,7 +214,7 @@ Manager.prototype.unload = async function (name) {
214
214
  Manager.prototype.reload = async function (name) {
215
215
  let mod = this.getMod(name);
216
216
  if (mod) {
217
- return await mod.exec('reload');
217
+ return await mod.do('reload');
218
218
  }
219
219
  return null;
220
220
  };
@@ -251,7 +251,7 @@ Manager.prototype.loads = async function () {
251
251
  var promises = [];
252
252
  for (let name in this.mods) {
253
253
  let mod = this.mods[name];
254
- promises.push(mod.exec('load'));
254
+ promises.push(mod.do('load'));
255
255
  }
256
256
  await Promise.all(promises);
257
257
  };
@@ -284,7 +284,7 @@ Manager.prototype.loadScripts = async function () {
284
284
  var promises = [];
285
285
  for (let name in this.mods) {
286
286
  let mod = this.mods[name];
287
- promises.push(mod.exec('loadScript'));
287
+ promises.push(mod.call('loadScript'));
288
288
  }
289
289
  await Promise.all(promises);
290
290
  };
@@ -324,13 +324,10 @@ Manager.prototype.update = async function (dir, clear = true) {
324
324
  // 批量加载脚本
325
325
  await this.loadScripts();
326
326
  }
327
+ this.is_loaded = true;
327
328
  };
328
329
 
329
330
  // ==== 高性能调用接口 ====
330
- Manager.prototype.run = async function (name, method, ...params) {
331
- return await this.main(name, method, ...params);
332
- };
333
-
334
331
  /**
335
332
  * 调用模块的方法(高性能版本)
336
333
  * @param {string} name 模块名
@@ -434,14 +431,14 @@ Manager.prototype._runSub = async function (mod, method, ...params) {
434
431
  try {
435
432
  // 确保模块已加载
436
433
  if (!mod.isLoaded()) {
437
- await mod.exec('loadScript');
434
+ await mod.call('loadScript');
438
435
  }
439
436
 
440
437
  // 执行方法
441
- let ret = await mod.exec(method, ...params);
438
+ let ret = await mod.call(method, ...params);
442
439
  // 根据模式决定是否重载
443
440
  if (this.mode >= 4) {
444
- mod.exec('reload');
441
+ mod.do('reload');
445
442
  }
446
443
 
447
444
  return ret;
@@ -451,16 +448,6 @@ Manager.prototype._runSub = async function (mod, method, ...params) {
451
448
  }
452
449
  };
453
450
 
454
- /**
455
- * 调用模块的方法
456
- * @param {string} name 模块名
457
- * @param {object} params 参数集合
458
- * @returns {Promise<any>} 执行结果
459
- */
460
- Manager.prototype.call = async function (name, params = {}) {
461
- return await this.run(name, 'main', params);
462
- };
463
-
464
451
  /**
465
452
  * 初始化管理器
466
453
  */
@@ -494,8 +481,8 @@ Manager.prototype._initCore = function () {
494
481
 
495
482
  module.exports = {
496
483
  Manager,
497
- Item,
498
484
  Drive,
499
485
  // 向后兼容
500
- Index: Manager
486
+ Index: Manager,
487
+ Item: Drive
501
488
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_machine",
3
- "version": "2.2.5",
3
+ "version": "2.2.7",
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,9 +33,8 @@
33
33
  "README.md"
34
34
  ],
35
35
  "dependencies": {
36
- "mm_config": "^2.2.8",
37
- "mm_expand": "^2.1.0",
38
- "mm_hot_reload": "^1.2.5",
36
+ "mm_config": "^2.3.0",
37
+ "mm_hot_reload": "^1.3.0",
39
38
  "mm_tpl": "^2.4.9"
40
39
  },
41
40
  "devDependencies": {
package/item.js DELETED
@@ -1,697 +0,0 @@
1
- const {
2
- Drive
3
- } = require('./drive');
4
- require('mm_tpl');
5
- require('mm_hot_reload');
6
- let {
7
- conf
8
- } = require('mm_config');
9
-
10
- /**
11
- * 增强require函数,专门用于脚本文件(.js)热重载
12
- * 当脚本文件内容发生变化时,自动重新加载并触发回调
13
- * @param {string} file 脚本文件路径(.js)
14
- * @param {Function} func 热更新回调函数,文件变化时触发
15
- * @returns {object} 加载的模块对象
16
- * @throws {TypeError} 文件路径不是字符串或回调不是函数时抛出
17
- */
18
- $.require = function (file, func) {
19
- // 参数校验
20
- if (typeof file !== 'string') {
21
- throw new TypeError('文件路径必须是字符串');
22
- }
23
-
24
- if (func && typeof func !== 'function') {
25
- throw new TypeError('回调函数必须是函数');
26
- }
27
-
28
- // 确保文件是.js文件
29
- if (!file.endsWith('.js')) {
30
- throw new TypeError('$.require 只能用于.js脚本文件');
31
- }
32
-
33
- return $.mod.load(file, func);
34
- };
35
-
36
- /**
37
- * 增强JSON加载函数,专门用于配置文件(.json)热重载
38
- * 当配置文件内容发生变化时,自动重新加载并触发回调
39
- * @param {string} file 配置文件路径(.json)
40
- * @param {Function} func 热更新回调函数,文件变化时触发
41
- * @returns {object} 解析的JSON对象
42
- * @throws {TypeError} 文件路径不是字符串或回调不是函数时抛出
43
- */
44
- $.loadJson = function (file, func) {
45
- // 参数校验
46
- if (typeof file !== 'string') {
47
- throw new TypeError('文件路径必须是字符串');
48
- }
49
-
50
- if (func && typeof func !== 'function') {
51
- throw new TypeError('回调函数必须是函数');
52
- }
53
-
54
- // 确保文件是.json文件
55
- if (!file.endsWith('.json')) {
56
- throw new TypeError('$.loadJson 只能用于.json配置文件');
57
- }
58
-
59
- return $.mod.load(file, func);
60
- };
61
-
62
- /**
63
- * 驱动基础类
64
- * @class
65
- */
66
- class Item extends Drive {
67
- // 模块基础目录,用于放置脚本模板文件和配置模板文件
68
- static base_dir = '';
69
-
70
- // 配置项
71
- static config = {
72
- // 名称, 由中英文和下"_"组成, 用于卸载接口 例如: demo
73
- name: '',
74
- // 标题, 介绍作用
75
- title: '',
76
- // 描述, 用于描述该有什么用的
77
- description: '',
78
- // 文件路径, 当调用函数不存在时,会先从文件中加载
79
- main: './index.js',
80
- // 回调函数名 用于决定调用脚本的哪个函数
81
- func_name: 'main',
82
- // 作用域(同时作为检索的后缀名)
83
- scope: ($.val && $.val.scope) ? $.val.scope : 'server',
84
- // 排序
85
- sort: 10,
86
- // 状态, 0表示未启用, 1表示启用
87
- state: 1,
88
- // 显示, 0表示不显示, 1表示显示
89
- show: 0,
90
- // 是否结束,可选,默认false
91
- end: false
92
- };
93
-
94
- /**
95
- * 构造函数
96
- * @param {object} config 配置项
97
- * @param {object} parent 父项
98
- * @class
99
- */
100
- constructor(config, parent) {
101
- super({
102
- ...Item.config,
103
- ...config
104
- }, parent);
105
- // 当前配置文件路径
106
- this.config_file = '';
107
-
108
- // 当前脚本文件路径
109
- this.script_file = '';
110
-
111
- // 模式: 1.生产模式 2.热更新模式 3.热重载模式 4.热更新+重载模式 5.重载模式
112
- this.mode = 1;
113
-
114
- this.status = '';
115
- // 脚本的方法
116
- this.methods = {};
117
-
118
- // 资源配置列表
119
- this.getParent = function () {
120
- return parent;
121
- };
122
- }
123
- }
124
-
125
- /**
126
- * 检查模块是否已加载
127
- * @returns {boolean} 是否已加载
128
- */
129
- Item.prototype.isLoaded = function () {
130
- return this.is_loaded;
131
- };
132
-
133
- /**
134
- * 获取方法函数
135
- * @param {string} method 方法名
136
- * @returns {Function|null} 方法函数
137
- */
138
- Item.prototype._getMethod = function (method) {
139
- let func = this._methods && this._methods[method];
140
- if (!func) {
141
- func = this[method];
142
- }
143
- return func || null;
144
- };
145
-
146
- /**
147
- * 设置脚本方法
148
- * @param {object} methods 脚本方法对象
149
- */
150
- Item.prototype.setMethods = function (methods) {
151
- if (!methods) return;
152
- Object.assign(this.methods, methods);
153
- };
154
-
155
- /**
156
- * 获取配置
157
- * @param {string} file 配置文件路径
158
- * @returns {object} 配置项
159
- */
160
- Item.prototype.loadConfig = function (file) {
161
- if (file) {
162
- this.config_file = file;
163
- };
164
- // 加载配置
165
- let config = $.loadJson(this.config_file, (cg) => {
166
- this.setConfig(cg);
167
- return cg;
168
- });
169
- if (!config) {
170
- this.newConfig(this.config_file);
171
- config = $.loadJson(this.config_file, (cg) => {
172
- this.setConfig(cg);
173
- return cg;
174
- });
175
- }
176
- this.setConfig(config);
177
- return config;
178
- };
179
-
180
- /**
181
- * 设置配置
182
- * @param {object} config 配置对象
183
- */
184
- Item.prototype.setConfig = function (config) {
185
- if (config) {
186
- // 如果main改变,重置加载状态
187
- if (config.main !== this.config.main) {
188
- this.is_loaded = false;
189
- }
190
-
191
- if (this.config_file) {
192
- // 合并配置并应用配置处理
193
- this.config = conf({
194
- ...this.config,
195
- ...config
196
- }, this.config_file);
197
- }
198
- else {
199
- Object.assign(this.config, config);
200
- }
201
- }
202
- return this.config;
203
- };
204
-
205
- /**
206
- * 获取配置
207
- * @returns {object} 配置项
208
- */
209
- Item.prototype.getConfig = function () {
210
- return this.config;
211
- };
212
-
213
- /**
214
- * 获取当前文件
215
- * @returns {object} 当前文件对象
216
- */
217
- Item.prototype._getDir = function () {
218
- let dir = this._dir;
219
- if (!dir) {
220
- if (this.script_file) {
221
- dir = this.script_file.dirname();
222
- this._dir = dir;
223
- }
224
- else if (this.config_file) {
225
- dir = this.config_file.dirname();
226
- this._dir = dir;
227
- }
228
- }
229
- return dir;
230
- };
231
-
232
- /**
233
- * 获取模块目录
234
- * @returns {string} 模块目录
235
- */
236
- Item.prototype._getBaseDir = function () {
237
- return this.getParent().getBaseDir();
238
- };
239
-
240
- /**
241
- * 创建脚本
242
- * @param {string} file 文件路径
243
- * @param {object} model 模板数据
244
- * @param {string} tpl_dir 模板文件路径
245
- * @returns {boolean} 创建是否成功
246
- */
247
- Item.prototype._createScriptFile = function (file, model = {}, tpl_dir = '') {
248
- var tpl = this.getScriptTpl(tpl_dir);
249
- var content = $.tpl.render(tpl, model);
250
- file.saveText(content);
251
- return file;
252
- };
253
-
254
- /**
255
- * 获取脚本模板
256
- * @param {string} tpl_dir 模板文件路径
257
- * @returns {string} 脚本模板内容
258
- */
259
- Item.prototype.getScriptTpl = function (tpl_dir = '') {
260
- var f = './script.tpl.js'.fullname(tpl_dir || this.constructor.base_dir);
261
- if (f.hasFile()) {
262
- return f.loadText();
263
- } else {
264
- return `module.exports = {
265
- /**
266
- * 初始化
267
- */
268
- async _init() {
269
- this.log('debug', \`初始化!\`);
270
- },
271
- /**
272
- * 销毁
273
- */
274
- async _destroy(...args) {
275
- this.log('debug', \`销毁!\`);
276
- },
277
- /**
278
- * 主要逻辑
279
- */
280
- async main(...args) {
281
- // 主要代码写在这
282
- }
283
- }`;
284
- }
285
- };
286
-
287
- /**
288
- * 移除脚本
289
- */
290
- Item.prototype._remove = function () {
291
- let file = this._getScriptFile();
292
- if (!file) return;
293
-
294
- try {
295
- if (this.mode === 3 || this.mode === 4) {
296
- // 移除模块和监听
297
- $.mod.unload(file);
298
- } else {
299
- // 移除模块缓存
300
- let filename = require.resolve(file);
301
- if (require.cache[filename]) {
302
- require.cache[filename] = null;
303
- delete require.cache[filename];
304
- }
305
- }
306
- } catch (err) {
307
- this.log('error', `移除脚本失败: `, err);
308
- }
309
- };
310
-
311
- /**
312
- * 卸载脚本
313
- */
314
- Item.prototype.unloadScript = function () {
315
- this._remove();
316
- this.is_loaded = false;
317
- };
318
-
319
- /**
320
- * 重新加载脚本
321
- * @returns {object | null} 返回加载的模块对象
322
- */
323
- Item.prototype.reloadScript = function () {
324
- this.unloadScript();
325
- return this.loadScript();
326
- };
327
-
328
- /**
329
- * 卸载钩子方法
330
- */
331
- Item.prototype.unload = async function () {
332
-
333
- };
334
-
335
- /**
336
- * 卸载之后处理
337
- * @param {boolean} remove 是否删除文件
338
- */
339
- Item.prototype.unloadAfter = async function (remove) {
340
- // 删除脚本
341
- this.unloadScript();
342
- if (remove) {
343
- this.removeFile();
344
- }
345
- };
346
-
347
- /**
348
- * 获取脚本文件路径
349
- * @param {string} file 文件路径
350
- * @returns {string | null} 完整文件路径
351
- */
352
- Item.prototype._getScriptFile = function () {
353
- let main = this.config.main || '';
354
- if (!main) return null;
355
-
356
- let filename = main.fullname(this._getDir());
357
- if (!filename.hasFile()) {
358
- this.newScript(filename);
359
- }
360
-
361
- return filename;
362
- };
363
-
364
- /**
365
- * 加载脚本文件,支持热重载模式
366
- * 在开发模式(mode=3或4)下使用 $.require 进行热重载
367
- * 在生产模式下使用标准的 require 加载
368
- * @returns {object | null} 加载的模块对象
369
- */
370
- Item.prototype.loadScript = function () {
371
- let file = this._getScriptFile();
372
- if (!file) return null;
373
- if (this.mode === 3 || this.mode === 4) {
374
- // 开发模式:使用 $.require 进行热重载,绑定热更新回调
375
- var cs = $.require(file, (mod) => {
376
- this._setMainMethod(mod);
377
- });
378
- this._setMainMethod(cs);
379
- return cs;
380
- } else {
381
- var cs = require(file);
382
- this._setMainMethod(cs);
383
- return cs;
384
- }
385
- };
386
-
387
- /**
388
- * 设置主方法
389
- * @param {object} mod 模块对象
390
- */
391
- Item.prototype._setMainMethod = function (mod) {
392
- if (!mod) return;
393
- let name = this.config.func_name || 'main';
394
- if (name && mod[name]) {
395
- this.main = mod[name];
396
- }
397
- if ($.push) {
398
- $.push(this, mod, true);
399
- }
400
- else {
401
- Object.assign(this, mod);
402
- }
403
- this.is_loaded = true;
404
- };
405
-
406
- /**
407
- * 获取配置文件作用域
408
- * @param {object} file 文件对象
409
- * @returns {string} 配置文件作用域
410
- */
411
- Item.prototype._getScope = function (file) {
412
- return file.replace(/\\/g, '/').between('app/', '/');
413
- };
414
-
415
- /**
416
- * 新建配置文件
417
- * @param {string} file 目标文件路径
418
- */
419
- Item.prototype.newConfig = function (file) {
420
- if (!this.config.name) {
421
- this.config.name = this._getName(file);
422
- this.config.scope = this._getScope(file);
423
- }
424
- this._createConfigFile(file);
425
- };
426
-
427
- /**
428
- * 创建配置文件
429
- * @param {string} file 目标文件路径
430
- * @returns {string} 配置文件内容
431
- */
432
- Item.prototype._createConfigFile = function (file) {
433
- var tpl = this.getConfigTpl();
434
- var content = $.tpl.render(tpl, this.config);
435
- file.saveText(content);
436
- return file;
437
- };
438
-
439
- /**
440
- * 获取配置模板
441
- * @param {string} tpl_dir 模板文件路径
442
- * @returns {string} 配置模板内容
443
- */
444
- Item.prototype.getConfigTpl = function (tpl_dir = '') {
445
- var f = './config.tpl.json'.fullname(tpl_dir || this.constructor.base_dir);
446
- if (f.hasFile()) {
447
- return f.loadText();
448
- } else {
449
- return `{
450
- // 模块名称,必填
451
- "name": "\${name}",
452
- // 模块标题,可选,默认"示例标题"
453
- "title": "\${title || "示例标题"}",
454
- // 模块描述,可选,默认"示例描述"
455
- "description": "\${description || "示例描述"}",
456
- // 主脚本文件路径,可选,默认"./index.js"
457
- "main": "\${main || "./index.js"}",
458
- // 模块作用域,可选,默认"server"
459
- "scope": "\${scope || "server"}",
460
- // 模块状态,可选,默认1
461
- "state": \${state || 1},
462
- // 模块排序,可选,默认100
463
- "sort": \${sort || 100},
464
- // 是否结束,可选,默认false
465
- "end": \${end || false}
466
- }`;
467
- }
468
- };
469
-
470
- /**
471
- * 加载配置文件
472
- * @param {string} file 文件路径
473
- * @param {string} name 配置项名称
474
- * @returns {object | null} 配置对象
475
- */
476
- Item.prototype.loadFile = function (file, name) {
477
- try {
478
- let filename = file.fullname(this._getDir());
479
- let text = filename.loadText();
480
-
481
- // 如果文件不存在,创建新的配置文件
482
- if (!text) {
483
- this.newConfig(filename);
484
- text = filename.loadText();
485
- }
486
-
487
- if (!text) return null;
488
-
489
- let config = this._loadHotReload(filename);
490
- let final_config = this._findConfigByName(config, name);
491
- return final_config;
492
- } catch (err) {
493
- this.log('error', `加载配置文件失败: `, err);
494
- return null;
495
- }
496
- };
497
-
498
- /**
499
- * 根据模式加载配置(支持热更新)
500
- * @param {string} file 完整文件路径
501
- * @returns {object | Array | null} 配置对象
502
- */
503
- Item.prototype._loadHotReload = function (file) {
504
- if (this.mode === 2 || this.mode === 3 || this.mode === 4) {
505
- return $.loadJson(file, this._handleHotReload.bind(this));
506
- }
507
- return file.loadJson();
508
- };
509
-
510
- /**
511
- * 根据名称在配置数组中查找配置项
512
- * @param {object | Array} config 配置对象或数组
513
- * @param {string} name 配置项名称
514
- * @returns {object | null} 匹配的配置项
515
- */
516
- Item.prototype._findConfigByName = function (config, name) {
517
- if (!name || !Array.isArray(config)) return config;
518
- return config.find((item) => item.name === name) || null;
519
- };
520
-
521
- /**
522
- * 根据模式决定是否重新加载脚本
523
- */
524
- Item.prototype._reloadIfNeeded = function () {
525
- if (this.mode === 3 || this.mode === 4) {
526
- this.reloadScript();
527
- }
528
- };
529
-
530
- /**
531
- * 删除目录
532
- */
533
- Item.prototype.delDir = function () {
534
- let main = this.config.main;
535
- if (main && $.dir && $.dir.del) {
536
- $.dir.del(this.dir);
537
- }
538
- };
539
-
540
- /**
541
- * 删除配置和脚本文件
542
- * @returns {string | null} 错误消息,如果没有错误则返回null
543
- */
544
- Item.prototype.removeFile = function () {
545
- let name = this.config.name;
546
- let file = this.script_file;
547
-
548
- let error_message = null;
549
- try {
550
- if (!file || !file.hasFile) return null;
551
-
552
- if (!file.hasFile()) {
553
- return '配置文件不存在';
554
- }
555
-
556
- error_message = this._removeConfigFile(file, name);
557
- } catch (err) {
558
- this.log('error', `删除文件失败: `, err);
559
- error_message = `删除失败: ${err.message}`;
560
- }
561
- return error_message;
562
- };
563
-
564
- /**
565
- * 删除配置文件
566
- * @param {object} file 文件对象
567
- * @param {string} name 配置名称
568
- * @returns {string | null} 错误消息
569
- */
570
- Item.prototype._removeConfigFile = function (file, name) {
571
- let text = file.loadText();
572
- if (!text) {
573
- this.delDir();
574
- return null;
575
- }
576
-
577
- let config = text.toJson();
578
- if (Array.isArray(config)) {
579
- return this._delArray(file, config, name);
580
- }
581
-
582
- this.delDir();
583
- return null;
584
- };
585
-
586
- /**
587
- * 从数组配置中删除指定项
588
- * @param {object} file 文件对象
589
- * @param {Array} config 配置数组
590
- * @param {string} name 配置名称
591
- * @returns {string | null} 错误消息
592
- */
593
- Item.prototype._delArray = function (file, config, name) {
594
- let index = config.findIndex((item) => item.name === name);
595
- if (index === -1) return null;
596
-
597
- this.delDir();
598
- config.splice(index, 1);
599
-
600
- if (config.length > 0) {
601
- file.saveText(JSON.stringify(config, null, 4));
602
- } else if (file.delFile) {
603
- file.delFile();
604
- }
605
-
606
- return null;
607
- };
608
-
609
- /**
610
- * 获取配置文件名称
611
- * @param {object} file 文件对象
612
- * @returns {string} 配置文件名称
613
- */
614
- Item.prototype._getName = function (file) {
615
- return file.dirname().basename();
616
- };
617
-
618
- /**
619
- * 加载前处理
620
- */
621
- Item.prototype.loadBefore = async function () {
622
- try {
623
- let module = this.loadScript();
624
- if (module) {
625
- this.is_loaded = true;
626
- }
627
- } catch (err) {
628
- this.log('error', `加载前处理失败: `, err);
629
- this.is_loaded = false;
630
- }
631
- };
632
-
633
- /**
634
- * 加载处理
635
- */
636
- Item.prototype.load = async function () {
637
- this.loadConfig();
638
- this.loadScript();
639
- };
640
-
641
- /**
642
- * 重载配置和脚本
643
- */
644
- Item.prototype.reload = async function () {
645
- await this.exec('unload');
646
- await this.exec('load');
647
- };
648
-
649
- /**
650
- * 保存配置
651
- */
652
- Item.prototype.save = function () {
653
- try {
654
- if (!this.script_file) return;
655
-
656
- let file = this.script_file.fullname(this._getDir());
657
- let text = file.loadText();
658
-
659
- if (text && text.trim().startsWith('[')) {
660
- // 数组格式配置
661
- let config = text.toJson();
662
- if (Array.isArray(config)) {
663
- // 查找并更新现有配置项
664
- let index = config.findIndex((item) => item.name === this.config.name);
665
- if (index !== -1) {
666
- config[index] = this.config;
667
- } else {
668
- // 如果不存在,添加新配置项
669
- config.push(this.config);
670
- }
671
- file.saveText(JSON.stringify(config, null, 4));
672
- return;
673
- }
674
- }
675
-
676
- // 单对象格式配置,直接保存
677
- file.saveText(JSON.stringify(this.config, null, 4));
678
- } catch (err) {
679
- this.log('error', `保存配置失败: `, err);
680
- }
681
- };
682
-
683
- /**
684
- * 触发事件
685
- * @param {string} event 事件名
686
- * @param {...any} args 事件参数
687
- */
688
- Item.prototype.emitEvent = function (event, ...args) {
689
- this._eventer?.emit(event, ...args);
690
- };
691
-
692
- /**
693
- * @module 导出Item类
694
- */
695
- module.exports = {
696
- Item
697
- };