versacompiler 2.0.0 → 2.0.1

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.
@@ -1,6 +1,173 @@
1
+ import { createHash } from 'node:crypto';
1
2
  import fs, { readFile } from 'node:fs/promises';
2
3
  import oxc from 'oxc-parser';
3
- // import { simple as walk } from 'acorn-walk';
4
+ class ParserASTCache {
5
+ static instance;
6
+ cache = new Map();
7
+ MAX_CACHE_SIZE = 150; // Máximo ASTs en cache
8
+ MAX_CACHE_MEMORY = 30 * 1024 * 1024; // 30MB límite
9
+ CACHE_TTL = 10 * 60 * 1000; // 10 minutos
10
+ currentMemoryUsage = 0;
11
+ // Métricas
12
+ cacheHits = 0;
13
+ cacheMisses = 0;
14
+ totalParses = 0;
15
+ static getInstance() {
16
+ if (!ParserASTCache.instance) {
17
+ ParserASTCache.instance = new ParserASTCache();
18
+ }
19
+ return ParserASTCache.instance;
20
+ }
21
+ /**
22
+ * Genera un hash del contenido del código
23
+ */
24
+ generateContentHash(code, astType) {
25
+ return createHash('sha256').update(`${code}:${astType}`).digest('hex');
26
+ }
27
+ /**
28
+ * Estima el tamaño en memoria de un AST
29
+ */
30
+ estimateASTSize(ast) {
31
+ try {
32
+ return JSON.stringify(ast).length * 2; // UTF-16 characters
33
+ }
34
+ catch {
35
+ return 10000; // Estimación por defecto
36
+ }
37
+ }
38
+ /**
39
+ * Obtiene AST desde cache o lo parsea
40
+ */
41
+ async getOrParseAST(filename, code, astType = 'js') {
42
+ this.totalParses++;
43
+ const contentHash = this.generateContentHash(code, astType);
44
+ const cacheKey = `${filename}:${contentHash}`;
45
+ // Verificar cache
46
+ const cached = this.cache.get(cacheKey);
47
+ if (cached && Date.now() - cached.timestamp < this.CACHE_TTL) {
48
+ // Actualizar timestamp de uso (LRU)
49
+ cached.timestamp = Date.now();
50
+ this.cacheHits++;
51
+ return {
52
+ ast: cached.ast,
53
+ cached: true,
54
+ };
55
+ }
56
+ // Cache miss - parsear nuevo AST
57
+ this.cacheMisses++;
58
+ const ast = oxc.parseSync(filename, code, {
59
+ sourceType: 'module',
60
+ showSemanticErrors: true,
61
+ astType,
62
+ });
63
+ // Cachear resultado si es válido
64
+ if (ast && !ast.errors?.length) {
65
+ this.addToCache(cacheKey, ast, astType);
66
+ }
67
+ return {
68
+ ast,
69
+ cached: false,
70
+ };
71
+ }
72
+ /**
73
+ * Añade AST al cache con gestión de memoria
74
+ */
75
+ addToCache(cacheKey, ast, astType) {
76
+ try {
77
+ const size = this.estimateASTSize(ast);
78
+ // Aplicar políticas de eviction si es necesario
79
+ this.evictIfNeeded(size);
80
+ const entry = {
81
+ contentHash: cacheKey.split(':')[1] || '',
82
+ ast,
83
+ astType,
84
+ timestamp: Date.now(),
85
+ size,
86
+ };
87
+ this.cache.set(cacheKey, entry);
88
+ this.currentMemoryUsage += size;
89
+ }
90
+ catch (error) {
91
+ console.warn('[ParserASTCache] Error cacheando AST:', error);
92
+ }
93
+ }
94
+ /**
95
+ * Aplica políticas de eviction LRU si es necesario
96
+ */
97
+ evictIfNeeded(newEntrySize) {
98
+ // Verificar límite de entradas
99
+ while (this.cache.size >= this.MAX_CACHE_SIZE) {
100
+ this.evictLRU();
101
+ }
102
+ // Verificar límite de memoria
103
+ while (this.currentMemoryUsage + newEntrySize > this.MAX_CACHE_MEMORY &&
104
+ this.cache.size > 0) {
105
+ this.evictLRU();
106
+ }
107
+ }
108
+ /**
109
+ * Elimina la entrada menos recientemente usada
110
+ */
111
+ evictLRU() {
112
+ let oldestKey = '';
113
+ let oldestTime = Infinity;
114
+ for (const [key, entry] of this.cache) {
115
+ if (entry.timestamp < oldestTime) {
116
+ oldestTime = entry.timestamp;
117
+ oldestKey = key;
118
+ }
119
+ }
120
+ if (oldestKey) {
121
+ const entry = this.cache.get(oldestKey);
122
+ if (entry) {
123
+ this.currentMemoryUsage -= entry.size;
124
+ this.cache.delete(oldestKey);
125
+ }
126
+ }
127
+ }
128
+ /**
129
+ * Limpia entradas expiradas
130
+ */
131
+ cleanExpired() {
132
+ const now = Date.now();
133
+ for (const [key, entry] of this.cache.entries()) {
134
+ if (now - entry.timestamp > this.CACHE_TTL) {
135
+ this.currentMemoryUsage -= entry.size;
136
+ this.cache.delete(key);
137
+ }
138
+ }
139
+ }
140
+ /**
141
+ * Obtiene estadísticas del cache
142
+ */
143
+ getStats() {
144
+ const hitRate = this.totalParses > 0
145
+ ? Math.round((this.cacheHits / this.totalParses) * 100)
146
+ : 0;
147
+ return {
148
+ cacheHits: this.cacheHits,
149
+ cacheMisses: this.cacheMisses,
150
+ hitRate,
151
+ totalParses: this.totalParses,
152
+ cacheSize: this.cache.size,
153
+ maxCacheSize: this.MAX_CACHE_SIZE,
154
+ memoryUsage: this.currentMemoryUsage,
155
+ maxMemoryUsage: this.MAX_CACHE_MEMORY,
156
+ };
157
+ }
158
+ /**
159
+ * Limpia todo el cache
160
+ */
161
+ clear() {
162
+ this.cache.clear();
163
+ this.currentMemoryUsage = 0;
164
+ this.cacheHits = 0;
165
+ this.cacheMisses = 0;
166
+ this.totalParses = 0;
167
+ }
168
+ }
169
+ // Instancia global del cache AST
170
+ const astCache = ParserASTCache.getInstance();
4
171
  /**
5
172
  * Parses the given JavaScript code using Acorn and returns the Abstract Syntax Tree (AST).
6
173
  *
@@ -9,11 +176,7 @@ import oxc from 'oxc-parser';
9
176
  * @throws {Error} If there is an error during parsing, it logs the error details and stack trace.
10
177
  */
