From 4aa33e8dd28d47175d7e69bd71b8d79995aac57d Mon Sep 17 00:00:00 2001 From: garrettmills Date: Sat, 6 Aug 2022 13:10:51 -0500 Subject: [PATCH] Add SocketRouteBuilder and make Route.socket(...) return it --- package.json | 2 +- src/http/routing/Route.ts | 13 ++++++- src/http/routing/SocketRouteBuilder.ts | 53 ++++++++++++++++++++++++++ src/index.ts | 1 + 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 src/http/routing/SocketRouteBuilder.ts diff --git a/package.json b/package.json index 248ed55..23e22a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@extollo/lib", - "version": "0.12.1", + "version": "0.13.0", "description": "The framework library that lifts up your code.", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/http/routing/Route.ts b/src/http/routing/Route.ts index 7c54de6..90bd084 100644 --- a/src/http/routing/Route.ts +++ b/src/http/routing/Route.ts @@ -10,6 +10,7 @@ import {Config} from '../../service/Config' import {Application} from '../../lifecycle/Application' import {Logging} from '../../service/Logging' import {WebSocketBus} from '../../support/bus/WebSocketBus' +import {SocketRouteBuilder} from './SocketRouteBuilder' /** * Type alias for an item that is a valid response object, or lack thereof. @@ -141,8 +142,16 @@ export class Route, [WebSocketBus]> { - return new Route, [WebSocketBus]>('ws', endpoint) + public static socket(endpoint: string): SocketRouteBuilder { + const builder = SocketRouteBuilder.get() + + ;(new Route, [WebSocketBus]>('ws', endpoint)) + .passingRequest() + .handledBy(async (ws: WebSocketBus, request: Request) => { + await builder.build(request, ws) + }) + + return builder } /** diff --git a/src/http/routing/SocketRouteBuilder.ts b/src/http/routing/SocketRouteBuilder.ts new file mode 100644 index 0000000..7a68000 --- /dev/null +++ b/src/http/routing/SocketRouteBuilder.ts @@ -0,0 +1,53 @@ +import {StateEvent, WebSocketBus} from '../../support/bus' +import {constructable, Constructable, Instantiable, TypedDependencyKey} from '../../di' +import {Awaitable, Collection, JSONState} from '../../util' +import {Request} from '../lifecycle/Request' + +export type SocketEventHandler = { + eventClass: Instantiable>, + handler: Constructable<(state: TState) => Awaitable>, +} + +export class SocketRouteBuilder { + public static get(): SocketRouteBuilder { + return new SocketRouteBuilder() + } + + protected handlers: Collection> = new Collection() + + protected connectionCallback?: Constructable<(ws: WebSocketBus) => Awaitable> + + connected( + key: TypedDependencyKey, + selector: (x: TKey) => (ws: WebSocketBus) => Awaitable, + ): this { + this.connectionCallback = constructable(key) + .tap(inst => Function.prototype.bind.call(selector(inst), inst as any) as ((ws: WebSocketBus) => Awaitable)) + return this + } + + event( + eventClass: Instantiable>, + key: TypedDependencyKey, + selector: (x: TKey) => (state: TState) => Awaitable, + ): this { + const handler = constructable(key) + .tap(inst => Function.prototype.bind.call(selector(inst), inst as any) as ((state: TState) => Awaitable)) + + this.handlers.push({ + eventClass, + handler, + }) + return this + } + + async build(request: Request, ws: WebSocketBus): Promise { + await this.handlers.promiseMap(handler => { + ws.subscribe(handler.eventClass, handler.handler.apply(request)) + }) + + if ( this.connectionCallback ) { + await this.connectionCallback.apply(request)(ws) + } + } +} diff --git a/src/index.ts b/src/index.ts index 5bbf252..5e5bc3d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -54,6 +54,7 @@ export * from './http/response/ViewResponseFactory' export * from './http/response/FileResponseFactory' export * from './http/response/RouteResponseFactory' +export * from './http/routing/SocketRouteBuilder' export * from './http/routing/ActivatedRoute' export * from './http/routing/Route' export * from './http/routing/RouteGroup'