versacompiler 1.0.5 → 2.0.1

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 (48) hide show
  1. package/README.md +633 -145
  2. package/dist/compiler/compile.js +1362 -0
  3. package/dist/compiler/error-reporter.js +467 -0
  4. package/dist/compiler/linter.js +72 -0
  5. package/dist/compiler/minify.js +229 -0
  6. package/dist/compiler/module-resolution-optimizer.js +844 -0
  7. package/dist/compiler/parser.js +203 -0
  8. package/dist/compiler/performance-monitor.js +192 -0
  9. package/dist/compiler/tailwindcss.js +39 -0
  10. package/dist/compiler/transform-optimizer.js +287 -0
  11. package/dist/compiler/transformTStoJS.js +16 -0
  12. package/dist/compiler/transforms.js +578 -0
  13. package/dist/compiler/typescript-compiler.js +379 -0
  14. package/dist/compiler/typescript-error-parser.js +281 -0
  15. package/dist/compiler/typescript-manager.js +378 -0
  16. package/dist/compiler/typescript-sync-validator.js +228 -0
  17. package/dist/compiler/typescript-worker-pool.js +479 -0
  18. package/dist/compiler/typescript-worker-thread.cjs +457 -0
  19. package/dist/compiler/typescript-worker.js +339 -0
  20. package/dist/compiler/vuejs.js +390 -0
  21. package/dist/hrm/VueHRM.js +353 -0
  22. package/dist/hrm/errorScreen.js +23 -1
  23. package/dist/hrm/getInstanciaVue.js +313 -0
  24. package/dist/hrm/initHRM.js +140 -0
  25. package/dist/main.js +286 -0
  26. package/dist/servicios/browserSync.js +469 -0
  27. package/dist/servicios/file-watcher.js +316 -0
  28. package/dist/servicios/logger.js +34 -0
  29. package/dist/servicios/readConfig.js +430 -0
  30. package/dist/utils/module-resolver.js +495 -0
  31. package/dist/utils/promptUser.js +48 -0
  32. package/dist/utils/resolve-bin.js +48 -0
  33. package/dist/utils/utils.js +8 -35
  34. package/dist/wrappers/eslint-node.js +145 -0
  35. package/dist/wrappers/oxlint-node.js +120 -0
  36. package/dist/wrappers/tailwind-node.js +92 -0
  37. package/package.json +62 -17
  38. package/dist/hrm/devMode.js +0 -346
  39. package/dist/hrm/instanciaVue.js +0 -35
  40. package/dist/hrm/setupHMR.js +0 -57
  41. package/dist/index.js +0 -1010
  42. package/dist/services/acorn.js +0 -29
  43. package/dist/services/linter.js +0 -55
  44. package/dist/services/minify.js +0 -31
  45. package/dist/services/typescript.js +0 -89
  46. package/dist/services/vueLoader.js +0 -326
  47. package/dist/services/vuejs.js +0 -259
  48. package/dist/utils/transformWithAcorn.js +0 -316
