versacompiler 2.4.1 → 2.6.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 (52) hide show
  1. package/README.md +722 -722
  2. package/dist/compiler/compile-worker-pool.js +108 -0
  3. package/dist/compiler/compile-worker-thread.cjs +72 -0
  4. package/dist/compiler/compile.js +177 -18
  5. package/dist/compiler/error-reporter.js +12 -0
  6. package/dist/compiler/integrity-validator.js +13 -1
  7. package/dist/compiler/linter.js +12 -0
  8. package/dist/compiler/minify.js +12 -0
  9. package/dist/compiler/minifyTemplate.js +12 -0
  10. package/dist/compiler/module-resolution-optimizer.js +35 -20
  11. package/dist/compiler/parser.js +12 -0
  12. package/dist/compiler/performance-monitor.js +73 -61
  13. package/dist/compiler/pipeline/build-pipeline.js +139 -0
  14. package/dist/compiler/pipeline/core-plugins.js +230 -0
  15. package/dist/compiler/pipeline/module-graph.js +75 -0
  16. package/dist/compiler/pipeline/plugin-driver.js +99 -0
  17. package/dist/compiler/pipeline/types.js +14 -0
  18. package/dist/compiler/tailwindcss.js +12 -0
  19. package/dist/compiler/transform-optimizer.js +12 -0
  20. package/dist/compiler/transformTStoJS.js +38 -5
  21. package/dist/compiler/transforms.js +234 -16
  22. package/dist/compiler/typescript-compiler.js +12 -0
  23. package/dist/compiler/typescript-error-parser.js +12 -0
  24. package/dist/compiler/typescript-manager.js +15 -1
  25. package/dist/compiler/typescript-sync-validator.js +45 -31
  26. package/dist/compiler/typescript-worker-pool.js +12 -0
  27. package/dist/compiler/typescript-worker-thread.cjs +482 -475
  28. package/dist/compiler/typescript-worker.js +12 -0
  29. package/dist/compiler/vuejs.js +73 -47
  30. package/dist/config.js +14 -0
  31. package/dist/hrm/VueHRM.js +484 -359
  32. package/dist/hrm/errorScreen.js +95 -83
  33. package/dist/hrm/getInstanciaVue.js +325 -313
  34. package/dist/hrm/initHRM.js +736 -586
  35. package/dist/hrm/versaHMR.js +317 -0
  36. package/dist/main.js +23 -3
  37. package/dist/servicios/browserSync.js +127 -6
  38. package/dist/servicios/file-watcher.js +139 -8
  39. package/dist/servicios/logger.js +12 -0
  40. package/dist/servicios/readConfig.js +141 -54
  41. package/dist/servicios/versacompile.config.types.js +14 -0
  42. package/dist/utils/excluded-modules.js +12 -0
  43. package/dist/utils/module-resolver.js +86 -40
  44. package/dist/utils/promptUser.js +12 -0
  45. package/dist/utils/proxyValidator.js +12 -0
  46. package/dist/utils/resolve-bin.js +12 -0
  47. package/dist/utils/utils.js +12 -0
  48. package/dist/utils/vue-types-setup.js +260 -248
  49. package/dist/wrappers/eslint-node.js +15 -1
  50. package/dist/wrappers/oxlint-node.js +15 -1
  51. package/dist/wrappers/tailwind-node.js +12 -0
  52. package/package.json +74 -54
