mm_cachebase 1.6.0 → 1.8.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mm_cachebase",
3
- "version": "1.6.0",
4
- "description": "一个轻量级的本地缓存类库,提供与Redis兼容的API接口,支持过期时间设置、哈希表操作、数值操作、字符串操作等功能,以及完整的事件通知系统。",
3
+ "version": "1.8.0",
4
+ "description": "一个轻量级的本地缓存类库,提供与Redis兼容的API接口,支持过期时间设置、哈希表操作、数值操作、字符串操作等功能,以及完整的事件通知系统和多文件持久化功能。",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "node test.js"
@@ -27,7 +27,10 @@
27
27
  "ttl",
28
28
  "expire",
29
29
  "incr",
30
- "decr"
30
+ "decr",
31
+ "persistence",
32
+ "persist",
33
+ "scope"
31
34
  ],
32
35
  "author": "邱文武",
33
36
  "license": "MIT",
package/simple_test.js ADDED
@@ -0,0 +1,70 @@
1
+ const { CacheBase } = require('./index');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ async function simpleTest() {
6
+ console.log('====== 简单持久化测试 ======');
7
+
8
+ const cacheDir = './test_simple_cache';
9
+ const cacheFile = path.join(cacheDir, 'simple_cache.json');
10
+
11
+ // 清理之前的测试文件
12
+ if (fs.existsSync(cacheFile)) {
13
+ fs.unlinkSync(cacheFile);
14
+ console.log('已清理旧测试文件');
15
+ }
16
+
17
+ // 步骤1: 创建缓存并设置数据
18
+ console.log('\n步骤1: 创建缓存并设置数据');
19
+ const cache = new CacheBase({
20
+ persist: true,
21
+ scope: 'simple',
22
+ dir: cacheDir
23
+ });
24
+
25
+ // 直接设置数据
26
+ console.log('设置数据...');
27
+ cache.data['test_key'] = { value: 'test_value', expire: 0 };
28
+ cache.list = ['test_key'];
29
+ console.log('当前data:', cache.data);
30
+ console.log('当前list:', cache.list);
31
+
32
+ // 步骤2: 手动保存
33
+ console.log('\n步骤2: 手动保存数据');
34
+ await cache.save();
35
+
36
+ // 检查文件是否存在且有内容
37
+ if (fs.existsSync(cacheFile)) {
38
+ const content = fs.readFileSync(cacheFile, 'utf8');
39
+ console.log('保存的文件内容:');
40
+ console.log(content);
41
+ } else {
42
+ console.log('错误: 文件未创建');
43
+ }
44
+
45
+ // 步骤3: 销毁缓存
46
+ console.log('\n步骤3: 销毁缓存');
47
+ await cache.dispose();
48
+
49
+ // 步骤4: 创建新缓存,应该加载数据
50
+ console.log('\n步骤4: 创建新缓存,尝试加载数据');
51
+ const newCache = new CacheBase({
52
+ persist: true,
53
+ scope: 'simple',
54
+ dir: cacheDir
55
+ });
56
+
57
+ // 等待一点时间让_loadData完成
58
+ await new Promise(resolve => setTimeout(resolve, 100));
59
+
60
+ // 检查是否加载了数据
61
+ console.log('加载后的data:', newCache.data);
62
+ console.log('加载后的list:', newCache.list);
63
+ console.log('test_key值:', newCache.data.test_key ? newCache.data.test_key.value : 'undefined');
64
+
65
+ // 清理
66
+ await newCache.dispose();
67
+ console.log('\n测试完成!');
68
+ }
69
+
70
+ simpleTest().catch(console.error);
package/test.js CHANGED
@@ -107,7 +107,7 @@ async function testBasicMethods(runner) {
107
107
  });
108
108
 
