versacompiler 2.0.7 → 2.0.8

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 (39) hide show
  1. package/dist/compiler/compile.js +26 -2332
  2. package/dist/compiler/error-reporter.js +38 -467
  3. package/dist/compiler/linter.js +1 -72
  4. package/dist/compiler/minify.js +1 -229
  5. package/dist/compiler/module-resolution-optimizer.js +1 -821
  6. package/dist/compiler/parser.js +1 -203
  7. package/dist/compiler/performance-monitor.js +56 -192
  8. package/dist/compiler/tailwindcss.js +1 -39
  9. package/dist/compiler/transform-optimizer.js +1 -392
  10. package/dist/compiler/transformTStoJS.js +1 -16
  11. package/dist/compiler/transforms.js +1 -550
  12. package/dist/compiler/typescript-compiler.js +2 -172
  13. package/dist/compiler/typescript-error-parser.js +10 -281
  14. package/dist/compiler/typescript-manager.js +2 -273
  15. package/dist/compiler/typescript-sync-validator.js +31 -295
  16. package/dist/compiler/typescript-worker-pool.js +1 -842
  17. package/dist/compiler/typescript-worker-thread.cjs +41 -466
  18. package/dist/compiler/typescript-worker.js +1 -339
  19. package/dist/compiler/vuejs.js +37 -392
  20. package/dist/hrm/VueHRM.js +1 -353
  21. package/dist/hrm/errorScreen.js +1 -83
  22. package/dist/hrm/getInstanciaVue.js +1 -313
  23. package/dist/hrm/initHRM.js +1 -141
  24. package/dist/main.js +7 -347
  25. package/dist/servicios/browserSync.js +5 -501
  26. package/dist/servicios/file-watcher.js +4 -379
  27. package/dist/servicios/logger.js +3 -63
  28. package/dist/servicios/readConfig.js +105 -430
  29. package/dist/utils/excluded-modules.js +1 -36
  30. package/dist/utils/module-resolver.js +1 -466
  31. package/dist/utils/promptUser.js +2 -48
  32. package/dist/utils/proxyValidator.js +1 -68
  33. package/dist/utils/resolve-bin.js +1 -48
  34. package/dist/utils/utils.js +1 -21
  35. package/dist/utils/vue-types-setup.js +241 -435
  36. package/dist/wrappers/eslint-node.js +1 -145
  37. package/dist/wrappers/oxlint-node.js +1 -120
  38. package/dist/wrappers/tailwind-node.js +1 -92
  39. package/package.json +36 -35
