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.
- package/README.md +722 -722
- package/dist/compiler/compile-worker-pool.js +108 -0
- package/dist/compiler/compile-worker-thread.cjs +72 -0
- package/dist/compiler/compile.js +177 -18
- package/dist/compiler/error-reporter.js +12 -0
- package/dist/compiler/integrity-validator.js +13 -1
- package/dist/compiler/linter.js +12 -0
- package/dist/compiler/minify.js +12 -0
- package/dist/compiler/minifyTemplate.js +12 -0
- package/dist/compiler/module-resolution-optimizer.js +35 -20
- package/dist/compiler/parser.js +12 -0
- package/dist/compiler/performance-monitor.js +73 -61
- package/dist/compiler/pipeline/build-pipeline.js +139 -0
- package/dist/compiler/pipeline/core-plugins.js +230 -0
- package/dist/compiler/pipeline/module-graph.js +75 -0
- package/dist/compiler/pipeline/plugin-driver.js +99 -0
- package/dist/compiler/pipeline/types.js +14 -0
- package/dist/compiler/tailwindcss.js +12 -0
- package/dist/compiler/transform-optimizer.js +12 -0
- package/dist/compiler/transformTStoJS.js +38 -5
- package/dist/compiler/transforms.js +234 -16
- package/dist/compiler/typescript-compiler.js +12 -0
- package/dist/compiler/typescript-error-parser.js +12 -0
- package/dist/compiler/typescript-manager.js +15 -1
- package/dist/compiler/typescript-sync-validator.js +45 -31
- package/dist/compiler/typescript-worker-pool.js +12 -0
- package/dist/compiler/typescript-worker-thread.cjs +482 -475
- package/dist/compiler/typescript-worker.js +12 -0
- package/dist/compiler/vuejs.js +73 -47
- package/dist/config.js +14 -0
- package/dist/hrm/VueHRM.js +484 -359
- package/dist/hrm/errorScreen.js +95 -83
- package/dist/hrm/getInstanciaVue.js +325 -313
- package/dist/hrm/initHRM.js +736 -586
- package/dist/hrm/versaHMR.js +317 -0
- package/dist/main.js +23 -3
- package/dist/servicios/browserSync.js +127 -6
- package/dist/servicios/file-watcher.js +139 -8
- package/dist/servicios/logger.js +12 -0
- package/dist/servicios/readConfig.js +141 -54
- package/dist/servicios/versacompile.config.types.js +14 -0
- package/dist/utils/excluded-modules.js +12 -0
- package/dist/utils/module-resolver.js +86 -40
- package/dist/utils/promptUser.js +12 -0
- package/dist/utils/proxyValidator.js +12 -0
- package/dist/utils/resolve-bin.js +12 -0
- package/dist/utils/utils.js +12 -0
- package/dist/utils/vue-types-setup.js +260 -248
- package/dist/wrappers/eslint-node.js +15 -1
- package/dist/wrappers/oxlint-node.js +15 -1
- package/dist/wrappers/tailwind-node.js +12 -0
- 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
|
+
});
|
package/dist/compiler/compile.js
CHANGED
|
@@ -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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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} │ `) +
|
|
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 &&
|
|
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}`);
|
package/dist/compiler/linter.js
CHANGED
|
@@ -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';
|
package/dist/compiler/minify.js
CHANGED
|
@@ -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';
|