49 lines
1.5 KiB
TypeScript
49 lines
1.5 KiB
TypeScript
import type { EventBusLike } from "@suaveplan/types";
|
|
import { recordPresenceUpdate } from "../otel/otel.js";
|
|
import type { GatewayEventMap, PresenceWebhookConfig } from "../types/types.js";
|
|
import { deliverPresenceWebhook } from "./presence-webhook.js";
|
|
|
|
/**
|
|
* Single presence-event side-effect helper. Emits the typed bus event,
|
|
* bumps the OTel counter, and (if configured) delivers a signed
|
|
* webhook. Failures from any of the three sinks are swallowed.
|
|
*/
|
|
export async function firePresence(
|
|
deps: {
|
|
readonly bus?: EventBusLike<GatewayEventMap> | undefined;
|
|
readonly presenceWebhook?: PresenceWebhookConfig | undefined;
|
|
readonly clock: () => number;
|
|
},
|
|
kind: "join" | "leave" | "update",
|
|
clientId: string,
|
|
roomId: string | undefined,
|
|
status: string
|
|
): Promise<void> {
|
|
if (kind === "update") recordPresenceUpdate("update");
|
|
if (deps.bus) {
|
|
try {
|
|
deps.bus.emit("ws_gateway:presence", {
|
|
kind,
|
|
clientId,
|
|
roomId,
|
|
at: deps.clock(),
|
|
});
|
|
} catch {
|
|
/* bus failures must not crash the daemon */
|
|
}
|
|
}
|
|
if (!deps.presenceWebhook) return;
|
|
await deliverPresenceWebhook(deps.presenceWebhook, {
|
|
kind:
|
|
kind === "join"
|
|
? "presence:join"
|
|
: kind === "leave"
|
|
? "presence:leave"
|
|
: "presence:update",
|
|
clientId,
|
|
roomId,
|
|
status,
|
|
at: deps.clock(),
|
|
});
|
|
}
|