UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

171 lines (170 loc) • 6.45 kB
import { t as executeExistingOpenClawStateRead } from "./openclaw-state-db-readonly-ywwvuxdQ.mjs"; import { o as runOpenClawStateWorkerOperation } from "./openclaw-state-worker-store-BxZXTKna.mjs"; import { n as withOpenClawStateLeaseAsync } from "./openclaw-state-lease-BVIgxmmg.mjs"; import { i as withOpenClawStateLeasesWorkerAdmission } from "./openclaw-state-lease-worker-owner-BhM4d-xx.mjs"; import { c as withWorktreeRunEnd, i as captureWorktreeRunEndContext, o as retainWorktreeRunEndFailure } from "./run-end-lifecycle-CRbsD4Aj.mjs"; import { randomUUID } from "node:crypto"; //#region src/gateway/worker-environments/local-workspace-store.ts async function hasLocalWorkspaceProjection(id, env) { const reply = await executeExistingOpenClawStateRead({ env }, { type: "localWorkspace.exists", input: { id } }, { current: true, live: true }); if (!reply) return false; if (!reply.ok || reply.type !== "localWorkspace.exists") throw new Error("Unexpected local workspace result"); return reply.exists; } /** The reconciliation lease owns present and absent rows through effects and settlement. */ function withLocalWorkspaceStore(params, run) { const env = params.env ?? process.env; const captured = captureWorktreeRunEndContext(env); const inherited = params.workerAuthority?.leaseSet; const mutationWorktreeIds = inherited?.mutationWorktreeIds?.slice(); const context = inherited?.context ?? captured; if (context.admission.coordinationKey !== captured.admission.coordinationKey) throw new Error("Local workspace lease belongs to another database"); return withWorktreeRunEnd(env, () => withOpenClawStateLeaseAsync({ scope: "workspace.local-reconciliation", key: params.worktreeId, leaseMs: 6e4, waitMs: 6e5, leaseLabel: "local sandbox workspace", operationLabel: "workspace.local-reconciliation" }, context, (lease) => { const leases = [...inherited?.leases ?? [], lease]; return withOpenClawStateLeasesWorkerAdmission(leases, context, async (authority) => { let active = true; let pending = false; const assertHost = () => { captured.admission.assertCurrent(); authority.assertCurrent(); if (!active) throw new Error("Local workspace custody has ended"); (params.workerAuthority ? params.workerAuthority.assertCurrent : params.assertCurrent)?.(); }; const assertCurrent = () => { assertHost(); if (pending) throw new Error("Local workspace publication has not settled"); params.assertCurrent?.(); }; try { return await runOpenClawStateWorkerOperation(context, async () => { const reply = await executeExistingOpenClawStateRead({ path: context.admission.databasePath, env: context.environment }, { type: params.requireAbsent ? "localWorkspace.exists" : "localWorkspace.get", input: { id: params.worktreeId } }, { context, current: true, live: true }); if (reply && (!reply.ok || reply.type !== (params.requireAbsent ? "localWorkspace.exists" : "localWorkspace.get"))) throw new Error("Unexpected local workspace result"); assertCurrent(); if (reply?.type === "localWorkspace.exists" && reply.exists) throw new Error("Snapshot retains local workspace projection custody; preserve its recovery data"); let row = reply?.type === "localWorkspace.get" && reply.row ? Object.freeze(reply.row) : void 0; const mutate = async (mutation, next, guard = params.workerAuthority ?? {}) => { assertCurrent(); const capturedMutation = structuredClone(mutation); const postimage = next && Object.freeze(structuredClone(next)); const receipt = randomUUID(); let admission; let settled; const predicates = structuredClone(guard.predicates); const assertWrite = () => { assertHost(); guard.assertCurrent?.(); }; pending = true; try { const acknowledged = await withOpenClawStateLeasesWorkerAdmission(leases, context, (write) => runOpenClawStateWorkerOperation(context, (scope) => scope.execute({ type: "localWorkspace.mutate", input: { id: params.worktreeId, mutation: capturedMutation, predicates, leases: write.identities, receipt } }), { assertCurrent: assertWrite, createAdmission(operation) { settled = operation.settled; const result = write.createAdmission(operation); admission = result.admission; return result; } }), { assertCurrent: assertWrite }); row = acknowledged && Object.freeze(acknowledged); } catch (error) { if ((await settled)?.kind === "completed" && admission?.committed?.facts === receipt) row = postimage; else { active = false; retainWorktreeRunEndFailure(error); throw error; } } finally { pending = false; } }; return await run({ signal: lease.signal, assertCurrent, workerAuthority: { ...params.workerAuthority, leaseSet: { context, leases, mutationWorktreeIds }, assertCurrent: assertHost }, get: () => { assertHost(); if (pending) throw new Error("Local workspace publication has not settled"); return row; }, create: async (value, guard) => { const next = { ...value, revision: 0 }; await mutate({ kind: "create", row: value }, next, guard); return row; }, update: async (previous, patch, guard) => { if (previous.worktree_id !== params.worktreeId) throw new Error("Local workspace binding changed"); await mutate({ kind: "update", revision: previous.revision, patch }, { ...previous, ...patch, worktree_id: params.worktreeId, revision: previous.revision + 1 }, guard); return row; }, delete: async (previous, guard) => { if (previous.worktree_id !== params.worktreeId) throw new Error("Local workspace binding changed"); await mutate({ kind: "delete", revision: previous.revision }, void 0, guard); } }); }, { assertCurrent: assertHost }); } finally { active = false; } }); })); } //#endregion export { withLocalWorkspaceStore as n, hasLocalWorkspaceProjection as t };