openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
171 lines (170 loc) • 6.45 kB
JavaScript
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 };