* refactor: move Discord channel implementation to extensions/discord/src/ Move all Discord source files from src/discord/ to extensions/discord/src/, following the extension migration pattern. Source files in src/discord/ are replaced with re-export shims. Channel-plugin files from src/channels/plugins/*/discord* are similarly moved and shimmed. - Copy all .ts source files preserving subdirectory structure (monitor/, voice/) - Move channel-plugin files (actions, normalize, onboarding, outbound, status-issues) - Fix all relative imports to use correct paths from new location - Create re-export shims at original locations for backward compatibility - Delete test files from shim locations (tests live in extension now) - Update tsconfig.plugin-sdk.dts.json rootDir from "src" to "." to accommodate extension files outside src/ - Update write-plugin-sdk-entry-dts.ts to match new declaration output paths * fix: add importOriginal to thread-bindings session-meta mock for extensions test * style: fix formatting in thread-bindings lifecycle test
62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
import type { GatewayPresenceUpdate } from "discord-api-types/v10";
|
|
|
|
/**
|
|
* In-memory cache of Discord user presence data.
|
|
* Populated by PRESENCE_UPDATE gateway events when the GuildPresences intent is enabled.
|
|
* Per-account maps are capped to prevent unbounded growth (#4948).
|
|
*/
|
|
const MAX_PRESENCE_PER_ACCOUNT = 5000;
|
|
const presenceCache = new Map<string, Map<string, GatewayPresenceUpdate>>();
|
|
|
|
function resolveAccountKey(accountId?: string): string {
|
|
return accountId ?? "default";
|
|
}
|
|
|
|
/** Update cached presence for a user. */
|
|
export function setPresence(
|
|
accountId: string | undefined,
|
|
userId: string,
|
|
data: GatewayPresenceUpdate,
|
|
): void {
|
|
const accountKey = resolveAccountKey(accountId);
|
|
let accountCache = presenceCache.get(accountKey);
|
|
if (!accountCache) {
|
|
accountCache = new Map();
|
|
presenceCache.set(accountKey, accountCache);
|
|
}
|
|
accountCache.set(userId, data);
|
|
// Evict oldest entries if cache exceeds limit
|
|
if (accountCache.size > MAX_PRESENCE_PER_ACCOUNT) {
|
|
const oldest = accountCache.keys().next().value;
|
|
if (oldest !== undefined) {
|
|
accountCache.delete(oldest);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Get cached presence for a user. Returns undefined if not cached. */
|
|
export function getPresence(
|
|
accountId: string | undefined,
|
|
userId: string,
|
|
): GatewayPresenceUpdate | undefined {
|
|
return presenceCache.get(resolveAccountKey(accountId))?.get(userId);
|
|
}
|
|
|
|
/** Clear cached presence data. */
|
|
export function clearPresences(accountId?: string): void {
|
|
if (accountId) {
|
|
presenceCache.delete(resolveAccountKey(accountId));
|
|
return;
|
|
}
|
|
presenceCache.clear();
|
|
}
|
|
|
|
/** Get the number of cached presence entries. */
|
|
export function presenceCacheSize(): number {
|
|
let total = 0;
|
|
for (const accountCache of presenceCache.values()) {
|
|
total += accountCache.size;
|
|
}
|
|
return total;
|
|
}
|