mm_vars 1.0.0 → 1.1.0

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/README.md CHANGED
@@ -19,12 +19,12 @@ npm install mm_vars
19
19
  const { Vars, varsAdmin } = require('mm_vars');
20
20
 
21
21
  // 直接使用存储类
22
- const vars = new Vars('./data/vars.json');
22
+ const vars = new Vars({ file: './data/vars.json' });
23
23
  vars.set('step', 1).set('state', 'busy');
24
24
  vars.save();
25
25
 
26
26
  // 通过管理器按作用域获取实例(相同作用域返回同一实例)
27
- const scoped = varsAdmin('app', './data/app_vars.json');
27
+ const scoped = varsAdmin('app', { file: './data/app_vars.json' });
28
28
  scoped.set('count', 10);
29
29
  ```
30
30
 
@@ -41,7 +41,7 @@ scoped.set('count', 10);
41
41
  | load | 从持久化文件加载 | - | boolean |
42
42
 
43
43
  ## 依赖
44
- - mm_corejs:提供 Admin 管理器
44
+ - mm_admin:提供 Admin 管理器
45
45
 
46
46
  ## 许可证
47
47
  ISC
@@ -0,0 +1,49 @@
1
+ /**
2
+ * mm_vars 变量存储示例
3
+ * 演示 varsAdmin() 作用域工厂,以及 Vars 类可随时修改、
4
+ * 删除的键值变量存取与 JSON 文件持久化(save / load)。
5
+ * 运行:node example/index.js
6
+ */
7
+ const fs = require('fs');
8
+ const os = require('os');
9
+ const path = require('path');
10
+ const { Vars, varsAdmin } = require('../index.js');
11
+
12
+ /** 示例临时目录 */
13
+ const TMP_DIR = fs.mkdtempSync(path.join(os.tmpdir(), 'mm-vars-example-'));
14
+
15
+ /**
16
+ * 主流程
17
+ */
18
+ function main() {
19
+ // 方式1:作用域工厂,获取 os 作用域的变量存储实例
20
+ const store = varsAdmin('os');
21
+ store.set('token', 'abc123');
22
+ console.log('工厂实例读取 token:', store.get('token'));
23
+
24
+ // 方式2:类实例 + 文件持久化
25
+ const file = path.join(TMP_DIR, 'vars.json');
26
+ const vars = new Vars({ file });
27
+ vars.set('name', 'demo').set('count', 1);
28
+ console.log('变量列表:', vars.list());
29
+ console.log('保存到文件:', vars.save());
30
+
31
+ // 变量可随时修改
32
+ vars.set('count', 2);
33
+ console.log('修改后 count:', vars.get('count'));
34
+
35
+ // 变量可删除
36
+ console.log('删除 name:', vars.del('name'));
37
+ console.log('删除后列表:', vars.list());
38
+
39
+ // 从文件重新加载(文件里是保存时的数据)
40
+ const loaded = new Vars({ file });
41
+ loaded.load();
42
+ console.log('重新加载后 name:', loaded.get('name'));
43
+ console.log('重新加载后 count:', loaded.get('count'));
44
+
45
+ // 清理临时目录
46
+ fs.rmSync(TMP_DIR, { recursive: true, force: true });
47
+ }
48
+
49
+ main();
package/index.js CHANGED
@@ -1,7 +1,7 @@
1
- const Admin = require('mm_corejs').Admin;
1
+ const { reg } = require('mm_admin');
2
2
  const Vars = require('./lib/vars.js');
3
3
 
4
- let admin = new Admin();
4
+ const admin = reg('vars');
5
5
  admin.setClass(Vars);
6
6
 
7
7
  module.exports = {
@@ -14,9 +14,17 @@ module.exports = {
14
14
  * @returns {Vars} 变量存储实例
15
15
  */
16
16
  varsAdmin(scope, config) {
17
- if (!scope) {
18
- scope = 'os';
19
- }
20
- return admin.get(scope, config);
17
+ return admin.get(scope || 'os', config);
18
+ },
19
+ /**
20
+ * 获取缺省变量存储实例
21
+ * @returns {Vars} 变量存储实例
22
+ */
23
+ getVars() {
24
+ return admin.get('os');
21
25
  }
22
26
  };
27
+
28
+ /* mm-tool-logic-export 工具能力层:其它模块可 require("<pkg>").tools.<name> 直接引用 */
29
+ Object.defineProperty(module.exports, 'tools', { enumerable: true, configurable: true,
30
+ get: function () { return require('./lib/tools'); } });
package/jest.config.js ADDED
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Jest 测试配置
5
+ */
6
+ module.exports = {
7
+ testEnvironment: 'node',
8
+ testMatch: ['<rootDir>/test/**/*.test.js'],
9
+ collectCoverageFrom: ['lib/**/*.js', 'index.js'],
10
+ coverageThreshold: {
11
+ global: {
12
+ branches: 100,
13
+ functions: 100,
14
+ lines: 100,
15
+ statements: 100
16
+ }
17
+ }
18
+ };
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ /** 模块能力层:懒加载工具实现,避免模块入口被 require 时加载全部实现 */
5
+ module.exports = new Proxy({}, {
6
+ get(_t, key) {
7
+ if (typeof key !== 'string') return undefined;
8
+ if (!fs.existsSync(path.join(__dirname, key, 'index.js'))) return undefined;
9
+ return require('./' + key);
10
+ },
11
+ has(_t, key) {
12
+ return typeof key === 'string' && fs.existsSync(path.join(__dirname, key, 'index.js'));
13
+ },
14
+ ownKeys() { return fs.readdirSync(__dirname, { withFileTypes: true }).filter(e => e.isDirectory()).map(e => e.name); },
15
+ getOwnPropertyDescriptor(_t, key) { return this.has(_t, key) ? { enumerable: true, configurable: true } : undefined; }
16
+ });
@@ -0,0 +1,73 @@
1
+ /**
2
+ * 变量管理器
3
+ * 运行时 key-value 变量存储,支持读取/写入/删除/自增/条件判断
4
+ * 可作为工作流间的轻量状态共享层
5
+ */
6
+ var _variables = {};
7
+
8
+ async function main(params, ctx, options) {
9
+ var action = params.action || 'get';
10
+ var key = params.key;
11
+ var value = params.value;
12
+ var namespace = params.namespace || 'global';
13
+
14
+ var store = _getStore(namespace);
15
+
16
+ if (!key && action !== 'list' && action !== 'reset') {
17
+ ctx.output = { error: { code: 'MGR_MISSING_PARAM', message: '缺少 key 参数' } };
18
+ return ctx.output;
19
+ }
20
+
21
+ switch (action) {
22
+ case 'get':
23
+ ctx.output = { obj: store[key], key: key, namespace: namespace, exists: key in store };
24
+ break;
25
+ case 'set':
26
+ store[key] = value;
27
+ ctx.output = { msg: '变量设置成功', key: key, namespace: namespace };
28
+ break;
29
+ case 'delete':
30
+ delete store[key];
31
+ ctx.output = { msg: '变量删除成功', key: key, namespace: namespace };
32
+ break;
33
+ case 'increment':
34
+ if (typeof store[key] !== 'number') store[key] = 0;
35
+ store[key] += params.delta || 1;
36
+ ctx.output = { msg: '自增成功', key: key, value: store[key], namespace: namespace };
37
+ break;
38
+ case 'decrement':
39
+ if (typeof store[key] !== 'number') store[key] = 0;
40
+ store[key] -= params.delta || 1;
41
+ ctx.output = { msg: '自减成功', key: key, value: store[key], namespace: namespace };
42
+ break;
43
+ case 'toggle':
44
+ store[key] = !store[key];
45
+ ctx.output = { msg: '切换成功', key: key, value: store[key], namespace: namespace };
46
+ break;
47
+ case 'exists':
48
+ ctx.output = { obj: key in store, key: key, namespace: namespace };
49
+ break;
50
+ case 'list':
51
+ ctx.output = {
52
+ list: Object.keys(store),
53
+ count: Object.keys(store).length,
54
+ namespace: namespace
55
+ };
56
+ break;
57
+ case 'reset':
58
+ _variables[namespace] = {};
59
+ ctx.output = { msg: '命名空间已重置', namespace: namespace };
60
+ break;
61
+ default:
62
+ ctx.output = { error: { code: 'MGR_UNKNOWN_ACTION', message: '不支持的操作: ' + action } };
63
+ }
64
+
65
+ return ctx.output;
66
+ }
67
+
68
+ function _getStore(namespace) {
69
+ if (!_variables[namespace]) _variables[namespace] = {};
70
+ return _variables[namespace];
71
+ }
72
+
73
+ module.exports = { main };
package/lib/vars.js CHANGED
@@ -1,4 +1,4 @@
1
- const KvStore = require('mm_corejs').KvStore;
1
+ const KvStore = require('mm_kv_store').KvStore;
2
2
 
3
3
  /**
4
4
  * 变量存储类,可随时修改和删除
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "mm_vars",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "变量存储模块:用于存储可随时修改和删除的键值变量",
5
5
  "main": "index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://gitee.com/qiuwenwu91/mm_vars.git"
9
+ },
6
10
  "keywords": [
7
11
  "mm_mod",
8
12
  "mm_infra",
@@ -11,15 +15,16 @@
11
15
  "变量",
12
16
  "存储"
13
17
  ],
14
- "layer": "infra",
15
- "group": "data",
18
+ "layer": "infrastructure",
19
+ "group": "state",
16
20
  "author": "邱文武",
17
21
  "license": "ISC",
18
22
  "scripts": {
19
23
  "test": "jest --coverage"
20
24
  },
21
25
  "dependencies": {
22
- "mm_corejs": "^1.1.4"
26
+ "mm_admin": "^1.1.0",
27
+ "mm_kv_store": "^1.0.0"
23
28
  },
24
29
  "devDependencies": {
25
30
  "jest": "^30.5.2"
package/test/vars.test.js CHANGED
@@ -21,6 +21,10 @@ describe('mm_vars 模块入口', () => {
21
21
  it('varsAdmin 缺省作用域为 os', () => {
22
22
  expect(mod.varsAdmin()).toBeInstanceOf(Vars);
23
23
  });
24
+
25
+ it('getVars 返回 os 作用域的实例', () => {
26
+ expect(mod.getVars()).toBe(mod.varsAdmin());
27
+ });
24
28
  });
25
29
 
26
30
  describe('Vars', () => {
@@ -37,14 +41,14 @@ describe('Vars', () => {
37
41
  describe('构造', () => {
38
42
  it('默认不传文件路径时 file 为空字符串', () => {
39
43
  const vars = new Vars();
40
- expect(vars._file).toBe('');
44
+ expect(vars.config.file).toBe('');
41
45
  expect(vars.list()).toEqual({});
42
46
  });
43
47
 
44
48
  it('传入文件路径时保存路径', () => {
45
49
  const file = path.join(tmp_dir, 'vars.json');
46
- const vars = new Vars(file);
47
- expect(vars._file).toBe(file);
50
+ const vars = new Vars({ file });
51
+ expect(vars.config.file).toBe(file);
48
52
  });
49
53
  });
50
54
 
@@ -141,7 +145,7 @@ describe('Vars', () => {
141
145
 
142
146
  it('save 写入文件返回 true', () => {
143
147
  const file = path.join(tmp_dir, 'vars.json');
144
- const vars = new Vars(file);
148
+ const vars = new Vars({ file });
145
149
  vars.set('a', 1);
146
150
  expect(vars.save()).toBe(true);
147
151
  expect(JSON.parse(fs.readFileSync(file, 'utf8'))).toEqual({ a: 1 });
@@ -153,14 +157,14 @@ describe('Vars', () => {
153
157
  });
154
158
 
155
159
  it('文件不存在时 load 返回 false', () => {
156
- const vars = new Vars(path.join(tmp_dir, 'nope.json'));
160
+ const vars = new Vars({ file: path.join(tmp_dir, 'nope.json') });
157
161
  expect(vars.load()).toBe(false);
158
162
  });
159
163
 
160
164
  it('文件存在时 load 加载数据返回 true', () => {
161
165
  const file = path.join(tmp_dir, 'vars.json');
162
166
  fs.writeFileSync(file, JSON.stringify({ a: 1, b: 'x' }));
163
- const vars = new Vars(file);
167
+ const vars = new Vars({ file });
164
168
  expect(vars.load()).toBe(true);
165
169
  expect(vars.get('a')).toBe(1);
166
170
  expect(vars.get('b')).toBe('x');
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+ /**
3
+ * variables —— 工具契约适配层
4
+ * 业务实现归位于模块 lib/tools/variables/,本文件只把模块能力暴露给加载器。
5
+ * 其它模块可直接 require('mm_vars').tools.variables 复用。
6
+ */
7
+ module.exports = require('../../lib/tools/variables');
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "variables",
3
+ "handler": "manager",
4
+ "title": "变量管理器",
5
+ "description": "运行时键值存储,支持读写、增减、切换与重置。适用场景:流程间传递状态、计数或开关时。工作流提示:action 选 get/set/delete/increment/decrement 等,namespace 隔离(默认 global),set 配 value、增减 delta,读在 obj/list、写在 msg。",
6
+ "type": "core",
7
+ "params": {
8
+ "type": "object",
9
+ "properties": {
10
+ "action": {
11
+ "type": "string",
12
+ "description": "操作: get/set/delete/increment/decrement/toggle/exists/list/reset",
13
+ "default": "get",
14
+ "enum": [
15
+ "get",
16
+ "set",
17
+ "delete",
18
+ "increment",
19
+ "decrement",
20
+ "toggle",
21
+ "exists",
22
+ "list",
23
+ "reset"
24
+ ]
25
+ },
26
+ "key": {
27
+ "type": "string",
28
+ "description": "变量名"
29
+ },
30
+ "value": {
31
+ "description": "变量值(set 模式)"
32
+ },
33
+ "namespace": {
34
+ "type": "string",
35
+ "description": "命名空间(隔离不同场景的变量)",
36
+ "default": "global"
37
+ },
38
+ "delta": {
39
+ "type": "number",
40
+ "description": "增量值(increment/decrement 模式)",
41
+ "default": 1
42
+ }
43
+ }
44
+ },
45
+ "returns": {
46
+ "description": "管理操作结果,读操作返回 obj 或 list+count,写操作返回 msg,异常时返回 error",
47
+ "type": "object",
48
+ "properties": {
49
+ "obj": {
50
+ "description": "读取操作的单条结果(get/exists 操作)"
51
+ },
52
+ "list": {
53
+ "type": "array",
54
+ "description": "变量名列表(list 操作)"
55
+ },
56
+ "count": {
57
+ "type": "number",
58
+ "description": "变量数量(list 操作)"
59
+ },
60
+ "msg": {
61
+ "type": "string",
62
+ "description": "写操作结果描述(set/delete/increment/decrement/toggle/reset 操作)"
63
+ }
64
+ }
65
+ },
66
+ "options": {},
67
+ "group": "state"
68
+ }