boardgame-core/src/utils/middleware.ts

35 lines
1.0 KiB
TypeScript

type Middleware<TContext, TReturn> = (
context: TContext,
next: () => Promise<TReturn>
) => Promise<TReturn>;
export type MiddlewareChain<TContext, TReturn> = {
use: (middleware: Middleware<TContext, TReturn>) => void;
execute: (context: TContext) => Promise<TReturn>;
};
export function createMiddlewareChain<TContext extends object, TReturn=TContext>(
fallback?: (context: TContext) => Promise<TReturn>
): MiddlewareChain<TContext, TReturn> {
const middlewares: Middleware<TContext, TReturn>[] = [];
return {
use(middleware: Middleware<TContext, TReturn>) {
middlewares.push(middleware);
},
async execute(context: TContext) {
let index = 0;
async function dispatch(ctx: TContext): Promise<TReturn> {
if (index >= middlewares.length) {
return fallback ? fallback(ctx) : ctx as unknown as TReturn;
}
const current = middlewares[index++];
return current(ctx, () => dispatch(ctx));
}
return dispatch(context);
},
};
}