import * as plugins from './mod.plugins.js'; import { FormatContext } from './classes.formatcontext.js'; import type { IPlannedChange } from './interfaces.format.js'; import { Project } from '../classes.project.js'; import { ChangeCache } from './classes.changecache.js'; export abstract class BaseFormatter { protected context: FormatContext; protected project: Project; protected cache: ChangeCache; protected stats: any; // Will be FormatStats from context constructor(context: FormatContext, project: Project) { this.context = context; this.project = project; this.cache = context.getChangeCache(); this.stats = context.getFormatStats(); } abstract get name(): string; abstract analyze(): Promise; abstract applyChange(change: IPlannedChange): Promise; async execute(changes: IPlannedChange[]): Promise { const startTime = this.stats.moduleStartTime(this.name); this.stats.startModule(this.name); try { await this.preExecute(); for (const change of changes) { try { await this.applyChange(change); this.stats.recordFileOperation(this.name, change.type, true); } catch (error) { this.stats.recordFileOperation(this.name, change.type, false); throw error; } } await this.postExecute(); } catch (error) { await this.context.rollbackOperation(); throw error; } finally { this.stats.endModule(this.name, startTime); } } protected async preExecute(): Promise { // Override in subclasses if needed } protected async postExecute(): Promise { // Override in subclasses if needed } protected async modifyFile(filepath: string, content: string): Promise { await this.context.trackFileChange(filepath); await plugins.smartfile.memory.toFs(content, filepath); await this.cache.updateFileCache(filepath); } protected async createFile(filepath: string, content: string): Promise { await plugins.smartfile.memory.toFs(content, filepath); await this.cache.updateFileCache(filepath); } protected async deleteFile(filepath: string): Promise { await this.context.trackFileChange(filepath); await plugins.smartfile.fs.remove(filepath); } protected async shouldProcessFile(filepath: string): Promise { const config = new plugins.npmextra.Npmextra(); const useCache = config.dataFor('gitzone.format.cache.enabled', true); if (!useCache) { return true; // Process all files if cache is disabled } const hasChanged = await this.cache.hasFileChanged(filepath); // Record cache statistics if (hasChanged) { this.stats.recordCacheMiss(); } else { this.stats.recordCacheHit(); } return hasChanged; } }