openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
68 lines (67 loc) • 2.13 kB
JavaScript
import { M as resolveNonNegativeIntegerOption } from "./number-coercion-CLj0HTDM.js";
import { i as resolveGlobalSingleton } from "./global-singleton-Dc_stLtU.js";
import { t as pruneMapToMaxSize } from "./map-size-CNcWiFKu.js";
//#region src/infra/dedupe.ts
/** Creates a bounded in-memory dedupe cache with optional TTL expiry. */
function createDedupeCache(options) {
const ttlMs = resolveNonNegativeIntegerOption(options.ttlMs, 0);
const maxSize = resolveNonNegativeIntegerOption(options.maxSize, 0);
const cache = /* @__PURE__ */ new Map();
const prune = (now) => {
const cutoff = ttlMs > 0 ? now - ttlMs : void 0;
if (cutoff !== void 0) {
for (const [entryKey, entry] of cache) if (entry.recordedAt <= cutoff) cache.delete(entryKey);
}
if (maxSize <= 0) {
cache.clear();
return;
}
pruneMapToMaxSize(cache, maxSize);
};
const hasUnexpired = (key, now, touchOnRead) => {
const existing = cache.get(key);
if (!existing) return false;
if (ttlMs > 0 && now - existing.recordedAt >= ttlMs) {
cache.delete(key);
return false;
}
if (touchOnRead) {
existing.recordedAt = now;
cache.delete(key);
cache.set(key, existing);
}
return true;
};
return {
check: (key, now, ownerToken) => {
if (!key) return false;
const checkedAt = now ?? Date.now();
if (hasUnexpired(key, checkedAt, true)) return true;
cache.set(key, {
recordedAt: checkedAt,
...ownerToken ? { ownerToken } : {}
});
prune(checkedAt);
return false;
},
peek: (key, now = Date.now()) => {
if (!key) return false;
return hasUnexpired(key, now, false);
},
delete: (key, ownerToken) => {
if (!key) return;
if (ownerToken && cache.get(key)?.ownerToken !== ownerToken) return;
cache.delete(key);
},
clear: () => {
cache.clear();
},
size: () => cache.size
};
}
/** Resolves a process-global dedupe cache for hot paths that can load this module twice. */
function resolveGlobalDedupeCache(key, options) {
return resolveGlobalSingleton(key, () => createDedupeCache(options));
}
//#endregion
export { resolveGlobalDedupeCache as n, createDedupeCache as t };