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
This commit is contained in:
parent
f65455fb22
commit
8ff382ca3b
895 changed files with 143654 additions and 28268 deletions
|
|
@ -0,0 +1,338 @@
|
|||
/**
|
||||
* 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue