**feat(core): enhance vector handling, model loading, and compatibility**

- **Vector Handling Updates**:
  - Added a `dimensions` property to `BrainyDataConfig` for specifying vector dimensions.
  - Introduced validation for vector dimensions during database creation and insertion to ensure consistency.
  - Enhanced error handling and logging for dimension mismatches.

- **Model Loading Improvements**:
  - Implemented retry logic for Universal Sentence Encoder model loading to handle network instability and JSON parsing errors gracefully.
  - Improved logging and debugging support for failures during model initialization and embedding operations.

- **Compatibility Enhancements**:
  - Updated polyfills to support TensorFlow.js compatibility across diverse server environments (Node.js, serverless, etc.).
  - Introduced and refactored global `TextEncoder`/`TextDecoder` definitions for seamless operation in non-browser environments.
  - Simplified TensorFlow.js backend setup with streamlined imports and logging for GPU/WebGL fallback.

- **Purpose**:
  - These updates improve BrainyData's robustness, enforce correct vector usage, and extend compatibility with varied runtime environments. The changes enhance the usability, reliability, and cross-platform readiness of core functionalities.
This commit is contained in:
David Snelling 2025-07-16 13:51:00 -07:00
parent ad4af27385
commit 3ec183dab6
9 changed files with 828 additions and 365 deletions

View file

@ -413,6 +413,7 @@ export class FileSystemStorage implements StorageAdapter {
public async saveMetadata(id: string, metadata: any): Promise<void> {
if (!this.isInitialized) await this.init()
const filePath = path.join(this.metadataDir, `${id}.json`)
await this.ensureDirectoryExists(path.dirname(filePath))
await fs.promises.writeFile(filePath, JSON.stringify(metadata, null, 2))
}
@ -437,7 +438,60 @@ export class FileSystemStorage implements StorageAdapter {
public async clear(): Promise<void> {
if (!this.isInitialized) await this.init()
await fs.promises.rm(this.rootDir, { recursive: true, force: true })
// Helper function to recursively remove directory contents
const removeDirectoryContents = async (dirPath: string): Promise<void> => {
try {
const files = await fs.promises.readdir(dirPath, { withFileTypes: true })
for (const file of files) {
const fullPath = path.join(dirPath, file.name)
if (file.isDirectory()) {
await removeDirectoryContents(fullPath)
// Use fs.promises.rm with recursive option instead of rmdir
try {
await fs.promises.rm(fullPath, { recursive: true, force: true })
} catch (rmError: any) {
// Fallback to rmdir if rm fails
await fs.promises.rmdir(fullPath)
}
} else {
await fs.promises.unlink(fullPath)
}
}
} catch (error: any) {
if (error.code !== 'ENOENT') {
console.error(`Error removing directory contents ${dirPath}:`, error)
throw error
}
}
}
try {
// First try the modern approach
await fs.promises.rm(this.rootDir, { recursive: true, force: true })
} catch (error: any) {
console.warn('Modern rm failed, falling back to manual cleanup:', error)
// Fallback: manually remove contents then directory
try {
await removeDirectoryContents(this.rootDir)
// Use fs.promises.rm with recursive option instead of rmdir
try {
await fs.promises.rm(this.rootDir, { recursive: true, force: true })
} catch (rmError: any) {
// Final fallback to rmdir if rm fails
await fs.promises.rmdir(this.rootDir)
}
} catch (fallbackError: any) {
if (fallbackError.code !== 'ENOENT') {
console.error('Manual cleanup also failed:', fallbackError)
throw fallbackError
}
}
}
this.isInitialized = false // Reset state
await this.init() // Re-create directories
}