test(web-next): e2e realtime-ping (4 checkpoints)

This commit is contained in:
2026-05-09 00:39:44 +02:00
parent 2351ca6249
commit b9caf605d2
5 changed files with 120 additions and 3 deletions

View File

@@ -1,17 +1,24 @@
import type { z } from "zod";
import type { RealtimeChannelDescriptor } from "./realtime-channel";
import type { IInboundDescriptor } from "./realtime-handler.interface";
export interface IRealtimeHandlerRegistry {
register<T>(entry: IInboundDescriptor<string, z.ZodType<T>>): void;
getInboundDescriptor(channelName: string): IInboundDescriptor<string, z.ZodType> | null;
list(): IInboundDescriptor<string, z.ZodType>[];
/** Register an outbound-only channel so Gate 2 can authorize subscriptions to it. */
registerChannel(descriptor: RealtimeChannelDescriptor<string, z.ZodType>): void;
listChannels(): RealtimeChannelDescriptor<string, z.ZodType>[];
}
export class RealtimeHandlerRegistry implements IRealtimeHandlerRegistry {
private readonly entries = new Map<string, IInboundDescriptor<string, z.ZodType>>();
private readonly channels = new Map<string, RealtimeChannelDescriptor<string, z.ZodType>>();
register<T>(entry: IInboundDescriptor<string, z.ZodType<T>>): void {
this.entries.set(entry.descriptor.name, entry as IInboundDescriptor<string, z.ZodType>);
// Also add the descriptor to the channel map so Gate 2 can authorize subscriptions.
this.channels.set(entry.descriptor.name, entry.descriptor);
}
getInboundDescriptor(channelName: string): IInboundDescriptor<string, z.ZodType> | null {
@@ -21,4 +28,12 @@ export class RealtimeHandlerRegistry implements IRealtimeHandlerRegistry {
list(): IInboundDescriptor<string, z.ZodType>[] {
return Array.from(this.entries.values());
}
registerChannel(descriptor: RealtimeChannelDescriptor<string, z.ZodType>): void {
this.channels.set(descriptor.name, descriptor);
}
listChannels(): RealtimeChannelDescriptor<string, z.ZodType>[] {
return Array.from(this.channels.values());
}
}

View File

@@ -55,11 +55,12 @@ export class SocketIORealtimeServer implements IRealtimeServer {
// Gate 2: subscribe.
socket.on("subscribe", async (requestedName: string, ack?: (r: unknown) => void) => {
// Find a registered descriptor whose name (or template) matches requestedName.
// listChannels() covers both inbound descriptors and outbound-only channels.
let matched: { descriptor: { name: string; scope: unknown }; params: Record<string, string> } | null = null;
for (const entry of registry.list()) {
const m = matchChannelTemplate(entry.descriptor.name, requestedName);
for (const descriptor of registry.listChannels()) {
const m = matchChannelTemplate(descriptor.name, requestedName);
if (m) {
matched = { descriptor: entry.descriptor, params: m.params };
matched = { descriptor, params: m.params };
break;
}
}