feat: v0.49 - Filter discovery API, remove deprecated methods, improve performance

BREAKING CHANGES:
- Removed deprecated getAllNouns() and getAllVerbs() methods
- All internal usage migrated to pagination-based methods

New Features:
- Filter Discovery API:
  - getFilterValues(field): Get all available values for a field
  - getFilterFields(): Get all filterable fields
  - Enables dynamic filter UI generation with O(1) field discovery
- Hybrid metadata indexing with field-level indexes
- Adaptive auto-flush for optimal performance
- LRU caching for metadata indexes

Improvements:
- Fixed ENAMETOOLONG errors from vector-based filenames
- Safe filename generation using hash-based approach
- Scalable chunked value storage for millions of entries
- Performance optimization with adaptive flush thresholds
- Added support for $includes operator in metadata filters

Technical:
- Replaced vector-based filenames with safe hash approach
- Implemented MetadataIndexCache with existing SearchCache pattern
- Field indexes enable O(1) filter discovery
- Adaptive flush based on performance metrics (20-200 entries)
- All tests passing with improved metadata filtering
This commit is contained in:
David Snelling 2025-08-06 14:39:33 -07:00
parent cc1c6fb718
commit 2231f90913
18 changed files with 958 additions and 486 deletions

View file

@ -255,46 +255,6 @@ export class OPFSStorage extends BaseStorage {
}
}
/**
* Get all nouns from storage
*/
protected async getAllNouns_internal(): Promise<HNSWNoun_internal[]> {
await this.ensureInitialized()
const allNouns: HNSWNoun_internal[] = []
try {
// Iterate through all files in the nouns directory
for await (const [name, handle] of this.nounsDir!.entries()) {
if (handle.kind === 'file') {
try {
// Read the noun data from the file
const file = await safeGetFile(handle)
const text = await file.text()
const data = JSON.parse(text)
// Convert serialized connections back to Map<number, Set<string>>
const connections = new Map<number, Set<string>>()
for (const [level, nounIds] of Object.entries(data.connections)) {
connections.set(Number(level), new Set(nounIds as string[]))
}
allNouns.push({
id: data.id,
vector: data.vector,
connections,
level: data.level || 0
})
} catch (error) {
console.error(`Error reading noun file ${name}:`, error)
}
}
}
} catch (error) {
console.error('Error reading nouns directory:', error)
}
return allNouns
}
/**
* Get nouns by noun type (internal implementation)
@ -469,12 +429,6 @@ export class OPFSStorage extends BaseStorage {
}
}
/**
* Get all verbs from storage (internal implementation)
*/
protected async getAllVerbs_internal(): Promise<HNSWVerb[]> {
return this.getAllEdges()
}
/**
* Get all edges from storage