11
178
  export const parser = async (filename, code, astType = 'js') => {
12
- const ast = oxc.parseSync(filename, code, {
13
- sourceType: 'module',
14
- showSemanticErrors: true,
15
- astType,
16
- });
179
+ const { ast } = await astCache.getOrParseAST(filename, code, astType);
17
180
  return ast;
18
181
  };
19
182
  export const getCodeFile = async (filename) => {
@@ -27,4 +190,14 @@ export const getCodeFile = async (filename) => {
27
190
  return { code: null, error };
28
191
  }
29
192
  };
193
+ // ✨ NUEVAS FUNCIONES: Exportar funcionalidades del cache AST para uso externo
194
+ export const getParserCacheStats = () => {
195
+ return astCache.getStats();
196
+ };
197
+ export const clearParserCache = () => {
198
+ astCache.clear();
199
+ };
200
+ export const cleanExpiredParserCache = () => {
201
+ astCache.cleanExpired();
202
+ };
30
203
  //# sourceMappingURL=parser.js.map
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Performance Monitor - Sistema centralizado de monitoreo de optimizaciones
3
+ * Reúne todas las métricas de cache y performance del VersaCompiler
4
+ */
5
+ import { clearBrowserSyncCache, getBrowserSyncCacheStats, } from '../servicios/browserSync.js';
6
+ import { cleanExpiredMinificationCache, clearMinificationCache, getMinificationCacheStats, } from './minify.js';
7
+ import { getModuleResolutionMetrics } from './module-resolution-optimizer.js';
8
+ import { cleanExpiredParserCache, clearParserCache, getParserCacheStats, } from './parser.js';
9
+ import { TransformOptimizer } from './transform-optimizer.js';
10
+ import { cleanExpiredVueHMRCache, clearVueHMRCache, getVueHMRCacheStats, } from './vuejs.js';
11
+ export class PerformanceMonitor {
12
+ static instance;
13
+ static getInstance() {
14
+ if (!PerformanceMonitor.instance) {
15
+ PerformanceMonitor.instance = new PerformanceMonitor();
16
+ }
17
+ return PerformanceMonitor.instance;
18
+ }
19
+ /**
20
+ * Obtiene todas las estadísticas de performance de manera unificada
21
+ */
22
+ getAllStats() {
23
+ const vueHMRCache = getVueHMRCacheStats();
24
+ const parserCache = getParserCacheStats();
25
+ const browserSyncCache = getBrowserSyncCacheStats();
26
+ const minificationCache = getMinificationCacheStats();
27
+ const transformOptimizer = TransformOptimizer.getInstance().getStats();
28
+ const moduleResolution = getModuleResolutionMetrics();
29
+ // Calcular resumen general
30
+ const totalCacheHits = (parserCache.cacheHits || 0) +
31
+ (browserSyncCache.cacheHits || 0) +
32
+ (minificationCache.cacheHits || 0) +
33
+ (transformOptimizer.cacheHits || 0) +
34
+ (moduleResolution.cacheHits || 0);
35
+ const totalCacheMisses = (parserCache.cacheMisses || 0) +
36
+ (browserSyncCache.cacheMisses || 0) +
37
+ (minificationCache.cacheMisses || 0) +
38
+ (transformOptimizer.cacheMisses || 0) +
39
+ (moduleResolution.cacheMisses || 0);
40
+ const totalRequests = totalCacheHits + totalCacheMisses;
41
+ const overallHitRate = totalRequests > 0
42
+ ? Math.round((totalCacheHits / totalRequests) * 100)
43
+ : 0;
44
+ const totalMemoryUsage = (parserCache.memoryUsage || 0) +
45
+ (browserSyncCache.memoryUsage || 0) +
46
+ (minificationCache.memoryUsage || 0) +
47
+ (transformOptimizer.memoryUsage || 0);
48
+ const totalCacheEntries = (vueHMRCache.size || 0) +
49
+ (parserCache.cacheSize || 0) +
50
+ (browserSyncCache.cacheSize || 0) +
51
+ (minificationCache.cacheSize || 0) +
52
+ (transformOptimizer.cacheSize || 0) +
53
+ (moduleResolution.cacheSize || 0);
54
+ return {
55
+ vueHMRCache,
56
+ parserCache,
57
+ browserSyncCache,
58
+ minificationCache,
59
+ transformOptimizer,
60
+ moduleResolution,
61
+ summary: {
62
+ totalCacheHits,
63
+ totalCacheMisses,
64
+ overallHitRate,
65
+ totalMemoryUsage,
66
+ totalCacheEntries,
67
+ },
68
+ };
69
+ }
70
+ /**
71
+ * Genera un reporte detallado de performance
72
+ */
73
+ generateReport() {
74
+ const stats = this.getAllStats();
75
+ const formatBytes = (bytes) => {
76
+ if (bytes === 0)
77
+ return '0 B';
78
+ const k = 1024;
79
+ const sizes = ['B', 'KB', 'MB', 'GB'];
80
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
81
+ return (parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]);
82
+ };
83
+ const report = `
84
+ 🚀 VERSACOMPILER PERFORMANCE REPORT
85
+ =====================================
86
+
87
+ 📊 RESUMEN GENERAL
88
+ Hit Rate Total: ${stats.summary.overallHitRate}%
89
+ Cache Hits: ${stats.summary.totalCacheHits}
90
+ Cache Misses: ${stats.summary.totalCacheMisses}
91
+ Memoria Total: ${formatBytes(stats.summary.totalMemoryUsage)}
92
+ Entradas Cache: ${stats.summary.totalCacheEntries}
93
+
94
+ 🎯 VUE HMR CACHE
95
+ Size: ${stats.vueHMRCache.size}/${stats.vueHMRCache.maxSize}
96
+ TTL: ${Math.round(stats.vueHMRCache.ttl / 1000 / 60)}min
97
+
98
+ 📝 PARSER AST CACHE
99
+ Hit Rate: ${stats.parserCache.hitRate}%
100
+ Cache Hits: ${stats.parserCache.cacheHits}
101
+ Cache Misses: ${stats.parserCache.cacheMisses}
102
+ Size: ${stats.parserCache.cacheSize}/${stats.parserCache.maxCacheSize}
103
+ Memoria: ${formatBytes(stats.parserCache.memoryUsage)}/${formatBytes(stats.parserCache.maxMemoryUsage)}
104
+
105
+ 🌐 BROWSERSYNC FILE CACHE
106
+ Hit Rate: ${stats.browserSyncCache.hitRate}%
107
+ Cache Hits: ${stats.browserSyncCache.cacheHits}
108
+ Cache Misses: ${stats.browserSyncCache.cacheMisses}
109
+ Size: ${stats.browserSyncCache.cacheSize}/${stats.browserSyncCache.maxCacheSize}
110
+ Memoria: ${formatBytes(stats.browserSyncCache.memoryUsage)}/${formatBytes(stats.browserSyncCache.maxMemoryUsage)}
111
+
112
+ 🗜️ MINIFICATION CACHE
113
+ Hit Rate: ${stats.minificationCache.hitRate}%
114
+ Cache Hits: ${stats.minificationCache.cacheHits}
115
+ Cache Misses: ${stats.minificationCache.cacheMisses}
116
+ Size: ${stats.minificationCache.cacheSize}/${stats.minificationCache.maxCacheSize}
117
+ Memoria: ${formatBytes(stats.minificationCache.memoryUsage)}/${formatBytes(stats.minificationCache.maxMemoryUsage)}
118
+ Compresión Promedio: ${stats.minificationCache.avgCompressionRatio}%
119
+
120
+ 🔄 TRANSFORM OPTIMIZER
121
+ Hit Rate: ${stats.transformOptimizer.hitRate}%
122
+ Cache Hits: ${stats.transformOptimizer.cacheHits}
123
+ Cache Misses: ${stats.transformOptimizer.cacheMisses}
124
+ Transformaciones: ${stats.transformOptimizer.totalTransforms}
125
+ Size: ${stats.transformOptimizer.cacheSize}
126
+ Memoria: ${formatBytes(stats.transformOptimizer.memoryUsage)}
127
+
128
+ 📦 MODULE RESOLUTION
129
+ Hit Rate: ${stats.moduleResolution.cacheHitRate?.toFixed(1)}%
130
+ Cache Hits: ${stats.moduleResolution.cacheHits}
131
+ Cache Misses: ${stats.moduleResolution.cacheMisses}
132
+ Resoluciones: ${stats.moduleResolution.totalResolutions}
133
+ Índice Módulos: ${stats.moduleResolution.moduleIndexSize}
134
+ Índice Alias: ${stats.moduleResolution.aliasIndexSize}
135
+ Tiempo Promedio: ${stats.moduleResolution.averageResolveTime?.toFixed(2)}ms
136
+
137
+ =====================================
138
+ `;
139
+ return report;
140
+ }
141
+ /**
142
+ * Limpia todos los caches
143
+ */
144
+ clearAllCaches() {
145
+ clearVueHMRCache();
146
+ clearParserCache();
147
+ clearBrowserSyncCache();
148
+ clearMinificationCache();
149
+ TransformOptimizer.getInstance().clear();
150
+ console.log('🧹 Todos los caches han sido limpiados');
151
+ }
152
+ /**
153
+ * Limpia entradas expiradas de todos los caches
154
+ */
155
+ cleanExpiredCaches() {
156
+ cleanExpiredVueHMRCache();
157
+ cleanExpiredParserCache();
158
+ cleanExpiredMinificationCache();
159
+ console.log('🧹 Entradas expiradas limpiadas de todos los caches');
160
+ }
161
+ /**
162
+ * Configura limpieza automática periódica
163
+ */
164
+ setupAutomaticCleanup(intervalMinutes = 30) {
165
+ setInterval(() => {
166
+ this.cleanExpiredCaches();
167
+ console.log(`🔄 Limpieza automática ejecutada cada ${intervalMinutes} minutos`);
168
+ }, intervalMinutes * 60 * 1000);
169
+ }
170
+ /**
171
+ * Obtiene métricas simplificadas para logging
172
+ */
173
+ getSimpleMetrics() {
174
+ const stats = this.getAllStats();
175
+ return {
176
+ hitRate: stats.summary.overallHitRate,
177
+ totalHits: stats.summary.totalCacheHits,
178
+ totalMisses: stats.summary.totalCacheMisses,
179
+ memoryUsage: stats.summary.totalMemoryUsage,
180
+ cacheEntries: stats.summary.totalCacheEntries,
181
+ };
182
+ }
183
+ }
184
+ // Exportar instancia singleton
185
+ export const performanceMonitor = PerformanceMonitor.getInstance();
186
+ // Funciones de conveniencia
187
+ export const getAllPerformanceStats = () => performanceMonitor.getAllStats();
188
+ export const generatePerformanceReport = () => performanceMonitor.generateReport();
189
+ export const clearAllCaches = () => performanceMonitor.clearAllCaches();
190
+ export const cleanExpiredCaches = () => performanceMonitor.cleanExpiredCaches();
191
+ export const getSimpleMetrics = () => performanceMonitor.getSimpleMetrics();
192
+ //# sourceMappingURL=performance-monitor.js.map
@@ -0,0 +1,287 @@
1
+ /**
2
+ * Transform Optimizer - Sistema de optimización de transformaciones AST
3
+ * Implementa procesamiento paralelo y caching inteligente para transformaciones
4
+ */
5
+ import { createHash } from 'node:crypto';
6
+ import * as os from 'node:os';
7
+ /**
8
+ * Sistema de optimización de transformaciones con paralelización y caching
9
+ */
10
+ export class TransformOptimizer {
11
+ static instance;
12
+ transformCache = new Map();
13
+ workers = [];
14
+ workerQueue = [];
15
+ pendingTasks = new Map();
16
+ // Configuración de performance
17
+ MAX_CACHE_SIZE = 200; // Máximo transformaciones en cache
18
+ MAX_CACHE_MEMORY = 50 * 1024 * 1024; // 50MB límite
19
+ WORKER_POOL_SIZE = Math.min(os.cpus().length, 4);
20
+ TASK_TIMEOUT = 10000; // 10 segundos timeout
21
+ // Métricas
22
+ cacheHits = 0;
23
+ cacheMisses = 0;
24
+ totalTransforms = 0;
25
+ currentMemoryUsage = 0;
26
+ constructor() {
27
+ this.initializeWorkers();
28
+ }
29
+ static getInstance() {
30
+ if (!TransformOptimizer.instance) {
31
+ TransformOptimizer.instance = new TransformOptimizer();
32
+ }
33
+ return TransformOptimizer.instance;
34
+ }
35
+ /**
36
+ * Inicializa el pool de workers para transformaciones paralelas
37
+ */
38
+ async initializeWorkers() {
39
+ // Por ahora, implementaremos sin workers para evitar complejidad adicional
40
+ // En el futuro se puede añadir worker pool específico para transformaciones
41
+ console.log('[TransformOptimizer] Inicializado sin workers (procesamiento síncrono optimizado)');
42
+ }
43
+ /**
44
+ * Aplica transformaciones con caching y optimización
45
+ */
46
+ async transform(code, transforms, options = {}) {
47
+ this.totalTransforms++;
48
+ // 1. Generar hash para cache lookup
49
+ const cacheKey = this.generateCacheKey(code, transforms, options);
50
+ // 2. Verificar cache
51
+ const cached = await this.getFromCache(cacheKey);
52
+ if (cached) {
53
+ this.cacheHits++;
54
+ return cached;
55
+ }
56
+ this.cacheMisses++;
57
+ // 3. Aplicar transformaciones
58
+ const result = await this.applyTransforms(code, transforms, options);
59
+ // 4. Cachear resultado
60
+ await this.addToCache(cacheKey, code, transforms, options, result);
61
+ return result;
62
+ }
63
+ /**
64
+ * Genera clave de cache basada en contenido y transformaciones
65
+ */
66
+ generateCacheKey(code, transforms, options) {
67
+ const content = `${code}||${transforms.join(',')}||${JSON.stringify(options)}`;
68
+ return createHash('sha256').update(content).digest('hex');
69
+ }
70
+ /**
71
+ * Obtiene resultado del cache si es válido
72
+ */
73
+ async getFromCache(cacheKey) {
74
+ const entry = this.transformCache.get(cacheKey);
75
+ if (!entry)
76
+ return null;
77
+ // Actualizar tiempo de uso para LRU
78
+ entry.lastUsed = Date.now();
79
+ return entry.result;
80
+ }
81
+ /**
82
+ * Añade resultado al cache con gestión de memoria
83
+ */
84
+ async addToCache(cacheKey, code, transforms, options, result) {
85
+ try {
86
+ const size = this.estimateSize(code, result);
87
+ // Aplicar políticas de eviction si es necesario
88
+ this.evictIfNeeded(size);
89
+ const entry = {
90
+ inputHash: createHash('sha256').update(code).digest('hex'),
91
+ transformHash: createHash('sha256')
92
+ .update(transforms.join(','))
93
+ .digest('hex'),
94
+ result,
95
+ lastUsed: Date.now(),
96
+ size,
97
+ };
98
+ this.transformCache.set(cacheKey, entry);
99
+ this.currentMemoryUsage += size;
100
+ }
101
+ catch (error) {
102
+ console.warn('[TransformOptimizer] Error cacheando transformación:', error);
103
+ }
104
+ }
105
+ /**
106
+ * Aplica las transformaciones reales al código
107
+ */
108
+ async applyTransforms(code, transforms, options) {
109
+ try {
110
+ let currentCode = code;
111
+ let currentMap;
112
+ const dependencies = [];
113
+ // Aplicar transformaciones secuencialmente (por ahora)
114
+ // En el futuro se puede paralelizar transformaciones independientes
115
+ for (const transform of transforms) {
116
+ const transformResult = await this.applySingleTransform(currentCode, transform, options, currentMap);
117
+ currentCode = transformResult.code;
118
+ if (transformResult.map) {
119
+ currentMap = transformResult.map;
120
+ }
121
+ if (transformResult.dependencies) {
122
+ dependencies.push(...transformResult.dependencies);
123
+ }
124
+ }
125
+ return {
126
+ code: currentCode,
127
+ map: currentMap,
128
+ dependencies: [...new Set(dependencies)], // Deduplicar dependencias
129
+ };
130
+ }
131
+ catch (error) {
132
+ throw new Error(`Error aplicando transformaciones: ${error instanceof Error ? error.message : String(error)}`);
133
+ }
134
+ }
135
+ /**
136
+ * Aplica una transformación individual
137
+ */
138
+ async applySingleTransform(code, transform, options, sourceMap) {
139
+ // Importar dinámicamente el módulo de transformación necesario
140
+ switch (transform) {
141
+ case 'typescript':
142
+ return this.applyTypeScriptTransform(code, options, sourceMap);
143
+ case 'vue':
144
+ return this.applyVueTransform(code, options, sourceMap);
145
+ case 'minify':
146
+ return this.applyMinifyTransform(code, options, sourceMap);
147
+ case 'babel':
148
+ return this.applyBabelTransform(code, options, sourceMap);
149
+ default:
150
+ throw new Error(`Transformación desconocida: ${transform}`);
151
+ }
152
+ } /**
153
+ * Aplica transformación TypeScript
154
+ */
155
+ async applyTypeScriptTransform(code, options, sourceMap) {
156
+ // Importación dinámica para evitar carga innecesaria
157
+ const { preCompileTS } = await import('./typescript-manager.js');
158
+ const result = await preCompileTS(code, 'temp.ts');
159
+ if (result.error) {
160
+ throw result.error;
161
+ }
162
+ return {
163
+ code: result.data || code,
164
+ map: sourceMap, // Mantener source map existente por ahora
165
+ dependencies: [], // TypeScript puede extraer dependencias en el futuro
166
+ };
167
+ } /**
168
+ * Aplica transformación Vue
169
+ */
170
+ async applyVueTransform(code, options, sourceMap) {
171
+ const { preCompileVue } = await import('./vuejs.js');
172
+ const result = await preCompileVue(code, 'temp.vue', false);
173
+ if (result.error) {
174
+ throw result.error;
175
+ }
176
+ return {
177
+ code: result.data || code,
178
+ map: sourceMap,
179
+ dependencies: [],
180
+ };
181
+ } /**
182
+ * Aplica transformación de minificación
183
+ */
184
+ async applyMinifyTransform(code, options, sourceMap) {
185
+ const { minifyJS } = await import('./minify.js');
186
+ const result = await minifyJS(code, 'temp.js', true);
187
+ if (result.error) {
188
+ throw result.error;
189
+ }
190
+ return {
191
+ code: result.code || code,
192
+ map: sourceMap, // minifyJS no devuelve map, mantener el existente
193
+ dependencies: [],
194
+ };
195
+ }
196
+ /**
197
+ * Aplica transformación Babel (futuro)
198
+ */
199
+ async applyBabelTransform(code, options, sourceMap) {
200
+ // Placeholder para transformaciones Babel futuras
201
+ return {
202
+ code,
203
+ map: sourceMap,
204
+ dependencies: [],
205
+ };
206
+ }
207
+ /**
208
+ * Estima el tamaño en memoria de una entrada de cache
209
+ */
210
+ estimateSize(code, result) {
211
+ return (code.length * 2 + // UTF-16 characters
212
+ result.code.length * 2 +
213
+ (result.map?.length || 0) * 2 +
214
+ (result.dependencies?.join('').length || 0) * 2 +
215
+ 200 // Overhead de objetos
216
+ );
217
+ }
218
+ /**
219
+ * Aplica políticas de eviction LRU si es necesario
220
+ */
221
+ evictIfNeeded(newEntrySize) {
222
+ // Verificar límite de entradas
223
+ while (this.transformCache.size >= this.MAX_CACHE_SIZE) {
224
+ this.evictLRU();
225
+ }
226
+ // Verificar límite de memoria
227
+ while (this.currentMemoryUsage + newEntrySize > this.MAX_CACHE_MEMORY &&
228
+ this.transformCache.size > 0) {
229
+ this.evictLRU();
230
+ }
231
+ }
232
+ /**
233
+ * Elimina la entrada menos recientemente usada
234
+ */
235
+ evictLRU() {
236
+ let oldestKey = '';
237
+ let oldestTime = Infinity;
238
+ for (const [key, entry] of this.transformCache) {
239
+ if (entry.lastUsed < oldestTime) {
240
+ oldestTime = entry.lastUsed;
241
+ oldestKey = key;
242
+ }
243
+ }
244
+ if (oldestKey) {
245
+ const entry = this.transformCache.get(oldestKey);
246
+ if (entry) {
247
+ this.currentMemoryUsage -= entry.size;
248
+ this.transformCache.delete(oldestKey);
249
+ }
250
+ }
251
+ }
252
+ /**
253
+ * Obtiene estadísticas del optimizador
254
+ */
255
+ getStats() {
256
+ const hitRate = this.totalTransforms > 0
257
+ ? Math.round((this.cacheHits / this.totalTransforms) * 100)
258
+ : 0;
259
+ return {
260
+ cacheHits: this.cacheHits,
261
+ cacheMisses: this.cacheMisses,
262
+ hitRate,
263
+ totalTransforms: this.totalTransforms,
264
+ cacheSize: this.transformCache.size,
265
+ memoryUsage: this.currentMemoryUsage,
266
+ };
267
+ }
268
+ /**
269
+ * Limpia el cache y reinicia estadísticas
270
+ */
271
+ clear() {
272
+ this.transformCache.clear();
273
+ this.currentMemoryUsage = 0;
274
+ this.cacheHits = 0;
275
+ this.cacheMisses = 0;
276
+ this.totalTransforms = 0;
277
+ }
278
+ /**
279
+ * Cierra el optimizador y limpia recursos
280
+ */
281
+ async terminate() {
282
+ // Limpiar workers si se implementan en el futuro
283
+ this.clear();
284
+ console.log('[TransformOptimizer] Cerrado exitosamente');
285
+ }
286
+ }
287
+ //# sourceMappingURL=transform-optimizer.js.map