mirror of https://github.com/openclaw/openclaw.git
145 lines
4.1 KiB
TypeScript
145 lines
4.1 KiB
TypeScript
import { getMatrixRuntime } from "../runtime.js";
|
|
import type { CoreConfig } from "../types.js";
|
|
import { getActiveMatrixClient } from "./active-client.js";
|
|
import { acquireSharedMatrixClient, isBunRuntime, resolveMatrixAuthContext } from "./client.js";
|
|
import { releaseSharedClientInstance } from "./client/shared.js";
|
|
import type { MatrixClient } from "./sdk.js";
|
|
|
|
type ResolvedRuntimeMatrixClient = {
|
|
client: MatrixClient;
|
|
stopOnDone: boolean;
|
|
cleanup?: (mode: ResolvedRuntimeMatrixClientStopMode) => Promise<void>;
|
|
};
|
|
|
|
type MatrixRuntimeClientReadiness = "none" | "prepared" | "started";
|
|
type ResolvedRuntimeMatrixClientStopMode = "stop" | "persist";
|
|
|
|
type MatrixResolvedClientHook = (
|
|
client: MatrixClient,
|
|
context: { preparedByDefault: boolean },
|
|
) => Promise<void> | void;
|
|
|
|
async function ensureResolvedClientReadiness(params: {
|
|
client: MatrixClient;
|
|
readiness?: MatrixRuntimeClientReadiness;
|
|
preparedByDefault: boolean;
|
|
}): Promise<void> {
|
|
if (params.readiness === "started") {
|
|
await params.client.start();
|
|
return;
|
|
}
|
|
if (params.readiness === "prepared" || (!params.readiness && params.preparedByDefault)) {
|
|
await params.client.prepareForOneOff();
|
|
}
|
|
}
|
|
|
|
function ensureMatrixNodeRuntime() {
|
|
if (isBunRuntime()) {
|
|
throw new Error("Matrix support requires Node (bun runtime not supported)");
|
|
}
|
|
}
|
|
|
|
async function resolveRuntimeMatrixClient(opts: {
|
|
client?: MatrixClient;
|
|
cfg?: CoreConfig;
|
|
timeoutMs?: number;
|
|
accountId?: string | null;
|
|
onResolved?: MatrixResolvedClientHook;
|
|
}): Promise<ResolvedRuntimeMatrixClient> {
|
|
ensureMatrixNodeRuntime();
|
|
if (opts.client) {
|
|
await opts.onResolved?.(opts.client, { preparedByDefault: false });
|
|
return { client: opts.client, stopOnDone: false };
|
|
}
|
|
|
|
const cfg = opts.cfg ?? (getMatrixRuntime().config.loadConfig() as CoreConfig);
|
|
const authContext = resolveMatrixAuthContext({
|
|
cfg,
|
|
accountId: opts.accountId,
|
|
});
|
|
const active = getActiveMatrixClient(authContext.accountId);
|
|
if (active) {
|
|
await opts.onResolved?.(active, { preparedByDefault: false });
|
|
return { client: active, stopOnDone: false };
|
|
}
|
|
|
|
const client = await acquireSharedMatrixClient({
|
|
cfg,
|
|
timeoutMs: opts.timeoutMs,
|
|
accountId: authContext.accountId,
|
|
startClient: false,
|
|
});
|
|
try {
|
|
await opts.onResolved?.(client, { preparedByDefault: true });
|
|
} catch (err) {
|
|
await releaseSharedClientInstance(client, "stop");
|
|
throw err;
|
|
}
|
|
return {
|
|
client,
|
|
stopOnDone: true,
|
|
cleanup: async (mode) => {
|
|
await releaseSharedClientInstance(client, mode);
|
|
},
|
|
};
|
|
}
|
|
|
|
export async function resolveRuntimeMatrixClientWithReadiness(opts: {
|
|
client?: MatrixClient;
|
|
cfg?: CoreConfig;
|
|
timeoutMs?: number;
|
|
accountId?: string | null;
|
|
readiness?: MatrixRuntimeClientReadiness;
|
|
}): Promise<ResolvedRuntimeMatrixClient> {
|
|
return await resolveRuntimeMatrixClient({
|
|
client: opts.client,
|
|
cfg: opts.cfg,
|
|
timeoutMs: opts.timeoutMs,
|
|
accountId: opts.accountId,
|
|
onResolved: async (client, context) => {
|
|
await ensureResolvedClientReadiness({
|
|
client,
|
|
readiness: opts.readiness,
|
|
preparedByDefault: context.preparedByDefault,
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
export async function stopResolvedRuntimeMatrixClient(
|
|
resolved: ResolvedRuntimeMatrixClient,
|
|
mode: ResolvedRuntimeMatrixClientStopMode = "stop",
|
|
): Promise<void> {
|
|
if (!resolved.stopOnDone) {
|
|
return;
|
|
}
|
|
if (resolved.cleanup) {
|
|
await resolved.cleanup(mode);
|
|
return;
|
|
}
|
|
if (mode === "persist") {
|
|
await resolved.client.stopAndPersist();
|
|
return;
|
|
}
|
|
resolved.client.stop();
|
|
}
|
|
|
|
export async function withResolvedRuntimeMatrixClient<T>(
|
|
opts: {
|
|
client?: MatrixClient;
|
|
cfg?: CoreConfig;
|
|
timeoutMs?: number;
|
|
accountId?: string | null;
|
|
readiness?: MatrixRuntimeClientReadiness;
|
|
},
|
|
run: (client: MatrixClient) => Promise<T>,
|
|
stopMode: ResolvedRuntimeMatrixClientStopMode = "stop",
|
|
): Promise<T> {
|
|
const resolved = await resolveRuntimeMatrixClientWithReadiness(opts);
|
|
try {
|
|
return await run(resolved.client);
|
|
} finally {
|
|
await stopResolvedRuntimeMatrixClient(resolved, stopMode);
|
|
}
|
|
}
|