All files / utils/cache CacheKeyGenerator.ts

100% Statements 6/6
100% Branches 2/2
100% Functions 2/2
100% Lines 6/6

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47        13x                                 78x 78x                             13x 13x   2x            
import IFileSystem from "../../transpiler/types/IFileSystem";
import NodeFileSystem from "../../transpiler/NodeFileSystem";
 
/** Default file system instance (singleton for performance) */
const defaultFs = NodeFileSystem.instance;
 
/**
 * Generates and validates cache keys for files.
 * Encapsulates the cache invalidation strategy for future flexibility.
 *
 * Currently: mtime-based (fast, no file reads)
 * Future: content-hash-based (more accurate, handles touch without changes)
 */
class CacheKeyGenerator {
  /**
   * Generate a cache key for a file.
   * @param filePath Absolute path to the file
   * @param fs File system abstraction (defaults to NodeFileSystem)
   * @returns Cache key string (format: "mtime:<timestamp>")
   */
  static generate(filePath: string, fs: IFileSystem = defaultFs): string {
    const stats = fs.stat(filePath);
    return `mtime:${stats.mtimeMs}`;
  }
 
  /**
   * Check if a file's current state matches a cached key.
   * @param filePath Absolute path to the file
   * @param cachedKey The key stored in cache
   * @param fs File system abstraction (defaults to NodeFileSystem)
   * @returns true if file is unchanged
   */
  static isValid(
    filePath: string,
    cachedKey: string,
    fs: IFileSystem = defaultFs,
  ): boolean {
    try {
      return CacheKeyGenerator.generate(filePath, fs) === cachedKey;
    } catch {
      return false; // File doesn't exist or unreadable
    }
  }
}
 
export default CacheKeyGenerator;