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,7 +1,8 @@
1
+ import { createHash } from 'node:crypto';
1
2
  import { glob, mkdir, readFile, stat, unlink, writeFile, } from 'node:fs/promises';
2
3
  import os from 'node:os';
3
4
  import path from 'node:path';
4
- import { env } from 'node:process';
5
+ import { cwd, env, stdout } from 'node:process';
5
6
  // Lazy loading optimizations - Only import lightweight modules synchronously
6
7
  import { logger } from '../servicios/logger.js';
7
8
  import { promptUser } from '../utils/promptUser.js';
@@ -16,157 +17,267 @@ let generateTailwindCSS;
16
17
  let estandarizaCode;
17
18
  let preCompileTS;
18
19
  let preCompileVue;
19
- // 🚀 Sistema de Carga Inteligente de Módulos - VERSIÓN OPTIMIZADA
20
- class ModuleManager {
20
+ // 🚀 Importar optimizador de transformaciones
21
+ let TransformOptimizer;
22
+ // 🚀 Importar optimizador de resolución de módulos
23
+ let ModuleResolutionOptimizer;
24
+ // 🚀 Sistema de Carga Inteligente de Módulos - VERSIÓN OPTIMIZADA V2
25
+ class OptimizedModuleManager {
21
26
  static instance;
22
27
  isInitialized = false;
23
- initializationPromise = null;
24
28
  loadedModules = new Set();
25
- // NUEVOS: Gestión de modo y precarga
26
- currentMode = null;
27
- preloadPromises = new Map();
28
- moduleCache = new Map();
29
- constructor() { }
29
+ // NUEVAS OPTIMIZACIONES
30
+ modulePool = new Map(); // Pool de instancias reutilizables
31
+ loadingPromises = new Map(); // Prevenir cargas duplicadas
32
+ usageStats = new Map(); // Estadísticas de uso
33
+ preloadQueue = new Set(); // Cola de precarga
34
+ backgroundLoader = null; // Cargador en background
35
+ // Módulos críticos que siempre se precargan
36
+ HOT_MODULES = ['chalk', 'parser'];
37
+ // Contexto actual para optimizar cargas
38
+ currentContext = null;
39
+ constructor() {
40
+ // Iniciar precarga en background inmediatamente
41
+ this.startBackgroundPreloading();
42
+ }
30
43
  static getInstance() {
31
- if (!ModuleManager.instance) {
32
- ModuleManager.instance = new ModuleManager();
44
+ if (!OptimizedModuleManager.instance) {
45
+ OptimizedModuleManager.instance = new OptimizedModuleManager();
33
46
  }
34
- return ModuleManager.instance;
47
+ return OptimizedModuleManager.instance;
35
48
  }
36
49
  /**
37
- * NUEVO: Precarga estratégica para modo watch
50
+ * NUEVO: Precarga en background para módulos críticos
38
51
  */
39
- async preloadForWatchMode() {
40
- const essentialModules = ['chalk', 'parser', 'transforms'];
41
- const preloadPromises = essentialModules.map(async (moduleName) => {
42
- if (!this.loadedModules.has(moduleName)) {
43
- switch (moduleName) {
44
- case 'chalk':
45
- return this._loadModule('chalk', loadChalk);
46
- case 'parser':
47
- return this._loadModule('parser', loadParser);
48
- case 'transforms':
49
- return this._loadModule('transforms', loadTransforms);
50
- }
51
- }
52
- });
53
- await Promise.all(preloadPromises);
54
- // console.log('[ModuleManager] Precarga completada para modo watch');
55
- } /**
56
- * MEJORADO: Inicializa los módulos necesarios según el contexto de compilación
57
- * @param context Contexto de compilación: 'individual', 'batch', 'watch'
58
- * @param fileExtensions Extensiones de archivos a compilar para optimizar la carga
52
+ startBackgroundPreloading() {
53
+ this.backgroundLoader = this.preloadCriticalModules();
54
+ }
55
+ /**
56
+ * NUEVO: Precarga módulos críticos en background
59
57
  */
60
- async initializeModules(context = 'individual', fileExtensions = new Set()) {
61
- // Si cambia el contexto, reinicializar
62
- if (this.currentMode !== context) {
63
- this.currentMode = context;
64
- // En modo watch, precargar módulos esenciales
65
- if (context === 'watch') {
66
- await this.preloadForWatchMode();
67
- }
58
+ async preloadCriticalModules() {
59
+ try {
60
+ // Precargar módulos críticos de forma asíncrona
61
+ const preloadPromises = this.HOT_MODULES.map(moduleName => this.ensureModuleLoaded(moduleName).catch(() => {
62
+ // Silenciar errores de precarga, se intentará cargar después
63
+ }));
64
+ await Promise.allSettled(preloadPromises);
68
65
  }
69
- if (this.initializationPromise) {
70
- return this.initializationPromise;
66
+ catch {
67
+ // Fallos en precarga no deben afectar la funcionalidad principal
71
68
  }
72
- if (this.isInitialized && context !== 'individual') {
73
- return;
74
- }
75
- this.initializationPromise = this._performInitialization(context, fileExtensions);
76
- await this.initializationPromise;
77
- this.initializationPromise = null;
78
69
  }
79
- async _performInitialization(context, fileExtensions) {
80
- const modulesToLoad = [];
81
- // Módulos siempre necesarios
82
- if (!this.loadedModules.has('chalk')) {
83
- modulesToLoad.push(this._loadModule('chalk', loadChalk));
84
- }
85
- if (!this.loadedModules.has('parser')) {
86
- modulesToLoad.push(this._loadModule('parser', loadParser));
87
- }
88
- if (!this.loadedModules.has('transforms')) {
89
- modulesToLoad.push(this._loadModule('transforms', loadTransforms));
70
+ /**
71
+ * MEJORADO: Precarga contextual basada en tipos de archivo
72
+ */
73
+ async preloadForContext(context, fileTypes = new Set()) {
74
+ this.currentContext = context;
75
+ // Esperar que termine la precarga crítica si está en progreso
76
+ if (this.backgroundLoader) {
77
+ await this.backgroundLoader;
90
78
  }
91
- // Carga contextual según el tipo de compilación
79
+ const toPreload = []; // Precarga basada en contexto
92
80
  if (context === 'batch' || context === 'watch') {
93
- // En modo batch/watch, precargar todos los módulos necesarios
94
- if (!this.loadedModules.has('vue')) {
95
- modulesToLoad.push(this._loadModule('vue', loadVue));
96
- }
97
- if (!this.loadedModules.has('typescript')) {
98
- modulesToLoad.push(this._loadModule('typescript', loadTypeScript));
99
- }
100
- if (!this.loadedModules.has('minify')) {
101
- modulesToLoad.push(this._loadModule('minify', loadMinify));
102
- }
81
+ // En batch/watch, precargar todos los módulos comunes
82
+ toPreload.push('transforms', 'vue', 'typescript', 'module-resolution-optimizer');
103
83
  }
104
84
  else {
105
- // En modo individual, cargar solo según las extensiones necesarias
106
- if (fileExtensions.has('.vue') && !this.loadedModules.has('vue')) {
107
- modulesToLoad.push(this._loadModule('vue', loadVue));
108
- }
109
- if ((fileExtensions.has('.ts') || fileExtensions.has('.vue')) &&
110
- !this.loadedModules.has('typescript')) {
111
- modulesToLoad.push(this._loadModule('typescript', loadTypeScript));
112
- }
113
- if (env.isPROD === 'true' && !this.loadedModules.has('minify')) {
114
- modulesToLoad.push(this._loadModule('minify', loadMinify));
115
- }
116
- }
117
- // Cargar módulos en paralelo
118
- await Promise.all(modulesToLoad);
119
- this.isInitialized = true;
120
- }
121
- async _loadModule(name, loadFunction) {
122
- if (!this.loadedModules.has(name)) {
123
- await loadFunction();
124
- this.loadedModules.add(name);
85
+ // En individual, cargar solo según tipos de archivo detectados
86
+ if (fileTypes.has('.vue'))
87
+ toPreload.push('vue');
88
+ if (fileTypes.has('.ts') || fileTypes.has('.vue'))
89
+ toPreload.push('typescript');
90
+ if (!this.loadedModules.has('transforms'))
91
+ toPreload.push('transforms');
125
92
  }
93
+ // Precargar en paralelo
94
+ const preloadPromises = toPreload.map(moduleName => this.ensureModuleLoaded(moduleName).catch(() => {
95
+ // Log warning pero no fallar
96
+ console.warn(`Warning: No se pudo precargar módulo ${moduleName}`);
97
+ }));
98
+ await Promise.allSettled(preloadPromises);
126
99
  }
127
100
  /**
128
- * Carga un módulo específico bajo demanda (lazy loading)
101
+ * MEJORADO: Carga inteligente con pooling y deduplicación
129
102
  */
130
103
  async ensureModuleLoaded(moduleName) {
131
- if (this.loadedModules.has(moduleName)) {
132
- return;
104
+ // 1. Verificar pool de módulos primero
105
+ if (this.modulePool.has(moduleName)) {
106
+ this.updateUsageStats(moduleName);
107
+ return this.modulePool.get(moduleName);
133
108
  }
109
+ // 2. Verificar si ya está cargando (deduplicación)
110
+ if (this.loadingPromises.has(moduleName)) {
111
+ return this.loadingPromises.get(moduleName);
112
+ }
113
+ // 3. Iniciar carga
114
+ const loadPromise = this.loadModuleInternal(moduleName);
115
+ this.loadingPromises.set(moduleName, loadPromise);
116
+ try {
117
+ const moduleInstance = await loadPromise;
118
+ // 4. Almacenar en pool y estadísticas
119
+ this.modulePool.set(moduleName, moduleInstance);
120
+ this.loadedModules.add(moduleName);
121
+ this.updateUsageStats(moduleName);
122
+ return moduleInstance;
123
+ }
124
+ finally {
125
+ // 5. Limpiar promesa de carga
126
+ this.loadingPromises.delete(moduleName);
127
+ }
128
+ }
129
+ /**
130
+ * ✨ NUEVO: Actualiza estadísticas de uso para optimizaciones futuras
131
+ */
132
+ updateUsageStats(moduleName) {
133
+ const currentCount = this.usageStats.get(moduleName) || 0;
134
+ this.usageStats.set(moduleName, currentCount + 1);
135
+ }
136
+ /**
137
+ * ✨ MEJORADO: Carga interna de módulos con mejor manejo de errores
138
+ */ async loadModuleInternal(moduleName) {
134
139
  switch (moduleName) {
140
+ case 'chalk':
141
+ return this.loadChalk();
142
+ case 'parser':
143
+ return this.loadParser();
144
+ case 'transforms':
145
+ return this.loadTransforms();
135
146
  case 'vue':
136
- await this._loadModule('vue', loadVue);
137
- break;
147
+ return this.loadVue();
138
148
  case 'typescript':
139
- await this._loadModule('typescript', loadTypeScript);
140
- break;
149
+ return this.loadTypeScript();
141
150
  case 'minify':
142
- await this._loadModule('minify', loadMinify);
143
- break;
151
+ return this.loadMinify();
144
152
  case 'tailwind':
145
- await this._loadModule('tailwind', loadTailwind);
146
- break;
153
+ return this.loadTailwind();
147
154
  case 'linter':
148
- await this._loadModule('linter', loadLinter);
149
- break;
155
+ return this.loadLinter();
156
+ case 'transform-optimizer':
157
+ return this.loadTransformOptimizer();
158
+ case 'module-resolution-optimizer':
159
+ return this.loadModuleResolutionOptimizer();
150
160
  default:
151
161
  throw new Error(`Módulo desconocido: ${moduleName}`);
152
162
  }
153
163
  }
164
+ // ✨ Métodos de carga específicos optimizados
165
+ async loadChalk() {
166
+ if (!chalk) {
167
+ chalk = (await import('chalk')).default;
168
+ }
169
+ return chalk;
170
+ }
171
+ async loadParser() {
172
+ if (!getCodeFile) {
173
+ const parserModule = await import('./parser.js');
174
+ getCodeFile = parserModule.getCodeFile;
175
+ }
176
+ return getCodeFile;
177
+ }
178
+ async loadTransforms() {
179
+ if (!estandarizaCode) {
180
+ const transformsModule = await import('./transforms.js');
181
+ estandarizaCode = transformsModule.estandarizaCode;
182
+ }
183
+ return estandarizaCode;
184
+ }
185
+ async loadVue() {
186
+ if (!preCompileVue) {
187
+ const vueModule = await import('./vuejs.js');
188
+ preCompileVue = vueModule.preCompileVue;
189
+ }
190
+ return preCompileVue;
191
+ }
192
+ async loadTypeScript() {
193
+ if (!preCompileTS) {
194
+ const typescriptModule = await import('./typescript-manager.js');
195
+ preCompileTS = typescriptModule.preCompileTS;
196
+ }
197
+ return preCompileTS;
198
+ }
199
+ async loadMinify() {
200
+ if (!minifyJS) {
201
+ const minifyModule = await import('./minify.js');
202
+ minifyJS = minifyModule.minifyJS;
203
+ }
204
+ return minifyJS;
205
+ }
206
+ async loadTailwind() {
207
+ if (!generateTailwindCSS) {
208
+ const tailwindModule = await import('./tailwindcss.js');
209
+ generateTailwindCSS = tailwindModule.generateTailwindCSS;
210
+ }
211
+ return generateTailwindCSS;
212
+ }
213
+ async loadLinter() {
214
+ if (!ESLint || !OxLint) {
215
+ const linterModule = await import('./linter.js');
216
+ ESLint = linterModule.ESLint;
217
+ OxLint = linterModule.OxLint;
218
+ }
219
+ return { ESLint, OxLint };
220
+ }
221
+ async loadTransformOptimizer() {
222
+ if (!TransformOptimizer) {
223
+ const transformModule = await import('./transform-optimizer.js');
224
+ TransformOptimizer =
225
+ transformModule.TransformOptimizer.getInstance();
226
+ }
227
+ return TransformOptimizer;
228
+ }
229
+ async loadModuleResolutionOptimizer() {
230
+ if (!ModuleResolutionOptimizer) {
231
+ const resolutionModule = await import('./module-resolution-optimizer.js');
232
+ ModuleResolutionOptimizer =
233
+ resolutionModule.ModuleResolutionOptimizer.getInstance();
234
+ }
235
+ return ModuleResolutionOptimizer;
236
+ }
237
+ /**
238
+ * ✨ NUEVO: Obtiene estadísticas de performance del manager
239
+ */
240
+ getPerformanceStats() {
241
+ const sortedByUsage = Array.from(this.usageStats.entries())
242
+ .sort((a, b) => b[1] - a[1])
243
+ .slice(0, 5)
244
+ .map(([name]) => name);
245
+ return {
246
+ loadedModules: Array.from(this.loadedModules),
247
+ usageStats: Object.fromEntries(this.usageStats),
248
+ poolSize: this.modulePool.size,
249
+ loadingInProgress: Array.from(this.loadingPromises.keys()),
250
+ mostUsedModules: sortedByUsage,
251
+ };
252
+ }
253
+ /**
254
+ * ✨ NUEVO: Limpia módulos no utilizados para liberar memoria
255
+ */
256
+ cleanupUnusedModules() {
257
+ const threshold = 1; // Mínimo de usos para mantener en pool
258
+ for (const [moduleName, usageCount] of this.usageStats) {
259
+ if (usageCount < threshold &&
260
+ !this.HOT_MODULES.includes(moduleName)) {
261
+ this.modulePool.delete(moduleName);
262
+ this.loadedModules.delete(moduleName);
263
+ this.usageStats.delete(moduleName);
264
+ }
265
+ }
266
+ }
154
267
  /**
155
268
  * Resetea el estado del manager (útil para tests)
156
269
  */
157
270
  reset() {
158
271
  this.isInitialized = false;
159
- this.initializationPromise = null;
160
272
  this.loadedModules.clear();
161
- }
162
- /**
163
- * Obtiene estadísticas de módulos cargados
164
- */
165
- getStats() {
166
- return {
167
- loaded: Array.from(this.loadedModules),
168
- initialized: this.isInitialized,
169
- };
273
+ this.modulePool.clear();
274
+ this.loadingPromises.clear();
275
+ this.usageStats.clear();
276
+ this.preloadQueue.clear();
277
+ this.currentContext = null;
278
+ this.backgroundLoader = null;
279
+ // Reiniciar precarga crítica
280
+ this.startBackgroundPreloading();
170
281
  }
171
282
  }
172
283
  // Lazy loading helper functions
@@ -214,7 +325,7 @@ async function loadTransforms() {
214
325
  }
215
326
  async function loadTypeScript() {
216
327
  if (!preCompileTS) {
217
- const typescriptModule = await import('./typescript.js');
328
+ const typescriptModule = await import('./typescript-manager.js');
218
329
  preCompileTS = typescriptModule.preCompileTS;
219
330
  }
220
331
  return preCompileTS;
@@ -229,40 +340,194 @@ async function loadVue() {
229
340
  // Almacenamiento global de errores y resultados
230
341
  const compilationErrors = [];
231
342
  const compilationResults = [];
232
- const compilationCache = new Map();
233
- const CACHE_DIR = path.join(path.resolve(env.PATH_PROY || process.cwd(), 'compiler'), '.cache');
234
- const CACHE_FILE = path.join(CACHE_DIR, 'versacompile-cache.json');
235
- async function loadCache() {
236
- try {
237
- if (env.cleanCache === 'true') {
238
- compilationCache.clear();
239
- try {
240
- await unlink(CACHE_FILE);
343
+ class SmartCompilationCache {
344
+ cache = new Map();
345
+ maxEntries = 500; // Máximo archivos en cache
346
+ maxMemory = 100 * 1024 * 1024; // 100MB límite
347
+ currentMemoryUsage = 0;
348
+ /**
349
+ * Genera hash SHA-256 del contenido del archivo
350
+ */ async generateContentHash(filePath) {
351
+ try {
352
+ const content = await readFile(filePath, 'utf8');
353
+ return createHash('sha256').update(content).digest('hex');
354
+ }
355
+ catch {
356
+ // Si no se puede leer el archivo, generar hash único basado en la ruta y timestamp
357
+ const fallback = `${filePath}-${Date.now()}`;
358
+ return createHash('sha256').update(fallback).digest('hex');
359
+ }
360
+ }
361
+ /**
362
+ * Verifica si una entrada de cache es válida
363
+ */
364
+ async isValid(filePath) {
365
+ const entry = this.cache.get(filePath);
366
+ if (!entry)
367
+ return false;
368
+ try {
369
+ // Verificar si el archivo de salida existe
370
+ await stat(entry.outputPath);
371
+ // Verificar si el contenido ha cambiado
372
+ const currentHash = await this.generateContentHash(filePath);
373
+ if (entry.contentHash !== currentHash) {
374
+ this.cache.delete(filePath);
375
+ return false;
241
376
  }
242
- catch {
243
- // Ignorar errores al eliminar el archivo
377
+ // Verificar tiempo de modificación como backup
378
+ const stats = await stat(filePath);
379
+ if (stats.mtimeMs > entry.mtime) {
380
+ this.cache.delete(filePath);
381
+ return false;
244
382
  }
383
+ // Actualizar tiempo de uso para LRU
384
+ entry.lastUsed = Date.now();
385
+ return true;
245
386
  }
246
- const cacheData = await readFile(CACHE_FILE, 'utf-8');
247
- const parsed = JSON.parse(cacheData);
248
- for (const [key, value] of Object.entries(parsed)) {
249
- compilationCache.set(key, value);
387
+ catch {
388
+ // Si hay error verificando, eliminar del cache
389
+ this.cache.delete(filePath);
390
+ return false;
250
391
  }
251
392
  }
252
- catch {
253
- // Cache file doesn't exist or is invalid, start fresh
393
+ /**
394
+ * Añade una entrada al cache
395
+ */
396
+ async set(filePath, outputPath) {
397
+ try {
398
+ const stats = await stat(filePath);
399
+ const contentHash = await this.generateContentHash(filePath);
400
+ const entry = {
401
+ contentHash,
402
+ mtime: stats.mtimeMs,
403
+ outputPath,
404
+ lastUsed: Date.now(),
405
+ size: stats.size,
406
+ };
407
+ // Aplicar límites de memoria y entradas antes de agregar
408
+ this.evictIfNeeded(entry.size);
409
+ this.cache.set(filePath, entry);
410
+ this.currentMemoryUsage += entry.size;
411
+ }
412
+ catch (error) {
413
+ // Si hay error, no cachear
414
+ console.warn(`Warning: No se pudo cachear ${filePath}:`, error);
415
+ }
254
416
  }
255
- }
256
- async function saveCache() {
257
- try {
258
- await mkdir(CACHE_DIR, { recursive: true });
259
- const cacheData = Object.fromEntries(compilationCache);
260
- await writeFile(CACHE_FILE, JSON.stringify(cacheData, null, 2));
417
+ /**
418
+ * Aplica política LRU para liberar espacio
419
+ */
420
+ evictIfNeeded(newEntrySize) {
421
+ // Verificar límite de entradas
422
+ while (this.cache.size >= this.maxEntries) {
423
+ this.evictLRU();
424
+ }
425
+ // Verificar límite de memoria
426
+ while (this.currentMemoryUsage + newEntrySize > this.maxMemory &&
427
+ this.cache.size > 0) {
428
+ this.evictLRU();
429
+ }
430
+ }
431
+ /**
432
+ * Elimina la entrada menos recientemente usada
433
+ */
434
+ evictLRU() {
435
+ let oldestKey = '';
436
+ let oldestTime = Infinity;
437
+ for (const [key, entry] of this.cache) {
438
+ if (entry.lastUsed < oldestTime) {
439
+ oldestTime = entry.lastUsed;
440
+ oldestKey = key;
441
+ }
442
+ }
443
+ if (oldestKey) {
444
+ const entry = this.cache.get(oldestKey);
445
+ if (entry) {
446
+ this.currentMemoryUsage -= entry.size;
447
+ this.cache.delete(oldestKey);
448
+ }
449
+ }
450
+ }
451
+ /**
452
+ * Carga el cache desde disco
453
+ */
454
+ async load(cacheFile) {
455
+ try {
456
+ if (env.cleanCache === 'true') {
457
+ this.cache.clear();
458
+ this.currentMemoryUsage = 0;
459
+ try {
460
+ await unlink(cacheFile);
461
+ }
462
+ catch {
463
+ // Ignorar errores al eliminar el archivo
464
+ }
465
+ return;
466
+ }
467
+ const cacheData = await readFile(cacheFile, 'utf-8');
468
+ const parsed = JSON.parse(cacheData);
469
+ // Validar y cargar entradas del cache
470
+ for (const [key, value] of Object.entries(parsed)) {
471
+ const entry = value;
472
+ if (entry.contentHash && entry.outputPath && entry.mtime) {
473
+ this.cache.set(key, entry);
474
+ this.currentMemoryUsage += entry.size || 0;
475
+ }
476
+ }
477
+ }
478
+ catch {
479
+ // Cache file doesn't exist or is invalid, start fresh
480
+ this.cache.clear();
481
+ this.currentMemoryUsage = 0;
482
+ }
261
483
  }
262
- catch {
263
- // Ignore save errors
484
+ /**
485
+ * Guarda el cache a disco
486
+ */
487
+ async save(cacheFile, cacheDir) {
488
+ try {
489
+ await mkdir(cacheDir, { recursive: true });
490
+ const cacheData = Object.fromEntries(this.cache);
491
+ await writeFile(cacheFile, JSON.stringify(cacheData, null, 2));
492
+ }
493
+ catch (error) {
494
+ console.warn('Warning: No se pudo guardar el cache:', error);
495
+ }
496
+ }
497
+ /**
498
+ * Limpia completamente el cache
499
+ */
500
+ clear() {
501
+ this.cache.clear();
502
+ this.currentMemoryUsage = 0;
503
+ } /**
504
+ * Obtiene la ruta de salida para un archivo cacheado
505
+ */
506
+ getOutputPath(filePath) {
507
+ const entry = this.cache.get(filePath);
508
+ return entry?.outputPath || '';
509
+ }
510
+ /**
511
+ * Obtiene estadísticas del cache
512
+ */
513
+ getStats() {
514
+ return {
515
+ entries: this.cache.size,
516
+ memoryUsage: this.currentMemoryUsage,
517
+ hitRate: 0, // Se calculará externamente
518
+ };
264
519
  }
265
520
  }
521
+ // Instancia global del cache inteligente
522
+ const smartCache = new SmartCompilationCache();
523
+ const CACHE_DIR = path.join(path.resolve(env.PATH_PROY || cwd(), 'compiler'), '.cache');
524
+ const CACHE_FILE = path.join(CACHE_DIR, 'versacompile-cache.json');
525
+ async function loadCache() {
526
+ await smartCache.load(CACHE_FILE);
527
+ }
528
+ async function saveCache() {
529
+ await smartCache.save(CACHE_FILE, CACHE_DIR);
530
+ }
266
531
  // 🎯 Funciones del Sistema Unificado de Manejo de Errores
267
532
  /**
268
533
  * Registra un error de compilación en el sistema unificado
@@ -551,10 +816,10 @@ class WatchModeOptimizer {
551
816
  if (cached && cached.mtime >= stats.mtimeMs) {
552
817
  resolve({ success: true, cached: true });
553
818
  return;
554
- } // Configurar worker para modo watch
555
- const { TypeScriptWorkerManager } = await import('./typescript-worker.js');
556
- const workerManager = TypeScriptWorkerManager.getInstance();
557
- workerManager.setMode('watch');
819
+ } // Configurar worker pool para modo watch
820
+ const { TypeScriptWorkerPool } = await import('./typescript-worker-pool.js');
821
+ const workerPool = TypeScriptWorkerPool.getInstance();
822
+ workerPool.setMode('watch');
558
823
  const result = await compileFn(filePath);
559
824
  this.fileSystemCache.set(filePath, {
560
825
  mtime: stats.mtimeMs,
@@ -579,9 +844,8 @@ async function compileJS(inPath, outPath, mode = 'individual') {
579
844
  // Si la ruta ya es absoluta, no la resolvamos de nuevo
580
845
  inPath = path.isAbsolute(inPath)
581
846
  ? normalizeRuta(inPath)
582
- : normalizeRuta(path.resolve(inPath));
583
- // 🚀 Usar ModuleManager para carga optimizada
584
- const moduleManager = ModuleManager.getInstance();
847
+ : normalizeRuta(path.resolve(inPath)); // 🚀 Usar OptimizedModuleManager para carga optimizada
848
+ const moduleManager = OptimizedModuleManager.getInstance();
585
849
  // Timing de lectura
586
850
  let start = Date.now();
587
851
  const extension = path.extname(inPath);
@@ -729,9 +993,6 @@ async function compileJS(inPath, outPath, mode = 'individual') {
729
993
  const destinationDir = path.dirname(outPath);
730
994
  await mkdir(destinationDir, { recursive: true });
731
995
  await writeFile(outPath, code, 'utf-8');
732
- if (env.VERBOSE === 'true') {
733
- logger.info(`\n📊 Timings para ${path.basename(inPath)}:`, JSON.stringify(timings));
734
- }
735
996
  return {
736
997
  error: null,
737
998
  action: 'extension',
@@ -740,11 +1001,11 @@ async function compileJS(inPath, outPath, mode = 'individual') {
740
1001
  export async function initCompile(ruta, compileTailwind = true, mode = 'individual') {
741
1002
  try {
742
1003
  // 🚀 Sistema de Carga Inteligente de Módulos
743
- const moduleManager = ModuleManager.getInstance();
1004
+ const moduleManager = OptimizedModuleManager.getInstance();
744
1005
  const fileExtension = path.extname(ruta);
745
1006
  const fileExtensions = new Set([fileExtension]);
746
1007
  // Inicializar módulos según el contexto
747
- await moduleManager.initializeModules(mode === 'all' ? 'batch' : mode, fileExtensions);
1008
+ await moduleManager.preloadForContext(mode === 'all' ? 'batch' : mode, fileExtensions);
748
1009
  // Generar TailwindCSS si está habilitado
749
1010
  if (compileTailwind && Boolean(env.TAILWIND)) {
750
1011
  await moduleManager.ensureModuleLoaded('tailwind');
@@ -950,28 +1211,7 @@ function createProgressBar(current, total, width = 30) {
950
1211
  }
951
1212
  // Función helper para verificar si un archivo debe ser omitido por cache
952
1213
  async function shouldSkipFile(filePath) {
953
- try {
954
- const stats = await stat(filePath);
955
- const cacheEntry = compilationCache.get(filePath);
956
- if (!cacheEntry) {
957
- return false; // No hay entrada en cache, debe compilarse
958
- }
959
- // Verificar si el archivo no ha cambiado desde la última compilación
960
- if (stats.mtimeMs <= cacheEntry.mtime) {
961
- // Verificar si el archivo de salida existe
962
- try {
963
- await stat(cacheEntry.outputPath);
964
- return true; // Archivo existe y no ha cambiado, se puede omitir
965
- }
966
- catch {
967
- return false; // Archivo de salida no existe, debe recompilarse
968
- }
969
- }
970
- return false; // Archivo ha cambiado, debe recompilarse
971
- }
972
- catch {
973
- return false; // Error al verificar, compilar por seguridad
974
- }
1214
+ return await smartCache.isValid(filePath);
975
1215
  }
976
1216
  // Función para compilar archivos con límite de concurrencia
977
1217
  async function compileWithConcurrencyLimit(files, maxConcurrency = 8) {
@@ -987,7 +1227,7 @@ async function compileWithConcurrencyLimit(files, maxConcurrency = 8) {
987
1227
  const progressPercent = Math.round((currentTotal / total) * 100);
988
1228
  if (progressPercent > lastProgressUpdate + 1 ||
989
1229
  currentTotal === total) {
990
- process.stdout.write(`\r🚀 ${progressBar} [✅ ${completed} | ⏭️ ${skipped} | ❌ ${failed}]`);
1230
+ stdout.write(`\r🚀 ${progressBar} [✅ ${completed} | ⏭️ ${skipped} | ❌ ${failed}]`);
991
1231
  lastProgressUpdate = progressPercent;
992
1232
  }
993
1233
  }
@@ -1001,18 +1241,12 @@ async function compileWithConcurrencyLimit(files, maxConcurrency = 8) {
1001
1241
  return {
1002
1242
  success: true,
1003
1243
  cached: true,
1004
- output: compilationCache.get(file)?.outputPath || '',
1244
+ output: smartCache.getOutputPath(file),
1005
1245
  };
1006
1246
  }
1007
- const result = await initCompile(file, false, 'batch');
1008
- // Actualizar cache si la compilación fue exitosa
1247
+ const result = await initCompile(file, false, 'batch'); // Actualizar cache si la compilación fue exitosa
1009
1248
  if (result.success && result.output) {
1010
- const stats = await stat(file);
1011
- compilationCache.set(file, {
1012
- hash: '', // Se podría implementar hash del contenido si es necesario
1013
- mtime: stats.mtimeMs,
1014
- outputPath: result.output,
1015
- });
1249
+ await smartCache.set(file, result.output);
1016
1250
  }
1017
1251
  completed++;
1018
1252
  showProgress();
@@ -1094,7 +1328,15 @@ export async function initCompileAll() {
1094
1328
  else {
1095
1329
  maxConcurrency = Math.min(cpuCount * 2, 16);
1096
1330
  }
1097
- logger.info(`🚀 Compilando ${fileCount} archivos con concurrencia optimizada (${maxConcurrency} hilos)...`);
1331
+ logger.info(`🚀 Compilando ${fileCount} archivos con concurrencia optimizada (${maxConcurrency} hilos)...`); // Configurar worker pool para modo batch
1332
+ try {
1333
+ const { TypeScriptWorkerPool } = await import('./typescript-worker-pool.js');
1334
+ const workerPool = TypeScriptWorkerPool.getInstance();
1335
+ workerPool.setMode('batch');
1336
+ }
1337
+ catch {
1338
+ // Error silencioso en configuración del pool
1339
+ }
1098
1340
  await compileWithConcurrencyLimit(filesToCompile, maxConcurrency);
1099
1341
  // Guardar cache al final
1100
1342
  await saveCache();