mm_expand 2.0.0 → 2.0.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/lib/base.js CHANGED
@@ -8,6 +8,17 @@ require('./global');
8
8
  * 基础类
9
9
  */
10
10
  class Base extends Event {
11
+ static config = {
12
+ // 模块名称
13
+ name: '',
14
+ // 模块标题
15
+ title: '',
16
+ // 模块描述
17
+ description: '',
18
+ // 状态, 可选值: 1-启用, 0-禁用
19
+ state: 1
20
+ };
21
+
11
22
  /**
12
23
  * 构造函数
13
24
  * @param {object} config 配置参数
@@ -18,20 +29,11 @@ class Base extends Event {
18
29
  * 配置参数
19
30
  * @type {object}
20
31
  */
21
- this.config = {
22
- // 模块名称
23
- name: '',
24
- // 模块标题
25
- title: '',
26
- // 模块描述
27
- description: '',
28
- // 状态, 可选值: 1-启用, 0-禁用
29
- state: 1
30
- };
32
+ this.config = {...this.constructor.config};
31
33
 
32
34
  /**
33
35
  * 状态
34
- * @type {string} - 状态, 可选值: created, init, running, stopped
36
+ * @type {string} - 状态, 可选值: created, initing, starting, running, stopped, destroying, destroyed
35
37
  */
36
38
  this.status = 'created';
37
39
 
@@ -42,43 +44,68 @@ class Base extends Event {
42
44
  }
43
45
  }
44
46
 
47
+ /**
48
+ * 日志输出
49
+ * @param {string} level 日志级别
50
+ * @param {string} message 日志消息
51
+ * @param {...any} args 日志参数
52
+ */
53
+ Base.prototype.log = function (level, message, ...args) {
54
+ this._logger[level](`[${this.constructor.name}] [${this.config.name}] ${message}`, ...args);
55
+ };
56
+
45
57
  /**
46
58
  * 初始化监听
47
59
  */
