mm_os 4.2.4 → 4.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 (77) hide show
  1. package/README.md +1 -1
  2. package/README_EN.md +2 -2
  3. package/adapter/adapter.js +105 -52
  4. package/adapter/custom_persistence.js +32 -31
  5. package/adapter/mqtt.js +59 -79
  6. package/adapter/socket.js +188 -58
  7. package/adapter/web.js +92 -68
  8. package/adapter/websocket.js +43 -146
  9. package/com/api/drive.js +732 -708
  10. package/com/api/index.js +196 -198
  11. package/com/api/script.tpl.js +24 -24
  12. package/com/cmd/config.tpl.json +48 -122
  13. package/com/cmd/drive.js +176 -1548
  14. package/com/cmd/index.js +287 -1066
  15. package/com/cmd/job/config.json +66 -0
  16. package/com/cmd/job/index.js +241 -0
  17. package/com/cmd/job/test.js +188 -0
  18. package/com/cmd/script.tpl.js +12 -33
  19. package/com/db/drive.js +2206 -2019
  20. package/com/db/index.js +241 -242
  21. package/com/event/config.tpl.json +3 -1
  22. package/com/event/drive.js +3 -1
  23. package/com/event/index.js +73 -46
  24. package/com/event/script.tpl.js +22 -22
  25. package/com/mqtt/config.tpl.json +16 -8
  26. package/com/mqtt/drive.js +696 -676
  27. package/com/mqtt/index.js +1012 -822
  28. package/com/mqtt/index.test.js +503 -0
  29. package/com/mqtt/mm_mqtt.js +446 -420
  30. package/com/mqtt/script.tpl.js +3 -7
  31. package/com/nav/drive.js +7 -7
  32. package/com/nav/index.js +228 -231
  33. package/com/param/index.js +19 -17
  34. package/com/pendant/index.js +467 -441
  35. package/com/socket/drive.js +679 -651
  36. package/com/socket/index.js +94 -48
  37. package/com/sql/drive.js +1283 -1259
  38. package/com/sql/index.js +152 -150
  39. package/com/static/drive.js +1 -1
  40. package/com/static/index.js +232 -226
  41. package/com/static/script.tpl.js +25 -25
  42. package/com/task/drive.js +428 -405
  43. package/com/task/index.js +154 -148
  44. package/com/task/script.tpl.js +37 -34
  45. package/com/template/drive.js +1 -1
  46. package/com/template/index.js +141 -138
  47. package/com.js +87 -6
  48. package/common/middleware/web_after/index.js +5 -11
  49. package/common/middleware/web_base/index.js +1 -1
  50. package/common/middleware/web_cors/index.js +1 -1
  51. package/common/middleware/web_error/index.js +131 -119
  52. package/common/middleware/web_error/middleware.json +2 -1
  53. package/common/middleware/web_logger/index.js +1 -1
  54. package/common/middleware/web_main/index.js +2 -0
  55. package/common/middleware/web_static/index.js +2 -2
  56. package/common/middleware/web_waf/index.js +1 -1
  57. package/core/app/config.tpl.json +4 -4
  58. package/core/app/index.js +710 -534
  59. package/core/middleware/index.js +1 -9
  60. package/core/mod/config.tpl.json +1 -1
  61. package/core/model/config.tpl.json +1 -1
  62. package/core/plugin/config.tpl.json +15 -3
  63. package/core/plugin/index.js +31 -0
  64. package/core/pusher/index.js +158 -161
  65. package/core/scene/loop.js +1306 -1255
  66. package/core/store/index.js +1794 -1755
  67. package/core/store/sql.js +1488 -1464
  68. package/core/zone/bat/index.js +744 -728
  69. package/core/zone/config.tpl.json +3 -3
  70. package/core/zone/index.js +655 -616
  71. package/os.js +0 -4
  72. package/package.json +16 -16
  73. package/server.js +583 -427
  74. package/com/cmd/nlp.js +0 -525
  75. package/core/app/index copy.js +0 -611
  76. package/software.js +0 -194
  77. package/tcp.js +0 -279
package/com.js CHANGED
@@ -1,4 +1,3 @@
1
- require('mm_machine');
2
1
  const { Word } = require('./ulits/word.js');
