feat(core-realtime): realtime-ping proof-of-life channel pair

This commit is contained in:
2026-05-08 23:19:52 +02:00
parent 4e72a16b3c
commit 90ef577b9d
2 changed files with 43 additions and 0 deletions

View File

@@ -13,3 +13,10 @@ export { SocketIORealtimeBroadcaster } from "./socket-io-realtime-broadcaster";
export { SocketIORealtimeServer } from "./socket-io-realtime-server";
export { authorize } from "./authorize";
export { matchChannelTemplate } from "./channel-template";
export {
realtimePingChannel,
realtimePongChannel,
realtimePingInboundDescriptor,
type PingPayload,
type PongPayload,
} from "./realtime-ping";

View File

@@ -0,0 +1,36 @@
import { z } from "zod";
import { defineRealtimeChannel } from "./realtime-channel";
import type { IRealtimeBroadcaster } from "./realtime-broadcaster.interface";
import type { IInboundDescriptor, RealtimeContext } from "./realtime-handler.interface";
const pingSchema = z.object({ at: z.string().datetime() }).strict();
const pongSchema = z.object({ at: z.string().datetime(), echo: z.string() }).strict();
export type PingPayload = z.infer<typeof pingSchema>;
export type PongPayload = z.infer<typeof pongSchema>;
export const realtimePingChannel = defineRealtimeChannel(
"realtime.ping",
pingSchema,
{ scope: "authenticated" },
);
export const realtimePongChannel = defineRealtimeChannel(
"realtime.pong",
pongSchema,
{ scope: "authenticated" },
);
export function realtimePingInboundDescriptor(
broadcaster: IRealtimeBroadcaster,
): IInboundDescriptor<typeof realtimePingChannel.name, typeof pingSchema> {
return {
descriptor: realtimePingChannel,
handler: async (input: PingPayload, ctx: RealtimeContext): Promise<void> => {
await broadcaster.broadcast(realtimePongChannel, {
at: input.at,
echo: ctx.userId ?? "anonymous",
});
},
};
}