109
109
  await runner.runTest('keys方法', async () => {
110
- await cache.flushdb();
110
+ await cache.clear();
111
111
  await cache.set('key4', 'value4');
112
112
  await cache.set('key5', 'value5');
113
113
  const keys = await cache.keys();
@@ -139,7 +139,7 @@ async function testBasicMethods(runner) {
139
139
  });
140
140
 
141
141
  await runner.runTest('flushdb/clear方法', async () => {
142
- let result = await cache.flushdb();
142
+ let result = await cache.clear();
143
143
  if (result !== 'OK') {
144
144
  throw new Error(`flushdb失败,预期: OK, 实际: ${result}`);
145
145
  }
@@ -0,0 +1,5 @@
1
+ {
2
+ "data": {},
3
+ "list": [],
4
+ "timestamp": 1759920414864
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "data": {},
3
+ "list": [],
4
+ "timestamp": 1759920414866
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "data": {},
3
+ "list": [],
4
+ "timestamp": 1759920414869
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "data": {},
3
+ "list": [],
4
+ "timestamp": 1759920431894
5
+ }
@@ -0,0 +1,160 @@
1
+ const { CacheBase } = require('./index');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ async function testMultiFilePersistence() {
6
+ console.log('====== 测试多文件持久化功能 ======');
7
+
8
+ // 测试目录
9
+ const testDir = './test_cache';
10
+
11
+ // 清理之前的测试文件
12
+ console.log('清理之前的测试文件...');
13
+ if (fs.existsSync(testDir)) {
14
+ const files = fs.readdirSync(testDir);
15
+ for (const file of files) {
16
+ if (file.endsWith('.cache.json')) {
17
+ fs.unlinkSync(path.join(testDir, file));
18
+ console.log(`删除文件: ${file}`);
19
+ }
20
+ }
21
+ }
22
+
23
+ try {
24
+ // 创建多个不同scope的缓存实例
25
+ console.log('\n创建多个缓存实例...');
26
+
27
+ const cache1 = new CacheBase('scope1', {
28
+ persist: true,
29
+ dir: testDir
30
+ });
31
+
32
+ const cache2 = new CacheBase('scope2', {
33
+ persist: true,
34
+ dir: testDir
35
+ });
36
+
37
+ const cache3 = new CacheBase('scope3', {
38
+ persist: true,
39
+ dir: testDir
40
+ });
41
+
42
+ // 为每个实例设置数据
43
+ console.log('\n为每个实例设置数据...');
44
+
45
+ // scope1 数据
46
+ await cache1.set('scope1_key1', 'scope1_value1');
47
+ await cache1.set('scope1_key2', { nested: 'object1' });
48
+ await cache1.set('scope1_key3', 100);
49
+ console.log('scope1 设置的数据:');
50
+ console.log('scope1_key1:', await cache1.get('scope1_key1'));
51
+ console.log('scope1_key2:', await cache1.get('scope1_key2'));
52
+ console.log('scope1_key3:', await cache1.get('scope1_key3'));
53
+
54
+ // scope2 数据
55
+ await cache2.set('scope2_key1', 'scope2_value1');
56
+ await cache2.set('scope2_key2', { nested: 'object2' });
57
+ await cache2.set('scope2_key3', 200);
58
+ console.log('\nscope2 设置的数据:');
59
+ console.log('scope2_key1:', await cache2.get('scope2_key1'));
60
+ console.log('scope2_key2:', await cache2.get('scope2_key2'));
61
+ console.log('scope2_key3:', await cache2.get('scope2_key3'));
62
+
63
+ // scope3 数据
64
+ await cache3.set('scope3_key1', 'scope3_value1');
65
+ await cache3.set('scope3_key2', { nested: 'object3' });
66
+ await cache3.set('scope3_key3', 300);
67
+ console.log('\nscope3 设置的数据:');
68
+ console.log('scope3_key1:', await cache3.get('scope3_key1'));
69
+ console.log('scope3_key2:', await cache3.get('scope3_key2'));
70
+ console.log('scope3_key3:', await cache3.get('scope3_key3'));
71
+
72
+ // 手动保存数据
73
+ console.log('\n手动保存所有数据...');
74
+ await cache1.save();
75
+ await cache2.save();
76
+ await cache3.save();
77
+
78
+ // 检查生成的文件
79
+ console.log('\n检查生成的缓存文件:');
80
+ const files = fs.readdirSync(testDir);
81
+ const cacheFiles = files.filter(file => file.endsWith('.cache.json'));
82
+ console.log('生成的缓存文件:', cacheFiles);
83
+
84
+ // 销毁所有实例
85
+ console.log('\n销毁所有实例...');
86
+ await cache1.dispose();
87
+ await cache2.dispose();
88
+ await cache3.dispose();
89
+
90
+ // 重新创建实例并验证数据隔离
91
+ console.log('\n重新创建缓存实例并验证数据隔离...');
92
+
93
+ // 只应该加载自己scope的数据
94
+ const newCache1 = new CacheBase('scope1', {
95
+ persist: true,
96
+ dir: testDir
97
+ });
98
+
99
+ const newCache2 = new CacheBase('scope2', {
100
+ persist: true,
101
+ dir: testDir
102
+ });
103
+
104
+ const newCache3 = new CacheBase('scope3', {
105
+ persist: true,
106
+ dir: testDir
107
+ });
108
+
109
+ // 验证每个实例只加载了自己scope的数据
110
+ console.log('\n验证数据隔离:');
111
+
112
+ // 验证scope1只加载了自己的数据
113
+ const scope1Keys = await newCache1.keys();
114
+ console.log('scope1 加载的键数量:', scope1Keys.length);
115
+ console.log('scope1 加载的键:', scope1Keys);
116
+
117
+ // 验证scope2只加载了自己的数据
118
+ const scope2Keys = await newCache2.keys();
119
+ console.log('scope2 加载的键数量:', scope2Keys.length);
120
+ console.log('scope2 加载的键:', scope2Keys);
121
+
122
+ // 验证scope3只加载了自己的数据
123
+ const scope3Keys = await newCache3.keys();
124
+ console.log('scope3 加载的键数量:', scope3Keys.length);
125
+ console.log('scope3 加载的键:', scope3Keys);
126
+
127
+ // 验证数据正确性
128
+ console.log('\n验证数据正确性:');
129
+ console.log('scope1_key1:', await newCache1.get('scope1_key1'));
130
+ console.log('scope2_key1:', await newCache2.get('scope2_key1'));
131
+ console.log('scope3_key1:', await newCache3.get('scope3_key1'));
132
+
133
+ // 验证数据隔离 - scope1不应该能访问scope2的数据
134
+ console.log('\n验证数据隔离 - scope1不应访问其他scope数据:');
135
+ console.log('scope1能否获取scope2_key1:', await newCache1.get('scope2_key1') === undefined ? '✓ 不能 (正确)' : '✗ 能 (错误)');
136
+ console.log('scope1能否获取scope3_key1:', await newCache1.get('scope3_key1') === undefined ? '✓ 不能 (正确)' : '✗ 能 (错误)');
137
+
138
+ // 清理测试数据
139
+ console.log('\n清理测试数据...');
140
+ await newCache1.flushdb();
141
+ await newCache2.flushdb();
142
+ await newCache3.flushdb();
143
+ await newCache1.save();
144
+ await newCache2.save();
145
+ await newCache3.save();
146
+
147
+ // 销毁实例
148
+ await newCache1.dispose();
149
+ await newCache2.dispose();
150
+ await newCache3.dispose();
151
+
152
+ console.log('\n多文件持久化测试完成!');
153
+
154
+ } catch (error) {
155
+ console.error('测试过程中发生错误:', error);
156
+ }
157
+ }
158
+
159
+ // 运行测试
160
+ testMultiFilePersistence();
@@ -0,0 +1,138 @@
1
+ const { CacheBase } = require('./index');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ async function testPersistence() {
6
+ console.log('====== 测试数据持久化功能 ======');
7
+
8
+ // 清理之前的测试文件
9
+ const testDir = './test_cache';
10
+ const testFilePath = path.join(testDir, 'test_scope.cache.json');
11
+ if (fs.existsSync(testFilePath)) {
12
+ fs.unlinkSync(testFilePath);
13
+ console.log(`清理之前的测试文件: ${testFilePath}`);
14
+ }
15
+
16
+ // 创建缓存实例,启用持久化
17
+ // 注意:最新版本的构造函数签名是 (scope, config)
18
+ const cache = new CacheBase('test_scope', {
19
+ persist: true,
20
+ dir: './test_cache',
21
+ saveInterval: 5000 // 5秒保存一次
22
+ });
23
+
24
+ try {
25
+ // 启动定时保存
26
+ console.log('启动定时保存...');
27
+ const connected = await cache.connect();
28
+ console.log(`定时保存启动${connected ? '成功' : '失败'}`);
29
+
30
+ // 设置一些测试数据
31
+ console.log('\n设置测试数据...');
32
+ await cache.set('key1', 'value1');
33
+ await cache.set('key2', { nested: 'object', array: [1, 2, 3], boolean: true });
34
+ await cache.set('key3', 123);
35
+ await cache.set('key4', 'expire_value', 30); // 30秒过期
36
+
37
+ // 增加更多测试数据
38
+ await cache.set('number_key', 42.5);
39
+ await cache.set('boolean_key', false);
40
+ await cache.set('array_key', [1, 'two', { three: 3 }]);
41
+ await cache.set('null_key', null);
42
+ await cache.set('undefined_key', undefined);
43
+ await cache.set('empty_string', '');
44
+ await cache.set('long_string', '这是一个很长的字符串,用于测试不同长度的数据存储。This is a long string for testing data storage with different lengths.');
45
+
46
+ // 使用哈希表功能
47
+ await cache.hset('hash_key', 'field1', 'hash_value1');
48
+ await cache.hset('hash_key', 'field2', 100);
49
+ await cache.hset('hash_key', 'field3', { nested: 'data' });
50
+
51
+ // 设置一些递增递减的值
52
+ await cache.incr('counter');
53
+ await cache.incrby('counter_by', 10);
54
+ await cache.decr('counter_dec');
55
+
56
+ // 检查设置的数据
57
+ console.log('设置的数据:');
58
+ console.log('key1:', await cache.get('key1'));
59
+ console.log('key2:', JSON.stringify(await cache.get('key2')));
60
+ console.log('key3:', await cache.get('key3'));
61
+ console.log('key4:', await cache.get('key4'));
62
+ console.log('新增数据示例:');
63
+ console.log('array_key:', JSON.stringify(await cache.get('array_key')));
64
+ console.log('hash_key 字段1:', await cache.hget('hash_key', 'field1'));
65
+ console.log('counter:', await cache.get('counter'));
66
+
67
+ // 获取键数量
68
+ const initialKeys = await cache.keys();
69
+ console.log(`\n初始设置的键数量: ${initialKeys.length}`);
70
+ console.log('键列表:', initialKeys);
71
+
72
+ // 手动保存数据
73
+ console.log('\n手动保存数据...');
74
+ const saved = await cache.save();
75
+ console.log(`手动保存${saved ? '成功' : '失败'}`);
76
+
77
+ // 销毁当前实例
78
+ console.log('\n销毁当前实例...');
79
+ await cache.dispose();
80
+ console.log('实例已销毁');
81
+
82
+ // 创建新实例,应该能加载之前保存的数据
83
+ console.log('\n创建新实例,尝试加载数据...');
84
+ const newCache = new CacheBase('test_scope', {
85
+ persist: true,
86
+ dir: './test_cache'
87
+ });
88
+
89
+ // 检查数据是否被正确加载
90
+ console.log('\n加载的数据:');
91
+ console.log('key1:', await newCache.get('key1'));
92
+ console.log('key2:', JSON.stringify(await newCache.get('key2')));
93
+ console.log('key3:', await newCache.get('key3'));
94
+ console.log('key4:', await newCache.get('key4'));
95
+
96
+ // 验证新加的数据是否正确加载
97
+ console.log('\n验证新加的数据:');
98
+ console.log('number_key:', await newCache.get('number_key'));
99
+ console.log('boolean_key:', await newCache.get('boolean_key'));
100
+ console.log('array_key:', JSON.stringify(await newCache.get('array_key')));
101
+ console.log('null_key:', await newCache.get('null_key'));
102
+ console.log('undefined_key:', await newCache.get('undefined_key'));
103
+ console.log('empty_string:', JSON.stringify(await newCache.get('empty_string')));
104
+ console.log('long_string 长度:', (await newCache.get('long_string')).length);
105
+
106
+ // 验证哈希表数据
107
+ console.log('\n验证哈希表数据:');
108
+ console.log('hash_key 字段1:', await newCache.hget('hash_key', 'field1'));
109
+ console.log('hash_key 字段2:', await newCache.hget('hash_key', 'field2'));
110
+ console.log('hash_key 字段3:', JSON.stringify(await newCache.hget('hash_key', 'field3')));
111
+
112
+ // 验证计数数据
113
+ console.log('\n验证计数数据:');
114
+ console.log('counter:', await newCache.get('counter'));
115
+ console.log('counter_by:', await newCache.get('counter_by'));
116
+ console.log('counter_dec:', await newCache.get('counter_dec'));
117
+
118
+ // 验证键的数量
119
+ const loadedKeys = await newCache.keys();
120
+ console.log('\n加载的键数量:', loadedKeys.length);
121
+ console.log('键列表:', loadedKeys);
122
+
123
+ // 清理测试数据
124
+ console.log('\n清理测试数据...');
125
+ await newCache.flushdb();
126
+ await newCache.save();
127
+ await newCache.dispose();
128
+
129
+ console.log('\n测试完成!');
130
+
131
+ } catch (error) {
132
+ console.error('测试过程中发生错误:', error);
133
+ await cache.dispose().catch(() => {});
134
+ }
135
+ }
136
+
137
+ // 运行测试
138
+ testPersistence();