75 lines
1.5 KiB
JavaScript
Raw Normal View History

/**
* 简单 TTL 缓存
* GH-GMP-005 · M1 · Notion Sync Layer
*
* 用于缓存人格页面工单内容等减少Notion API调用
*/
'use strict';
const DEFAULT_TTL_MS = 10 * 60 * 1000; // 10分钟
const DEFAULT_MAX_SIZE = 200;
class TTLCache {
/**
* @param {object} [opts]
* @param {number} [opts.ttlMs] - 缓存过期时间
* @param {number} [opts.maxSize] - 最大缓存条目数
*/
constructor(opts = {}) {
this.ttlMs = opts.ttlMs || DEFAULT_TTL_MS;
this.maxSize = opts.maxSize || DEFAULT_MAX_SIZE;
this._store = new Map();
}
get(key) {
const entry = this._store.get(key);
if (!entry) return undefined;
if (Date.now() - entry.ts > this.ttlMs) {
this._store.delete(key);
return undefined;
}
return entry.value;
}
set(key, value) {
// LRU-ish: 超过容量时删除最旧的
if (this._store.size >= this.maxSize) {
const oldest = this._store.keys().next().value;
this._store.delete(oldest);
}
this._store.set(key, { value, ts: Date.now() });
}
has(key) {
return this.get(key) !== undefined;
}
delete(key) {
this._store.delete(key);
}
clear() {
this._store.clear();
}
get size() {
// 清理过期
const now = Date.now();
for (const [k, v] of this._store) {
if (now - v.ts > this.ttlMs) this._store.delete(k);
}
return this._store.size;
}
get stats() {
return {
size: this.size,
maxSize: this.maxSize,
ttlMs: this.ttlMs,
};
}
}
module.exports = TTLCache;