@typecad/jlcpcb-parts
Version:
Intelligent fuzzy search for JLCPCB electrical components with CLI interface
157 lines • 6.24 kB
JavaScript
import { DataManager } from '../data/DataManager.js';
import { ElectricalParameterParser } from '../parsers/ParameterParser.js';
import { ComponentFuzzyScorer } from '../scoring/FuzzyScorer.js';
import { ComponentSearchEngine } from '../scoring/SearchEngine.js';
import { CommandLineInterface } from '../cli/CommandLineInterface.js';
import { ErrorHandler } from '../cli/ErrorHandler.js';
import { Logger, LogLevel } from '../cli/Logger.js';
import { GlobalErrorHandler } from '../cli/GlobalErrorHandler.js';
/**
* Application class that initializes and coordinates all components
*/
export class Application {
dataManager;
parameterParser;
fuzzyScorer;
searchEngine;
cli;
logger;
/**
* Creates a new Application instance
* @param csvUrl - URL to download the CSV file from
* @param localCsvFileName - Name of the CSV file to save
* @param cacheDir - Directory to store cache files (used when useSharedCache is false)
* @param cacheExpirationHours - Number of hours before cache expires
* @param programName - Name of the program for CLI display
* @param logLevel - Minimum log level to display in the console
* @param useSharedCache - Whether to use shared cache directory (default: true)
*/
constructor(csvUrl = 'https://cdfer.github.io/jlcpcb-parts-database/jlcpcb-components-basic-preferred.csv', localCsvFileName = 'jlcpcb-components-basic-preferred.csv', cacheDir = '.', cacheExpirationHours = 24, programName = 'jlcpcb-search', logLevel = LogLevel.WARN, useSharedCache = true) {
// Initialize logger
this.logger = Logger.getInstance({
consoleLevel: logLevel
});
// Initialize global error handler
GlobalErrorHandler.initialize(this.logger);
this.logger.info('Initializing application');
try {
// Initialize components
this.dataManager = new DataManager(csvUrl, localCsvFileName, cacheDir, cacheExpirationHours, useSharedCache);
this.parameterParser = new ElectricalParameterParser();
this.fuzzyScorer = new ComponentFuzzyScorer();
// Create search engine
this.searchEngine = new ComponentSearchEngine(this.dataManager, this.parameterParser, this.fuzzyScorer);
// Create CLI
this.cli = new CommandLineInterface(this.searchEngine, programName);
this.logger.info('Application initialized successfully');
}
catch (error) {
this.logger.error('Failed to initialize application', error);
throw error;
}
}
/**
* Runs the application with the provided command-line arguments
* @param args - Command-line arguments (process.argv)
* @returns Promise that resolves when the application completes
*/
async run(args) {
try {
this.logger.info('Starting application', { args: args.slice(2) });
// Run the CLI with the provided arguments
await this.cli.run(args);
this.logger.info('Application completed successfully');
}
catch (error) {
// Log the error
this.logger.error('Application failed', error);
// Handle any uncaught errors
const errorMessage = ErrorHandler.handleError(error);
console.error(errorMessage);
// Exit with error code
process.exit(1);
}
}
/**
* Performs cleanup operations before shutdown
*/
async shutdown() {
this.logger.info('Shutting down application...');
try {
// Add any cleanup operations here
// For example, closing database connections, saving state, etc.
// Clear search engine cache if available
if (this.searchEngine && typeof this.searchEngine.clearCache === 'function') {
this.searchEngine.clearCache();
this.logger.debug('Search engine cache cleared');
}
this.logger.info('Application shutdown complete');
}
catch (error) {
this.logger.error('Error during shutdown', error);
}
}
/**
* Gets the logger instance
* @returns The logger instance
*/
getLogger() {
return this.logger;
}
/**
* Gets the search engine instance
* @returns The search engine instance
*/
getSearchEngine() {
return this.searchEngine;
}
/**
* Gets the data manager instance
* @returns The data manager instance
*/
getDataManager() {
return this.dataManager;
}
}
/**
* Creates and runs the application
* @param args - Command-line arguments (process.argv)
* @param options - Application options
* @returns Promise that resolves when the application completes
*/
export async function runApplication(args, options = {}) {
let app = null;
try {
// Create application with provided options
app = new Application(options.csvUrl, options.localCsvFileName, options.cacheDir, options.cacheExpirationHours, options.programName, options.logLevel, options.useSharedCache);
const logger = app.getLogger();
// Set up signal handlers for graceful shutdown
process.on('SIGINT', async () => {
logger.info('\nReceived SIGINT. Shutting down...');
if (app) {
await app.shutdown();
}
process.exit(0);
});
process.on('SIGTERM', async () => {
logger.info('\nReceived SIGTERM. Shutting down...');
if (app) {
await app.shutdown();
}
process.exit(0);
});
// Run the application
await app.run(args);
}
catch (error) {
// If we couldn't even create the application or get the logger,
// fall back to console.error
if (!app) {
console.error('Failed to initialize application:', error instanceof Error ? error.message : String(error));
process.exit(1);
}
// Otherwise, the application's error handling should have caught this
throw error;
}
}
//# sourceMappingURL=index.js.map