versacompiler 1.0.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +357 -145
  2. package/dist/compiler/compile.js +1120 -0
  3. package/dist/compiler/error-reporter.js +467 -0
  4. package/dist/compiler/linter.js +72 -0
  5. package/dist/{services → compiler}/minify.js +40 -31
  6. package/dist/compiler/parser.js +30 -0
  7. package/dist/compiler/tailwindcss.js +39 -0
  8. package/dist/compiler/transformTStoJS.js +16 -0
  9. package/dist/compiler/transforms.js +544 -0
  10. package/dist/compiler/typescript-error-parser.js +282 -0
  11. package/dist/compiler/typescript-sync-validator.js +230 -0
  12. package/dist/compiler/typescript-worker-thread.cjs +457 -0
  13. package/dist/compiler/typescript-worker.js +309 -0
  14. package/dist/compiler/typescript.js +382 -0
  15. package/dist/compiler/vuejs.js +296 -0
  16. package/dist/hrm/VueHRM.js +353 -0
  17. package/dist/hrm/errorScreen.js +23 -1
  18. package/dist/hrm/getInstanciaVue.js +313 -0
  19. package/dist/hrm/initHRM.js +140 -0
  20. package/dist/main.js +287 -0
  21. package/dist/servicios/browserSync.js +177 -0
  22. package/dist/servicios/chokidar.js +178 -0
  23. package/dist/servicios/logger.js +33 -0
  24. package/dist/servicios/readConfig.js +429 -0
  25. package/dist/utils/module-resolver.js +506 -0
  26. package/dist/utils/promptUser.js +48 -0
  27. package/dist/utils/resolve-bin.js +29 -0
  28. package/dist/utils/utils.js +21 -48
  29. package/dist/wrappers/eslint-node.js +145 -0
  30. package/dist/wrappers/oxlint-node.js +120 -0
  31. package/dist/wrappers/tailwind-node.js +92 -0
  32. package/package.json +62 -15
  33. package/dist/hrm/devMode.js +0 -249
  34. package/dist/hrm/instanciaVue.js +0 -35
  35. package/dist/hrm/setupHMR.js +0 -57
  36. package/dist/index.js +0 -873
  37. package/dist/services/acorn.js +0 -29
  38. package/dist/services/linter.js +0 -55
  39. package/dist/services/typescript.js +0 -89
  40. package/dist/services/vueLoader.js +0 -324
  41. package/dist/services/vuejs.js +0 -259
