UNPKG

bowling-analysis-system

Version:

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

214 lines (193 loc) 5.63 kB
/** * Base command class for implementing the command pattern * All command handlers should extend this * @class Command */ class Command { /** * Creates an instance of Command * @param {Object} options - Command options * @param {String} options.name - Command name * @param {String} [options.description=''] - Command description * @param {Object} [options.logger] - Logger instance */ constructor(options = {}) { if (!options.name) { throw new Error('Command name is required'); } this.name = options.name; this.description = options.description || ''; this.logger = options.logger || console; this.executed = false; this.successful = false; this.result = null; this.error = null; this.startTime = null; this.endTime = null; } /** * Get command metadata * @returns {Object} - Command metadata */ getMetadata() { return { name: this.name, description: this.description, executed: this.executed, successful: this.successful, duration: this.endTime && this.startTime ? this.endTime - this.startTime : null }; } /** * Execute the command * @param {Object} args - Command arguments * @param {Object} [context={}] - Command context * @returns {Promise<Object>} - Execution result */ async execute(args, context = {}) { this.startTime = Date.now(); this.executed = true; this.successful = false; this.error = null; try { // Validate arguments first await this.validate(args, context); // Execute the command this.result = await this._executeInternal(args, context); this.successful = true; return this.result; } catch (error) { this.error = error; this.logger.error(`Error executing command '${this.name}':`, error); // Try to roll back if needed if (context.autoRollback !== false) { try { await this.rollback(args, context); } catch (rollbackError) { this.logger.error(`Error rolling back command '${this.name}':`, rollbackError); } } throw error; } finally { this.endTime = Date.now(); } } /** * Internal execution method to be implemented by subclasses * @param {Object} args - Command arguments * @param {Object} context - Command context * @returns {Promise<Object>} - Execution result * @protected */ async _executeInternal(args, context) { throw new Error(`Command ${this.name} does not implement _executeInternal method`); } /** * Validate command arguments * @param {Object} args - Command arguments * @param {Object} [context={}] - Validation context * @returns {Promise<Boolean>} - Validation result */ async validate(args, context = {}) { try { return await this._validateInternal(args, context); } catch (error) { this.logger.error(`Validation error in command '${this.name}':`, error); throw error; } } /** * Internal validation method to be implemented by subclasses * @param {Object} args - Command arguments * @param {Object} context - Validation context * @returns {Promise<Boolean>} - Validation result * @protected */ async _validateInternal(args, context) { // Default implementation passes validation return true; } /** * Roll back command execution * @param {Object} args - Command arguments * @param {Object} [context={}] - Rollback context * @returns {Promise<Boolean>} - Rollback result */ async rollback(args, context = {}) { if (!this.executed) { // Nothing to roll back return true; } try { return await this._rollbackInternal(args, context); } catch (error) { this.logger.error(`Rollback error in command '${this.name}':`, error); throw error; } } /** * Internal rollback method to be implemented by subclasses * @param {Object} args - Command arguments * @param {Object} context - Rollback context * @returns {Promise<Boolean>} - Rollback result * @protected */ async _rollbackInternal(args, context) { // Default implementation does nothing this.logger.warn(`Command '${this.name}' does not implement rollback`); return true; } /** * Get command help text * @returns {String} - Help text */ getHelp() { return ` Command: ${this.name} ${this.description} This command has not provided custom help documentation. `; } /** * Get command result * @returns {Object|null} - Command result or null if not executed */ getResult() { return this.result; } /** * Get command error * @returns {Error|null} - Command error or null if successful */ getError() { return this.error; } /** * Check if command was successful * @returns {Boolean} - Success indicator */ isSuccessful() { return this.successful; } /** * Check if command has been executed * @returns {Boolean} - Execution indicator */ isExecuted() { return this.executed; } /** * Reset command state * @returns {Command} - For method chaining */ reset() { this.executed = false; this.successful = false; this.result = null; this.error = null; this.startTime = null; this.endTime = null; return this; } } module.exports = Command;