openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
169 lines (168 loc) • 8.72 kB
JavaScript
import { c as isRecord } from "../../record-coerce-TIsquoVR.mjs";
import { d as readDatabasePathIdentitySync } from "../../sqlite-worker-identity-BRNRpRyc.mjs";
import { s as OPENCLAW_SQLITE_BUSY_TIMEOUT_MS } from "../../openclaw-state-db-contract-BYv0nUQr.mjs";
import { c as withSqlitePostCommitPublications } from "../../sqlite-post-commit-DENvzR6w.mjs";
import { r as runSqliteDeferredTransactionSync, s as runSqliteWorkerTransactionSync, t as assertTransactionUsable } from "../../sqlite-transaction-DBRLvCDM.mjs";
import { a as readOpenClawAgentDatabaseIdentity } from "../../openclaw-agent-db-identity-BlmER9-X.mjs";
import { l as resolveOpenClawAgentSqlitePath } from "../../openclaw-agent-db.paths-BbmZlEP5.mjs";
import { i as deferSqliteWorkerCommitReceipt } from "../../sqlite-worker-operation-admission-C5lBzzTk.mjs";
import { t as captureSessionRowChanges } from "../../session-row-changes-Dj2yVWo-.mjs";
import { i as getOpenClawAgentDatabaseIfOpen } from "../../openclaw-agent-db-DWI9Bgur.mjs";
import { i as toDatabaseOptions } from "../../session-accessor.sqlite-scope-helpers-CfDTAEsL.mjs";
import { t as createSqliteCommitReceipt } from "../../sqlite-commit-receipt-DafgyYOc.mjs";
import { s as resolveSqliteScope } from "../../session-accessor.sqlite-scope-BkgwxatT.mjs";
import { a as readSqliteSessionParticipantProjection } from "../../session-accessor.sqlite-participant-projection-BXRIuuEE.mjs";
import { t as assignSessionOwner } from "../../session-accessor.sqlite-owner-BqW6gmHA.mjs";
import { a as updatePreparedSessionProfileInvolvement, i as recordSessionParticipantFromWorker, n as removeSessionMember, t as addSessionMember } from "../../session-sharing-store.native-DO4w6Chl.mjs";
import { n as assertSessionGroupCategoryDestination, r as prepareSessionGroupCategoryMutation, t as applySessionGroupCategoryMutation } from "../../session-group-categories.kernel-C6PynYJp.mjs";
import { i as releaseSessionSuggestionDispatch, n as claimSessionSuggestionDispatch, r as finalizeSessionSuggestionClaim, t as addSessionSuggestion } from "../../session-suggestion-store-DSkLUMVS.mjs";
//#region src/config/sessions/session-sharing-store.worker.ts
/** The canonical agent executor retains the connection and both live admission checks. */
function bindSqliteWorkerBackend(_input, context) {
const db = context.database;
const source = readOpenClawAgentDatabaseIdentity({ db });
let categoryPlan;
const categoryDatabase = (scope) => {
const database = getOpenClawAgentDatabaseIfOpen(toDatabaseOptions(resolveSqliteScope(scope)));
if (!database || database.db !== db || database.path !== context.databasePath) throw new Error("Session group category write lost its physical store owner");
return database;
};
return {
execute(command) {
const scope = { ...command.input.scope };
const target = resolveOpenClawAgentSqlitePath(toDatabaseOptions(resolveSqliteScope(scope)));
if (!(db.location() ? readDatabasePathIdentitySync(target).canonicalPath === context.databasePath : target === context.databasePath && getOpenClawAgentDatabaseIfOpen(toDatabaseOptions(resolveSqliteScope(scope)))?.db === db)) throw new Error("Session collaboration target changed its database owner");
scope.storePath = context.databasePath;
if (command.type === "category.prepare") {
const database = categoryDatabase(scope);
return withSqlitePostCommitPublications(db, () => runSqliteDeferredTransactionSync(db, () => {
categoryPlan = {
from: command.input.from,
storePath: database.path,
rows: prepareSessionGroupCategoryMutation(database, command.input.from)
};
return [...categoryPlan.rows.keys()];
}));
}
let candidate;
let keys = [scope.sessionKey];
let participantResult;
let membershipResult;
let ownerResult;
return withSqlitePostCommitPublications(db, () => runSqliteWorkerTransactionSync({
...context,
admit(stage) {
context.admit(stage, stage === "commit" && typeof source.identity === "string" ? (request, dispatch) => {
if (!candidate || !isRecord(request.facts)) throw new Error("Session collaboration commit omitted its candidate");
dispatch({
...request,
facts: {
...request.facts,
publication: candidate
}
});
} : void 0);
}
}, () => {
const captured = captureSessionRowChanges(db, () => {
if (command.type === "involvement") return updatePreparedSessionProfileInvolvement(scope, command.input.params, command.input.profiles);
if (command.type === "owner.assign") {
ownerResult = { value: assignSessionOwner(scope, command.input.params) };
return ownerResult;
}
if (command.type === "suggestion.add") return addSessionSuggestion(scope, command.input.params);
if (command.type === "suggestion.claim") return claimSessionSuggestionDispatch(scope, command.input.params);
if (command.type === "suggestion.release") return releaseSessionSuggestionDispatch(scope, command.input.params);
if (command.type === "suggestion.finalize") return finalizeSessionSuggestionClaim(scope, command.input.params);
if (command.type === "category.apply") {
const database = categoryDatabase(scope);
if (!categoryPlan || categoryPlan.from !== command.input.from || categoryPlan.storePath !== database.path) throw new Error("Session group category mutation has no matching prepared rows");
keys = [...categoryPlan.rows.keys()];
return applySessionGroupCategoryMutation(database, categoryPlan.rows, command.input.to, scope.env ?? process.env);
}
if (command.type === "participant") {
participantResult = {
value: recordSessionParticipantFromWorker(scope, command.input.params),
projectionChanged: false,
participants: readSqliteSessionParticipantProjection(db, scope.sessionKey)
};
return participantResult;
}
if (command.type === "add") {
const result = { value: addSessionMember(scope, command.input.params) };
membershipResult = result;
return result;
}
const result = { value: removeSessionMember(scope, command.input.identityId, command.input.expected, command.input.expectedSessionId, command.input.expectedEntry) };
membershipResult = result;
return result;
});
const factsByKey = /* @__PURE__ */ new Map();
const recordFact = (sessionKey, facts) => {
const current = factsByKey.get(sessionKey) ?? [];
current.push(facts);
factsByKey.set(sessionKey, current);
};
for (const change of captured.changes) {
if (!("sessionKey" in change) || !change.facts) continue;
const facts = change.facts;
if (membershipResult && facts.kind === "member") {
membershipResult.facts = facts;
recordFact(change.sessionKey, facts);
} else if (ownerResult && facts.kind === "owner") {
ownerResult.facts = facts;
recordFact(change.sessionKey, facts);
} else if (participantResult && facts.kind === "participants") {
participantResult.projectionChanged = true;
recordFact(change.sessionKey, {
...facts,
projection: participantResult.participants
});
} else if (command.type === "category.apply" && facts.kind === "entry") recordFact(change.sessionKey, {
kind: "category",
sessionId: facts.sessionId,
category: facts.category
});
else if (command.type === "involvement" && facts.kind === "entry") recordFact(change.sessionKey, { kind: "unchanged" });
}
if (typeof source.identity === "string") {
const publication = createSqliteCommitReceipt({
source,
domain: "session-collaboration",
keys,
readFact: (key) => {
const current = factsByKey.get(key);
return current && current.length > 0 ? {
kind: "postimage",
value: current
} : { kind: "unchanged" };
}
});
candidate = {
kind: "session-collaboration-committed",
type: command.type,
result: captured.result,
publication
};
deferSqliteWorkerCommitReceipt(db, candidate);
}
return captured.result;
}, {
operationLabel: `sessions.${command.type}`,
busyTimeoutMs: OPENCLAW_SQLITE_BUSY_TIMEOUT_MS,
databaseLabel: context.databasePath,
withCommit(commit) {
if (command.type === "category.apply") assertSessionGroupCategoryDestination(command.input.to, command.input.scope.env ?? process.env);
commit();
}
}));
},
assertSettled() {
assertTransactionUsable(db);
if (db.isTransaction) throw new Error("Session collaboration transaction did not settle");
},
close() {}
};
}
//#endregion
export { bindSqliteWorkerBackend };