Files
openclaw/src/plugins/plugin-cache-primitives.ts
T
2026-05-02 06:22:28 +01:00

103 lines
2.6 KiB
TypeScript

import type { OpenClawConfig } from "../config/types.openclaw.js";
export type PluginLruCacheResult<T> = { hit: true; value: T } | { hit: false };
export class PluginLruCache<T> {
readonly #defaultMaxEntries: number;
#maxEntries: number;
readonly #entries = new Map<string, T>();
constructor(defaultMaxEntries: number) {
this.#defaultMaxEntries = normalizeMaxEntries(defaultMaxEntries, 1);
this.#maxEntries = this.#defaultMaxEntries;
}
get maxEntries(): number {
return this.#maxEntries;
}
get size(): number {
return this.#entries.size;
}
setMaxEntriesForTest(value?: number): void {
this.#maxEntries =
typeof value === "number"
? normalizeMaxEntries(value, this.#defaultMaxEntries)
: this.#defaultMaxEntries;
this.#evictOldestEntries();
}
clear(): void {
this.#entries.clear();
}
get(cacheKey: string): T | undefined {
const cached = this.getResult(cacheKey);
return cached.hit ? cached.value : undefined;
}
getResult(cacheKey: string): PluginLruCacheResult<T> {
if (!this.#entries.has(cacheKey)) {
return { hit: false };
}
const cached = this.#entries.get(cacheKey) as T;
this.#entries.delete(cacheKey);
this.#entries.set(cacheKey, cached);
return { hit: true, value: cached };
}
set(cacheKey: string, value: T): void {
if (this.#entries.has(cacheKey)) {
this.#entries.delete(cacheKey);
}
this.#entries.set(cacheKey, value);
this.#evictOldestEntries();
}
#evictOldestEntries(): void {
while (this.#entries.size > this.#maxEntries) {
const oldestEntry = this.#entries.keys().next();
if (oldestEntry.done) {
break;
}
this.#entries.delete(oldestEntry.value);
}
}
}
export type ConfigScopedRuntimeCache<T> = WeakMap<OpenClawConfig, Map<string, T>>;
export function resolveConfigScopedRuntimeCacheValue<T>(params: {
cache: ConfigScopedRuntimeCache<T>;
config?: OpenClawConfig;
key: string;
load: () => T;
}): T {
if (!params.config) {
return params.load();
}
let configCache = params.cache.get(params.config);
if (!configCache) {
configCache = new Map();
params.cache.set(params.config, configCache);
}
if (configCache.has(params.key)) {
return configCache.get(params.key) as T;
}
const loaded = params.load();
configCache.set(params.key, loaded);
return loaded;
}
export function createPluginCacheKey(parts: readonly unknown[]): string {
return JSON.stringify(parts);
}
function normalizeMaxEntries(value: number, fallback: number): number {
if (!Number.isFinite(value) || value <= 0) {
return fallback;
}
return Math.max(1, Math.floor(value));
}