openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
56 lines (55 loc) • 2.47 kB
JavaScript
import { O as parseAgentSessionKey } from "./session-key-BnWWjqNc.js";
import "./operator-scopes-Dw7Gu2cA.js";
import { r as authorizeOperatorScopesForRequiredScope } from "./method-scopes-K6J_UQGL.js";
import { g as isGatewayClientProfilePending } from "./operator-role-policy-wsr1DeJv.js";
import { c as resolveCanonicalSessionStoreMatchFromStoreKeys, f as resolveGatewaySessionStoreTargetWithStore } from "./session-utils-store-CInT2loy.js";
import { F as isGatewayAdmin, i as prepareSessionSharing } from "./session-sharing-B7MI8hNo.js";
//#region src/gateway/presence-projection.ts
/** One synchronous snapshot/fanout owns these reads; never reuse them across broadcasts. */
function createPresenceRecipientProjection(params) {
const targets = /* @__PURE__ */ new Map();
const targetDiscoveryCache = /* @__PURE__ */ new Map();
const resolveTarget = (sessionKey) => {
if (!targets.has(sessionKey)) {
const parsed = parseAgentSessionKey(sessionKey);
const key = parsed?.rest === "global" || parsed?.rest === "unknown" ? parsed.rest : sessionKey;
const target = resolveGatewaySessionStoreTargetWithStore({
cfg: params.cfg,
key,
agentId: parsed?.agentId,
readOnly: true,
exactRead: true,
clone: false,
targetDiscoveryCache
});
const match = resolveCanonicalSessionStoreMatchFromStoreKeys(target.store, target.storeKeys);
targets.set(sessionKey, match ? {
canonicalKey: target.canonicalKey,
entry: match.entry
} : void 0);
}
return targets.get(sessionKey);
};
return (client) => {
if (!client?.connect || (client.connect.role ?? "operator") !== "operator" || !authorizeOperatorScopesForRequiredScope("operator.read", client.connect.scopes ?? []).allowed) return [];
const canReadSessions = isGatewayAdmin(client) || !isGatewayClientProfilePending(client);
const entryFilter = canReadSessions ? prepareSessionSharing({
cfg: params.cfg,
client
}).entryFilter : void 0;
return params.presence.map((row) => {
if (!row.watchedSessions) return row;
const watchedSessions = canReadSessions ? row.watchedSessions.filter((key) => {
const target = resolveTarget(key);
return target && (entryFilter?.(target.canonicalKey, target.entry) ?? true);
}) : [];
const { watchedSessions: _watchedSessions, ...person } = row;
return watchedSessions.length ? {
...person,
watchedSessions
} : person;
});
};
}
//#endregion
export { createPresenceRecipientProjection as t };