UNPKG

bowling-analysis-system

Version:

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

104 lines (89 loc) 3.14 kB
/** * @fileoverview File saver stage for saving final results */ const fs = require('fs'); class FileSaver { /** * Build and save final result * @param {Object} params - Stage parameters * @param {Object} params.context - Pipeline context * @param {string} params.outputPath - Path to save output * @param {Object} params.options - Stage options * @param {boolean} [params.options.debug] - Enable debug logging * @returns {Promise<Object>} Final result */ async execute({ context, outputPath, options = {} }) { const { debug = false } = options; // Build final result object const result = this.buildFinalResult(context); // Save to file if path provided if (outputPath) { // Ensure we're writing a single, complete result const finalResult = JSON.stringify(result, null, 2); fs.writeFileSync(outputPath, finalResult); if (debug) { console.log(`Results saved to ${outputPath}`); } } return result; } /** * Build the final result object * @param {Object} context - Pipeline context * @returns {Object} Final result */ buildFinalResult(context) { // Debug the input context metrics if (context.metrics) { console.log(`\nBuilding final result with ${Object.keys(context.metrics).length} metrics categories`); for (const category in context.metrics) { const metrics = context.metrics[category]; console.log(`- ${category}: ${Object.keys(metrics).length} metrics`); } } // Include all required top-level keys const result = { metrics: context.metrics || {}, events: context.events || {}, timeSeries: context.timeSeries || {}, metadata: { frameCount: context.metadata?.totalFrames || 0, validFrames: context.metadata?.validFrames || 0, nullFrames: context.metadata?.nullFrames || 0, validFramesStart: 0, analysisTimestamp: new Date().toISOString(), pipelineId: context.pipeline?.id || 'unknown', pipelineName: context.pipeline?.name || 'unknown', timings: context.metadata?.timings || {} } }; // Include analysis if available if (context.analysis) { result.analysis = context.analysis; } // Include bias data if available if (context.bias) { result.bias = context.bias; } // Include moments data if available if (context.events && context.events.moments) { result.moments = context.events.moments; // Remove moments from events object to avoid duplication const eventsCopy = { ...context.events }; delete eventsCopy.moments; result.events = eventsCopy; } // Debug the output result metrics if (result.metrics) { console.log(`\nFinal result has ${Object.keys(result.metrics).length} metrics categories`); for (const category in result.metrics) { const metrics = result.metrics[category]; console.log(`- ${category}: ${Object.keys(metrics).length} metrics`); } } return result; } } module.exports = { FileSaver };