@typecad/kicad-symbols
Version:
Intelligent fuzzy search for KiCad symbols with CLI interface
136 lines • 5.24 kB
JavaScript
import { promises as fs } from 'fs';
import { join } from 'path';
import { TimestampManager } from './TimestampManager.js';
import { CacheUtils } from '../utils/CacheUtils.js';
/**
* Manages cache validation based on remote "Last updated" dates
* Extends TimestampManager to add date-based cache validation
*/
export class DateBasedCacheManager extends TimestampManager {
lastUpdatedFile;
useSharedCacheForDates;
constructor(cacheDir = '.', cacheExpirationHours = 24, useSharedCache = true) {
super(cacheDir, cacheExpirationHours, useSharedCache);
this.useSharedCacheForDates = useSharedCache;
if (useSharedCache) {
// Will be set asynchronously in getLastUpdatedFile()
this.lastUpdatedFile = '';
}
else {
// Legacy behavior for backward compatibility
this.lastUpdatedFile = join(cacheDir, '.kicad-last-updated-date');
}
}
/**
* Gets the last updated file path, creating shared cache directory if needed
*/
async getLastUpdatedFile() {
if (this.useSharedCacheForDates) {
const cacheDir = await CacheUtils.getSharedCacheDir();
return join(cacheDir, '.kicad-last-updated-date');
}
return this.lastUpdatedFile;
}
/**
* Gets the stored "Last updated" date from the cache
* @returns The last updated date as a Date object, or null if not found or invalid
*/
async getLastUpdatedDate() {
try {
const lastUpdatedFile = await this.getLastUpdatedFile();
const dateStr = await fs.readFile(lastUpdatedFile, 'utf-8');
const date = new Date(dateStr.trim());
// Validate that the date is a valid date
if (isNaN(date.getTime())) {
return null;
}
return date;
}
catch (error) {
// File doesn't exist or can't be read
return null;
}
}
/**
* Stores the "Last updated" date to the cache
* @param date The last updated date to store
*/
async setLastUpdatedDate(date) {
try {
const lastUpdatedFile = await this.getLastUpdatedFile();
await fs.writeFile(lastUpdatedFile, date.toISOString(), 'utf-8');
}
catch (error) {
throw new Error(`Failed to write last updated date file: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
/**
* Checks if the cache is stale based on comparing stored date with remote date
* @param remoteDate The current "Last updated" date from the remote source
* @returns true if cache is stale (dates don't match or no stored date exists)
*/
async isCacheStaleByDate(remoteDate) {
const storedDate = await this.getLastUpdatedDate();
if (!storedDate) {
// No stored date exists, cache is considered stale
return true;
}
// Compare dates - if they're different, cache is stale
return storedDate.getTime() !== remoteDate.getTime();
}
/**
* Comprehensive cache validation that combines date-based and time-based checks
* @param remoteDate The current "Last updated" date from the remote source (optional)
* @returns true if cache is stale and needs to be refreshed
*/
async isCacheStale(remoteDate) {
// First check if we need to validate based on 24-hour interval
const shouldCheckRemote = await this.shouldCheckRemoteDate();
if (!shouldCheckRemote && !remoteDate) {
// Within 24-hour window and no remote date provided, cache is fresh
return false;
}
if (remoteDate) {
// We have a remote date, use date-based validation
const isStaleByDate = await this.isCacheStaleByDate(remoteDate);
if (isStaleByDate) {
return true;
}
// Dates match, update our check timestamp and consider cache fresh
await this.writeTimestamp();
return false;
}
// Fallback to time-based caching if date parsing fails or no remote date
return await super.isCacheStale();
}
/**
* Checks if we should validate against the remote date based on 24-hour interval
* @returns true if more than 24 hours have passed since last check
*/
async shouldCheckRemoteDate() {
const cacheAge = await this.getCacheAgeHours();
if (cacheAge === null) {
// No timestamp exists, should check remote
return true;
}
// Check if 24 hours have passed since last validation
return cacheAge >= 24;
}
/**
* Deletes both timestamp and last updated date files
*/
async deleteTimestamp() {
await super.deleteTimestamp();
try {
const lastUpdatedFile = await this.getLastUpdatedFile();
await fs.unlink(lastUpdatedFile);
}
catch (error) {
// Ignore errors if file doesn't exist
if (error.code !== 'ENOENT') {
throw error;
}
}
}
}
//# sourceMappingURL=DateBasedCacheManager.js.map