versacompiler 2.4.0 → 2.5.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.
Files changed (33) hide show
  1. package/README.md +722 -722
  2. package/dist/compiler/compile-worker-pool.js +96 -0
  3. package/dist/compiler/compile-worker-thread.cjs +72 -0
  4. package/dist/compiler/compile.js +81 -2
  5. package/dist/compiler/integrity-validator.js +1 -1
  6. package/dist/compiler/module-resolution-optimizer.js +23 -20
  7. package/dist/compiler/performance-monitor.js +61 -61
  8. package/dist/compiler/pipeline/build-pipeline.js +127 -0
  9. package/dist/compiler/pipeline/core-plugins.js +218 -0
  10. package/dist/compiler/pipeline/module-graph.js +63 -0
  11. package/dist/compiler/pipeline/plugin-driver.js +87 -0
  12. package/dist/compiler/pipeline/types.js +2 -0
  13. package/dist/compiler/transforms.js +222 -16
  14. package/dist/compiler/typescript-manager.js +3 -1
  15. package/dist/compiler/typescript-sync-validator.js +33 -31
  16. package/dist/compiler/typescript-worker-pool.js +66 -19
  17. package/dist/compiler/typescript-worker-thread.cjs +482 -469
  18. package/dist/compiler/vuejs.js +32 -32
  19. package/dist/config.js +2 -0
  20. package/dist/hrm/VueHRM.js +359 -359
  21. package/dist/hrm/errorScreen.js +83 -83
  22. package/dist/hrm/getInstanciaVue.js +313 -313
  23. package/dist/hrm/initHRM.js +628 -586
  24. package/dist/main.js +2 -1
  25. package/dist/servicios/browserSync.js +8 -2
  26. package/dist/servicios/file-watcher.js +48 -6
  27. package/dist/servicios/readConfig.js +129 -54
  28. package/dist/servicios/versacompile.config.types.js +2 -0
  29. package/dist/utils/module-resolver.js +74 -40
  30. package/dist/utils/vue-types-setup.js +248 -248
  31. package/dist/wrappers/eslint-node.js +3 -1
  32. package/dist/wrappers/oxlint-node.js +3 -1
  33. package/package.json +73 -54
@@ -10,36 +10,36 @@ import * as typescript from 'typescript';
10
10
  * Genera declaraciones básicas de tipos para Vue como fallback
11
11
  */
