import { randomUUID } from "node:crypto"; import type { MemoryNotFoundError, MemoryStore } from "./memory-store.js"; import { failure, type Result, success } from "./result.js"; import type { Memory, MemoryCreateInput, MemoryFilter, MemoryUpdateInput, } from "./types.js"; function generateId(): string { return randomUUID(); } function memoryNotFoundError(memoryId: string): MemoryNotFoundError { return { type: "MEMORY_NOT_FOUND", memoryId }; } function matchesFilter(memory: Memory, filter: MemoryFilter): boolean { if (filter.projectId && memory.projectId !== filter.projectId) { return false; } if (filter.folderId && memory.folderId !== filter.folderId) { return false; } if (filter.tags && filter.tags.length > 0) { const memoryTagIds = new Set(memory.tags.map((tag) => tag.id)); const hasAllTags = filter.tags.every((tagId) => memoryTagIds.has(tagId)); if (!hasAllTags) { return false; } } return true; } export class InMemoryStore implements MemoryStore { private memories: Map = new Map(); async create(input: MemoryCreateInput): Promise { const now = new Date(); const memory: Memory = { id: generateId(), content: input.content, projectId: input.projectId, folderId: input.folderId ?? null, tags: input.tags ?? [], metadata: input.metadata ?? {}, createdAt: now, updatedAt: now, }; this.memories.set(memory.id, memory); return memory; } async read(id: string): Promise> { const memory = this.memories.get(id); if (!memory) { return failure(memoryNotFoundError(id)); } return success(memory); } async update( id: string, input: MemoryUpdateInput, ): Promise> { const existing = this.memories.get(id); if (!existing) { return failure(memoryNotFoundError(id)); } const updated: Memory = { ...existing, content: input.content ?? existing.content, projectId: input.projectId !== undefined ? input.projectId : existing.projectId, folderId: input.folderId !== undefined ? input.folderId : existing.folderId, tags: input.tags ?? existing.tags, metadata: input.metadata ?? existing.metadata, updatedAt: new Date(), }; this.memories.set(id, updated); return success(updated); } async delete(id: string): Promise> { if (!this.memories.has(id)) { return failure(memoryNotFoundError(id)); } this.memories.delete(id); return success(undefined); } async list(filter?: MemoryFilter): Promise { const allMemories = Array.from(this.memories.values()); if (!filter) { return allMemories; } return allMemories.filter((memory) => matchesFilter(memory, filter)); } }