noormme 1.0.6 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -63
- package/dist/cjs/agentic/ActionJournal.js +13 -9
- package/dist/cjs/agentic/CapabilityManager.d.ts +9 -4
- package/dist/cjs/agentic/CapabilityManager.js +113 -17
- package/dist/cjs/agentic/CognitiveRepository.js +19 -9
- package/dist/cjs/agentic/ContextBuffer.js +24 -12
- package/dist/cjs/agentic/Cortex.d.ts +8 -1
- package/dist/cjs/agentic/Cortex.js +30 -7
- package/dist/cjs/agentic/EpisodicMemory.js +7 -5
- package/dist/cjs/agentic/PersonaManager.js +16 -8
- package/dist/cjs/agentic/PolicyEnforcer.js +31 -12
- package/dist/cjs/agentic/ResourceMonitor.js +4 -4
- package/dist/cjs/agentic/SessionCompressor.js +22 -14
- package/dist/cjs/agentic/SessionManager.js +36 -18
- package/dist/cjs/agentic/VectorIndexer.js +22 -18
- package/dist/cjs/agentic/improvement/AblationEngine.js +22 -15
- package/dist/cjs/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/cjs/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/cjs/agentic/improvement/CortexJanitor.d.ts +1 -1
- package/dist/cjs/agentic/improvement/CortexJanitor.js +64 -27
- package/dist/cjs/agentic/improvement/CuriosityEngine.d.ts +2 -2
- package/dist/cjs/agentic/improvement/CuriosityEngine.js +68 -59
- package/dist/cjs/agentic/improvement/EvolutionRitual.d.ts +24 -0
- package/dist/cjs/agentic/improvement/EvolutionRitual.js +91 -0
- package/dist/cjs/agentic/improvement/EvolutionaryPilot.d.ts +5 -0
- package/dist/cjs/agentic/improvement/EvolutionaryPilot.js +80 -7
- package/dist/cjs/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/cjs/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/cjs/agentic/improvement/GovernanceManager.d.ts +1 -1
- package/dist/cjs/agentic/improvement/GovernanceManager.js +85 -49
- package/dist/cjs/agentic/improvement/HiveLink.d.ts +9 -0
- package/dist/cjs/agentic/improvement/HiveLink.js +120 -26
- package/dist/cjs/agentic/improvement/KnowledgeDistiller.d.ts +2 -0
- package/dist/cjs/agentic/improvement/KnowledgeDistiller.js +101 -47
- package/dist/cjs/agentic/improvement/RecursiveReasoner.d.ts +7 -1
- package/dist/cjs/agentic/improvement/RecursiveReasoner.js +106 -22
- package/dist/cjs/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/cjs/agentic/improvement/RitualOrchestrator.js +34 -22
- package/dist/cjs/agentic/improvement/RuleEngine.js +22 -17
- package/dist/cjs/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/cjs/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/cjs/agentic/improvement/SkillSynthesizer.d.ts +48 -0
- package/dist/cjs/agentic/improvement/SkillSynthesizer.js +288 -0
- package/dist/cjs/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/cjs/agentic/improvement/StrategicPlanner.d.ts +1 -1
- package/dist/cjs/agentic/improvement/StrategicPlanner.js +129 -55
- package/dist/cjs/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/cjs/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/cjs/agentic/telemetry/ResearchAlchemist.js +13 -4
- package/dist/cjs/cache/cache-manager.js +7 -4
- package/dist/cjs/cli/commands/analyze.js +5 -4
- package/dist/cjs/cli/commands/generate.js +81 -44
- package/dist/cjs/cli/commands/init.js +7 -3
- package/dist/cjs/cli/commands/inspect.js +139 -36
- package/dist/cjs/cli/commands/migrate.js +5 -4
- package/dist/cjs/cli/commands/optimize.js +4 -4
- package/dist/cjs/cli/commands/status.js +9 -7
- package/dist/cjs/cli/commands/watch.js +7 -6
- package/dist/cjs/cli/index.js +2 -2
- package/dist/cjs/cli/ui/spinner.d.ts +15 -0
- package/dist/cjs/cli/ui/spinner.js +76 -0
- package/dist/cjs/dialect/database-introspector.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/cjs/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/cjs/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/cjs/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/cjs/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/cjs/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/cjs/edge-runtime/edge-config.js +21 -19
- package/dist/cjs/errors/NoormError.js +22 -20
- package/dist/cjs/helpers/agent-schema.js +3 -0
- package/dist/cjs/helpers/postgresql.js +7 -4
- package/dist/cjs/helpers/schema-evolution.js +31 -6
- package/dist/cjs/index.d.ts +18 -16
- package/dist/cjs/logging/logger.js +8 -4
- package/dist/cjs/migration/data_migrator.js +12 -11
- package/dist/cjs/migration/database_migration_manager.js +17 -13
- package/dist/cjs/migration/schema_differ.js +22 -14
- package/dist/cjs/migration/schema_introspector.js +8 -8
- package/dist/cjs/migration/type_mapper.js +68 -67
- package/dist/cjs/noormme.js +54 -37
- package/dist/cjs/performance/index.js +5 -5
- package/dist/cjs/performance/query-optimizer.js +26 -21
- package/dist/cjs/performance/services/cache-service.js +26 -16
- package/dist/cjs/performance/services/connection-factory.js +28 -23
- package/dist/cjs/performance/services/metrics-collector.js +41 -36
- package/dist/cjs/performance/utils/query-parser.js +15 -16
- package/dist/cjs/relationships/relationship-engine.js +10 -8
- package/dist/cjs/repository/repository-factory.js +97 -38
- package/dist/cjs/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/cjs/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/cjs/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/cjs/schema/core/discovery/view-discovery.js +5 -4
- package/dist/cjs/schema/core/factories/discovery-factory.js +4 -4
- package/dist/cjs/schema/core/utils/name-generator.js +14 -5
- package/dist/cjs/schema/core/utils/type-mapper.js +24 -24
- package/dist/cjs/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/cjs/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/cjs/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/cjs/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/cjs/schema/test/basic-schema-test.js +11 -9
- package/dist/cjs/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/cjs/schema/test/discovery-factory.test.js +2 -2
- package/dist/cjs/schema/test/error-handling.test.js +8 -6
- package/dist/cjs/schema/test/integration.test.js +24 -18
- package/dist/cjs/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/cjs/schema/test/simple-schema-test.js +9 -9
- package/dist/cjs/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/cjs/schema/test/test-runner.js +3 -3
- package/dist/cjs/sqlite-migration/index.d.ts +2 -2
- package/dist/cjs/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/cjs/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/cjs/testing/test-utils.js +36 -34
- package/dist/cjs/types/index.d.ts +61 -4
- package/dist/cjs/types/index.js +6 -3
- package/dist/cjs/types/type-generator.js +46 -42
- package/dist/cjs/util/safe-sql-helpers.js +1 -1
- package/dist/cjs/util/security-validator.js +20 -9
- package/dist/cjs/utils/errorHelpers.js +20 -10
- package/dist/cjs/watch/schema-watcher.js +22 -23
- package/dist/esm/agentic/ActionJournal.js +13 -9
- package/dist/esm/agentic/CapabilityManager.d.ts +9 -4
- package/dist/esm/agentic/CapabilityManager.js +113 -17
- package/dist/esm/agentic/CognitiveRepository.js +19 -9
- package/dist/esm/agentic/ContextBuffer.js +24 -12
- package/dist/esm/agentic/Cortex.d.ts +8 -1
- package/dist/esm/agentic/Cortex.js +30 -7
- package/dist/esm/agentic/EpisodicMemory.js +7 -5
- package/dist/esm/agentic/PersonaManager.js +16 -8
- package/dist/esm/agentic/PolicyEnforcer.js +31 -12
- package/dist/esm/agentic/ResourceMonitor.js +4 -4
- package/dist/esm/agentic/SessionCompressor.js +22 -14
- package/dist/esm/agentic/SessionManager.js +36 -18
- package/dist/esm/agentic/VectorIndexer.js +22 -18
- package/dist/esm/agentic/improvement/AblationEngine.js +22 -15
- package/dist/esm/agentic/improvement/ActionRefiner.js +12 -10
- package/dist/esm/agentic/improvement/ConflictResolver.js +5 -5
- package/dist/esm/agentic/improvement/CortexJanitor.d.ts +1 -1
- package/dist/esm/agentic/improvement/CortexJanitor.js +64 -27
- package/dist/esm/agentic/improvement/CuriosityEngine.d.ts +2 -2
- package/dist/esm/agentic/improvement/CuriosityEngine.js +68 -59
- package/dist/esm/agentic/improvement/EvolutionRitual.d.ts +24 -0
- package/dist/esm/agentic/improvement/EvolutionRitual.js +88 -0
- package/dist/esm/agentic/improvement/EvolutionaryPilot.d.ts +5 -0
- package/dist/esm/agentic/improvement/EvolutionaryPilot.js +80 -7
- package/dist/esm/agentic/improvement/GoalArchitect.d.ts +2 -2
- package/dist/esm/agentic/improvement/GoalArchitect.js +20 -18
- package/dist/esm/agentic/improvement/GovernanceManager.d.ts +1 -1
- package/dist/esm/agentic/improvement/GovernanceManager.js +85 -49
- package/dist/esm/agentic/improvement/HiveLink.d.ts +9 -0
- package/dist/esm/agentic/improvement/HiveLink.js +120 -26
- package/dist/esm/agentic/improvement/KnowledgeDistiller.d.ts +2 -0
- package/dist/esm/agentic/improvement/KnowledgeDistiller.js +101 -47
- package/dist/esm/agentic/improvement/RecursiveReasoner.d.ts +7 -1
- package/dist/esm/agentic/improvement/RecursiveReasoner.js +106 -22
- package/dist/esm/agentic/improvement/ReflectionEngine.js +10 -8
- package/dist/esm/agentic/improvement/RitualOrchestrator.js +34 -22
- package/dist/esm/agentic/improvement/RuleEngine.js +22 -17
- package/dist/esm/agentic/improvement/SelfEvolution.js +24 -18
- package/dist/esm/agentic/improvement/SelfTestRegistry.js +18 -15
- package/dist/esm/agentic/improvement/SkillSynthesizer.d.ts +48 -0
- package/dist/esm/agentic/improvement/SkillSynthesizer.js +285 -0
- package/dist/esm/agentic/improvement/SovereignMetrics.js +19 -17
- package/dist/esm/agentic/improvement/StrategicPlanner.d.ts +1 -1
- package/dist/esm/agentic/improvement/StrategicPlanner.js +129 -55
- package/dist/esm/agentic/telemetry/CognitiveSynthesizer.js +26 -12
- package/dist/esm/agentic/telemetry/EventHarvester.js +3 -2
- package/dist/esm/agentic/telemetry/ResearchAlchemist.js +13 -4
- package/dist/esm/cache/cache-manager.js +7 -4
- package/dist/esm/cli/commands/analyze.js +5 -4
- package/dist/esm/cli/commands/generate.js +82 -45
- package/dist/esm/cli/commands/init.js +8 -4
- package/dist/esm/cli/commands/inspect.js +140 -37
- package/dist/esm/cli/commands/migrate.js +5 -4
- package/dist/esm/cli/commands/optimize.js +4 -4
- package/dist/esm/cli/commands/status.js +9 -7
- package/dist/esm/cli/commands/watch.js +7 -6
- package/dist/esm/cli/index.js +2 -2
- package/dist/esm/cli/ui/spinner.d.ts +15 -0
- package/dist/esm/cli/ui/spinner.js +70 -0
- package/dist/esm/dialect/database-introspector.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-driver.js +3 -1
- package/dist/esm/dialect/postgresql/postgresql-features.js +18 -8
- package/dist/esm/dialect/postgresql/postgresql-introspector.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-auto-indexer.js +47 -33
- package/dist/esm/dialect/sqlite/sqlite-auto-optimizer.js +8 -7
- package/dist/esm/dialect/sqlite/sqlite-driver.js +2 -2
- package/dist/esm/dialect/sqlite/sqlite-introspector.js +15 -12
- package/dist/esm/dynamic/dynamic.js +1 -1
- package/dist/esm/edge-runtime/edge-config.js +21 -19
- package/dist/esm/errors/NoormError.js +22 -20
- package/dist/esm/helpers/agent-schema.js +3 -0
- package/dist/esm/helpers/postgresql.js +7 -4
- package/dist/esm/helpers/schema-evolution.js +31 -6
- package/dist/esm/index.d.ts +18 -16
- package/dist/esm/index.js +2 -2
- package/dist/esm/logging/logger.js +8 -4
- package/dist/esm/migration/data_migrator.js +12 -11
- package/dist/esm/migration/database_migration_manager.js +18 -14
- package/dist/esm/migration/schema_differ.js +22 -14
- package/dist/esm/migration/schema_introspector.js +8 -8
- package/dist/esm/migration/type_mapper.js +68 -67
- package/dist/esm/noormme.js +54 -37
- package/dist/esm/performance/index.js +5 -5
- package/dist/esm/performance/query-optimizer.js +26 -21
- package/dist/esm/performance/services/cache-service.js +26 -16
- package/dist/esm/performance/services/connection-factory.js +28 -23
- package/dist/esm/performance/services/metrics-collector.js +41 -36
- package/dist/esm/performance/utils/query-parser.js +15 -16
- package/dist/esm/raw-builder/sql.js +1 -1
- package/dist/esm/relationships/relationship-engine.js +10 -8
- package/dist/esm/repository/repository-factory.js +98 -39
- package/dist/esm/schema/builders/alter-table-add-index-builder.js +1 -1
- package/dist/esm/schema/builders/create-index-builder.js +2 -2
- package/dist/esm/schema/core/coordinators/schema-discovery.coordinator.js +1 -3
- package/dist/esm/schema/core/discovery/relationship-discovery.js +16 -16
- package/dist/esm/schema/core/discovery/table-metadata-discovery.js +9 -9
- package/dist/esm/schema/core/discovery/view-discovery.js +5 -4
- package/dist/esm/schema/core/factories/discovery-factory.js +4 -4
- package/dist/esm/schema/core/utils/name-generator.js +14 -5
- package/dist/esm/schema/core/utils/type-mapper.js +24 -24
- package/dist/esm/schema/dialects/postgresql/postgresql-discovery.coordinator.js +8 -7
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-constraint-discovery.js +17 -15
- package/dist/esm/schema/dialects/sqlite/discovery/sqlite-index-discovery.js +8 -8
- package/dist/esm/schema/dialects/sqlite/introspection/sqlite-schema-introspector.js +6 -11
- package/dist/esm/schema/dialects/sqlite/sqlite-discovery.coordinator.js +14 -13
- package/dist/esm/schema/test/basic-schema-test.js +11 -9
- package/dist/esm/schema/test/dialect-capabilities.test.js +6 -6
- package/dist/esm/schema/test/discovery-factory.test.js +2 -2
- package/dist/esm/schema/test/error-handling.test.js +8 -6
- package/dist/esm/schema/test/integration.test.js +24 -18
- package/dist/esm/schema/test/schema-discovery-coordinator.test.js +9 -9
- package/dist/esm/schema/test/simple-schema-test.js +9 -9
- package/dist/esm/schema/test/sqlite-discovery-coordinator.test.js +64 -48
- package/dist/esm/schema/test/test-runner.js +3 -3
- package/dist/esm/sqlite-migration/index.d.ts +2 -2
- package/dist/esm/sqlite-migration/sqlite-migration-manager.js +21 -17
- package/dist/esm/sqlite-migration/sqlite-migration-provider.js +38 -34
- package/dist/esm/testing/test-utils.js +36 -34
- package/dist/esm/types/index.d.ts +61 -4
- package/dist/esm/types/index.js +6 -3
- package/dist/esm/types/type-generator.js +46 -42
- package/dist/esm/util/safe-sql-helpers.js +1 -1
- package/dist/esm/util/security-validator.js +20 -9
- package/dist/esm/utils/errorHelpers.js +21 -11
- package/dist/esm/watch/schema-watcher.js +22 -23
- package/package.json +40 -44
package/dist/cjs/noormme.js
CHANGED
|
@@ -86,7 +86,9 @@ class NOORMME {
|
|
|
86
86
|
this.dialect = this.createDialect();
|
|
87
87
|
this.db = new kysely_js_1.Kysely({
|
|
88
88
|
dialect: this.dialect,
|
|
89
|
-
log: this.config.logging?.enabled
|
|
89
|
+
log: this.config.logging?.enabled
|
|
90
|
+
? this.logger.createKyselyLogger()
|
|
91
|
+
: undefined,
|
|
90
92
|
});
|
|
91
93
|
// Initialize core components
|
|
92
94
|
this.schemaDiscovery = new schema_discovery_js_1.SchemaDiscovery(this.db, this.config.introspection, this.dialect);
|
|
@@ -100,7 +102,7 @@ class NOORMME {
|
|
|
100
102
|
: null,
|
|
101
103
|
schema: new agent_schema_js_1.AgentSchemaHelper(this.db, agenticConfig),
|
|
102
104
|
cortex: new Cortex_js_1.Cortex(this.db, this.config),
|
|
103
|
-
evolution: new schema_evolution_js_1.SchemaEvolutionHelper(this.db)
|
|
105
|
+
evolution: new schema_evolution_js_1.SchemaEvolutionHelper(this.db),
|
|
104
106
|
};
|
|
105
107
|
this.repositoryFactory = new repository_factory_js_1.RepositoryFactory(this.db, this.config.performance, this.agent.cortex);
|
|
106
108
|
this.relationshipEngine = new relationship_engine_js_1.RelationshipEngine(this.db, this.config.performance);
|
|
@@ -167,7 +169,7 @@ class NOORMME {
|
|
|
167
169
|
schemaInfo = {
|
|
168
170
|
tables: [],
|
|
169
171
|
relationships: [],
|
|
170
|
-
views: []
|
|
172
|
+
views: [],
|
|
171
173
|
};
|
|
172
174
|
}
|
|
173
175
|
// Generate types - handle empty schema gracefully
|
|
@@ -183,7 +185,7 @@ class NOORMME {
|
|
|
183
185
|
generatedTypes = {
|
|
184
186
|
entities: [],
|
|
185
187
|
relationships: [],
|
|
186
|
-
types: {}
|
|
188
|
+
types: {},
|
|
187
189
|
};
|
|
188
190
|
}
|
|
189
191
|
// Cache schema and types - handle caching errors gracefully
|
|
@@ -207,7 +209,7 @@ class NOORMME {
|
|
|
207
209
|
slowQueryThreshold: 1000,
|
|
208
210
|
nPlusOneDetection: true,
|
|
209
211
|
missingIndexDetection: true,
|
|
210
|
-
persistPath: process.env.NOORMME_METRICS_PATH || '.noormme/metrics.json'
|
|
212
|
+
persistPath: process.env.NOORMME_METRICS_PATH || '.noormme/metrics.json',
|
|
211
213
|
}, this.logger);
|
|
212
214
|
// Initialize SQLite-specific auto-optimization features
|
|
213
215
|
if (this.config.dialect === 'sqlite') {
|
|
@@ -245,15 +247,15 @@ class NOORMME {
|
|
|
245
247
|
const result = await this.sqliteAutoOptimizer.optimizeDatabase(this.db, config);
|
|
246
248
|
if (result.appliedOptimizations.length > 0) {
|
|
247
249
|
this.logger.info(`Applied ${result.appliedOptimizations.length} SQLite optimizations`);
|
|
248
|
-
result.appliedOptimizations.forEach(opt => this.logger.debug(` ✓ ${opt}`));
|
|
250
|
+
result.appliedOptimizations.forEach((opt) => this.logger.debug(` ✓ ${opt}`));
|
|
249
251
|
}
|
|
250
252
|
if (result.recommendations.length > 0) {
|
|
251
253
|
this.logger.info(`Generated ${result.recommendations.length} recommendations`);
|
|
252
|
-
result.recommendations.forEach(rec => this.logger.debug(` 💡 ${rec}`));
|
|
254
|
+
result.recommendations.forEach((rec) => this.logger.debug(` 💡 ${rec}`));
|
|
253
255
|
}
|
|
254
256
|
if (result.warnings.length > 0) {
|
|
255
257
|
this.logger.warn(`Found ${result.warnings.length} warnings`);
|
|
256
|
-
result.warnings.forEach(warning => this.logger.warn(` ⚠️ ${warning}`));
|
|
258
|
+
result.warnings.forEach((warning) => this.logger.warn(` ⚠️ ${warning}`));
|
|
257
259
|
}
|
|
258
260
|
}
|
|
259
261
|
catch (error) {
|
|
@@ -338,9 +340,9 @@ class NOORMME {
|
|
|
338
340
|
if (!schemaInfo) {
|
|
339
341
|
throw new Error('Schema not found. Please reinitialize NOORMME.');
|
|
340
342
|
}
|
|
341
|
-
const table = schemaInfo.tables.find(t => t.name === tableName);
|
|
343
|
+
const table = schemaInfo.tables.find((t) => t.name === tableName);
|
|
342
344
|
if (!table) {
|
|
343
|
-
const availableTables = schemaInfo.tables.map(t => t.name);
|
|
345
|
+
const availableTables = schemaInfo.tables.map((t) => t.name);
|
|
344
346
|
throw new NoormError_js_1.TableNotFoundError(tableName, availableTables);
|
|
345
347
|
}
|
|
346
348
|
const repository = this.repositoryFactory.createRepository(table, schemaInfo.relationships);
|
|
@@ -411,7 +413,7 @@ class NOORMME {
|
|
|
411
413
|
// Auto-refresh schema when changes detected
|
|
412
414
|
this.schemaWatcher.onSchemaChange(async (changes) => {
|
|
413
415
|
this.logger.info(`Schema changes detected: ${changes.length} changes`);
|
|
414
|
-
changes.forEach(change => {
|
|
416
|
+
changes.forEach((change) => {
|
|
415
417
|
this.logger.info(` - ${change.type}: ${change.table}`);
|
|
416
418
|
});
|
|
417
419
|
try {
|
|
@@ -452,12 +454,12 @@ class NOORMME {
|
|
|
452
454
|
queryCount: this.logger.getQueryCount(),
|
|
453
455
|
averageQueryTime: this.logger.getAverageQueryTime(),
|
|
454
456
|
cacheHitRate: this.cacheManager.getHitRate(),
|
|
455
|
-
repositoryCount: this.repositories.size
|
|
457
|
+
repositoryCount: this.repositories.size,
|
|
456
458
|
};
|
|
457
459
|
if (this.metricsCollector) {
|
|
458
460
|
return {
|
|
459
461
|
...baseMetrics,
|
|
460
|
-
...this.metricsCollector.getPerformanceStats()
|
|
462
|
+
...this.metricsCollector.getPerformanceStats(),
|
|
461
463
|
};
|
|
462
464
|
}
|
|
463
465
|
return baseMetrics;
|
|
@@ -477,7 +479,7 @@ class NOORMME {
|
|
|
477
479
|
enabled: true,
|
|
478
480
|
slowQueryThreshold: options?.slowQueryThreshold || 1000,
|
|
479
481
|
nPlusOneDetection: true,
|
|
480
|
-
missingIndexDetection: true
|
|
482
|
+
missingIndexDetection: true,
|
|
481
483
|
}, this.logger);
|
|
482
484
|
this.logger.info('Query performance monitoring enabled');
|
|
483
485
|
}
|
|
@@ -537,25 +539,27 @@ class NOORMME {
|
|
|
537
539
|
includeViews: false,
|
|
538
540
|
excludeTables: [],
|
|
539
541
|
customTypeMappings: {},
|
|
540
|
-
...config.introspection
|
|
542
|
+
...config.introspection,
|
|
541
543
|
},
|
|
542
544
|
cache: {
|
|
543
545
|
ttl: 300000, // 5 minutes
|
|
544
546
|
maxSize: 1000,
|
|
545
547
|
strategy: 'lru',
|
|
546
|
-
...config.cache
|
|
548
|
+
...config.cache,
|
|
547
549
|
},
|
|
548
550
|
logging: {
|
|
549
551
|
level: 'info',
|
|
550
552
|
enabled: true,
|
|
551
|
-
...config.logging
|
|
553
|
+
...config.logging,
|
|
552
554
|
},
|
|
553
555
|
performance: {
|
|
554
556
|
enableQueryOptimization: true,
|
|
555
557
|
enableBatchLoading: true,
|
|
556
558
|
maxBatchSize: 100,
|
|
557
|
-
...config.performance
|
|
558
|
-
}
|
|
559
|
+
...config.performance,
|
|
560
|
+
},
|
|
561
|
+
agentic: config.agentic,
|
|
562
|
+
automation: config.automation,
|
|
559
563
|
};
|
|
560
564
|
}
|
|
561
565
|
/**
|
|
@@ -579,7 +583,7 @@ class NOORMME {
|
|
|
579
583
|
default:
|
|
580
584
|
throw new NoormError_js_1.NoormError(`Unsupported database protocol: ${url.protocol}`, {
|
|
581
585
|
operation: 'connection_string_parsing',
|
|
582
|
-
suggestion: 'Supported protocols: sqlite, postgresql, postgres, mysql'
|
|
586
|
+
suggestion: 'Supported protocols: sqlite, postgresql, postgres, mysql',
|
|
583
587
|
});
|
|
584
588
|
}
|
|
585
589
|
if (dialect === 'sqlite') {
|
|
@@ -590,8 +594,8 @@ class NOORMME {
|
|
|
590
594
|
host: '',
|
|
591
595
|
port: 0,
|
|
592
596
|
username: '',
|
|
593
|
-
password: ''
|
|
594
|
-
}
|
|
597
|
+
password: '',
|
|
598
|
+
},
|
|
595
599
|
};
|
|
596
600
|
}
|
|
597
601
|
if (dialect === 'postgresql' || dialect === 'mysql') {
|
|
@@ -608,23 +612,31 @@ class NOORMME {
|
|
|
608
612
|
}
|
|
609
613
|
else {
|
|
610
614
|
// For other SSL modes, we'll need more configuration
|
|
611
|
-
ssl = {
|
|
615
|
+
ssl = {
|
|
616
|
+
rejectUnauthorized: sslParam !== 'allow' && sslParam !== 'prefer',
|
|
617
|
+
};
|
|
612
618
|
}
|
|
613
619
|
}
|
|
614
620
|
return {
|
|
615
621
|
dialect,
|
|
616
622
|
connection: {
|
|
617
623
|
host: url.hostname || 'localhost',
|
|
618
|
-
port: url.port
|
|
624
|
+
port: url.port
|
|
625
|
+
? parseInt(url.port, 10)
|
|
626
|
+
: this.getDefaultPort(dialect),
|
|
619
627
|
database: url.pathname.replace(/^\//, ''),
|
|
620
628
|
username: url.username || undefined,
|
|
621
629
|
password: url.password || undefined,
|
|
622
630
|
ssl,
|
|
623
631
|
pool: {
|
|
624
|
-
max: searchParams.get('pool_max')
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
632
|
+
max: searchParams.get('pool_max')
|
|
633
|
+
? parseInt(searchParams.get('pool_max'), 10)
|
|
634
|
+
: 10,
|
|
635
|
+
min: searchParams.get('pool_min')
|
|
636
|
+
? parseInt(searchParams.get('pool_min'), 10)
|
|
637
|
+
: 0,
|
|
638
|
+
},
|
|
639
|
+
},
|
|
628
640
|
};
|
|
629
641
|
}
|
|
630
642
|
return {
|
|
@@ -635,14 +647,15 @@ class NOORMME {
|
|
|
635
647
|
database: url.pathname.slice(1), // Remove leading slash
|
|
636
648
|
username: url.username || '',
|
|
637
649
|
password: url.password || '',
|
|
638
|
-
ssl: url.searchParams.get('ssl') === 'true' ||
|
|
639
|
-
|
|
650
|
+
ssl: url.searchParams.get('ssl') === 'true' ||
|
|
651
|
+
url.searchParams.get('sslmode') === 'require',
|
|
652
|
+
},
|
|
640
653
|
};
|
|
641
654
|
}
|
|
642
655
|
catch (error) {
|
|
643
656
|
throw new NoormError_js_1.NoormError(`Failed to parse connection string: ${error instanceof Error ? error.message : String(error)}`, {
|
|
644
657
|
operation: 'connection_string_parsing',
|
|
645
|
-
suggestion: 'Ensure connection string format is: protocol://username:password@host:port/database'
|
|
658
|
+
suggestion: 'Ensure connection string format is: protocol://username:password@host:port/database',
|
|
646
659
|
});
|
|
647
660
|
}
|
|
648
661
|
}
|
|
@@ -651,10 +664,14 @@ class NOORMME {
|
|
|
651
664
|
*/
|
|
652
665
|
getDefaultPort(dialect) {
|
|
653
666
|
switch (dialect) {
|
|
654
|
-
case 'sqlite':
|
|
655
|
-
|
|
656
|
-
case '
|
|
657
|
-
|
|
667
|
+
case 'sqlite':
|
|
668
|
+
return 0;
|
|
669
|
+
case 'postgresql':
|
|
670
|
+
return 5432;
|
|
671
|
+
case 'mysql':
|
|
672
|
+
return 3306;
|
|
673
|
+
default:
|
|
674
|
+
return 0;
|
|
658
675
|
}
|
|
659
676
|
}
|
|
660
677
|
createDialect() {
|
|
@@ -662,7 +679,7 @@ class NOORMME {
|
|
|
662
679
|
switch (dialect) {
|
|
663
680
|
case 'sqlite':
|
|
664
681
|
return new sqlite_dialect_js_1.SqliteDialect({
|
|
665
|
-
database: new better_sqlite3_1.default(connection.database)
|
|
682
|
+
database: new better_sqlite3_1.default(connection.database),
|
|
666
683
|
});
|
|
667
684
|
case 'postgresql':
|
|
668
685
|
return new postgresql_dialect_js_1.PostgresDialect({
|
|
@@ -676,7 +693,7 @@ class NOORMME {
|
|
|
676
693
|
max: connection.pool?.max ?? 10,
|
|
677
694
|
min: connection.pool?.min ?? 0,
|
|
678
695
|
idleTimeoutMillis: connection.pool?.idleTimeoutMillis ?? 10000,
|
|
679
|
-
}
|
|
696
|
+
},
|
|
680
697
|
});
|
|
681
698
|
default:
|
|
682
699
|
throw new Error(`Unsupported dialect: ${dialect}`);
|
|
@@ -35,7 +35,7 @@ exports.defaultPerformanceConfig = {
|
|
|
35
35
|
maxSize: 1000,
|
|
36
36
|
defaultTtl: 300000, // 5 minutes
|
|
37
37
|
cleanupInterval: 60000, // 1 minute
|
|
38
|
-
enableMetrics: true
|
|
38
|
+
enableMetrics: true,
|
|
39
39
|
},
|
|
40
40
|
metrics: {
|
|
41
41
|
enabled: true,
|
|
@@ -44,14 +44,14 @@ exports.defaultPerformanceConfig = {
|
|
|
44
44
|
missingIndexDetection: true,
|
|
45
45
|
largeResultSetThreshold: 1000,
|
|
46
46
|
maxHistorySize: 10000,
|
|
47
|
-
warningRetentionDays: 7
|
|
47
|
+
warningRetentionDays: 7,
|
|
48
48
|
},
|
|
49
49
|
connectionPool: {
|
|
50
50
|
minConnections: 2,
|
|
51
51
|
maxConnections: 10,
|
|
52
52
|
acquireTimeout: 30000,
|
|
53
53
|
idleTimeout: 300000,
|
|
54
|
-
validationInterval: 60000
|
|
54
|
+
validationInterval: 60000,
|
|
55
55
|
},
|
|
56
56
|
optimizer: {
|
|
57
57
|
enableQueryCache: true,
|
|
@@ -59,6 +59,6 @@ exports.defaultPerformanceConfig = {
|
|
|
59
59
|
enableQueryRewriting: true,
|
|
60
60
|
slowQueryThreshold: 1000,
|
|
61
61
|
cacheSize: 1000,
|
|
62
|
-
maxCacheAge: 300000
|
|
63
|
-
}
|
|
62
|
+
maxCacheAge: 300000,
|
|
63
|
+
},
|
|
64
64
|
};
|
|
@@ -28,20 +28,20 @@ class QueryOptimizer {
|
|
|
28
28
|
slowQueryThreshold: 1000,
|
|
29
29
|
cacheSize: 1000,
|
|
30
30
|
maxCacheAge: 300000,
|
|
31
|
-
...options
|
|
31
|
+
...options,
|
|
32
32
|
};
|
|
33
33
|
// Initialize services
|
|
34
34
|
this.cacheService = new cache_service_1.QueryCacheService({
|
|
35
35
|
maxSize: this.options.cacheSize,
|
|
36
36
|
defaultTtl: this.options.maxCacheAge,
|
|
37
|
-
enableMetrics: true
|
|
37
|
+
enableMetrics: true,
|
|
38
38
|
}, this.logger);
|
|
39
39
|
this.metricsCollector = new metrics_collector_1.MetricsCollector({
|
|
40
40
|
enabled: true,
|
|
41
41
|
slowQueryThreshold: this.options.slowQueryThreshold,
|
|
42
42
|
nPlusOneDetection: true,
|
|
43
43
|
missingIndexDetection: this.options.enableIndexRecommendations,
|
|
44
|
-
largeResultSetThreshold: 1000
|
|
44
|
+
largeResultSetThreshold: 1000,
|
|
45
45
|
}, this.logger);
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
@@ -62,7 +62,7 @@ class QueryOptimizer {
|
|
|
62
62
|
executionTime,
|
|
63
63
|
improvement: 100,
|
|
64
64
|
suggestions: ['Query served from cache'],
|
|
65
|
-
result: cachedResult
|
|
65
|
+
result: cachedResult,
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -82,7 +82,7 @@ class QueryOptimizer {
|
|
|
82
82
|
this.metricsCollector.recordQuery(query, executionTime, {
|
|
83
83
|
table: context?.table,
|
|
84
84
|
operation: context?.operation,
|
|
85
|
-
resultCount: Array.isArray(result) ? result.length : 1
|
|
85
|
+
resultCount: Array.isArray(result) ? result.length : 1,
|
|
86
86
|
});
|
|
87
87
|
// Generate suggestions
|
|
88
88
|
const suggestions = this.generateSuggestions(parsedQuery, executionTime, context);
|
|
@@ -93,7 +93,7 @@ class QueryOptimizer {
|
|
|
93
93
|
executionTime,
|
|
94
94
|
improvement: optimization.improvement,
|
|
95
95
|
suggestions,
|
|
96
|
-
result
|
|
96
|
+
result,
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
catch (error) {
|
|
@@ -103,11 +103,11 @@ class QueryOptimizer {
|
|
|
103
103
|
this.metricsCollector.recordQuery(query, executionTime, {
|
|
104
104
|
table: context?.table,
|
|
105
105
|
operation: context?.operation,
|
|
106
|
-
error: errorMessage
|
|
106
|
+
error: errorMessage,
|
|
107
107
|
});
|
|
108
108
|
this.logger.error(`Query optimization failed: ${errorMessage}`, {
|
|
109
109
|
query,
|
|
110
|
-
executionTime
|
|
110
|
+
executionTime,
|
|
111
111
|
});
|
|
112
112
|
throw error;
|
|
113
113
|
}
|
|
@@ -137,7 +137,7 @@ class QueryOptimizer {
|
|
|
137
137
|
return {
|
|
138
138
|
...metricsStats,
|
|
139
139
|
cache: cacheStats,
|
|
140
|
-
indexRecommendations: 0 // Would be populated by recommendations
|
|
140
|
+
indexRecommendations: 0, // Would be populated by recommendations
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
@@ -198,7 +198,7 @@ class QueryOptimizer {
|
|
|
198
198
|
return {
|
|
199
199
|
optimizedQuery,
|
|
200
200
|
type,
|
|
201
|
-
improvement
|
|
201
|
+
improvement,
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
@@ -208,7 +208,8 @@ class QueryOptimizer {
|
|
|
208
208
|
let optimizedQuery = originalQuery;
|
|
209
209
|
let improvement = 0;
|
|
210
210
|
// Add LIMIT if missing and query could return many rows
|
|
211
|
-
if (!parsedQuery.hasLimit &&
|
|
211
|
+
if (!parsedQuery.hasLimit &&
|
|
212
|
+
query_parser_1.QueryParser.couldReturnManyRows(originalQuery)) {
|
|
212
213
|
optimizedQuery = `${originalQuery} LIMIT 1000`;
|
|
213
214
|
improvement = 10;
|
|
214
215
|
}
|
|
@@ -222,7 +223,7 @@ class QueryOptimizer {
|
|
|
222
223
|
}
|
|
223
224
|
return {
|
|
224
225
|
optimizedQuery,
|
|
225
|
-
improvement
|
|
226
|
+
improvement,
|
|
226
227
|
};
|
|
227
228
|
}
|
|
228
229
|
/**
|
|
@@ -247,13 +248,14 @@ class QueryOptimizer {
|
|
|
247
248
|
// Check for missing indexes on GROUP BY columns
|
|
248
249
|
if (parsedQuery.hasAggregates && parsedQuery.groupByColumns.length > 0) {
|
|
249
250
|
const table = parsedQuery.tables[0];
|
|
250
|
-
if (table &&
|
|
251
|
+
if (table &&
|
|
252
|
+
parsedQuery.groupByColumns.every((col) => this.hasIndexOnColumn(table, col))) {
|
|
251
253
|
improvement = Math.max(improvement, 25);
|
|
252
254
|
}
|
|
253
255
|
}
|
|
254
256
|
return {
|
|
255
257
|
optimizedQuery,
|
|
256
|
-
improvement
|
|
258
|
+
improvement,
|
|
257
259
|
};
|
|
258
260
|
}
|
|
259
261
|
/**
|
|
@@ -274,7 +276,7 @@ class QueryOptimizer {
|
|
|
274
276
|
type: 'btree',
|
|
275
277
|
reason: `WHERE clause on ${column}`,
|
|
276
278
|
estimatedImprovement: 20,
|
|
277
|
-
priority: 'medium'
|
|
279
|
+
priority: 'medium',
|
|
278
280
|
});
|
|
279
281
|
}
|
|
280
282
|
}
|
|
@@ -287,7 +289,7 @@ class QueryOptimizer {
|
|
|
287
289
|
type: 'btree',
|
|
288
290
|
reason: `JOIN condition on ${column}`,
|
|
289
291
|
estimatedImprovement: 30,
|
|
290
|
-
priority: 'high'
|
|
292
|
+
priority: 'high',
|
|
291
293
|
});
|
|
292
294
|
}
|
|
293
295
|
}
|
|
@@ -300,7 +302,7 @@ class QueryOptimizer {
|
|
|
300
302
|
type: 'btree',
|
|
301
303
|
reason: `ORDER BY clause on ${column}`,
|
|
302
304
|
estimatedImprovement: 15,
|
|
303
|
-
priority: 'medium'
|
|
305
|
+
priority: 'medium',
|
|
304
306
|
});
|
|
305
307
|
}
|
|
306
308
|
}
|
|
@@ -359,7 +361,10 @@ class QueryOptimizer {
|
|
|
359
361
|
}
|
|
360
362
|
catch (error) {
|
|
361
363
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
362
|
-
this.logger.error(`Query execution failed: ${errorMessage}`, {
|
|
364
|
+
this.logger.error(`Query execution failed: ${errorMessage}`, {
|
|
365
|
+
query,
|
|
366
|
+
params,
|
|
367
|
+
});
|
|
363
368
|
throw error;
|
|
364
369
|
}
|
|
365
370
|
}
|
|
@@ -367,15 +372,15 @@ class QueryOptimizer {
|
|
|
367
372
|
* Check if column has an index
|
|
368
373
|
*/
|
|
369
374
|
hasIndexOnColumn(table, column) {
|
|
370
|
-
const tableInfo = this.schemaInfo.tables.find(t => t.name === table);
|
|
375
|
+
const tableInfo = this.schemaInfo.tables.find((t) => t.name === table);
|
|
371
376
|
if (!tableInfo)
|
|
372
377
|
return false;
|
|
373
378
|
// Check if column is primary key
|
|
374
|
-
const columnInfo = tableInfo.columns.find(col => col.name === column);
|
|
379
|
+
const columnInfo = tableInfo.columns.find((col) => col.name === column);
|
|
375
380
|
if (columnInfo?.isPrimaryKey)
|
|
376
381
|
return true;
|
|
377
382
|
// Check if column has an index
|
|
378
|
-
return tableInfo.indexes.some(idx => idx.columns.includes(column));
|
|
383
|
+
return tableInfo.indexes.some((idx) => idx.columns.includes(column));
|
|
379
384
|
}
|
|
380
385
|
}
|
|
381
386
|
exports.QueryOptimizer = QueryOptimizer;
|
|
@@ -21,7 +21,7 @@ class CacheService {
|
|
|
21
21
|
cleanupInterval: 60000, // 1 minute
|
|
22
22
|
enableCompression: false,
|
|
23
23
|
enableMetrics: true,
|
|
24
|
-
...config
|
|
24
|
+
...config,
|
|
25
25
|
};
|
|
26
26
|
this.stats = {
|
|
27
27
|
size: 0,
|
|
@@ -31,25 +31,25 @@ class CacheService {
|
|
|
31
31
|
hitRate: 0,
|
|
32
32
|
totalSize: 0,
|
|
33
33
|
evictions: 0,
|
|
34
|
-
lastCleanup: new Date()
|
|
34
|
+
lastCleanup: new Date(),
|
|
35
35
|
};
|
|
36
36
|
this.metrics = {
|
|
37
37
|
operations: {
|
|
38
38
|
get: 0,
|
|
39
39
|
set: 0,
|
|
40
40
|
delete: 0,
|
|
41
|
-
clear: 0
|
|
41
|
+
clear: 0,
|
|
42
42
|
},
|
|
43
43
|
performance: {
|
|
44
44
|
averageGetTime: 0,
|
|
45
45
|
averageSetTime: 0,
|
|
46
|
-
slowestOperation: 0
|
|
46
|
+
slowestOperation: 0,
|
|
47
47
|
},
|
|
48
48
|
memory: {
|
|
49
49
|
totalSize: 0,
|
|
50
50
|
averageEntrySize: 0,
|
|
51
|
-
largestEntry: 0
|
|
52
|
-
}
|
|
51
|
+
largestEntry: 0,
|
|
52
|
+
},
|
|
53
53
|
};
|
|
54
54
|
this.startCleanupTimer();
|
|
55
55
|
}
|
|
@@ -106,7 +106,7 @@ class CacheService {
|
|
|
106
106
|
timestamp: Date.now(),
|
|
107
107
|
ttl: entryTtl,
|
|
108
108
|
hitCount: 0,
|
|
109
|
-
size: entrySize
|
|
109
|
+
size: entrySize,
|
|
110
110
|
};
|
|
111
111
|
this.cache.set(key, entry);
|
|
112
112
|
this.updateStats();
|
|
@@ -192,7 +192,10 @@ class CacheService {
|
|
|
192
192
|
* Get cache entries (for debugging)
|
|
193
193
|
*/
|
|
194
194
|
entries() {
|
|
195
|
-
return Array.from(this.cache.entries()).map(([key, entry]) => ({
|
|
195
|
+
return Array.from(this.cache.entries()).map(([key, entry]) => ({
|
|
196
|
+
key,
|
|
197
|
+
entry,
|
|
198
|
+
}));
|
|
196
199
|
}
|
|
197
200
|
/**
|
|
198
201
|
* Warm cache with multiple entries
|
|
@@ -219,19 +222,23 @@ class CacheService {
|
|
|
219
222
|
recommendations.push('Consider increasing TTL or cache size');
|
|
220
223
|
}
|
|
221
224
|
// Check memory usage
|
|
222
|
-
if (this.stats.totalSize > 100 * 1024 * 1024) {
|
|
225
|
+
if (this.stats.totalSize > 100 * 1024 * 1024) {
|
|
226
|
+
// 100MB
|
|
223
227
|
issues.push(`High memory usage: ${(this.stats.totalSize / 1024 / 1024).toFixed(1)}MB`);
|
|
224
228
|
recommendations.push('Consider reducing cache size or enabling compression');
|
|
225
229
|
}
|
|
226
230
|
// Check eviction rate
|
|
227
|
-
const evictionRate = this.stats.evictions /
|
|
231
|
+
const evictionRate = this.stats.evictions /
|
|
232
|
+
Math.max(this.stats.hitCount + this.stats.missCount, 1);
|
|
228
233
|
if (evictionRate > 0.1) {
|
|
229
234
|
issues.push(`High eviction rate: ${(evictionRate * 100).toFixed(1)}%`);
|
|
230
235
|
recommendations.push('Consider increasing cache size');
|
|
231
236
|
}
|
|
232
237
|
let status = 'healthy';
|
|
233
238
|
if (issues.length > 0) {
|
|
234
|
-
status = issues.some(issue => issue.includes('critical'))
|
|
239
|
+
status = issues.some((issue) => issue.includes('critical'))
|
|
240
|
+
? 'critical'
|
|
241
|
+
: 'warning';
|
|
235
242
|
}
|
|
236
243
|
return { status, issues, recommendations };
|
|
237
244
|
}
|
|
@@ -300,7 +307,8 @@ class CacheService {
|
|
|
300
307
|
this.stats.totalSize = totalSize;
|
|
301
308
|
this.metrics.memory.totalSize = totalSize;
|
|
302
309
|
this.metrics.memory.largestEntry = largestEntry;
|
|
303
|
-
this.metrics.memory.averageEntrySize =
|
|
310
|
+
this.metrics.memory.averageEntrySize =
|
|
311
|
+
this.cache.size > 0 ? totalSize / this.cache.size : 0;
|
|
304
312
|
}
|
|
305
313
|
/**
|
|
306
314
|
* Update hit rate
|
|
@@ -319,12 +327,14 @@ class CacheService {
|
|
|
319
327
|
if (operation === 'get') {
|
|
320
328
|
const totalGets = this.metrics.operations.get;
|
|
321
329
|
this.metrics.performance.averageGetTime =
|
|
322
|
-
(this.metrics.performance.averageGetTime * (totalGets - 1) + duration) /
|
|
330
|
+
(this.metrics.performance.averageGetTime * (totalGets - 1) + duration) /
|
|
331
|
+
totalGets;
|
|
323
332
|
}
|
|
324
333
|
else if (operation === 'set') {
|
|
325
334
|
const totalSets = this.metrics.operations.set;
|
|
326
335
|
this.metrics.performance.averageSetTime =
|
|
327
|
-
(this.metrics.performance.averageSetTime * (totalSets - 1) + duration) /
|
|
336
|
+
(this.metrics.performance.averageSetTime * (totalSets - 1) + duration) /
|
|
337
|
+
totalSets;
|
|
328
338
|
}
|
|
329
339
|
}
|
|
330
340
|
/**
|
|
@@ -371,7 +381,7 @@ class QueryCacheService extends CacheService {
|
|
|
371
381
|
defaultTtl: 300000, // 5 minutes
|
|
372
382
|
cleanupInterval: 60000, // 1 minute
|
|
373
383
|
enableMetrics: true,
|
|
374
|
-
...config
|
|
384
|
+
...config,
|
|
375
385
|
}, logger);
|
|
376
386
|
}
|
|
377
387
|
/**
|
|
@@ -393,7 +403,7 @@ class QueryCacheService extends CacheService {
|
|
|
393
403
|
*/
|
|
394
404
|
generateQueryKey(query, params) {
|
|
395
405
|
const normalizedQuery = query.replace(/\s+/g, ' ').trim();
|
|
396
|
-
const paramsKey = params.map(p => String(p)).join('|');
|
|
406
|
+
const paramsKey = params.map((p) => String(p)).join('|');
|
|
397
407
|
return `query:${normalizedQuery}:${paramsKey}`;
|
|
398
408
|
}
|
|
399
409
|
/**
|