Add SocketRouteBuilder and make Route.socket(...) return it

This commit is contained in:
Garrett Mills 2022-08-06 13:10:51 -05:00
parent ef405093dc
commit 4aa33e8dd2
4 changed files with 66 additions and 3 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@extollo/lib", "name": "@extollo/lib",
"version": "0.12.1", "version": "0.13.0",
"description": "The framework library that lifts up your code.", "description": "The framework library that lifts up your code.",
"main": "lib/index.js", "main": "lib/index.js",
"types": "lib/index.d.ts", "types": "lib/index.d.ts",

View File

@ -10,6 +10,7 @@ import {Config} from '../../service/Config'
import {Application} from '../../lifecycle/Application' import {Application} from '../../lifecycle/Application'
import {Logging} from '../../service/Logging' import {Logging} from '../../service/Logging'
import {WebSocketBus} from '../../support/bus/WebSocketBus' import {WebSocketBus} from '../../support/bus/WebSocketBus'
import {SocketRouteBuilder} from './SocketRouteBuilder'
/** /**
* Type alias for an item that is a valid response object, or lack thereof. * Type alias for an item that is a valid response object, or lack thereof.
@ -141,8 +142,16 @@ export class Route<TReturn extends ResponseObject, THandlerParams extends unknow
* Create a new WebSocket route on the given endpoint. * Create a new WebSocket route on the given endpoint.
* @param endpoint * @param endpoint
*/ */
public static socket(endpoint: string): Route<Awaitable<void>, [WebSocketBus]> { public static socket(endpoint: string): SocketRouteBuilder {
return new Route<Awaitable<void>, [WebSocketBus]>('ws', endpoint) const builder = SocketRouteBuilder.get()
;(new Route<Awaitable<void>, [WebSocketBus]>('ws', endpoint))
.passingRequest()
.handledBy(async (ws: WebSocketBus, request: Request) => {
await builder.build(request, ws)
})
return builder
} }
/** /**

View File

@ -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<TState extends JSONState> = {
eventClass: Instantiable<StateEvent<TState>>,
handler: Constructable<(state: TState) => Awaitable<void>>,
}
export class SocketRouteBuilder {
public static get(): SocketRouteBuilder {
return new SocketRouteBuilder()
}
protected handlers: Collection<SocketEventHandler<any>> = new Collection()
protected connectionCallback?: Constructable<(ws: WebSocketBus) => Awaitable<void>>
connected<TKey extends any>(
key: TypedDependencyKey<TKey>,
selector: (x: TKey) => (ws: WebSocketBus) => Awaitable<void>,
): this {
this.connectionCallback = constructable<TKey>(key)
.tap(inst => Function.prototype.bind.call(selector(inst), inst as any) as ((ws: WebSocketBus) => Awaitable<void>))
return this
}
event<TState extends JSONState, TKey extends any>(
eventClass: Instantiable<StateEvent<TState>>,
key: TypedDependencyKey<TKey>,
selector: (x: TKey) => (state: TState) => Awaitable<void>,
): this {
const handler = constructable<TKey>(key)
.tap(inst => Function.prototype.bind.call(selector(inst), inst as any) as ((state: TState) => Awaitable<void>))
this.handlers.push({
eventClass,
handler,
})
return this
}
async build(request: Request, ws: WebSocketBus): Promise<void> {
await this.handlers.promiseMap(handler => {
ws.subscribe(handler.eventClass, handler.handler.apply(request))
})
if ( this.connectionCallback ) {
await this.connectionCallback.apply(request)(ws)
}
}
}

View File

@ -54,6 +54,7 @@ export * from './http/response/ViewResponseFactory'
export * from './http/response/FileResponseFactory' export * from './http/response/FileResponseFactory'
export * from './http/response/RouteResponseFactory' export * from './http/response/RouteResponseFactory'
export * from './http/routing/SocketRouteBuilder'
export * from './http/routing/ActivatedRoute' export * from './http/routing/ActivatedRoute'
export * from './http/routing/Route' export * from './http/routing/Route'
export * from './http/routing/RouteGroup' export * from './http/routing/RouteGroup'