@nocobase/cache 1.6.0-beta.3 → 1.6.0-beta.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/lib/bloom-filter/redis-bloom-filter.d.ts +1 -2
- package/lib/bloom-filter/redis-bloom-filter.js +12 -9
- package/lib/cache-manager.d.ts +12 -0
- package/lib/cache-manager.js +32 -2
- package/lib/counter/index.d.ts +23 -0
- package/lib/counter/index.js +42 -0
- package/lib/counter/lock-counter.d.ts +23 -0
- package/lib/counter/lock-counter.js +70 -0
- package/lib/counter/memory-counter.d.ts +27 -0
- package/lib/counter/memory-counter.js +89 -0
- package/lib/counter/redis-counter.d.ts +23 -0
- package/lib/counter/redis-counter.js +77 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/package.json +3 -2
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
import { RedisStore } from 'cache-manager-redis-yet';
|
|
10
9
|
import { BloomFilter } from '.';
|
|
11
10
|
import { Cache } from '../cache';
|
|
12
11
|
/**
|
|
@@ -15,7 +14,7 @@ import { Cache } from '../cache';
|
|
|
15
14
|
export declare class RedisBloomFilter implements BloomFilter {
|
|
16
15
|
cache: Cache;
|
|
17
16
|
constructor(cache: Cache);
|
|
18
|
-
|
|
17
|
+
private get store();
|
|
19
18
|
reserve(key: string, errorRate: number, capacity: number): Promise<void>;
|
|
20
19
|
add(key: string, value: string): Promise<void>;
|
|
21
20
|
mAdd(key: string, values: string[]): Promise<void>;
|
|
@@ -36,24 +36,27 @@ const _RedisBloomFilter = class _RedisBloomFilter {
|
|
|
36
36
|
constructor(cache) {
|
|
37
37
|
this.cache = cache;
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
get store() {
|
|
40
40
|
return this.cache.store.store;
|
|
41
41
|
}
|
|
42
42
|
async reserve(key, errorRate, capacity) {
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
try {
|
|
44
|
+
await this.store.client.bf.reserve(key, errorRate, capacity);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error.message.includes("ERR item exists")) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
45
51
|
}
|
|
46
52
|
async add(key, value) {
|
|
47
|
-
|
|
48
|
-
await store.client.bf.add(key, value);
|
|
53
|
+
await this.store.client.bf.add(key, value);
|
|
49
54
|
}
|
|
50
55
|
async mAdd(key, values) {
|
|
51
|
-
|
|
52
|
-
await store.client.bf.mAdd(key, values);
|
|
56
|
+
await this.store.client.bf.mAdd(key, values);
|
|
53
57
|
}
|
|
54
58
|
async exists(key, value) {
|
|
55
|
-
|
|
56
|
-
return await store.client.bf.exists(key, value);
|
|
59
|
+
return this.store.client.bf.exists(key, value);
|
|
57
60
|
}
|
|
58
61
|
};
|
|
59
62
|
__name(_RedisBloomFilter, "RedisBloomFilter");
|
package/lib/cache-manager.d.ts
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import { FactoryStore, Store } from 'cache-manager';
|
|
10
10
|
import { Cache } from './cache';
|
|
11
11
|
import { BloomFilter } from './bloom-filter';
|
|
12
|
+
import { Counter } from './counter';
|
|
13
|
+
import { LockManager } from '@nocobase/lock-manager';
|
|
12
14
|
type StoreOptions = {
|
|
13
15
|
store?: 'memory' | FactoryStore<Store, any>;
|
|
14
16
|
close?: (store: Store) => Promise<void>;
|
|
@@ -19,9 +21,11 @@ export type CacheManagerOptions = Partial<{
|
|
|
19
21
|
stores: {
|
|
20
22
|
[storeType: string]: StoreOptions;
|
|
21
23
|
};
|
|
24
|
+
prefix: string;
|
|
22
25
|
}>;
|
|
23
26
|
export declare class CacheManager {
|
|
24
27
|
defaultStore: string;
|
|
28
|
+
prefix?: string;
|
|
25
29
|
private stores;
|
|
26
30
|
/**
|
|
27
31
|
* @internal
|
|
@@ -52,5 +56,13 @@ export declare class CacheManager {
|
|
|
52
56
|
createBloomFilter(options?: {
|
|
53
57
|
store?: string;
|
|
54
58
|
}): Promise<BloomFilter>;
|
|
59
|
+
/**
|
|
60
|
+
* @experimental
|
|
61
|
+
*/
|
|
62
|
+
createCounter(options: {
|
|
63
|
+
name: string;
|
|
64
|
+
prefix?: string;
|
|
65
|
+
store?: string;
|
|
66
|
+
}, lockManager?: LockManager): Promise<Counter>;
|
|
55
67
|
}
|
|
56
68
|
export {};
|
package/lib/cache-manager.js
CHANGED
|
@@ -47,8 +47,10 @@ var import_cache_manager_redis_yet = require("cache-manager-redis-yet");
|
|
|
47
47
|
var import_deepmerge = __toESM(require("deepmerge"));
|
|
48
48
|
var import_memory_bloom_filter = require("./bloom-filter/memory-bloom-filter");
|
|
49
49
|
var import_redis_bloom_filter = require("./bloom-filter/redis-bloom-filter");
|
|
50
|
+
var import_counter = require("./counter");
|
|
50
51
|
const _CacheManager = class _CacheManager {
|
|
51
52
|
defaultStore;
|
|
53
|
+
prefix;
|
|
52
54
|
stores = /* @__PURE__ */ new Map();
|
|
53
55
|
/**
|
|
54
56
|
* @internal
|
|
@@ -80,8 +82,9 @@ const _CacheManager = class _CacheManager {
|
|
|
80
82
|
}
|
|
81
83
|
};
|
|
82
84
|
const cacheOptions = (0, import_deepmerge.default)(defaultOptions, options || {});
|
|
83
|
-
const { defaultStore = "memory", stores } = cacheOptions;
|
|
85
|
+
const { defaultStore = "memory", stores, prefix } = cacheOptions;
|
|
84
86
|
this.defaultStore = defaultStore;
|
|
87
|
+
this.prefix = prefix;
|
|
85
88
|
for (const [name, store] of Object.entries(stores)) {
|
|
86
89
|
const { store: s, ...globalConfig } = store;
|
|
87
90
|
this.registerStore({ name, store: s, ...globalConfig });
|
|
@@ -109,7 +112,9 @@ const _CacheManager = class _CacheManager {
|
|
|
109
112
|
return cache;
|
|
110
113
|
}
|
|
111
114
|
async createCache(options) {
|
|
112
|
-
const { name,
|
|
115
|
+
const { name, store = this.defaultStore, ...config } = options;
|
|
116
|
+
let { prefix } = options;
|
|
117
|
+
prefix = this.prefix ? prefix ? `${this.prefix}:${prefix}` : this.prefix : prefix;
|
|
113
118
|
if (!import_lodash.default.isEmpty(config) || store === "memory") {
|
|
114
119
|
const newStore = await this.createStore({ name, storeType: store, ...config });
|
|
115
120
|
return this.newCache({ name, prefix, store: newStore });
|
|
@@ -164,6 +169,31 @@ const _CacheManager = class _CacheManager {
|
|
|
164
169
|
throw new Error(`BloomFilter store [${store}] is not supported`);
|
|
165
170
|
}
|
|
166
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* @experimental
|
|
174
|
+
*/
|
|
175
|
+
async createCounter(options, lockManager) {
|
|
176
|
+
const { store = this.defaultStore, name, prefix } = options || {};
|
|
177
|
+
let cache;
|
|
178
|
+
if (store !== "memory") {
|
|
179
|
+
try {
|
|
180
|
+
cache = this.getCache(name);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
cache = await this.createCache({ name, store, prefix });
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
switch (store) {
|
|
186
|
+
case "memory":
|
|
187
|
+
return new import_counter.MemoryCounter();
|
|
188
|
+
case "redis":
|
|
189
|
+
return new import_counter.RedisCounter(cache);
|
|
190
|
+
default:
|
|
191
|
+
if (!lockManager) {
|
|
192
|
+
throw new Error(`Counter store [${store}] is not supported`);
|
|
193
|
+
}
|
|
194
|
+
return new import_counter.LockCounter(cache, lockManager);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
167
197
|
};
|
|
168
198
|
__name(_CacheManager, "CacheManager");
|
|
169
199
|
let CacheManager = _CacheManager;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* @experimental
|
|
11
|
+
* atomic counter
|
|
12
|
+
*/
|
|
13
|
+
export interface Counter {
|
|
14
|
+
get(key: string): Promise<number>;
|
|
15
|
+
incr(key: string): Promise<number>;
|
|
16
|
+
incr(key: string, ttl: number): Promise<number>;
|
|
17
|
+
incrby(key: string, val: number): Promise<number>;
|
|
18
|
+
incrby(key: string, val: number, ttl: number): Promise<number>;
|
|
19
|
+
reset(key: string): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export { MemoryCounter } from './memory-counter';
|
|
22
|
+
export { RedisCounter } from './redis-counter';
|
|
23
|
+
export { LockCounter } from './lock-counter';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var counter_exports = {};
|
|
28
|
+
__export(counter_exports, {
|
|
29
|
+
LockCounter: () => import_lock_counter.LockCounter,
|
|
30
|
+
MemoryCounter: () => import_memory_counter.MemoryCounter,
|
|
31
|
+
RedisCounter: () => import_redis_counter.RedisCounter
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(counter_exports);
|
|
34
|
+
var import_memory_counter = require("./memory-counter");
|
|
35
|
+
var import_redis_counter = require("./redis-counter");
|
|
36
|
+
var import_lock_counter = require("./lock-counter");
|
|
37
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
38
|
+
0 && (module.exports = {
|
|
39
|
+
LockCounter,
|
|
40
|
+
MemoryCounter,
|
|
41
|
+
RedisCounter
|
|
42
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { LockManager } from '@nocobase/lock-manager';
|
|
10
|
+
import { Counter as ICounter } from '.';
|
|
11
|
+
import { Cache } from '../cache';
|
|
12
|
+
/**
|
|
13
|
+
* @experimental
|
|
14
|
+
*/
|
|
15
|
+
export declare class LockCounter implements ICounter {
|
|
16
|
+
cache: Cache;
|
|
17
|
+
lockManager: LockManager;
|
|
18
|
+
constructor(cache: Cache, lockManager: LockManager);
|
|
19
|
+
get(key: string): Promise<number>;
|
|
20
|
+
incr(key: string, ttl?: number): Promise<number>;
|
|
21
|
+
incrby(key: string, value: number, ttl?: number): Promise<number>;
|
|
22
|
+
reset(key: string): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var lock_counter_exports = {};
|
|
29
|
+
__export(lock_counter_exports, {
|
|
30
|
+
LockCounter: () => LockCounter
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(lock_counter_exports);
|
|
33
|
+
const _LockCounter = class _LockCounter {
|
|
34
|
+
cache;
|
|
35
|
+
lockManager;
|
|
36
|
+
constructor(cache, lockManager) {
|
|
37
|
+
this.cache = cache;
|
|
38
|
+
this.lockManager = lockManager;
|
|
39
|
+
}
|
|
40
|
+
async get(key) {
|
|
41
|
+
return await this.cache.get(key) || 0;
|
|
42
|
+
}
|
|
43
|
+
async incr(key, ttl) {
|
|
44
|
+
return this.incrby(key, 1, ttl);
|
|
45
|
+
}
|
|
46
|
+
async incrby(key, value, ttl) {
|
|
47
|
+
const lockKey = `lock:${key}`;
|
|
48
|
+
const release = await this.lockManager.acquire(lockKey, 3e3);
|
|
49
|
+
try {
|
|
50
|
+
const v = await this.cache.get(key);
|
|
51
|
+
const n = v || 0;
|
|
52
|
+
const newValue = n + value;
|
|
53
|
+
await this.cache.set(key, newValue, ttl);
|
|
54
|
+
return newValue;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
throw error;
|
|
57
|
+
} finally {
|
|
58
|
+
await release();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async reset(key) {
|
|
62
|
+
return this.cache.del(key);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
__name(_LockCounter, "LockCounter");
|
|
66
|
+
let LockCounter = _LockCounter;
|
|
67
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
68
|
+
0 && (module.exports = {
|
|
69
|
+
LockCounter
|
|
70
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Counter as ICounter } from '.';
|
|
10
|
+
declare class Cache {
|
|
11
|
+
data: Map<any, any>;
|
|
12
|
+
timers: Map<any, any>;
|
|
13
|
+
set(k: string, v: any, ttl?: number): void;
|
|
14
|
+
get(k: string): any;
|
|
15
|
+
del(k: string): boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @experimental
|
|
19
|
+
*/
|
|
20
|
+
export declare class MemoryCounter implements ICounter {
|
|
21
|
+
cache: Cache;
|
|
22
|
+
get(key: string): Promise<any>;
|
|
23
|
+
incr(key: string, ttl?: number): Promise<any>;
|
|
24
|
+
incrby(key: string, value: number, ttl?: number): Promise<any>;
|
|
25
|
+
reset(key: string): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var memory_counter_exports = {};
|
|
29
|
+
__export(memory_counter_exports, {
|
|
30
|
+
MemoryCounter: () => MemoryCounter
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(memory_counter_exports);
|
|
33
|
+
const _Cache = class _Cache {
|
|
34
|
+
data = /* @__PURE__ */ new Map();
|
|
35
|
+
timers = /* @__PURE__ */ new Map();
|
|
36
|
+
set(k, v, ttl) {
|
|
37
|
+
if (ttl) {
|
|
38
|
+
if (this.timers.has(k)) {
|
|
39
|
+
clearTimeout(this.timers.get(k));
|
|
40
|
+
}
|
|
41
|
+
this.timers.set(
|
|
42
|
+
k,
|
|
43
|
+
setTimeout(() => this.del(k), ttl)
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
this.data.set(k, v);
|
|
47
|
+
}
|
|
48
|
+
get(k) {
|
|
49
|
+
return this.data.get(k);
|
|
50
|
+
}
|
|
51
|
+
del(k) {
|
|
52
|
+
if (this.timers.has(k)) {
|
|
53
|
+
clearTimeout(this.timers.get(k));
|
|
54
|
+
}
|
|
55
|
+
this.timers.delete(k);
|
|
56
|
+
return this.data.delete(k);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
__name(_Cache, "Cache");
|
|
60
|
+
let Cache = _Cache;
|
|
61
|
+
const _MemoryCounter = class _MemoryCounter {
|
|
62
|
+
cache = new Cache();
|
|
63
|
+
async get(key) {
|
|
64
|
+
return this.cache.get(key) || 0;
|
|
65
|
+
}
|
|
66
|
+
async incr(key, ttl) {
|
|
67
|
+
return this.incrby(key, 1, ttl);
|
|
68
|
+
}
|
|
69
|
+
async incrby(key, value, ttl) {
|
|
70
|
+
const v = this.cache.get(key);
|
|
71
|
+
const n = v || 0;
|
|
72
|
+
const newValue = n + value;
|
|
73
|
+
if (!v) {
|
|
74
|
+
this.cache.set(key, newValue, ttl);
|
|
75
|
+
} else {
|
|
76
|
+
this.cache.set(key, newValue);
|
|
77
|
+
}
|
|
78
|
+
return newValue;
|
|
79
|
+
}
|
|
80
|
+
async reset(key) {
|
|
81
|
+
this.cache.del(key);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
__name(_MemoryCounter, "MemoryCounter");
|
|
85
|
+
let MemoryCounter = _MemoryCounter;
|
|
86
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
87
|
+
0 && (module.exports = {
|
|
88
|
+
MemoryCounter
|
|
89
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Counter as ICounter } from '.';
|
|
10
|
+
import { Cache } from '../cache';
|
|
11
|
+
/**
|
|
12
|
+
* @experimental
|
|
13
|
+
*/
|
|
14
|
+
export declare class RedisCounter implements ICounter {
|
|
15
|
+
cache: Cache;
|
|
16
|
+
scriptSha: string;
|
|
17
|
+
constructor(cache: Cache);
|
|
18
|
+
private get store();
|
|
19
|
+
get(key: string): Promise<number>;
|
|
20
|
+
incr(key: string, ttl?: number): Promise<number>;
|
|
21
|
+
incrby(key: string, value: number, ttl?: number): Promise<number>;
|
|
22
|
+
reset(key: string): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var redis_counter_exports = {};
|
|
29
|
+
__export(redis_counter_exports, {
|
|
30
|
+
RedisCounter: () => RedisCounter
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(redis_counter_exports);
|
|
33
|
+
const script = `
|
|
34
|
+
local key = KEYS[1]
|
|
35
|
+
local value = tonumber(ARGV[1]) or 1
|
|
36
|
+
local ttl = tonumber(ARGV[2])
|
|
37
|
+
local current = redis.call('INCRBY', key, value)
|
|
38
|
+
if tonumber(current) == value and ttl then
|
|
39
|
+
redis.call('PEXPIRE', key, ttl)
|
|
40
|
+
end
|
|
41
|
+
return current
|
|
42
|
+
`;
|
|
43
|
+
const _RedisCounter = class _RedisCounter {
|
|
44
|
+
cache;
|
|
45
|
+
scriptSha;
|
|
46
|
+
constructor(cache) {
|
|
47
|
+
this.cache = cache;
|
|
48
|
+
}
|
|
49
|
+
get store() {
|
|
50
|
+
return this.cache.store.store;
|
|
51
|
+
}
|
|
52
|
+
async get(key) {
|
|
53
|
+
return await this.cache.get(key) || 0;
|
|
54
|
+
}
|
|
55
|
+
async incr(key, ttl) {
|
|
56
|
+
return this.incrby(key, 1, ttl);
|
|
57
|
+
}
|
|
58
|
+
async incrby(key, value, ttl) {
|
|
59
|
+
if (!this.scriptSha) {
|
|
60
|
+
this.scriptSha = await this.store.client.scriptLoad(script);
|
|
61
|
+
}
|
|
62
|
+
const result = await this.store.client.evalSha(this.scriptSha, {
|
|
63
|
+
keys: [this.cache.key(key)],
|
|
64
|
+
arguments: [value, ttl].map((v) => v ? v.toString() : "")
|
|
65
|
+
});
|
|
66
|
+
return Number(result);
|
|
67
|
+
}
|
|
68
|
+
async reset(key) {
|
|
69
|
+
return this.cache.del(key);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
__name(_RedisCounter, "RedisCounter");
|
|
73
|
+
let RedisCounter = _RedisCounter;
|
|
74
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
75
|
+
0 && (module.exports = {
|
|
76
|
+
RedisCounter
|
|
77
|
+
});
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -26,9 +26,11 @@ module.exports = __toCommonJS(src_exports);
|
|
|
26
26
|
__reExport(src_exports, require("./cache-manager"), module.exports);
|
|
27
27
|
__reExport(src_exports, require("./cache"), module.exports);
|
|
28
28
|
__reExport(src_exports, require("./bloom-filter"), module.exports);
|
|
29
|
+
__reExport(src_exports, require("./counter"), module.exports);
|
|
29
30
|
// Annotate the CommonJS export names for ESM import in node:
|
|
30
31
|
0 && (module.exports = {
|
|
31
32
|
...require("./cache-manager"),
|
|
32
33
|
...require("./cache"),
|
|
33
|
-
...require("./bloom-filter")
|
|
34
|
+
...require("./bloom-filter"),
|
|
35
|
+
...require("./counter")
|
|
34
36
|
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cache",
|
|
3
|
-
"version": "1.6.0-beta.
|
|
3
|
+
"version": "1.6.0-beta.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"main": "./lib/index.js",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
+
"@nocobase/lock-manager": "1.6.0-alpha.6",
|
|
9
10
|
"bloom-filters": "^3.0.1",
|
|
10
11
|
"cache-manager": "^5.2.4",
|
|
11
12
|
"cache-manager-redis-yet": "^4.1.2"
|
|
@@ -18,5 +19,5 @@
|
|
|
18
19
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
19
20
|
"directory": "packages/cache"
|
|
20
21
|
},
|
|
21
|
-
"gitHead": "
|
|
22
|
+
"gitHead": "66e7c7239b29361bc60543886d107ba0e00085d9"
|
|
22
23
|
}
|