core: add withHandlerClass api

This commit is contained in:
undefined committed 2022-11-06 05:43:28 +08:00
1 parent b20834dd70
commit 84309e86fd
3 files changed
+42 -11

No files matched your search

+1
View File
@@ -25,6 +25,7 @@ export interface Context {
loader: Loader; loader: Loader;
Route: typeof import('./service/server').Route; Route: typeof import('./service/server').Route;
Connection: typeof import('./service/server').Connection; Connection: typeof import('./service/server').Connection;
withHandlerClass: import('./service/server').RouteService['withHandlerClass'];
setTimeout: typeof setTimeout; setTimeout: typeof setTimeout;
setInterval: typeof setInterval; setInterval: typeof setInterval;
setImmediate: typeof setImmediate; setImmediate: typeof setImmediate;
+1
View File
@@ -26,6 +26,7 @@ type HandlerEvents =
KnownHandlerEvents KnownHandlerEvents
& Record<`handler/${HookType}/${string}`, (thisArg: Handler & Record<string, any>) => VoidReturn> & Record<`handler/${HookType}/${string}`, (thisArg: Handler & Record<string, any>) => VoidReturn>
& Record<`handler/${HookType}`, (thisArg: Handler) => VoidReturn> & Record<`handler/${HookType}`, (thisArg: Handler) => VoidReturn>
& Record<`handler/register/${string}`, (HandlerClass: typeof Handler) => VoidReturn>
& Record<`connection/${'create' | 'active' | 'close'}`, (thisArg: ConnectionHandler) => VoidReturn>; & Record<`connection/${'create' | 'active' | 'close'}`, (thisArg: ConnectionHandler) => VoidReturn>;
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
+40 -11
View File
@@ -8,7 +8,7 @@ import Compress from 'koa-compress';
import proxy from 'koa-proxies'; import proxy from 'koa-proxies';
import cache from 'koa-static-cache'; import cache from 'koa-static-cache';
import WebSocket from 'ws'; import WebSocket from 'ws';
import { parseMemoryMB } from '@hydrooj/utils/lib/utils'; import { isClass, parseMemoryMB } from '@hydrooj/utils/lib/utils';
import { Context, Service } from '../context'; import { Context, Service } from '../context';
import { import {
HydroError, InvalidOperationError, MethodNotAllowedError, HydroError, InvalidOperationError, MethodNotAllowedError,
@@ -386,26 +386,54 @@ class NotFoundHandler extends Handler {
all() { } all() { }
} }
class RouteService extends Service { export class RouteService extends Service {
static readonly methods = ['Route', 'Connection']; static readonly methods = ['Route', 'Connection', 'withHandlerClass'];
private registry = {};
constructor(ctx) { constructor(ctx) {
super(ctx, 'server', true); super(ctx, 'server', true);
} }
// eslint-disable-next-line @typescript-eslint/naming-convention private register(func: typeof Route | typeof Connection, ...args: Parameters<typeof Route>) {
Route(...args: Parameters<typeof Route>) { const HandlerClass = args[2];
const res = Route(...args); if (!isClass(HandlerClass)) throw new Error('Invalid registration.');
this.caller?.on('dispose', () => res()); if (this.registry[HandlerClass.name]) logger.warn('Route name with %s already exists.', HandlerClass.name);
this.registry[HandlerClass.name] = HandlerClass;
const dispose = () => delete this.registry[HandlerClass.name];
const res = func(...args);
this.ctx.parallel(`handler/register/${HandlerClass.name}`, HandlerClass);
this.caller?.on('dispose', () => {
res();
dispose();
});
}
public withHandlerClass(name: string, callback: (HandlerClass: typeof HandlerCommon) => any) {
if (this.registry[name]) callback(this.registry[name]);
this.ctx.on(`handler/register/${name}`, callback);
this.caller?.on('dispose', () => {
this.ctx.off(`handler/register/${name}`, callback);
});
} }
// eslint-disable-next-line @typescript-eslint/naming-convention // eslint-disable-next-line @typescript-eslint/naming-convention
Connection(...args: Parameters<typeof Connection>) { public Route(...args: Parameters<typeof Route>) {
const res = Connection(...args); this.register(Route, ...args);
this.caller?.on('dispose', () => res()); }
// eslint-disable-next-line @typescript-eslint/naming-convention
public Connection(...args: Parameters<typeof Connection>) {
this.register(Connection, ...args);
} }
} }
export async function apply(pluginContext) { declare module '../context' {
interface Context {
server: RouteService;
}
}
export async function apply(pluginContext: Context) {
Context.service('server', RouteService); Context.service('server', RouteService);
pluginContext.server = new RouteService(pluginContext); pluginContext.server = new RouteService(pluginContext);
app.keys = system.get('session.keys') as unknown as string[]; app.keys = system.get('session.keys') as unknown as string[];
@@ -490,6 +518,7 @@ global.Hydro.service.server = {
wsServer, wsServer,
router, router,
captureAllRoutes, captureAllRoutes,
RouteService,
HandlerCommon, HandlerCommon,
Handler, Handler,
ConnectionHandler, ConnectionHandler,