- Type socket.data.user via AppSocketData/AppSocket generics (no more any)
- Wrap Gate 1 authenticator call in try/catch so exceptions reject the
connection with connect_error instead of being swallowed
- Fix Gate 3 userScoped channel authorize: derive params.userId from the
authenticated socket user so owner-inbound is accepted
- Await io.close(callback) in stop() to ensure full shutdown
- Remove unused httpServer field from constructor (io already holds the ref)
- Extract CHANNEL_ROOM_PREFIX/channelRoom helper to channel-room.ts;
replace three `ch:${name}` magic strings; re-export from index
- Add JSDoc to ChannelScope explaining userScoped params/template convention
- Fix "allows subscribe + invokes handler with ctx" test: hoist received
outside beforeEach and assert ctx shape
- New test: rejects connection when authenticator throws
- New test: userScoped channel accepts inbound from owner, rejects from anon
18 lines
646 B
TypeScript
18 lines
646 B
TypeScript
import type { Server as IOServer } from "socket.io";
|
|
import type { z } from "zod";
|
|
import { channelRoom } from "./channel-room";
|
|
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(channelRoom(descriptor.name)).emit(descriptor.name, payload);
|
|
}
|
|
}
|