brainy/dist/storage/storageFactory.js
David Snelling f8c45f2d8d Initial commit: Brainy - Multi-Dimensional AI Database
Open source vector database with HNSW indexing, graph relationships,
and metadata facets. Features CLI with professional augmentation registry
integration for discovering extensions and capabilities.
2025-08-18 17:35:06 -07:00

227 lines
No EOL
10 KiB
JavaScript

/**
* Storage Factory
* Creates the appropriate storage adapter based on the environment and configuration
*/
import { MemoryStorage } from './adapters/memoryStorage.js';
import { OPFSStorage } from './adapters/opfsStorage.js';
import { S3CompatibleStorage, R2Storage } from './adapters/s3CompatibleStorage.js';
// FileSystemStorage is dynamically imported to avoid issues in browser environments
import { isBrowser } from '../utils/environment.js';
/**
* Create a storage adapter based on the environment and configuration
* @param options Options for creating the storage adapter
* @returns Promise that resolves to a storage adapter
*/
export async function createStorage(options = {}) {
// If memory storage is forced, use it regardless of other options
if (options.forceMemoryStorage) {
console.log('Using memory storage (forced)');
return new MemoryStorage();
}
// If file system storage is forced, use it regardless of other options
if (options.forceFileSystemStorage) {
if (isBrowser()) {
console.warn('FileSystemStorage is not available in browser environments, falling back to memory storage');
return new MemoryStorage();
}
console.log('Using file system storage (forced)');
try {
const { FileSystemStorage } = await import('./adapters/fileSystemStorage.js');
return new FileSystemStorage(options.rootDirectory || './brainy-data');
}
catch (error) {
console.warn('Failed to load FileSystemStorage, falling back to memory storage:', error);
return new MemoryStorage();
}
}
// If a specific storage type is specified, use it
if (options.type && options.type !== 'auto') {
switch (options.type) {
case 'memory':
console.log('Using memory storage');
return new MemoryStorage();
case 'opfs': {
// Check if OPFS is available
const opfsStorage = new OPFSStorage();
if (opfsStorage.isOPFSAvailable()) {
console.log('Using OPFS storage');
await opfsStorage.init();
// Request persistent storage if specified
if (options.requestPersistentStorage) {
const isPersistent = await opfsStorage.requestPersistentStorage();
console.log(`Persistent storage ${isPersistent ? 'granted' : 'denied'}`);
}
return opfsStorage;
}
else {
console.warn('OPFS storage is not available, falling back to memory storage');
return new MemoryStorage();
}
}
case 'filesystem': {
if (isBrowser()) {
console.warn('FileSystemStorage is not available in browser environments, falling back to memory storage');
return new MemoryStorage();
}
console.log('Using file system storage');
try {
const { FileSystemStorage } = await import('./adapters/fileSystemStorage.js');
return new FileSystemStorage(options.rootDirectory || './brainy-data');
}
catch (error) {
console.warn('Failed to load FileSystemStorage, falling back to memory storage:', error);
return new MemoryStorage();
}
}
case 's3':
if (options.s3Storage) {
console.log('Using Amazon S3 storage');
return new S3CompatibleStorage({
bucketName: options.s3Storage.bucketName,
region: options.s3Storage.region,
accessKeyId: options.s3Storage.accessKeyId,
secretAccessKey: options.s3Storage.secretAccessKey,
sessionToken: options.s3Storage.sessionToken,
serviceType: 's3',
operationConfig: options.operationConfig,
cacheConfig: options.cacheConfig
});
}
else {
console.warn('S3 storage configuration is missing, falling back to memory storage');
return new MemoryStorage();
}
case 'r2':
if (options.r2Storage) {
console.log('Using Cloudflare R2 storage');
return new R2Storage({
bucketName: options.r2Storage.bucketName,
accountId: options.r2Storage.accountId,
accessKeyId: options.r2Storage.accessKeyId,
secretAccessKey: options.r2Storage.secretAccessKey,
serviceType: 'r2',
cacheConfig: options.cacheConfig
});
}
else {
console.warn('R2 storage configuration is missing, falling back to memory storage');
return new MemoryStorage();
}
case 'gcs':
if (options.gcsStorage) {
console.log('Using Google Cloud Storage');
return new S3CompatibleStorage({
bucketName: options.gcsStorage.bucketName,
region: options.gcsStorage.region,
endpoint: options.gcsStorage.endpoint || 'https://storage.googleapis.com',
accessKeyId: options.gcsStorage.accessKeyId,
secretAccessKey: options.gcsStorage.secretAccessKey,
serviceType: 'gcs',
cacheConfig: options.cacheConfig
});
}
else {
console.warn('GCS storage configuration is missing, falling back to memory storage');
return new MemoryStorage();
}
default:
console.warn(`Unknown storage type: ${options.type}, falling back to memory storage`);
return new MemoryStorage();
}
}
// If custom S3-compatible storage is specified, use it
if (options.customS3Storage) {
console.log(`Using custom S3-compatible storage: ${options.customS3Storage.serviceType || 'custom'}`);
return new S3CompatibleStorage({
bucketName: options.customS3Storage.bucketName,
region: options.customS3Storage.region,
endpoint: options.customS3Storage.endpoint,
accessKeyId: options.customS3Storage.accessKeyId,
secretAccessKey: options.customS3Storage.secretAccessKey,
serviceType: options.customS3Storage.serviceType || 'custom',
cacheConfig: options.cacheConfig
});
}
// If R2 storage is specified, use it
if (options.r2Storage) {
console.log('Using Cloudflare R2 storage');
return new R2Storage({
bucketName: options.r2Storage.bucketName,
accountId: options.r2Storage.accountId,
accessKeyId: options.r2Storage.accessKeyId,
secretAccessKey: options.r2Storage.secretAccessKey,
serviceType: 'r2',
cacheConfig: options.cacheConfig
});
}
// If S3 storage is specified, use it
if (options.s3Storage) {
console.log('Using Amazon S3 storage');
return new S3CompatibleStorage({
bucketName: options.s3Storage.bucketName,
region: options.s3Storage.region,
accessKeyId: options.s3Storage.accessKeyId,
secretAccessKey: options.s3Storage.secretAccessKey,
sessionToken: options.s3Storage.sessionToken,
serviceType: 's3',
cacheConfig: options.cacheConfig
});
}
// If GCS storage is specified, use it
if (options.gcsStorage) {
console.log('Using Google Cloud Storage');
return new S3CompatibleStorage({
bucketName: options.gcsStorage.bucketName,
region: options.gcsStorage.region,
endpoint: options.gcsStorage.endpoint || 'https://storage.googleapis.com',
accessKeyId: options.gcsStorage.accessKeyId,
secretAccessKey: options.gcsStorage.secretAccessKey,
serviceType: 'gcs',
cacheConfig: options.cacheConfig
});
}
// Auto-detect the best storage adapter based on the environment
// First, try OPFS (browser only)
const opfsStorage = new OPFSStorage();
if (opfsStorage.isOPFSAvailable()) {
console.log('Using OPFS storage (auto-detected)');
await opfsStorage.init();
// Request persistent storage if specified
if (options.requestPersistentStorage) {
const isPersistent = await opfsStorage.requestPersistentStorage();
console.log(`Persistent storage ${isPersistent ? 'granted' : 'denied'}`);
}
return opfsStorage;
}
// Next, try file system storage (Node.js only)
try {
// Check if we're in a Node.js environment
if (typeof process !== 'undefined' &&
process.versions &&
process.versions.node) {
console.log('Using file system storage (auto-detected)');
try {
const { FileSystemStorage } = await import('./adapters/fileSystemStorage.js');
return new FileSystemStorage(options.rootDirectory || './brainy-data');
}
catch (fsError) {
console.warn('Failed to load FileSystemStorage, falling back to memory storage:', fsError);
}
}
}
catch (error) {
// Not in a Node.js environment or file system is not available
console.warn('Not in a Node.js environment:', error);
}
// Finally, fall back to memory storage
console.log('Using memory storage (auto-detected)');
return new MemoryStorage();
}
/**
* Export storage adapters
*/
export { MemoryStorage, OPFSStorage, S3CompatibleStorage, R2Storage };
// Export FileSystemStorage conditionally
// NOTE: FileSystemStorage is now only imported dynamically to avoid fs imports in browser builds
// export { FileSystemStorage } from './adapters/fileSystemStorage.js'
//# sourceMappingURL=storageFactory.js.map