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.
Files changed (41) hide show
  1. package/README.md +1 -1
  2. package/dist/compiler/compile.js +2520 -26
  3. package/dist/compiler/error-reporter.js +467 -38
  4. package/dist/compiler/linter.js +72 -1
  5. package/dist/compiler/minify.js +272 -1
  6. package/dist/compiler/minifyTemplate.js +230 -0
  7. package/dist/compiler/module-resolution-optimizer.js +844 -1
  8. package/dist/compiler/parser.js +336 -1
  9. package/dist/compiler/performance-monitor.js +204 -56
  10. package/dist/compiler/tailwindcss.js +39 -1
  11. package/dist/compiler/transform-optimizer.js +392 -1
  12. package/dist/compiler/transformTStoJS.js +16 -1
  13. package/dist/compiler/transforms.js +554 -1
  14. package/dist/compiler/typescript-compiler.js +172 -2
  15. package/dist/compiler/typescript-error-parser.js +281 -10
  16. package/dist/compiler/typescript-manager.js +304 -2
  17. package/dist/compiler/typescript-sync-validator.js +295 -31
  18. package/dist/compiler/typescript-worker-pool.js +936 -1
  19. package/dist/compiler/typescript-worker-thread.cjs +466 -41
  20. package/dist/compiler/typescript-worker.js +339 -1
  21. package/dist/compiler/vuejs.js +396 -37
  22. package/dist/hrm/VueHRM.js +359 -1
  23. package/dist/hrm/errorScreen.js +83 -1
  24. package/dist/hrm/getInstanciaVue.js +313 -1
  25. package/dist/hrm/initHRM.js +586 -1
  26. package/dist/main.js +353 -7
  27. package/dist/servicios/browserSync.js +587 -5
  28. package/dist/servicios/file-watcher.js +425 -4
  29. package/dist/servicios/logger.js +63 -3
  30. package/dist/servicios/readConfig.js +399 -105
  31. package/dist/utils/excluded-modules.js +37 -1
  32. package/dist/utils/module-resolver.js +466 -1
  33. package/dist/utils/promptUser.js +48 -2
  34. package/dist/utils/proxyValidator.js +68 -1
  35. package/dist/utils/resolve-bin.js +58 -1
  36. package/dist/utils/utils.js +21 -1
  37. package/dist/utils/vue-types-setup.js +435 -241
  38. package/dist/wrappers/eslint-node.js +147 -1
  39. package/dist/wrappers/oxlint-node.js +122 -1
  40. package/dist/wrappers/tailwind-node.js +94 -1
  41. package/package.json +39 -42