48
60
  Base.prototype._initListen = function () {
61
+ let status_last = 'created';
62
+ // 初始化
49
63
  this.on('init:before', (ctx) => {
50
64
  this.status = 'initing';
51
65
  this._initCore(...ctx.params);
52
66
  });
67
+ this.on('init:after', (ctx) => {
68
+ this.status = 'inited';
69
+ });
70
+ // 启动
53
71
  this.on('start:before', (ctx) => {
72
+ status_last = this.status;
54
73
  this.status = 'starting';
55
74
  });
56
- this.on('start:after', (ctx) => {
75
+ this.on('start:success', (ctx) => {
57
76
  this.status = 'running';
58
77
  });
78
+ this.on('start:error', (ctx) => {
79
+ this.status = status_last;
80
+ });
81
+ // 停止
59
82
  this.on('stop:before', (ctx) => {
83
+ status_last = this.status;
60
84
  this.status = 'stopping';
61
85
  });
62
- this.on('stop:after', (ctx) => {
86
+ this.on('stop:success', (ctx) => {
63
87
  this.status = 'stopped';
64
88
  });
65
- this.on('restart:before', (ctx) => {
66
- this.status = 'restarting';
67
- });
68
- this.on('restart:after', (ctx) => {
69
- this.status = 'running';
89
+ this.on('stop:error', (ctx) => {
90
+ this.status = status_last;
70
91
  });
92
+ // 销毁
71
93
  this.on('destroy:before', (ctx) => {
94
+ status_last = this.status;
72
95
  this.status = 'destroying';
73
96
  });
74
97
  this.on('destroy:check', (ctx) => {
75
- if (this.status !== 'stopped') {
98
+ if (status_last !== 'stopped') {
99
+ status_last = this.status;
76
100
  ctx.error = new Error('销毁前必须先停止');
77
101
  }
78
102
  });
79
- this.on('destroy:after', (ctx) => {
103
+ this.on('destroy:success', (ctx) => {
80
104
  this.status = 'destroyed';
81
105
  });
106
+ this.on('destroy:error', (ctx) => {
107
+ this.status = status_last;
108
+ });
82
109
  };
83
110
 
84
111
  /**
@@ -137,8 +164,8 @@ Base.prototype.destroy = async function () {
137
164
  * 重启
138
165
  */
139
166
  Base.prototype.restart = async function () {
140
- await this.stop();
141
- await this.start();
167
+ await this.do('stop');
168
+ await this.do('start');
142
169
  };
143
170
 
144
171
  /**
@@ -183,102 +210,133 @@ Base.prototype.do = async function (method, ...args) {
183
210
 
184
211
  try {
185
212
  await this._doBeforeProcess(method, ctx);
186
- if (ctx.error || ctx.cancelled) {
213
+ if (ctx.cancelled) {
187
214
  return ctx.result;
188
215
  }
189
216
 
190
217
  await this._doExecuteMethod(method, ctx);
218
+
219
+ // 如果执行成功,进行成功处理
220
+ if (!ctx.error) {
221
+ await this._doSuccessProcess(method, ctx);
222
+ }
223
+
224
+ return ctx.result;
191
225
  } catch (error) {
192
226
  ctx.error = error;
193
227
  this.log('error', `事件驱动执行异常 [${method}]`, error);
228
+
229
+ // 执行错误处理
230
+ await this._doErrorProcess(method, ctx);
231
+
232
+ // 重新抛出错误,让上层能够捕获
233
+ throw error;
234
+ } finally {
235
+ // 无论成功失败,都要执行后处理
236
+ await this._doAfterProcess(method, ctx);
194
237
  }
195
-
196
- await this._doAfterProcess(method, ctx);
197
-
198
- return ctx.result;
199
238
  };
200
239
 
240
+ /**
241
+ * 前处理阶段
242
+ * @param {string} method 方法名称
243
+ * @param {object} ctx 上下文对象
244
+ * @private
245
+ */
201
246
  Base.prototype._doBeforeProcess = async function (method, ctx) {
202
- try {
203
- await this.emitWait(method + ':before', ctx);
204
- } catch (error) {
205
- this.log('error', `前置处理失败 [${method}:before]`, error);
206
- ctx.error = error;
207
- }
247
+ await this.emitWait(method + ':before', ctx);
208
248
  };
209
249
 
250
+ /**
251
+ * 执行方法
252
+ * @param {string} method 方法名称
253
+ * @param {object} ctx 上下文对象
254
+ * @private
255
+ */
210
256
  Base.prototype._doExecuteMethod = async function (method, ctx) {
211
- try {
212
- await this._doCheckPhase(method, ctx);
213
- if (ctx.error) return;
257
+ await this._doCheckPhase(method, ctx);
258
+ if (ctx.error) return;
214
259
 
215
- await this._doMainMethod(method, ctx);
216
- if (ctx.error) return;
260
+ await this._doMainMethod(method, ctx);
261
+ if (ctx.error) return;
217
262
 
218
- await this._doRenderPhase(method, ctx);
219
- } catch (error) {
220
- ctx.error = error;
221
- this.log('error', `执行阶段异常 [${method}]`, error);
222
- }
263
+ await this._doRenderPhase(method, ctx);
223
264
  };
224
265
 
266
+ /**
267
+ * 检查阶段
268
+ * @param {string} method 方法名称
269
+ * @param {object} ctx 上下文对象
270
+ */
225
271
  Base.prototype._doCheckPhase = async function (method, ctx) {
226
- let check_result;
227
- try {
228
- check_result = await this.emitRace(method + ':check', ctx);
229
- } catch (error) {
230
- this.log('error', `检查阶段失败 [${method}:check]`, error);
231
- ctx.error = error;
232
- return;
233
- }
272
+ let ret = await this.emitRace(method + ':check', ctx);
234
273
 
235
- if (check_result) {
236
- if (check_result.status === 'rejected') {
237
- ctx.error = check_result.error;
238
- } else if (check_result.status === 'fulfilled' && check_result.result) {
239
- ctx.result = check_result.result;
274
+ if (ret) {
275
+ if (ret.status === 'rejected') {
276
+ ctx.error = ret.error;
277
+ } else if (ret.status === 'fulfilled' && ret.result) {
278
+ ctx.result = ret.result;
240
279
  }
241
280
  }
242
281
  };
243
282
 
283
+ /**
284
+ * 主方法执行
285
+ * @param {string} method 方法名称
286
+ * @param {object} ctx 上下文对象
287
+ * @private
288
+ */
244
289
  Base.prototype._doMainMethod = async function (method, ctx) {
245
290
  if (!ctx.result) {
246
- try {
247
- ctx.result = await this[method](...ctx.params);
248
- } catch (error) {
249
- ctx.error = error;
250
- this.log('error', `主方法执行失败 [${method}]`, error);
251
- }
291
+ ctx.result = await this[method](...ctx.params);
252
292
  }
253
293
  };
254
294
 
295
+ /**
296
+ * 渲染阶段
297
+ * @param {string} method 方法名称
298
+ * @param {object} ctx 上下文对象
299
+ * @private
300
+ */
255
301
  Base.prototype._doRenderPhase = async function (method, ctx) {
256
302
  if (ctx.result && !ctx.error) {
257
- try {
258
- let result = await this.emitWaterfall(method + ':render', ctx.result, ctx);
259
- if (result) {
260
- ctx.result = result;
261
- }
262
- } catch (error) {
263
- this.log('error', `渲染阶段失败 [${method}:render]`, error);
303
+ let result = await this.emitWaterfall(method + ':render', ctx.result, ctx);
304
+ if (result) {
305
+ ctx.result = result;
264
306
  }
265
307
  }
266
308
  };
267
309
 
310
+ /**
311
+ * 成功处理阶段
312
+ * @param {string} method 方法名称
313
+ * @param {object} ctx 上下文对象
314
+ * @private
315
+ */
316
+ Base.prototype._doSuccessProcess = async function (method, ctx) {
317
+ await this.emitWait(method + ':success', ctx);
318
+ };
319
+
320
+ /**
321
+ * 后处理阶段
322
+ * @param {string} method 方法名称
323
+ * @param {object} ctx 上下文对象
324
+ * @private
325
+ */
268
326
  Base.prototype._doAfterProcess = async function (method, ctx) {
269
- if (ctx.error) {
270
- try {
271
- await this.emitAsync(method + ':error', ctx);
272
- this.log('error', `执行方法${method}出错:`, ctx.error);
273
- } catch (error) {
274
- this.log('error', `错误处理失败 [${method}:error]`, error);
275
- }
276
- }
327
+ // 异步触发after事件,不等待执行完成
328
+ this.emitAsync(method + ':after', ctx);
329
+ };
277
330
 
278
- try {
279
- await this.emitWait(method + ':after', ctx);
280
- } catch (error) {
281
- this.log('error', `后置处理失败 [${method}:after]`, error);
331
+ /**
332
+ * 错误处理
333
+ * @param {string} method 方法名称
334
+ * @param {object} ctx 上下文对象
335
+ */
336
+ Base.prototype._doErrorProcess = async function (method, ctx) {
337
+ if (ctx.error) {
338
+ await this.emitAsync(method + ':error', ctx);
339
+ this.log('error', `执行方法${method}出错:`, ctx.error);
282
340
  }
283
341
  };
284
342
 
@@ -361,6 +419,16 @@ Base.prototype.run = async function (...args) {
361
419
  return await this.do('main', ...args);
362
420
  };
363
421
 
422
+ /**
423
+ * 执行方法
424
+ * @param {string} method 方法名称
425
+ * @param {...any} args 参数列表
426
+ * @returns
427
+ */
428
+ Base.prototype.exec = async function (method, ...args) {
429
+ return await this.do(method, ...args);
430
+ };
431
+
364
432
  /**
365
433
  * 执行指令(主要)
366
434
  * @param {string} command 指令
@@ -398,6 +466,11 @@ Base.prototype.cmd = async function (command, ...args) {
398
466
  }
399
467
  };
400
468
 
469
+ /**
470
+ * 解析指令
471
+ * @param {object} ctx 上下文对象
472
+ * @private
473
+ */
401
474
  Base.prototype._cmdParseCommand = function (ctx) {
402
475
  try {
403
476
  ctx.cmds = ctx.command.split('.');
@@ -413,6 +486,11 @@ Base.prototype._cmdParseCommand = function (ctx) {
413
486
  }
414
487
  };
415
488
 
489
+ /**
490
+ * 遍历指令路径
491
+ * @param {object} ctx 上下文对象
492
+ * @private
493
+ */
416
494
  Base.prototype._cmdTraversePath = async function (ctx) {
417
495
  for (let index = 0; index < ctx.cmds.length; index++) {
418
496
  const key = ctx.cmds[index];
@@ -446,6 +524,14 @@ Base.prototype._cmdTraversePath = async function (ctx) {
446
524
  ctx.result = ctx.obj;
447
525
  };
448
526
 
527
+ /**
528
+ * 处理指令对象类型
529
+ * @param {object} ctx 上下文对象
530
+ * @param {string} key 当前键名
531
+ * @param {boolean} is_last 是否为最后一个键名
532
+ * @returns {boolean} 是否停止遍历
533
+ * @private
534
+ */
449
535
  Base.prototype._cmdHandleType = async function (ctx, key, is_last) {
450
536
  const type = typeof ctx.obj;
451
537
 
@@ -461,6 +547,13 @@ Base.prototype._cmdHandleType = async function (ctx, key, is_last) {
461
547
  return false;
462
548
  };
463
549
 
550
+ /**
551
+ * 处理指令对象类型:函数
552
+ * @param {object} ctx 上下文对象
553
+ * @param {boolean} is_last 是否为最后一个键名
554
+ * @returns {boolean} 是否停止遍历
555
+ * @private
556
+ */
464
557
  Base.prototype._cmdHandleFunction = async function (ctx, is_last) {
465
558
  if (typeof ctx.obj !== 'function') {
466
559
  this.log('error', `指令指向的对象不是函数 [${ctx.command}]`);
@@ -484,6 +577,13 @@ Base.prototype._cmdHandleFunction = async function (ctx, is_last) {
484
577
  return false;
485
578
  };
486
579
 
580
+ /**
581
+ * 处理指令对象类型:数组
582
+ * @param {object} ctx 上下文对象
583
+ * @param {boolean} is_last 是否为最后一个键名
584
+ * @returns {boolean} 是否停止遍历
585
+ * @private
586
+ */
487
587
  Base.prototype._cmdHandleArray = function (ctx, is_last) {
488
588
  if (is_last) {
489
589
  ctx.result = ctx.obj;
@@ -496,6 +596,13 @@ Base.prototype._cmdHandleArray = function (ctx, is_last) {
496
596
  return true;
497
597
  };
498
598
 
599
+ /**
600
+ * 处理指令对象类型:原始值
601
+ * @param {object} ctx 上下文对象
602
+ * @param {boolean} is_last 是否为最后一个键名
603
+ * @returns {boolean} 是否停止遍历
604
+ * @private
605
+ */
499
606
  Base.prototype._cmdHandlePrimitive = function (ctx, is_last) {
500
607
  if (is_last) {
501
608
  ctx.result = ctx.obj;
@@ -533,6 +640,11 @@ Base.prototype.help = async function (...args) {
533
640
  }
534
641
  };
535
642
 
643
+ /**
644
+ * 处理帮助参数
645
+ * @param {object} ctx 上下文对象
646
+ * @private
647
+ */
536
648
  Base.prototype._helpProcessArgs = function (ctx) {
537
649
  if (ctx.args.length > 0) {
538
650
  ctx.param = ctx.args[0];
@@ -544,6 +656,11 @@ Base.prototype._helpProcessArgs = function (ctx) {
544
656
  }
545
657
  };
546
658
 
659
+ /**
660
+ * 处理帮助内容
661
+ * @param {object} ctx 上下文对象
662
+ * @private
663
+ */
547
664
  Base.prototype._helpProcessContent = async function (ctx) {
548
665
  if (ctx.param !== null) {
549
666
  await this._helpWithParam(ctx);
@@ -552,6 +669,11 @@ Base.prototype._helpProcessContent = async function (ctx) {
552
669
  }
553
670
  };
554
671
 
672
+ /**
673
+ * 处理帮助参数:有参数
674
+ * @param {object} ctx 上下文对象
675
+ * @private
676
+ */
555
677
  Base.prototype._helpWithParam = async function (ctx) {
556
678
  if (this.helper) {
557
679
  await this._helpUsingHelper(ctx);
@@ -560,6 +682,11 @@ Base.prototype._helpWithParam = async function (ctx) {
560
682
  }
561
683
  };
562
684
 
685
+ /**
686
+ * 处理帮助参数:无参数
687
+ * @param {object} ctx 上下文对象
688
+ * @private
689
+ */
563
690
  Base.prototype._helpUsingHelper = async function (ctx) {
564
691
  try {
565
692
  let hp = this._helpGetHelperValue(ctx.param);
@@ -579,6 +706,12 @@ Base.prototype._helpUsingHelper = async function (ctx) {
579
706
  }
580
707
  };
581
708
 
709
+ /**
710
+ * 获取帮助属性值
711
+ * @param {string} param 参数名
712
+ * @returns {object} 帮助属性值
713
+ * @private
714
+ */
582
715
  Base.prototype._helpGetHelperValue = function (param) {
583
716
  if (!param) {
584
717
  return this.helper;
@@ -592,6 +725,12 @@ Base.prototype._helpGetHelperValue = function (param) {
592
725
  return this.helper;
593
726
  };
594
727
 
728
+ /**
729
+ * 处理帮助数组
730
+ * @param {object} array 数组对象
731
+ * @returns {string} 处理后的数组字符串
732
+ * @private
733
+ */
595
734
  Base.prototype._helpProcessArray = function (array) {
596
735
  let result = '';
597
736
 
@@ -607,6 +746,12 @@ Base.prototype._helpProcessArray = function (array) {
607
746
  return result;
608
747
  };
609
748
 
749
+ /**
750
+ * 处理帮助对象
751
+ * @param {object} obj 对象对象
752
+ * @returns {string} 处理后的对象字符串
753
+ * @private
754
+ */
610
755
  Base.prototype._helpProcessObject = function (obj) {
611
756
  let result = '';
612
757
 
@@ -629,6 +774,11 @@ Base.prototype._helpProcessObject = function (obj) {
629
774
  return result;
630
775
  };
631
776
 
777
+ /**
778
+ * 处理帮助参数:无参数
779
+ * @param {object} ctx 上下文对象
780
+ * @private
781
+ */
632
782
  Base.prototype._helpUsingObject = async function (ctx) {
633
783
  try {
634
784
  if (!ctx.param || typeof ctx.param !== 'string') {
@@ -644,6 +794,12 @@ Base.prototype._helpUsingObject = async function (ctx) {
644
794
  }
645
795
  };
646
796
 
797
+ /**
798
+ * 导航帮助路径
799
+ * @param {string} path 路径字符串
800
+ * @returns {object} 目标对象
801
+ * @private
802
+ */
647
803
  Base.prototype._helpNavigatePath = function (path) {
648
804
  const keys = path.split('.');
649
805
  let obj = this;
@@ -667,6 +823,12 @@ Base.prototype._helpNavigatePath = function (path) {
667
823
  return obj;
668
824
  };
669
825
 
826
+ /**
827
+ * 格式化帮助结果
828
+ * @param {object} target 目标对象
829
+ * @returns {string} 格式化后的结果字符串
830
+ * @private
831
+ */
670
832
  Base.prototype._helpFormatResult = function (target) {
671
833
  if (typeof target === 'function') {
672
834
  try {
@@ -689,6 +851,11 @@ Base.prototype._helpFormatResult = function (target) {
689
851
  }
690
852
  };
691
853
 
854
+ /**
855
+ * 处理帮助参数:无参数
856
+ * @param {object} ctx 上下文对象
857
+ * @private
858
+ */
692
859
  Base.prototype._helpWithoutParam = async function (ctx) {
693
860
  try {
694
861
  ctx.result = this._helpProcessObject(this);