UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

68 lines (67 loc) • 3.32 kB
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 };