Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
import type { ChannelAccountSnapshot } from "openclaw/plugin-sdk/channel-contract";
import {
createConnectedChannelStatusPatch,
createTransportActivityStatusPatch,
} from "openclaw/plugin-sdk/gateway-runtime";
import { formatMatrixErrorMessage } from "../errors.js";
import {
isMatrixDisconnectedSyncState,
isMatrixReadySyncState,
type MatrixSyncState,
} from "../sync-state.js";
type MatrixMonitorStatusSink = (patch: ChannelAccountSnapshot) => void;
function cloneLastDisconnect(
value: ChannelAccountSnapshot["lastDisconnect"],
): ChannelAccountSnapshot["lastDisconnect"] {
if (!value || typeof value === "string") {
return value ?? null;
}
return { ...value };
}
function formatSyncError(error: unknown): string | null {
if (!error) {
return null;
}
if (error instanceof Error) {
return error.message || error.name || "unknown";
}
return formatMatrixErrorMessage(error);
}
export type MatrixMonitorStatusController = ReturnType<typeof createMatrixMonitorStatusController>;
export function createMatrixMonitorStatusController(params: {
accountId: string;
baseUrl?: string;
statusSink?: MatrixMonitorStatusSink;
}) {
const status: ChannelAccountSnapshot = {
accountId: params.accountId,
...(params.baseUrl ? { baseUrl: params.baseUrl } : {}),
connected: false,
lastConnectedAt: null,
lastDisconnect: null,
lastError: null,
healthState: "starting",
};
const emit = () => {
params.statusSink?.({
...status,
lastDisconnect: cloneLastDisconnect(status.lastDisconnect),
});
};
const noteConnected = (at = Date.now(), options?: { transportActivity?: boolean }) => {
if (status.connected === true) {
status.lastEventAt = at;
} else {
Object.assign(status, createConnectedChannelStatusPatch(at));
}
if (options?.transportActivity) {
Object.assign(status, createTransportActivityStatusPatch(at));
}
status.lastError = null;
status.lastDisconnect = null;
status.healthState = "healthy";
emit();
};
const noteDisconnected = (params: { state: MatrixSyncState; at?: number; error?: unknown }) => {
const at = params.at ?? Date.now();
const error = formatSyncError(params.error);
status.connected = false;
status.lastEventAt = at;
status.lastDisconnect = {
at,
...(error ? { error } : {}),
};
status.lastError = error;
status.healthState = params.state.toLowerCase();
emit();
};
emit();
return {
noteSyncState(state: MatrixSyncState, error?: unknown, at = Date.now()) {
if (isMatrixReadySyncState(state)) {
// matrix-js-sdk emits SYNCING after each successful /sync response.
// PREPARED can be cache-backed and CATCHUP is a lifecycle bridge, so
// neither should refresh transport liveness.
noteConnected(at, { transportActivity: state === "SYNCING" });
return;
}
if (isMatrixDisconnectedSyncState(state)) {
noteDisconnected({ state, at, error });
return;
}
// Unknown future SDK states inherit the current connectivity bit until the
// SDK classifies them as ready or disconnected. Avoid guessing here.
status.lastEventAt = at;
status.healthState = state.toLowerCase();
emit();
},
noteUnexpectedError(error: unknown, at = Date.now()) {
noteDisconnected({ state: "ERROR", at, error });
},
markStopped(at = Date.now()) {
status.connected = false;
status.lastEventAt = at;
if (status.healthState !== "error") {
status.healthState = "stopped";
}
emit();
},
};
}
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-04-27)
¤
*© Formatika GbR, Deutschland