230 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import * as plugins from './mod.plugins.js';
 | 
						|
import { logger } from '../gitzone.logging.js';
 | 
						|
 | 
						|
export interface IModuleStats {
 | 
						|
  name: string;
 | 
						|
  filesProcessed: number;
 | 
						|
  executionTime: number;
 | 
						|
  errors: number;
 | 
						|
  successes: number;
 | 
						|
  filesCreated: number;
 | 
						|
  filesModified: number;
 | 
						|
  filesDeleted: number;
 | 
						|
}
 | 
						|
 | 
						|
export interface IFormatStats {
 | 
						|
  totalExecutionTime: number;
 | 
						|
  startTime: number;
 | 
						|
  endTime: number;
 | 
						|
  moduleStats: Map<string, IModuleStats>;
 | 
						|
  overallStats: {
 | 
						|
    totalFiles: number;
 | 
						|
    totalCreated: number;
 | 
						|
    totalModified: number;
 | 
						|
    totalDeleted: number;
 | 
						|
    totalErrors: number;
 | 
						|
    cacheHits: number;
 | 
						|
    cacheMisses: number;
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
export class FormatStats {
 | 
						|
  private stats: IFormatStats;
 | 
						|
 | 
						|
  constructor() {
 | 
						|
    this.stats = {
 | 
						|
      totalExecutionTime: 0,
 | 
						|
      startTime: Date.now(),
 | 
						|
      endTime: 0,
 | 
						|
      moduleStats: new Map(),
 | 
						|
      overallStats: {
 | 
						|
        totalFiles: 0,
 | 
						|
        totalCreated: 0,
 | 
						|
        totalModified: 0,
 | 
						|
        totalDeleted: 0,
 | 
						|
        totalErrors: 0,
 | 
						|
        cacheHits: 0,
 | 
						|
        cacheMisses: 0,
 | 
						|
      },
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  startModule(moduleName: string): void {
 | 
						|
    this.stats.moduleStats.set(moduleName, {
 | 
						|
      name: moduleName,
 | 
						|
      filesProcessed: 0,
 | 
						|
      executionTime: 0,
 | 
						|
      errors: 0,
 | 
						|
      successes: 0,
 | 
						|
      filesCreated: 0,
 | 
						|
      filesModified: 0,
 | 
						|
      filesDeleted: 0,
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  moduleStartTime(moduleName: string): number {
 | 
						|
    return Date.now();
 | 
						|
  }
 | 
						|
 | 
						|
  endModule(moduleName: string, startTime: number): void {
 | 
						|
    const moduleStats = this.stats.moduleStats.get(moduleName);
 | 
						|
    if (moduleStats) {
 | 
						|
      moduleStats.executionTime = Date.now() - startTime;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  recordFileOperation(
 | 
						|
    moduleName: string,
 | 
						|
    operation: 'create' | 'modify' | 'delete',
 | 
						|
    success: boolean = true,
 | 
						|
  ): void {
 | 
						|
    const moduleStats = this.stats.moduleStats.get(moduleName);
 | 
						|
    if (!moduleStats) return;
 | 
						|
 | 
						|
    moduleStats.filesProcessed++;
 | 
						|
 | 
						|
    if (success) {
 | 
						|
      moduleStats.successes++;
 | 
						|
      this.stats.overallStats.totalFiles++;
 | 
						|
 | 
						|
      switch (operation) {
 | 
						|
        case 'create':
 | 
						|
          moduleStats.filesCreated++;
 | 
						|
          this.stats.overallStats.totalCreated++;
 | 
						|
          break;
 | 
						|
        case 'modify':
 | 
						|
          moduleStats.filesModified++;
 | 
						|
          this.stats.overallStats.totalModified++;
 | 
						|
          break;
 | 
						|
        case 'delete':
 | 
						|
          moduleStats.filesDeleted++;
 | 
						|
          this.stats.overallStats.totalDeleted++;
 | 
						|
          break;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      moduleStats.errors++;
 | 
						|
      this.stats.overallStats.totalErrors++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  recordCacheHit(): void {
 | 
						|
    this.stats.overallStats.cacheHits++;
 | 
						|
  }
 | 
						|
 | 
						|
  recordCacheMiss(): void {
 | 
						|
    this.stats.overallStats.cacheMisses++;
 | 
						|
  }
 | 
						|
 | 
						|
  finish(): void {
 | 
						|
    this.stats.endTime = Date.now();
 | 
						|
    this.stats.totalExecutionTime = this.stats.endTime - this.stats.startTime;
 | 
						|
  }
 | 
						|
 | 
						|
  displayStats(): void {
 | 
						|
    console.log('\n📊 Format Operation Statistics:');
 | 
						|
    console.log('═'.repeat(50));
 | 
						|
 | 
						|
    // Overall stats
 | 
						|
    console.log('\nOverall Summary:');
 | 
						|
    console.log(
 | 
						|
      `  Total Execution Time: ${this.formatDuration(this.stats.totalExecutionTime)}`,
 | 
						|
    );
 | 
						|
    console.log(`  Files Processed: ${this.stats.overallStats.totalFiles}`);
 | 
						|
    console.log(`    • Created: ${this.stats.overallStats.totalCreated}`);
 | 
						|
    console.log(`    • Modified: ${this.stats.overallStats.totalModified}`);
 | 
						|
    console.log(`    • Deleted: ${this.stats.overallStats.totalDeleted}`);
 | 
						|
    console.log(`  Errors: ${this.stats.overallStats.totalErrors}`);
 | 
						|
 | 
						|
    if (
 | 
						|
      this.stats.overallStats.cacheHits > 0 ||
 | 
						|
      this.stats.overallStats.cacheMisses > 0
 | 
						|
    ) {
 | 
						|
      const cacheHitRate =
 | 
						|
        (this.stats.overallStats.cacheHits /
 | 
						|
          (this.stats.overallStats.cacheHits +
 | 
						|
            this.stats.overallStats.cacheMisses)) *
 | 
						|
        100;
 | 
						|
      console.log(`  Cache Hit Rate: ${cacheHitRate.toFixed(1)}%`);
 | 
						|
      console.log(`    • Hits: ${this.stats.overallStats.cacheHits}`);
 | 
						|
      console.log(`    • Misses: ${this.stats.overallStats.cacheMisses}`);
 | 
						|
    }
 | 
						|
 | 
						|
    // Module stats
 | 
						|
    console.log('\nModule Breakdown:');
 | 
						|
    console.log('─'.repeat(50));
 | 
						|
 | 
						|
    const sortedModules = Array.from(this.stats.moduleStats.values()).sort(
 | 
						|
      (a, b) => b.filesProcessed - a.filesProcessed,
 | 
						|
    );
 | 
						|
 | 
						|
    for (const moduleStats of sortedModules) {
 | 
						|
      console.log(
 | 
						|
        `\n${this.getModuleIcon(moduleStats.name)} ${moduleStats.name}:`,
 | 
						|
      );
 | 
						|
      console.log(
 | 
						|
        `  Execution Time: ${this.formatDuration(moduleStats.executionTime)}`,
 | 
						|
      );
 | 
						|
      console.log(`  Files Processed: ${moduleStats.filesProcessed}`);
 | 
						|
 | 
						|
      if (moduleStats.filesCreated > 0) {
 | 
						|
        console.log(`    • Created: ${moduleStats.filesCreated}`);
 | 
						|
      }
 | 
						|
      if (moduleStats.filesModified > 0) {
 | 
						|
        console.log(`    • Modified: ${moduleStats.filesModified}`);
 | 
						|
      }
 | 
						|
      if (moduleStats.filesDeleted > 0) {
 | 
						|
        console.log(`    • Deleted: ${moduleStats.filesDeleted}`);
 | 
						|
      }
 | 
						|
 | 
						|
      if (moduleStats.errors > 0) {
 | 
						|
        console.log(`  ❌ Errors: ${moduleStats.errors}`);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    console.log('\n' + '═'.repeat(50));
 | 
						|
  }
 | 
						|
 | 
						|
  async saveReport(outputPath: string): Promise<void> {
 | 
						|
    const report = {
 | 
						|
      timestamp: new Date().toISOString(),
 | 
						|
      executionTime: this.stats.totalExecutionTime,
 | 
						|
      overallStats: this.stats.overallStats,
 | 
						|
      moduleStats: Array.from(this.stats.moduleStats.values()),
 | 
						|
    };
 | 
						|
 | 
						|
    await plugins.smartfile.memory.toFs(
 | 
						|
      JSON.stringify(report, null, 2),
 | 
						|
      outputPath,
 | 
						|
    );
 | 
						|
    logger.log('info', `Statistics report saved to ${outputPath}`);
 | 
						|
  }
 | 
						|
 | 
						|
  private formatDuration(ms: number): string {
 | 
						|
    if (ms < 1000) {
 | 
						|
      return `${ms}ms`;
 | 
						|
    } else if (ms < 60000) {
 | 
						|
      return `${(ms / 1000).toFixed(1)}s`;
 | 
						|
    } else {
 | 
						|
      const minutes = Math.floor(ms / 60000);
 | 
						|
      const seconds = Math.floor((ms % 60000) / 1000);
 | 
						|
      return `${minutes}m ${seconds}s`;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  private getModuleIcon(module: string): string {
 | 
						|
    const icons: Record<string, string> = {
 | 
						|
      packagejson: '📦',
 | 
						|
      license: '📝',
 | 
						|
      tsconfig: '🔧',
 | 
						|
      cleanup: '🚮',
 | 
						|
      gitignore: '🔒',
 | 
						|
      prettier: '✨',
 | 
						|
      readme: '📖',
 | 
						|
      templates: '📄',
 | 
						|
      npmextra: '⚙️',
 | 
						|
      copy: '📋',
 | 
						|
    };
 | 
						|
    return icons[module] || '📁';
 | 
						|
  }
 | 
						|
}
 |