@@ -0,0 +1,108 @@
1
+ /* VersaCompiler HMR shim [dev] */
2
+ if (typeof window !== 'undefined' && window.__versaHMR) {
3
+ (() => {
4
+ const _id = new URL(import.meta.url).pathname;
5
+ import.meta.hot = {
6
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
7
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
8
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
9
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
10
+ };
11
+ })();
12
+ }
13
+ import * as os from 'node:os';
14
+ import * as path from 'node:path';
15
+ import * as process from 'node:process';
16
+ import { Worker } from 'node:worker_threads';
17
+ export class CompileWorkerPool {
18
+ static instance;
19
+ workers = [];
20
+ pending = new Map();
21
+ queue = [];
22
+ poolSize;
23
+ workerPath;
24
+ TASK_TIMEOUT = 60000;
25
+ constructor() {
26
+ const cpuCount = os.cpus().length;
27
+ const configuredMax = parseInt(process.env.COMPILE_MAX_WORKERS || '2', 10);
28
+ this.poolSize = Math.min(configuredMax, Math.max(1, cpuCount - 1));
29
+ this.workerPath = path.join(process.env.PATH_PROY || path.join(process.cwd(), 'src'), 'compiler', 'compile-worker-thread.cjs');
30
+ this.initWorkers();
31
+ }
32
+ static getInstance() {
33
+ if (!CompileWorkerPool.instance) {
34
+ CompileWorkerPool.instance = new CompileWorkerPool();
35
+ }
36
+ return CompileWorkerPool.instance;
37
+ }
38
+ initWorkers() {
39
+ for (let i = 0; i < this.poolSize; i++) {
40
+ const worker = new Worker(this.workerPath, {
41
+ env: process.env,
42
+ });
43
+ const poolWorker = { worker, busy: false };
44
+ worker.on('message', (response) => {
45
+ const pending = this.pending.get(response.id);
46
+ if (!pending)
47
+ return;
48
+ clearTimeout(pending.timeout);
49
+ this.pending.delete(response.id);
50
+ poolWorker.busy = false;
51
+ if (!response.success) {
52
+ pending.reject(new Error(response.error || 'Worker task failed'));
53
+ }
54
+ else {
55
+ pending.resolve(response.data);
56
+ }
57
+ this.drainQueue();
58
+ });
59
+ worker.on('error', error => {
60
+ poolWorker.busy = false;
61
+ for (const [id, pending] of this.pending) {
62
+ clearTimeout(pending.timeout);
63
+ const normalized = error instanceof Error
64
+ ? error
65
+ : new Error(String(error));
66
+ pending.reject(normalized);
67
+ this.pending.delete(id);
68
+ }
69
+ this.drainQueue();
70
+ });
71
+ this.workers.push(poolWorker);
72
+ }
73
+ }
74
+ async runTask(type, payload) {
75
+ const id = `${type}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
76
+ const message = { id, type, payload };
77
+ return new Promise((resolve, reject) => {
78
+ const timeout = setTimeout(() => {
79
+ this.pending.delete(id);
80
+ reject(new Error(`Worker timeout: ${type}`));
81
+ }, this.TASK_TIMEOUT);
82
+ this.pending.set(id, { resolve, reject, timeout });
83
+ const worker = this.getAvailableWorker();
84
+ if (worker) {
85
+ worker.busy = true;
86
+ worker.worker.postMessage(message);
87
+ return;
88
+ }
89
+ this.queue.push(message);
90
+ });
91
+ }
92
+ getAvailableWorker() {
93
+ return this.workers.find(worker => !worker.busy) || null;
94
+ }
95
+ drainQueue() {
96
+ if (this.queue.length === 0)
97
+ return;
98
+ const worker = this.getAvailableWorker();
99
+ if (!worker)
100
+ return;
101
+ const message = this.queue.shift();
102
+ if (!message)
103
+ return;
104
+ worker.busy = true;
105
+ worker.worker.postMessage(message);
106
+ }
107
+ }
108
+ //# sourceMappingURL=compile-worker-pool.js.map
@@ -0,0 +1,72 @@
1
+ const { parentPort } = require('node:worker_threads');
2
+
3
+ let preCompileVue;
4
+ let preCompileTS;
5
+ let minifyJS;
6
+
7
+ async function loadVue() {
8
+ if (!preCompileVue) {
9
+ const mod = await import('./vuejs.js');
10
+ preCompileVue = mod.preCompileVue;
11
+ }
12
+ return preCompileVue;
13
+ }
14
+
15
+ async function loadTypeScript() {
16
+ if (!preCompileTS) {
17
+ const mod = await import('./typescript-manager.js');
18
+ preCompileTS = mod.preCompileTS;
19
+ }
20
+ return preCompileTS;
21
+ }
22
+
23
+ async function loadMinify() {
24
+ if (!minifyJS) {
25
+ const mod = await import('./minify.js');
26
+ minifyJS = mod.minifyJS;
27
+ }
28
+ return minifyJS;
29
+ }
30
+
31
+ parentPort.on('message', async message => {
32
+ const { id, type, payload } = message;
33
+ try {
34
+ if (type === 'vue') {
35
+ const compileVue = await loadVue();
36
+ const result = await compileVue(
37
+ payload.source,
38
+ payload.fileName,
39
+ payload.isProd === true,
40
+ );
41
+ parentPort.postMessage({ id, success: true, data: result });
42
+ return;
43
+ }
44
+ if (type === 'ts') {
45
+ const compileTS = await loadTypeScript();
46
+ const result = await compileTS(
47
+ payload.source,
48
+ payload.fileName,
49
+ payload.scriptInfo,
50
+ );
51
+ parentPort.postMessage({ id, success: true, data: result });
52
+ return;
53
+ }
54
+ if (type === 'minify') {
55
+ const minify = await loadMinify();
56
+ const result = await minify(payload.source, payload.fileName, true);
57
+ parentPort.postMessage({ id, success: true, data: result });
58
+ return;
59
+ }
60
+ parentPort.postMessage({
61
+ id,
62
+ success: false,
63
+ error: `Tipo de tarea desconocido: ${type}`,
64
+ });
65
+ } catch (error) {
66
+ parentPort.postMessage({
67
+ id,
68
+ success: false,
69
+ error: error instanceof Error ? error.message : String(error),
70
+ });
71
+ }
72
+ });
@@ -1,3 +1,15 @@
1
+ /* VersaCompiler HMR shim [dev] */
2
+ if (typeof window !== 'undefined' && window.__versaHMR) {
3
+ (() => {
4
+ const _id = new URL(import.meta.url).pathname;
5
+ import.meta.hot = {
6
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
7
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
8
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
9
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
10
+ };
11
+ })();
12
+ }
1
13
  import { createHash } from 'node:crypto';
2
14
  import { glob, mkdir, readFile, stat, unlink, writeFile, } from 'node:fs/promises';
3
15
  import * as os from 'node:os';
@@ -6,9 +18,12 @@ import * as process from 'node:process';
6
18
  const { argv, cwd, env } = process;
7
19
  // Lazy loading optimizations - Only import lightweight modules synchronously
8
20
  import { logger, setProgressManagerGetter } from '../servicios/logger.js';
21
+ import { getLoadedConfig } from '../servicios/readConfig.js';
9
22
  import { promptUser } from '../utils/promptUser.js';
10
23
  import { showTimingForHumans } from '../utils/utils.js';
11
24
  import { integrityValidator } from './integrity-validator.js';
25
+ import { BuildPipeline } from './pipeline/build-pipeline.js';
26
+ import { createCorePlugins } from './pipeline/core-plugins.js';
12
27
  // Configurar el getter del ProgressManager para el logger
13
28
  setProgressManagerGetter(() => ProgressManager.getInstance());
14
29
  /**
@@ -29,6 +44,7 @@ let generateTailwindCSS;
29
44
  let estandarizaCode;
30
45
  let preCompileTS;
31
46
  let preCompileVue;
47
+ let pipelineInstance = null;
32
48
  // 🚀 Importar optimizador de transformaciones
33
49
  let TransformOptimizer;
34
50
  // 🚀 Importar optimizador de resolución de módulos
@@ -70,18 +86,22 @@ class OptimizedModuleManager {
70
86
  }
71
87
  /**
72
88
  * ✨ NUEVO: Precarga módulos críticos en background
89
+ * Cada módulo se precarga de forma independiente con su propio try-catch
90
+ * para que un fallo individual no rechace toda la Promise raíz.
73
91
  */
74
92
  async preloadCriticalModules() {
75
- try {
76
- // Precargar módulos críticos de forma asíncrona
77
- const preloadPromises = this.HOT_MODULES.map(moduleName => this.ensureModuleLoaded(moduleName).catch(() => {
78
- // Silenciar errores de precarga, se intentará cargar después
79
- }));
80
- await Promise.allSettled(preloadPromises);
81
- }
82
- catch {
83
- // Fallos en precarga no deben afectar la funcionalidad principal
84
- }
93
+ const preloadPromises = this.HOT_MODULES.map(async (moduleName) => {
94
+ try {
95
+ await this.ensureModuleLoaded(moduleName);
96
+ }
97
+ catch {
98
+ // Fallo individual no debe afectar otros módulos ni la Promise raíz
99
+ if (env.VERBOSE === 'true') {
100
+ console.warn(`[ModuleManager] Precarga fallida para '${moduleName}', se intentará al primer uso`);
101
+ }
102
+ }
103
+ });
104
+ await Promise.all(preloadPromises);
85
105
  }
86
106
  /**
87
107
  * ✨ MEJORADO: Precarga contextual basada en tipos de archivo con lock para prevenir cargas concurrentes
@@ -348,21 +368,25 @@ class OptimizedModuleManager {
348
368
  if (currentMemory > this.MAX_POOL_MEMORY ||
349
369
  currentSize > this.MAX_POOL_SIZE) {
350
370
  // LRU: Ordenar por menos usado
351
- const sortedModules = Array.from(this.usageStats.entries())
352
- .sort((a, b) => a[1] - b[1]) // Ascendente por uso
353
- .filter(([name]) => !this.HOT_MODULES.includes(name)); // No eliminar HOT_MODULES
371
+ const sortedModules = Array.from(this.usageStats.entries()).sort((a, b) => a[1] - b[1]); // Ascendente por uso
354
372
  // Eliminar módulos hasta estar por debajo del 70% del límite
355
373
  const targetMemory = this.MAX_POOL_MEMORY * 0.7;
356
374
  const targetSize = this.MAX_POOL_SIZE * 0.7;
375
+ const criticalPressure = currentMemory > this.MAX_POOL_MEMORY * 0.9;
357
376
  for (const [moduleName] of sortedModules) {
358
- this.modulePool.delete(moduleName);
359
- this.loadedModules.delete(moduleName);
360
- this.usageStats.delete(moduleName);
361
377
  const newMemory = this.getPoolMemoryUsage();
362
378
  const newSize = this.modulePool.size;
363
379
  if (newMemory <= targetMemory && newSize <= targetSize) {
364
380
  break;
365
381
  }
382
+ // HOT_MODULES solo se desalojan si la presión de memoria es crítica (>90%)
383
+ if (this.HOT_MODULES.includes(moduleName) &&
384
+ !criticalPressure) {
385
+ continue;
386
+ }
387
+ this.modulePool.delete(moduleName);
388
+ this.loadedModules.delete(moduleName);
389
+ this.usageStats.delete(moduleName);
366
390
  }
367
391
  if (env.VERBOSE === 'true') {
368
392
  console.log(`[ModuleManager] Limpieza: ${currentSize} → ${this.modulePool.size} módulos, ` +
@@ -544,6 +568,16 @@ class SmartCompilationCache {
544
568
  catch {
545
569
  // Ignorar si no existe package-lock.json
546
570
  }
571
+ // 2b. Hash de pnpm-lock.yaml si existe (pnpm)
572
+ try {
573
+ const pnpmLockPath = path.join(cwd(), 'pnpm-lock.yaml');
574
+ const pnpmLockContent = await readFile(pnpmLockPath, 'utf8');
575
+ hash.update(`pnpm-lock:${pnpmLockContent.length}`);
576
+ hash.update(pnpmLockContent);
577
+ }
578
+ catch {
579
+ // Ignorar si no existe pnpm-lock.yaml
580
+ }
547
581
  // 3. ✨ NUEVO: Hash de timestamps críticos de node_modules
548
582
  try {
549
583
  const nodeModulesPath = path.join(cwd(), 'node_modules');
@@ -609,7 +643,7 @@ class SmartCompilationCache {
609
643
  return false;
610
644
  try {
611
645
  // Ejecutar todas las verificaciones independientes en paralelo
612
- const [currentContentHash, currentDependencyHash, fileStat, _outputStat] = await Promise.all([
646
+ const [currentContentHash, currentDependencyHash, fileStat, _outputStat,] = await Promise.all([
613
647
  this.generateContentHash(filePath),
614
648
  this.generateDependencyHash(),
615
649
  stat(filePath),
@@ -1406,7 +1440,8 @@ async function _displaySingleLinterError(error, filePath) {
1406
1440
  }
1407
1441
  else {
1408
1442
  // Líneas de contexto
1409
- logger.info(chalkLib.blue(` ${prefix} │ `) + chalkLib.gray(currentLine));
1443
+ logger.info(chalkLib.blue(` ${prefix} │ `) +
1444
+ chalkLib.gray(currentLine));
1410
1445
  }
1411
1446
  }
1412
1447
  logger.info(chalkLib.blue(' ╰────'));
@@ -1558,6 +1593,124 @@ class WatchModeOptimizer {
1558
1593
  this.fileSystemCache.clear();
1559
1594
  }
1560
1595
  }
1596
+ function getBuildPipeline() {
1597
+ if (!pipelineInstance) {
1598
+ const basePlugins = createCorePlugins();
1599
+ const config = getLoadedConfig();
1600
+ const userPlugins = normalizeUserPlugins(config?.plugins);
1601
+ pipelineInstance = new BuildPipeline([...basePlugins, ...userPlugins]);
1602
+ }
1603
+ return pipelineInstance;
1604
+ }
1605
+ function normalizeUserPlugins(plugins) {
1606
+ if (!plugins || !Array.isArray(plugins))
1607
+ return [];
1608
+ return plugins.filter((plugin) => {
1609
+ if (!plugin || typeof plugin !== 'object')
1610
+ return false;
1611
+ const candidate = plugin;
1612
+ if (!candidate.name || typeof candidate.name !== 'string')
1613
+ return false;
1614
+ return Boolean(candidate.onResolve ||
1615
+ candidate.onLoad ||
1616
+ candidate.onTransform ||
1617
+ candidate.onHotUpdate ||
1618
+ candidate.onEnd);
1619
+ });
1620
+ }
1621
+ export function getPipelineModuleGraph() {
1622
+ if (env.PIPELINE_V2 === 'false')
1623
+ return null;
1624
+ return getBuildPipeline().getModuleGraph();
1625
+ }
1626
+ export async function runPipelineHotUpdate(filePath, type) {
1627
+ if (env.PIPELINE_V2 === 'false') {
1628
+ return { reload: 'none' };
1629
+ }
1630
+ return getBuildPipeline().hotUpdate({ path: filePath, type });
1631
+ }
1632
+ /**
1633
+ * Extrae los imports locales (rutas absolutas con /) del código compilado.
1634
+ * Solo imports estáticos de rutas absolutas del proyecto (excluye /node_modules/).
1635
+ */
1636
+ function extractLocalImports(code) {
1637
+ const imports = [];
1638
+ const importRegex = /(?:from|import)\s+['"](\/((?!node_modules)[^'"?#]+\.js))['"]/g;
1639
+ let match;
1640
+ while ((match = importRegex.exec(code)) !== null) {
1641
+ const importPath = match[1];
1642
+ if (importPath && !imports.includes(importPath)) {
1643
+ imports.push(importPath);
1644
+ }
1645
+ }
1646
+ return imports;
1647
+ }
1648
+ /**
1649
+ * Inyecta el shim de import.meta.hot al inicio de archivos JS compilados en modo dev.
1650
+ * Adicionalmente registra accept() para cada dependencia local: cuando una dependencia
1651
+ * se actualiza en versaHMR, el módulo actual se re-importa con timestamp nuevo,
1652
+ * forzando al browser a crear un nuevo module record con la dependencia actualizada.
1653
+ * Solo se llama cuando env.isPROD !== 'true' y la salida es un archivo .js.
1654
+ */
1655
+ function injectHmrShim(code) {
1656
+ const localImports = extractLocalImports(code);
1657
+ // Detecta si es un Vue SFC (el compilador Vue inyecta 'data-versa-hmr-component')
1658
+ const isVueComponent = code.includes('data-versa-hmr-component');
1659
+ const depsAccept = localImports.length > 0
1660
+ ? localImports
1661
+ .map(dep => {
1662
+ if (isVueComponent) {
1663
+ // Vue SFC: tras actualizar dependencia, re-cargar instancia Vue en DOM
1664
+ return ` window.__versaHMR.accept(${JSON.stringify(dep)}, async () => { await window.__versaHMR._reloadVueByPath?.(_id); });`;
1665
+ }
1666
+ // Módulo JS/TS plano: re-importar con nuevo timestamp para actualizar module record
1667
+ return ` window.__versaHMR.accept(${JSON.stringify(dep)}, () => { import(_id + '?t=' + Date.now()); });`;
1668
+ })
1669
+ .join('\n') + '\n'
1670
+ : '';
1671
+ const shim = `/* VersaCompiler HMR shim [dev] */
1672
+ if (typeof window !== 'undefined' && window.__versaHMR) {
1673
+ (() => {
1674
+ const _id = new URL(import.meta.url).pathname;
1675
+ import.meta.hot = {
1676
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
1677
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
1678
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
1679
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
1680
+ };
1681
+ ${depsAccept} })();
1682
+ }\n`;
1683
+ return shim + code;
1684
+ }
1685
+ async function compileWithPipeline(inPath, outPath, mode = 'individual') {
1686
+ const pipeline = getBuildPipeline();
1687
+ const result = await pipeline.compileFile(inPath);
1688
+ if (result.errors.length > 0) {
1689
+ for (const message of result.errors) {
1690
+ await handleCompilationError(new Error(message), inPath, 'pipeline', mode, env.VERBOSE === 'true');
1691
+ }
1692
+ throw new Error(result.errors[0]);
1693
+ }
1694
+ if (!result.code || result.code.trim().length === 0) {
1695
+ await handleCompilationError(new Error('El código compilado está vacío.'), inPath, 'pipeline', mode, env.VERBOSE === 'true');
1696
+ throw new Error('El código compilado está vacío.');
1697
+ }
1698
+ const destinationDir = path.dirname(outPath);
1699
+ await mkdir(destinationDir, { recursive: true });
1700
+ let pipelineCode = result.code;
1701
+ if (env.isPROD !== 'true' && outPath.endsWith('.js')) {
1702
+ pipelineCode = injectHmrShim(pipelineCode);
1703
+ }
1704
+ await writeFile(outPath, pipelineCode, 'utf-8');
1705
+ if (result.dependencies.length > 0) {
1706
+ smartCache.registerDependencies(inPath, result.dependencies);
1707
+ }
1708
+ registerCompilationSuccess(inPath, 'pipeline');
1709
+ return {
1710
+ error: null,
1711
+ action: 'extension',
1712
+ };
1713
+ }
1561
1714
  async function compileJS(inPath, outPath, mode = 'individual') {
1562
1715
  const timings = {};
1563
1716
  // Si la ruta ya es absoluta, no la resolvamos de nuevo
@@ -1565,6 +1718,9 @@ async function compileJS(inPath, outPath, mode = 'individual') {
1565
1718
  ? normalizeRuta(inPath)
1566
1719
  : normalizeRuta(path.resolve(inPath)); // 🚀 Usar OptimizedModuleManager para carga optimizada
1567
1720
  const moduleManager = OptimizedModuleManager.getInstance();
1721
+ if (env.PIPELINE_V2 !== 'false') {
1722
+ return compileWithPipeline(inPath, outPath, mode);
1723
+ }
1568
1724
  // Timing de lectura
1569
1725
  let start = Date.now();
1570
1726
  const extension = path.extname(inPath); // Asegurar que el parser esté cargado
@@ -1724,6 +1880,9 @@ async function compileJS(inPath, outPath, mode = 'individual') {
1724
1880
  } // Escribir archivo final
1725
1881
  const destinationDir = path.dirname(outPath);
1726
1882
  await mkdir(destinationDir, { recursive: true });
1883
+ if (env.isPROD !== 'true' && outPath.endsWith('.js')) {
1884
+ code = injectHmrShim(code);
1885
+ }
1727
1886
  await writeFile(outPath, code, 'utf-8');
1728
1887
  // Logs de timing detallados en modo verbose
1729
1888
  if (shouldShowDetailedLogs) {
@@ -1,3 +1,15 @@
1
+ /* VersaCompiler HMR shim [dev] */
2
+ if (typeof window !== 'undefined' && window.__versaHMR) {
3
+ (() => {
4
+ const _id = new URL(import.meta.url).pathname;
5
+ import.meta.hot = {
6
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
7
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
8
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
9
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
10
+ };
11
+ })();
12
+ }
1
13
  // Lazy loading optimizations - Only import lightweight modules synchronously
2
14
  // Heavy dependencies will be loaded dynamically when needed
3
15
  let chalk;
@@ -1,3 +1,15 @@
1
+ /* VersaCompiler HMR shim [dev] */
2
+ if (typeof window !== 'undefined' && window.__versaHMR) {
3
+ (() => {
4
+ const _id = new URL(import.meta.url).pathname;
5
+ import.meta.hot = {
6
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
7
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
8
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
9
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
10
+ };
11
+ })();
12
+ }
1
13
  import { parseSync } from 'oxc-parser';
2
14
  import { logger } from '../servicios/logger.js';
3
15
  /**
@@ -48,7 +60,7 @@ export class IntegrityValidator {
48
60
  // Revisar cache
49
61
  const cacheKey = this.getCacheKey(context, processed);
50
62
  const cached = this.cache.get(cacheKey);
51
- if (cached && (Date.now() - cached.timestamp) < this.CACHE_TTL) {
63
+ if (cached && Date.now() - cached.timestamp < this.CACHE_TTL) {
52
64
  this.stats.cacheHits++;
53
65
  if (options.verbose) {
54
66
  logger.info(`[IntegrityValidator] Cache hit for ${context}`);
@@ -1,3 +1,15 @@
1
+ /* VersaCompiler HMR shim [dev] */
2
+ if (typeof window !== 'undefined' && window.__versaHMR) {
3
+ (() => {
4
+ const _id = new URL(import.meta.url).pathname;
5
+ import.meta.hot = {
6
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
7
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
8
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
9
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
10
+ };
11
+ })();
12
+ }
1
13
  import { env } from 'node:process';
2
14
  import { logger } from '../servicios/logger.js';
3
15
  import { ESLintNode, } from './../wrappers/eslint-node.js';
@@ -1,3 +1,15 @@
1
+ /* VersaCompiler HMR shim [dev] */
2
+ if (typeof window !== 'undefined' && window.__versaHMR) {
3
+ (() => {
4
+ const _id = new URL(import.meta.url).pathname;
5
+ import.meta.hot = {
6
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
7
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
8
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
9
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
10
+ };
11
+ })();
12
+ }
1
13
  import { createHash } from 'node:crypto';
2
14
  import { minifySync } from 'oxc-minify';
3
15
  import { logger } from '../servicios/logger.js';
@@ -1,3 +1,15 @@
1
+ /* VersaCompiler HMR shim [dev] */
2
+ if (typeof window !== 'undefined' && window.__versaHMR) {
3
+ (() => {
4
+ const _id = new URL(import.meta.url).pathname;
5
+ import.meta.hot = {
6
+ accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
7
+ invalidate() { window.__versaHMR._invalidate?.(_id); },
8
+ dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
9
+ get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
10
+ };
11
+ })();
12
+ }
1
13
  import { minifyHTMLLiterals } from 'minify-html-literals';
2
14
  import { logger } from '../servicios/logger.js';
3
15
  import { integrityValidator } from './integrity-validator.js';