mm_config 2.1.3 → 2.1.5
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 +284 -194
- package/index.js +337 -185
- package/package.json +3 -3
- package/test.js +132 -65
- package/base.js +0 -30
- package/config.json +0 -6
package/README.md
CHANGED
|
@@ -1,194 +1,284 @@
|
|
|
1
|
-
# mm_config
|
|
2
|
-
|
|
3
|
-
超级美眉配置帮助类,动态同步文件修改配置。
|
|
4
|
-
|
|
5
|
-
## 功能特点
|
|
6
|
-
|
|
7
|
-
- 支持配置文件的动态读取和修改
|
|
8
|
-
- 修改配置后自动同步保存到JSON文件
|
|
9
|
-
- 使用Proxy实现属性监听,操作方便
|
|
10
|
-
- 支持同步和异步API操作
|
|
11
|
-
- 支持配置修改防抖功能,减少频繁保存
|
|
12
|
-
- 内置错误处理机制,提高稳定性
|
|
13
|
-
- 支持JSON5格式配置文件
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
*
|
|
44
|
-
* @param {
|
|
45
|
-
* @
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
1
|
+
# mm_config
|
|
2
|
+
|
|
3
|
+
超级美眉配置帮助类,动态同步文件修改配置。
|
|
4
|
+
|
|
5
|
+
## 功能特点
|
|
6
|
+
|
|
7
|
+
- 支持配置文件的动态读取和修改
|
|
8
|
+
- 修改配置后自动同步保存到JSON文件
|
|
9
|
+
- 使用Proxy实现属性监听,操作方便
|
|
10
|
+
- 支持同步和异步API操作
|
|
11
|
+
- 支持配置修改防抖功能,减少频繁保存
|
|
12
|
+
- 内置错误处理机制,提高稳定性
|
|
13
|
+
- 支持JSON5格式配置文件
|
|
14
|
+
- 简洁命名,遵循单字优先原则
|
|
15
|
+
- 内置缓存管理,避免重复创建配置实例
|
|
16
|
+
|
|
17
|
+
## 安装
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install mm_config
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## API说明
|
|
24
|
+
|
|
25
|
+
### 导入模块
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
// 导入配置类
|
|
29
|
+
const { Config, create, createAsync, clear, clearAll } = require('mm_config');
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 配置初始化
|
|
33
|
+
|
|
34
|
+
#### 同步API
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
/**
|
|
38
|
+
* 创建同步配置
|
|
39
|
+
* @param {String} file - 配置文件路径
|
|
40
|
+
* @param {Object} config - 配置对象,可选
|
|
41
|
+
* @param {Object} options - 配置选项,可选
|
|
42
|
+
* @param {Number} options.debounce_time - 防抖时间(ms),默认0
|
|
43
|
+
* @param {Boolean} options.pretty - 是否美化输出,默认true
|
|
44
|
+
* @param {String} options.format - 格式(json/json5),默认json
|
|
45
|
+
* @returns {Proxy} 返回配置代理对象
|
|
46
|
+
*/
|
|
47
|
+
const config = create(file, config, options);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### 异步API
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
/**
|
|
54
|
+
* 创建异步配置
|
|
55
|
+
* @param {String} file - 配置文件路径
|
|
56
|
+
* @param {Object} config - 配置对象,可选
|
|
57
|
+
* @param {Object} options - 配置选项,可选
|
|
58
|
+
* @returns {Promise<Proxy>} 返回配置代理对象的Promise
|
|
59
|
+
*/
|
|
60
|
+
const config = await createAsync(file, config, options);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### 缓存管理API
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
/**
|
|
67
|
+
* 清理指定文件配置缓存
|
|
68
|
+
* @param {String} file - 配置文件路径
|
|
69
|
+
*/
|
|
70
|
+
clear(file);
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 清理所有配置缓存
|
|
74
|
+
*/
|
|
75
|
+
clearAll();
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### 代理对象特殊方法
|
|
79
|
+
|
|
80
|
+
通过代理对象可以访问以下特殊方法:
|
|
81
|
+
|
|
82
|
+
- `_saveSync()`: 同步保存配置到文件
|
|
83
|
+
- `_saveAsync()`: 异步保存配置到文件
|
|
84
|
+
- `_raw`: 获取原始配置对象
|
|
85
|
+
|
|
86
|
+
## 使用示例
|
|
87
|
+
|
|
88
|
+
### 1. 基本同步配置
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
const { create } = require('mm_config');
|
|
92
|
+
|
|
93
|
+
// 创建配置并指定保存路径
|
|
94
|
+
const config = create("./config.json", {
|
|
95
|
+
name: "demo",
|
|
96
|
+
state: 1
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// 修改配置会自动保存到文件
|
|
100
|
+
config.name = "test";
|
|
101
|
+
config.sort = 2;
|
|
102
|
+
|
|
103
|
+
// 显式调用保存
|
|
104
|
+
config._saveSync();
|
|
105
|
+
|
|
106
|
+
// 读取现有配置
|
|
107
|
+
const existingConfig = create("./config.json");
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 2. 使用异步API
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
const { createAsync } = require('mm_config');
|
|
114
|
+
|
|
115
|
+
async function setupConfig() {
|
|
116
|
+
// 创建异步配置
|
|
117
|
+
const config = await createAsync("./async_config.json", {
|
|
118
|
+
name: "asyncDemo",
|
|
119
|
+
version: "1.0.0"
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// 修改配置会异步自动保存
|
|
123
|
+
config.timestamp = new Date().toISOString();
|
|
124
|
+
|
|
125
|
+
// 显式调用异步保存
|
|
126
|
+
await config._saveAsync();
|
|
127
|
+
|
|
128
|
+
return config;
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 3. 使用防抖功能
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
const { create } = require('mm_config');
|
|
136
|
+
|
|
137
|
+
// 创建带防抖的配置(500ms延迟保存)
|
|
138
|
+
const config = create("./debounce_config.json", {
|
|
139
|
+
name: "debounceDemo"
|
|
140
|
+
}, {
|
|
141
|
+
debounce_time: 500 // 500ms防抖时间
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// 快速多次修改,只会在最后一次修改后500ms保存一次
|
|
145
|
+
for (let i = 0; i < 10; i++) {
|
|
146
|
+
config.counter = i;
|
|
147
|
+
config.timestamp = new Date().toISOString();
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 4. 使用JSON5格式
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
const { create } = require('mm_config');
|
|
155
|
+
|
|
156
|
+
// 创建支持JSON5格式的配置
|
|
157
|
+
const config = create("./config.json5", null, {
|
|
158
|
+
format: 'json5'
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// JSON5格式支持注释、尾随逗号等特性
|
|
162
|
+
config.description = "This supports JSON5 format";
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 5. 直接使用Config类
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
const { Config } = require('mm_config');
|
|
169
|
+
|
|
170
|
+
// 创建配置实例
|
|
171
|
+
const cfg = new Config({
|
|
172
|
+
name: "directDemo"
|
|
173
|
+
}, "./direct_config.json");
|
|
174
|
+
|
|
175
|
+
// 获取代理对象
|
|
176
|
+
const config = cfg.getProxy();
|
|
177
|
+
|
|
178
|
+
// 使用配置
|
|
179
|
+
config.version = "1.0.0";
|
|
180
|
+
|
|
181
|
+
// 手动调用保存方法
|
|
182
|
+
cfg.saveSync();
|
|
183
|
+
await cfg.saveAsync();
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 6. 使用配置操作方法
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
const { Config } = require('mm_config');
|
|
190
|
+
|
|
191
|
+
const cfg = new Config({}, "./methods_config.json");
|
|
192
|
+
|
|
193
|
+
// 设置配置值
|
|
194
|
+
await cfg.set("name", "test");
|
|
195
|
+
|
|
196
|
+
// 获取配置值
|
|
197
|
+
const name = await cfg.get("name");
|
|
198
|
+
|
|
199
|
+
// 检查配置是否存在
|
|
200
|
+
const hasName = await cfg.has("name");
|
|
201
|
+
|
|
202
|
+
// 删除配置项
|
|
203
|
+
await cfg.del("name");
|
|
204
|
+
|
|
205
|
+
// 获取所有键
|
|
206
|
+
const keys = await cfg.keys();
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 7. 缓存管理功能
|
|
210
|
+
|
|
211
|
+
```javascript
|
|
212
|
+
const { create, clear, clearAll } = require('mm_config');
|
|
213
|
+
|
|
214
|
+
// 创建配置实例
|
|
215
|
+
const config1 = create("./cache1.json", { test: "cache1" });
|
|
216
|
+
const config2 = create("./cache2.json", { test: "cache2" });
|
|
217
|
+
|
|
218
|
+
// 清理指定文件缓存
|
|
219
|
+
clear("./cache1.json");
|
|
220
|
+
|
|
221
|
+
// 重新创建会生成新实例
|
|
222
|
+
const config1New = create("./cache1.json", { test: "cache1_new" });
|
|
223
|
+
|
|
224
|
+
// 清理所有缓存
|
|
225
|
+
clearAll();
|
|
226
|
+
|
|
227
|
+
// 所有配置都会重新创建
|
|
228
|
+
const config2New = create("./cache2.json", { test: "cache2_new" });
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## 配置选项
|
|
232
|
+
|
|
233
|
+
创建配置时可提供以下选项:
|
|
234
|
+
|
|
235
|
+
| 选项 | 类型 | 默认值 | 描述 |
|
|
236
|
+
|------|------|--------|------|
|
|
237
|
+
| debounce_time | Number | 0 | 防抖时间(毫秒),设置后多次修改会延迟保存 |
|
|
238
|
+
| pretty | Boolean | true | 是否美化JSON输出,设为false可生成压缩的JSON |
|
|
239
|
+
| format | String | 'json' | 配置文件格式,可选'json'或'json5' |
|
|
240
|
+
|
|
241
|
+
## 注意事项
|
|
242
|
+
|
|
243
|
+
1. 配置文件会自动创建和同步
|
|
244
|
+
2. 修改配置对象的属性会自动保存到文件
|
|
245
|
+
3. 确保有文件的写入权限
|
|
246
|
+
4. 使用防抖功能可以减少频繁的文件IO操作
|
|
247
|
+
5. 异步API适合在非阻塞环境中使用
|
|
248
|
+
6. 当使用JSON5格式时,保存仍使用标准JSON格式,但可读取JSON5格式的文件
|
|
249
|
+
7. 配置实例会被缓存,相同文件路径会返回同一实例,使用clear/clearAll可清理缓存
|
|
250
|
+
|
|
251
|
+
## 依赖
|
|
252
|
+
|
|
253
|
+
- json5: 用于解析JSON5格式
|
|
254
|
+
- mm_expand: 提供文件操作扩展
|
|
255
|
+
|
|
256
|
+
## 命名规范
|
|
257
|
+
|
|
258
|
+
本模块遵循简洁命名原则:
|
|
259
|
+
- 类名:`Config`(单字优先)
|
|
260
|
+
- 方法名:`get()`、`set()`、`has()`、`del()`(动词开头)
|
|
261
|
+
- 变量名:`val`、`key`、`bl`(简洁无废话)
|
|
262
|
+
|
|
263
|
+
## 测试
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
# 运行测试
|
|
267
|
+
npm test
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## 许可证
|
|
271
|
+
|
|
272
|
+
ISC License
|
|
273
|
+
|
|
274
|
+
## 版本历史
|
|
275
|
+
|
|
276
|
+
- v2.1.4: 添加缓存管理功能,修复内存泄漏问题
|
|
277
|
+
- v2.1.3: 重构API,遵循简洁命名规范
|
|
278
|
+
- v2.1.2: 添加JSON5格式支持
|
|
279
|
+
- v2.1.1: 优化防抖功能
|
|
280
|
+
- v2.1.0: 初始版本发布
|
|
281
|
+
|
|
282
|
+
## 贡献
|
|
283
|
+
|
|
284
|
+
欢迎提交Issue和Pull Request来改进这个项目。
|
package/index.js
CHANGED
|
@@ -1,199 +1,351 @@
|
|
|
1
|
-
require('
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
await this.writePromise;
|
|
62
|
-
|
|
63
|
-
this.writePromise = Promise.resolve()
|
|
64
|
-
.then(() => {
|
|
65
|
-
this.filePath.saveJson(this.config);
|
|
66
|
-
return true;
|
|
67
|
-
})
|
|
68
|
-
.catch(error => {
|
|
69
|
-
$.log.error(`[Config] Error saving config to ${this.filePath}:`, error.message);
|
|
70
|
-
return false;
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
return this.writePromise;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* 获取代理对象
|
|
78
|
-
* @returns {Proxy}
|
|
79
|
-
*/
|
|
80
|
-
getProxy() {
|
|
81
|
-
const self = this;
|
|
82
|
-
|
|
83
|
-
return new Proxy(this.config, {
|
|
84
|
-
set(obj, prop, value) {
|
|
85
|
-
obj[prop] = value;
|
|
86
|
-
|
|
87
|
-
if (self.options.debounceTime > 0) {
|
|
88
|
-
// 防抖处理
|
|
89
|
-
if (self.writeTimer) {
|
|
90
|
-
clearTimeout(self.writeTimer);
|
|
91
|
-
}
|
|
92
|
-
self.writeTimer = setTimeout(() => {
|
|
93
|
-
self.saveSync();
|
|
94
|
-
}, self.options.debounceTime);
|
|
95
|
-
} else {
|
|
96
|
-
// 无防抖,直接保存
|
|
97
|
-
self.saveSync();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return true;
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
get(obj, prop) {
|
|
104
|
-
// 提供一些特殊属性访问
|
|
105
|
-
if (prop === '_saveAsync') {
|
|
106
|
-
return () => self.saveAsync();
|
|
107
|
-
}
|
|
108
|
-
if (prop === '_saveSync') {
|
|
109
|
-
return () => self.saveSync();
|
|
110
|
-
}
|
|
111
|
-
if (prop === '_raw') {
|
|
112
|
-
return obj;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return obj[prop];
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* 获取异步代理对象
|
|
122
|
-
* @returns {Proxy}
|
|
123
|
-
*/
|
|
124
|
-
getAsyncProxy() {
|
|
125
|
-
const self = this;
|
|
126
|
-
|
|
127
|
-
return new Proxy(this.config, {
|
|
128
|
-
set(obj, prop, value) {
|
|
129
|
-
obj[prop] = value;
|
|
130
|
-
|
|
131
|
-
if (self.options.debounceTime > 0) {
|
|
132
|
-
if (self.writeTimer) {
|
|
133
|
-
clearTimeout(self.writeTimer);
|
|
134
|
-
}
|
|
135
|
-
self.writeTimer = setTimeout(() => {
|
|
136
|
-
self.saveAsync();
|
|
137
|
-
}, self.options.debounceTime);
|
|
138
|
-
} else {
|
|
139
|
-
self.saveAsync();
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return true;
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
get(obj, prop) {
|
|
146
|
-
if (prop === '_saveAsync') {
|
|
147
|
-
return () => self.saveAsync();
|
|
148
|
-
}
|
|
149
|
-
if (prop === '_saveSync') {
|
|
150
|
-
return () => self.saveSync();
|
|
151
|
-
}
|
|
152
|
-
if (prop === '_raw') {
|
|
153
|
-
return obj;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return obj[prop];
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
1
|
+
require('mm_expand');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 配置类
|
|
5
|
+
* @class
|
|
6
|
+
*/
|
|
7
|
+
class Config {
|
|
8
|
+
/**
|
|
9
|
+
* 创建配置实例
|
|
10
|
+
* @param {Object} options - 配置对象
|
|
11
|
+
* @param {String} file - 配置文件路径
|
|
12
|
+
* @param {Object} config - 配置选项
|
|
13
|
+
* @param {Number} config.debounce_time - 防抖时间(ms)
|
|
14
|
+
* @param {Boolean} config.pretty - 是否美化输出
|
|
15
|
+
* @param {String} config.format - 格式(json/json5)
|
|
16
|
+
* @throws {TypeError} 当options非对象时
|
|
17
|
+
* @throws {TypeError} 当file非字符串时
|
|
18
|
+
*/
|
|
19
|
+
constructor(options, file, config) {
|
|
20
|
+
// 参数校验
|
|
21
|
+
if (options && typeof options !== 'object') {
|
|
22
|
+
throw new TypeError('options must be an object');
|
|
23
|
+
}
|
|
24
|
+
if (file && typeof file !== 'string') {
|
|
25
|
+
throw new TypeError('file must be a string');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.config = {
|
|
29
|
+
debounce_time: 0, // 默认不防抖
|
|
30
|
+
pretty: true,
|
|
31
|
+
format: 'json'
|
|
32
|
+
};
|
|
33
|
+
this.options = {};
|
|
34
|
+
this._file = file;
|
|
35
|
+
this._conn = null;
|
|
36
|
+
this._timer = null;
|
|
37
|
+
this._promise = Promise.resolve();
|
|
38
|
+
|
|
39
|
+
// 如果没有提供配置且有文件路径,则从文件加载
|
|
40
|
+
if (!options && file) {
|
|
41
|
+
try {
|
|
42
|
+
this.options = file.loadJson();
|
|
43
|
+
} catch (err) {
|
|
44
|
+
$.log.error(`[options] Error loading options from ${file}:`, err.message);
|
|
45
|
+
this.options = {};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// 设置配置
|
|
49
|
+
this.setOptions(options);
|
|
50
|
+
// 设置配置
|
|
51
|
+
this.setConfig(config);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 设置配置
|
|
57
|
+
* @param {Object} config - 配置对象
|
|
58
|
+
*/
|
|
59
|
+
Config.prototype.setConfig = function (config) {
|
|
60
|
+
Object.assign(this.config, config);
|
|
160
61
|
}
|
|
161
62
|
|
|
162
63
|
/**
|
|
163
|
-
*
|
|
164
|
-
* @param {Object}
|
|
165
|
-
|
|
166
|
-
|
|
64
|
+
* 设置配置
|
|
65
|
+
* @param {Object} options - 配置对象
|
|
66
|
+
*/
|
|
67
|
+
Config.prototype.setOptions = function (options) {
|
|
68
|
+
$.push(this.options, options, true);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 初始化配置(连接文件)
|
|
73
|
+
* @param {Object} conn - 已连接的文件对象
|
|
74
|
+
* @returns {Promise} 连接结果
|
|
75
|
+
*/
|
|
76
|
+
Config.prototype.setup = async function (conn) {
|
|
77
|
+
if (conn) this._conn = conn;
|
|
78
|
+
return this._conn;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* 保存配置到文件(同步)
|
|
83
|
+
* @returns {Boolean} 保存是否成功
|
|
84
|
+
*/
|
|
85
|
+
Config.prototype.saveSync = function () {
|
|
86
|
+
if (!this._file) return false;
|
|
87
|
+
try {
|
|
88
|
+
this._file.saveJson(this.options);
|
|
89
|
+
return true;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
$.log.error(`[options] Error saving options to ${this._file}:`, err.message);
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 保存配置到文件(异步)
|
|
98
|
+
* @returns {Promise<Boolean>}
|
|
99
|
+
*/
|
|
100
|
+
Config.prototype.saveAsync = async function () {
|
|
101
|
+
if (!this._file) return Promise.resolve(true);
|
|
102
|
+
|
|
103
|
+
// 确保之前的写操作完成
|
|
104
|
+
await this._promise;
|
|
105
|
+
|
|
106
|
+
this._promise = Promise.resolve()
|
|
107
|
+
.then(() => {
|
|
108
|
+
this._file.saveJson(this.options);
|
|
109
|
+
return true;
|
|
110
|
+
})
|
|
111
|
+
.catch(err => {
|
|
112
|
+
$.log.error(`[options] Error saving options to ${this._file}:`, err.message);
|
|
113
|
+
return false;
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return this._promise;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 获取代理对象
|
|
121
|
+
* @returns {Proxy}
|
|
122
|
+
*/
|
|
123
|
+
Config.prototype.getProxy = function () {
|
|
124
|
+
var self = this;
|
|
125
|
+
|
|
126
|
+
return new Proxy(this.options, {
|
|
127
|
+
set(obj, prop, val) {
|
|
128
|
+
obj[prop] = val;
|
|
129
|
+
|
|
130
|
+
if (self.config.debounce_time > 0) {
|
|
131
|
+
// 防抖处理
|
|
132
|
+
if (self._timer) {
|
|
133
|
+
clearTimeout(self._timer);
|
|
134
|
+
}
|
|
135
|
+
self._timer = setTimeout(() => {
|
|
136
|
+
self.saveSync();
|
|
137
|
+
}, self.config.debounce_time);
|
|
138
|
+
} else {
|
|
139
|
+
// 无防抖,直接保存
|
|
140
|
+
self.saveSync();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return true;
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
get(obj, prop) {
|
|
147
|
+
// 提供一些特殊属性访问
|
|
148
|
+
if (prop === '_saveAsync') {
|
|
149
|
+
return () => self.saveAsync();
|
|
150
|
+
}
|
|
151
|
+
if (prop === '_saveSync') {
|
|
152
|
+
return () => self.saveSync();
|
|
153
|
+
}
|
|
154
|
+
if (prop === '_raw') {
|
|
155
|
+
return obj;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return obj[prop];
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* 获取异步代理对象
|
|
167
165
|
* @returns {Proxy}
|
|
168
166
|
*/
|
|
169
|
-
function
|
|
170
|
-
|
|
171
|
-
if (!_jsonFile && this && this.filename) {
|
|
172
|
-
_jsonFile = this.filename;
|
|
173
|
-
}
|
|
167
|
+
Config.prototype.getAsyncProxy = function () {
|
|
168
|
+
var self = this;
|
|
174
169
|
|
|
175
|
-
|
|
176
|
-
|
|
170
|
+
return new Proxy(this.options, {
|
|
171
|
+
set(obj, prop, val) {
|
|
172
|
+
obj[prop] = val;
|
|
173
|
+
|
|
174
|
+
if (self.config.debounce_time > 0) {
|
|
175
|
+
if (self._timer) {
|
|
176
|
+
clearTimeout(self._timer);
|
|
177
|
+
}
|
|
178
|
+
self._timer = setTimeout(() => {
|
|
179
|
+
self.saveAsync();
|
|
180
|
+
}, self.config.debounce_time);
|
|
181
|
+
} else {
|
|
182
|
+
self.saveAsync();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return true;
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
get(obj, prop) {
|
|
189
|
+
if (prop === '_saveAsync') {
|
|
190
|
+
return () => self.saveAsync();
|
|
191
|
+
}
|
|
192
|
+
if (prop === '_saveSync') {
|
|
193
|
+
return () => self.saveSync();
|
|
194
|
+
}
|
|
195
|
+
if (prop === '_raw') {
|
|
196
|
+
return obj;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return obj[prop];
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* 配置字典(私有)
|
|
206
|
+
* @type {Object}
|
|
207
|
+
*/
|
|
208
|
+
const dict = {};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 创建配置(同步)
|
|
212
|
+
* @param {String} file - 配置文件路径
|
|
213
|
+
* @param {Object} options - 配置对象
|
|
214
|
+
* @param {Object} config - 配置选项
|
|
215
|
+
* @returns {Proxy}
|
|
216
|
+
*/
|
|
217
|
+
function create(file, options = {}, config = {}) {
|
|
218
|
+
let f = file.fullname();
|
|
219
|
+
// 检查是否已存在配置
|
|
220
|
+
if (dict[f]) {
|
|
221
|
+
// $.log.warn(`[options] Config for file ${f} already exists.`);
|
|
222
|
+
return dict[f].getProxy();
|
|
223
|
+
}
|
|
224
|
+
var cfg = new Config(options, f, config);
|
|
225
|
+
cfg.saveSync(); // 确保文件存在
|
|
226
|
+
// 注册配置字典
|
|
227
|
+
dict[f] = cfg;
|
|
228
|
+
return dict[f].getProxy();
|
|
177
229
|
}
|
|
178
230
|
|
|
179
231
|
/**
|
|
180
|
-
*
|
|
181
|
-
* @param {
|
|
182
|
-
* @param {
|
|
183
|
-
* @param {Object}
|
|
232
|
+
* 创建配置(异步)
|
|
233
|
+
* @param {String} file - 配置文件路径
|
|
234
|
+
* @param {Object} options - 配置对象
|
|
235
|
+
* @param {Object} config - 配置选项
|
|
184
236
|
* @returns {Promise<Proxy>}
|
|
185
237
|
*/
|
|
186
|
-
async function
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
238
|
+
async function createAsync(file, options = {}, config = {}) {
|
|
239
|
+
let f = file.fullname();
|
|
240
|
+
// 检查是否已存在配置
|
|
241
|
+
if (dict[f]) {
|
|
242
|
+
$.log.warn(`[options] Config for file ${f} already exists.`);
|
|
243
|
+
return dict[f].getAsyncProxy();
|
|
244
|
+
}
|
|
245
|
+
var cfg = new Config(options, f, config);
|
|
246
|
+
await cfg.saveAsync(); // 确保文件存在
|
|
247
|
+
// 注册配置字典
|
|
248
|
+
dict[f] = cfg;
|
|
249
|
+
return dict[f].getAsyncProxy();
|
|
250
|
+
}
|
|
191
251
|
|
|
192
|
-
|
|
193
|
-
|
|
252
|
+
/**
|
|
253
|
+
* 清理指定文件配置缓存
|
|
254
|
+
* @param {String} file - 配置文件路径
|
|
255
|
+
*/
|
|
256
|
+
function clear(file) {
|
|
257
|
+
if (!file) return clearAll();
|
|
258
|
+
let f = file.fullname();
|
|
259
|
+
if (dict[f]) {
|
|
260
|
+
delete dict[f];
|
|
261
|
+
}
|
|
194
262
|
}
|
|
195
263
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
264
|
+
/**
|
|
265
|
+
* 清理所有配置缓存
|
|
266
|
+
*/
|
|
267
|
+
function clearAll() {
|
|
268
|
+
Object.keys(dict).forEach(key => {
|
|
269
|
+
delete dict[key];
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* 获取配置值
|
|
275
|
+
* @param {String} key - 配置键
|
|
276
|
+
* @returns {*}
|
|
277
|
+
*/
|
|
278
|
+
Config.prototype.get = async function (key) {
|
|
279
|
+
var value;
|
|
280
|
+
if (this._conn) {
|
|
281
|
+
value = await this._conn.get(key);
|
|
282
|
+
}
|
|
283
|
+
if (!value) {
|
|
284
|
+
value = this.options[key];
|
|
285
|
+
}
|
|
286
|
+
return value;
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* 设置配置值
|
|
291
|
+
* @param {String} key - 配置键
|
|
292
|
+
* @param {*} value - 配置值
|
|
293
|
+
*/
|
|
294
|
+
Config.prototype.set = async function (key, value) {
|
|
295
|
+
if (this._conn) {
|
|
296
|
+
await this._conn.set(key, value);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
this.options[key] = value;
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* 检查配置是否存在
|
|
305
|
+
* @param {String} key - 配置键
|
|
306
|
+
* @returns {Boolean}
|
|
307
|
+
*/
|
|
308
|
+
Config.prototype.has = async function (key) {
|
|
309
|
+
var bl = false;
|
|
310
|
+
if (this._conn) {
|
|
311
|
+
bl = await this._conn.has(key);
|
|
312
|
+
};
|
|
313
|
+
if (!bl) {
|
|
314
|
+
bl = this.options.hasOwnProperty(key);
|
|
315
|
+
}
|
|
316
|
+
return bl;
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* 删除配置项
|
|
321
|
+
* @param {String} key - 配置键
|
|
322
|
+
*/
|
|
323
|
+
Config.prototype.del = async function (key) {
|
|
324
|
+
if (this._conn) {
|
|
325
|
+
await this._conn.del(key);
|
|
326
|
+
};
|
|
327
|
+
delete this.options[key];
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* 获取所有配置键
|
|
332
|
+
* @returns {Array<String>}
|
|
333
|
+
*/
|
|
334
|
+
Config.prototype.keys = async function () {
|
|
335
|
+
let keys = [];
|
|
336
|
+
if (this._conn) {
|
|
337
|
+
keys = await this._conn.keys();
|
|
338
|
+
}
|
|
339
|
+
let local_keys = Object.keys(this.options);
|
|
340
|
+
keys = keys.concat(local_keys);
|
|
341
|
+
return keys;
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
// 模块导出
|
|
345
|
+
module.exports = {
|
|
346
|
+
Config,
|
|
347
|
+
create,
|
|
348
|
+
createAsync,
|
|
349
|
+
clear,
|
|
350
|
+
clearAll
|
|
351
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mm_config",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.5",
|
|
4
4
|
"description": "这是超级美眉配置同步器,用于更改配置同步保存为JSON文件",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,6 +26,6 @@
|
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://gitee.com/qiuwenwu91/mm_config#readme",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"
|
|
29
|
+
"mm_expand": "^1.9.7"
|
|
30
30
|
}
|
|
31
|
-
}
|
|
31
|
+
}
|
package/test.js
CHANGED
|
@@ -1,132 +1,199 @@
|
|
|
1
|
-
const
|
|
2
|
-
const createConfigAsync = conf.createConfigAsync;
|
|
1
|
+
const { create, createAsync, Config, clear, clearAll } = require('./index.js');
|
|
3
2
|
|
|
4
|
-
// 测试同步API
|
|
3
|
+
// 测试同步API
|
|
5
4
|
function testSyncConfig() {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
$.log.debug('=== 测试同步配置 API ===');
|
|
6
|
+
|
|
8
7
|
// 方式1:提供配置对象和文件路径
|
|
9
|
-
const config1 =
|
|
8
|
+
const config1 = create("./config1.json", {
|
|
10
9
|
name: "demo",
|
|
11
10
|
state: 1
|
|
12
|
-
}
|
|
13
|
-
|
|
11
|
+
});
|
|
12
|
+
|
|
14
13
|
// 修改配置,会自动保存
|
|
15
14
|
config1.name = "test1";
|
|
16
15
|
config1.sort = 1;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// 方式2
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const config2 = conf.call(context, {
|
|
25
|
-
name: "demo",
|
|
26
|
-
state: 2
|
|
27
|
-
});
|
|
28
|
-
|
|
16
|
+
$.log.debug('配置1:', config1);
|
|
17
|
+
|
|
18
|
+
// 方式2:创建空配置
|
|
19
|
+
const config2 = create("./config2.json");
|
|
20
|
+
|
|
29
21
|
config2.name = "test2";
|
|
30
22
|
config2.sort = 2;
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
$.log.debug('配置2:', config2);
|
|
24
|
+
|
|
33
25
|
// 从文件加载配置
|
|
34
|
-
const config3 =
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
const config3 = create("./config1.json");
|
|
27
|
+
$.log.debug('从文件加载的配置:', config3);
|
|
28
|
+
|
|
37
29
|
// 手动保存
|
|
38
30
|
config3.age = 26;
|
|
39
31
|
config3._saveSync(); // 显式调用保存
|
|
40
|
-
|
|
32
|
+
$.log.debug('更新后的配置3:', config3);
|
|
41
33
|
}
|
|
42
34
|
|
|
43
35
|
// 测试异步API
|
|
44
36
|
async function testAsyncConfig() {
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
$.log.debug('\n=== 测试异步配置 API ===');
|
|
38
|
+
|
|
47
39
|
try {
|
|
48
40
|
// 创建异步配置
|
|
49
|
-
const configAsync = await
|
|
41
|
+
const configAsync = await createAsync("./config_async.json", {
|
|
50
42
|
name: "asyncDemo",
|
|
51
43
|
state: 3
|
|
52
|
-
}
|
|
53
|
-
|
|
44
|
+
});
|
|
45
|
+
|
|
54
46
|
// 修改配置,会异步自动保存
|
|
55
47
|
configAsync.name = "asyncTest2";
|
|
56
48
|
configAsync.timestamp = new Date().toISOString();
|
|
57
|
-
|
|
58
|
-
|
|
49
|
+
$.log.debug('异步配置:', configAsync);
|
|
50
|
+
|
|
59
51
|
// 显式调用异步保存
|
|
60
52
|
// await configAsync._saveAsync();
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
} catch (
|
|
64
|
-
|
|
53
|
+
$.log.debug('异步保存完成');
|
|
54
|
+
|
|
55
|
+
} catch (err) {
|
|
56
|
+
$.log.error('异步配置测试出错:', err);
|
|
65
57
|
}
|
|
66
58
|
}
|
|
67
59
|
|
|
68
60
|
// 测试高级功能:防抖
|
|
69
61
|
function testDebounce() {
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
$.log.debug('\n=== 测试防抖功能 ===');
|
|
63
|
+
|
|
72
64
|
// 创建带防抖的配置(500ms延迟保存)
|
|
73
|
-
const configDebounce =
|
|
65
|
+
const configDebounce = create("./config_debounce.json", {
|
|
74
66
|
name: "debounceDemo"
|
|
75
|
-
},
|
|
76
|
-
|
|
67
|
+
}, {
|
|
68
|
+
debounce_time: 500, // 500ms防抖时间
|
|
77
69
|
pretty: true // 美化JSON输出
|
|
78
70
|
});
|
|
79
|
-
|
|
71
|
+
|
|
80
72
|
// 快速多次修改,应该只保存最后一次
|
|
81
|
-
|
|
73
|
+
$.log.debug('开始多次快速修改...');
|
|
82
74
|
for (let i = 0; i < 5; i++) {
|
|
83
75
|
configDebounce.value = i;
|
|
84
76
|
configDebounce.timestamp = new Date().toISOString();
|
|
85
77
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
|
|
79
|
+
$.log.debug('修改完成,等待防抖触发保存...');
|
|
80
|
+
$.log.debug('最终配置:', configDebounce);
|
|
89
81
|
}
|
|
90
82
|
|
|
91
83
|
// 测试JSON5格式
|
|
92
84
|
function testJson5() {
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
$.log.debug('\n=== 测试JSON5格式支持 ===');
|
|
86
|
+
|
|
95
87
|
// 创建配置时指定JSON5格式
|
|
96
|
-
const configJson5 =
|
|
97
|
-
name: "json5Demo"
|
|
98
|
-
|
|
99
|
-
// 虽然保存时会转为标准JSON,但读取时可以处理JSON5格式
|
|
100
|
-
}, "./config_json5.json", {
|
|
88
|
+
const configJson5 = create("./config_json5.json", {
|
|
89
|
+
name: "json5Demo"
|
|
90
|
+
}, {
|
|
101
91
|
format: 'json5',
|
|
102
92
|
pretty: true
|
|
103
93
|
});
|
|
104
|
-
|
|
94
|
+
|
|
105
95
|
configJson5.description = "This uses JSON5 format";
|
|
106
|
-
|
|
96
|
+
$.log.debug('JSON5配置:', configJson5);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 测试配置方法
|
|
101
|
+
*/
|
|
102
|
+
async function testMethods() {
|
|
103
|
+
$.log.debug('\n=== 测试配置方法 ===');
|
|
104
|
+
|
|
105
|
+
// 创建测试配置
|
|
106
|
+
const cg = new Config({
|
|
107
|
+
name: "methodsDemo",
|
|
108
|
+
sort: 100,
|
|
109
|
+
state: 1
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// 测试设置和获取
|
|
113
|
+
await cg.set('name', 'testMethods');
|
|
114
|
+
const name = await cg.get('name');
|
|
115
|
+
$.log.debug('获取到的名称:', name);
|
|
116
|
+
|
|
117
|
+
// 测试检查存在
|
|
118
|
+
const hasName = await cg.has('name');
|
|
119
|
+
$.log.debug('是否存在名称:', hasName);
|
|
120
|
+
|
|
121
|
+
// 测试删除
|
|
122
|
+
await cg.del('name');
|
|
123
|
+
const hasNameAfterDelete = await cg.has('name');
|
|
124
|
+
$.log.debug('删除后是否存在名称:', hasNameAfterDelete);
|
|
125
|
+
|
|
126
|
+
// 测试获取所有键
|
|
127
|
+
const keys = await cg.keys();
|
|
128
|
+
$.log.debug('所有键:', keys);
|
|
129
|
+
|
|
130
|
+
const state = await cg.get('state');
|
|
131
|
+
$.log.debug('获取到的状态:', state);
|
|
132
|
+
|
|
133
|
+
// 测试设置选项
|
|
134
|
+
await cg.setOptions({
|
|
135
|
+
sort: 200,
|
|
136
|
+
state: "2"
|
|
137
|
+
});
|
|
138
|
+
$.log.debug('设置后的选项:', await cg.options);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 测试缓存清理功能
|
|
142
|
+
async function testCacheClear() {
|
|
143
|
+
$.log.debug('\n=== 测试缓存清理功能 ===');
|
|
144
|
+
|
|
145
|
+
// 创建几个配置实例
|
|
146
|
+
const config1 = create("./cache_test1.json", { test: "cache1" });
|
|
147
|
+
const config2 = create("./cache_test2.json", { test: "cache2" });
|
|
148
|
+
const config3 = await createAsync("./cache_test3.json", { test: "cache3" });
|
|
149
|
+
|
|
150
|
+
$.log.debug('创建了3个配置实例');
|
|
151
|
+
|
|
152
|
+
// 测试清理单个缓存
|
|
153
|
+
clear("./cache_test1.json");
|
|
154
|
+
$.log.debug('已清理cache_test1.json的缓存');
|
|
155
|
+
|
|
156
|
+
// 重新创建应该会创建新实例
|
|
157
|
+
const config1New = create("./cache_test1.json", { test: "cache1_new" });
|
|
158
|
+
$.log.debug('重新创建cache_test1.json');
|
|
159
|
+
|
|
160
|
+
// 测试清理所有缓存
|
|
161
|
+
clearAll();
|
|
162
|
+
$.log.debug('已清理所有缓存');
|
|
163
|
+
|
|
164
|
+
// 再次创建应该都是新实例
|
|
165
|
+
const config2New = create("./cache_test2.json", { test: "cache2_new" });
|
|
166
|
+
const config3New = await createAsync("./cache_test3.json", { test: "cache3_new" });
|
|
167
|
+
$.log.debug('重新创建所有配置实例');
|
|
107
168
|
}
|
|
108
169
|
|
|
109
170
|
// 运行所有测试
|
|
110
171
|
async function runAllTests() {
|
|
111
|
-
|
|
112
|
-
|
|
172
|
+
$.log.debug('开始运行配置管理器测试...');
|
|
173
|
+
|
|
113
174
|
// 运行同步测试
|
|
114
175
|
testSyncConfig();
|
|
115
|
-
|
|
176
|
+
|
|
116
177
|
// 运行异步测试
|
|
117
178
|
await testAsyncConfig();
|
|
118
|
-
|
|
179
|
+
|
|
119
180
|
// 运行防抖测试
|
|
120
181
|
testDebounce();
|
|
121
|
-
|
|
182
|
+
|
|
122
183
|
// 运行JSON5测试
|
|
123
184
|
testJson5();
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
185
|
+
|
|
186
|
+
// 运行缓存清理测试
|
|
187
|
+
await testCacheClear();
|
|
188
|
+
|
|
189
|
+
$.log.debug('\n所有测试完成!');
|
|
190
|
+
$.log.debug('请查看生成的配置文件以验证保存结果。');
|
|
191
|
+
|
|
192
|
+
// 运行方法测试
|
|
193
|
+
await testMethods();
|
|
127
194
|
}
|
|
128
195
|
|
|
129
196
|
// 执行测试
|
|
130
197
|
runAllTests().catch(err => {
|
|
131
|
-
|
|
198
|
+
$.log.error('测试过程中出现错误:', err);
|
|
132
199
|
});
|
package/base.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 重够配置,同步保存
|
|
3
|
-
* @param {Object} _config 配置对象
|
|
4
|
-
* @param {String} _jsonFile 配置文件
|
|
5
|
-
*/
|
|
6
|
-
module.exports = function(_config, _jsonFile) {
|
|
7
|
-
if (!_jsonFile) {
|
|
8
|
-
_jsonFile = this.filename;
|
|
9
|
-
}
|
|
10
|
-
if (!_config) {
|
|
11
|
-
try {
|
|
12
|
-
_config = _jsonFile.loadJson();
|
|
13
|
-
} catch (error) {
|
|
14
|
-
_config = {};
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return new Proxy(_config, {
|
|
18
|
-
set: function(obj, prop, value) {
|
|
19
|
-
obj[prop] = value;
|
|
20
|
-
if (_jsonFile) {
|
|
21
|
-
try {
|
|
22
|
-
_jsonFile.saveJson(obj); // 使用saveJson原型函数,参数为对象和缩进空格数
|
|
23
|
-
} catch (error) {
|
|
24
|
-
console.error('[Config] 保存配置失败:', error);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return true
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|