@@ -1,37 +1,396 @@
1
- import{createHash as e}from"node:crypto";import t from"node:path";import*as n from"vue/compiler-sfc";const r=n;import{logger as i}from"../servicios/logger.js";import{parser as a}from"./parser.js";let o;async function s(){return o||=(await import(`chalk`)).default,o}class c{static instance;cache=new Map;MAX_CACHE_SIZE=100;CACHE_TTL=300*1e3;static getInstance(){return c.instance||=new c,c.instance}generateContentHash(t){return e(`md5`).update(t).digest(`hex`)}getOrGenerateHMRInjection(e,t){let n=this.generateContentHash(e),r=`${t}:${n}`,i=this.cache.get(r);if(i&&Date.now()-i.timestamp<this.CACHE_TTL)return{injectedData:i.injectedCode,cached:!0};let a=/import\s*\{[^}]*\bref\b[^}]*\}\s*from\s*['"]vue['"]/,o=a.test(e),s=`
2
- ${o?``:`import { ref } from "/node_modules/vue/dist/vue.esm-browser.js";`}
3
- const versaComponentKey = ref(0);
4
- `,c,l=e.includes(`<script`);return c=l?e.replace(/(<script.*?>)/,`$1${s}`):`<script setup lang="ts">${s}<\/script>/n`+e,c=c.replace(/(<template[^>]*>[\s\S]*?)(<(\w+)([^>]*?))(\/?>)/,(e,t,n,r,i,a)=>{if(i.includes(`:key=`)||i.includes(`key=`))return e;let o=a===`/>`;return o?`${t}<${r}${i} :key="versaComponentKey" />`:`${t}<${r}${i} :key="versaComponentKey">`}),this.cache.set(r,{contentHash:n,injectedCode:c,hasRefImport:o,timestamp:Date.now()}),this.evictIfNeeded(),{injectedData:c,cached:!1}}evictIfNeeded(){if(this.cache.size<=this.MAX_CACHE_SIZE)return;let e=Array.from(this.cache.entries());e.sort((e,t)=>e[1].timestamp-t[1].timestamp);let t=e.slice(0,e.length-this.MAX_CACHE_SIZE);t.forEach(([e])=>this.cache.delete(e))}cleanExpired(){let e=Date.now();for(let[t,n]of this.cache.entries())e-n.timestamp>this.CACHE_TTL&&this.cache.delete(t)}getStats(){return{size:this.cache.size,maxSize:this.MAX_CACHE_SIZE,ttl:this.CACHE_TTL}}clear(){this.cache.clear()}}const l=c.getInstance(),u=async e=>{let t=[],n=e?.module?.staticImports;if(n){let e=n.filter(e=>e.moduleRequest.value.endsWith(`.vue`));t=e.map(e=>e.entries.map(e=>e.localName.value)),t=t.flat()}return t};export const preCompileVue=async(e,n,o=!1)=>{try{let c=t.basename(n).replace(`.vue`,``);if(!e||e.trim().length===0)return{error:null,data:`export default {};`,lang:`js`};if(!o){let{injectedData:t}=l.getOrGenerateHMRInjection(e,c);e=t}let{descriptor:d,errors:f}=r.parse(e,{filename:c,sourceMap:!o,sourceRoot:t.dirname(n)});if(f.length)throw Error(`Error al analizar el componente Vue ${n}:\n${f.map(e=>e.message).join(`
5
- `)}`);let p=Math.random().toString(36).slice(2,12),m=d.styles.some(e=>e.scoped)?`data-v-${p}`:null,h,g=`js`,_,v;if(d.script||d.scriptSetup){v=d.script?`script`:`scriptSetup`;let e=d.script||d.scriptSetup,t={id:p,isProd:o,sourceMap:!o,inlineTemplate:!1,propsDestructure:!0,templateOptions:{compilerOptions:{mode:`module`,scopeId:m,prefixIdentifiers:!0,hoistStatic:o,cacheHandlers:o,nodeTransforms:[],directiveTransforms:{}},transformAssetUrls:!0},customElement:!1},n=r.compileScript(d,t);h=n.content,g=e.lang?.toLowerCase()===`ts`||e.lang?.toLowerCase()===`typescript`?`ts`:`js`,_=n.bindings}else h=`export default {};`,g=`js`;let y=await a(`temp.${g}`,h,g);if(y?.errors.length>0)throw Error(`Error al analizar el script del componente Vue ${n}:\n${y.errors.map(e=>e.message).join(`
6
- `)}`);let b=await u(y);_&&Object.keys(_).forEach(e=>{b.includes(e)&&delete _[e]});let x=``;if(d.template){let e={source:d.template.content,filename:`${c}.vue`,id:p,scoped:!!m,slotted:d.slotted,isProd:o,compilerOptions:{scopeId:m,mode:`module`,bindingMetadata:_,prefixIdentifiers:!0,hoistStatic:o,cacheHandlers:o,runtimeGlobalName:`Vue`,runtimeModuleName:`/node_modules/vue/dist/vue.esm-browser.js`,whitespace:`condense`,ssr:!1,nodeTransforms:[],directiveTransforms:{}}},t=r.compileTemplate(e);t.errors?.length>0&&i.error(`Template compilation errors:`,t.errors),x=t.code}else{let e=await s();i.warn(e.yellow(`Advertencia: El componente Vue ${n} no tiene una sección de plantilla.`))}let S={content:h,lang:g,type:v},C={code:x},w=``;d.customBlocks.length>0&&(w=d.customBlocks[0]?.content.slice(0,-1)??``);let T=d.styles.map(e=>{let t=e.lang?.toLowerCase(),n;return(t===`scss`||t===`sass`||t===`less`||t===`styl`||t===`stylus`)&&(n=t),r.compileStyle({id:p,source:e.content,scoped:e.scoped,preprocessLang:n,isProd:o,trim:!0,filename:`${c}.vue`})}),E=T.length?`(function(){
7
- let styleTag = document.createElement('style');
8
- styleTag.setAttribute('data-v-${p}', '');
9
- styleTag.innerHTML = \`${T.map(e=>e.code).join(`
10
- `)}\`;
11
- document.head.appendChild(styleTag);
12
- })();`:``,D=`
13
- ${E}
14
- ${S.content}
15
- ${C.code}
16
- `,O=c.replace(/[^a-zA-Z0-9_$]/g,``).replace(/^[0-9]/,`_$&`)||`component`,k=`${O}_component`,A=/name\s*:\s*['"`]/.test(D),j=/components\s*:\s*\{/.test(D),M=`
17
- __file: '${n}',
18
- __name: '${c}',
19
- ${A?``:`name: '${c}',`}
20
- ${j?``:`components: {
21
- ${b.map(e=>`${e}`).join(`,
22
- `)}
23
- },`}
24
- `;D.includes(`export default {`)?D=D.replace(`export default {`,`const ${k} = {
25
- \n${M}
26
- `):D.includes(`export default defineComponent({`)?D=D.replace(`export default defineComponent({`,`const ${k} = defineComponent({
27
- \n${M}
28
- `):D.includes(`const default = /*@__PURE__*/_defineComponent({`)?D=D.replace(`const default = /*@__PURE__*/_defineComponent({`,`const ${k} = /*@__PURE__*/_defineComponent({
29
- \n${M}
30
- `):D.includes(`export default /*@__PURE__*/_defineComponent({`)&&(D=D.replace(`export default /*@__PURE__*/_defineComponent({`,`const ${k} = /*@__PURE__*/_defineComponent({
31
- \n${M}
32
- `)),D.includes(`export function render`)&&(D=D.replace(`export function render`,`function render_${k}`));let N=D.includes(`render_${k}`)||D.includes(`function render(`);!N&&d.template&&i.warn(`Warning: No render function found in compiled output`);let P=`
33
- ${N?`${k}.render = render_${k};`:``}
34
- ${m?`${k}.__scopeId = '${m}';`:``}
35
- ${w}
36
-
37
- export default ${k}; `;return D=`${D}\n${P}`,{lang:S.lang,error:null,data:D}}catch(e){return i.error(`Vue compilation error:`,e),{lang:null,error:e instanceof Error?e:Error(String(e)),data:null}}};export const getVueHMRCacheStats=()=>l.getStats();export const clearVueHMRCache=()=>{l.clear()};export const cleanExpiredVueHMRCache=()=>{l.cleanExpired()};
1
+ import { createHash } from 'node:crypto';
2
+ import path from 'node:path';
3
+ import * as vCompiler from 'vue/compiler-sfc';
4
+ // Type casting para evitar problemas de tipos con Vue SFC
5
+ const vueCompiler = vCompiler;
6
+ import { logger } from '../servicios/logger.js';
7
+ import { parser } from './parser.js';
8
+ // Lazy loading para chalk
9
+ let chalk;
10
+ async function loadChalk() {
11
+ if (!chalk) {
12
+ chalk = (await import('chalk')).default;
13
+ }
14
+ return chalk;
15
+ }
16
+ class VueHMRInjectionCache {
17
+ static instance;
18
+ cache = new Map();
19
+ MAX_CACHE_SIZE = 100;
20
+ CACHE_TTL = 5 * 60 * 1000; // 5 minutos
21
+ static getInstance() {
22
+ if (!VueHMRInjectionCache.instance) {
23
+ VueHMRInjectionCache.instance = new VueHMRInjectionCache();
24
+ }
25
+ return VueHMRInjectionCache.instance;
26
+ }
27
+ /**
28
+ * Genera un hash del contenido original para detectar cambios
29
+ */
30
+ generateContentHash(data) {
31
+ return createHash('md5').update(data).digest('hex');
32
+ }
33
+ /**
34
+ * Obtiene código HMR inyectado desde cache o lo genera
35
+ */
36
+ getOrGenerateHMRInjection(originalData, fileName) {
37
+ const contentHash = this.generateContentHash(originalData);
38
+ const cacheKey = `${fileName}:${contentHash}`;
39
+ // Verificar cache
40
+ const cached = this.cache.get(cacheKey);
41
+ if (cached && Date.now() - cached.timestamp < this.CACHE_TTL) {
42
+ return {
43
+ injectedData: cached.injectedCode,
44
+ cached: true,
45
+ };
46
+ }
47
+ // Generar nueva inyección HMR
48
+ const vueImportPattern = /import\s*\{[^}]*\bref\b[^}]*\}\s*from\s*['"]vue['"]/;
49
+ const hasRefImport = vueImportPattern.test(originalData);
50
+ const varContent = `
51
+ ${hasRefImport ? '' : 'import { ref } from "/node_modules/vue/dist/vue.esm-browser.js";'}
52
+ const versaComponentKey = ref(0);
53
+ `;
54
+ let injectedData;
55
+ const ifExistScript = originalData.includes('<script');
56
+ if (!ifExistScript) {
57
+ injectedData =
58
+ `<script setup lang="ts">${varContent}</script>/n` +
59
+ originalData;
60
+ }
61
+ else {
62
+ injectedData = originalData.replace(/(<script.*?>)/, `$1${varContent}`);
63
+ }
64
+ // Inyectar :key en el template
65
+ injectedData = injectedData.replace(/(<template[^>]*>[\s\S]*?)(<(\w+)([^>]*?))(\/?>)/, (match, p1, p2, p3, p4, p5) => {
66
+ if (p4.includes(':key=') || p4.includes('key=')) {
67
+ return match;
68
+ }
69
+ const isSelfClosing = p5 === '/>';
70
+ if (isSelfClosing) {
71
+ return `${p1}<${p3}${p4} :key="versaComponentKey" />`;
72
+ }
73
+ else {
74
+ return `${p1}<${p3}${p4} :key="versaComponentKey">`;
75
+ }
76
+ });
77
+ // Cachear resultado
78
+ this.cache.set(cacheKey, {
79
+ contentHash,
80
+ injectedCode: injectedData,
81
+ hasRefImport,
82
+ timestamp: Date.now(),
83
+ });
84
+ // Limpiar cache si es necesario
85
+ this.evictIfNeeded();
86
+ return {
87
+ injectedData,
88
+ cached: false,
89
+ };
90
+ }
91
+ /**
92
+ * Limpia entradas de cache cuando se excede el límite
93
+ */
94
+ evictIfNeeded() {
95
+ if (this.cache.size <= this.MAX_CACHE_SIZE)
96
+ return;
97
+ const entries = Array.from(this.cache.entries());
98
+ entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
99
+ // Eliminar las entradas más antiguas
100
+ const toDelete = entries.slice(0, entries.length - this.MAX_CACHE_SIZE);
101
+ toDelete.forEach(([key]) => this.cache.delete(key));
102
+ }
103
+ /**
104
+ * Limpia entradas expiradas
105
+ */
106
+ cleanExpired() {
107
+ const now = Date.now();
108
+ for (const [key, entry] of this.cache.entries()) {
109
+ if (now - entry.timestamp > this.CACHE_TTL) {
110
+ this.cache.delete(key);
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Obtiene estadísticas del cache
116
+ */
117
+ getStats() {
118
+ return {
119
+ size: this.cache.size,
120
+ maxSize: this.MAX_CACHE_SIZE,
121
+ ttl: this.CACHE_TTL,
122
+ };
123
+ }
124
+ /**
125
+ * Limpia todo el cache
126
+ */
127
+ clear() {
128
+ this.cache.clear();
129
+ }
130
+ }
131
+ // Instancia global del cache HMR
132
+ const hmrInjectionCache = VueHMRInjectionCache.getInstance();
133
+ const getComponentsVueMap = async (ast) => {
134
+ let components = [];
135
+ const importsStatic = ast?.module?.staticImports;
136
+ if (importsStatic) {
137
+ const vueImports = importsStatic.filter((item) => item.moduleRequest.value.endsWith('.vue'));
138
+ components = vueImports.map((item) => {
139
+ return item.entries.map((entry) => entry.localName.value);
140
+ });
141
+ components = components.flat();
142
+ }
143
+ return components;
144
+ };
145
+ /**
146
+ * Precompila un componente Vue.
147
+ * @param {string} data - El código del componente Vue.
148
+ * @param {string} source - La fuente del componente Vue.
149
+ * @returns {Promise<Object>} - Un objeto con el código precompilado o un error.
150
+ */
151
+ export const preCompileVue = async (data, source, isProd = false) => {
152
+ try {
153
+ const fileName = path.basename(source).replace('.vue', '');
154
+ if (!data || data.trim().length === 0) {
155
+ return {
156
+ error: null,
157
+ data: 'export default {};',
158
+ lang: 'js',
159
+ };
160
+ }
161
+ if (!isProd) {
162
+ const { injectedData } = hmrInjectionCache.getOrGenerateHMRInjection(data, fileName);
163
+ data = injectedData;
164
+ }
165
+ const { descriptor, errors } = vueCompiler.parse(data, {
166
+ filename: fileName,
167
+ sourceMap: !isProd,
168
+ sourceRoot: path.dirname(source),
169
+ templateParseOptions: {
170
+ comments: !isProd, // ✨ Eliminar comentarios HTML del template
171
+ },
172
+ });
173
+ if (errors.length) {
174
+ throw new Error(`Error al analizar el componente Vue ${source}:\n${errors.map((e) => e.message).join('\n')}`);
175
+ }
176
+ const id = Math.random().toString(36).slice(2, 12);
177
+ const scopeId = descriptor.styles.some((s) => s.scoped)
178
+ ? `data-v-${id}`
179
+ : null;
180
+ // --- 1. Compilación del Script ---
181
+ let scriptContent;
182
+ let scriptLang = 'js';
183
+ let scriptBindings;
184
+ let scriptType;
185
+ if (descriptor.script || descriptor.scriptSetup) {
186
+ scriptType = descriptor.script ? 'script' : 'scriptSetup';
187
+ const scriptToCompile = descriptor.script || descriptor.scriptSetup;
188
+ const scriptCompileOptions = {
189
+ id,
190
+ isProd,
191
+ sourceMap: !isProd,
192
+ inlineTemplate: false, // Siempre compilar por separado para tener control
193
+ propsDestructure: true,
194
+ templateOptions: {
195
+ compilerOptions: {
196
+ mode: 'module',
197
+ scopeId,
198
+ prefixIdentifiers: true,
199
+ hoistStatic: isProd,
200
+ cacheHandlers: isProd,
201
+ nodeTransforms: [],
202
+ directiveTransforms: {},
203
+ },
204
+ transformAssetUrls: true,
205
+ },
206
+ customElement: false,
207
+ };
208
+ const compiledScriptResult = vueCompiler.compileScript(descriptor, scriptCompileOptions);
209
+ scriptContent = compiledScriptResult.content;
210
+ scriptLang =
211
+ scriptToCompile.lang?.toLowerCase() === 'ts' ||
212
+ scriptToCompile.lang?.toLowerCase() === 'typescript'
213
+ ? 'ts'
214
+ : 'js';
215
+ scriptBindings = compiledScriptResult.bindings;
216
+ }
217
+ else {
218
+ scriptContent = 'export default {};';
219
+ scriptLang = 'js';
220
+ }
221
+ const ast = await parser(`temp.${scriptLang}`, scriptContent, scriptLang);
222
+ if (ast?.errors.length > 0) {
223
+ throw new Error(`Error al analizar el script del componente Vue ${source}:\n${ast.errors
224
+ .map((e) => e.message)
225
+ .join('\n')}`);
226
+ }
227
+ const components = await getComponentsVueMap(ast);
228
+ if (scriptBindings) {
229
+ Object.keys(scriptBindings).forEach(key => {
230
+ if (components.includes(key)) {
231
+ delete scriptBindings[key];
232
+ }
233
+ });
234
+ } // --- 2. Compilación de la Plantilla (CORREGIDA) ---
235
+ let templateCode = '';
236
+ if (descriptor.template) {
237
+ const templateCompileOptions = {
238
+ source: descriptor.template.content,
239
+ filename: `${fileName}.vue`,
240
+ id,
241
+ scoped: !!scopeId,
242
+ slotted: descriptor.slotted,
243
+ isProd,
244
+ compilerOptions: {
245
+ scopeId,
246
+ mode: 'module',
247
+ bindingMetadata: scriptBindings,
248
+ prefixIdentifiers: true,
249
+ hoistStatic: isProd,
250
+ cacheHandlers: isProd,
251
+ runtimeGlobalName: 'Vue',
252
+ runtimeModuleName: '/node_modules/vue/dist/vue.esm-browser.js',
253
+ whitespace: 'condense',
254
+ ssr: false,
255
+ comments: !isProd, // ✨ Eliminar comentarios HTML del template
256
+ nodeTransforms: [],
257
+ directiveTransforms: {},
258
+ },
259
+ };
260
+ const compiledTemplateResult = vueCompiler.compileTemplate(templateCompileOptions);
261
+ if (compiledTemplateResult.errors?.length > 0) {
262
+ logger.error('Template compilation errors:', compiledTemplateResult.errors);
263
+ }
264
+ templateCode = compiledTemplateResult.code;
265
+ }
266
+ else {
267
+ const chalkInstance = await loadChalk();
268
+ logger.warn(chalkInstance.yellow(`Advertencia: El componente Vue ${source} no tiene una sección de plantilla.`));
269
+ }
270
+ const finalCompiledScript = {
271
+ content: scriptContent,
272
+ lang: scriptLang,
273
+ type: scriptType,
274
+ };
275
+ const finalCompiledTemplate = {
276
+ code: templateCode,
277
+ };
278
+ let customBlocks = '';
279
+ if (descriptor.customBlocks.length > 0) {
280
+ customBlocks =
281
+ descriptor.customBlocks[0]?.content.slice(0, -1) ?? '';
282
+ }
283
+ // Compile styles
284
+ const compiledStyles = descriptor.styles.map((style) => {
285
+ const lang = style.lang?.toLowerCase();
286
+ let currentPreprocessLang = undefined;
287
+ if (lang === 'scss' ||
288
+ lang === 'sass' ||
289
+ lang === 'less' ||
290
+ lang === 'styl' ||
291
+ lang === 'stylus') {
292
+ currentPreprocessLang = lang;
293
+ }
294
+ return vueCompiler.compileStyle({
295
+ id,
296
+ source: style.content,
297
+ scoped: style.scoped,
298
+ preprocessLang: currentPreprocessLang,
299
+ isProd,
300
+ trim: true,
301
+ filename: `${fileName}.vue`,
302
+ });
303
+ });
304
+ const insertStyles = compiledStyles.length
305
+ ? `(function(){
306
+ let styleTag = document.createElement('style');
307
+ styleTag.setAttribute('data-v-${id}', '');
308
+ styleTag.innerHTML = \`${compiledStyles.map((s) => s.code).join('\n')}\`;
309
+ document.head.appendChild(styleTag);
310
+ })();`
311
+ : '';
312
+ let output = `
313
+ ${insertStyles}
314
+ ${finalCompiledScript.content}
315
+ ${finalCompiledTemplate.code}
316
+ `; // Sanitizar el nombre del archivo para crear un nombre de variable JavaScript válido
317
+ const sanitizedFileName = fileName.replace(/[^a-zA-Z0-9_$]/g, '').replace(/^[0-9]/, '_$&') ||
318
+ 'component';
319
+ const componentName = `${sanitizedFileName}_component`; // Verificar si ya existe una propiedad 'name' en el output
320
+ const hasNameProperty = /name\s*:\s*['"`]/.test(output);
321
+ // Verificar si ya existe una propiedad 'components' en el output
322
+ const hasComponentsProperty = /components\s*:\s*\{/.test(output);
323
+ const exportComponent = `
324
+ __file: '${source}',
325
+ __name: '${fileName}',
326
+ ${hasNameProperty ? '' : `name: '${fileName}',`}
327
+ ${hasComponentsProperty
328
+ ? ''
329
+ : `components: {
330
+ ${components.map(comp => `${comp}`).join(',\n ')}
331
+ },`}
332
+ `;
333
+ // MEJORAR: Manejo más robusto de export default
334
+ if (output.includes('export default {')) {
335
+ output = output.replace('export default {', `const ${componentName} = {
336
+ \n${exportComponent}
337
+ `);
338
+ }
339
+ else if (output.includes('export default defineComponent({')) {
340
+ output = output.replace('export default defineComponent({', `const ${componentName} = defineComponent({
341
+ \n${exportComponent}
342
+ `);
343
+ }
344
+ else if (output.includes('const default = /*@__PURE__*/_defineComponent({')) {
345
+ output = output.replace('const default = /*@__PURE__*/_defineComponent({', `const ${componentName} = /*@__PURE__*/_defineComponent({
346
+ \n${exportComponent}
347
+ `);
348
+ }
349
+ else if (output.includes('export default /*@__PURE__*/_defineComponent({')) {
350
+ output = output.replace('export default /*@__PURE__*/_defineComponent({', `const ${componentName} = /*@__PURE__*/_defineComponent({
351
+ \n${exportComponent}
352
+ `);
353
+ }
354
+ // MEJORAR: Manejo más robusto de render function
355
+ if (output.includes('export function render')) {
356
+ output = output.replace('export function render', `function render_${componentName}`);
357
+ }
358
+ // AÑADIR: Verificar si render fue generado correctamente
359
+ const hasRenderFunction = output.includes(`render_${componentName}`) ||
360
+ output.includes('function render(');
361
+ if (!hasRenderFunction && descriptor.template) {
362
+ logger.warn('Warning: No render function found in compiled output');
363
+ }
364
+ const finishComponent = `
365
+ ${hasRenderFunction ? `${componentName}.render = render_${componentName};` : ''}
366
+ ${scopeId ? `${componentName}.__scopeId = '${scopeId}';` : ''}
367
+ ${customBlocks}
368
+
369
+ export default ${componentName}; `;
370
+ output = `${output}\n${finishComponent}`;
371
+ return {
372
+ lang: finalCompiledScript.lang,
373
+ error: null,
374
+ data: output,
375
+ };
376
+ }
377
+ catch (error) {
378
+ logger.error('Vue compilation error:', error);
379
+ return {
380
+ lang: null,
381
+ error: error instanceof Error ? error : new Error(String(error)),
382
+ data: null,
383
+ };
384
+ }
385
+ };
386
+ // ✨ NUEVA FUNCIÓN: Exportar funcionalidades del cache HMR para uso externo
387
+ export const getVueHMRCacheStats = () => {
388
+ return hmrInjectionCache.getStats();
389
+ };
390
+ export const clearVueHMRCache = () => {
391
+ hmrInjectionCache.clear();
392
+ };
393
+ export const cleanExpiredVueHMRCache = () => {
394
+ hmrInjectionCache.cleanExpired();
395
+ };
396
+ //# sourceMappingURL=vuejs.js.map