@@ -1,821 +1 @@
1
- /**
2
- * Module Resolution Optimizer
3
- *
4
- * Optimiza la resolución de módulos mediante:
5
- * - Sistema de indexación O(1) para búsquedas de módulos
6
- * - Caché LRU para resoluciones repetidas
7
- * - Indexación de alias para búsquedas rápidas
8
- * - Batch processing para múltiples resoluciones
9
- * - Monitoreo de performance y métricas
10
- */
11
- import { createHash } from 'node:crypto';
12
- import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
13
- import { dirname, join, relative } from 'node:path';
14
- import { cwd, env } from 'node:process';
15
- import { logger } from '../servicios/logger.js';
16
- import { EXCLUDED_MODULES } from '../utils/excluded-modules.js';
17
- /**
18
- * Sistema de optimización de resolución de módulos
19
- * Implementa indexación, caché y búsquedas O(1)
20
- */
21
- export class ModuleResolutionOptimizer {
22
- static instance;
23
- // Índice principal de módulos para búsquedas O(1)
24
- moduleIndex = new Map();
25
- // Caché LRU para resoluciones repetidas
26
- resolutionCache = new Map();
27
- cacheOrder = [];
28
- // Índice de alias optimizado
29
- aliasIndex = [];
30
- // Caché de rutas de node_modules descubiertas
31
- nodeModulesCache = new Map();
32
- // Métricas de rendimiento
33
- metrics = {
34
- totalResolutions: 0,
35
- cacheHits: 0,
36
- cacheMisses: 0,
37
- averageResolveTime: 0,
38
- indexLookups: 0,
39
- filesystemAccess: 0,
40
- aliasMatches: 0,
41
- };
42
- // Configuración
43
- maxCacheSize = 500;
44
- cacheMaxAge = 5 * 60 * 1000; // 5 minutos
45
- indexRefreshInterval = 10 * 60 * 1000; // 10 minutos // Lista de módulos excluidos - usar la lista centralizada
46
- excludedModules = EXCLUDED_MODULES;
47
- lastIndexUpdate = 0;
48
- constructor() {
49
- this.initializeIndexes();
50
- this.setupPeriodicRefresh();
51
- }
52
- static getInstance() {
53
- if (!ModuleResolutionOptimizer.instance) {
54
- ModuleResolutionOptimizer.instance =
55
- new ModuleResolutionOptimizer();
56
- }
57
- return ModuleResolutionOptimizer.instance;
58
- }
59
- /**
60
- * Inicializa los índices de módulos y alias
61
- */
62
- initializeIndexes() {
63
- const startTime = performance.now();
64
- try {
65
- this.buildModuleIndex();
66
- this.buildAliasIndex();
67
- this.lastIndexUpdate = Date.now();
68
- const indexTime = performance.now() - startTime;
69
- if (env.VERBOSE === 'true') {
70
- logger.info(`🚀 Índices de resolución construidos en ${indexTime.toFixed(2)}ms`);
71
- logger.info(`📦 ${this.moduleIndex.size} módulos indexados`);
72
- logger.info(`🔗 ${this.aliasIndex.length} alias indexados`);
73
- }
74
- }
75
- catch (error) {
76
- logger.error('Error inicializando índices de resolución:', error);
77
- }
78
- }
79
- /**
80
- * Construye el índice principal de módulos para búsquedas O(1)
81
- */
82
- buildModuleIndex() {
83
- const nodeModulesPath = join(cwd(), 'node_modules');
84
- if (!existsSync(nodeModulesPath)) {
85
- return;
86
- }
87
- try {
88
- const modules = this.discoverModules(nodeModulesPath);
89
- for (const moduleData of modules) {
90
- this.moduleIndex.set(moduleData.name, {
91
- fullPath: moduleData.fullPath,
92
- entryPoint: moduleData.entryPoint,
93
- packageJson: moduleData.packageJson,
94
- isESM: moduleData.isESM,
95
- hasExports: moduleData.hasExports,
96
- optimizedEntry: moduleData.optimizedEntry,
97
- lastModified: moduleData.lastModified,
98
- });
99
- }
100
- if (env.VERBOSE === 'true') {
101
- logger.info(`📚 Índice de módulos construido: ${this.moduleIndex.size} entradas`);
102
- }
103
- }
104
- catch (error) {
105
- logger.error('Error construyendo índice de módulos:', error);
106
- }
107
- }
108
- /**
109
- * Descubre módulos disponibles en node_modules con información optimizada
110
- */
111
- discoverModules(nodeModulesPath) {
112
- const modules = [];
113
- try {
114
- const entries = readdirSync(nodeModulesPath);
115
- this.metrics.filesystemAccess++;
116
- for (const entry of entries) {
117
- const modulePath = join(nodeModulesPath, entry);
118
- try {
119
- if (entry.startsWith('/dist/examples')) {
120
- // Scoped packages
121
- const scopedModules = readdirSync(modulePath);
122
- this.metrics.filesystemAccess++;
123
- for (const scopedModule of scopedModules) {
124
- const scopedPath = join(modulePath, scopedModule);
125
- const moduleData = this.analyzeModule(`${entry}/${scopedModule}`, scopedPath);
126
- if (moduleData) {
127
- modules.push(moduleData);
128
- }
129
- }
130
- }
131
- else {
132
- // Regular packages
133
- const moduleData = this.analyzeModule(entry, modulePath);
134
- if (moduleData) {
135
- modules.push(moduleData);
136
- }
137
- }
138
- }
139
- catch {
140
- // Ignorar módulos que no se puedan analizar
141
- continue;
142
- }
143
- }
144
- }
145
- catch (error) {
146
- logger.error('Error descubriendo módulos:', error);
147
- }
148
- return modules;
149
- }
150
- /**
151
- * Analiza un módulo individual y extrae información relevante
152
- */
153
- analyzeModule(name, modulePath) {
154
- try {
155
- const packageJsonPath = join(modulePath, 'package.json');
156
- if (!existsSync(packageJsonPath)) {
157
- return null;
158
- }
159
- const stats = statSync(packageJsonPath);
160
- this.metrics.filesystemAccess++;
161
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
162
- this.metrics.filesystemAccess++;
163
- const isESM = packageJson.type === 'module';
164
- const hasExports = !!packageJson.exports; // Determinar entry point optimizado
165
- const entryPoint = this.determineOptimalEntryPoint(packageJson);
166
- let optimizedEntry;
167
- // Buscar versión ESM/browser optimizada
168
- if (entryPoint) {
169
- optimizedEntry = this.findOptimalESMVersion(modulePath, entryPoint);
170
- }
171
- return {
172
- name,
173
- fullPath: modulePath,
174
- entryPoint: entryPoint || 'index.js',
175
- packageJson,
176
- isESM,
177
- hasExports,
178
- optimizedEntry,
179
- lastModified: stats.mtime.getTime(),
180
- };
181
- }
182
- catch {
183
- return null;
184
- }
185
- } /**
186
- * Determina el entry point óptimo basado en package.json
187
- */
188
- determineOptimalEntryPoint(packageJson) {
189
- // Prioridad: module > exports > browser > main
190
- let entryPoint = null;
191
- if (packageJson.module) {
192
- entryPoint = packageJson.module;
193
- }
194
- else if (packageJson.exports) {
195
- if (typeof packageJson.exports === 'string') {
196
- entryPoint = packageJson.exports;
197
- }
198
- else if (packageJson.exports['.']) {
199
- const dotExport = packageJson.exports['.'];
200
- if (typeof dotExport === 'string') {
201
- entryPoint = dotExport;
202
- }
203
- else if (typeof dotExport === 'object') {
204
- entryPoint =
205
- dotExport.import ||
206
- dotExport.browser ||
207
- dotExport.default;
208
- }
209
- }
210
- }
211
- else if (packageJson.browser &&
212
- typeof packageJson.browser === 'string') {
213
- entryPoint = packageJson.browser;
214
- }
215
- else {
216
- entryPoint = packageJson.main || null;
217
- }
218
- // ✨ NUEVA VALIDACIÓN POST-RESOLUCIÓN
219
- // Verificar si el archivo resuelto cumple con criterios de desarrollo
220
- if (entryPoint) {
221
- entryPoint = this.validateAndOptimizeEntryPoint(entryPoint, packageJson);
222
- }
223
- return entryPoint;
224
- }
225
- /**
226
- * ✨ NUEVA FUNCIÓN: Valida y optimiza el entry point basado en criterios de desarrollo
227
- */
228
- validateAndOptimizeEntryPoint(entryPoint, packageJson) {
229
- const isProd = env.isProd === 'true';
230
- const fileName = entryPoint.toLowerCase();
231
- // Si estamos en desarrollo, evitar archivos .min o .prod
232
- if (!isProd &&
233
- (fileName.includes('.min.') || fileName.includes('.prod.'))) {
234
- // Buscar alternativas mejores en el package.json
235
- const alternatives = this.findDevelopmentAlternatives(entryPoint, packageJson);
236
- if (alternatives) {
237
- return alternatives;
238
- }
239
- }
240
- // Priorizar versiones browser y esm para mejor compatibilidad
241
- if (fileName.includes('runtime') && !fileName.includes('browser')) {
242
- const browserAlternative = this.findBrowserAlternative(entryPoint, packageJson);
243
- if (browserAlternative) {
244
- return browserAlternative;
245
- }
246
- }
247
- return entryPoint;
248
- } /**
249
- * ✨ NUEVA FUNCIÓN: Busca alternativas de desarrollo (no minificadas)
250
- */
251
- findDevelopmentAlternatives(entryPoint, packageJson) {
252
- // Crear versión de desarrollo basada en el entry point actual
253
- const devVersion = entryPoint
254
- .replace('.min.', '.')
255
- .replace('.prod.', '.');
256
- // Si hay exports, buscar en diferentes condiciones
257
- if (packageJson.exports && typeof packageJson.exports === 'object') {
258
- const dotExport = packageJson.exports['.'];
259
- if (dotExport && typeof dotExport === 'object') {
260
- // Buscar versiones development, import, browser
261
- const candidates = [
262
- dotExport.development,
263
- dotExport.import,
264
- dotExport.browser,
265
- dotExport.default,
266
- ].filter(Boolean);
267
- for (const candidate of candidates) {
268
- if (typeof candidate === 'string' &&
269
- !candidate.includes('.min.') &&
270
- !candidate.includes('.prod.')) {
271
- return candidate;
272
- }
273
- }
274
- }
275
- } // Si browser field es un objeto, buscar alternativas
276
- if (packageJson.browser && typeof packageJson.browser === 'object') {
277
- for (const value of Object.values(packageJson.browser)) {
278
- if (typeof value === 'string' &&
279
- !value.includes('.min.') &&
280
- !value.includes('.prod.') &&
281
- (value.includes('browser') || value.includes('esm'))) {
282
- return value;
283
- }
284
- }
285
- }
286
- return devVersion !== entryPoint ? devVersion : null;
287
- }
288
- /**
289
- * ✨ NUEVA FUNCIÓN: Busca alternativas browser para versiones runtime
290
- */
291
- findBrowserAlternative(entryPoint, packageJson) {
292
- // Primero intentar con exports
293
- if (packageJson.exports && typeof packageJson.exports === 'object') {
294
- const dotExport = packageJson.exports['.'];
295
- if (dotExport && typeof dotExport === 'object') {
296
- // Buscar specific browser+esm combinations
297
- const browserKeys = Object.keys(dotExport).filter(key => key.includes('browser') &&
298
- (key.includes('esm') || key.includes('module')));
299
- if (browserKeys.length > 0) {
300
- const firstBrowserKey = browserKeys[0];
301
- if (firstBrowserKey &&
302
- typeof dotExport[firstBrowserKey] === 'string') {
303
- return dotExport[firstBrowserKey];
304
- }
305
- }
306
- // Fallback a browser general
307
- if (dotExport.browser &&
308
- typeof dotExport.browser === 'string') {
309
- return dotExport.browser;
310
- }
311
- }
312
- }
313
- // Buscar en directorio dist versiones browser
314
- const baseName = entryPoint.replace(/\.[^/.]+$/, '');
315
- const browserCandidates = [
316
- baseName.replace('runtime', 'esm-browser'),
317
- baseName.replace('runtime', 'browser'),
318
- baseName.replace('runtime.esm-bundler', 'esm-browser'),
319
- entryPoint.replace('runtime', 'esm-browser'),
320
- entryPoint.replace('runtime', 'browser'),
321
- ];
322
- // Para Vue específicamente
323
- if (entryPoint.includes('vue.runtime.esm-bundler')) {
324
- browserCandidates.unshift('dist/vue.esm-browser.js', 'dist/vue.browser.esm.js');
325
- }
326
- return (browserCandidates.find(candidate => candidate !== entryPoint) ||
327
- null);
328
- }
329
- /**
330
- * Busca versión ESM/browser optimizada (simplificada del module-resolver)
331
- */
332
- findOptimalESMVersion(moduleDir, entryPoint) {
333
- const dir = dirname(entryPoint);
334
- const baseName = entryPoint.split('/').pop() || '';
335
- const nameWithoutExt = baseName.replace(/\.[^/.]+$/, '');
336
- const searchDir = join(moduleDir, dir);
337
- if (!existsSync(searchDir)) {
338
- return undefined;
339
- }
340
- try {
341
- const files = readdirSync(searchDir);
342
- this.metrics.filesystemAccess++;
343
- // Patrones de prioridad para versiones optimizadas
344
- const patterns = [
345
- `${nameWithoutExt}.esm-browser.js`,
346
- `${nameWithoutExt}.esm.js`,
347
- `${nameWithoutExt}.module.js`,
348
- `${nameWithoutExt}.browser.js`,
349
- ];
350
- for (const pattern of patterns) {
351
- if (files.includes(pattern)) {
352
- return join(dir, pattern);
353
- }
354
- }
355
- }
356
- catch {
357
- // Ignorar errores de filesystem
358
- }
359
- return undefined;
360
- }
361
- /**
362
- * Construye el índice de alias optimizado para búsquedas rápidas
363
- */
364
- buildAliasIndex() {
365
- if (!env.PATH_ALIAS) {
366
- return;
367
- }
368
- try {
369
- const pathAlias = JSON.parse(env.PATH_ALIAS);
370
- this.aliasIndex = [];
371
- // Convertir alias a índice con prioridad
372
- for (const [alias, target] of Object.entries(pathAlias)) {
373
- const pattern = alias.replace('/*', '');
374
- const priority = pattern.length; // Patrones más largos tienen prioridad
375
- this.aliasIndex.push({
376
- pattern,
377
- target: Array.isArray(target) ? target : [target],
378
- regex: new RegExp(`^${pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?=/|$)`),
379
- priority,
380
- });
381
- }
382
- // Ordenar por prioridad (patrones más largos primero)
383
- this.aliasIndex.sort((a, b) => b.priority - a.priority);
384
- if (env.VERBOSE === 'true') {
385
- logger.info(`🔗 Índice de alias construido: ${this.aliasIndex.length} patrones`);
386
- }
387
- }
388
- catch (error) {
389
- logger.error('Error construyendo índice de alias:', error);
390
- }
391
- }
392
- /**
393
- * Resuelve un módulo utilizando el sistema optimizado
394
- */
395
- async resolveModule(moduleName, fromFile) {
396
- const startTime = performance.now();
397
- this.metrics.totalResolutions++;
398
- // Verificar si está excluido
399
- if (this.excludedModules.has(moduleName)) {
400
- return {
401
- path: null,
402
- cached: false,
403
- resolveTime: performance.now() - startTime,
404
- };
405
- }
406
- // Crear clave de caché
407
- const cacheKey = this.createCacheKey(moduleName, fromFile);
408
- // Verificar caché
409
- const cached = this.getFromCache(cacheKey);
410
- if (cached !== undefined) {
411
- this.metrics.cacheHits++;
412
- return {
413
- path: cached,
414
- cached: true,
415
- resolveTime: performance.now() - startTime,
416
- fromCache: true,
417
- };
418
- }
419
- this.metrics.cacheMisses++;
420
- // Resolver módulo
421
- let resolvedPath = null;
422
- try {
423
- // 1. Verificar si es subpath de módulo (ej: 'vue/dist/vue.esm-bundler')
424
- if (moduleName.includes('/')) {
425
- resolvedPath = await this.resolveSubPath(moduleName);
426
- }
427
- else {
428
- // 2. Búsqueda O(1) en el índice
429
- resolvedPath = this.resolveFromIndex(moduleName);
430
- }
431
- // 3. Si no se encuentra en índice, intentar resolución tradicional
432
- if (!resolvedPath) {
433
- resolvedPath = this.fallbackResolve(moduleName);
434
- }
435
- // Convertir a ruta relativa desde node_modules
436
- if (resolvedPath) {
437
- resolvedPath = this.getNodeModulesRelativePath(resolvedPath);
438
- }
439
- }
440
- catch (error) {
441
- if (env.VERBOSE === 'true') {
442
- logger.warn(`Error resolviendo ${moduleName}:`, error);
443
- }
444
- }
445
- // Guardar en caché
446
- this.setCache(cacheKey, resolvedPath);
447
- const resolveTime = performance.now() - startTime;
448
- this.updateMetrics(resolveTime);
449
- return {
450
- path: resolvedPath,
451
- cached: false,
452
- resolveTime,
453
- };
454
- }
455
- /**
456
- * Busca módulo en el índice (O(1))
457
- */
458
- resolveFromIndex(moduleName) {
459
- this.metrics.indexLookups++;
460
- const moduleInfo = this.moduleIndex.get(moduleName);
461
- if (!moduleInfo) {
462
- return null;
463
- }
464
- // Usar versión optimizada si está disponible
465
- const entryPoint = moduleInfo.optimizedEntry || moduleInfo.entryPoint;
466
- return join(moduleInfo.fullPath, entryPoint);
467
- }
468
- /**
469
- * Resuelve subpaths de módulos (ej: 'vue/dist/vue.esm-bundler')
470
- */
471
- async resolveSubPath(moduleName) {
472
- const [packageName, ...subPathParts] = moduleName.split('/');
473
- const subPath = subPathParts.join('/');
474
- if (!packageName) {
475
- return null;
476
- }
477
- this.metrics.indexLookups++;
478
- const moduleInfo = this.moduleIndex.get(packageName);
479
- if (!moduleInfo) {
480
- return null;
481
- }
482
- // Verificar exports field para subpaths
483
- if (moduleInfo.hasExports && moduleInfo.packageJson.exports) {
484
- const exportKey = `./${subPath}`;
485
- const exportPath = moduleInfo.packageJson.exports[exportKey];
486
- if (exportPath) {
487
- if (typeof exportPath === 'string') {
488
- return join(moduleInfo.fullPath, exportPath);
489
- }
490
- else if (typeof exportPath === 'object') {
491
- const importPath = exportPath.import || exportPath.default;
492
- if (typeof importPath === 'string') {
493
- return join(moduleInfo.fullPath, importPath);
494
- }
495
- }
496
- }
497
- }
498
- // Fallback: resolver directamente el subpath
499
- const directPath = join(moduleInfo.fullPath, subPath);
500
- if (existsSync(directPath)) {
501
- this.metrics.filesystemAccess++;
502
- return directPath;
503
- }
504
- // Intentar con extensiones comunes
505
- const extensions = ['.mjs', '.js', '.cjs'];
506
- for (const ext of extensions) {
507
- const pathWithExt = directPath + ext;
508
- if (existsSync(pathWithExt)) {
509
- this.metrics.filesystemAccess++;
510
- return pathWithExt;
511
- }
512
- }
513
- return null;
514
- }
515
- /**
516
- * Resolución de fallback cuando no se encuentra en índice
517
- */
518
- fallbackResolve(moduleName) {
519
- const nodeModulesPath = join(cwd(), 'node_modules', moduleName);
520
- const packagePath = join(nodeModulesPath, 'package.json');
521
- if (!existsSync(packagePath)) {
522
- this.metrics.filesystemAccess++;
523
- return null;
524
- }
525
- try {
526
- const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
527
- this.metrics.filesystemAccess++;
528
- const entryPoint = this.determineOptimalEntryPoint(packageJson) || 'index.js';
529
- const finalPath = join(nodeModulesPath, entryPoint);
530
- if (existsSync(finalPath)) {
531
- this.metrics.filesystemAccess++;
532
- return finalPath;
533
- }
534
- }
535
- catch {
536
- // Ignorar errores
537
- }
538
- return null;
539
- }
540
- /**
541
- * Encuentra alias que coincida con el path dado
542
- */
543
- findMatchingAlias(path) {
544
- this.metrics.aliasMatches++;
545
- for (const alias of this.aliasIndex) {
546
- if (alias.regex.test(path)) {
547
- return alias;
548
- }
549
- }
550
- return null;
551
- } /**
552
- * Resuelve un alias a su ruta correspondiente
553
- */
554
- resolveAlias(path) {
555
- const alias = this.findMatchingAlias(path);
556
- if (!alias || !env.PATH_DIST) {
557
- return null;
558
- }
559
- const relativePath = path.replace(alias.pattern, '');
560
- const targetPath = alias.target[0];
561
- if (!targetPath) {
562
- return null;
563
- } // Construir ruta final
564
- let finalPath;
565
- const pathDist = env.PATH_DIST.replace('./', '');
566
- // Manejar caso especial: alias exacto sin wildcard (como #config -> config/index.js)
567
- if (relativePath === '' && !targetPath.includes('*')) {
568
- // Es un alias exacto, usar el target tal como está
569
- if (targetPath.startsWith('/')) {
570
- finalPath = join('/', pathDist, targetPath.substring(1));
571
- }
572
- else {
573
- const cleanTarget = targetPath.replace('./', '');
574
- if (cleanTarget.startsWith('src/')) {
575
- const targetWithoutSrc = cleanTarget.replace('src/', '');
576
- finalPath = join('/', pathDist, targetWithoutSrc);
577
- }
578
- else {
579
- finalPath = join('/', pathDist, cleanTarget);
580
- }
581
- }
582
- }
583
- else if (targetPath.startsWith('/')) {
584
- // Si el target empieza con /, es una ruta absoluta desde la raíz del proyecto
585
- // Para targets como "/src/*", mapear directamente al PATH_DIST
586
- // Remover el primer directorio si es diferente de PATH_DIST
587
- const targetWithoutSlash = targetPath
588
- .substring(1)
589
- .replace('/*', '');
590
- if (targetWithoutSlash === 'src' ||
591
- targetWithoutSlash.startsWith('src/')) {
592
- // Para "/src/*" mapear directamente a "/pathDist/relativePath"
593
- finalPath = join('/', pathDist, relativePath);
594
- }
595
- else {
596
- // Para otros casos como "/examples/*", también mapear directamente
597
- finalPath = join('/', pathDist, relativePath);
598
- }
599
- }
600
- else {
601
- // Si es una ruta relativa, construir basándose en el target
602
- const cleanTarget = targetPath.replace('./', '').replace('/*', '');
603
- // Si el target ya incluye el directorio de distribución, no duplicar
604
- if (cleanTarget === pathDist) {
605
- finalPath = join('/', pathDist, relativePath);
606
- }
607
- else if (cleanTarget.startsWith(pathDist + '/')) {
608
- // Si el target ya contiene PATH_DIST como prefijo
609
- finalPath = join('/', cleanTarget, relativePath);
610
- }
611
- else {
612
- // Caso normal: mapear manteniendo la estructura relativa al target
613
- if (cleanTarget.startsWith('src/')) {
614
- // Para "src/components/*" -> "/pathDist/components/*"
615
- const targetWithoutSrc = cleanTarget.replace('src/', '');
616
- finalPath = join('/', pathDist, targetWithoutSrc, relativePath);
617
- }
618
- else {
619
- // Para casos como "examples/*" -> "/pathDist/*"
620
- // No incluir el directorio raíz en la ruta final
621
- const isRootDirectory = [
622
- 'examples',
623
- 'src',
624
- 'app',
625
- 'lib',
626
- ].includes(cleanTarget);
627
- if (isRootDirectory) {
628
- finalPath = join('/', pathDist, relativePath);
629
- }
630
- else {
631
- // Para subdirectorios específicos, mantener la estructura
632
- finalPath = join('/', pathDist, cleanTarget, relativePath);
633
- }
634
- }
635
- }
636
- }
637
- return finalPath.replace(/\\/g, '/');
638
- }
639
- /**
640
- * Gestión de caché LRU
641
- */
642
- getFromCache(key) {
643
- const entry = this.resolutionCache.get(key);
644
- if (!entry) {
645
- return undefined;
646
- }
647
- // Verificar expiración
648
- if (Date.now() - entry.timestamp > this.cacheMaxAge) {
649
- this.resolutionCache.delete(key);
650
- this.cacheOrder = this.cacheOrder.filter(k => k !== key);
651
- return undefined;
652
- }
653
- // Actualizar orden LRU
654
- entry.hits++;
655
- this.cacheOrder = this.cacheOrder.filter(k => k !== key);
656
- this.cacheOrder.push(key);
657
- return entry.result;
658
- }
659
- setCache(key, result) {
660
- // Implementar límite de caché LRU
661
- if (this.resolutionCache.size >= this.maxCacheSize) {
662
- const oldestKey = this.cacheOrder.shift();
663
- if (oldestKey) {
664
- this.resolutionCache.delete(oldestKey);
665
- }
666
- }
667
- this.resolutionCache.set(key, {
668
- result,
669
- timestamp: Date.now(),
670
- hits: 0,
671
- });
672
- this.cacheOrder.push(key);
673
- }
674
- createCacheKey(moduleName, fromFile) {
675
- const hash = createHash('md5');
676
- hash.update(moduleName);
677
- if (fromFile) {
678
- hash.update(fromFile);
679
- }
680
- return hash.digest('hex');
681
- }
682
- /**
683
- * Convierte ruta absoluta a ruta relativa desde node_modules
684
- */
685
- getNodeModulesRelativePath(fullPath) {
686
- const idx = fullPath.indexOf('node_modules');
687
- if (idx !== -1) {
688
- return '/' + fullPath.substring(idx).replace(/\\/g, '/');
689
- }
690
- // Para rutas que no están en node_modules
691
- const rel = relative(cwd(), fullPath).replace(/\\/g, '/');
692
- return rel.startsWith('/') ? rel : '/' + rel;
693
- }
694
- /**
695
- * Actualiza métricas de rendimiento
696
- */
697
- updateMetrics(resolveTime) {
698
- this.metrics.averageResolveTime =
699
- (this.metrics.averageResolveTime *
700
- (this.metrics.totalResolutions - 1) +
701
- resolveTime) /
702
- this.metrics.totalResolutions;
703
- }
704
- /**
705
- * Configura actualización periódica de índices
706
- */
707
- setupPeriodicRefresh() {
708
- setInterval(() => {
709
- if (Date.now() - this.lastIndexUpdate > this.indexRefreshInterval) {
710
- if (env.VERBOSE === 'true') {
711
- logger.info('🔄 Actualizando índices de resolución de módulos');
712
- }
713
- this.refreshIndexes();
714
- }
715
- }, this.indexRefreshInterval);
716
- }
717
- /**
718
- * Actualiza los índices manteniendo el caché válido
719
- */
720
- refreshIndexes() {
721
- try {
722
- const oldSize = this.moduleIndex.size;
723
- this.buildModuleIndex();
724
- this.buildAliasIndex();
725
- this.lastIndexUpdate = Date.now();
726
- if (env.VERBOSE === 'true') {
727
- logger.info(`📚 Índices actualizados: ${oldSize} → ${this.moduleIndex.size} módulos`);
728
- }
729
- }
730
- catch (error) {
731
- logger.error('Error actualizando índices:', error);
732
- }
733
- }
734
- /**
735
- * Limpia caché expirado
736
- */
737
- clearExpiredCache() {
738
- const now = Date.now();
739
- const keysToDelete = [];
740
- for (const [key, entry] of this.resolutionCache.entries()) {
741
- if (now - entry.timestamp > this.cacheMaxAge) {
742
- keysToDelete.push(key);
743
- }
744
- }
745
- for (const key of keysToDelete) {
746
- this.resolutionCache.delete(key);
747
- this.cacheOrder = this.cacheOrder.filter(k => k !== key);
748
- }
749
- if (env.VERBOSE === 'true' && keysToDelete.length > 0) {
750
- logger.info(`🧹 Limpiado caché expirado: ${keysToDelete.length} entradas`);
751
- }
752
- }
753
- /**
754
- * Obtiene métricas de rendimiento
755
- */
756
- getMetrics() {
757
- return {
758
- ...this.metrics,
759
- cacheSize: this.resolutionCache.size,
760
- moduleIndexSize: this.moduleIndex.size,
761
- aliasIndexSize: this.aliasIndex.length,
762
- cacheHitRate: this.metrics.totalResolutions > 0
763
- ? (this.metrics.cacheHits / this.metrics.totalResolutions) *
764
- 100
765
- : 0,
766
- };
767
- }
768
- /**
769
- * Resetea métricas de rendimiento
770
- */
771
- resetMetrics() {
772
- this.metrics = {
773
- totalResolutions: 0,
774
- cacheHits: 0,
775
- cacheMisses: 0,
776
- averageResolveTime: 0,
777
- indexLookups: 0,
778
- filesystemAccess: 0,
779
- aliasMatches: 0,
780
- };
781
- }
782
- /**
783
- * Forzar reconstrucción de índices
784
- */
785
- forceRefresh() {
786
- this.initializeIndexes();
787
- this.resolutionCache.clear();
788
- this.cacheOrder = [];
789
- if (env.VERBOSE === 'true') {
790
- logger.info('🔄 Índices de resolución reconstruidos forzosamente');
791
- }
792
- }
793
- /**
794
- * Limpia todos los cachés y índices
795
- */
796
- cleanup() {
797
- this.moduleIndex.clear();
798
- this.resolutionCache.clear();
799
- this.cacheOrder = [];
800
- this.aliasIndex = [];
801
- this.nodeModulesCache.clear();
802
- if (env.VERBOSE === 'true') {
803
- logger.info('🧹 Sistema de resolución de módulos limpiado');
804
- }
805
- }
806
- }
807
- // Funciones de compatibilidad con el sistema existente
808
- export async function getOptimizedModulePath(moduleName, fromFile) {
809
- const optimizer = ModuleResolutionOptimizer.getInstance();
810
- const result = await optimizer.resolveModule(moduleName, fromFile);
811
- return result.path;
812
- }
813
- export function getOptimizedAliasPath(path) {
814
- const optimizer = ModuleResolutionOptimizer.getInstance();
815
- return optimizer.resolveAlias(path);
816
- }
817
- export function getModuleResolutionMetrics() {
818
- const optimizer = ModuleResolutionOptimizer.getInstance();
819
- return optimizer.getMetrics();
820
- }
821
- //# sourceMappingURL=module-resolution-optimizer.js.map
1
+ import{createHash as e}from"node:crypto";import{existsSync as i,readFileSync as a,readdirSync as o,statSync as s}from"node:fs";import{dirname as c,join as l,relative as u}from"node:path";import{cwd as d,env as f}from"node:process";import{logger as p}from"../servicios/logger.js";import{EXCLUDED_MODULES as m}from"../utils/excluded-modules.js";export class ModuleResolutionOptimizer{static instance;moduleIndex=new Map;resolutionCache=new Map;cacheOrder=[];aliasIndex=[];nodeModulesCache=new Map;metrics={totalResolutions:0,cacheHits:0,cacheMisses:0,averageResolveTime:0,indexLookups:0,filesystemAccess:0,aliasMatches:0};maxCacheSize=500;cacheMaxAge=300*1e3;indexRefreshInterval=600*1e3;excludedModules=m;lastIndexUpdate=0;constructor(){this.initializeIndexes(),this.setupPeriodicRefresh()}static getInstance(){return ModuleResolutionOptimizer.instance||=new ModuleResolutionOptimizer,ModuleResolutionOptimizer.instance}initializeIndexes(){let e=performance.now();try{this.buildModuleIndex(),this.buildAliasIndex(),this.lastIndexUpdate=Date.now();let i=performance.now()-e;f.VERBOSE===`true`&&(p.info(`🚀 Índices de resolución construidos en ${i.toFixed(2)}ms`),p.info(`📦 ${this.moduleIndex.size} módulos indexados`),p.info(`🔗 ${this.aliasIndex.length} alias indexados`))}catch(e){p.error(`Error inicializando índices de resolución:`,e)}}buildModuleIndex(){let e=l(d(),`node_modules`);if(i(e))try{let i=this.discoverModules(e);for(let e of i)this.moduleIndex.set(e.name,{fullPath:e.fullPath,entryPoint:e.entryPoint,packageJson:e.packageJson,isESM:e.isESM,hasExports:e.hasExports,optimizedEntry:e.optimizedEntry,lastModified:e.lastModified});f.VERBOSE===`true`&&p.info(`📚 Índice de módulos construido: ${this.moduleIndex.size} entradas`)}catch(e){p.error(`Error construyendo índice de módulos:`,e)}}discoverModules(e){let i=[];try{let a=o(e);this.metrics.filesystemAccess++;for(let s of a){let a=l(e,s);try{if(s.startsWith(`/dist/examples`)){let e=o(a);this.metrics.filesystemAccess++;for(let o of e){let e=l(a,o),c=this.analyzeModule(`${s}/${o}`,e);c&&i.push(c)}}else{let e=this.analyzeModule(s,a);e&&i.push(e)}}catch{continue}}}catch(e){p.error(`Error descubriendo módulos:`,e)}return i}analyzeModule(e,o){try{let c=l(o,`package.json`);if(!i(c))return null;let u=s(c);this.metrics.filesystemAccess++;let d=JSON.parse(a(c,`utf-8`));this.metrics.filesystemAccess++;let f=d.type===`module`,p=!!d.exports,m=this.determineOptimalEntryPoint(d),h;return m&&(h=this.findOptimalESMVersion(o,m)),{name:e,fullPath:o,entryPoint:m||`index.js`,packageJson:d,isESM:f,hasExports:p,optimizedEntry:h,lastModified:u.mtime.getTime()}}catch{return null}}determineOptimalEntryPoint(e){let i=null;if(e.module)i=e.module;else if(e.exports){if(typeof e.exports==`string`)i=e.exports;else if(e.exports[`.`]){let a=e.exports[`.`];typeof a==`string`?i=a:typeof a==`object`&&(i=a.import||a.browser||a.default)}}else i=e.browser&&typeof e.browser==`string`?e.browser:e.main||null;return i&&=this.validateAndOptimizeEntryPoint(i,e),i}validateAndOptimizeEntryPoint(e,i){let a=f.isProd===`true`,o=e.toLowerCase();if(!a&&(o.includes(`.min.`)||o.includes(`.prod.`))){let a=this.findDevelopmentAlternatives(e,i);if(a)return a}if(o.includes(`runtime`)&&!o.includes(`browser`)){let a=this.findBrowserAlternative(e,i);if(a)return a}return e}findDevelopmentAlternatives(e,i){let a=e.replace(`.min.`,`.`).replace(`.prod.`,`.`);if(i.exports&&typeof i.exports==`object`){let e=i.exports[`.`];if(e&&typeof e==`object`){let i=[e.development,e.import,e.browser,e.default].filter(Boolean);for(let e of i)if(typeof e==`string`&&!e.includes(`.min.`)&&!e.includes(`.prod.`))return e}}if(i.browser&&typeof i.browser==`object`){for(let e of Object.values(i.browser))if(typeof e==`string`&&!e.includes(`.min.`)&&!e.includes(`.prod.`)&&(e.includes(`browser`)||e.includes(`esm`)))return e}return a===e?null:a}findBrowserAlternative(e,i){if(i.exports&&typeof i.exports==`object`){let e=i.exports[`.`];if(e&&typeof e==`object`){let i=Object.keys(e).filter(e=>e.includes(`browser`)&&(e.includes(`esm`)||e.includes(`module`)));if(i.length>0){let a=i[0];if(a&&typeof e[a]==`string`)return e[a]}if(e.browser&&typeof e.browser==`string`)return e.browser}}let a=e.replace(/\.[^/.]+$/,``),o=[a.replace(`runtime`,`esm-browser`),a.replace(`runtime`,`browser`),a.replace(`runtime.esm-bundler`,`esm-browser`),e.replace(`runtime`,`esm-browser`),e.replace(`runtime`,`browser`)];return e.includes(`vue.runtime.esm-bundler`)&&o.unshift(`dist/vue.esm-browser.js`,`dist/vue.browser.esm.js`),o.find(i=>i!==e)||null}findOptimalESMVersion(e,a){let s=c(a),u=a.split(`/`).pop()||``,d=u.replace(/\.[^/.]+$/,``),f=l(e,s);if(i(f))try{let e=o(f);this.metrics.filesystemAccess++;let i=[`${d}.esm-browser.js`,`${d}.esm.js`,`${d}.module.js`,`${d}.browser.js`];for(let a of i)if(e.includes(a))return l(s,a)}catch{}}buildAliasIndex(){if(f.PATH_ALIAS)try{let e=JSON.parse(f.PATH_ALIAS);this.aliasIndex=[];for(let[i,a]of Object.entries(e)){let e=i.replace(`/*`,``),o=e.length;this.aliasIndex.push({pattern:e,target:Array.isArray(a)?a:[a],regex:RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}(?=/|$)`),priority:o})}this.aliasIndex.sort((e,i)=>i.priority-e.priority),f.VERBOSE===`true`&&p.info(`🔗 Índice de alias construido: ${this.aliasIndex.length} patrones`)}catch(e){p.error(`Error construyendo índice de alias:`,e)}}async resolveModule(e,i){let a=performance.now();if(this.metrics.totalResolutions++,this.excludedModules.has(e))return{path:null,cached:!1,resolveTime:performance.now()-a};let o=this.createCacheKey(e,i),s=this.getFromCache(o);if(s!==void 0)return this.metrics.cacheHits++,{path:s,cached:!0,resolveTime:performance.now()-a,fromCache:!0};this.metrics.cacheMisses++;let c=null;try{c=e.includes(`/`)?await this.resolveSubPath(e):this.resolveFromIndex(e),c||=this.fallbackResolve(e),c&&=this.getNodeModulesRelativePath(c)}catch(i){f.VERBOSE===`true`&&p.warn(`Error resolviendo ${e}:`,i)}this.setCache(o,c);let l=performance.now()-a;return this.updateMetrics(l),{path:c,cached:!1,resolveTime:l}}resolveFromIndex(e){this.metrics.indexLookups++;let i=this.moduleIndex.get(e);if(!i)return null;let a=i.optimizedEntry||i.entryPoint;return l(i.fullPath,a)}async resolveSubPath(e){let[a,...o]=e.split(`/`),s=o.join(`/`);if(!a)return null;this.metrics.indexLookups++;let c=this.moduleIndex.get(a);if(!c)return null;if(c.hasExports&&c.packageJson.exports){let e=`./${s}`,i=c.packageJson.exports[e];if(i){if(typeof i==`string`)return l(c.fullPath,i);if(typeof i==`object`){let e=i.import||i.default;if(typeof e==`string`)return l(c.fullPath,e)}}}let u=l(c.fullPath,s);if(i(u))return this.metrics.filesystemAccess++,u;let d=[`.mjs`,`.js`,`.cjs`];for(let e of d){let a=u+e;if(i(a))return this.metrics.filesystemAccess++,a}return null}fallbackResolve(e){let o=l(d(),`node_modules`,e),s=l(o,`package.json`);if(!i(s))return this.metrics.filesystemAccess++,null;try{let e=JSON.parse(a(s,`utf-8`));this.metrics.filesystemAccess++;let c=this.determineOptimalEntryPoint(e)||`index.js`,u=l(o,c);if(i(u))return this.metrics.filesystemAccess++,u}catch{}return null}findMatchingAlias(e){this.metrics.aliasMatches++;for(let i of this.aliasIndex)if(i.regex.test(e))return i;return null}resolveAlias(e){let i=this.findMatchingAlias(e);if(!i||!f.PATH_DIST)return null;let a=e.replace(i.pattern,``),o=i.target[0];if(!o)return null;let s,c=f.PATH_DIST.replace(`./`,``);if(a===``&&!o.includes(`*`))if(o.startsWith(`/`))s=l(`/`,c,o.substring(1));else{let e=o.replace(`./`,``);if(e.startsWith(`src/`)){let i=e.replace(`src/`,``);s=l(`/`,c,i)}else s=l(`/`,c,e)}else if(o.startsWith(`/`)){let e=o.substring(1).replace(`/*`,``);s=(e===`src`||e.startsWith(`src/`),l(`/`,c,a))}else{let e=o.replace(`./`,``).replace(`/*`,``);if(e===c)s=l(`/`,c,a);else if(e.startsWith(c+`/`))s=l(`/`,e,a);else if(e.startsWith(`src/`)){let i=e.replace(`src/`,``);s=l(`/`,c,i,a)}else{let i=[`examples`,`src`,`app`,`lib`].includes(e);s=i?l(`/`,c,a):l(`/`,c,e,a)}}return s.replace(/\\/g,`/`)}getFromCache(e){let i=this.resolutionCache.get(e);if(i){if(Date.now()-i.timestamp>this.cacheMaxAge){this.resolutionCache.delete(e),this.cacheOrder=this.cacheOrder.filter(i=>i!==e);return}return i.hits++,this.cacheOrder=this.cacheOrder.filter(i=>i!==e),this.cacheOrder.push(e),i.result}}setCache(e,i){if(this.resolutionCache.size>=this.maxCacheSize){let e=this.cacheOrder.shift();e&&this.resolutionCache.delete(e)}this.resolutionCache.set(e,{result:i,timestamp:Date.now(),hits:0}),this.cacheOrder.push(e)}createCacheKey(i,a){let o=e(`md5`);return o.update(i),a&&o.update(a),o.digest(`hex`)}getNodeModulesRelativePath(e){let i=e.indexOf(`node_modules`);if(i!==-1)return`/`+e.substring(i).replace(/\\/g,`/`);let a=u(d(),e).replace(/\\/g,`/`);return a.startsWith(`/`)?a:`/`+a}updateMetrics(e){this.metrics.averageResolveTime=(this.metrics.averageResolveTime*(this.metrics.totalResolutions-1)+e)/this.metrics.totalResolutions}setupPeriodicRefresh(){setInterval(()=>{Date.now()-this.lastIndexUpdate>this.indexRefreshInterval&&(f.VERBOSE===`true`&&p.info(`🔄 Actualizando índices de resolución de módulos`),this.refreshIndexes())},this.indexRefreshInterval)}refreshIndexes(){try{let e=this.moduleIndex.size;this.buildModuleIndex(),this.buildAliasIndex(),this.lastIndexUpdate=Date.now(),f.VERBOSE===`true`&&p.info(`📚 Índices actualizados: ${e} → ${this.moduleIndex.size} módulos`)}catch(e){p.error(`Error actualizando índices:`,e)}}clearExpiredCache(){let e=Date.now(),i=[];for(let[a,o]of this.resolutionCache.entries())e-o.timestamp>this.cacheMaxAge&&i.push(a);for(let e of i)this.resolutionCache.delete(e),this.cacheOrder=this.cacheOrder.filter(i=>i!==e);f.VERBOSE===`true`&&i.length>0&&p.info(`🧹 Limpiado caché expirado: ${i.length} entradas`)}getMetrics(){return{...this.metrics,cacheSize:this.resolutionCache.size,moduleIndexSize:this.moduleIndex.size,aliasIndexSize:this.aliasIndex.length,cacheHitRate:this.metrics.totalResolutions>0?this.metrics.cacheHits/this.metrics.totalResolutions*100:0}}resetMetrics(){this.metrics={totalResolutions:0,cacheHits:0,cacheMisses:0,averageResolveTime:0,indexLookups:0,filesystemAccess:0,aliasMatches:0}}forceRefresh(){this.initializeIndexes(),this.resolutionCache.clear(),this.cacheOrder=[],f.VERBOSE===`true`&&p.info(`🔄 Índices de resolución reconstruidos forzosamente`)}cleanup(){this.moduleIndex.clear(),this.resolutionCache.clear(),this.cacheOrder=[],this.aliasIndex=[],this.nodeModulesCache.clear(),f.VERBOSE===`true`&&p.info(`🧹 Sistema de resolución de módulos limpiado`)}}export async function getOptimizedModulePath(e,i){let a=ModuleResolutionOptimizer.getInstance(),o=await a.resolveModule(e,i);return o.path}export function getOptimizedAliasPath(e){let i=ModuleResolutionOptimizer.getInstance();return i.resolveAlias(e)}export function getModuleResolutionMetrics(){let e=ModuleResolutionOptimizer.getInstance();return e.getMetrics()}