← Files RivetARCHIVED FILE
node_modules/rivet-design/dist/services/ProjectMetadataStore.js
6 KB · Nov 7, 2026 · 13:16 UTC
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectMetadataStore = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const ProjectStorage_1 = require("./ProjectStorage");
const logger_1 = require("../utils/logger");
const ProjectMetadataRecords_1 = require("../storage/project-metadata/ProjectMetadataRecords");
const migrations_1 = require("../storage/project-metadata/migrations");
const log = (0, logger_1.createLogger)('ProjectMetadataStore');
const DATABASE_FILENAME = 'rivet.db';
const DATABASE_SIBLING_SUFFIXES = ['-wal', '-shm'];
const VARIANT_INDEX_STATE_KEY = 'variant_index_state';
const VARIANT_INDEX_READY = 'ready';
const VARIANT_INDEX_STALE = 'stale';
const VARIANTS_UI_STATE_KEY = 'variants_ui_state';
class ProjectMetadataStore {
storage;
handles = new Map();
staleOverrides = new Set();
migrations;
constructor(migrations = migrations_1.PROJECT_METADATA_MIGRATIONS, storage = new ProjectStorage_1.ProjectStorage()) {
this.storage = storage;
this.migrations = migrations;
}
databasePath(projectPath) {
return path_1.default.join(this.storage.resolve(projectPath).dataDirectory, DATABASE_FILENAME);
}
hasDatabase(projectPath) {
return fs_1.default.existsSync(this.databasePath(projectPath));
}
async initialize(projectPath) {
await this.openDatabase(projectPath);
}
async upsertVariantFromManifest(args) {
const db = await this.openDatabase(args.projectPath);
db.upsert(args);
}
async rebuildVariantIndex(args) {
const db = await this.openDatabase(args.projectPath);
db.transaction(() => {
db.clearVariants();
for (const entry of args.entries)
db.upsert(entry);
db.writeState(VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_READY);
});
this.staleOverrides.delete(path_1.default.resolve(args.projectPath));
}
async isVariantIndexReady(projectPath) {
if (this.staleOverrides.has(path_1.default.resolve(projectPath)))
return false;
if (!this.handles.has(path_1.default.resolve(projectPath))) {
if (!this.hasDatabase(projectPath))
return false;
}
const db = await this.openDatabase(projectPath);
return db.readState(VARIANT_INDEX_STATE_KEY) === VARIANT_INDEX_READY;
}
async markVariantIndexStale(projectPath) {
this.staleOverrides.add(path_1.default.resolve(projectPath));
try {
const db = await this.openDatabase(projectPath);
db.writeState(VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_STALE);
}
catch (err) {
log.warn(`markVariantIndexStale: durable stale flag failed for ${projectPath} — the in-memory override still forces a rebuild in this process`, err);
}
}
async listVariants(args) {
const db = await this.openDatabase(args.projectPath);
return db.list({ status: args.status, limit: args.limit });
}
async searchVariants(args) {
const db = await this.openDatabase(args.projectPath);
return db.search({ query: args.query, limit: args.limit });
}
async readVariantsUiState(projectPath) {
if (!this.hasDatabase(projectPath))
return null;
const db = await this.openDatabase(projectPath);
return db.readState(VARIANTS_UI_STATE_KEY);
}
async writeVariantsUiState(projectPath, json) {
const db = await this.openDatabase(projectPath);
db.writeState(VARIANTS_UI_STATE_KEY, json);
}
closeAll() {
for (const [key, db] of this.handles) {
try {
db.close();
}
catch (err) {
log.warn(`closeAll: failed to close database for ${key}`, err);
}
}
this.handles.clear();
}
async openDatabase(projectPath) {
const key = path_1.default.resolve(projectPath);
const dbPath = this.databasePath(key);
const existing = this.handles.get(key);
if (existing) {
if (fs_1.default.existsSync(dbPath))
return existing;
try {
existing.close();
}
catch (err) {
log.warn(`openDatabase: failed to close stale handle for ${key}`, err);
}
this.handles.delete(key);
}
fs_1.default.mkdirSync(path_1.default.dirname(dbPath), { recursive: true });
let db;
try {
db = await ProjectMetadataRecords_1.ProjectMetadataRecords.open(dbPath, this.migrations);
}
catch (err) {
if (err instanceof migrations_1.UnsupportedSchemaVersionError)
throw err;
log.warn(`openDatabase: ${dbPath} is unreadable — recreating the projection`, err);
this.deleteDatabaseFiles(dbPath);
db = await ProjectMetadataRecords_1.ProjectMetadataRecords.open(dbPath, this.migrations);
}
if (db.wasUpgraded) {
this.staleOverrides.add(key);
try {
db.writeState(VARIANT_INDEX_STATE_KEY, VARIANT_INDEX_STALE);
}
catch (err) {
log.warn(`openDatabase: durable stale flag failed after upgrading ${dbPath}`, err);
}
}
this.handles.set(key, db);
return db;
}
deleteDatabaseFiles(dbPath) {
for (const target of [
dbPath,
...DATABASE_SIBLING_SUFFIXES.map((suffix) => `${dbPath}${suffix}`),
]) {
try {
fs_1.default.rmSync(target, { force: true });
}
catch (err) {
log.warn(`deleteDatabaseFiles: failed to remove ${target}`, err);
}
}
}
}
exports.ProjectMetadataStore = ProjectMetadataStore;
//# sourceMappingURL=ProjectMetadataStore.js.mapSHA-256: 80d07dbea0f8ca935283aae7d87c0b57efa2848edae9a99194985822b2ca47d7