feat(core-realtime): SocketIORealtimeBroadcaster
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
import { describe, it, expect, vi } from "vitest";
|
||||||
|
import { z } from "zod";
|
||||||
|
import { SocketIORealtimeBroadcaster } from "@/socket-io-realtime-broadcaster";
|
||||||
|
import { defineRealtimeChannel } from "@/realtime-channel";
|
||||||
|
|
||||||
|
const ch = defineRealtimeChannel(
|
||||||
|
"a.b",
|
||||||
|
z.object({ x: z.number() }).strict(),
|
||||||
|
{ scope: "public" },
|
||||||
|
);
|
||||||
|
|
||||||
|
describe("SocketIORealtimeBroadcaster", () => {
|
||||||
|
it("emits to the channel's room with the channel name as event", async () => {
|
||||||
|
const emit = vi.fn();
|
||||||
|
const to = vi.fn(() => ({ emit }));
|
||||||
|
const io = { to } as never;
|
||||||
|
const b = new SocketIORealtimeBroadcaster(io);
|
||||||
|
await b.broadcast(ch, { x: 1 });
|
||||||
|
expect(to).toHaveBeenCalledWith("ch:a.b");
|
||||||
|
expect(emit).toHaveBeenCalledWith("a.b", { x: 1 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("validates payload before emitting", async () => {
|
||||||
|
const emit = vi.fn();
|
||||||
|
const to = vi.fn(() => ({ emit }));
|
||||||
|
const io = { to } as never;
|
||||||
|
const b = new SocketIORealtimeBroadcaster(io);
|
||||||
|
await expect(
|
||||||
|
b.broadcast(ch, { x: "not a number" } as never),
|
||||||
|
).rejects.toThrow();
|
||||||
|
expect(emit).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
16
packages/core-realtime/src/socket-io-realtime-broadcaster.ts
Normal file
16
packages/core-realtime/src/socket-io-realtime-broadcaster.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import type { Server as IOServer } from "socket.io";
|
||||||
|
import type { z } from "zod";
|
||||||
|
import type { IRealtimeBroadcaster } from "./realtime-broadcaster.interface";
|
||||||
|
import type { RealtimeChannelDescriptor } from "./realtime-channel";
|
||||||
|
|
||||||
|
export class SocketIORealtimeBroadcaster implements IRealtimeBroadcaster {
|
||||||
|
constructor(private readonly io: IOServer) {}
|
||||||
|
|
||||||
|
async broadcast<T>(
|
||||||
|
descriptor: RealtimeChannelDescriptor<string, z.ZodType<T>>,
|
||||||
|
payload: T,
|
||||||
|
): Promise<void> {
|
||||||
|
descriptor.schema.parse(payload);
|
||||||
|
this.io.to(`ch:${descriptor.name}`).emit(descriptor.name, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user