brainy/.recovery-workspace/dist-backup-20250910-141917/augmentations/cacheAugmentation.js
David Snelling 8ff382ca3b chore: recovery checkpoint - v3.0 API successfully recovered
CRITICAL CHECKPOINT - DO NOT PUSH TO GITHUB

Recovery Status:
- Successfully recovered brainy.ts from compiled JavaScript
- All core v3.0 API methods functional (add, get, update, delete, relate, find, etc.)
- Neural subsystem intact (562KB embedded patterns, NLP working)
- Augmentation pipeline operational (20+ augmentations)
- HNSW clustering system complete
- Triple Intelligence compiled (needs constructor fix)
- Test suite validates functionality

Changes preserved:
- 898 files with changes from last 3 days
- 144,475 insertions
- All augmentation improvements
- All test coverage enhancements
- Complete v3.0 feature set

This is a LOCAL checkpoint only - contains recovered work after corruption incident.
Created backup in .backups/brainy-full-20250910-151314.tar.gz

Branch: recovery-checkpoint-20250910-151433
Date: Wed Sep 10 03:18:04 PM PDT 2025
2025-09-10 15:18:04 -07:00

338 lines
No EOL
11 KiB
JavaScript

/**
* Cache Augmentation - Optional Search Result Caching
*
* Replaces the hardcoded SearchCache in Brainy with an optional augmentation.
* This reduces core size and allows custom cache implementations.
*
* Zero-config: Automatically enabled with sensible defaults
* Can be disabled or customized via augmentation registry
*/
import { BaseAugmentation } from './brainyAugmentation.js';
import { SearchCache } from '../utils/searchCache.js';
/**
* CacheAugmentation - Makes search caching optional and pluggable
*
* Features:
* - Transparent search result caching
* - Automatic invalidation on data changes
* - Memory-aware cache management
* - Zero-config with smart defaults
*/
export class CacheAugmentation extends BaseAugmentation {
constructor(config) {
super(config);
this.name = 'cache';
this.timing = 'around';
this.metadata = 'none'; // Cache doesn't access metadata
this.operations = ['search', 'find', 'similar', 'add', 'update', 'delete', 'clear', 'all'];
this.priority = 50; // Mid-priority, runs after data operations
// Augmentation metadata
this.category = 'core';
this.description = 'Transparent search result caching with automatic invalidation';
this.searchCache = null;
}
getManifest() {
return {
id: 'cache',
name: 'Cache',
version: '2.0.0',
description: 'Intelligent caching for search and query operations',
longDescription: 'Provides transparent caching for search results with automatic invalidation on data changes. Significantly improves performance for repeated queries while maintaining data consistency.',
category: 'performance',
configSchema: {
type: 'object',
properties: {
enabled: {
type: 'boolean',
default: true,
description: 'Enable or disable caching'
},
maxSize: {
type: 'number',
default: 1000,
minimum: 10,
maximum: 100000,
description: 'Maximum number of cached entries'
},
ttl: {
type: 'number',
default: 300000, // 5 minutes
minimum: 1000, // 1 second
maximum: 3600000, // 1 hour
description: 'Time to live for cache entries in milliseconds'
},
invalidateOnWrite: {
type: 'boolean',
default: true,
description: 'Automatically invalidate cache on data modifications'
}
},
additionalProperties: false
},
configDefaults: {
enabled: true,
maxSize: 1000,
ttl: 300000,
invalidateOnWrite: true
},
configExamples: [
{
name: 'High Performance',
description: 'Large cache with longer TTL for read-heavy workloads',
config: {
enabled: true,
maxSize: 10000,
ttl: 1800000, // 30 minutes
invalidateOnWrite: true
}
},
{
name: 'Conservative',
description: 'Small cache with short TTL for frequently changing data',
config: {
enabled: true,
maxSize: 100,
ttl: 60000, // 1 minute
invalidateOnWrite: true
}
}
],
minBrainyVersion: '2.0.0',
keywords: ['cache', 'performance', 'search', 'optimization'],
documentation: 'https://docs.brainy.dev/augmentations/cache',
status: 'stable',
performance: {
memoryUsage: 'medium',
cpuUsage: 'low',
networkUsage: 'none'
},
features: ['search-caching', 'auto-invalidation', 'ttl-support', 'memory-management'],
enhancedOperations: ['search', 'searchText', 'findSimilar'],
metrics: [
{
name: 'cache_hits',
type: 'counter',
description: 'Number of cache hits'
},
{
name: 'cache_misses',
type: 'counter',
description: 'Number of cache misses'
},
{
name: 'cache_size',
type: 'gauge',
description: 'Current cache size'
}
],
ui: {
icon: '⚡',
color: '#FFC107'
}
};
}
async onInitialize() {
if (!this.config.enabled) {
this.log('Cache augmentation disabled by configuration');
return;
}
// Initialize search cache with config
this.searchCache = new SearchCache({
maxSize: this.config.maxSize,
maxAge: this.config.ttl, // SearchCache uses maxAge, not ttl
enabled: true
});
this.log(`Cache augmentation initialized (maxSize: ${this.config.maxSize}, ttl: ${this.config.ttl}ms)`);
}
async onShutdown() {
if (this.searchCache) {
this.searchCache.clear();
this.searchCache = null;
}
this.log('Cache augmentation shut down');
}
/**
* Execute augmentation - wrap operations with caching logic
*/
async execute(operation, params, next) {
// If cache is disabled, just pass through
if (!this.searchCache || !this.config.enabled) {
return next();
}
switch (operation) {
case 'search':
return this.handleSearch(params, next);
case 'add':
case 'update':
case 'delete':
// Invalidate cache on data changes
if (this.config.invalidateOnWrite) {
const result = await next();
this.searchCache.invalidateOnDataChange(operation);
this.log(`Cache invalidated due to ${operation} operation`);
return result;
}
return next();
case 'clear':
// Clear cache when all data is cleared
const result = await next();
this.searchCache.clear();
this.log('Cache cleared due to clear operation');
return result;
default:
return next();
}
}
/**
* Handle search operation with caching
*/
async handleSearch(params, next) {
if (!this.searchCache)
return next();
// Extract search parameters
const { query, k, options = {} } = params;
// Skip cache if explicitly disabled or has complex filters
if (options.skipCache || options.metadata) {
return next();
}
// Generate cache key
const cacheKey = this.searchCache.getCacheKey(query, k, options);
// Check cache
const cachedResult = this.searchCache.get(cacheKey);
if (cachedResult) {
this.log('Cache hit for search query');
// Update metrics if available
if (this.context?.brain) {
const metrics = this.context.brain.augmentations?.get('metrics');
if (metrics) {
metrics.recordCacheHit?.();
}
}
return cachedResult;
}
// Execute search
const result = await next();
// Cache the result
this.searchCache.set(cacheKey, result);
this.log('Search result cached');
// Update metrics if available
if (this.context?.brain) {
const metrics = this.context.brain.augmentations?.get('metrics');
if (metrics) {
metrics.recordCacheMiss?.();
}
}
return result;
}
/**
* Get cache statistics
*/
getStats() {
if (!this.searchCache) {
return {
enabled: false,
hits: 0,
misses: 0,
size: 0,
memoryUsage: 0
};
}
const stats = this.searchCache.getStats();
return {
...stats,
memoryUsage: this.searchCache.getMemoryUsage()
};
}
/**
* Clear the cache manually
*/
clear() {
if (this.searchCache) {
this.searchCache.clear();
this.log('Cache manually cleared');
}
}
/**
* Handle runtime configuration changes
*/
async onConfigChange(newConfig, oldConfig) {
if (this.searchCache && newConfig.enabled) {
this.searchCache.updateConfig({
maxSize: newConfig.maxSize,
maxAge: newConfig.ttl, // SearchCache uses maxAge
enabled: newConfig.enabled
});
this.log('Cache configuration updated');
}
else if (!newConfig.enabled && this.searchCache) {
this.searchCache.clear();
this.log('Cache disabled and cleared');
}
}
/**
* Clean up expired entries
*/
cleanupExpiredEntries() {
if (!this.searchCache)
return 0;
const cleaned = this.searchCache.cleanupExpiredEntries();
if (cleaned > 0) {
this.log(`Cleaned ${cleaned} expired cache entries`);
}
return cleaned;
}
/**
* Invalidate cache when data changes
*/
invalidateOnDataChange(operation) {
if (!this.searchCache)
return;
this.searchCache.invalidateOnDataChange(operation);
this.log(`Cache invalidated due to ${operation} operation`);
}
/**
* Get cache key for a query
*/
getCacheKey(query, options) {
if (!this.searchCache)
return '';
return this.searchCache.getCacheKey(query, options);
}
/**
* Direct cache get
*/
get(key) {
if (!this.searchCache)
return null;
return this.searchCache.get(key);
}
/**
* Direct cache set
*/
set(key, value) {
if (!this.searchCache)
return;
this.searchCache.set(key, value);
}
/**
* Get the underlying SearchCache instance (for compatibility)
*/
getSearchCache() {
return this.searchCache;
}
/**
* Get memory usage
*/
getMemoryUsage() {
if (!this.searchCache)
return 0;
return this.searchCache.getMemoryUsage();
}
}
/**
* Factory function for zero-config cache augmentation
*/
export function createCacheAugmentation(config) {
return new CacheAugmentation(config);
}
//# sourceMappingURL=cacheAugmentation.js.map