versacompiler 1.0.3 → 1.0.5
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/dist/hrm/devMode.js +346 -0
- package/dist/hrm/errorScreen.js +61 -0
- package/dist/hrm/instanciaVue.js +35 -0
- package/dist/hrm/setupHMR.js +57 -0
- package/dist/index.js +306 -88
- package/dist/services/acorn.js +2 -1
- package/dist/services/vueLoader.js +326 -0
- package/dist/services/vuejs.js +38 -14
- package/dist/utils/transformWithAcorn.js +316 -0
- package/dist/utils/utils.js +48 -48
- package/package.json +13 -9
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
let currentComponentTree = null;
|
|
2
|
+
|
|
3
|
+
function findNodeByInstance(tree, instance) {
|
|
4
|
+
if (tree.name === instance) return tree;
|
|
5
|
+
for (const child of tree.children) {
|
|
6
|
+
const found = findNodeByInstance(child, instance);
|
|
7
|
+
if (found) return found;
|
|
8
|
+
}
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getPathToRoot(node) {
|
|
13
|
+
const path = [];
|
|
14
|
+
while (node) {
|
|
15
|
+
path.push(node);
|
|
16
|
+
node = node.parent;
|
|
17
|
+
}
|
|
18
|
+
return path; // Ordenado desde hijo hasta raíz
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Función auxiliar para encontrar componentes recursivamente dentro de un VNode genérico
|
|
22
|
+
function recursivelyFindComponentsInVNode(vnode, parentTreeNode) {
|
|
23
|
+
if (!vnode || typeof vnode !== 'object') {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (vnode.component) {
|
|
28
|
+
const childComponentInstance = vnode.component;
|
|
29
|
+
|
|
30
|
+
let componentName = 'Anonymous';
|
|
31
|
+
if (childComponentInstance.type) {
|
|
32
|
+
if (childComponentInstance.type.name) {
|
|
33
|
+
componentName = childComponentInstance.type.name;
|
|
34
|
+
} else if (childComponentInstance.type.__name) {
|
|
35
|
+
componentName = childComponentInstance.type.__name;
|
|
36
|
+
} else if (typeof childComponentInstance.type === 'function') {
|
|
37
|
+
const funcName = childComponentInstance.type.name;
|
|
38
|
+
if (funcName && funcName !== 'Anonymous function') {
|
|
39
|
+
componentName = funcName;
|
|
40
|
+
}
|
|
41
|
+
// Heurísticas para componentes comunes de Vue
|
|
42
|
+
const typeStr = childComponentInstance.type.toString();
|
|
43
|
+
if (typeStr.includes('BaseTransition')) {
|
|
44
|
+
componentName = 'Transition';
|
|
45
|
+
} else if (typeStr.includes('KeepAlive')) {
|
|
46
|
+
componentName = 'KeepAlive';
|
|
47
|
+
} else if (typeStr.includes('Suspense')) {
|
|
48
|
+
componentName = 'Suspense';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const childTreeNode = {
|
|
54
|
+
name: componentName,
|
|
55
|
+
instancia: childComponentInstance,
|
|
56
|
+
children: [],
|
|
57
|
+
parent: parentTreeNode,
|
|
58
|
+
isRoot: false,
|
|
59
|
+
};
|
|
60
|
+
parentTreeNode.children.push(childTreeNode);
|
|
61
|
+
traverseComponentInstance(childComponentInstance, childTreeNode);
|
|
62
|
+
} else {
|
|
63
|
+
const childrenToExplore = vnode.children || vnode.dynamicChildren;
|
|
64
|
+
if (Array.isArray(childrenToExplore)) {
|
|
65
|
+
childrenToExplore.forEach(childVNode => {
|
|
66
|
+
recursivelyFindComponentsInVNode(childVNode, parentTreeNode);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Función principal de recorrido, ahora llamada traverseComponentInstance
|
|
73
|
+
function traverseComponentInstance(componentInstance, currentTreeNode) {
|
|
74
|
+
const subTreeVNode = componentInstance.subTree;
|
|
75
|
+
|
|
76
|
+
if (!subTreeVNode) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
recursivelyFindComponentsInVNode(subTreeVNode, currentTreeNode);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const buildComponentTree = componentRootInstance => {
|
|
84
|
+
const tree = {
|
|
85
|
+
name:
|
|
86
|
+
componentRootInstance.type?.name ||
|
|
87
|
+
componentRootInstance.type?.__name ||
|
|
88
|
+
'Anonymous',
|
|
89
|
+
instancia: componentRootInstance,
|
|
90
|
+
children: [],
|
|
91
|
+
parent: null,
|
|
92
|
+
isRoot: true,
|
|
93
|
+
};
|
|
94
|
+
traverseComponentInstance(componentRootInstance, tree);
|
|
95
|
+
return tree;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Nueva función auxiliar para intentar forzar la actualización de una instancia
|
|
99
|
+
function tryForceUpdate(instance) {
|
|
100
|
+
if (!instance) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
if (instance.proxy && typeof instance.proxy.$forceUpdate === 'function') {
|
|
104
|
+
instance.proxy.$forceUpdate();
|
|
105
|
+
instance.update();
|
|
106
|
+
// buscar una varible en el componente que se llame versaComponentKey y sumarle 1
|
|
107
|
+
instance.ctx._.setupState.versaComponentKey++;
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (typeof instance.update === 'function') {
|
|
111
|
+
if (instance.ctx._.setupState.versaComponentKey) {
|
|
112
|
+
instance.ctx._.setupState.versaComponentKey++;
|
|
113
|
+
}
|
|
114
|
+
instance.update();
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function reloadComponent(
|
|
121
|
+
app,
|
|
122
|
+
componentName,
|
|
123
|
+
relativePath,
|
|
124
|
+
_extension,
|
|
125
|
+
_type,
|
|
126
|
+
) {
|
|
127
|
+
try {
|
|
128
|
+
const baseUrl = window.location.href;
|
|
129
|
+
// console.log(relativePath);
|
|
130
|
+
const newBaseUrl = new URL(baseUrl);
|
|
131
|
+
const urlOrigin = `${newBaseUrl.origin}/${relativePath}`;
|
|
132
|
+
const module = await import(`${urlOrigin}?t=${Date.now()}`);
|
|
133
|
+
currentComponentTree = buildComponentTree(app._instance);
|
|
134
|
+
|
|
135
|
+
const targetNode = findNodeByInstance(
|
|
136
|
+
currentComponentTree,
|
|
137
|
+
componentName,
|
|
138
|
+
);
|
|
139
|
+
const path = getPathToRoot(targetNode);
|
|
140
|
+
for (const instanciaParent of path) {
|
|
141
|
+
if (
|
|
142
|
+
instanciaParent.isRoot ||
|
|
143
|
+
instanciaParent.name === 'KeepAlive'
|
|
144
|
+
) {
|
|
145
|
+
window.location.reload();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (instanciaParent.name !== componentName) {
|
|
149
|
+
if (
|
|
150
|
+
instanciaParent.name !== 'BaseTransition' &&
|
|
151
|
+
instanciaParent.name !== 'Transition' &&
|
|
152
|
+
instanciaParent.name !== 'Suspense'
|
|
153
|
+
) {
|
|
154
|
+
const componentsDefinition =
|
|
155
|
+
instanciaParent.instancia?.type?.components ||
|
|
156
|
+
instanciaParent.instancia?.components;
|
|
157
|
+
|
|
158
|
+
if (
|
|
159
|
+
componentsDefinition &&
|
|
160
|
+
componentsDefinition[componentName]
|
|
161
|
+
) {
|
|
162
|
+
componentsDefinition[componentName] = module.default;
|
|
163
|
+
if (tryForceUpdate(instanciaParent.instancia)) {
|
|
164
|
+
console.log(
|
|
165
|
+
`✔️ Versa HMR: Component updated successfully`,
|
|
166
|
+
);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.log(error.stack);
|
|
176
|
+
return {
|
|
177
|
+
msg: `Error al recargar ${componentName}: ${error}`,
|
|
178
|
+
error,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Función Debounce
|
|
184
|
+
export function debounce(func, waitFor) {
|
|
185
|
+
let timeout = null;
|
|
186
|
+
|
|
187
|
+
const debounced = (...args) => {
|
|
188
|
+
if (timeout) {
|
|
189
|
+
clearTimeout(timeout);
|
|
190
|
+
}
|
|
191
|
+
timeout = setTimeout(() => func(...args), waitFor);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
return debounced;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export async function reloadJS(pathWithTimestamp) {
|
|
198
|
+
// Extraer la ruta base sin el timestamp
|
|
199
|
+
const pathParts = pathWithTimestamp.split('?');
|
|
200
|
+
const basePath = pathParts[0];
|
|
201
|
+
|
|
202
|
+
const contenidoArchivo = await fetch(pathWithTimestamp).then(res =>
|
|
203
|
+
res.text(),
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
// Verificar la marca para recarga completa
|
|
207
|
+
if (contenidoArchivo.startsWith('//versaHRM-reloadFILE')) {
|
|
208
|
+
console.log(
|
|
209
|
+
`[HMR] Marca //versaHRM-reloadFILE detectada en ${basePath}. Recargando página completa.`,
|
|
210
|
+
);
|
|
211
|
+
window.location.reload();
|
|
212
|
+
return; // Detener procesamiento adicional para este archivo
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/* La lógica anterior para createApp/mount ya no es necesaria aquí, la marca la cubre.
|
|
216
|
+
if (
|
|
217
|
+
contenidoArchivo.includes('createApp') ||
|
|
218
|
+
contenidoArchivo.includes('.mount')
|
|
219
|
+
) {
|
|
220
|
+
window.location.reload();
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
// Verificar si tenemos una función de recarga registrada para este módulo
|
|
226
|
+
if (
|
|
227
|
+
window.__VERSA_HMR &&
|
|
228
|
+
window.__VERSA_HMR.modules &&
|
|
229
|
+
window.__VERSA_HMR.modules[basePath]
|
|
230
|
+
) {
|
|
231
|
+
console.log(
|
|
232
|
+
`[HMR] Usando sistema HMR interno para recargar: ${basePath}`,
|
|
233
|
+
);
|
|
234
|
+
try {
|
|
235
|
+
const result = await window.__VERSA_HMR.modules[basePath]();
|
|
236
|
+
return result;
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error(
|
|
239
|
+
`[HMR] Error al recargar el módulo usando sistema HMR interno:`,
|
|
240
|
+
error,
|
|
241
|
+
);
|
|
242
|
+
// Si falla el sistema interno, intentamos el enfoque tradicional
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Si no hay una función específica, usar la lógica existente
|
|
247
|
+
try {
|
|
248
|
+
console.log(`[HMR] Intentando re-importar JS: ${pathWithTimestamp}`);
|
|
249
|
+
// La URL ya está completa y lista para usar.
|
|
250
|
+
// El `import()` dinámico usa la URL base del script actual si la ruta es relativa,
|
|
251
|
+
// o la URL tal cual si es absoluta (comenzando con / o http/https).
|
|
252
|
+
// Como pathWithTimestamp comienza con '/', se resolverá desde la raíz del host.
|
|
253
|
+
const newModule = await import(pathWithTimestamp);
|
|
254
|
+
console.log(
|
|
255
|
+
`[HMR] Módulo JS ${pathWithTimestamp} re-importado exitosamente.`,
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
// Lógica de ejemplo: si el módulo exporta una función 'onHotUpdate' o 'init', llamarla.
|
|
259
|
+
// Esto es una convención que tus módulos JS tendrían que seguir.
|
|
260
|
+
if (newModule && typeof newModule.onHotUpdate === 'function') {
|
|
261
|
+
console.log(
|
|
262
|
+
`[HMR] Llamando a onHotUpdate() para el módulo ${pathWithTimestamp}`,
|
|
263
|
+
);
|
|
264
|
+
newModule.onHotUpdate();
|
|
265
|
+
} else if (newModule && typeof newModule.init === 'function') {
|
|
266
|
+
// Alternativamente, una función 'init' si es más genérico
|
|
267
|
+
console.log(
|
|
268
|
+
`[HMR] Llamando a init() para el módulo ${pathWithTimestamp}`,
|
|
269
|
+
);
|
|
270
|
+
newModule.init();
|
|
271
|
+
} else if (newModule && typeof newModule.main === 'function') {
|
|
272
|
+
// O una función 'main'
|
|
273
|
+
console.log(
|
|
274
|
+
`[HMR] Llamando a main() para el módulo ${pathWithTimestamp}`,
|
|
275
|
+
);
|
|
276
|
+
newModule.main();
|
|
277
|
+
}
|
|
278
|
+
// Si no hay una función específica, la simple re-importación podría ser suficiente
|
|
279
|
+
// si el módulo se auto-ejecuta (ej. añade event listeners, modifica el DOM globalmente).
|
|
280
|
+
// ¡CUIDADO con efectos secundarios duplicados en este caso!
|
|
281
|
+
|
|
282
|
+
return null; // Indicar éxito
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error(
|
|
285
|
+
`[HMR] Error al re-importar el módulo JS ${pathWithTimestamp}:`,
|
|
286
|
+
error,
|
|
287
|
+
);
|
|
288
|
+
// Aquí podrías decidir si mostrar un error en el overlay o, como último recurso, recargar.
|
|
289
|
+
// Por ahora, solo retornamos false para que el llamador (vueLoader.js) decida.
|
|
290
|
+
return {
|
|
291
|
+
msg: `Error al re-importar el módulo JS ${pathWithTimestamp}:`,
|
|
292
|
+
error,
|
|
293
|
+
}; // Indicar fallo
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export function socketReload(app) {
|
|
298
|
+
if (window.___browserSync___?.socket) {
|
|
299
|
+
// const socket = window.___browserSync___.socket;
|
|
300
|
+
// Configura el observer para actualizar el árbol de componentes en cada mutación relevante
|
|
301
|
+
if (app && app._container) {
|
|
302
|
+
currentComponentTree = buildComponentTree(app._instance);
|
|
303
|
+
initializeMutationObserver(app._container, () => {
|
|
304
|
+
if (app._instance) {
|
|
305
|
+
currentComponentTree = buildComponentTree(app._instance);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
// socket.on('vue:update', data => {
|
|
310
|
+
// console.log('pasa');
|
|
311
|
+
// if (document.querySelector('#versa-hmr-error-overlay')) {
|
|
312
|
+
// window.location.reload();
|
|
313
|
+
// return;
|
|
314
|
+
// }
|
|
315
|
+
|
|
316
|
+
// const { component, relativePath, extension, type, timestamp } =
|
|
317
|
+
// data;
|
|
318
|
+
// if (extension === 'vue') {
|
|
319
|
+
// reloadComponent(
|
|
320
|
+
// app,
|
|
321
|
+
// component,
|
|
322
|
+
// `/${relativePath}`,
|
|
323
|
+
// type,
|
|
324
|
+
// extension,
|
|
325
|
+
// );
|
|
326
|
+
// } else {
|
|
327
|
+
// reloadJS(`/${relativePath}?t=${timestamp}`);
|
|
328
|
+
// }
|
|
329
|
+
// });
|
|
330
|
+
} else {
|
|
331
|
+
setTimeout(() => {
|
|
332
|
+
window.location.reload();
|
|
333
|
+
}, 5000);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function initializeMutationObserver(targetNode, callback, options) {
|
|
338
|
+
const observerInstance = new MutationObserver(callback);
|
|
339
|
+
const defaultOptions = {
|
|
340
|
+
childList: true,
|
|
341
|
+
subtree: true,
|
|
342
|
+
attributes: false,
|
|
343
|
+
};
|
|
344
|
+
observerInstance.observe(targetNode, { ...defaultOptions, ...options });
|
|
345
|
+
return observerInstance;
|
|
346
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
let errorOverlay;
|
|
2
|
+
export function hideErrorOverlay() {
|
|
3
|
+
const existingOverlay = document.getElementById('versa-hmr-error-overlay');
|
|
4
|
+
if (existingOverlay) {
|
|
5
|
+
existingOverlay.remove();
|
|
6
|
+
}
|
|
7
|
+
errorOverlay = null;
|
|
8
|
+
}
|
|
9
|
+
export function showErrorOverlay(errorMessage, errorDetails = '') {
|
|
10
|
+
hideErrorOverlay(); // Ensure no duplicate overlays
|
|
11
|
+
|
|
12
|
+
errorOverlay = document.createElement('div');
|
|
13
|
+
errorOverlay.id = 'versa-hmr-error-overlay';
|
|
14
|
+
errorOverlay.style.position = 'fixed';
|
|
15
|
+
errorOverlay.style.top = '0';
|
|
16
|
+
errorOverlay.style.left = '0';
|
|
17
|
+
errorOverlay.style.width = '100vw';
|
|
18
|
+
errorOverlay.style.height = '100vh';
|
|
19
|
+
errorOverlay.style.backgroundColor = 'rgba(0, 0, 0, 1.85)';
|
|
20
|
+
errorOverlay.style.color = '#ff8080';
|
|
21
|
+
errorOverlay.style.zIndex = '999999';
|
|
22
|
+
errorOverlay.style.display = 'flex';
|
|
23
|
+
errorOverlay.style.flexDirection = 'column';
|
|
24
|
+
errorOverlay.style.alignItems = 'center';
|
|
25
|
+
errorOverlay.style.justifyContent = 'center';
|
|
26
|
+
errorOverlay.style.fontFamily = 'monospace';
|
|
27
|
+
errorOverlay.style.fontSize = '16px';
|
|
28
|
+
errorOverlay.style.padding = '20px';
|
|
29
|
+
errorOverlay.style.boxSizing = 'border-box';
|
|
30
|
+
errorOverlay.style.textAlign = 'left';
|
|
31
|
+
errorOverlay.style.overflow = 'auto';
|
|
32
|
+
|
|
33
|
+
const title = document.createElement('h2');
|
|
34
|
+
title.textContent = 'Versa HMR Error';
|
|
35
|
+
title.style.color = '#ff4d4d';
|
|
36
|
+
title.style.fontSize = '24px';
|
|
37
|
+
title.style.marginBottom = '20px';
|
|
38
|
+
|
|
39
|
+
const messageDiv = document.createElement('div');
|
|
40
|
+
messageDiv.textContent = errorMessage;
|
|
41
|
+
messageDiv.style.marginBottom = '15px';
|
|
42
|
+
messageDiv.style.whiteSpace = 'pre-wrap';
|
|
43
|
+
|
|
44
|
+
const detailsPre = document.createElement('pre');
|
|
45
|
+
detailsPre.textContent = errorDetails;
|
|
46
|
+
detailsPre.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
|
|
47
|
+
detailsPre.style.padding = '10px';
|
|
48
|
+
detailsPre.style.borderRadius = '5px';
|
|
49
|
+
detailsPre.style.maxHeight = '50vh';
|
|
50
|
+
detailsPre.style.overflow = 'auto';
|
|
51
|
+
detailsPre.style.width = '100%';
|
|
52
|
+
detailsPre.style.maxWidth = '800px';
|
|
53
|
+
|
|
54
|
+
errorOverlay.appendChild(title);
|
|
55
|
+
errorOverlay.appendChild(messageDiv);
|
|
56
|
+
if (errorDetails) {
|
|
57
|
+
errorOverlay.appendChild(detailsPre);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
document.body.appendChild(errorOverlay);
|
|
61
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Store for the Vue app instance
|
|
2
|
+
let vueAppInstance = null;
|
|
3
|
+
|
|
4
|
+
// Exponer la instancia en window para acceso global
|
|
5
|
+
if (typeof window !== 'undefined') {
|
|
6
|
+
window.__VUE_APP_INSTANCE__ = {
|
|
7
|
+
set: function(instance) {
|
|
8
|
+
vueAppInstance = instance;
|
|
9
|
+
console.log('Vue app instance stored successfully in window.__VUE_APP_INSTANCE__');
|
|
10
|
+
return instance;
|
|
11
|
+
},
|
|
12
|
+
get: function() {
|
|
13
|
+
return vueAppInstance;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default {
|
|
19
|
+
methods: {
|
|
20
|
+
// Set the Vue app instance
|
|
21
|
+
set(instance) {
|
|
22
|
+
vueAppInstance = instance;
|
|
23
|
+
// También lo guardamos en window para acceso global
|
|
24
|
+
if (typeof window !== 'undefined') {
|
|
25
|
+
window.__VUE_APP_INSTANCE__.set(instance);
|
|
26
|
+
}
|
|
27
|
+
console.log('Vue app instance stored successfully');
|
|
28
|
+
return instance;
|
|
29
|
+
},
|
|
30
|
+
// Get the Vue app instance
|
|
31
|
+
get() {
|
|
32
|
+
return vueAppInstance;
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// setupHMR.js - Helper to set up Hot Module Reloading for Vue
|
|
2
|
+
import instanciaVue from './instanciaVue.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Set up Hot Module Reloading for a Vue application
|
|
6
|
+
* @param {Object} app - The Vue application instance
|
|
7
|
+
* @returns {Object} - The same Vue application instance
|
|
8
|
+
*/
|
|
9
|
+
export function setupHMR(app) {
|
|
10
|
+
// Store the Vue app instance in our instanciaVue module
|
|
11
|
+
instanciaVue.methods.set(app);
|
|
12
|
+
|
|
13
|
+
// También lo guardamos directamente en window para mayor accesibilidad
|
|
14
|
+
if (typeof window !== 'undefined') {
|
|
15
|
+
window.__VUE_APP__ = app;
|
|
16
|
+
console.log('Vue app instance stored directly in window.__VUE_APP__');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log('HMR setup complete - Vue instance stored for hot reloading');
|
|
20
|
+
|
|
21
|
+
return app;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Helper function to wrap your Vue app creation with HMR support
|
|
26
|
+
* @param {Function} createAppFn - Function that creates and returns your Vue app
|
|
27
|
+
* @returns {Object} - The Vue application instance with HMR support
|
|
28
|
+
*/
|
|
29
|
+
export function createAppWithHMR(createAppFn) {
|
|
30
|
+
const app = createAppFn();
|
|
31
|
+
return setupHMR(app);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Función para obtener la instancia de Vue desde cualquier parte de la aplicación
|
|
36
|
+
* @returns {Object|null} - La instancia de Vue o null si no está disponible
|
|
37
|
+
*/
|
|
38
|
+
export function getVueInstance() {
|
|
39
|
+
// Intentar obtener la instancia desde diferentes fuentes
|
|
40
|
+
if (typeof window !== 'undefined') {
|
|
41
|
+
// Primero intentar desde window.__VUE_APP__
|
|
42
|
+
if (window.__VUE_APP__) {
|
|
43
|
+
return window.__VUE_APP__;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Luego intentar desde window.__VUE_APP_INSTANCE__
|
|
47
|
+
if (
|
|
48
|
+
window.__VUE_APP_INSTANCE__ &&
|
|
49
|
+
typeof window.__VUE_APP_INSTANCE__.get === 'function'
|
|
50
|
+
) {
|
|
51
|
+
return window.__VUE_APP_INSTANCE__.get();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Finalmente intentar desde instanciaVue
|
|
56
|
+
return instanciaVue.methods.get();
|
|
57
|
+
}
|