/** * 统一缓存管理器 * * 管理项目元数据和接口缓存,所有数据存储在 apifox-interfaces-cache.json * 接口只缓存基础信息(id, name, folderPath, docUrl, version),不缓存 method, path, description * * 优化特性: * - 内存缓存:减少 I/O 操作,提升查询性能 * - 延迟保存:只在必要时保存,批量更新时只保存一次 * - 文件锁:防止并发写入导致的数据损坏 * - 索引优化:使用 Map 建立索引,查找时间复杂度 O(1) * - 错误恢复:自动备份损坏的文件 */ import type { ConfigManager } from '../config/manager.js'; /** * 缓存的接口信息(只包含从 llms.txt 解析的基础信息) * 注意:不包含 method, path, description,这些信息每次查询详情时都重新获取 */ export interface CachedInterface { id: string; name: string; folderPath: string; docUrl: string; version?: string; } /** * 项目缓存对象 */ export interface ProjectCache { /** 项目名称 */ projectName: string; /** 项目 ID(字符串) */ projectId: string; /** 分享 ID(shareId),用于通过 URL 查找项目 */ shareId?: string; /** llms.txt URL */ llmsUrls: string; /** 最后更新时间 */ lastUpdated?: string; /** 接口列表(扁平数组) */ interfaces: CachedInterface[]; /** 缓存过期时间(ISO 8601),新增字段 */ cacheExpiresAt?: string; /** llms.txt 内容 Hash(16 位),新增字段 */ llmsContentHash?: string; /** 接口数量(用于快速检测变化),新增字段 */ interfaceCount?: number; } /** * 统一缓存文件结构 */ export type UnifiedCache = ProjectCache[]; /** * 统一缓存管理器 */ export declare class UnifiedCacheManager { private cachePath; private cache; private cacheDirty; private lastLoadTime; private projectNameIndex; private projectIdIndex; private shareIdIndex; private interfaceIndex; constructor(projectRoot: string); /** * 构建索引 */ private buildIndexes; /** * 加载缓存文件(带类型验证) */ private loadCache; /** * 标记缓存为已修改 */ private markDirty; /** * 检查并清理过期的锁文件 */ private checkAndCleanExpiredLock; /** * 保存缓存到文件(带文件锁) * 使用 fs.openSync 的排他模式实现简单的文件锁 */ private saveCache; /** * 同步保存缓存(用于需要立即保存的场景) */ private saveCacheSync; /** * 通过项目名称查找项目(使用索引,O(1) 时间复杂度) */ findProjectByName(projectName: string): ProjectCache | null; /** * 通过项目 ID 查找项目(使用索引,O(1) 时间复杂度) */ findProjectById(projectId: string): ProjectCache | null; /** * 通过分享 ID (shareId) 查找项目(使用索引,O(1) 时间复杂度) */ findProjectByShareId(shareId: string): ProjectCache | null; /** * 获取项目的 llmsUrl */ getLlmsUrl(projectName: string): string | null; /** * 查找接口基础信息(使用索引,O(1) 时间复杂度) * 支持通过 projectName 或 projectId 查找 */ findInterface(projectName: string, interfaceId: string, projectId?: string): CachedInterface | null; /** * 获取项目的接口列表 */ getInterfaces(projectName: string, keyword?: string): CachedInterface[]; /** * 检查缓存是否过期(基于 TTL) * @param project 项目缓存对象 * @param configManager 配置管理器(可选,用于获取 TTL) * @returns 是否过期 */ isCacheExpired(project: ProjectCache, configManager?: ConfigManager): boolean; /** * 计算过期时间 * @param projectId 项目 ID * @param configManager 配置管理器(可选) * @returns ISO 8601 格式的过期时间字符串 */ private calculateExpiresAt; /** * 添加或更新项目元数据 * @param configManager 配置管理器(可选,用于设置 TTL) */ upsertProjectMetadata(projectName: string, projectId: string, llmsUrl: string, shareId?: string, configManager?: ConfigManager): void; /** * 更新项目的接口列表(从 llms.txt 解析) * 支持增量更新:只更新变化的接口 * @param contentHash 内容 Hash(可选,用于版本检测) */ updateInterfacesFromLlms(projectName: string, parsedInterfaces: Array<{ id: string; name: string; folderPath: string; docUrl: string; version?: string; }>, contentHash?: string): void; /** * 列出所有项目 */ listProjects(): Array<{ name: string; id: string; }>; /** * 获取缓存文件路径 */ getCachePath(): string; /** * 获取缓存统计信息 */ getCacheStats(): { projectCount: number; totalInterfaces: number; cacheSize: number; lastUpdated: Date | null; }; /** * 强制保存缓存(用于需要立即保存的场景) */ flush(): Promise; /** * 刷新策略枚举 */ static RefreshStrategy: { readonly LAZY: "lazy"; readonly FORCE: "force"; readonly SKIP: "skip"; }; /** * 检查项目是否需要刷新(基于版本检测) * 性能优化:先检查 TTL,只有未过期时才进行版本检测 */ needsRefresh(project: ProjectCache, configManager?: ConfigManager): Promise<{ needsRefresh: boolean; reason?: 'expired' | 'hash_mismatch' | 'count_mismatch' | 'version_mismatch'; }>; /** * 检查接口版本号是否变化 */ private checkVersionMismatch; /** * 智能刷新项目缓存 * @param projectName 项目名称 * @param configManager 配置管理器(可选) * @param strategy 刷新策略 */ refreshProjectCache(projectName: string, configManager?: ConfigManager, strategy?: 'lazy' | 'force' | 'skip'): Promise<{ refreshed: boolean; reason?: string; interfaceCount?: number; }>; /** * 执行刷新操作 */ private doRefresh; /** * 写入或更新单个接口详情(从 MCP 等来源获取) * - 如果项目不存在且提供了 projectId,则创建一个最小项目记录 * - 如果接口已存在,更新基础信息(name/method/path/description/docUrl/version) * - 如果接口不存在,插入一条记录(docUrl 可为空,后续可由 llms 刷新补齐) */ upsertInterfaceDetail(projectName: string, projectId: string, detail: { id: string; name?: string; method?: string; path?: string; description?: string; docUrl?: string; version?: string; folderPath?: string; }): void; } //# sourceMappingURL=unified-cache-manager.d.ts.map