UNPKG

@yihuangdb/storage-object

Version:

A Node.js storage object layer library using Redis OM

754 lines 23.7 kB
/** * @module storage-system * @description Central management system for all storage instances. * Provides a unified, object-oriented API for creating, managing, and monitoring storage objects. * * @since 0.1.0 * @author StorageObject Team */ import { StorageObject, StorageOptions } from './storage'; import { SchemaConfig } from './schema'; import { StorageSchema as NewStorageSchema } from './storage-schema'; import { SchemaMetadata } from './schema-registry'; import { ExportOptions, ImportOptions } from './export-import-manager'; /** * Configuration options for StorageSystem initialization. * Used to configure global settings that apply to all storage instances. * * @interface StorageSystemConfig * @since 0.1.0 */ export interface StorageSystemConfig { /** Redis connection configuration */ redis?: { host?: string; port?: number; password?: string; db?: number; }; /** Connection pool configuration */ connectionPool?: { maxSize?: number; idleTimeout?: number; acquireTimeout?: number; }; /** Default storage options */ defaultOptions?: StorageOptions; /** Redis OM version validation settings */ versionValidation?: { /** Enable version validation (default: true) */ enabled?: boolean; /** Strict mode for version checking (default: true) */ strictMode?: boolean; }; } /** * Migration options for storage data migration */ export interface MigrationOptions { /** Transform function to apply during migration */ transform?: (oldData: any) => any; /** Whether to validate data after transformation */ validateData?: boolean; /** Batch size for migration operations */ batchSize?: number; } /** * Backup options for storage backup operations */ export interface BackupOptions { /** Storage names to backup (all if not specified) */ names?: string[]; /** Include data in backup */ includeData?: boolean; /** Compress backup data */ compress?: boolean; } /** * Restore options for storage restore operations */ export interface RestoreOptions { /** Overwrite existing storages */ overwrite?: boolean; /** Skip existing storages */ skipExisting?: boolean; /** Validate schema after restore */ validateSchema?: boolean; } /** * Monitor event type for storage monitoring */ export interface MonitorEvent { /** Type of operation */ type: 'create' | 'update' | 'delete'; /** Entity ID involved in the operation */ entityId?: string; /** Data involved in the operation */ data?: any; /** Timestamp of the event */ timestamp: Date; } /** * System-wide export options */ export interface SystemExportOptions extends ExportOptions { /** Specific schemas to export */ schemasToExport?: string[]; } /** * System-wide import options */ export interface SystemImportOptions extends ImportOptions { /** Specific schemas to import */ schemasToImport?: string[]; } /** * System export result */ export interface SystemExportResult { systemExportId: string; exportTimestamp: number; exportedSchemas: Array<{ schemaName: string; schemaVersionNum: number; storageVersionNum: number; entityCount: number; exportFilePath: string; }>; totalExportedEntities: number; exportFormat: string; isCompressed: boolean; } /** * System import result */ export interface SystemImportResult { systemImportId: string; importTimestamp: number; importedSchemas: Array<{ schemaName: string; importedEntities: number; failedEntities: number; schemaUpdated: boolean; errors: Array<{ entityId: string; error: string; }>; }>; totalImportedEntities: number; totalFailedEntities: number; totalImportDuration: number; } /** * StorageSystem - Central management class for all storage operations. * * This class provides static methods for managing storage instances, schemas, and system-wide operations. * All methods are static - no instantiation is required or allowed. * * @class StorageSystem * @since 0.1.0 * * @example Basic Usage * ```typescript * // Initialize the system with configuration * await StorageSystem.initialize({ * redis: { host: 'localhost', port: 6379 }, * connectionPool: { maxSize: 20 } * }); * * // Create a new storage * const userStorage = await StorageSystem.create('users', schema); * * // Get existing storage * const storage = await StorageSystem.get('users'); * * // List all storages * const schemas = await StorageSystem.list(); * * // Delete a storage * await StorageSystem.delete('users'); * ``` * * @example Advanced Operations * ```typescript * // Get or create a storage * const storage = await StorageSystem.getOrCreate('products', schema); * * // Check if storage exists * if (await StorageSystem.exists('orders')) { * const orders = await StorageSystem.get('orders'); * } * * // Get storage statistics * const stats = await StorageSystem.getStats('users'); * console.log('Total users:', stats.objectCount); * * // Backup and restore * const backup = await StorageSystem.backup({ includeData: true }); * await StorageSystem.restore(backup, { overwrite: true }); * ``` */ export declare class StorageSystem { /** Singleton schema registry instance */ private static registry; /** System configuration */ private static config; /** Whether the system has been initialized */ private static initialized; /** Storage version managers for each schema */ private static storageVersionManagers; /** Export/import managers for each schema */ private static exportImportManagers; /** Storage instances for system-wide operations */ private static storageInstances; /** Version validator instance */ private static versionValidator; /** * Private constructor to prevent instantiation */ private constructor(); /** * Get or create the schema registry instance */ private static getRegistry; /** * Initialize the StorageSystem with global configuration. * This method is optional - StorageSystem works with defaults if not called. * * @param config - System configuration options * @returns Promise that resolves when initialization is complete * * @example * ```typescript * // Optional initialization with custom config * await StorageSystem.initialize({ * redis: { host: 'localhost', port: 6379 }, * defaultOptions: { * useJSON: true, * enableOptimisticLocking: true * } * }); * * // Or just start using it with defaults * const users = await StorageSystem.create('users', schema); * ``` */ static initialize(config?: StorageSystemConfig): Promise<void>; /** * Configure StorageSystem with a config object or function. * Alternative to initialize() with a more flexible API. * * @param configOrFn - Configuration object or function that returns config * @returns The StorageSystem class for chaining * * @example * ```typescript * // Configure with object * StorageSystem.configure({ * redis: { host: 'redis.example.com' } * }); * * // Configure with function * StorageSystem.configure((config) => { * config.redis = { host: process.env.REDIS_HOST }; * config.defaultOptions = { useJSON: true }; * }); * ``` */ static configure(configOrFn: StorageSystemConfig | ((config: StorageSystemConfig) => void)): typeof StorageSystem; /** * Create a new storage instance with the given schema. * * This is the primary method for creating storage instances. It automatically: * - Validates the schema * - Registers it with the schema registry * - Initializes the storage with optimized settings * - Returns a ready-to-use StorageObject * * @template T - Type of the entities to be stored * @param name - Unique name for the storage * @param schema - Schema configuration or StorageSchema instance * @param options - Optional storage configuration * @returns Promise resolving to the created StorageObject instance * * @example Simple Usage * ```typescript * // Using inline schema definition * const users = await StorageSystem.create('users', { * name: 'text', * email: 'string', * age: 'number' * }); * * // Using StorageSchema * const schema = StorageSchema.define({ * name: { type: 'text', indexed: true }, * email: { type: 'string', indexed: true, required: true }, * age: { type: 'number', indexed: true } * }); * const users = await StorageSystem.create('users', schema); * ``` * * @example Advanced Usage * ```typescript * const users = await StorageSystem.create('users', { * email: { * type: 'string', * indexed: true, * required: true, * validate: (value) => value.includes('@') || 'Invalid email' * }, * role: { * type: 'string', * indexed: true, * default: 'user' * }, * tags: { type: 'string[]', separator: ',', indexed: true } * }, { * enableOptimisticLocking: true, * enableChangeTracking: true * }); * ``` */ static create<T extends Record<string, any> = any>(name: string, schema: SchemaConfig | NewStorageSchema<T>, options?: StorageOptions): Promise<StorageObject<T>>; /** * Get an existing storage instance by name. * * @param name - Name of the storage to retrieve * @returns Promise resolving to the StorageObject instance or null if not found * * @example * ```typescript * const users = await StorageSystem.get('users'); * if (users) { * const allUsers = await users.findAll(); * } * ``` */ static get<T extends Record<string, any> = any>(name: string): Promise<StorageObject<T> | null>; /** * Open an existing storage or throw if not found. * Convenience method that ensures the storage exists. * * @param name - Name of the storage to open * @returns Promise resolving to the StorageObject instance * @throws Error if storage doesn't exist * * @example * ```typescript * const users = await StorageSystem.open('users'); * // No null check needed - throws if not found * const allUsers = await users.findAll(); * ``` */ static open<T extends Record<string, any> = any>(name: string): Promise<StorageObject<T>>; /** * Delete a storage and all its data. * * @param name - Name of the storage to delete * @returns Promise resolving to true if deleted, false otherwise * * @example * ```typescript * const deleted = await StorageSystem.delete('users'); * console.log(deleted ? 'Deleted successfully' : 'Not found'); * ``` */ static delete(name: string): Promise<boolean>; /** * Clear all data from a storage without deleting the schema. * * @param name - Name of the storage to clear * @returns Promise resolving when cleared * @throws Error if storage doesn't exist * * @example * ```typescript * await StorageSystem.clear('users'); * console.log('All user data cleared'); * ``` */ static clear(name: string): Promise<void>; /** * Get storage metadata including statistics * * @param name - Name of the storage * @returns Promise resolving to metadata or null if not found * * @example * ```typescript * const metadata = await StorageSystem.getMetadata('users'); * if (metadata) { * console.log('Object count:', metadata.statistics.objectCount); * } * ``` */ static getMetadata(name: string): Promise<SchemaMetadata | null>; /** * Validate a storage schema against its data * * @param name - Name of the storage to validate * @returns Promise resolving to validation results * * @example * ```typescript * const validation = await StorageSystem.validate('users'); * if (!validation.valid) { * console.error('Validation errors:', validation.errors); * } * ``` */ static validate(name: string): Promise<{ valid: boolean; errors: string[]; warnings: string[]; }>; /** * Check if a storage exists. * * @param name - Name of the storage to check * @returns Promise resolving to true if storage exists, false otherwise * * @example * ```typescript * if (await StorageSystem.exists('users')) { * const users = await StorageSystem.open('users'); * } * ``` */ static exists(name: string): Promise<boolean>; /** * Get all storage names. * * @returns Promise resolving to array of storage names * * @example * ```typescript * const names = await StorageSystem.names(); * console.log('Available storages:', names); * // ['users', 'products', 'orders'] * ``` */ static names(): Promise<string[]>; /** * List all registered storage schemas with metadata. * * @returns Promise resolving to array of schema metadata * * @example * ```typescript * const schemas = await StorageSystem.list(); * schemas.forEach(schema => { * console.log(`${schema.name}: ${schema.statistics.objectCount} objects`); * }); * ``` */ static list(): Promise<SchemaMetadata[]>; /** * Flush all Redis data (DANGEROUS - requires confirmation) * * @param confirmation - Must be 'CONFIRM_FLUSH_ALL' to execute * @returns Promise resolving to true if flushed, false if not confirmed * * @example * ```typescript * // This will delete ALL Redis data - use with extreme caution! * const flushed = await StorageSystem.flushAll('CONFIRM_FLUSH_ALL'); * ``` */ static flushAll(confirmation: string): Promise<boolean>; /** * Get or create a storage instance. * * @param name - Name of the storage * @param schema - Schema configuration (required if storage doesn't exist) * @param options - Optional storage configuration * @returns Promise resolving to the StorageObject instance * * @example * ```typescript * // Will create if doesn't exist, or return existing * const users = await StorageSystem.getOrCreate('users', { * name: 'text', * email: 'string' * }); * ``` */ static getOrCreate<T extends Record<string, any> = any>(name: string, schema?: SchemaConfig | NewStorageSchema<T>, options?: StorageOptions): Promise<StorageObject<T>>; /** * Get storage statistics * * @param name - Name of the storage * @returns Promise resolving to statistics or null if not found * * @example * ```typescript * const stats = await StorageSystem.getStats('users'); * if (stats) { * console.log('Average create time:', stats.performance.averageCreateTime); * } * ``` */ static getStats(name: string): Promise<{ objectCount: number; totalOperations: number; averageObjectSize: number; performance: { averageCreateTime: number; averageReadTime: number; averageUpdateTime: number; averageDeleteTime: number; }; } | null>; /** * Backup all storages or specific storages * * @param options - Backup options * @returns Promise resolving to backup JSON string * * @example * ```typescript * const backup = await StorageSystem.backup({ * names: ['users', 'products'], * includeData: true * }); * ``` */ static backup(options?: BackupOptions): Promise<string>; /** * Restore storages from backup * * @param backupJson - Backup JSON string * @param options - Restore options * @returns Promise resolving to restore results * * @example * ```typescript * const result = await StorageSystem.restore(backupJson, { * overwrite: true, * validateSchema: true * }); * ``` */ static restore(backupJson: string, options?: RestoreOptions): Promise<{ success: boolean; restored: string[]; failed: string[]; errors: Record<string, string>; }>; /** * Clean up inactive storages * * @param inactiveDays - Number of days of inactivity before cleanup (default: 30) * @returns Promise resolving to cleanup results * * @example * ```typescript * const result = await StorageSystem.cleanup(90); * console.log('Cleaned:', result.cleaned); * console.log('Kept:', result.kept); * ``` */ static cleanup(inactiveDays?: number): Promise<{ cleaned: string[]; kept: string[]; }>; /** * Get global statistics across all storages * * @returns Promise resolving to global statistics * * @example * ```typescript * const stats = await StorageSystem.getGlobalStats(); * console.log('Total schemas:', stats.totalSchemas); * console.log('Total objects:', stats.totalObjects); * ``` */ static getGlobalStats(): Promise<{ totalSchemas: number; activeSchemas: number; totalObjects: number; totalOperations: number; storageSize: number; topSchemas: Array<{ name: string; operations: number; objects: number; }>; }>; /** * Cleanup orphaned Redis OM keys not managed by current schemas * Scans using Redis OM patterns and removes keys not in registry * * @param schemaName - Optional specific schema to clean (all if not provided) * @returns Promise resolving to cleanup results * * @example * ```typescript * // Clean all orphaned keys * const result = await StorageSystem.cleanupOrphanedKeys(); * console.log(`Deleted ${result.deleted} orphaned keys`); * * // Clean specific schema * const result = await StorageSystem.cleanupOrphanedKeys('users'); * ``` */ static cleanupOrphanedKeys(schemaName?: string): Promise<{ deleted: number; patterns: string[]; orphans: string[]; }>; /** * Monitor storage changes with a callback * * @param name - Name of the storage to monitor * @param callback - Callback function for events * @returns Unsubscribe function * * @example * ```typescript * const unsubscribe = StorageSystem.monitor('users', (event) => { * console.log(`${event.type} operation on ${event.entityId}`); * }); * * // Later: unsubscribe(); * ``` */ static monitor(name: string, callback: (event: MonitorEvent) => void): () => void; /** * Migrate data from one schema version to another * * @param name - Name of the storage to migrate * @param newSchema - New schema configuration * @param options - Migration options * @returns Promise resolving to migration results * * @example * ```typescript * const result = await StorageSystem.migrate('users', newSchema, { * transform: (oldData) => ({ * ...oldData, * fullName: `${oldData.firstName} ${oldData.lastName}` * }) * }); * ``` */ static migrate(name: string, newSchema: SchemaConfig, options?: MigrationOptions): Promise<{ success: boolean; migrated: number; failed: number; errors: string[]; }>; /** * Export all storage data and schemas to a directory * * @param outputDir - Directory to export to * @param options - Export options * @returns Export result with metadata */ static exportAll(outputDir: string, options?: SystemExportOptions): Promise<SystemExportResult>; /** * Import all storage data and schemas from a directory * * @param inputDir - Directory to import from * @param options - Import options * @returns Import result with statistics */ static importAll(inputDir: string, options?: SystemImportOptions): Promise<SystemImportResult>; /** * Export incremental changes since last version */ static exportIncremental(outputDir: string, lastExportedStorageVersions: Map<string, number>, options?: SystemExportOptions): Promise<SystemExportResult>; /** * System-wide backup */ static systemBackup(backupName?: string): Promise<string>; /** * System-wide restore */ static systemRestore(backupPath: string): Promise<SystemImportResult>; /** * Get system version status */ static getSystemVersionStatus(): Promise<{ schemas: Array<{ schemaName: string; currentStorageVersion: number; currentSchemaVersion: number; entityCount: number; }>; totalSystemEntities: number; }>; /** * Remove a storage instance and clean up its associated managers * * @param name - The storage schema name to remove */ static removeStorage(name: string): void; /** * Clear all static maps and reset the system * WARNING: This will remove all references to storage instances */ static clearAll(): void; /** * Get the size of static maps for monitoring memory usage * * @returns Object with map sizes */ static getMapSizes(): { storageVersionManagers: number; exportImportManagers: number; storageInstances: number; total: number; }; /** * Check if a storage instance exists in memory * * @param name - The storage schema name * @returns True if the storage exists in memory */ static hasStorageInMemory(name: string): boolean; /** * Get Redis OM version validation status * * @returns Version validation status and information * * @example * ```typescript * const versionStatus = await StorageSystem.getVersionStatus(); * console.log('Current version:', versionStatus.currentVersion); * console.log('Is valid:', versionStatus.isValid); * ``` */ static getVersionStatus(): Promise<{ enabled: boolean; currentVersion: string; requiredVersion: string; supportedRange: string; isValid: boolean; storedVersion: string | null; features: string[]; errors?: string[]; warnings?: string[]; }>; /** * Configure version validation settings * * @param settings - Version validation settings * * @example * ```typescript * // Disable version validation for development * StorageSystem.configureVersionValidation({ enabled: false }); * * // Enable strict mode * StorageSystem.configureVersionValidation({ enabled: true, strictMode: true }); * ``` */ static configureVersionValidation(settings: { enabled?: boolean; strictMode?: boolean; }): void; } //# sourceMappingURL=storage-system.d.ts.map