12
12
  const generateBasicVueTypes = () => {
13
- return `// Declaraciones básicas de tipos Vue para validación
14
- declare global {
15
- function ref<T>(value: T): { value: T };
16
- function reactive<T extends object>(target: T): T;
17
- function computed<T>(getter: () => T): { value: T };
18
- function defineComponent<T>(options: T): T;
19
- function defineProps<T = {}>(): T;
20
- function defineEmits<T = {}>(): T;
21
- function defineExpose<T = {}>(exposed: T): void;
22
- function onMounted(fn: () => void): void;
23
- function onUnmounted(fn: () => void): void;
24
- function onBeforeMount(fn: () => void): void;
25
- function onBeforeUnmount(fn: () => void): void;
26
- function onUpdated(fn: () => void): void;
27
- function onBeforeUpdate(fn: () => void): void;
28
- function provide<T>(key: string | symbol, value: T): void;
29
- function inject<T>(key: string | symbol, defaultValue?: T): T | undefined;
30
- function useSlots(): { [key: string]: (...args: any[]) => any };
31
- function useAttrs(): { [key: string]: any };
32
- function useModel<T>(modelName?: string): { value: T };
33
- function watch<T>(source: () => T, callback: (newValue: T, oldValue: T) => void): void;
34
- function watchEffect(effect: () => void): void;
35
- function nextTick(callback?: () => void): Promise<void>;
36
- function getCurrentInstance(): any;
37
- function mergeModels<T>(models: T): T;
38
- }
39
- declare module '*.vue' {
40
- const component: any;
41
- export default component;
42
- }
13
+ return `// Declaraciones básicas de tipos Vue para validación
14
+ declare global {
15
+ function ref<T>(value: T): { value: T };
16
+ function reactive<T extends object>(target: T): T;
17
+ function computed<T>(getter: () => T): { value: T };
18
+ function defineComponent<T>(options: T): T;
19
+ function defineProps<T = {}>(): T;
20
+ function defineEmits<T = {}>(): T;
21
+ function defineExpose<T = {}>(exposed: T): void;
22
+ function onMounted(fn: () => void): void;
23
+ function onUnmounted(fn: () => void): void;
24
+ function onBeforeMount(fn: () => void): void;
25
+ function onBeforeUnmount(fn: () => void): void;
26
+ function onUpdated(fn: () => void): void;
27
+ function onBeforeUpdate(fn: () => void): void;
28
+ function provide<T>(key: string | symbol, value: T): void;
29
+ function inject<T>(key: string | symbol, defaultValue?: T): T | undefined;
30
+ function useSlots(): { [key: string]: (...args: any[]) => any };
31
+ function useAttrs(): { [key: string]: any };
32
+ function useModel<T>(modelName?: string): { value: T };
33
+ function watch<T>(source: () => T, callback: (newValue: T, oldValue: T) => void): void;
34
+ function watchEffect(effect: () => void): void;
35
+ function nextTick(callback?: () => void): Promise<void>;
36
+ function getCurrentInstance(): any;
37
+ function mergeModels<T>(models: T): T;
38
+ }
39
+ declare module '*.vue' {
40
+ const component: any;
41
+ export default component;
42
+ }
43
43
  export {};`;
44
44
  };
45
45
  /**
@@ -269,7 +269,9 @@ export const validateTypesWithLanguageService = (fileName, content, compilerOpti
269
269
  try {
270
270
  languageService.dispose();
271
271
  }
272
- catch { /* ignore dispose errors */ }
272
+ catch {
273
+ /* ignore dispose errors */
274
+ }
273
275
  }
274
276
  }
275
277
  catch (error) {
@@ -19,8 +19,8 @@ export class TypeScriptWorkerPool {
19
19
  workerPath;
20
20
  initPromise = null;
21
21
  isInitialized = false; // Configuración optimizada con reciclaje de workers
22
- TASK_TIMEOUT = 8000; // 8 segundos por tarea (reducido para mayor velocidad)
23
- WORKER_INIT_TIMEOUT = 3000; // 3 segundos para inicializar (reducido)
22
+ TASK_TIMEOUT = 60000; // 60 segundos por tarea - workers son secuenciales, necesitan tiempo
23
+ WORKER_INIT_TIMEOUT = 10000; // 10 segundos para inicializar
24
24
  MAX_TASKS_PER_WORKER = 200; // ✨ OPTIMIZADO: Aumentado de 50 a 200 para reducir overhead de reciclaje
25
25
  WORKER_MEMORY_CHECK_INTERVAL = 500; // ✨ OPTIMIZADO: Verificar cada 500 tareas (reducir overhead)
26
26
  // ✨ FIX #1: Referencias a timers para limpieza adecuada
@@ -28,7 +28,7 @@ export class TypeScriptWorkerPool {
28
28
  cleanupInterval = null;
29
29
  // Cola de tareas para cuando todos los workers están ocupados
30
30
  taskQueue = [];
31
- MAX_QUEUE_SIZE = 50;
31
+ MAX_QUEUE_SIZE = 1000; // Suficiente para proyectos de 300+ archivos
32
32
  // Flag para evitar concurrencia en ensureWorkerCapacity
33
33
  isScalingUp = false;
34
34
  // Métricas de rendimiento
@@ -85,8 +85,11 @@ export class TypeScriptWorkerPool {
85
85
  // ✨ ISSUE #4: Obtener memoria real del worker
86
86
  const memoryInfo = await this.getWorkerMemoryUsage(poolWorker);
87
87
  poolWorker.memoryUsage = memoryInfo.heapUsed;
88
- // Verificar límites de memoria y reciclaje automático
89
- if (this.shouldRecycleWorker(poolWorker)) {
88
+ // Verificar límites de memoria y reciclaje automático.
89
+ // Solo reciclar workers INACTIVOS para evitar rechazar tareas en vuelo.
90
+ // Los workers con tareas pendientes se reciclan vía drainQueue cuando quedan libres.
91
+ const isIdle = !poolWorker.busy && poolWorker.pendingTasks.size === 0;
92
+ if (isIdle && this.shouldRecycleWorker(poolWorker)) {
90
93
  const reason = this.getRecycleReason(poolWorker);
91
94
  console.warn(`[WorkerPool] Worker ${poolWorker.id} requiere reciclaje: ${reason}`);
92
95
  await this.recycleWorker(poolWorker);
@@ -198,8 +201,8 @@ export class TypeScriptWorkerPool {
198
201
  const cpuCount = os.cpus().length;
199
202
  switch (mode) {
200
203
  case 'batch':
201
- // Para modo batch, hasta 3 workers conservando al menos 1 CPU libre
202
- this.poolSize = Math.min(3, Math.max(1, cpuCount - 1));
204
+ // Para modo batch, hasta 4 workers para mejor rendimiento en proyectos grandes
205
+ this.poolSize = Math.min(4, Math.max(1, cpuCount - 1));
203
206
  break;
204
207
  case 'watch':
205
208
  // Para modo watch, hasta 2 workers para menor impacto en sistema
@@ -376,9 +379,10 @@ export class TypeScriptWorkerPool {
376
379
  });
377
380
  }
378
381
  else {
379
- this.failedTasks++;
380
382
  const errorMessage = response.error || 'Error desconocido del worker';
381
383
  // ✨ FIX MEMORIA: Error simple sin referencias pesadas
384
+ // failedTasks se incrementa en el wrapper de queued.reject para tareas de cola,
385
+ // o en handleWorkerError/Exit para tareas directas que se re-encolan.
382
386
  const error = new Error(errorMessage);
383
387
  reject(error);
384
388
  }
@@ -404,7 +408,8 @@ export class TypeScriptWorkerPool {
404
408
  const pendingTasksArray = Array.from(poolWorker.pendingTasks.entries());
405
409
  for (const [taskId, task] of pendingTasksArray) {
406
410
  clearTimeout(task.timeout);
407
- this.failedTasks++;
411
+ // failedTasks se contabiliza en el wrapper de queued.reject (para cola)
412
+ // o via re-encolado en typeCheck() catch (para tareas directas).
408
413
  task.reject(new Error(`Worker ${poolWorker.id} failed`));
409
414
  poolWorker.pendingTasks.delete(taskId);
410
415
  }
@@ -436,6 +441,8 @@ export class TypeScriptWorkerPool {
436
441
  if (index !== -1) {
437
442
  this.workers[index] = newWorker;
438
443
  }
444
+ // Drenar la cola con el nuevo worker para evitar tareas atascadas
445
+ setImmediate(() => this.drainAllWorkers());
439
446
  }
440
447
  catch {
441
448
  // Silencioso
@@ -451,7 +458,8 @@ export class TypeScriptWorkerPool {
451
458
  // 1. Rechazar tareas pendientes con cleanup
452
459
  poolWorker.pendingTasks.forEach(task => {
453
460
  clearTimeout(task.timeout);
454
- this.failedTasks++;
461
+ // failedTasks se contabiliza en el wrapper de queued.reject (para cola)
462
+ // o via re-encolado en typeCheck() catch (para tareas directas).
455
463
  task.reject(new Error(`Worker ${poolWorker.id} exited with code ${code}`));
456
464
  });
457
465
  poolWorker.pendingTasks.clear();
@@ -543,6 +551,8 @@ export class TypeScriptWorkerPool {
543
551
  if (index !== -1) {
544
552
  this.workers[index] = newWorker;
545
553
  }
554
+ // Drenar la cola con el nuevo worker listo
555
+ setImmediate(() => this.drainQueue(newWorker));
546
556
  }
547
557
  catch (error) {
548
558
  console.error(`[WorkerPool] Error reciclando worker ${poolWorker.id}:`, error);
@@ -573,6 +583,18 @@ export class TypeScriptWorkerPool {
573
583
  }
574
584
  return null; // Todos los workers están muy ocupados
575
585
  }
586
+ /**
587
+ * Drena la cola en todos los workers disponibles
588
+ */
589
+ drainAllWorkers() {
590
+ for (const worker of this.workers) {
591
+ if (!worker.busy && worker.pendingTasks.size === 0) {
592
+ this.drainQueue(worker);
593
+ if (this.taskQueue.length === 0)
594
+ break;
595
+ }
596
+ }
597
+ }
576
598
  /**
577
599
  * Procesa la siguiente tarea de la cola en el worker liberado
578
600
  */
@@ -581,19 +603,27 @@ export class TypeScriptWorkerPool {
581
603
  return;
582
604
  if (poolWorker.busy || poolWorker.pendingTasks.size > 0)
583
605
  return;
584
- if (poolWorker.taskCounter >= this.MAX_TASKS_PER_WORKER)
606
+ // Si el worker alcanzó el límite de tareas, reciclarlo y luego drenar
607
+ if (poolWorker.taskCounter >= this.MAX_TASKS_PER_WORKER) {
608
+ this.recycleWorker(poolWorker)
609
+ .then(() => setImmediate(() => this.drainAllWorkers()))
610
+ .catch(() => { });
585
611
  return;
612
+ }
586
613
  const queued = this.taskQueue.shift();
587
614
  if (!queued)
588
615
  return;
589
616
  const waitMs = Date.now() - queued.queuedAt;
590
617
  if (waitMs > 30000) {
618
+ // queued.reject incluye failedTasks++ en el wrapper (ver typeCheck())
591
619
  queued.reject(new Error(`Queue task expired after ${waitMs}ms`));
620
+ // Continuar drenando la cola con la siguiente tarea
621
+ setImmediate(() => this.drainQueue(poolWorker));
592
622
  return;
593
623
  }
594
624
  this.typeCheckWithWorker(poolWorker, queued.fileName, queued.content, queued.compilerOptions)
595
625
  .then(queued.resolve)
596
- .catch(queued.reject);
626
+ .catch(queued.reject); // queued.reject incluye failedTasks++ en el wrapper
597
627
  }
598
628
  /**
599
629
  * Realiza type checking usando el pool de workers
@@ -613,23 +643,38 @@ export class TypeScriptWorkerPool {
613
643
  return await this.typeCheckWithWorker(availableWorker, fileName, content, compilerOptions);
614
644
  }
615
645
  catch {
616
- // Worker falló; intentar encolar
646
+ // Worker falló o llegó al límite de tareas
647
+ // Si alcanzó el límite, disparar reciclaje inmediato
648
+ if (availableWorker.taskCounter >= this.MAX_TASKS_PER_WORKER) {
649
+ this.recycleWorker(availableWorker)
650
+ .then(() => setImmediate(() => this.drainAllWorkers()))
651
+ .catch(() => { });
652
+ }
617
653
  }
618
654
  }
619
655
  // Ningún worker disponible: encolar la tarea
620
656
  if (this.taskQueue.length >= this.MAX_QUEUE_SIZE) {
621
- // Cola llena → fallback síncrono para no perder el type check
622
- return this.typeCheckWithSyncFallback(fileName, content, compilerOptions);
657
+ // Cola llena → omitir type check para no bloquear el event loop
658
+ // (con MAX_QUEUE_SIZE=1000 esto solo ocurre en proyectos extremadamente grandes)
659
+ console.warn(`[TypeCheckQueue] Cola llena (${this.MAX_QUEUE_SIZE} tareas). Type check omitido para: ${path.basename(fileName)}`);
660
+ this.completedTasks++; // Contabilizar como completado para mantener métricas consistentes
661
+ return { diagnostics: [], hasErrors: false };
623
662
  }
624
663
  // Escalar el pool si es posible
625
664
  this.ensureWorkerCapacity().catch(() => { });
626
665
  return new Promise((resolve, reject) => {
666
+ // Wrapper para reject que garantiza que failedTasks se incrementa exactamente una vez
667
+ // para todas las tareas que pasan por la cola (drainQueue path).
668
+ const wrappedReject = (err) => {
669
+ this.failedTasks++;
670
+ reject(err);
671
+ };
627
672
  this.taskQueue.push({
628
673
  fileName,
629
674
  content,
630
675
  compilerOptions,
631
676
  resolve,
632
- reject,
677
+ reject: wrappedReject,
633
678
  queuedAt: Date.now(),
634
679
  });
635
680
  });
@@ -639,9 +684,9 @@ export class TypeScriptWorkerPool {
639
684
  * ✨ FIX MEMORIA: Optimizado para prevenir fugas de memoria
640
685
  */
641
686
  async typeCheckWithWorker(poolWorker, fileName, content, compilerOptions) {
642
- // Si el worker alcanzó su límite de tareas, usar fallback síncrono
687
+ // Si el worker alcanzó su límite de tareas, encolar para reciclaje
643
688
  if (poolWorker.taskCounter >= this.MAX_TASKS_PER_WORKER) {
644
- return this.typeCheckWithSyncFallback(fileName, content, compilerOptions);
689
+ throw new Error(`Worker ${poolWorker.id} ha alcanzado el límite de tareas`);
645
690
  }
646
691
  return new Promise((resolve, reject) => {
647
692
  const taskId = `task-${poolWorker.id}-${++poolWorker.taskCounter}-${Date.now()}`;
@@ -660,6 +705,8 @@ export class TypeScriptWorkerPool {
660
705
  poolWorker.busy = false;
661
706
  }
662
707
  reject(new Error(`Timeout (${dynamicTimeout}ms) en type checking para ${fileName}`));
708
+ // Drenar la cola cuando se libera la tarea por timeout
709
+ setImmediate(() => this.drainQueue(poolWorker));
663
710
  }
664
711
  }, dynamicTimeout);
665
712
  // ✨ FIX MEMORIA: Wrapper para resolver/rechazar que limpia el timeout
@@ -764,7 +811,7 @@ export class TypeScriptWorkerPool {
764
811
  complexityMultiplier = Math.min(complexityMultiplier, 5); // Máximo 5x el timeout base
765
812
  complexityMultiplier = Math.max(complexityMultiplier, 0.5); // Mínimo 0.5x el timeout base
766
813
  const finalTimeout = Math.round(baseTimeout * complexityMultiplier);
767
- return Math.min(finalTimeout, 60000); // Máximo absoluto de 60 segundos
814
+ return Math.min(finalTimeout, 120000); // Máximo absoluto de 120 segundos
768
815
  }
769
816
  /**
770
817
  * Fallback síncrono para type checking