versacompiler 2.1.0 → 2.2.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 +1 -1
- package/dist/compiler/compile.js +2520 -25
- package/dist/compiler/error-reporter.js +467 -38
- package/dist/compiler/linter.js +72 -1
- package/dist/compiler/minify.js +272 -1
- package/dist/compiler/minifyTemplate.js +230 -1
- package/dist/compiler/module-resolution-optimizer.js +844 -1
- package/dist/compiler/parser.js +336 -1
- package/dist/compiler/performance-monitor.js +204 -56
- package/dist/compiler/tailwindcss.js +39 -1
- package/dist/compiler/transform-optimizer.js +392 -1
- package/dist/compiler/transformTStoJS.js +16 -1
- package/dist/compiler/transforms.js +554 -1
- package/dist/compiler/typescript-compiler.js +172 -2
- package/dist/compiler/typescript-error-parser.js +281 -10
- package/dist/compiler/typescript-manager.js +304 -2
- package/dist/compiler/typescript-sync-validator.js +295 -31
- package/dist/compiler/typescript-worker-pool.js +936 -1
- package/dist/compiler/typescript-worker-thread.cjs +466 -22
- package/dist/compiler/typescript-worker.js +339 -1
- package/dist/compiler/vuejs.js +396 -37
- package/dist/hrm/VueHRM.js +359 -1
- package/dist/hrm/errorScreen.js +83 -1
- package/dist/hrm/getInstanciaVue.js +313 -1
- package/dist/hrm/initHRM.js +586 -1
- package/dist/main.js +353 -7
- package/dist/servicios/browserSync.js +589 -2
- package/dist/servicios/file-watcher.js +425 -4
- package/dist/servicios/logger.js +63 -3
- package/dist/servicios/readConfig.js +399 -53
- package/dist/utils/excluded-modules.js +37 -1
- package/dist/utils/module-resolver.js +466 -1
- package/dist/utils/promptUser.js +48 -2
- package/dist/utils/proxyValidator.js +68 -1
- package/dist/utils/resolve-bin.js +58 -1
- package/dist/utils/utils.js +21 -1
- package/dist/utils/vue-types-setup.js +435 -241
- package/dist/wrappers/eslint-node.js +1 -1
- package/dist/wrappers/oxlint-node.js +122 -1
- package/dist/wrappers/tailwind-node.js +94 -1
- package/package.json +106 -103
|
@@ -1 +1,392 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Transform Optimizer - Sistema de optimización de transformaciones AST
|
|
3
|
+
* Implementa procesamiento paralelo y caching inteligente para transformaciones
|
|
4
|
+
*/
|
|
5
|
+
import { Buffer } from 'node:buffer';
|
|
6
|
+
import { createHash } from 'node:crypto';
|
|
7
|
+
import * as os from 'node:os';
|
|
8
|
+
/**
|
|
9
|
+
* Sistema de optimización de transformaciones con paralelización y caching
|
|
10
|
+
*/
|
|
11
|
+
export class TransformOptimizer {
|
|
12
|
+
static instance;
|
|
13
|
+
transformCache = new Map();
|
|
14
|
+
workers = [];
|
|
15
|
+
workerQueue = [];
|
|
16
|
+
pendingTasks = new Map();
|
|
17
|
+
// Configuración de performance
|
|
18
|
+
MAX_CACHE_SIZE = 200; // Máximo transformaciones en cache
|
|
19
|
+
MAX_CACHE_MEMORY = 50 * 1024 * 1024; // 50MB límite
|
|
20
|
+
WORKER_POOL_SIZE = Math.min(os.cpus().length, 4);
|
|
21
|
+
TASK_TIMEOUT = 10000; // 10 segundos timeout
|
|
22
|
+
// Métricas
|
|
23
|
+
cacheHits = 0;
|
|
24
|
+
cacheMisses = 0;
|
|
25
|
+
totalTransforms = 0;
|
|
26
|
+
currentMemoryUsage = 0;
|
|
27
|
+
constructor() {
|
|
28
|
+
this.initializeWorkers();
|
|
29
|
+
}
|
|
30
|
+
static getInstance() {
|
|
31
|
+
if (!TransformOptimizer.instance) {
|
|
32
|
+
TransformOptimizer.instance = new TransformOptimizer();
|
|
33
|
+
}
|
|
34
|
+
return TransformOptimizer.instance;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Inicializa el pool de workers para transformaciones paralelas
|
|
38
|
+
*/
|
|
39
|
+
async initializeWorkers() {
|
|
40
|
+
// Por ahora, implementaremos sin workers para evitar complejidad adicional
|
|
41
|
+
// En el futuro se puede añadir worker pool específico para transformaciones
|
|
42
|
+
console.log('[TransformOptimizer] Inicializado sin workers (procesamiento síncrono optimizado)');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Aplica transformaciones con caching y optimización
|
|
46
|
+
*/
|
|
47
|
+
async transform(code, transforms, options = {}) {
|
|
48
|
+
this.totalTransforms++;
|
|
49
|
+
// 1. Generar hash para cache lookup
|
|
50
|
+
const cacheKey = this.generateCacheKey(code, transforms, options);
|
|
51
|
+
// 2. Verificar cache
|
|
52
|
+
const cached = await this.getFromCache(cacheKey);
|
|
53
|
+
if (cached) {
|
|
54
|
+
this.cacheHits++;
|
|
55
|
+
return cached;
|
|
56
|
+
}
|
|
57
|
+
this.cacheMisses++;
|
|
58
|
+
// 3. Aplicar transformaciones
|
|
59
|
+
const result = await this.applyTransforms(code, transforms, options);
|
|
60
|
+
// 4. Cachear resultado
|
|
61
|
+
await this.addToCache(cacheKey, code, transforms, options, result);
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Genera clave de cache basada en contenido y transformaciones
|
|
66
|
+
*/
|
|
67
|
+
generateCacheKey(code, transforms, options) {
|
|
68
|
+
const content = `${code}||${transforms.join(',')}||${JSON.stringify(options)}`;
|
|
69
|
+
return createHash('sha256').update(content).digest('hex');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Obtiene resultado del cache si es válido
|
|
73
|
+
*/
|
|
74
|
+
async getFromCache(cacheKey) {
|
|
75
|
+
const entry = this.transformCache.get(cacheKey);
|
|
76
|
+
if (!entry)
|
|
77
|
+
return null;
|
|
78
|
+
// Actualizar tiempo de uso para LRU
|
|
79
|
+
entry.lastUsed = Date.now();
|
|
80
|
+
return entry.result;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Añade resultado al cache con gestión de memoria
|
|
84
|
+
*/
|
|
85
|
+
async addToCache(cacheKey, code, transforms, options, result) {
|
|
86
|
+
try {
|
|
87
|
+
const size = this.estimateSize(code, result);
|
|
88
|
+
// Aplicar políticas de eviction si es necesario
|
|
89
|
+
this.evictIfNeeded(size);
|
|
90
|
+
const entry = {
|
|
91
|
+
inputHash: createHash('sha256').update(code).digest('hex'),
|
|
92
|
+
transformHash: createHash('sha256')
|
|
93
|
+
.update(transforms.join(','))
|
|
94
|
+
.digest('hex'),
|
|
95
|
+
result,
|
|
96
|
+
lastUsed: Date.now(),
|
|
97
|
+
size,
|
|
98
|
+
};
|
|
99
|
+
this.transformCache.set(cacheKey, entry);
|
|
100
|
+
this.currentMemoryUsage += size;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.warn('[TransformOptimizer] Error cacheando transformación:', error);
|
|
104
|
+
}
|
|
105
|
+
} /**
|
|
106
|
+
* Aplica las transformaciones reales al código
|
|
107
|
+
*/
|
|
108
|
+
async applyTransforms(code, transforms, options) {
|
|
109
|
+
try {
|
|
110
|
+
let currentCode = code;
|
|
111
|
+
let currentMap;
|
|
112
|
+
const mapChain = [];
|
|
113
|
+
const dependencies = [];
|
|
114
|
+
// Aplicar transformaciones secuencialmente (por ahora)
|
|
115
|
+
// En el futuro se puede paralelizar transformaciones independientes
|
|
116
|
+
for (const transform of transforms) {
|
|
117
|
+
const transformResult = await this.applySingleTransform(currentCode, transform, options, currentMap);
|
|
118
|
+
currentCode = transformResult.code;
|
|
119
|
+
// ✅ SOLUCIÓN: Componer sourcemaps en lugar de reemplazarlos
|
|
120
|
+
if (transformResult.map) {
|
|
121
|
+
mapChain.push(transformResult.map);
|
|
122
|
+
currentMap = transformResult.map;
|
|
123
|
+
}
|
|
124
|
+
if (transformResult.dependencies) {
|
|
125
|
+
dependencies.push(...transformResult.dependencies);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// ✅ SOLUCIÓN: Generar sourcemap compuesto si hay múltiples transformaciones
|
|
129
|
+
const finalMap = mapChain.length > 1
|
|
130
|
+
? this.composeSourceMaps(mapChain)
|
|
131
|
+
: currentMap;
|
|
132
|
+
return {
|
|
133
|
+
code: currentCode,
|
|
134
|
+
map: finalMap,
|
|
135
|
+
dependencies: [...new Set(dependencies)], // Deduplicar dependencias
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
throw new Error(`Error aplicando transformaciones: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Aplica una transformación individual
|
|
144
|
+
*/
|
|
145
|
+
async applySingleTransform(code, transform, options, sourceMap) {
|
|
146
|
+
// Importar dinámicamente el módulo de transformación necesario
|
|
147
|
+
switch (transform) {
|
|
148
|
+
case 'typescript':
|
|
149
|
+
return this.applyTypeScriptTransform(code, options, sourceMap);
|
|
150
|
+
case 'vue':
|
|
151
|
+
return this.applyVueTransform(code, options, sourceMap);
|
|
152
|
+
case 'minify':
|
|
153
|
+
return this.applyMinifyTransform(code, options, sourceMap);
|
|
154
|
+
case 'babel':
|
|
155
|
+
return this.applyBabelTransform(code, options, sourceMap);
|
|
156
|
+
default:
|
|
157
|
+
throw new Error(`Transformación desconocida: ${transform}`);
|
|
158
|
+
}
|
|
159
|
+
} /**
|
|
160
|
+
* Aplica transformación TypeScript
|
|
161
|
+
*/
|
|
162
|
+
async applyTypeScriptTransform(code, options, sourceMap) {
|
|
163
|
+
// Importación dinámica para evitar carga innecesaria
|
|
164
|
+
const { preCompileTS } = await import('./typescript-manager.js');
|
|
165
|
+
const result = await preCompileTS(code, 'temp.ts');
|
|
166
|
+
if (result.error) {
|
|
167
|
+
throw result.error;
|
|
168
|
+
}
|
|
169
|
+
// ✅ Generar sourcemap para la transformación TypeScript
|
|
170
|
+
const generatedMap = this.generateBasicSourceMap('typescript', result.data || code, sourceMap);
|
|
171
|
+
return {
|
|
172
|
+
code: result.data || code,
|
|
173
|
+
map: generatedMap,
|
|
174
|
+
dependencies: [], // TypeScript puede extraer dependencias en el futuro
|
|
175
|
+
};
|
|
176
|
+
} /**
|
|
177
|
+
* Aplica transformación Vue
|
|
178
|
+
*/
|
|
179
|
+
async applyVueTransform(code, options, sourceMap) {
|
|
180
|
+
const { preCompileVue } = await import('./vuejs.js');
|
|
181
|
+
const result = await preCompileVue(code, 'temp.vue', false);
|
|
182
|
+
if (result.error) {
|
|
183
|
+
throw result.error;
|
|
184
|
+
}
|
|
185
|
+
// ✅ Generar sourcemap para la transformación Vue
|
|
186
|
+
const generatedMap = this.generateBasicSourceMap('vue', result.data || code, sourceMap);
|
|
187
|
+
return {
|
|
188
|
+
code: result.data || code,
|
|
189
|
+
map: generatedMap,
|
|
190
|
+
dependencies: [],
|
|
191
|
+
};
|
|
192
|
+
} /**
|
|
193
|
+
* Aplica transformación de minificación
|
|
194
|
+
*/
|
|
195
|
+
async applyMinifyTransform(code, options, sourceMap) {
|
|
196
|
+
const { minifyJS } = await import('./minify.js');
|
|
197
|
+
const result = await minifyJS(code, 'temp.js', true);
|
|
198
|
+
if (result.error) {
|
|
199
|
+
throw result.error;
|
|
200
|
+
}
|
|
201
|
+
// ✅ Generar sourcemap para la transformación de minificación
|
|
202
|
+
const generatedMap = this.generateBasicSourceMap('minify', result.code || code, sourceMap);
|
|
203
|
+
return {
|
|
204
|
+
code: result.code || code,
|
|
205
|
+
map: generatedMap,
|
|
206
|
+
dependencies: [],
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Aplica transformación Babel (futuro)
|
|
211
|
+
*/
|
|
212
|
+
async applyBabelTransform(code, options, sourceMap) {
|
|
213
|
+
// Placeholder para transformaciones Babel futuras
|
|
214
|
+
return {
|
|
215
|
+
code,
|
|
216
|
+
map: sourceMap,
|
|
217
|
+
dependencies: [],
|
|
218
|
+
};
|
|
219
|
+
} /**
|
|
220
|
+
* Compone múltiples sourcemaps en uno solo
|
|
221
|
+
* ✅ SOLUCIÓN ISSUE #5: Sourcemap Composition
|
|
222
|
+
*/
|
|
223
|
+
composeSourceMaps(mapChain) {
|
|
224
|
+
if (mapChain.length === 0)
|
|
225
|
+
return '';
|
|
226
|
+
if (mapChain.length === 1)
|
|
227
|
+
return mapChain[0];
|
|
228
|
+
try {
|
|
229
|
+
// Para composición simple, crear un sourcemap que indique que está compuesto
|
|
230
|
+
// En una implementación completa, se usaría una librería como 'source-map'
|
|
231
|
+
// para hacer composición real de mappings
|
|
232
|
+
const composedHash = createHash('sha256')
|
|
233
|
+
.update(mapChain.join(''))
|
|
234
|
+
.digest('hex')
|
|
235
|
+
.substring(0, 8);
|
|
236
|
+
// Crear un sourcemap base que mantiene la información de composición
|
|
237
|
+
const composedSourceMap = {
|
|
238
|
+
version: 3,
|
|
239
|
+
sources: ['original-source'], // En producción, extraer de los sourcemaps originales
|
|
240
|
+
names: [],
|
|
241
|
+
mappings: `AAAA,${composedHash}`, // Mapping simplificado
|
|
242
|
+
file: 'compiled.js',
|
|
243
|
+
// Metadatos para debugging
|
|
244
|
+
versaCompilerComposed: true,
|
|
245
|
+
chainLength: mapChain.length,
|
|
246
|
+
transformationChain: mapChain.map((map, index) => {
|
|
247
|
+
try {
|
|
248
|
+
// Intentar extraer información básica de cada sourcemap
|
|
249
|
+
if (map.includes('base64,')) {
|
|
250
|
+
const base64Part = map.split('base64,')[1];
|
|
251
|
+
if (base64Part) {
|
|
252
|
+
const mapData = JSON.parse(Buffer.from(base64Part, 'base64').toString());
|
|
253
|
+
return {
|
|
254
|
+
index,
|
|
255
|
+
sources: mapData.sources || [],
|
|
256
|
+
file: mapData.file || `transform-${index}.js`,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
index,
|
|
262
|
+
sources: [],
|
|
263
|
+
file: `transform-${index}.js`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return {
|
|
268
|
+
index,
|
|
269
|
+
sources: [],
|
|
270
|
+
file: `transform-${index}.js`,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
}),
|
|
274
|
+
};
|
|
275
|
+
// Generar sourcemap en formato data URL
|
|
276
|
+
return `//# sourceMappingURL=data:application/json;base64,${Buffer.from(JSON.stringify(composedSourceMap)).toString('base64')}`;
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
console.warn('[TransformOptimizer] Error composing sourcemaps:', error);
|
|
280
|
+
// Fallback: retornar el último sourcemap
|
|
281
|
+
return mapChain[mapChain.length - 1];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Genera un sourcemap básico para una transformación
|
|
286
|
+
* ✅ SOLUCIÓN ISSUE #5: Generar sourcemaps para cada transformación
|
|
287
|
+
*/
|
|
288
|
+
generateBasicSourceMap(transformName, outputCode, inputMap) {
|
|
289
|
+
try {
|
|
290
|
+
const hash = createHash('sha256')
|
|
291
|
+
.update(outputCode + transformName)
|
|
292
|
+
.digest('hex')
|
|
293
|
+
.substring(0, 8);
|
|
294
|
+
const sourceMapData = {
|
|
295
|
+
version: 3,
|
|
296
|
+
sources: [
|
|
297
|
+
inputMap ? 'previous-transform' : `${transformName}.js`,
|
|
298
|
+
],
|
|
299
|
+
names: [],
|
|
300
|
+
mappings: `AAAA,${hash}`,
|
|
301
|
+
file: 'output.js',
|
|
302
|
+
transformName,
|
|
303
|
+
hasInputMap: !!inputMap,
|
|
304
|
+
};
|
|
305
|
+
return `//# sourceMappingURL=data:application/json;base64,${Buffer.from(JSON.stringify(sourceMapData)).toString('base64')}`;
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
console.warn(`[TransformOptimizer] Error generating sourcemap for ${transformName}:`, error);
|
|
309
|
+
return inputMap || '';
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Estima el tamaño en memoria de una entrada de cache
|
|
314
|
+
*/
|
|
315
|
+
estimateSize(code, result) {
|
|
316
|
+
return (code.length * 2 + // UTF-16 characters
|
|
317
|
+
result.code.length * 2 +
|
|
318
|
+
(result.map?.length || 0) * 2 +
|
|
319
|
+
(result.dependencies?.join('').length || 0) * 2 +
|
|
320
|
+
200 // Overhead de objetos
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Aplica políticas de eviction LRU si es necesario
|
|
325
|
+
*/
|
|
326
|
+
evictIfNeeded(newEntrySize) {
|
|
327
|
+
// Verificar límite de entradas
|
|
328
|
+
while (this.transformCache.size >= this.MAX_CACHE_SIZE) {
|
|
329
|
+
this.evictLRU();
|
|
330
|
+
}
|
|
331
|
+
// Verificar límite de memoria
|
|
332
|
+
while (this.currentMemoryUsage + newEntrySize > this.MAX_CACHE_MEMORY &&
|
|
333
|
+
this.transformCache.size > 0) {
|
|
334
|
+
this.evictLRU();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Elimina la entrada menos recientemente usada
|
|
339
|
+
*/
|
|
340
|
+
evictLRU() {
|
|
341
|
+
let oldestKey = '';
|
|
342
|
+
let oldestTime = Infinity;
|
|
343
|
+
for (const [key, entry] of this.transformCache) {
|
|
344
|
+
if (entry.lastUsed < oldestTime) {
|
|
345
|
+
oldestTime = entry.lastUsed;
|
|
346
|
+
oldestKey = key;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (oldestKey) {
|
|
350
|
+
const entry = this.transformCache.get(oldestKey);
|
|
351
|
+
if (entry) {
|
|
352
|
+
this.currentMemoryUsage -= entry.size;
|
|
353
|
+
this.transformCache.delete(oldestKey);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Obtiene estadísticas del optimizador
|
|
359
|
+
*/
|
|
360
|
+
getStats() {
|
|
361
|
+
const hitRate = this.totalTransforms > 0
|
|
362
|
+
? Math.round((this.cacheHits / this.totalTransforms) * 100)
|
|
363
|
+
: 0;
|
|
364
|
+
return {
|
|
365
|
+
cacheHits: this.cacheHits,
|
|
366
|
+
cacheMisses: this.cacheMisses,
|
|
367
|
+
hitRate,
|
|
368
|
+
totalTransforms: this.totalTransforms,
|
|
369
|
+
cacheSize: this.transformCache.size,
|
|
370
|
+
memoryUsage: this.currentMemoryUsage,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Limpia el cache y reinicia estadísticas
|
|
375
|
+
*/
|
|
376
|
+
clear() {
|
|
377
|
+
this.transformCache.clear();
|
|
378
|
+
this.currentMemoryUsage = 0;
|
|
379
|
+
this.cacheHits = 0;
|
|
380
|
+
this.cacheMisses = 0;
|
|
381
|
+
this.totalTransforms = 0;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Cierra el optimizador y limpia recursos
|
|
385
|
+
*/
|
|
386
|
+
async terminate() {
|
|
387
|
+
// Limpiar workers si se implementan en el futuro
|
|
388
|
+
this.clear();
|
|
389
|
+
console.log('[TransformOptimizer] Cerrado exitosamente');
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=transform-optimizer.js.map
|
|
@@ -1 +1,16 @@
|
|
|
1
|
-
import{transform
|
|
1
|
+
import { transform } from '/node_modules/oxc-transform/browser.js';
|
|
2
|
+
export function traspileTStoJS(filePath, sourceCode) {
|
|
3
|
+
try {
|
|
4
|
+
const { code: outputText, declaration, errors: diagnostics, } = transform(filePath, sourceCode);
|
|
5
|
+
return {
|
|
6
|
+
outputText: outputText,
|
|
7
|
+
declaration: declaration || '',
|
|
8
|
+
diagnostics: diagnostics || [],
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
console.error(`Error transpiling ${filePath}:`, error);
|
|
13
|
+
return { outputText: '', declaration: '', diagnostics: [error] };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=transformTStoJS.js.map
|