versacompiler 2.0.8 → 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 -26
- 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 -0
- 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 -41
- 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 +587 -5
- package/dist/servicios/file-watcher.js +425 -4
- package/dist/servicios/logger.js +63 -3
- package/dist/servicios/readConfig.js +399 -105
- 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 +147 -1
- package/dist/wrappers/oxlint-node.js +122 -1
- package/dist/wrappers/tailwind-node.js +94 -1
- package/package.json +39 -42
package/dist/compiler/parser.js
CHANGED
|
@@ -1 +1,336 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { statSync } from 'node:fs';
|
|
3
|
+
import { open, readFile } from 'node:fs/promises';
|
|
4
|
+
import { parseSync } from 'oxc-parser';
|
|
5
|
+
class FileContentCache {
|
|
6
|
+
static instance;
|
|
7
|
+
cache = new Map();
|
|
8
|
+
MAX_CACHE_SIZE = 500; // Máximo archivos en cache
|
|
9
|
+
MAX_FILE_SIZE_TO_CACHE = 1024 * 1024; // 1MB - solo cachear archivos < 1MB
|
|
10
|
+
CACHE_TTL = 5 * 60 * 1000; // 5 minutos
|
|
11
|
+
// Métricas
|
|
12
|
+
cacheHits = 0;
|
|
13
|
+
cacheMisses = 0;
|
|
14
|
+
totalReads = 0;
|
|
15
|
+
static getInstance() {
|
|
16
|
+
if (!FileContentCache.instance) {
|
|
17
|
+
FileContentCache.instance = new FileContentCache();
|
|
18
|
+
}
|
|
19
|
+
return FileContentCache.instance;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Lee archivo con cache inteligente
|
|
23
|
+
*/
|
|
24
|
+
async readFileWithCache(filename) {
|
|
25
|
+
this.totalReads++;
|
|
26
|
+
// Obtener stats del archivo (más rápido que leerlo)
|
|
27
|
+
const stats = statSync(filename);
|
|
28
|
+
// No cachear archivos muy grandes
|
|
29
|
+
if (stats.size > this.MAX_FILE_SIZE_TO_CACHE) {
|
|
30
|
+
this.cacheMisses++;
|
|
31
|
+
return await this.fastReadFile(filename, stats.size);
|
|
32
|
+
}
|
|
33
|
+
const cached = this.cache.get(filename);
|
|
34
|
+
// Verificar si cache es válido (mismo mtime y no expirado)
|
|
35
|
+
if (cached &&
|
|
36
|
+
cached.mtimeMs === stats.mtimeMs &&
|
|
37
|
+
Date.now() - cached.timestamp < this.CACHE_TTL) {
|
|
38
|
+
this.cacheHits++;
|
|
39
|
+
cached.timestamp = Date.now(); // LRU update
|
|
40
|
+
return cached.content;
|
|
41
|
+
}
|
|
42
|
+
// Cache miss - leer archivo
|
|
43
|
+
this.cacheMisses++;
|
|
44
|
+
const content = await this.fastReadFile(filename, stats.size);
|
|
45
|
+
// Cachear si está dentro de límites
|
|
46
|
+
if (this.cache.size >= this.MAX_CACHE_SIZE) {
|
|
47
|
+
this.evictLRU();
|
|
48
|
+
}
|
|
49
|
+
this.cache.set(filename, {
|
|
50
|
+
content,
|
|
51
|
+
mtimeMs: stats.mtimeMs,
|
|
52
|
+
size: stats.size,
|
|
53
|
+
timestamp: Date.now(),
|
|
54
|
+
});
|
|
55
|
+
return content;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Lectura ultra-rápida con buffer pre-allocated
|
|
59
|
+
*/
|
|
60
|
+
async fastReadFile(filename, size) {
|
|
61
|
+
// Para archivos pequeños, usar el método tradicional (más rápido en ese caso)
|
|
62
|
+
if (size < 16384) {
|
|
63
|
+
// 16KB
|
|
64
|
+
return await readFile(filename, 'utf-8');
|
|
65
|
+
}
|
|
66
|
+
// Para archivos grandes, usar open + read con buffer pre-allocated
|
|
67
|
+
let fileHandle;
|
|
68
|
+
try {
|
|
69
|
+
fileHandle = await open(filename, 'r');
|
|
70
|
+
const buffer = Buffer.allocUnsafe(size);
|
|
71
|
+
await fileHandle.read(buffer, 0, size, 0);
|
|
72
|
+
return buffer.toString('utf-8');
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
await fileHandle?.close();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Elimina entrada LRU
|
|
80
|
+
*/
|
|
81
|
+
evictLRU() {
|
|
82
|
+
let oldestKey = '';
|
|
83
|
+
let oldestTime = Infinity;
|
|
84
|
+
for (const [key, entry] of this.cache) {
|
|
85
|
+
if (entry.timestamp < oldestTime) {
|
|
86
|
+
oldestTime = entry.timestamp;
|
|
87
|
+
oldestKey = key;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (oldestKey) {
|
|
91
|
+
this.cache.delete(oldestKey);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Invalida cache de un archivo específico
|
|
96
|
+
*/
|
|
97
|
+
invalidate(filename) {
|
|
98
|
+
this.cache.delete(filename);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Limpia cache completo
|
|
102
|
+
*/
|
|
103
|
+
clear() {
|
|
104
|
+
this.cache.clear();
|
|
105
|
+
this.cacheHits = 0;
|
|
106
|
+
this.cacheMisses = 0;
|
|
107
|
+
this.totalReads = 0;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Obtiene estadísticas
|
|
111
|
+
*/
|
|
112
|
+
getStats() {
|
|
113
|
+
const hitRate = this.totalReads > 0
|
|
114
|
+
? Math.round((this.cacheHits / this.totalReads) * 100)
|
|
115
|
+
: 0;
|
|
116
|
+
return {
|
|
117
|
+
cacheHits: this.cacheHits,
|
|
118
|
+
cacheMisses: this.cacheMisses,
|
|
119
|
+
hitRate,
|
|
120
|
+
totalReads: this.totalReads,
|
|
121
|
+
cacheSize: this.cache.size,
|
|
122
|
+
maxCacheSize: this.MAX_CACHE_SIZE,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Instancia global del cache de archivos
|
|
127
|
+
const fileCache = FileContentCache.getInstance();
|
|
128
|
+
class ParserASTCache {
|
|
129
|
+
static instance;
|
|
130
|
+
cache = new Map();
|
|
131
|
+
MAX_CACHE_SIZE = 150; // Máximo ASTs en cache
|
|
132
|
+
MAX_CACHE_MEMORY = 30 * 1024 * 1024; // 30MB límite
|
|
133
|
+
CACHE_TTL = 10 * 60 * 1000; // 10 minutos
|
|
134
|
+
currentMemoryUsage = 0;
|
|
135
|
+
// Métricas
|
|
136
|
+
cacheHits = 0;
|
|
137
|
+
cacheMisses = 0;
|
|
138
|
+
totalParses = 0;
|
|
139
|
+
static getInstance() {
|
|
140
|
+
if (!ParserASTCache.instance) {
|
|
141
|
+
ParserASTCache.instance = new ParserASTCache();
|
|
142
|
+
}
|
|
143
|
+
return ParserASTCache.instance;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Genera un hash del contenido del código
|
|
147
|
+
*/
|
|
148
|
+
generateContentHash(code, astType) {
|
|
149
|
+
return createHash('sha256').update(`${code}:${astType}`).digest('hex');
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Estima el tamaño en memoria de un AST
|
|
153
|
+
*/
|
|
154
|
+
estimateASTSize(ast) {
|
|
155
|
+
try {
|
|
156
|
+
return JSON.stringify(ast).length * 2; // UTF-16 characters
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return 10000; // Estimación por defecto
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Obtiene AST desde cache o lo parsea
|
|
164
|
+
*/
|
|
165
|
+
async getOrParseAST(filename, code, astType = 'js') {
|
|
166
|
+
this.totalParses++;
|
|
167
|
+
const contentHash = this.generateContentHash(code, astType);
|
|
168
|
+
const cacheKey = `${filename}:${contentHash}`;
|
|
169
|
+
// Verificar cache
|
|
170
|
+
const cached = this.cache.get(cacheKey);
|
|
171
|
+
if (cached && Date.now() - cached.timestamp < this.CACHE_TTL) {
|
|
172
|
+
// Actualizar timestamp de uso (LRU)
|
|
173
|
+
cached.timestamp = Date.now();
|
|
174
|
+
this.cacheHits++;
|
|
175
|
+
return {
|
|
176
|
+
ast: cached.ast,
|
|
177
|
+
cached: true,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
// Cache miss - parsear nuevo AST
|
|
181
|
+
this.cacheMisses++;
|
|
182
|
+
const ast = parseSync(filename, code, {
|
|
183
|
+
sourceType: 'module',
|
|
184
|
+
showSemanticErrors: true,
|
|
185
|
+
astType,
|
|
186
|
+
});
|
|
187
|
+
// Cachear resultado si es válido
|
|
188
|
+
if (ast && !ast.errors?.length) {
|
|
189
|
+
this.addToCache(cacheKey, ast, astType);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
ast,
|
|
193
|
+
cached: false,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Añade AST al cache con gestión de memoria
|
|
198
|
+
*/
|
|
199
|
+
addToCache(cacheKey, ast, astType) {
|
|
200
|
+
try {
|
|
201
|
+
const size = this.estimateASTSize(ast);
|
|
202
|
+
// Aplicar políticas de eviction si es necesario
|
|
203
|
+
this.evictIfNeeded(size);
|
|
204
|
+
const entry = {
|
|
205
|
+
contentHash: cacheKey.split(':')[1] || '',
|
|
206
|
+
ast,
|
|
207
|
+
astType,
|
|
208
|
+
timestamp: Date.now(),
|
|
209
|
+
size,
|
|
210
|
+
};
|
|
211
|
+
this.cache.set(cacheKey, entry);
|
|
212
|
+
this.currentMemoryUsage += size;
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
console.warn('[ParserASTCache] Error cacheando AST:', error);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Aplica políticas de eviction LRU si es necesario
|
|
220
|
+
*/
|
|
221
|
+
evictIfNeeded(newEntrySize) {
|
|
222
|
+
// Verificar límite de entradas
|
|
223
|
+
while (this.cache.size >= this.MAX_CACHE_SIZE) {
|
|
224
|
+
this.evictLRU();
|
|
225
|
+
}
|
|
226
|
+
// Verificar límite de memoria
|
|
227
|
+
while (this.currentMemoryUsage + newEntrySize > this.MAX_CACHE_MEMORY &&
|
|
228
|
+
this.cache.size > 0) {
|
|
229
|
+
this.evictLRU();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Elimina la entrada menos recientemente usada
|
|
234
|
+
*/
|
|
235
|
+
evictLRU() {
|
|
236
|
+
let oldestKey = '';
|
|
237
|
+
let oldestTime = Infinity;
|
|
238
|
+
for (const [key, entry] of this.cache) {
|
|
239
|
+
if (entry.timestamp < oldestTime) {
|
|
240
|
+
oldestTime = entry.timestamp;
|
|
241
|
+
oldestKey = key;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (oldestKey) {
|
|
245
|
+
const entry = this.cache.get(oldestKey);
|
|
246
|
+
if (entry) {
|
|
247
|
+
this.currentMemoryUsage -= entry.size;
|
|
248
|
+
this.cache.delete(oldestKey);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Limpia entradas expiradas
|
|
254
|
+
*/
|
|
255
|
+
cleanExpired() {
|
|
256
|
+
const now = Date.now();
|
|
257
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
258
|
+
if (now - entry.timestamp > this.CACHE_TTL) {
|
|
259
|
+
this.currentMemoryUsage -= entry.size;
|
|
260
|
+
this.cache.delete(key);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Obtiene estadísticas del cache
|
|
266
|
+
*/
|
|
267
|
+
getStats() {
|
|
268
|
+
const hitRate = this.totalParses > 0
|
|
269
|
+
? Math.round((this.cacheHits / this.totalParses) * 100)
|
|
270
|
+
: 0;
|
|
271
|
+
return {
|
|
272
|
+
cacheHits: this.cacheHits,
|
|
273
|
+
cacheMisses: this.cacheMisses,
|
|
274
|
+
hitRate,
|
|
275
|
+
totalParses: this.totalParses,
|
|
276
|
+
cacheSize: this.cache.size,
|
|
277
|
+
maxCacheSize: this.MAX_CACHE_SIZE,
|
|
278
|
+
memoryUsage: this.currentMemoryUsage,
|
|
279
|
+
maxMemoryUsage: this.MAX_CACHE_MEMORY,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Limpia todo el cache
|
|
284
|
+
*/
|
|
285
|
+
clear() {
|
|
286
|
+
this.cache.clear();
|
|
287
|
+
this.currentMemoryUsage = 0;
|
|
288
|
+
this.cacheHits = 0;
|
|
289
|
+
this.cacheMisses = 0;
|
|
290
|
+
this.totalParses = 0;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Instancia global del cache AST
|
|
294
|
+
const astCache = ParserASTCache.getInstance();
|
|
295
|
+
/**
|
|
296
|
+
* Parses the given JavaScript code using Acorn and returns the Abstract Syntax Tree (AST).
|
|
297
|
+
*
|
|
298
|
+
* @param {string} data - The JavaScript code to be parsed.
|
|
299
|
+
* @returns {Promise<Object|null>} The parsed AST object if successful, or null if an error occurs.
|
|
300
|
+
* @throws {Error} If there is an error during parsing, it logs the error details and stack trace.
|
|
301
|
+
*/
|
|
302
|
+
export const parser = async (filename, code, astType = 'js') => {
|
|
303
|
+
const { ast } = await astCache.getOrParseAST(filename, code, astType);
|
|
304
|
+
return ast;
|
|
305
|
+
};
|
|
306
|
+
export const getCodeFile = async (filename) => {
|
|
307
|
+
try {
|
|
308
|
+
// ✨ Usar cache de archivos para lectura ultra-rápida
|
|
309
|
+
const code = await fileCache.readFileWithCache(filename);
|
|
310
|
+
return { code, error: null };
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
return { code: null, error };
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
// ✨ NUEVAS FUNCIONES: Exportar funcionalidades del cache AST para uso externo
|
|
317
|
+
export const getParserCacheStats = () => {
|
|
318
|
+
return astCache.getStats();
|
|
319
|
+
};
|
|
320
|
+
export const clearParserCache = () => {
|
|
321
|
+
astCache.clear();
|
|
322
|
+
};
|
|
323
|
+
export const cleanExpiredParserCache = () => {
|
|
324
|
+
astCache.cleanExpired();
|
|
325
|
+
};
|
|
326
|
+
// ✨ FUNCIONES: Cache de archivos
|
|
327
|
+
export const getFileContentCacheStats = () => {
|
|
328
|
+
return fileCache.getStats();
|
|
329
|
+
};
|
|
330
|
+
export const clearFileContentCache = () => {
|
|
331
|
+
fileCache.clear();
|
|
332
|
+
};
|
|
333
|
+
export const invalidateFileCache = (filename) => {
|
|
334
|
+
fileCache.invalidate(filename);
|
|
335
|
+
};
|
|
336
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -1,56 +1,204 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Performance Monitor - Sistema centralizado de monitoreo de optimizaciones
|
|
3
|
+
* Reúne todas las métricas de cache y performance del VersaCompiler
|
|
4
|
+
*/
|
|
5
|
+
import { clearBrowserSyncCache, getBrowserSyncCacheStats, } from '../servicios/browserSync.js';
|
|
6
|
+
import { cleanExpiredMinificationCache, clearMinificationCache, getMinificationCacheStats, } from './minify.js';
|
|
7
|
+
import { getModuleResolutionMetrics } from './module-resolution-optimizer.js';
|
|
8
|
+
import { cleanExpiredParserCache, clearFileContentCache, clearParserCache, getFileContentCacheStats, getParserCacheStats, } from './parser.js';
|
|
9
|
+
import { TransformOptimizer } from './transform-optimizer.js';
|
|
10
|
+
import { cleanExpiredVueHMRCache, clearVueHMRCache, getVueHMRCacheStats, } from './vuejs.js';
|
|
11
|
+
export class PerformanceMonitor {
|
|
12
|
+
static instance;
|
|
13
|
+
static getInstance() {
|
|
14
|
+
if (!PerformanceMonitor.instance) {
|
|
15
|
+
PerformanceMonitor.instance = new PerformanceMonitor();
|
|
16
|
+
}
|
|
17
|
+
return PerformanceMonitor.instance;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Obtiene todas las estadísticas de performance de manera unificada
|
|
21
|
+
*/
|
|
22
|
+
getAllStats() {
|
|
23
|
+
const vueHMRCache = getVueHMRCacheStats();
|
|
24
|
+
const parserCache = getParserCacheStats();
|
|
25
|
+
const fileContentCache = getFileContentCacheStats();
|
|
26
|
+
const browserSyncCache = getBrowserSyncCacheStats();
|
|
27
|
+
const minificationCache = getMinificationCacheStats();
|
|
28
|
+
const transformOptimizer = TransformOptimizer.getInstance().getStats();
|
|
29
|
+
const moduleResolution = getModuleResolutionMetrics();
|
|
30
|
+
// Calcular resumen general
|
|
31
|
+
const totalCacheHits = (parserCache.cacheHits || 0) +
|
|
32
|
+
(fileContentCache.cacheHits || 0) +
|
|
33
|
+
(browserSyncCache.cacheHits || 0) +
|
|
34
|
+
(minificationCache.cacheHits || 0) +
|
|
35
|
+
(transformOptimizer.cacheHits || 0) +
|
|
36
|
+
(moduleResolution.cacheHits || 0);
|
|
37
|
+
const totalCacheMisses = (parserCache.cacheMisses || 0) +
|
|
38
|
+
(fileContentCache.cacheMisses || 0) +
|
|
39
|
+
(browserSyncCache.cacheMisses || 0) +
|
|
40
|
+
(minificationCache.cacheMisses || 0) +
|
|
41
|
+
(transformOptimizer.cacheMisses || 0) +
|
|
42
|
+
(moduleResolution.cacheMisses || 0);
|
|
43
|
+
const totalRequests = totalCacheHits + totalCacheMisses;
|
|
44
|
+
const overallHitRate = totalRequests > 0
|
|
45
|
+
? Math.round((totalCacheHits / totalRequests) * 100)
|
|
46
|
+
: 0;
|
|
47
|
+
const totalMemoryUsage = (parserCache.memoryUsage || 0) +
|
|
48
|
+
(browserSyncCache.memoryUsage || 0) +
|
|
49
|
+
(minificationCache.memoryUsage || 0) +
|
|
50
|
+
(transformOptimizer.memoryUsage || 0);
|
|
51
|
+
const totalCacheEntries = (vueHMRCache.size || 0) +
|
|
52
|
+
(parserCache.cacheSize || 0) +
|
|
53
|
+
(fileContentCache.cacheSize || 0) +
|
|
54
|
+
(browserSyncCache.cacheSize || 0) +
|
|
55
|
+
(minificationCache.cacheSize || 0) +
|
|
56
|
+
(transformOptimizer.cacheSize || 0) +
|
|
57
|
+
(moduleResolution.cacheSize || 0);
|
|
58
|
+
return {
|
|
59
|
+
vueHMRCache,
|
|
60
|
+
parserCache,
|
|
61
|
+
fileContentCache,
|
|
62
|
+
browserSyncCache,
|
|
63
|
+
minificationCache,
|
|
64
|
+
transformOptimizer,
|
|
65
|
+
moduleResolution,
|
|
66
|
+
summary: {
|
|
67
|
+
totalCacheHits,
|
|
68
|
+
totalCacheMisses,
|
|
69
|
+
overallHitRate,
|
|
70
|
+
totalMemoryUsage,
|
|
71
|
+
totalCacheEntries,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Genera un reporte detallado de performance
|
|
77
|
+
*/
|
|
78
|
+
generateReport() {
|
|
79
|
+
const stats = this.getAllStats();
|
|
80
|
+
const formatBytes = (bytes) => {
|
|
81
|
+
if (bytes === 0)
|
|
82
|
+
return '0 B';
|
|
83
|
+
const k = 1024;
|
|
84
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
85
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
86
|
+
return (parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]);
|
|
87
|
+
};
|
|
88
|
+
const report = `
|
|
89
|
+
🚀 VERSACOMPILER PERFORMANCE REPORT
|
|
90
|
+
=====================================
|
|
91
|
+
|
|
92
|
+
📊 RESUMEN GENERAL
|
|
93
|
+
Hit Rate Total: ${stats.summary.overallHitRate}%
|
|
94
|
+
Cache Hits: ${stats.summary.totalCacheHits}
|
|
95
|
+
Cache Misses: ${stats.summary.totalCacheMisses}
|
|
96
|
+
Memoria Total: ${formatBytes(stats.summary.totalMemoryUsage)}
|
|
97
|
+
Entradas Cache: ${stats.summary.totalCacheEntries}
|
|
98
|
+
|
|
99
|
+
🎯 VUE HMR CACHE
|
|
100
|
+
Size: ${stats.vueHMRCache.size}/${stats.vueHMRCache.maxSize}
|
|
101
|
+
TTL: ${Math.round(stats.vueHMRCache.ttl / 1000 / 60)}min
|
|
102
|
+
|
|
103
|
+
📝 PARSER AST CACHE
|
|
104
|
+
Hit Rate: ${stats.parserCache.hitRate}%
|
|
105
|
+
Cache Hits: ${stats.parserCache.cacheHits}
|
|
106
|
+
Cache Misses: ${stats.parserCache.cacheMisses}
|
|
107
|
+
Size: ${stats.parserCache.cacheSize}/${stats.parserCache.maxCacheSize}
|
|
108
|
+
Memoria: ${formatBytes(stats.parserCache.memoryUsage)}/${formatBytes(stats.parserCache.maxMemoryUsage)}
|
|
109
|
+
|
|
110
|
+
📖 FILE CONTENT CACHE
|
|
111
|
+
Hit Rate: ${stats.fileContentCache.hitRate}%
|
|
112
|
+
Cache Hits: ${stats.fileContentCache.cacheHits}
|
|
113
|
+
Cache Misses: ${stats.fileContentCache.cacheMisses}
|
|
114
|
+
Size: ${stats.fileContentCache.cacheSize}/${stats.fileContentCache.maxCacheSize}
|
|
115
|
+
|
|
116
|
+
🌐 BROWSERSYNC FILE CACHE
|
|
117
|
+
Hit Rate: ${stats.browserSyncCache.hitRate}%
|
|
118
|
+
Cache Hits: ${stats.browserSyncCache.cacheHits}
|
|
119
|
+
Cache Misses: ${stats.browserSyncCache.cacheMisses}
|
|
120
|
+
Size: ${stats.browserSyncCache.cacheSize}/${stats.browserSyncCache.maxCacheSize}
|
|
121
|
+
Memoria: ${formatBytes(stats.browserSyncCache.memoryUsage)}/${formatBytes(stats.browserSyncCache.maxMemoryUsage)}
|
|
122
|
+
|
|
123
|
+
🗜️ MINIFICATION CACHE
|
|
124
|
+
Hit Rate: ${stats.minificationCache.hitRate}%
|
|
125
|
+
Cache Hits: ${stats.minificationCache.cacheHits}
|
|
126
|
+
Cache Misses: ${stats.minificationCache.cacheMisses}
|
|
127
|
+
Size: ${stats.minificationCache.cacheSize}/${stats.minificationCache.maxCacheSize}
|
|
128
|
+
Memoria: ${formatBytes(stats.minificationCache.memoryUsage)}/${formatBytes(stats.minificationCache.maxMemoryUsage)}
|
|
129
|
+
Compresión Promedio: ${stats.minificationCache.avgCompressionRatio}%
|
|
130
|
+
|
|
131
|
+
🔄 TRANSFORM OPTIMIZER
|
|
132
|
+
Hit Rate: ${stats.transformOptimizer.hitRate}%
|
|
133
|
+
Cache Hits: ${stats.transformOptimizer.cacheHits}
|
|
134
|
+
Cache Misses: ${stats.transformOptimizer.cacheMisses}
|
|
135
|
+
Transformaciones: ${stats.transformOptimizer.totalTransforms}
|
|
136
|
+
Size: ${stats.transformOptimizer.cacheSize}
|
|
137
|
+
Memoria: ${formatBytes(stats.transformOptimizer.memoryUsage)}
|
|
138
|
+
|
|
139
|
+
📦 MODULE RESOLUTION
|
|
140
|
+
Hit Rate: ${stats.moduleResolution.cacheHitRate?.toFixed(1)}%
|
|
141
|
+
Cache Hits: ${stats.moduleResolution.cacheHits}
|
|
142
|
+
Cache Misses: ${stats.moduleResolution.cacheMisses}
|
|
143
|
+
Resoluciones: ${stats.moduleResolution.totalResolutions}
|
|
144
|
+
Índice Módulos: ${stats.moduleResolution.moduleIndexSize}
|
|
145
|
+
Índice Alias: ${stats.moduleResolution.aliasIndexSize}
|
|
146
|
+
Tiempo Promedio: ${stats.moduleResolution.averageResolveTime?.toFixed(2)}ms
|
|
147
|
+
|
|
148
|
+
=====================================
|
|
149
|
+
`;
|
|
150
|
+
return report;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Limpia todos los caches
|
|
154
|
+
*/
|
|
155
|
+
clearAllCaches() {
|
|
156
|
+
clearVueHMRCache();
|
|
157
|
+
clearParserCache();
|
|
158
|
+
clearFileContentCache();
|
|
159
|
+
clearBrowserSyncCache();
|
|
160
|
+
clearMinificationCache();
|
|
161
|
+
TransformOptimizer.getInstance().clear();
|
|
162
|
+
console.log('🧹 Todos los caches han sido limpiados');
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Limpia entradas expiradas de todos los caches
|
|
166
|
+
*/
|
|
167
|
+
cleanExpiredCaches() {
|
|
168
|
+
cleanExpiredVueHMRCache();
|
|
169
|
+
cleanExpiredParserCache();
|
|
170
|
+
cleanExpiredMinificationCache();
|
|
171
|
+
console.log('🧹 Entradas expiradas limpiadas de todos los caches');
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Configura limpieza automática periódica
|
|
175
|
+
*/
|
|
176
|
+
setupAutomaticCleanup(intervalMinutes = 30) {
|
|
177
|
+
setInterval(() => {
|
|
178
|
+
this.cleanExpiredCaches();
|
|
179
|
+
console.log(`🔄 Limpieza automática ejecutada cada ${intervalMinutes} minutos`);
|
|
180
|
+
}, intervalMinutes * 60 * 1000);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Obtiene métricas simplificadas para logging
|
|
184
|
+
*/
|
|
185
|
+
getSimpleMetrics() {
|
|
186
|
+
const stats = this.getAllStats();
|
|
187
|
+
return {
|
|
188
|
+
hitRate: stats.summary.overallHitRate,
|
|
189
|
+
totalHits: stats.summary.totalCacheHits,
|
|
190
|
+
totalMisses: stats.summary.totalCacheMisses,
|
|
191
|
+
memoryUsage: stats.summary.totalMemoryUsage,
|
|
192
|
+
cacheEntries: stats.summary.totalCacheEntries,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Exportar instancia singleton
|
|
197
|
+
export const performanceMonitor = PerformanceMonitor.getInstance();
|
|
198
|
+
// Funciones de conveniencia
|
|
199
|
+
export const getAllPerformanceStats = () => performanceMonitor.getAllStats();
|
|
200
|
+
export const generatePerformanceReport = () => performanceMonitor.generateReport();
|
|
201
|
+
export const clearAllCaches = () => performanceMonitor.clearAllCaches();
|
|
202
|
+
export const cleanExpiredCaches = () => performanceMonitor.cleanExpiredCaches();
|
|
203
|
+
export const getSimpleMetrics = () => performanceMonitor.getSimpleMetrics();
|
|
204
|
+
//# sourceMappingURL=performance-monitor.js.map
|
|
@@ -1 +1,39 @@
|
|
|
1
|
-
import{env
|
|
1
|
+
import { env } from 'node:process';
|
|
2
|
+
import { logger } from '../servicios/logger.js';
|
|
3
|
+
import { TailwindNode } from '../wrappers/tailwind-node.js';
|
|
4
|
+
export async function generateTailwindCSS() {
|
|
5
|
+
if (env.tailwindcss === 'false' ||
|
|
6
|
+
env.tailwindcss === undefined ||
|
|
7
|
+
env.TAILWIND === 'false') {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
const tailwindcssConfig = JSON.parse(env.tailwindcss);
|
|
12
|
+
if (!tailwindcssConfig ||
|
|
13
|
+
!tailwindcssConfig.input ||
|
|
14
|
+
!tailwindcssConfig.output ||
|
|
15
|
+
!tailwindcssConfig.bin) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const tnode = await new TailwindNode({
|
|
19
|
+
binPath: tailwindcssConfig.bin,
|
|
20
|
+
input: tailwindcssConfig.input,
|
|
21
|
+
output: tailwindcssConfig.output,
|
|
22
|
+
minify: env.isProd === 'true',
|
|
23
|
+
});
|
|
24
|
+
return await tnode.run();
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
// Si es un error de JSON parse, devolver false en lugar de lanzar error
|
|
28
|
+
const errorMessage = err instanceof Error
|
|
29
|
+
? err.stderr || err.message
|
|
30
|
+
: String(err);
|
|
31
|
+
logger.error('❌ :Error al compilar Tailwind:', errorMessage);
|
|
32
|
+
if (err instanceof SyntaxError && err.message.includes('JSON')) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
// Para otros errores (como errores de ejecución de TailwindCSS), loggear y relanzar
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=tailwindcss.js.map
|