UNPKG

@synet/fs

Version:

Robust, battle-tested filesystem abstraction for Node.js

130 lines (129 loc) 4.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnalyticsFileSystem = void 0; exports.createAnalyticsFileSystem = createAnalyticsFileSystem; const unit_1 = require("@synet/unit"); /** * Analytics filesystem that tracks filesystem operations and provides usage statistics * Wraps any IFileSystem implementation to provide analytics capabilities */ class AnalyticsFileSystem { constructor(baseFileSystem, options = {}) { this.baseFileSystem = baseFileSystem; this.options = options; this.stats = { stats: { read: 0, write: 0, delete: 0 }, fileReads: [], }; this.operationCount = 0; this.eventEmitter = new unit_1.EventEmitter(); this.emitThreshold = options.emitOn ?? 100; } /** * Get current analytics statistics */ getStats() { return { stats: { ...this.stats.stats }, fileReads: [...this.stats.fileReads], }; } /** * Get the event emitter for analytics events */ getEventEmitter() { return this.eventEmitter; } /** * Record a file operation and check if stats should be emitted */ recordOperation(file, action) { // Update counters this.stats.stats[action]++; // Record file access this.stats.fileReads.push({ file, timestamp: new Date().toISOString(), access: action, }); this.operationCount++; // Emit stats if threshold reached if (this.operationCount >= this.emitThreshold) { this.emitStats(); } } /** * Emit current stats and reset counters */ emitStats() { const currentStats = this.getStats(); this.eventEmitter.emit({ type: "analytics.stats", data: currentStats, timestamp: new Date(), }); // Reset analytics data this.stats = { stats: { read: 0, write: 0, delete: 0 }, fileReads: [], }; this.operationCount = 0; } // IFileSystem implementation with analytics tracking existsSync(path) { const result = this.baseFileSystem.existsSync(path); // Note: exists operations are not tracked as read operations // as they don't actually read file content return result; } readFileSync(path) { const result = this.baseFileSystem.readFileSync(path); this.recordOperation(path, "read"); return result; } writeFileSync(path, data) { this.baseFileSystem.writeFileSync(path, data); this.recordOperation(path, "write"); } deleteFileSync(path) { this.baseFileSystem.deleteFileSync(path); this.recordOperation(path, "delete"); } deleteDirSync(path) { this.baseFileSystem.deleteDirSync(path); // Directory operations are not tracked individually // Could be extended if needed } readDirSync(dirPath) { const result = this.baseFileSystem.readDirSync(dirPath); // Directory reads could be tracked if needed return result; } ensureDirSync(path) { this.baseFileSystem.ensureDirSync(path); // Directory operations are not tracked individually } chmodSync(path, mode) { this.baseFileSystem.chmodSync(path, mode); // Permission changes are not tracked as file operations } clear(dirPath) { if (this.baseFileSystem.clear) { this.baseFileSystem.clear(dirPath); } } } exports.AnalyticsFileSystem = AnalyticsFileSystem; /** * Factory function to create AnalyticsFileSystem with easy access to event emitter * @param baseFileSystem The underlying filesystem implementation * @param options Configuration options * @returns Object containing the analytics filesystem instance and event emitter */ function createAnalyticsFileSystem(baseFileSystem, options = {}) { const instance = new AnalyticsFileSystem(baseFileSystem, options); return { instance, eventEmitter: instance.getEventEmitter(), }; }