@@ -0,0 +1,309 @@
1
+ /**
2
+ * TypeScript Worker Manager - Gestiona workers dedicados para type checking asíncrono
3
+ * Implementa el patrón Singleton para reutilizar workers entre compilaciones
4
+ */
5
+ import * as path from 'node:path';
6
+ import * as process from 'node:process';
7
+ import { Worker } from 'node:worker_threads';
8
+ import { validateTypesWithLanguageService } from './typescript-sync-validator.js';
9
+ /**
10
+ * Gestiona workers dedicados para type checking asíncrono de TypeScript
11
+ * Implementa patrón Singleton para eficiencia y reutilización de recursos
12
+ */
13
+ export class TypeScriptWorkerManager {
14
+ static instance;
15
+ worker = null;
16
+ pendingTasks = new Map();
17
+ taskCounter = 0;
18
+ workerReady = false;
19
+ initPromise = null;
20
+ // Configuración del worker
21
+ WORKER_TIMEOUT = 30000; // 30 segundos timeout (incrementado)
22
+ MAX_RETRY_ATTEMPTS = 2;
23
+ // NUEVOS: Gestión de modo y estado para optimización
24
+ currentMode = null;
25
+ constructor() { }
26
+ /**
27
+ * NUEVO: Configura el modo de operación del worker
28
+ */
29
+ setMode(mode) {
30
+ this.currentMode = mode;
31
+ // En modo watch, el worker se mantiene activo más tiempo
32
+ // En otros modos, se puede optimizar la gestión de recursos
33
+ console.log(`[WorkerManager] Modo establecido: ${mode}`);
34
+ }
35
+ /**
36
+ * Obtiene la instancia singleton del Worker Manager
37
+ */
38
+ static getInstance() {
39
+ if (!TypeScriptWorkerManager.instance) {
40
+ TypeScriptWorkerManager.instance = new TypeScriptWorkerManager();
41
+ }
42
+ return TypeScriptWorkerManager.instance;
43
+ }
44
+ /**
45
+ * Inicializa el worker thread de TypeScript
46
+ */
47
+ async initializeWorker() {
48
+ if (this.initPromise) {
49
+ return this.initPromise;
50
+ }
51
+ this.initPromise = this._performWorkerInitialization();
52
+ return this.initPromise;
53
+ } /**
54
+ * Realiza la inicialización del worker thread
55
+ */
56
+ async _performWorkerInitialization() {
57
+ try {
58
+ // Obtener ruta al worker thread (compatible con ES modules y Windows)
59
+ const workerPath = path.join(process.env.PATH_PROY || process.cwd(), 'compiler', 'typescript-worker-thread.cjs');
60
+ // console.log('[WorkerManager] Inicializando worker en:', workerPath);
61
+ // Crear el worker thread sin tsx para evitar dependencias externas
62
+ this.worker = new Worker(workerPath, {
63
+ env: {
64
+ ...process.env,
65
+ NODE_OPTIONS: '', // Limpiar NODE_OPTIONS para evitar conflictos con tsx
66
+ },
67
+ });
68
+ // Configurar listeners del worker
69
+ this.setupWorkerListeners();
70
+ // Esperar a que el worker esté listo
71
+ await this.waitForWorkerReady();
72
+ // console.log('[WorkerManager] Worker inicializado exitosamente');
73
+ }
74
+ catch (error) {
75
+ console.error('[WorkerManager] Error inicializando worker:', error);
76
+ this.worker = null;
77
+ this.workerReady = false;
78
+ throw error;
79
+ }
80
+ }
81
+ /**
82
+ * Configura los listeners del worker thread
83
+ */
84
+ setupWorkerListeners() {
85
+ if (!this.worker)
86
+ return;
87
+ this.worker.on('message', (response) => {
88
+ try {
89
+ // console.log('[WorkerManager] Mensaje recibido del worker:', {
90
+ // id: response.id,
91
+ // success: response.success,
92
+ // hasErrors: response.hasErrors,
93
+ // diagnosticsCount: response.diagnostics?.length,
94
+ // });
95
+ // Manejar mensaje de worker ready
96
+ if (response.id === 'worker-ready') {
97
+ this.workerReady = true;
98
+ return;
99
+ }
100
+ // Buscar la tarea pendiente correspondiente
101
+ const pendingTask = this.pendingTasks.get(response.id);
102
+ if (!pendingTask) {
103
+ console.warn('[WorkerManager] Respuesta para tarea desconocida:', response.id);
104
+ return;
105
+ }
106
+ // Limpiar timeout y eliminar tarea pendiente
107
+ clearTimeout(pendingTask.timeout);
108
+ this.pendingTasks.delete(response.id);
109
+ // Procesar respuesta
110
+ if (response.success &&
111
+ response.diagnostics !== undefined &&
112
+ response.hasErrors !== undefined) {
113
+ pendingTask.resolve({
114
+ diagnostics: response.diagnostics,
115
+ hasErrors: response.hasErrors,
116
+ });
117
+ }
118
+ else {
119
+ const errorMessage = response.error || 'Error desconocido del worker';
120
+ pendingTask.reject(new Error(errorMessage));
121
+ }
122
+ }
123
+ catch (error) {
124
+ console.error('[WorkerManager] Error procesando respuesta del worker:', error);
125
+ }
126
+ });
127
+ this.worker.on('error', error => {
128
+ console.error('[WorkerManager] Error en worker thread:', error);
129
+ this.handleWorkerError(error);
130
+ });
131
+ this.worker.on('exit', code => {
132
+ console.warn('[WorkerManager] Worker thread cerrado con código:', code);
133
+ this.workerReady = false;
134
+ // Rechazar todas las tareas pendientes
135
+ this.pendingTasks.forEach(task => {
136
+ clearTimeout(task.timeout);
137
+ task.reject(new Error(`Worker cerrado inesperadamente con código ${code}`));
138
+ });
139
+ this.pendingTasks.clear();
140
+ });
141
+ } /**
142
+ * Espera a que el worker esté listo para recibir tareas
143
+ */
144
+ async waitForWorkerReady() {
145
+ return new Promise((resolve, reject) => {
146
+ // Reducir timeout para inicialización a 5 segundos
147
+ const timeout = setTimeout(() => {
148
+ reject(new Error('Timeout esperando a que el worker esté listo'));
149
+ }, 5000);
150
+ const checkReady = () => {
151
+ if (this.workerReady) {
152
+ clearTimeout(timeout);
153
+ resolve();
154
+ }
155
+ else {
156
+ setTimeout(checkReady, 50); // Verificar cada 50ms (más frecuente)
157
+ }
158
+ };
159
+ checkReady();
160
+ });
161
+ }
162
+ /**
163
+ * Maneja errores del worker thread
164
+ */
165
+ handleWorkerError(error) {
166
+ console.error('[WorkerManager] Manejando error del worker:', error);
167
+ // Rechazar todas las tareas pendientes
168
+ this.pendingTasks.forEach(task => {
169
+ clearTimeout(task.timeout);
170
+ task.reject(new Error(`Error en worker: ${error.message}`));
171
+ });
172
+ this.pendingTasks.clear();
173
+ // Marcar worker como no disponible
174
+ this.workerReady = false;
175
+ }
176
+ /**
177
+ * Genera un ID único para cada tarea
178
+ */
179
+ generateTaskId() {
180
+ return `task-${++this.taskCounter}-${Date.now()}`;
181
+ } /**
182
+ * Realiza type checking usando el worker thread (con fallback síncrono)
183
+ * @param fileName - Nombre del archivo TypeScript
184
+ * @param content - Contenido del archivo
185
+ * @param compilerOptions - Opciones del compilador TypeScript
186
+ * @returns Resultado de la validación de tipos
187
+ */
188
+ async typeCheck(fileName, content, compilerOptions) {
189
+ // En modo de testing o si hay problemas de inicialización, usar fallback directo
190
+ if (process.env.NODE_ENV === 'test' || !this.worker) {
191
+ return this.typeCheckWithSyncFallback(fileName, content, compilerOptions);
192
+ }
193
+ try {
194
+ // Intentar usar el worker thread con timeout más corto
195
+ const workerPromise = this.typeCheckWithWorker(fileName, content, compilerOptions);
196
+ const timeoutPromise = new Promise((resolve, reject) => {
197
+ setTimeout(() => {
198
+ reject(new Error('Worker timeout - usando fallback'));
199
+ }, 5000); // 5 segundos max para worker
200
+ });
201
+ return await Promise.race([workerPromise, timeoutPromise]);
202
+ }
203
+ catch (workerError) {
204
+ const errorMessage = workerError instanceof Error
205
+ ? workerError.message
206
+ : String(workerError);
207
+ console.warn('[WorkerManager] Error en worker, usando fallback síncrono:', errorMessage);
208
+ // Fallback a validación síncrona
209
+ return this.typeCheckWithSyncFallback(fileName, content, compilerOptions);
210
+ }
211
+ }
212
+ /**
213
+ * Realiza type checking usando el worker thread
214
+ */
215
+ async typeCheckWithWorker(fileName, content, compilerOptions) {
216
+ // Asegurar que el worker esté inicializado
217
+ await this.initializeWorker();
218
+ if (!this.worker || !this.workerReady) {
219
+ throw new Error('Worker no disponible');
220
+ }
221
+ return new Promise((resolve, reject) => {
222
+ const taskId = this.generateTaskId();
223
+ // Configurar timeout para la tarea
224
+ const timeout = setTimeout(() => {
225
+ this.pendingTasks.delete(taskId);
226
+ reject(new Error(`Timeout en type checking para ${fileName}`));
227
+ }, this.WORKER_TIMEOUT);
228
+ // Agregar tarea a la lista de pendientes
229
+ this.pendingTasks.set(taskId, {
230
+ resolve,
231
+ reject,
232
+ timeout,
233
+ });
234
+ try {
235
+ // Crear mensaje para el worker
236
+ const message = {
237
+ id: taskId,
238
+ fileName,
239
+ content,
240
+ compilerOptions,
241
+ };
242
+ // console.log('[WorkerManager] Enviando tarea al worker:', {
243
+ // id: taskId,
244
+ // fileName,
245
+ // contentLength: content.length,
246
+ // compilerOptionsKeys: Object.keys(compilerOptions),
247
+ // });
248
+ // Enviar mensaje al worker
249
+ this.worker.postMessage(message);
250
+ }
251
+ catch (error) {
252
+ // Limpiar en caso de error
253
+ clearTimeout(timeout);
254
+ this.pendingTasks.delete(taskId);
255
+ reject(error);
256
+ }
257
+ });
258
+ }
259
+ /**
260
+ * Fallback síncrono para type checking cuando el worker no está disponible
261
+ */
262
+ typeCheckWithSyncFallback(fileName, content, compilerOptions) {
263
+ // console.log(
264
+ // '[WorkerManager] Ejecutando type checking síncrono como fallback',
265
+ // );
266
+ try {
267
+ return validateTypesWithLanguageService(fileName, content, compilerOptions);
268
+ }
269
+ catch (error) {
270
+ console.error('[WorkerManager] Error en fallback síncrono:', error);
271
+ // Devolver resultado vacío en caso de error total
272
+ return {
273
+ diagnostics: [],
274
+ hasErrors: false,
275
+ };
276
+ }
277
+ }
278
+ /**
279
+ * Cierra el worker thread y limpia recursos
280
+ */
281
+ async terminate() {
282
+ if (this.worker) {
283
+ // console.log('[WorkerManager] Cerrando worker thread...');
284
+ // Rechazar todas las tareas pendientes
285
+ this.pendingTasks.forEach(task => {
286
+ clearTimeout(task.timeout);
287
+ task.reject(new Error('Worker manager cerrado'));
288
+ });
289
+ this.pendingTasks.clear();
290
+ // Cerrar worker
291
+ await this.worker.terminate();
292
+ this.worker = null;
293
+ this.workerReady = false;
294
+ this.initPromise = null;
295
+ // console.log('[WorkerManager] Worker cerrado exitosamente');
296
+ }
297
+ }
298
+ /**
299
+ * Obtiene estadísticas del worker manager
300
+ */
301
+ getStats() {
302
+ return {
303
+ workerReady: this.workerReady,
304
+ pendingTasks: this.pendingTasks.size,
305
+ taskCounter: this.taskCounter,
306
+ };
307
+ }
308
+ }
309
+ //# sourceMappingURL=typescript-worker.js.map
@@ -0,0 +1,382 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { env } from 'node:process';
4
+ import * as ts from 'typescript';
5
+ import { createUnifiedErrorMessage, parseTypeScriptErrors, } from './typescript-error-parser.js';
6
+ import { TypeScriptWorkerManager } from './typescript-worker.js';
7
+ /**
8
+ * Cache para la configuración de TypeScript para evitar lecturas repetidas
9
+ */
10
+ let configCache = {};
11
+ /**
12
+ * Carga la configuración de TypeScript desde tsconfig.json
13
+ * @param fileName - Nombre del archivo para buscar el tsconfig.json relativo
14
+ * @returns Opciones del compilador TypeScript
15
+ */
16
+ export const loadTypeScriptConfig = (fileName) => {
17
+ const fileDir = path.dirname(fileName);
18
+ const configPath = ts.findConfigFile(fileDir, ts.sys.fileExists, 'tsconfig.json') ||
19
+ path.resolve(process.cwd(), 'tsconfig.json');
20
+ // Usar cache si el path no ha cambiado
21
+ if (configCache.path === configPath && configCache.options) {
22
+ return configCache.options;
23
+ }
24
+ let compilerOptions;
25
+ if (configPath && fs.existsSync(configPath)) {
26
+ try {
27
+ const { config, error: configError } = ts.readConfigFile(configPath, ts.sys.readFile);
28
+ if (!configError) {
29
+ const parsedConfig = ts.parseJsonConfigFileContent(config, ts.sys, path.dirname(configPath));
30
+ compilerOptions = {
31
+ ...parsedConfig.options,
32
+ // Asegurar opciones básicas necesarias
33
+ allowJs: parsedConfig.options.allowJs !== false,
34
+ esModuleInterop: parsedConfig.options.esModuleInterop !== false,
35
+ allowSyntheticDefaultImports: parsedConfig.options.allowSyntheticDefaultImports !==
36
+ false,
37
+ skipLibCheck: parsedConfig.options.skipLibCheck !== false,
38
+ };
39
+ }
40
+ else {
41
+ throw new Error(`Error al leer tsconfig.json: ${configError.messageText}`);
42
+ }
43
+ }
44
+ catch (error) {
45
+ console.warn(`[loadTypeScriptConfig] Error cargando ${configPath}:`, error);
46
+ // Fallback a opciones por defecto
47
+ compilerOptions = getDefaultCompilerOptions();
48
+ }
49
+ }
50
+ else {
51
+ // Opciones por defecto si no se encuentra tsconfig.json
52
+ compilerOptions = getDefaultCompilerOptions();
53
+ }
54
+ // Guardar en cache
55
+ configCache = { path: configPath, options: compilerOptions };
56
+ return compilerOptions;
57
+ };
58
+ /**
59
+ * Obtiene las opciones por defecto del compilador TypeScript
60
+ */
61
+ const getDefaultCompilerOptions = () => ({
62
+ target: ts.ScriptTarget.ES2020,
63
+ module: ts.ModuleKind.ES2020,
64
+ lib: ['es2020', 'dom', 'dom.iterable'],
65
+ strict: false,
66
+ skipLibCheck: true,
67
+ allowJs: true,
68
+ esModuleInterop: true,
69
+ allowSyntheticDefaultImports: true,
70
+ isolatedModules: true,
71
+ });
72
+ /**
73
+ * Crea una versión optimizada y serializable de las opciones del compilador TypeScript.
74
+ * @param options - Opciones originales del compilador
75
+ * @returns Opciones serializables seguras para workers
76
+ */
77
+ const createSerializableCompilerOptions = (options) => {
78
+ // Usar las opciones del tsconfig.json pero con optimizaciones para el worker
79
+ const { target = ts.ScriptTarget.ES2020, module = ts.ModuleKind.ES2020, lib = ['es2020', 'dom', 'dom.iterable'], allowJs = true, jsx, strict = false, skipLibCheck = true, esModuleInterop = true, allowSyntheticDefaultImports = true, isolatedModules = true, } = options;
80
+ return {
81
+ target,
82
+ module,
83
+ lib: Array.isArray(lib) ? lib : ['es2020', 'dom', 'dom.iterable'],
84
+ allowJs,
85
+ jsx,
86
+ strict,
87
+ skipLibCheck,
88
+ skipDefaultLibCheck: true,
89
+ esModuleInterop,
90
+ allowSyntheticDefaultImports,
91
+ isolatedModules,
92
+ noEmitOnError: false,
93
+ declaration: false,
94
+ sourceMap: false,
95
+ };
96
+ };
97
+ /**
98
+ * Crea un Language Service Host optimizado para validación de tipos eficiente.
99
+ */
100
+ class TypeScriptLanguageServiceHost {
101
+ files = new Map();
102
+ compilerOptions;
103
+ fileSystemCache = new Map();
104
+ constructor(compilerOptions) {
105
+ this.compilerOptions = compilerOptions;
106
+ }
107
+ addFile(fileName, content) {
108
+ const existing = this.files.get(fileName);
109
+ this.files.set(fileName, {
110
+ version: existing ? existing.version + 1 : 1,
111
+ content,
112
+ });
113
+ }
114
+ getCompilationSettings() {
115
+ return this.compilerOptions;
116
+ }
117
+ getScriptFileNames() {
118
+ return Array.from(this.files.keys());
119
+ }
120
+ getScriptVersion(fileName) {
121
+ const file = this.files.get(fileName);
122
+ return file ? file.version.toString() : '0';
123
+ }
124
+ getScriptSnapshot(fileName) {
125
+ const file = this.files.get(fileName);
126
+ if (file) {
127
+ return ts.ScriptSnapshot.fromString(file.content);
128
+ }
129
+ // Cache de sistema de archivos para evitar lecturas repetidas
130
+ if (this.fileSystemCache.has(fileName)) {
131
+ const cachedContent = this.fileSystemCache.get(fileName);
132
+ return cachedContent
133
+ ? ts.ScriptSnapshot.fromString(cachedContent)
134
+ : undefined;
135
+ }
136
+ // Intentar leer el archivo del sistema de archivos solo si es necesario
137
+ try {
138
+ if (fs.existsSync(fileName)) {
139
+ const content = fs.readFileSync(fileName, 'utf-8');
140
+ this.fileSystemCache.set(fileName, content);
141
+ return ts.ScriptSnapshot.fromString(content);
142
+ }
143
+ }
144
+ catch {
145
+ // Error al leer archivo
146
+ }
147
+ this.fileSystemCache.set(fileName, undefined);
148
+ return undefined;
149
+ }
150
+ getCurrentDirectory() {
151
+ return process.cwd();
152
+ }
153
+ getDefaultLibFileName(options) {
154
+ return ts.getDefaultLibFilePath(options);
155
+ }
156
+ fileExists(path) {
157
+ if (this.files.has(path))
158
+ return true;
159
+ if (this.fileSystemCache.has(path)) {
160
+ return this.fileSystemCache.get(path) !== undefined;
161
+ }
162
+ const exists = fs.existsSync(path);
163
+ if (!exists)
164
+ this.fileSystemCache.set(path, undefined);
165
+ return exists;
166
+ }
167
+ readFile(path) {
168
+ const file = this.files.get(path);
169
+ if (file)
170
+ return file.content;
171
+ if (this.fileSystemCache.has(path)) {
172
+ return this.fileSystemCache.get(path);
173
+ }
174
+ try {
175
+ if (fs.existsSync(path)) {
176
+ const content = fs.readFileSync(path, 'utf-8');
177
+ this.fileSystemCache.set(path, content);
178
+ return content;
179
+ }
180
+ }
181
+ catch {
182
+ // Error al leer archivo
183
+ }
184
+ this.fileSystemCache.set(path, undefined);
185
+ return undefined;
186
+ }
187
+ getNewLine() {
188
+ return ts.sys.newLine;
189
+ }
190
+ }
191
+ /**
192
+ * Realiza validación de tipos optimizada usando TypeScript Language Service.
193
+ * @param fileName - Nombre del archivo
194
+ * @param content - Contenido del archivo
195
+ * @param compilerOptions - Opciones del compilador
196
+ * @returns Resultado de la validación de tipos
197
+ */
198
+ const validateTypesWithLanguageService = (fileName, content, compilerOptions) => {
199
+ try {
200
+ // Validación temprana: contenido vacío
201
+ if (!content.trim()) {
202
+ return { diagnostics: [], hasErrors: false };
203
+ }
204
+ // Crear Language Service Host optimizado
205
+ const host = new TypeScriptLanguageServiceHost(compilerOptions);
206
+ // Determinar nombre de archivo efectivo
207
+ let actualFileName = path.isAbsolute(fileName)
208
+ ? fileName
209
+ : path.resolve(fileName);
210
+ // Para archivos Vue, crear archivo virtual
211
+ if (fileName.endsWith('.vue')) {
212
+ actualFileName = actualFileName.replace('.vue', '.vue.ts');
213
+ host.addFile(actualFileName, content);
214
+ // Añadir declaraciones Vue básicas solo si es necesario
215
+ const vueTypesPath = path.join(path.dirname(actualFileName), 'vue-types.d.ts');
216
+ const vueTypesDeclaration = `
217
+ declare global {
218
+ function ref<T>(value: T): { value: T };
219
+ function reactive<T extends object>(target: T): T;
220
+ function computed<T>(getter: () => T): { value: T };
221
+ function defineComponent<T>(options: T): T;
222
+ function defineProps<T = {}>(): T;
223
+ function defineEmits<T = {}>(): T;
224
+ function onMounted(fn: () => void): void;
225
+ function onUnmounted(fn: () => void): void;
226
+ function watch<T>(source: () => T, callback: (newValue: T, oldValue: T) => void): void;
227
+ }
228
+ export {};`;
229
+ host.addFile(vueTypesPath, vueTypesDeclaration);
230
+ }
231
+ else {
232
+ host.addFile(actualFileName, content);
233
+ }
234
+ // Crear Language Service
235
+ const languageService = ts.createLanguageService(host);
236
+ // Verificar existencia del archivo
237
+ if (!host.fileExists(actualFileName)) {
238
+ return { diagnostics: [], hasErrors: false };
239
+ }
240
+ // Obtener diagnósticos con manejo de errores optimizado
241
+ const allDiagnostics = [];
242
+ try {
243
+ allDiagnostics.push(...languageService.getSyntacticDiagnostics(actualFileName));
244
+ allDiagnostics.push(...languageService.getSemanticDiagnostics(actualFileName));
245
+ }
246
+ catch {
247
+ // Ignorar errores de diagnósticos
248
+ return { diagnostics: [], hasErrors: false };
249
+ }
250
+ // Filtrado optimizado de diagnósticos
251
+ const filteredDiagnostics = allDiagnostics.filter(diag => {
252
+ if (diag.category !== ts.DiagnosticCategory.Error)
253
+ return false;
254
+ const messageText = ts.flattenDiagnosticMessageText(diag.messageText, '\n');
255
+ // Lista optimizada de patrones a ignorar
256
+ const ignorePatterns = [
257
+ 'Cannot find module',
258
+ 'Could not find source file',
259
+ "Parameter '$props' implicitly has an 'any' type",
260
+ "Parameter '$setup' implicitly has an 'any' type",
261
+ "Parameter '_ctx' implicitly has an 'any' type",
262
+ "Parameter '_cache' implicitly has an 'any' type",
263
+ ];
264
+ return !ignorePatterns.some(pattern => messageText.includes(pattern));
265
+ });
266
+ return {
267
+ diagnostics: filteredDiagnostics,
268
+ hasErrors: filteredDiagnostics.length > 0,
269
+ };
270
+ }
271
+ catch (error) {
272
+ // Error handling simplificado
273
+ return {
274
+ diagnostics: [
275
+ {
276
+ file: undefined,
277
+ start: undefined,
278
+ length: undefined,
279
+ messageText: `Error en validación de tipos: ${error instanceof Error ? error.message : 'Error desconocido'}`,
280
+ category: ts.DiagnosticCategory.Error,
281
+ code: 0,
282
+ },
283
+ ],
284
+ hasErrors: true,
285
+ };
286
+ }
287
+ };
288
+ /**
289
+ * Valida tipos en archivos Vue antes de la compilación
290
+ * @param vueContent - Contenido del archivo Vue
291
+ * @param fileName - Nombre del archivo Vue
292
+ * @returns Resultado de la validación de tipos
293
+ */
294
+ export const validateVueTypes = (vueContent, fileName) => {
295
+ const compilerOptions = loadTypeScriptConfig(fileName);
296
+ return validateTypesWithLanguageService(fileName, vueContent, compilerOptions);
297
+ };
298
+ /**
299
+ * Precompila el código TypeScript con pipeline optimizado para máxima performance.
300
+ * @param {string} data - El código TypeScript a precompilar.
301
+ * @param {string} fileName - El nombre del archivo que contiene el código TypeScript.
302
+ * @returns {Promise<CompileResult>} - Un objeto con el código precompilado o un error.
303
+ */
304
+ export const preCompileTS = async (data, fileName) => {
305
+ try {
306
+ // Validación temprana: contenido vacío
307
+ if (!data.trim()) {
308
+ return { error: null, data: data, lang: 'ts' };
309
+ }
310
+ // Cargar configuración de TypeScript desde tsconfig.json
311
+ const compilerOptions = loadTypeScriptConfig(fileName);
312
+ // PASO 1: Transpilación rápida con detección de errores críticos
313
+ const transpileResult = ts.transpileModule(data, {
314
+ compilerOptions: {
315
+ ...compilerOptions,
316
+ noLib: true,
317
+ skipLibCheck: true,
318
+ isolatedModules: true,
319
+ },
320
+ fileName,
321
+ reportDiagnostics: true,
322
+ });
323
+ // const transpileResult = traspileTStoJS(
324
+ // fileName,data)
325
+ // Verificar errores críticos de sintaxis
326
+ if (transpileResult.diagnostics?.length) {
327
+ const criticalErrors = transpileResult.diagnostics.filter(diag => {
328
+ if (diag.category !== ts.DiagnosticCategory.Error)
329
+ return false;
330
+ const messageText = ts.flattenDiagnosticMessageText(diag.messageText, '\n');
331
+ // Ignorar errores de módulo no encontrado
332
+ return (!messageText.includes('Cannot find module') &&
333
+ !messageText.includes('Could not find source file') &&
334
+ diag.code !== 2307 &&
335
+ diag.code !== 6059);
336
+ });
337
+ if (criticalErrors.length > 0) {
338
+ const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(criticalErrors, fileName, data));
339
+ return {
340
+ error: new Error(errorMessage),
341
+ data: null,
342
+ lang: 'ts',
343
+ };
344
+ }
345
+ }
346
+ // PASO 2: Type checking opcional (solo si está habilitado)
347
+ if (env.typeCheck === 'true') {
348
+ try {
349
+ const workerManager = TypeScriptWorkerManager.getInstance();
350
+ const serializableOptions = createSerializableCompilerOptions(compilerOptions);
351
+ const typeCheckResult = await workerManager.typeCheck(fileName, data, serializableOptions);
352
+ if (typeCheckResult.hasErrors) {
353
+ const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(typeCheckResult.diagnostics, fileName, data));
354
+ return {
355
+ error: new Error(errorMessage),
356
+ data: null,
357
+ lang: 'ts',
358
+ };
359
+ }
360
+ }
361
+ catch (typeCheckError) {
362
+ // Type checking falla, pero continuar con transpilación
363
+ console.warn('[preCompileTS] Type checking failed:', typeCheckError);
364
+ }
365
+ }
366
+ // PASO 3: Devolver resultado optimizado
367
+ const output = transpileResult.outputText;
368
+ // Limpiar output vacío
369
+ if (output.trim() === 'export {};') {
370
+ return { error: null, data: '', lang: 'ts' };
371
+ }
372
+ return { error: null, data: output, lang: 'ts' };
373
+ }
374
+ catch (error) {
375
+ return {
376
+ error: error instanceof Error ? error : new Error('Error desconocido'),
377
+ data: null,
378
+ lang: 'ts',
379
+ };
380
+ }
381
+ };
382
+ //# sourceMappingURL=typescript.js.map