3
2
 
4
3
  if (!$.admin) {
@@ -87,7 +86,7 @@ Com.prototype._loadConfig = function (file) {
87
86
  * @param {object} cg 配置信息
88
87
  */
89
88
  Com.prototype._loadScript = function (cg) {
90
- var file = (cg.main || './index.js').fullname(cg.dir);
89
+ var file = cg._file || (cg.main || './index.js').fullname(cg.dir);
91
90
  if (!file.hasFile()) {
92
91
  var name = this.toClassName(cg.name);
93
92
  var title = cg.title;
@@ -108,11 +107,12 @@ exports.${name} = ${name};`;
108
107
  file.saveText(script);
109
108
  }
110
109
  try {
111
- this[cg.name] = $.require(file, (mod) => {
110
+ return $.require(file, (mod) => {
112
111
  this[cg.name] = mod;
113
112
  });
114
113
  } catch (error) {
115
114
  $.log.error('加载脚本失败!', error);
115
+ return null;
116
116
  }
117
117
  };
118
118
 
@@ -132,15 +132,96 @@ Com.prototype._loads = function (dir, dirname) {
132
132
  var cg = this._loadConfig(file);
133
133
  if (cg) {
134
134
  cg.dir = file.dirname();
135
- this.list.push(cg);
135
+ cg._file = (cg.main || './index.js').fullname(cg.dir);
136
+ cg._loaded = false;
137
+ var idx = this._findIndex(cg.name);
138
+ if (idx >= 0) {
139
+ var loaded = this.list[idx]._loaded;
140
+ Object.assign(this.list[idx], cg);
141
+ this.list[idx]._loaded = loaded;
142
+ } else {
143
+ this.list.push(cg);
144
+ this._defineLazy(cg);
145
+ }
136
146
  }
137
147
  }
138
-
139
148
  this._sort();
149
+ // 立即加载脚本(保证副作用执行,如 $.admin.xxx 注册)
140
150
  for (let i = 0; i < this.list.length; i++) {
141
151
  var cg = this.list[i];
142
- if (cg.state) {
152
+ if (cg.state && !cg._loaded) {
143
153
  this._loadScript(cg);
154
+ cg._loaded = true;
155
+ }
156
+ }
157
+ };
158
+
159
+ /**
160
+ * 查找配置索引
161
+ * @param {string} name 模块名称
162
+ * @returns {number} 索引位置, 未找到返回 -1
163
+ */
164
+ Com.prototype._findIndex = function (name) {
165
+ for (var i = 0; i < this.list.length; i++) {
166
+ if (this.list[i].name === name) {
167
+ return i;
168
+ }
169
+ }
170
+ return -1;
171
+ };
172
+
173
+ /**
174
+ * 查找配置
175
+ * @param {string} name 模块名称
176
+ * @returns {object|null} 配置信息
177
+ */
178
+ Com.prototype._findConfig = function (name) {
179
+ var idx = this._findIndex(name);
180
+ return idx >= 0 ? this.list[idx] : null;
181
+ };
182
+
183
+ /**
184
+ * 定义懒加载属性
185
+ * @param {object} cg 配置信息
186
+ */
187
+ Com.prototype._defineLazy = function (cg) {
188
+ var self = this;
189
+ var name = cg.name;
190
+ var key = '_' + name;
191
+ Object.defineProperty(this, name, {
192
+ get: function () {
193
+ if (self[key] === undefined) {
194
+ var mod = self._loadScript(cg);
195
+ if (mod !== undefined && mod !== null) {
196
+ self[key] = mod;
197
+ }
198
+ }
199
+ return self[key];
200
+ },
201
+ set: function (val) {
202
+ self[key] = val;
203
+ },
204
+ configurable: true,
205
+ enumerable: true
206
+ });
207
+ };
208
+
209
+ /**
210
+ * 预加载核心模块
211
+ * @param {Array<string>} names 模块名称列表
212
+ */
213
+ Com.prototype.loadCore = function (names) {
214
+ if (!names || !names.length) {
215
+ return;
216
+ }
217
+ for (var i = 0; i < names.length; i++) {
218
+ var name = names[i];
219
+ var cg = this._findConfig(name);
220
+ if (cg && cg.state) {
221
+ var val = this[name];
222
+ if (val === undefined || val === null) {
223
+ $.log.error('核心模块加载失败:', name);
224
+ }
144
225
  }
145
226
  }
146
227
  };
@@ -2,17 +2,11 @@
2
2
  * 中间件
3
3
  */
4
4
  module.exports = {
5
- /**
6
- * 中间件初始化
7
- * @param {object} adapter 适配器
8
- * @param {object} eventer 事件处理器
9
- */
10
- async _init(adapter, eventer) {
11
- var event = $.admin.event('api', 'API事件');
12
- // await event.call('update', 'app/');
13
- await event.do('init');
5
+ async _init(adapter) {
6
+ var event = $.admin.event('api');
7
+ await event.do('load');
14
8
  await event.runAll('load');
15
- event.runAll('init');
9
+ await event.runAll('init');
16
10
  },
17
11
  /**
18
12
  * 主要逻辑
@@ -29,4 +23,4 @@ module.exports = {
29
23
  }
30
24
  }
31
25
  }
32
- };
26
+ };
@@ -13,7 +13,7 @@ module.exports = {
13
13
  * 初始化
14
14
  * @param {object} adapter 适配器集合
15
15
  */
16
- init(adapter) {
16
+ _init(adapter) {
17
17
  // 参数校验
18
18
  if (typeof adapter !== 'object') {
19
19
  throw new TypeError('参数类型错误');
@@ -4,7 +4,7 @@ module.exports = {
4
4
  * 初始化
5
5
  * @param {object} adapter 适配器对象
6
6
  */
7
- init(adapter) {
7
+ _init(adapter) {
8
8
  // 获取web服务
9
9
  // var web = adapter.web;
10
10
 
@@ -1,119 +1,131 @@
1
- // 导出错误处理中间件
2
- module.exports = {
3
- /**
4
- * 初始化
5
- * @param {object} adapter 适配器对象
6
- */
7
- init(adapter) {
8
- // 获取配置
9
- this.config = { ...this.config, ...adapter.web.config};
10
- },
11
-
12
- /**
13
- * 获取错误消息
14
- * @private
15
- * @param {object} config 配置对象
16
- * @param {number} status 状态码
17
- * @returns {string} 错误消息
18
- */
19
- _getErrorMessage(config, status) {
20
- if (config.error_codes && config.error_codes[status]) {
21
- return config.error_codes[status];
22
- }
23
- return config.default_message || 'Internal Server Error';
24
- },
25
-
26
- /**
27
- * 格式化错误信息
28
- * @private
29
- * @param {object} config 配置对象
30
- * @param {Error} err 错误对象
31
- * @returns {object} 格式化后的错误信息
32
- */
33
- _formatError(config, err) {
34
- let errorInfo = {
35
- message: err.message,
36
- status: err.status || err.statusCode || config.default_status,
37
- stack: err.stack
38
- };
39
-
40
- if (err.code) {
41
- errorInfo.code = err.code;
42
- }
43
-
44
- if (err.details) {
45
- errorInfo.details = err.details;
46
- }
47
-
48
- if (err.name) {
49
- errorInfo.name = err.name;
50
- }
51
-
52
- return errorInfo;
53
- },
54
-
55
- /**
56
- * 处理错误
57
- * @private
58
- * @param {object} ctx Koa上下文
59
- * @param {Error} err 错误对象
60
- */
61
- async _handleError(ctx, err) {
62
- // 记录错误日志到控制台
63
- let error_info = this._formatError(this.config, err);
64
- this.log('error', `Error occurred: ${err.message}`, error_info);
65
-
66
- // 设置响应状态码
67
- let status = err.status || err.status_code || this.config.default_status;
68
-
69
- // 特殊错误处理:文件不存在错误返回404
70
- if (err.code === 'ENOENT') {
71
- status = 404;
72
- }
73
-
74
- ctx.status = status;
75
-
76
- let message = err.message || this._getErrorMessage(this.config, status);
77
- let error_response = $.ret.error(status, message);
78
-
79
- // 如果配置允许,暴露堆栈信息(仅在开发环境使用)
80
- if (this.config.expose_trace && err.stack) {
81
- error_response.trace = err.stack;
82
- }
83
-
84
- // 添加额外的错误信息
85
- if (err.code) {
86
- error_response.error_code = err.code;
87
- }
88
-
89
- if (err.details) {
90
- error_response.details = err.details;
91
- }
92
-
93
- // 设置响应体
94
- ctx.body = error_response;
95
-
96
- // 设置响应头
97
- ctx.set('Content-Type', 'application/json');
98
- },
99
-
100
- /**
101
- * 中间件主方法
102
- * @param {object} ctx Koa上下文
103
- * @param {Function} next 下一个中间件
104
- * @returns {Promise<void>}
105
- */
106
- async main(ctx, next) {
107
- try {
108
- await next();
109
-
110
- // 处理404错误
111
- if (ctx.status === 404 && !ctx.body) {
112
- ctx.status = 404;
113
- ctx.body = $.ret.error(404, 'Not Found');
114
- }
115
- } catch (error) {
116
- await this._handleError(ctx, error);
117
- }
118
- }
119
- };
1
+ // 导出错误处理中间件
2
+ module.exports = {
3
+ /**
4
+ * 初始化
5
+ * @param {object} adapter 适配器对象
6
+ */
7
+ _init(adapter) {
8
+ // 获取配置
9
+ this.config = { ...this.config, ...adapter.web.config };
10
+ },
11
+
12
+ /**
13
+ * 获取错误消息
14
+ * @private
15
+ * @param {object} config 配置对象
16
+ * @param {number} status 状态码
17
+ * @returns {string} 错误消息
18
+ */
19
+ _getErrorMessage(config, status) {
20
+ if (config.error_codes && config.error_codes[status]) {
21
+ return config.error_codes[status];
22
+ }
23
+ return config.default_message || "Internal Server Error";
24
+ },
25
+
26
+ /**
27
+ * 格式化错误信息
28
+ * @private
29
+ * @param {object} config 配置对象
30
+ * @param {Error} err 错误对象
31
+ * @returns {object} 格式化后的错误信息
32
+ */
33
+ _formatError(config, err) {
34
+ let errorInfo = {
35
+ message: err.message,
36
+ status: err.status || err.statusCode || config.default_status,
37
+ stack: err.stack,
38
+ };
39
+
40
+ if (err.code) {
41
+ errorInfo.code = err.code;
42
+ }
43
+
44
+ if (err.details) {
45
+ errorInfo.details = err.details;
46
+ }
47
+
48
+ if (err.name) {
49
+ errorInfo.name = err.name;
50
+ }
51
+
52
+ return errorInfo;
53
+ },
54
+
55
+ /**
56
+ * 处理错误
57
+ * @private
58
+ * @param {object} ctx Koa上下文
59
+ * @param {Error} err 错误对象
60
+ */
61
+ async _handleError(ctx, err) {
62
+ // 记录错误日志到控制台
63
+ let error_info = this._formatError(this.config, err);
64
+ this.log("error", `Error occurred: ${err.message}`, error_info);
65
+
66
+ // 设置响应状态码
67
+ let status = err.status || err.status_code || this.config.default_status;
68
+
69
+ // 特殊错误处理:文件不存在错误返回404
70
+ if (err.code === "ENOENT") {
71
+ status = 404;
72
+ }
73
+
74
+ ctx.status = status;
75
+
76
+ let message = err.message || this._getErrorMessage(this.config, status);
77
+ let error_response = $.ret.error(status, message);
78
+
79
+ // 如果配置允许,暴露堆栈信息(仅在开发环境使用)
80
+ if (this.config.expose_trace && err.stack) {
81
+ error_response.trace = err.stack;
82
+ }
83
+
84
+ // 添加额外的错误信息
85
+ if (err.code) {
86
+ error_response.error_code = err.code;
87
+ }
88
+
89
+ if (err.details) {
90
+ error_response.details = err.details;
91
+ }
92
+
93
+ // 设置响应体
94
+ ctx.body = error_response;
95
+
96
+ // 设置响应头
97
+ ctx.set("Content-Type", "application/json");
98
+ },
99
+
100
+ /**
101
+ * 中间件主方法
102
+ * @param {object} ctx Koa上下文
103
+ * @param {Function} next 下一个中间件
104
+ * @returns {Promise<void>}
105
+ */
106
+ async main(ctx, next) {
107
+ // 监听响应流错误,避免客户端断开导致 ERR_STREAM_PREMATURE_CLOSE 未捕获
108
+ ctx.res.on("error", (err) => {
109
+ if (
110
+ err.code === "ERR_STREAM_PREMATURE_CLOSE" ||
111
+ err.code === "ECONNRESET"
112
+ ) {
113
+ // 客户端断开连接属于正常行为,静默处理
114
+ return;
115
+ }
116
+ this.log("error", "响应流错误: " + err.message);
117
+ });
118
+
119
+ try {
120
+ await next();
121
+
122
+ // 处理404错误
123
+ if (ctx.status === 404 && !ctx.body) {
124
+ ctx.status = 404;
125
+ ctx.body = $.ret.error(404, "Not Found");
126
+ }
127
+ } catch (error) {
128
+ await this._handleError(ctx, error);
129
+ }
130
+ },
131
+ };
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "web_error",
3
- "description": "错误处理中间件",
3
+ "title": "错误处理中间件",
4
+ "description": "统一处理Web请求中的错误",
4
5
  "main": "index.js",
5
6
  "type": "web",
6
7
  "state": 1,
@@ -4,7 +4,7 @@ module.exports = {
4
4
  * 初始化
5
5
  * @param {object} adapter 适配器集合
6
6
  */
7
- init(adapter) {
7
+ _init(adapter) {
8
8
  // 获取web服务
9
9
  var web = adapter.web;
10
10
 
@@ -17,6 +17,8 @@ module.exports = {
17
17
  if (ret) {
18
18
  ctx.body = ret;
19
19
  }
20
+ // 已有处理结果,终止中间件链,避免后续中间件覆盖
21
+ return;
20
22
  }
21
23
  }
22
24
  await next();
@@ -16,7 +16,7 @@ module.exports = {
16
16
  * @param {object} eventer 事件管理器
17
17
  * @param {object} logger 日志管理器
18
18
  */
19
- init(adapter, eventer, logger) {
19
+ _init(adapter, eventer, logger) {
20
20
  // 获取web服务
21
21
  var web = adapter.web;
22
22
  let config = web.config.static || {};
@@ -26,7 +26,7 @@ module.exports = {
26
26
  this._setupMultiStatic(web, cg);
27
27
  this._setupGlobalStatic(web);
28
28
  } else {
29
- console.log('未找到静态文件配置');
29
+ console.warn('未找到静态文件配置');
30
30
  }
31
31
  },
32
32
  /**
@@ -8,7 +8,7 @@ module.exports = {
8
8
  * 初始化
9
9
  * @param {object} adapter 适配器集合
10
10
  */
11
- init(adapter) {
11
+ _init(adapter) {
12
12
  // 获取web服务
13
13
  var web = adapter.web;
14
14
 
@@ -8,7 +8,7 @@
8
8
  // 版本号
9
9
  "version": "${version || '1.0.0'}",
10
10
  // 作者
11
- "author": "${author || 'mos'}",
11
+ "author": "${author || 'qww'}",
12
12
  // 主文件
13
13
  "main": "${main || 'index.js'}",
14
14
  // 作用域,决定加载到什么区域(server/client/both)
@@ -44,9 +44,9 @@
44
44
  // 数据库用户名
45
45
  "username": "root",
46
46
  // 数据库密码
47
- "password": "Asd159357",
47
+ "password": "your_db_password_here",
48
48
  // 数据库名称
49
- "database": "mos"
49
+ "database": "mm"
50
50
  }
51
51
  },
52
52
  // 缓存配置 - 可以没有,没有则使用默认缓存
@@ -59,7 +59,7 @@
59
59
  // 缓存端口
60
60
  "port": 6379,
61
61
  // 缓存密码
62
- "password": "asd159357",
62
+ "password": "your_redis_password_here",
63
63
  // 缓存数据库
64
64
  "database": 0
65
65
  }