ti2 1.0.101 → 1.0.102
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/__tests__/cache.js +76 -0
- package/cache.js +21 -0
- package/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* globals describe it expect beforeAll afterAll afterEach */
|
|
2
|
+
|
|
3
|
+
const cache = require('../cache');
|
|
4
|
+
|
|
5
|
+
describe('cache', () => {
|
|
6
|
+
const testPluginName = 'testPlugin';
|
|
7
|
+
const testKeys = [];
|
|
8
|
+
|
|
9
|
+
afterEach(async () => {
|
|
10
|
+
// Clean up test keys
|
|
11
|
+
for (const key of testKeys) {
|
|
12
|
+
await cache.drop({ pluginName: testPluginName, key });
|
|
13
|
+
}
|
|
14
|
+
testKeys.length = 0;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
describe('scan', () => {
|
|
19
|
+
it('should return keys matching the pattern without plugin prefix', async () => {
|
|
20
|
+
// Save some test keys
|
|
21
|
+
const keys = ['product:123', 'product:456', 'booking:789'];
|
|
22
|
+
for (const key of keys) {
|
|
23
|
+
testKeys.push(key);
|
|
24
|
+
await cache.save({ pluginName: testPluginName, key, value: { test: true } });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Scan for product keys
|
|
28
|
+
const result = await cache.scan({ pluginName: testPluginName, pattern: 'product:*' });
|
|
29
|
+
|
|
30
|
+
expect(result).toHaveLength(2);
|
|
31
|
+
expect(result).toContain('product:123');
|
|
32
|
+
expect(result).toContain('product:456');
|
|
33
|
+
expect(result).not.toContain('booking:789');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should return empty array when no keys match', async () => {
|
|
37
|
+
const result = await cache.scan({ pluginName: testPluginName, pattern: 'nonexistent:*' });
|
|
38
|
+
|
|
39
|
+
expect(result).toEqual([]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should not include keys from other plugins', async () => {
|
|
43
|
+
const otherPluginName = 'otherPlugin';
|
|
44
|
+
|
|
45
|
+
// Save keys for both plugins
|
|
46
|
+
await cache.save({ pluginName: testPluginName, key: 'shared:key1', value: { test: true } });
|
|
47
|
+
await cache.save({ pluginName: otherPluginName, key: 'shared:key2', value: { test: true } });
|
|
48
|
+
testKeys.push('shared:key1');
|
|
49
|
+
|
|
50
|
+
// Scan should only return keys for the specified plugin
|
|
51
|
+
const result = await cache.scan({ pluginName: testPluginName, pattern: 'shared:*' });
|
|
52
|
+
|
|
53
|
+
expect(result).toHaveLength(1);
|
|
54
|
+
expect(result).toContain('shared:key1');
|
|
55
|
+
expect(result).not.toContain('shared:key2');
|
|
56
|
+
|
|
57
|
+
// Cleanup other plugin key
|
|
58
|
+
await cache.drop({ pluginName: otherPluginName, key: 'shared:key2' });
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should handle wildcard patterns correctly', async () => {
|
|
62
|
+
const keys = ['cache:v1:product:1', 'cache:v1:product:2', 'cache:v2:product:1'];
|
|
63
|
+
for (const key of keys) {
|
|
64
|
+
testKeys.push(key);
|
|
65
|
+
await cache.save({ pluginName: testPluginName, key, value: { test: true } });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Scan with nested wildcard
|
|
69
|
+
const result = await cache.scan({ pluginName: testPluginName, pattern: 'cache:v1:*' });
|
|
70
|
+
|
|
71
|
+
expect(result).toHaveLength(2);
|
|
72
|
+
expect(result).toContain('cache:v1:product:1');
|
|
73
|
+
expect(result).toContain('cache:v1:product:2');
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|
package/cache.js
CHANGED
|
@@ -93,6 +93,26 @@ const drop = async ({
|
|
|
93
93
|
|
|
94
94
|
const keys = async () => cache.keys('*');
|
|
95
95
|
|
|
96
|
+
const scan = ({
|
|
97
|
+
pluginName,
|
|
98
|
+
pattern,
|
|
99
|
+
count = 1000,
|
|
100
|
+
}) => new Promise((resolve, reject) => {
|
|
101
|
+
const fullPattern = `${pluginName}:${pattern}`;
|
|
102
|
+
const foundKeys = [];
|
|
103
|
+
const prefixLength = pluginName.length + 1; // +1 for the colon
|
|
104
|
+
|
|
105
|
+
const stream = cache.scanStream({ match: fullPattern, count });
|
|
106
|
+
stream.on('data', keys => {
|
|
107
|
+
keys.forEach(key => {
|
|
108
|
+
// Return keys without the plugin prefix
|
|
109
|
+
foundKeys.push(key.slice(prefixLength));
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
stream.on('end', () => resolve(foundKeys));
|
|
113
|
+
stream.on('error', reject);
|
|
114
|
+
});
|
|
115
|
+
|
|
96
116
|
module.exports = {
|
|
97
117
|
cache,
|
|
98
118
|
save,
|
|
@@ -100,4 +120,5 @@ module.exports = {
|
|
|
100
120
|
drop,
|
|
101
121
|
get,
|
|
102
122
|
keys,
|
|
123
|
+
scan,
|
|
103
124
|
};
|
package/index.js
CHANGED
|
@@ -89,6 +89,7 @@ module.exports = async ({
|
|
|
89
89
|
get: args => cache.get({ ...args, pluginName }),
|
|
90
90
|
getOrExec: args => cache.getOrExec({ ...args, pluginName }),
|
|
91
91
|
save: args => cache.save({ ...args, pluginName }),
|
|
92
|
+
scan: args => cache.scan({ ...args, pluginName }),
|
|
92
93
|
},
|
|
93
94
|
axios: pluginAxios,
|
|
94
95
|
events: ti2Events,
|