UNPKG

cs-element

Version:

Advanced reactive data management library with state machines, blueprints, persistence, compression, networking, and multithreading support

942 lines (742 loc) 33 kB
# 🔧 Продвинутые возможности CSElement предоставляет мощные инструменты для профессиональной разработки: систему плагинов, DevTools, миграции, визуализацию и многое другое. ## 📋 Содержание 1. [Система плагинов](#система-плагинов) 2. [DevTools и отладка](#devtools-и-отладка) 3. [Система миграций](#система-миграций) 4. [Визуализация и схемы](#визуализация-и-схемы) 5. [Производительность и профилирование](#производительность-и-профилирование) 6. [Безопасность и валидация](#безопасность-и-валидация) 7. [Полный пример: Экосистема плагинов](#полный-пример-экосистема-плагинов) ## Система плагинов ### Создание простого плагина ```typescript import { CSElementPlugin, LifecycleHooks } from 'cs-element'; class LoggingPlugin implements CSElementPlugin { name = 'LoggingPlugin'; version = '1.0.0'; description = 'Логирование всех операций с элементами'; install(CSElementClass: typeof CSElement): void { console.log(`📦 Установлен плагин ${this.name} v${this.version}`); } getLifecycleHooks(): LifecycleHooks { return { afterCreate: async (element) => { console.log(`✨ Создан элемент: ${element.name} (${element.id})`); }, beforeSetData: async (element, key, value) => { console.log(`📝 Установка данных: ${element.name}.${key} = ${JSON.stringify(value)}`); }, afterSetData: async (element, key, value) => { console.log(`✅ Данные установлены: ${element.name}.${key} = ${JSON.stringify(value)}`); }, beforeAddElement: async (parent, child) => { console.log(`🔗 Добавление элемента: ${child.name} -> ${parent.name}`); }, afterRemoveElement: async (parent, child) => { console.log(`🗑️ Удален элемент: ${child.name} из ${parent.name}`); } }; } uninstall(): void { console.log(`🗑️ Удален плагин ${this.name}`); } } // Использование плагина CSElement.use(new LoggingPlugin()); ``` ### Плагин с конфигурацией ```typescript interface MetricsConfig { enabled: boolean; collectInterval: number; maxHistorySize: number; enablePerformanceMetrics: boolean; } class MetricsPlugin implements CSElementPlugin { name = 'MetricsPlugin'; version = '2.0.0'; private config: MetricsConfig; private metrics = new Map<string, any>(); private timers = new Map<string, number>(); constructor(config: Partial<MetricsConfig> = {}) { this.config = { enabled: true, collectInterval: 1000, maxHistorySize: 1000, enablePerformanceMetrics: true, ...config }; } install(CSElementClass: typeof CSElement): void { if (this.config.enabled) { this.startMetricsCollection(); } } getLifecycleHooks(): LifecycleHooks { return { beforeSetData: async (element, key, value) => { if (this.config.enablePerformanceMetrics) { this.timers.set(`setData:${element.id}:${key}`, performance.now()); } }, afterSetData: async (element, key, value) => { if (this.config.enablePerformanceMetrics) { const startTime = this.timers.get(`setData:${element.id}:${key}`); if (startTime) { const duration = performance.now() - startTime; this.recordMetric('setData.duration', duration); this.timers.delete(`setData:${element.id}:${key}`); } } this.recordMetric('setData.count', 1); } }; } private startMetricsCollection(): void { setInterval(() => { this.collectSystemMetrics(); }, this.config.collectInterval); } private recordMetric(name: string, value: number): void { if (!this.metrics.has(name)) { this.metrics.set(name, []); } const history = this.metrics.get(name); history.push({ value, timestamp: Date.now() }); // Ограничиваем размер истории if (history.length > this.config.maxHistorySize) { history.shift(); } } private collectSystemMetrics(): void { // Сбор системных метрик this.recordMetric('memory.used', performance.memory?.usedJSHeapSize || 0); this.recordMetric('elements.total', CSElement.getAllInstances().length); } getMetrics(): Map<string, any> { return new Map(this.metrics); } getMetricSummary(name: string): { avg: number; min: number; max: number; count: number } | null { const data = this.metrics.get(name); if (!data || data.length === 0) return null; const values = data.map((d: any) => d.value); return { avg: values.reduce((a: number, b: number) => a + b, 0) / values.length, min: Math.min(...values), max: Math.max(...values), count: values.length }; } } // Использование с конфигурацией CSElement.use(new MetricsPlugin({ collectInterval: 5000, enablePerformanceMetrics: true })); ``` ### Плагин с middleware ```typescript class ValidationPlugin implements CSElementPlugin { name = 'ValidationPlugin'; version = '1.0.0'; private rules = new Map<string, (value: any) => boolean>(); install(CSElementClass: typeof CSElement): void { // Добавляем middleware для валидации CSElementClass.plugins.addAdvancedMiddleware('setData', { name: 'validation-middleware', middleware: async (context, next) => { const { element, key, value } = context.args; // Проверяем правила валидации const rule = this.rules.get(key); if (rule && !rule(value)) { throw new Error(`Валидация не пройдена для ${key}: ${JSON.stringify(value)}`); } // Продолжаем выполнение return await next(); } }); } addRule(key: string, validator: (value: any) => boolean): void { this.rules.set(key, validator); } removeRule(key: string): void { this.rules.delete(key); } } // Использование const validationPlugin = new ValidationPlugin(); CSElement.use(validationPlugin); // Добавляем правила валидации validationPlugin.addRule('email', (value) => { return typeof value === 'string' && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value); }); validationPlugin.addRule('age', (value) => { return typeof value === 'number' && value >= 0 && value <= 150; }); ``` ## DevTools и отладка ### Инспектор элементов ```typescript import { DevToolsManager } from 'cs-element'; // Инициализация DevTools const devTools = new DevToolsManager(); // Включаем автоматическое отслеживание devTools.setAutoTrackElements(true); // Создаем элементы для демонстрации const app = new CSElement('app'); const user = await app.addElement('user'); await user.setData('name', 'Алексей'); await user.setData('email', 'alexey@example.com'); // Создаем снимок структуры const snapshot = devTools.inspector.createSnapshot(app); console.log('📸 Снимок структуры:', snapshot); // Получаем детальную информацию об элементе const details = devTools.inspector.getElementDetails(user.id); console.log('🔍 Детали элемента:', details); // Анализ производительности const analysis = devTools.inspector.analyzePerformance(app); console.log('⚡ Анализ производительности:', analysis); // Подписка на события DevTools devTools.addEventListener('element:created', (event) => { console.log('✨ Новый элемент:', event.elementId); }); devTools.addEventListener('performance:measured', (event) => { console.log('📊 Метрика производительности:', event.data); }); devTools.addEventListener('error:occurred', (event) => { console.error('❌ Ошибка:', event.data.error); }); ``` ### Профилировщик производительности ```typescript // Запуск профилирования devTools.profiler.startProfiling('user-creation'); // Выполняем операции for (let i = 0; i < 1000; i++) { const user = await app.addElement(`user-${i}`); await user.setData('index', i); await user.setData('created', new Date()); } // Останавливаем профилирование const profile = devTools.profiler.stopProfiling('user-creation'); console.log('📈 Результаты профилирования:'); console.log(`Время выполнения: ${profile.duration}мс`); console.log(`Операций в секунду: ${profile.operationsPerSecond}`); console.log(`Пиковое использование памяти: ${profile.peakMemoryUsage}MB`); // Получение детальной статистики const stats = devTools.profiler.getDetailedStats(); console.log('📊 Детальная статистика:', stats); // Экспорт данных профилирования const exportData = devTools.exportData({ includeProfilerData: true, includeSnapshots: true, timeRange: { start: Date.now() - 60000, end: Date.now() } }); console.log('💾 Экспортированные данные:', exportData); ``` ### Диагностика системы ```typescript // Запуск полной диагностики const diagnostics = devTools.runDiagnostics(); console.log('🔍 Результаты диагностики:'); console.log(`Всего проблем: ${diagnostics.summary.totalIssues}`); console.log(`Критических: ${diagnostics.summary.criticalIssues}`); console.log(`Производительность: ${diagnostics.summary.performance}`); // Обработка найденных проблем diagnostics.issues.forEach(issue => { console.log(`${issue.type === 'error' ? '❌' : issue.type === 'warning' ? '⚠️' : 'ℹ️'} ${issue.message}`); if (issue.suggestion) { console.log(`💡 Рекомендация: ${issue.suggestion}`); } }); // Автоматическое исправление проблем const autoFixResults = devTools.autoFixIssues(diagnostics.issues); console.log('🔧 Автоматические исправления:', autoFixResults); ``` ## Система миграций ### Создание миграции ```typescript import { Migration, MigrationSystem } from 'cs-element'; class AddUserRolesMigration implements Migration { id = 'add-user-roles-001'; version = '1.1.0'; description = 'Добавление ролей пользователей'; async up(context: MigrationContext): Promise<void> { console.log('🔄 Выполнение миграции: добавление ролей'); const users = context.root.query('[type="user"]'); for (const user of users) { // Добавляем роль по умолчанию if (!user.getData('role')) { await user.setData('role', 'user'); } // Добавляем права доступа if (!user.getData('permissions')) { await user.setData('permissions', ['read']); } // Обновляем версию пользователя await user.setData('schemaVersion', '1.1.0'); context.progress?.update({ currentStep: `Обновление пользователя: ${user.getData('name')}`, completed: users.indexOf(user) + 1, total: users.length }); } } async down(context: MigrationContext): Promise<void> { console.log('↩️ Откат миграции: удаление ролей'); const users = context.root.query('[type="user"]'); for (const user of users) { await user.removeData('role'); await user.removeData('permissions'); await user.setData('schemaVersion', '1.0.0'); } } async validate(context: MigrationContext): Promise<boolean> { const users = context.root.query('[type="user"]'); // Проверяем, что у всех пользователей есть роли return users.every(user => user.getData('role') && user.getData('permissions')); } } // Регистрация и выполнение миграций const migrationSystem = new MigrationSystem(); migrationSystem.register(new AddUserRolesMigration()); // Выполнение миграций const root = new CSElement('app'); const migrationResult = await migrationSystem.migrate(root, '1.1.0'); console.log('📈 Результат миграции:'); console.log(`Успешно: ${migrationResult.success}`); console.log(`Применено миграций: ${migrationResult.appliedMigrations.length}`); console.log(`Ошибки: ${migrationResult.errors.length}`); ``` ### Сложная миграция с зависимостями ```typescript class DatabaseSchemaUpgrade implements Migration { id = 'database-schema-upgrade-002'; version = '2.0.0'; description = 'Обновление схемы базы данных'; dependencies = ['add-user-roles-001']; // Зависит от предыдущей миграции async up(context: MigrationContext): Promise<void> { // Создаем новые индексы await this.createIndexes(context); // Мигрируем данные await this.migrateUserData(context); // Оптимизируем структуру await this.optimizeStructure(context); } private async createIndexes(context: MigrationContext): Promise<void> { const indexContainer = await context.root.addElement('indexes') as CSElement; // Индекс по email const emailIndex = await indexContainer.addElement('email-index') as CSElement; await emailIndex.setData('type', 'unique'); await emailIndex.setData('field', 'email'); // Индекс по ролям const roleIndex = await indexContainer.addElement('role-index') as CSElement; await roleIndex.setData('type', 'multiple'); await roleIndex.setData('field', 'role'); context.logger?.info('Созданы индексы для email и ролей'); } private async migrateUserData(context: MigrationContext): Promise<void> { const users = context.root.query('[type="user"]'); for (const user of users) { // Нормализуем email const email = user.getData('email'); if (email) { await user.setData('email', email.toLowerCase().trim()); } // Добавляем метаданные await user.setData('metadata', { migratedAt: new Date().toISOString(), migratedBy: 'database-schema-upgrade-002', previousVersion: user.getData('schemaVersion') || '1.0.0' }); await user.setData('schemaVersion', '2.0.0'); } } private async optimizeStructure(context: MigrationContext): Promise<void> { // Группируем пользователей по ролям const usersByRole = new Map<string, CSElement[]>(); const users = context.root.query('[type="user"]'); for (const user of users) { const role = user.getData('role'); if (!usersByRole.has(role)) { usersByRole.set(role, []); } usersByRole.get(role)!.push(user); } // Создаем группы ролей const rolesContainer = await context.root.addElement('roles') as CSElement; for (const [roleName, roleUsers] of usersByRole) { const roleGroup = await rolesContainer.addElement(`role-${roleName}`) as CSElement; await roleGroup.setData('name', roleName); await roleGroup.setData('userCount', roleUsers.length); await roleGroup.setData('type', 'role-group'); } } async down(context: MigrationContext): Promise<void> { // Удаляем созданные структуры const indexContainer = context.root.getElement('indexes'); if (indexContainer) { await context.root.removeElement(indexContainer); } const rolesContainer = context.root.getElement('roles'); if (rolesContainer) { await context.root.removeElement(rolesContainer); } // Возвращаем пользователей к предыдущей версии const users = context.root.query('[type="user"]'); for (const user of users) { await user.removeData('metadata'); await user.setData('schemaVersion', '1.1.0'); } } } ``` ## Визуализация и схемы ### Создание диаграммы структуры ```typescript import { VisualizationManager } from 'cs-element'; const visualizer = new VisualizationManager(); // Создаем структуру для визуализации const company = new CSElement('company'); const itDept = await company.addElement('it-department') as CSElement; const hrDept = await company.addElement('hr-department') as CSElement; await itDept.setData('type', 'department'); await itDept.setData('name', 'IT отдел'); const developer1 = await itDept.addElement('dev-1') as CSElement; await developer1.setData('type', 'employee'); await developer1.setData('name', 'Алексей'); await developer1.setData('position', 'Senior Developer'); // Генерируем диаграмму Mermaid const mermaidDiagram = visualizer.generateMermaidDiagram(company, { includeData: true, maxDepth: 3, theme: 'default' }); console.log('📊 Mermaid диаграмма:'); console.log(mermaidDiagram); // Генерируем GraphViz диаграмму const graphvizDiagram = visualizer.generateGraphVizDiagram(company, { layout: 'hierarchical', includeMetadata: true, colorScheme: 'blues' }); console.log('🎨 GraphViz диаграмма:'); console.log(graphvizDiagram); // Создаем интерактивную схему const interactiveSchema = visualizer.createInteractiveSchema(company, { enableZoom: true, enablePanning: true, showTooltips: true, enableSelection: true }); // Экспорт в различные форматы const exportOptions = { format: 'svg' as const, width: 1200, height: 800, includeStyles: true }; const svgContent = await visualizer.exportDiagram(company, exportOptions); console.log('💾 SVG экспорт готов'); ``` ### Создание схемы данных ```typescript class SchemaGenerator { static generateJSONSchema(element: CSElement): any { const schema = { $schema: 'http://json-schema.org/draft-07/schema#', type: 'object', title: element.name, properties: {}, required: [] }; // Анализируем данные элемента const data = element.getAllData(); for (const [key, value] of Object.entries(data)) { schema.properties[key] = this.inferType(value); } // Анализируем дочерние элементы const children = element.getAllElements(); if (children.length > 0) { schema.properties.children = { type: 'array', items: { anyOf: children.map(child => ({ $ref: `#/definitions/${child.name}` })) } }; } return schema; } private static inferType(value: any): any { if (value === null) return { type: 'null' }; if (typeof value === 'boolean') return { type: 'boolean' }; if (typeof value === 'number') return { type: 'number' }; if (typeof value === 'string') return { type: 'string' }; if (Array.isArray(value)) { return { type: 'array', items: value.length > 0 ? this.inferType(value[0]) : {} }; } if (typeof value === 'object') { const properties = {}; for (const [key, val] of Object.entries(value)) { properties[key] = this.inferType(val); } return { type: 'object', properties }; } return {}; } static generateTypeScriptDefinitions(element: CSElement): string { const interfaces: string[] = []; const generateInterface = (el: CSElement, visited = new Set<string>()): string => { if (visited.has(el.name)) return ''; visited.add(el.name); const data = el.getAllData(); const properties: string[] = []; for (const [key, value] of Object.entries(data)) { const type = this.getTypeScriptType(value); properties.push(` ${key}: ${type};`); } const children = el.getAllElements(); if (children.length > 0) { properties.push(` children?: Array<${children.map(c => c.name).join(' | ')}>;`); } const interfaceStr = `interface ${el.name} {\n${properties.join('\n')}\n}`; interfaces.push(interfaceStr); // Рекурсивно обрабатываем дочерние элементы for (const child of children) { generateInterface(child, visited); } return interfaceStr; }; generateInterface(element); return interfaces.join('\n\n'); } private static getTypeScriptType(value: any): string { if (value === null) return 'null'; if (typeof value === 'boolean') return 'boolean'; if (typeof value === 'number') return 'number'; if (typeof value === 'string') return 'string'; if (Array.isArray(value)) { if (value.length === 0) return 'any[]'; const itemType = this.getTypeScriptType(value[0]); return `${itemType}[]`; } if (typeof value === 'object') { const properties = Object.entries(value) .map(([key, val]) => `${key}: ${this.getTypeScriptType(val)}`) .join('; '); return `{ ${properties} }`; } return 'any'; } } // Использование генератора схем const jsonSchema = SchemaGenerator.generateJSONSchema(company); console.log('📄 JSON Schema:', JSON.stringify(jsonSchema, null, 2)); const tsDefinitions = SchemaGenerator.generateTypeScriptDefinitions(company); console.log('📝 TypeScript определения:'); console.log(tsDefinitions); ``` ## Полный пример: Экосистема плагинов ```typescript // Комплексная система с несколькими плагинами class AdvancedCSElementApp { private devTools: DevToolsManager; private migrationSystem: MigrationSystem; private visualizer: VisualizationManager; private root: CSElement; constructor() { this.setupPlugins(); this.initializeDevTools(); this.setupMigrations(); this.root = new CSElement('app-root'); } private setupPlugins(): void { // Плагин логирования CSElement.use(new LoggingPlugin()); // Плагин метрик CSElement.use(new MetricsPlugin({ collectInterval: 5000, enablePerformanceMetrics: true })); // Плагин валидации const validationPlugin = new ValidationPlugin(); validationPlugin.addRule('email', (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) ); CSElement.use(validationPlugin); // Плагин кэширования CSElement.use(new CachePlugin({ maxSize: 1000, ttl: 300000 // 5 минут })); } private initializeDevTools(): void { this.devTools = new DevToolsManager(); this.devTools.setAutoTrackElements(true); // Настраиваем мониторинг this.devTools.addEventListener('error:occurred', (event) => { console.error('🚨 Ошибка в системе:', event.data); this.handleSystemError(event.data); }); this.devTools.addEventListener('performance:measured', (event) => { if (event.data.duration > 1000) { console.warn('⚠️ Медленная операция:', event.data); } }); } private setupMigrations(): void { this.migrationSystem = new MigrationSystem(); // Регистрируем миграции this.migrationSystem.register(new AddUserRolesMigration()); this.migrationSystem.register(new DatabaseSchemaUpgrade()); } async initialize(): Promise<void> { console.log('🚀 Инициализация приложения...'); try { // Выполняем миграции await this.runMigrations(); // Создаем базовую структуру await this.createBaseStructure(); // Запускаем диагностику await this.runDiagnostics(); console.log('✅ Приложение инициализировано'); } catch (error) { console.error('❌ Ошибка инициализации:', error); throw error; } } private async runMigrations(): Promise<void> { console.log('🔄 Выполнение миграций...'); const result = await this.migrationSystem.migrate(this.root, '2.0.0'); if (!result.success) { throw new Error(`Миграции не выполнены: ${result.errors.join(', ')}`); } console.log(`✅ Применено миграций: ${result.appliedMigrations.length}`); } private async createBaseStructure(): Promise<void> { // Создаем пользователей const usersContainer = await this.root.addElement('users') as CSElement; const admin = await usersContainer.addElement('admin') as CSElement; await admin.setData('type', 'user'); await admin.setData('name', 'Администратор'); await admin.setData('email', 'admin@example.com'); await admin.setData('role', 'admin'); await admin.setData('permissions', ['read', 'write', 'delete', 'admin']); // Создаем проекты const projectsContainer = await this.root.addElement('projects') as CSElement; const project1 = await projectsContainer.addElement('project-1') as CSElement; await project1.setData('type', 'project'); await project1.setData('name', 'Основной проект'); await project1.setData('status', 'active'); // Создаем задачи const task1 = await project1.addElement('task-1') as CSElement; await task1.setData('type', 'task'); await task1.setData('title', 'Реализовать функцию X'); await task1.setData('assignee', admin.id); await task1.setData('priority', 'high'); } private async runDiagnostics(): Promise<void> { console.log('🔍 Запуск диагностики...'); const diagnostics = this.devTools.runDiagnostics(); if (diagnostics.summary.criticalIssues > 0) { console.warn(`⚠️ Найдено критических проблем: ${diagnostics.summary.criticalIssues}`); diagnostics.issues .filter(issue => issue.type === 'error') .forEach(issue => { console.error(`❌ ${issue.message}`); if (issue.suggestion) { console.log(`💡 ${issue.suggestion}`); } }); } console.log(`📊 Производительность: ${diagnostics.summary.performance}`); } async createReport(): Promise<string> { const report = { timestamp: new Date().toISOString(), system: { elements: this.root.getAllElements().length, plugins: CSElement.plugins.getPlugins().length, performance: this.devTools.getStats() }, structure: this.devTools.createGlobalSnapshot(), metrics: this.getMetricsReport(), visualization: await this.generateVisualization() }; return JSON.stringify(report, null, 2); } private getMetricsReport(): any { const metricsPlugin = CSElement.plugins.getPlugin('MetricsPlugin') as MetricsPlugin; if (!metricsPlugin) return null; return { setDataDuration: metricsPlugin.getMetricSummary('setData.duration'), setDataCount: metricsPlugin.getMetricSummary('setData.count'), memoryUsage: metricsPlugin.getMetricSummary('memory.used'), elementsTotal: metricsPlugin.getMetricSummary('elements.total') }; } private async generateVisualization(): Promise<string> { this.visualizer = new VisualizationManager(); return this.visualizer.generateMermaidDiagram(this.root, { includeData: false, maxDepth: 2, theme: 'default' }); } private handleSystemError(error: any): void { // Логируем ошибку console.error('Системная ошибка:', error); // Отправляем уведомление this.notifyAdministrators(error); // Пытаемся автоматически восстановить this.attemptAutoRecovery(error); } private notifyAdministrators(error: any): void { // Реализация уведомлений console.log('📧 Уведомление администраторов об ошибке'); } private attemptAutoRecovery(error: any): void { // Реализация автоматического восстановления console.log('🔧 Попытка автоматического восстановления'); } async shutdown(): Promise<void> { console.log('🔄 Завершение работы приложения...'); // Сохраняем финальный отчет const finalReport = await this.createReport(); console.log('📄 Финальный отчет:', finalReport); // Очищаем ресурсы this.devTools.setEnabled(false); console.log('✅ Приложение завершено'); } } // Использование async function runAdvancedApp() { const app = new AdvancedCSElementApp(); try { await app.initialize(); // Работа приложения... await new Promise(resolve => setTimeout(resolve, 10000)); // Генерируем отчет const report = await app.createReport(); console.log('📊 Отчет о работе приложения:', report); } finally { await app.shutdown(); } } // runAdvancedApp(); ``` ## 🎯 Заключение Продвинутые возможности CSElement предоставляют: - **🔧 Систему плагинов** - расширение функциональности без изменения ядра - **🔍 DevTools** - мощные инструменты отладки и профилирования - **🔄 Миграции** - безопасное обновление схем данных - **📊 Визуализацию** - наглядное представление структур - **⚡ Мониторинг** - отслеживание производительности и ошибок - **🛡️ Валидацию** - контроль целостности данных Используйте эти инструменты для создания надежных, масштабируемых и легко поддерживаемых приложений. --- **Это завершает полную документацию CSElement!** Теперь у вас есть все необходимые знания для эффективного использования библиотеки.