UNPKG

bowling-analysis-system

Version:

A comprehensive system for analyzing bowling techniques using video processing and metrics calculation

193 lines (164 loc) 4.81 kB
/** * Middleware Registry * * Centralized system for registering and composing middleware functions * @module middleware/MiddlewareRegistry */ /** * @class MiddlewareRegistry * @description Registry for middleware functions with composition utilities */ class MiddlewareRegistry { /** * Create a new middleware registry */ constructor() { this.middleware = new Map(); } /** * Register middleware for a specific category * @param {string} category - Middleware category * @param {string} name - Middleware name * @param {Function} fn - Middleware function * @returns {MiddlewareRegistry} Registry instance for chaining */ register(category, name, fn) { if (!this.middleware.has(category)) { this.middleware.set(category, new Map()); } this.middleware.get(category).set(name, fn); return this; } /** * Get middleware by name * @param {string} category - Middleware category * @param {string} name - Middleware name * @returns {Function|null} Middleware function or null if not found */ get(category, name) { if (!this.middleware.has(category)) { return null; } return this.middleware.get(category).get(name) || null; } /** * Get all middleware for a category * @param {string} category - Middleware category * @returns {Map<string, Function>} Map of middleware functions */ getCategory(category) { return this.middleware.get(category) || new Map(); } /** * Check if middleware exists * @param {string} category - Middleware category * @param {string} name - Middleware name * @returns {boolean} True if middleware exists */ has(category, name) { if (!this.middleware.has(category)) { return false; } return this.middleware.get(category).has(name); } /** * List all middleware names for a category * @param {string} category - Middleware category * @returns {Array<string>} List of middleware names */ list(category) { if (!this.middleware.has(category)) { return []; } return Array.from(this.middleware.get(category).keys()); } /** * List all categories * @returns {Array<string>} List of categories */ listCategories() { return Array.from(this.middleware.keys()); } /** * Create a middleware chain from a list of middleware names * @param {string} category - Middleware category * @param {Array<string|Function>} names - Middleware names or functions * @returns {Function} Composed middleware function */ createChain(category, names) { const middlewareFns = names.map(name => { if (typeof name === 'function') { return name; } const fn = this.get(category, name); if (!fn) { throw new Error(`Middleware not found: ${category}/${name}`); } return fn; }); return compose(middlewareFns); } } /** * Compose middleware functions into a single function * @param {Array<Function>} middleware - Middleware functions * @returns {Function} Composed middleware function */ function compose(middleware) { return async (context, next) => { // Last called middleware let index = -1; async function dispatch(i) { if (i <= index) { throw new Error('next() called multiple times'); } index = i; let fn = middleware[i]; if (i === middleware.length) { fn = next; } if (!fn) { return; } return fn(context, dispatch.bind(null, i + 1)); } return dispatch(0); }; } /** * Create a middleware function that combines functions in sequence * @param {...Function} fns - Functions to combine * @returns {Function} Combined function */ function sequence(...fns) { return async (input, context) => { let result = input; for (const fn of fns) { result = await fn(result, context); } return result; }; } /** * Create a conditional middleware function * @param {Function} condition - Condition function * @param {Function} middleware - Middleware function * @returns {Function} Conditional middleware function */ function conditional(condition, middleware) { return async (input, context) => { if (await condition(input, context)) { return middleware(input, context); } return input; }; } // Create default registry instance const defaultRegistry = new MiddlewareRegistry(); module.exports = { MiddlewareRegistry, defaultRegistry, compose, sequence, conditional };