mm_config 2.1.3 → 2.1.4

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/index.js CHANGED
@@ -1,199 +1,351 @@
1
- require('mm_logs');
2
-
3
- /**
4
- * 配置管理器类,提供同步和异步API
5
- */
6
- class ConfigManager {
7
- /**
8
- * 构造函数
9
- * @param {Object} _config 配置对象
10
- * @param {String} _jsonFile 配置文件路径
11
- * @param {Object} options 配置选项
12
- * @param {Number} options.debounceTime 防抖时间(ms)
13
- * @param {Boolean} options.pretty 是否美化输出
14
- * @param {String} options.format 格式(json/json5)
15
- */
16
- constructor(_config, _jsonFile, options = {}) {
17
- this.config = _config || {};
18
- this.filePath = _jsonFile;
19
- this.options = {
20
- debounceTime: 0, // 默认不防抖
21
- pretty: true,
22
- format: 'json',
23
- ...options
24
- };
25
- this.writeTimer = null;
26
- this.writePromise = Promise.resolve();
27
-
28
- // 如果没有提供配置且有文件路径,则从文件加载
29
- if (!_config && _jsonFile) {
30
- try {
31
- this.config = _jsonFile.loadJson();
32
- } catch(error) {
33
- $.log.error(`[Config] Error loading config from ${_jsonFile}:`, error.message);
34
- this.config = {};
35
- }
36
- }
37
- }
38
-
39
- /**
40
- * 保存配置到文件(同步)
41
- */
42
- saveSync() {
43
- if (!this.filePath) return false;
44
- try {
45
- this.filePath.saveJson(this.config);
46
- return true;
47
- } catch(error) {
48
- $.log.error(`[Config] Error saving config to ${this.filePath}:`, error.message);
49
- return false;
50
- }
51
- }
52
-
53
- /**
54
- * 保存配置到文件(异步)
55
- * @returns {Promise<Boolean>}
56
- */
57
- async saveAsync() {
58
- if (!this.filePath) return Promise.resolve(true);
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} _config 配置对象
165
- * @param {String} _jsonFile 配置文件路径
166
- * @param {Object} options 配置选项
64
+ * 设置配置
65
+ * @param {Object} options - 配置对象
66
+ */
67
+ Config.prototype.setOptions = function (options) {
68
+ Object.assign(this.options, options);
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 createConfig(_config, _jsonFile, options = {}) {
170
- // 兼容旧的调用方式(this.filename)
171
- if (!_jsonFile && this && this.filename) {
172
- _jsonFile = this.filename;
173
- }
167
+ Config.prototype.getAsyncProxy = function () {
168
+ var self = this;
174
169
 
175
- const manager = new ConfigManager(_config, _jsonFile, options);
176
- return manager.getProxy(); // 默认返回同步代理
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 {Object} _config 配置对象
182
- * @param {String} _jsonFile 配置文件路径
183
- * @param {Object} options 配置选项
232
+ * 创建配置(异步)
233
+ * @param {String} file - 配置文件路径
234
+ * @param {Object} options - 配置对象
235
+ * @param {Object} config - 配置选项
184
236
  * @returns {Promise<Proxy>}
185
237
  */
186
- async function createConfigAsync(_config, _jsonFile, options = {}) {
187
- // 兼容旧的调用方式(this.filename)
188
- if (!_jsonFile && this && this.filename) {
189
- _jsonFile = this.filename;
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
- const manager = new ConfigManager(_config, _jsonFile, options);
193
- return manager.getAsyncProxy();
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
- module.exports = createConfig;
198
- module.exports.createConfigAsync = createConfigAsync;
199
- module.exports.ConfigManager = ConfigManager;
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",
3
+ "version": "2.1.4",
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
- "mm_logs": "^1.5.1"
29
+ "mm_expand": "^1.9.7"
30
30
  }
31
- }
31
+ }