/**
 * VectorStore — SQLite 기반 벡터 저장소
 *
 * 메모리/세션 엔티티의 임베딩 벡터를 BLOB으로 저장.
 * 검색: 전체 로드 → 앱 레벨 코사인 유사도 → 정렬.
 * (메모리 수 천~만 건 수준이므로 앱 레벨 충분)
 */
import { cosineSimilarity, serializeVector, deserializeVector, } from './cosine.js';
export class VectorStore {
    db;
    constructor(db) {
        this.db = db;
        this.initializeTables();
    }
    initializeTables() {
        this.db.exec(`
      CREATE TABLE IF NOT EXISTS memory_vectors (
        key TEXT PRIMARY KEY,
        embedding BLOB NOT NULL,
        dimension INTEGER NOT NULL,
        updatedAt TEXT NOT NULL
      );

      CREATE TABLE IF NOT EXISTS session_vectors (
        entityType TEXT NOT NULL,
        entityId INTEGER NOT NULL,
        embedding BLOB NOT NULL,
        dimension INTEGER NOT NULL,
        updatedAt TEXT NOT NULL,
        PRIMARY KEY (entityType, entityId)
      );
    `);
    }
    /**
     * 메모리 벡터 저장 (upsert)
     */
    saveMemoryVector(key, embedding) {
        const blob = serializeVector(embedding);
        const now = new Date().toISOString();
        this.db.prepare(`
      INSERT OR REPLACE INTO memory_vectors (key, embedding, dimension, updatedAt)
      VALUES (?, ?, ?, ?)
    `).run(key, blob, embedding.length, now);
    }
    /**
     * 세션 엔티티 벡터 저장 (upsert)
     */
    saveSessionVector(entityType, entityId, embedding) {
        const blob = serializeVector(embedding);
        const now = new Date().toISOString();
        this.db.prepare(`
      INSERT OR REPLACE INTO session_vectors (entityType, entityId, embedding, dimension, updatedAt)
      VALUES (?, ?, ?, ?, ?)
    `).run(entityType, entityId, blob, embedding.length, now);
    }
    /**
     * 메모리 벡터 삭제
     */
    deleteMemoryVector(key) {
        this.db.prepare('DELETE FROM memory_vectors WHERE key = ?').run(key);
    }
    /**
     * 세션 엔티티 벡터 삭제
     */
    deleteSessionVector(entityType, entityId) {
        this.db.prepare('DELETE FROM session_vectors WHERE entityType = ? AND entityId = ?').run(entityType, entityId);
    }
    /**
     * 메모리 벡터 코사인 유사도 검색
     */
    searchMemoryVectors(queryVec, limit = 20) {
        const rows = this.db.prepare('SELECT key, embedding FROM memory_vectors').all();
        const queryFloat = new Float32Array(queryVec);
        return rows
            .map(row => ({
            key: row.key,
            similarity: cosineSimilarity(queryFloat, deserializeVector(row.embedding)),
        }))
            .sort((a, b) => b.similarity - a.similarity)
            .slice(0, limit);
    }
    /**
     * 세션 엔티티 벡터 코사인 유사도 검색
     */
    searchSessionVectors(entityType, queryVec, limit = 20) {
        const rows = this.db.prepare('SELECT entityId, embedding FROM session_vectors WHERE entityType = ?').all(entityType);
        const queryFloat = new Float32Array(queryVec);
        return rows
            .map(row => ({
            entityType,
            entityId: row.entityId,
            similarity: cosineSimilarity(queryFloat, deserializeVector(row.embedding)),
        }))
            .sort((a, b) => b.similarity - a.similarity)
            .slice(0, limit);
    }
    /**
     * 저장된 메모리 벡터 수
     */
    getMemoryVectorCount() {
        const row = this.db.prepare('SELECT COUNT(*) as cnt FROM memory_vectors').get();
        return row.cnt;
    }
    /**
     * 저장된 세션 벡터 수
     */
    getSessionVectorCount(entityType) {
        if (entityType) {
            const row = this.db.prepare('SELECT COUNT(*) as cnt FROM session_vectors WHERE entityType = ?').get(entityType);
            return row.cnt;
        }
        const row = this.db.prepare('SELECT COUNT(*) as cnt FROM session_vectors').get();
        return row.cnt;
    }
}
//# sourceMappingURL=VectorStore.js.map