@@ -0,0 +1,353 @@
1
+ /**
2
+ * @typedef {Object} TreeNode
3
+ * @property {string} name - Nombre del componente
4
+ * @property {Object} instancia - Instancia del componente Vue
5
+ * @property {TreeNode[]} children - Nodos hijos
6
+ * @property {TreeNode|null} parent - Nodo padre
7
+ * @property {boolean} isRoot - Si es el nodo raíz
8
+ * @property {string} [from] - Origen del nodo
9
+ */
10
+
11
+ /**
12
+ * @typedef {Object} VNode
13
+ * @property {Object} [type] - Tipo del VNode
14
+ * @property {Object} [component] - Componente asociado
15
+ * @property {VNode[]} [children] - VNodes hijos
16
+ * @property {VNode[]} [dynamicChildren] - VNodes dinámicos
17
+ * @property {Object} [suspense] - Objeto suspense
18
+ */
19
+
20
+ /**
21
+ * @typedef {Object} ComponentInstance
22
+ * @property {Object} type - Tipo del componente
23
+ * @property {string} [type.name] - Nombre del tipo
24
+ * @property {string} [type.__name] - Nombre alternativo del tipo
25
+ * @property {Object} [components] - Componentes registrados
26
+ * @property {VNode} subTree - Subárbol del componente
27
+ * @property {Object} [proxy] - Proxy del componente
28
+ * @property {Function} [proxy.$forceUpdate] - Función de actualización forzada
29
+ * @property {Function} [update] - Función de actualización
30
+ * @property {Object} [ctx] - Contexto del componente
31
+ * @property {Object} [ctx._] - Contexto interno del componente
32
+ * @property {Object} [ctx._.setupState] - Estado del setup del componente
33
+ * @property {number} [ctx._.setupState.versaComponentKey] - Clave del componente para HMR
34
+ */
35
+
36
+ /**
37
+ * @typedef {Object} ComponentInfo
38
+ * @property {string} normalizedPath - Ruta normalizada del componente
39
+ * @property {string} nameFile - Nombre del archivo del componente
40
+ */
41
+
42
+ /**
43
+ * @typedef {Object} VueApp
44
+ * @property {ComponentInstance} _instance - Instancia principal de la aplicación
45
+ */
46
+
47
+ /**
48
+ * Busca nodos en el árbol por nombre de instancia
49
+ * @param {TreeNode} tree - Árbol de componentes
50
+ * @param {string} instance - Nombre de la instancia a buscar
51
+ * @returns {TreeNode[]} Array de nodos encontrados
52
+ */
53
+ function findNodeByInstance(tree, instance) {
54
+ const matches = [];
55
+ /**
56
+ * @param {TreeNode} node - Nodo a buscar recursivamente
57
+ */
58
+ function searchRecursively(node) {
59
+ if (node.name === instance) {
60
+ matches.push(node);
61
+ }
62
+ for (const child of node.children) {
63
+ searchRecursively(child);
64
+ }
65
+ }
66
+
67
+ searchRecursively(tree);
68
+ return matches;
69
+ }
70
+ /**
71
+ * Obtiene el camino desde un nodo hasta la raíz
72
+ * @param {TreeNode} node - Nodo inicial
73
+ * @returns {TreeNode[]} Camino desde el nodo hasta la raíz
74
+ */
75
+ function getPathToRoot(node) {
76
+ const path = [];
77
+ while (node) {
78
+ path.push(node);
79
+ node = node.parent;
80
+ }
81
+ return path; // Ordenado desde hijo hasta raíz
82
+ }
83
+
84
+ /**
85
+ * Encuentra componentes recursivamente dentro de un VNode
86
+ * @param {VNode} vnode - VNode a explorar
87
+ * @param {TreeNode} parentTreeNode - Nodo padre en el árbol
88
+ */
89
+ function recursivelyFindComponentsInVNode(vnode, parentTreeNode) {
90
+ if (!vnode || typeof vnode !== 'object') {
91
+ return;
92
+ }
93
+ if (vnode?.type.name === 'Suspense') {
94
+ const childComponentInstance = vnode?.suspense.activeBranch;
95
+ const childTreeNode = {
96
+ name: vnode?.type.name,
97
+ instancia: childComponentInstance,
98
+ children: [],
99
+ parent: parentTreeNode,
100
+ isRoot: false,
101
+ };
102
+ parentTreeNode.children.push(childTreeNode);
103
+ recursivelyFindComponentsInVNode(childComponentInstance, childTreeNode);
104
+ } else if (vnode.component) {
105
+ const childComponentInstance = vnode.component;
106
+
107
+ let componentName = 'Anonymous';
108
+ if (childComponentInstance.type) {
109
+ if (childComponentInstance.type.name) {
110
+ componentName = childComponentInstance.type.name;
111
+ } else if (childComponentInstance.type.__name) {
112
+ componentName = childComponentInstance.type.__name;
113
+ } else if (typeof childComponentInstance.type === 'function') {
114
+ const funcName = childComponentInstance.type.name;
115
+ if (funcName && funcName !== 'Anonymous function') {
116
+ componentName = funcName;
117
+ }
118
+ // Heurísticas para componentes comunes de Vue
119
+ const typeStr = childComponentInstance.type.toString();
120
+ if (typeStr.includes('BaseTransition')) {
121
+ componentName = 'Transition';
122
+ } else if (typeStr.includes('KeepAlive')) {
123
+ componentName = 'KeepAlive';
124
+ } else if (typeStr.includes('Suspense')) {
125
+ componentName = 'Suspense';
126
+ }
127
+ }
128
+ }
129
+
130
+ const childTreeNode = {
131
+ name: componentName,
132
+ instancia: childComponentInstance,
133
+ children: [],
134
+ parent: parentTreeNode,
135
+ isRoot: false,
136
+ };
137
+ parentTreeNode.children.push(childTreeNode);
138
+ traverseComponentInstance(childComponentInstance, childTreeNode);
139
+ } else {
140
+ const childrenToExplore = vnode.children || vnode.dynamicChildren;
141
+ if (Array.isArray(childrenToExplore)) {
142
+ childrenToExplore.forEach(childVNode => {
143
+ recursivelyFindComponentsInVNode(childVNode, parentTreeNode);
144
+ });
145
+ }
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Recorre una instancia de componente y construye el árbol
151
+ * @param {ComponentInstance} componentInstance - Instancia del componente
152
+ * @param {TreeNode} currentTreeNode - Nodo actual del árbol
153
+ */
154
+ function traverseComponentInstance(componentInstance, currentTreeNode) {
155
+ const subTreeVNode = componentInstance.subTree;
156
+
157
+ if (!subTreeVNode) {
158
+ return;
159
+ }
160
+
161
+ recursivelyFindComponentsInVNode(subTreeVNode, currentTreeNode);
162
+ }
163
+
164
+ /**
165
+ * Construye el árbol de componentes desde una instancia raíz
166
+ * @param {ComponentInstance} componentRootInstance - Instancia raíz del componente
167
+ * @returns {TreeNode|null} Árbol de componentes o null si falla
168
+ */
169
+ export const buildComponentTree = componentRootInstance => {
170
+ if (!componentRootInstance || !componentRootInstance.type) {
171
+ console.warn(
172
+ 'No se pudo construir el árbol de componentes: instancia inválida',
173
+ );
174
+ return null;
175
+ }
176
+ const tree = {
177
+ name:
178
+ componentRootInstance.type?.name ||
179
+ componentRootInstance.type?.__name ||
180
+ 'Anonymous',
181
+ instancia: componentRootInstance,
182
+ children: [],
183
+ parent: null,
184
+ isRoot: true,
185
+ from: 'root',
186
+ };
187
+ traverseComponentInstance(componentRootInstance, tree);
188
+
189
+ return tree;
190
+ };
191
+
192
+ /**
193
+ * Intenta forzar la actualización de una instancia de componente
194
+ * @param {ComponentInstance} instance - Instancia del componente a actualizar
195
+ * @returns {boolean} True si la actualización fue exitosa, false en caso contrario
196
+ */
197
+ function tryForceUpdate(instance) {
198
+ if (!instance) {
199
+ return false;
200
+ }
201
+ if (instance.proxy && typeof instance.proxy.$forceUpdate === 'function') {
202
+ instance.proxy.$forceUpdate();
203
+ if (typeof instance.update === 'function') {
204
+ instance.update();
205
+ }
206
+ // buscar una variable en el componente que se llame versaComponentKey y sumarle 1
207
+ if (instance.ctx?._.setupState?.versaComponentKey !== undefined) {
208
+ instance.ctx._.setupState.versaComponentKey++;
209
+ }
210
+ return true;
211
+ }
212
+ if (typeof instance.update === 'function') {
213
+ if (instance.ctx?._.setupState?.versaComponentKey !== undefined) {
214
+ instance.ctx._.setupState.versaComponentKey++;
215
+ }
216
+ instance.update();
217
+ return true;
218
+ }
219
+ return false;
220
+ }
221
+
222
+ /**
223
+ * Intenta actualizar un componente en el camino del árbol
224
+ * @param {TreeNode[]} path - Camino de nodos desde el componente hasta la raíz
225
+ * @param {Object} newComponent - Nuevo componente a usar
226
+ * @param {string} componentName - Nombre del componente
227
+ * @param {VueApp} App - Aplicación Vue
228
+ * @returns {boolean} True si la actualización fue exitosa
229
+ */
230
+ function tryUpdateComponentPath(path, newComponent, componentName, App) {
231
+ if (!path || !newComponent || !componentName || !App) {
232
+ console.error('❌ Parámetros inválidos para tryUpdateComponentPath');
233
+ return false;
234
+ }
235
+
236
+ // Recorrer el path desde el padre hacia la raíz (saltando el primer elemento que es el propio componente)
237
+ for (let i = 1; i < path.length; i++) {
238
+ const parent = path[i];
239
+
240
+ if (parent.isRoot || parent.name === 'KeepAlive') {
241
+ window.location.reload();
242
+ return true;
243
+ }
244
+
245
+ if (!parent || !parent.instancia) {
246
+ console.error('❌ Nodo padre no válido en el camino:', parent);
247
+ continue; // Continúa con el siguiente padre en lugar de fallar
248
+ }
249
+
250
+ // Actualizar la instancia del componente
251
+ const componentsDefinition =
252
+ parent.instancia?.type?.components || parent.instancia?.components;
253
+
254
+ if (componentsDefinition && componentsDefinition[componentName]) {
255
+ componentsDefinition[componentName] = newComponent;
256
+
257
+ // Forzar actualización de la instancia padre
258
+ return (
259
+ tryForceUpdate(parent.instancia) ||
260
+ tryForceUpdate(parent.instancia.proxy)
261
+ );
262
+ }
263
+ }
264
+
265
+ return false;
266
+ }
267
+
268
+ /**
269
+ * Recarga un componente Vue con Hot Module Replacement
270
+ * @param {VueApp} App - Aplicación Vue principal
271
+ * @param {ComponentInfo} Component - Información del componente a recargar
272
+ * @returns {Promise<boolean>} Promise que resuelve a true si la recarga fue exitosa
273
+ */
274
+ export async function reloadComponent(App, Component) {
275
+ try {
276
+ const { normalizedPath: relativePath, nameFile: componentName } =
277
+ Component;
278
+ if (!App || !App._instance) {
279
+ console.error('❌ App o App._instance no están definidos');
280
+ return false;
281
+ }
282
+
283
+ if (!relativePath) {
284
+ console.error('❌ No se proporcionó relativePath');
285
+ return false;
286
+ }
287
+
288
+ const baseUrl = window.location.href;
289
+ const newBaseUrl = new URL(baseUrl);
290
+ const urlOrigin = `${newBaseUrl.origin}/${relativePath}`;
291
+ const timestamp = Date.now();
292
+ const moduleUrl = `${urlOrigin}?t=${timestamp}`;
293
+
294
+ const module = await import(moduleUrl);
295
+
296
+ if (!module.default) {
297
+ console.error('❌ El módulo importado no tiene export default');
298
+ return false;
299
+ }
300
+
301
+ const componentTree = buildComponentTree(App._instance);
302
+ if (!componentTree) {
303
+ console.error('❌ No se pudo construir el árbol de componentes');
304
+ return false;
305
+ }
306
+
307
+ const targetNodes = findNodeByInstance(componentTree, componentName);
308
+ if (!targetNodes) {
309
+ console.warn(
310
+ '⚠️ No se encontró el nodo objetivo para:',
311
+ componentName,
312
+ );
313
+
314
+ return false;
315
+ }
316
+
317
+ console.log(
318
+ `🔍 Se encontraron ${targetNodes.length} instancias del componente ${componentName}`,
319
+ );
320
+
321
+ let successfulUpdates = 0; // Procesar TODAS las instancias encontradas
322
+ for (let i = 0; i < targetNodes.length; i++) {
323
+ const node = targetNodes[i];
324
+ if (node) {
325
+ const path = getPathToRoot(node);
326
+ const updateResult = await tryUpdateComponentPath(
327
+ path,
328
+ module.default,
329
+ componentName,
330
+ App,
331
+ );
332
+
333
+ if (updateResult) {
334
+ successfulUpdates++;
335
+ } else {
336
+ console.error(
337
+ `❌ No se pudo actualizar la instancia ${i + 1}`,
338
+ );
339
+ }
340
+ }
341
+ }
342
+
343
+ const hasSuccessfulUpdate = successfulUpdates > 0;
344
+ console.log(
345
+ `\n📊 Resultado final: ${successfulUpdates}/${targetNodes.length} instancias actualizadas`,
346
+ );
347
+
348
+ return hasSuccessfulUpdate;
349
+ } catch (error) {
350
+ console.error('❌ Error en reloadComponent:', error);
351
+ return false;
352
+ }
353
+ }
@@ -1,4 +1,13 @@
1
+ /**
2
+ * Variable global que mantiene la referencia al overlay de error actual
3
+ * @type {HTMLElement|null}
4
+ */
1
5
  let errorOverlay;
6
+
7
+ /**
8
+ * Oculta y remueve el overlay de error actual del DOM
9
+ * @returns {void}
10
+ */
2
11
  export function hideErrorOverlay() {
3
12
  const existingOverlay = document.getElementById('versa-hmr-error-overlay');
4
13
  if (existingOverlay) {
@@ -6,9 +15,17 @@ export function hideErrorOverlay() {
6
15
  }
7
16
  errorOverlay = null;
8
17
  }
18
+
19
+ /**
20
+ * Muestra un overlay de error personalizado para errores de HMR (Hot Module Replacement).
21
+ * @param {string} errorMessage - Mensaje de error principal.
22
+ * @param {string} [errorDetails=''] - Detalles adicionales del error, opcional.
23
+ * @returns {void}
24
+ */
9
25
  export function showErrorOverlay(errorMessage, errorDetails = '') {
10
- hideErrorOverlay(); // Ensure no duplicate overlays
26
+ hideErrorOverlay(); // Asegurar que no haya overlays duplicados
11
27
 
28
+ // Crear el contenedor principal del overlay
12
29
  errorOverlay = document.createElement('div');
13
30
  errorOverlay.id = 'versa-hmr-error-overlay';
14
31
  errorOverlay.style.position = 'fixed';
@@ -30,17 +47,20 @@ export function showErrorOverlay(errorMessage, errorDetails = '') {
30
47
  errorOverlay.style.textAlign = 'left';
31
48
  errorOverlay.style.overflow = 'auto';
32
49
 
50
+ // Crear el título del overlay
33
51
  const title = document.createElement('h2');
34
52
  title.textContent = 'Versa HMR Error';
35
53
  title.style.color = '#ff4d4d';
36
54
  title.style.fontSize = '24px';
37
55
  title.style.marginBottom = '20px';
38
56
 
57
+ // Crear el contenedor del mensaje principal
39
58
  const messageDiv = document.createElement('div');
40
59
  messageDiv.textContent = errorMessage;
41
60
  messageDiv.style.marginBottom = '15px';
42
61
  messageDiv.style.whiteSpace = 'pre-wrap';
43
62
 
63
+ // Crear el contenedor de detalles del error
44
64
  const detailsPre = document.createElement('pre');
45
65
  detailsPre.textContent = errorDetails;
46
66
  detailsPre.style.backgroundColor = 'rgba(255, 255, 255, 0.1)';
@@ -51,11 +71,13 @@ export function showErrorOverlay(errorMessage, errorDetails = '') {
51
71
  detailsPre.style.width = '100%';
52
72
  detailsPre.style.maxWidth = '800px';
53
73
 
74
+ // Agregar elementos al overlay
54
75
  errorOverlay.appendChild(title);
55
76
  errorOverlay.appendChild(messageDiv);
56
77
  if (errorDetails) {
57
78
  errorOverlay.appendChild(detailsPre);
58
79
  }
59
80
 
81
+ // Agregar el overlay al DOM
60
82
  document.body.appendChild(errorOverlay);
61
83
  }