openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
68 lines (67 loc) • 3.32 kB
JavaScript
import { a as resolveGlobalSingleton } from "./global-singleton-0m-JziJW.mjs";
import { d as readDatabasePathIdentitySync, s as normalizeDatabasePath } from "./sqlite-worker-identity-BRNRpRyc.mjs";
import { statSync } from "node:fs";
import { randomUUID } from "node:crypto";
//#region src/state/openclaw-agent-db-identity.ts
const identities = resolveGlobalSingleton(Symbol.for("openclaw.agentDatabaseIdentities"), () => /* @__PURE__ */ new WeakMap());
/** Prepare physical and connection identity once at open; cached aliases are not resolved again. */
function registerOpenClawAgentDatabaseIdentity(db) {
const filename = normalizeDatabasePath(db.location() ?? "");
const file = filename ? readDatabasePathIdentitySync(filename) : void 0;
if (file && !file.key.startsWith("file:")) throw new Error("OpenClaw agent database disappeared before identity registration");
const identity = file ? file.key.slice(5) : Symbol("incognito-agent-database");
identities.set(db, {
identity,
birthtime: file?.birthtime,
incarnation: randomUUID(),
filename,
canonicalPath: file?.canonicalPath ?? filename
});
}
/** Reuse facts captured at open; aliases must never be resolved again at a handoff. */
function readOpenClawAgentDatabaseIdentity(database) {
const prepared = findOpenClawAgentDatabaseIdentity(database);
if (prepared === void 0) throw new Error("OpenClaw agent database identity was not prepared at open");
return prepared;
}
/** Raw diagnostic connections have no admitted physical identity. */
function findOpenClawAgentDatabaseIdentity(database) {
return identities.get(database.db);
}
/** A retained connection can outlive its pathname or be deserialized away from that file. */
function isOpenClawAgentDatabasePathCurrent(database) {
if (!database.db.isOpen) return false;
const { identity, filename } = readOpenClawAgentDatabaseIdentity(database);
if (typeof identity === "symbol") return true;
if (normalizeDatabasePath(database.db.location() ?? "") !== filename) return false;
const current = statSync(database.path, {
bigint: true,
throwIfNoEntry: false
});
return current !== void 0 && identity === `${current.dev}:${current.ino}`;
}
function assertOpenClawAgentDatabaseIdentity(database, expected) {
const identity = readOpenClawAgentDatabaseIdentity(database);
if (`file:${String(identity.identity)}` !== expected.key || expected.birthtime !== void 0 && identity.birthtime !== expected.birthtime || !isOpenClawAgentDatabasePathCurrent(database)) throw new Error("Agent database changed during repair admission");
}
function createOpenClawAgentDatabaseClaim(database, release) {
let released = false;
const isCurrent = () => !released && database.db.isOpen;
const { identity, incarnation } = readOpenClawAgentDatabaseIdentity(database);
return {
identity,
incarnation,
isCurrent,
assertCurrent: () => {
if (!isCurrent()) throw new Error("OpenClaw agent database claim is no longer current");
},
release: () => {
if (!released) {
released = true;
release();
}
}
};
}
//#endregion
export { readOpenClawAgentDatabaseIdentity as a, isOpenClawAgentDatabasePathCurrent as i, createOpenClawAgentDatabaseClaim as n, registerOpenClawAgentDatabaseIdentity as o, findOpenClawAgentDatabaseIdentity as r, assertOpenClawAgentDatabaseIdentity as t };