diff --git a/src/http/routing/SocketRouteBuilder.ts b/src/http/routing/SocketRouteBuilder.ts index 7a68000..356f8a3 100644 --- a/src/http/routing/SocketRouteBuilder.ts +++ b/src/http/routing/SocketRouteBuilder.ts @@ -8,15 +8,43 @@ export type SocketEventHandler = { handler: Constructable<(state: TState) => Awaitable>, } +/** + * Helper class for building websocket APIs using first-class route syntax. + * This is returned by the `Route.socket(...)` method, so you'll probably want + * to use that. + * + * @see Route#socket + * @example + * ```ts + * Route.socket('/ws/endpoint') + * .connected(MyCtrl, (ctrl: MyCtrl) => ctrl.connect) + * .event(MyEvent, MyCtrl, (ctrl: MyCtrl) => ctrl.myHandler) + * ``` + */ export class SocketRouteBuilder { public static get(): SocketRouteBuilder { return new SocketRouteBuilder() } + /** Handlers that should be registered with any new socket connections. */ protected handlers: Collection> = new Collection() + /** Callback to execute when a new connection is opened. */ protected connectionCallback?: Constructable<(ws: WebSocketBus) => Awaitable> + /** + * Register a callback to execute each time a new socket is opened. + * This can be used to perform basic setup/validation/authentication tasks. + * + * @example + * ```ts + * Route.socket('/ws/endpoint') + * .connected(MyCtrl, (ctrl: MyCtrl) => ctrl.connect) + * ``` + * + * @param key + * @param selector + */ connected( key: TypedDependencyKey, selector: (x: TKey) => (ws: WebSocketBus) => Awaitable, @@ -26,6 +54,20 @@ export class SocketRouteBuilder { return this } + /** + * Register a `StateEvent` listener on the socket. + * + * @example + * ```ts + * Route.socket('/ws/endpoint') + * .event(MyEvent, MyCtrl, (ctrl: MyCtrl) => ctrl.myHandler) + * ``` + * + * @see StateEvent + * @param eventClass + * @param key + * @param selector + */ event( eventClass: Instantiable>, key: TypedDependencyKey, @@ -41,6 +83,14 @@ export class SocketRouteBuilder { return this } + /** + * Attaches event listeners & initial callback to the given socket. This is used + * by as the handler for new connections. + * + * @see Route#socket + * @param request + * @param ws + */ async build(request: Request, ws: WebSocketBus): Promise { await this.handlers.promiseMap(handler => { ws.subscribe(handler.eventClass, handler.handler.apply(request))