import { resolveGlobalMap } from "openclaw/plugin-sdk/global-singleton" ;
import type { DiscordComponentEntry, DiscordModalEntry } from "./components.js" ;
const DEFAULT_COMPONENT_TTL_MS = 30 * 60 * 1000 ;
const DISCORD_COMPONENT_ENTRIES_KEY = Symbol.for ("openclaw.discord.componentEntries" );
const DISCORD_MODAL_ENTRIES_KEY = Symbol.for ("openclaw.discord.modalEntries" );
let componentEntries: Map<string, DiscordComponentEntry> | undefined;
let modalEntries: Map<string, DiscordModalEntry> | undefined;
function getComponentEntries(): Map<string, DiscordComponentEntry> {
componentEntries ??= resolveGlobalMap<string, DiscordComponentEntry>(
DISCORD_COMPONENT_ENTRIES_KEY,
);
return componentEntries;
}
function getModalEntries(): Map<string, DiscordModalEntry> {
modalEntries ??= resolveGlobalMap<string, DiscordModalEntry>(DISCORD_MODAL_ENTRIES_KEY);
return modalEntries;
}
function isExpired(entry: { expiresAt?: number }, now: number) {
return typeof entry.expiresAt === "number" && entry.expiresAt <= now;
}
function normalizeEntryTimestamps<T extends { createdAt?: number; expiresAt?: number }>(
entry: T,
now: number,
ttlMs: number,
): T {
const createdAt = entry.createdAt ?? now;
const expiresAt = entry.expiresAt ?? createdAt + ttlMs;
return { ...entry, createdAt, expiresAt };
}
function registerEntries<
T extends { id: string; messageId?: string; createdAt?: number; expiresAt?: number },
>(
entries: T[],
store: Map<string, T>,
params: { now: number; ttlMs: number; messageId?: string },
): void {
for (const entry of entries) {
const normalized = normalizeEntryTimestamps(
{ ...entry, messageId: params.messageId ?? entry.messageId },
params.now,
params.ttlMs,
);
store.set(entry.id, normalized);
}
}
function resolveEntry<T extends { expiresAt?: number }>(
store: Map<string, T>,
params: { id: string; consume?: boolean },
): T | null {
const entry = store.get(params.id);
if (!entry) {
return null ;
}
const now = Date.now();
if (isExpired(entry, now)) {
store.delete (params.id);
return null ;
}
if (params.consume !== false ) {
store.delete (params.id);
}
return entry;
}
export function registerDiscordComponentEntries(params: {
entries: DiscordComponentEntry[];
modals: DiscordModalEntry[];
ttlMs?: number;
messageId?: string;
}): void {
const now = Date.now();
const ttlMs = params.ttlMs ?? DEFAULT_COMPONENT_TTL_MS;
registerEntries(params.entries, getComponentEntries(), {
now,
ttlMs,
messageId: params.messageId,
});
registerEntries(params.modals, getModalEntries(), { now, ttlMs, messageId: params.messageId });
}
export function resolveDiscordComponentEntry(params: {
id: string;
consume?: boolean ;
}): DiscordComponentEntry | null {
return resolveEntry(getComponentEntries(), params);
}
export function resolveDiscordModalEntry(params: {
id: string;
consume?: boolean ;
}): DiscordModalEntry | null {
return resolveEntry(getModalEntries(), params);
}
export function clearDiscordComponentEntries(): void {
getComponentEntries().clear();
getModalEntries().clear();
}
Messung V0.5 in Prozent C=100 H=98 G=98
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland