wu-framework 1.1.10 → 1.1.12
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/wu-framework.cjs.js +1 -1
- package/dist/wu-framework.cjs.js.map +1 -1
- package/dist/wu-framework.dev.js +247 -237
- package/dist/wu-framework.dev.js.map +1 -1
- package/dist/wu-framework.esm.js +1 -1
- package/dist/wu-framework.esm.js.map +1 -1
- package/dist/wu-framework.umd.js +1 -1
- package/dist/wu-framework.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/react/index.js +17 -10
- package/src/adapters/vue/index.js +18 -16
- package/src/core/wu-app.js +9 -7
- package/src/core/wu-cache.js +16 -14
- package/src/core/wu-error-boundary.js +17 -15
- package/src/core/wu-event-bus.js +4 -2
- package/src/core/wu-hooks.js +10 -8
- package/src/core/wu-loader.js +20 -18
- package/src/core/wu-manifest.js +10 -8
- package/src/core/wu-mcp-bridge.js +6 -5
- package/src/core/wu-performance.js +8 -6
- package/src/core/wu-plugin.js +8 -6
- package/src/core/wu-strategies.js +14 -12
- package/src/utils/dependency-resolver.js +13 -11
package/dist/wu-framework.dev.js
CHANGED
|
@@ -1,15 +1,152 @@
|
|
|
1
1
|
/*! wu-framework v1.1.8 | MIT License */
|
|
2
|
+
/**
|
|
3
|
+
* 📝 WU-LOGGER: Sistema de logging inteligente para entornos
|
|
4
|
+
* Controla los logs automáticamente según el entorno
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
class WuLogger {
|
|
8
|
+
constructor() {
|
|
9
|
+
// Detectar entorno automáticamente
|
|
10
|
+
this.isDevelopment = this.detectEnvironment();
|
|
11
|
+
// En desarrollo: warn (menos ruido), en producción: error
|
|
12
|
+
this.logLevel = this.isDevelopment ? 'warn' : 'error';
|
|
13
|
+
|
|
14
|
+
this.levels = {
|
|
15
|
+
debug: 0,
|
|
16
|
+
info: 1,
|
|
17
|
+
warn: 2,
|
|
18
|
+
error: 3,
|
|
19
|
+
silent: 4
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Detectar si estamos en desarrollo
|
|
25
|
+
*/
|
|
26
|
+
detectEnvironment() {
|
|
27
|
+
// Múltiples formas de detectar desarrollo
|
|
28
|
+
return (
|
|
29
|
+
// Vite development
|
|
30
|
+
window.location.hostname === 'localhost' ||
|
|
31
|
+
window.location.hostname === '127.0.0.1' ||
|
|
32
|
+
window.location.port !== '' ||
|
|
33
|
+
// NODE_ENV si está disponible
|
|
34
|
+
(typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') ||
|
|
35
|
+
// URL params para forzar debug
|
|
36
|
+
new URLSearchParams(window.location.search).has('wu-debug') ||
|
|
37
|
+
// Manual override
|
|
38
|
+
window.WU_DEBUG === true
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Configurar nivel de logging
|
|
44
|
+
*/
|
|
45
|
+
setLevel(level) {
|
|
46
|
+
this.logLevel = level;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Habilitar/deshabilitar development mode
|
|
52
|
+
*/
|
|
53
|
+
setDevelopment(isDev) {
|
|
54
|
+
this.isDevelopment = isDev;
|
|
55
|
+
this.logLevel = isDev ? 'debug' : 'error';
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Verificar si debemos mostrar el log
|
|
61
|
+
*/
|
|
62
|
+
shouldLog(level) {
|
|
63
|
+
return this.levels[level] >= this.levels[this.logLevel];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Logging methods
|
|
68
|
+
*/
|
|
69
|
+
debug(...args) {
|
|
70
|
+
if (this.shouldLog('debug')) {
|
|
71
|
+
console.log(...args);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
info(...args) {
|
|
76
|
+
if (this.shouldLog('info')) {
|
|
77
|
+
console.info(...args);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
warn(...args) {
|
|
82
|
+
if (this.shouldLog('warn')) {
|
|
83
|
+
console.warn(...args);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
error(...args) {
|
|
88
|
+
if (this.shouldLog('error')) {
|
|
89
|
+
console.error(...args);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Logging con contexto Wu
|
|
95
|
+
*/
|
|
96
|
+
wu(level, ...args) {
|
|
97
|
+
if (this.shouldLog(level)) {
|
|
98
|
+
const method = level === 'debug' ? 'log' : level;
|
|
99
|
+
console[method]('[Wu]', ...args);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Helper methods específicos para Wu
|
|
105
|
+
*/
|
|
106
|
+
wuDebug(...args) { this.wu('debug', ...args); }
|
|
107
|
+
wuInfo(...args) { this.wu('info', ...args); }
|
|
108
|
+
wuWarn(...args) { this.wu('warn', ...args); }
|
|
109
|
+
wuError(...args) { this.wu('error', ...args); }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Singleton instance
|
|
113
|
+
const logger = new WuLogger();
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* 🔇 Silenciar todos los logs de Wu Framework
|
|
117
|
+
* Útil en producción para eliminar todo el ruido
|
|
118
|
+
*/
|
|
119
|
+
function silenceAllLogs() {
|
|
120
|
+
logger.setLevel('silent');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 🔊 Restaurar logs (nivel debug)
|
|
125
|
+
*/
|
|
126
|
+
function enableAllLogs() {
|
|
127
|
+
logger.setLevel('debug');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
var wuLogger = /*#__PURE__*/Object.freeze({
|
|
131
|
+
__proto__: null,
|
|
132
|
+
WuLogger: WuLogger,
|
|
133
|
+
enableAllLogs: enableAllLogs,
|
|
134
|
+
logger: logger,
|
|
135
|
+
silenceAllLogs: silenceAllLogs
|
|
136
|
+
});
|
|
137
|
+
|
|
2
138
|
/**
|
|
3
139
|
* 🚀 WU-LOADER: SISTEMA DE CARGA DINÁMICA UNIVERSAL
|
|
4
140
|
* Carga aplicaciones y componentes sin depender del framework
|
|
5
141
|
*/
|
|
6
142
|
|
|
143
|
+
|
|
7
144
|
class WuLoader {
|
|
8
145
|
constructor() {
|
|
9
146
|
this.cache = new Map();
|
|
10
147
|
this.loadingPromises = new Map();
|
|
11
148
|
|
|
12
|
-
|
|
149
|
+
logger.debug('[WuLoader] 📦 Dynamic loader initialized');
|
|
13
150
|
}
|
|
14
151
|
|
|
15
152
|
/**
|
|
@@ -22,18 +159,18 @@ class WuLoader {
|
|
|
22
159
|
const entryFile = manifest?.entry || 'index.js';
|
|
23
160
|
const fullUrl = `${appUrl}/${entryFile}`;
|
|
24
161
|
|
|
25
|
-
|
|
162
|
+
logger.debug(`[WuLoader] 📥 Loading app from: ${fullUrl}`);
|
|
26
163
|
|
|
27
164
|
try {
|
|
28
165
|
// Verificar cache
|
|
29
166
|
if (this.cache.has(fullUrl)) {
|
|
30
|
-
|
|
167
|
+
logger.debug(`[WuLoader] ⚡ Cache hit for: ${fullUrl}`);
|
|
31
168
|
return this.cache.get(fullUrl);
|
|
32
169
|
}
|
|
33
170
|
|
|
34
171
|
// Verificar si ya está cargando
|
|
35
172
|
if (this.loadingPromises.has(fullUrl)) {
|
|
36
|
-
|
|
173
|
+
logger.debug(`[WuLoader] ⏳ Loading in progress for: ${fullUrl}`);
|
|
37
174
|
return await this.loadingPromises.get(fullUrl);
|
|
38
175
|
}
|
|
39
176
|
|
|
@@ -47,7 +184,7 @@ class WuLoader {
|
|
|
47
184
|
this.loadingPromises.delete(fullUrl);
|
|
48
185
|
this.cache.set(fullUrl, code);
|
|
49
186
|
|
|
50
|
-
|
|
187
|
+
logger.debug(`[WuLoader] ✅ App loaded successfully: ${fullUrl}`);
|
|
51
188
|
return code;
|
|
52
189
|
|
|
53
190
|
} catch (error) {
|
|
@@ -75,7 +212,7 @@ class WuLoader {
|
|
|
75
212
|
|
|
76
213
|
const fullUrl = `${appUrl}/${normalizedPath}`;
|
|
77
214
|
|
|
78
|
-
|
|
215
|
+
logger.debug(`[WuLoader] 🧩 Loading component from: ${fullUrl}`);
|
|
79
216
|
|
|
80
217
|
try {
|
|
81
218
|
// Cargar código del componente
|
|
@@ -92,13 +229,13 @@ class WuLoader {
|
|
|
92
229
|
// Ejecutar y obtener el componente
|
|
93
230
|
const fakeModule = { exports: {} };
|
|
94
231
|
const fakeRequire = (name) => {
|
|
95
|
-
|
|
232
|
+
logger.warn(`[WuLoader] Component ${componentPath} requires ${name} - not supported yet`);
|
|
96
233
|
return {};
|
|
97
234
|
};
|
|
98
235
|
|
|
99
236
|
const component = componentFunction(fakeRequire, fakeModule, fakeModule.exports);
|
|
100
237
|
|
|
101
|
-
|
|
238
|
+
logger.debug(`[WuLoader] ✅ Component loaded: ${componentPath}`);
|
|
102
239
|
return component;
|
|
103
240
|
|
|
104
241
|
} catch (error) {
|
|
@@ -169,19 +306,19 @@ class WuLoader {
|
|
|
169
306
|
* @param {Array} appConfigs - Configuraciones de aplicaciones
|
|
170
307
|
*/
|
|
171
308
|
async preload(appConfigs) {
|
|
172
|
-
|
|
309
|
+
logger.debug(`[WuLoader] 🚀 Preloading ${appConfigs.length} apps...`);
|
|
173
310
|
|
|
174
311
|
const preloadPromises = appConfigs.map(async (config) => {
|
|
175
312
|
try {
|
|
176
313
|
await this.loadApp(config.url, config.manifest);
|
|
177
|
-
|
|
314
|
+
logger.debug(`[WuLoader] ✅ Preloaded: ${config.name}`);
|
|
178
315
|
} catch (error) {
|
|
179
|
-
|
|
316
|
+
logger.warn(`[WuLoader] ⚠️ Failed to preload ${config.name}:`, error.message);
|
|
180
317
|
}
|
|
181
318
|
});
|
|
182
319
|
|
|
183
320
|
await Promise.allSettled(preloadPromises);
|
|
184
|
-
|
|
321
|
+
logger.debug(`[WuLoader] 🎉 Preload completed`);
|
|
185
322
|
}
|
|
186
323
|
|
|
187
324
|
/**
|
|
@@ -210,13 +347,13 @@ class WuLoader {
|
|
|
210
347
|
const [appName, componentName] = importPath.split('.');
|
|
211
348
|
|
|
212
349
|
if (!appName || !componentName) {
|
|
213
|
-
|
|
350
|
+
logger.warn(`[WuLoader] Invalid import format: ${importPath}`);
|
|
214
351
|
continue;
|
|
215
352
|
}
|
|
216
353
|
|
|
217
354
|
const app = availableApps.get(appName);
|
|
218
355
|
if (!app) {
|
|
219
|
-
|
|
356
|
+
logger.warn(`[WuLoader] Import app not found: ${appName}`);
|
|
220
357
|
continue;
|
|
221
358
|
}
|
|
222
359
|
|
|
@@ -224,14 +361,14 @@ class WuLoader {
|
|
|
224
361
|
const exportPath = manifest?.wu?.exports?.[componentName];
|
|
225
362
|
|
|
226
363
|
if (!exportPath) {
|
|
227
|
-
|
|
364
|
+
logger.warn(`[WuLoader] Export not found: ${importPath}`);
|
|
228
365
|
continue;
|
|
229
366
|
}
|
|
230
367
|
|
|
231
368
|
try {
|
|
232
369
|
const component = await this.loadComponent(app.url, exportPath);
|
|
233
370
|
resolved.set(importPath, component);
|
|
234
|
-
|
|
371
|
+
logger.debug(`[WuLoader] ✅ Resolved dependency: ${importPath}`);
|
|
235
372
|
} catch (error) {
|
|
236
373
|
console.error(`[WuLoader] ❌ Failed to resolve: ${importPath}`, error);
|
|
237
374
|
}
|
|
@@ -250,12 +387,12 @@ class WuLoader {
|
|
|
250
387
|
for (const [url] of this.cache) {
|
|
251
388
|
if (regex.test(url)) {
|
|
252
389
|
this.cache.delete(url);
|
|
253
|
-
|
|
390
|
+
logger.debug(`[WuLoader] 🗑️ Cleared cache for: ${url}`);
|
|
254
391
|
}
|
|
255
392
|
}
|
|
256
393
|
} else {
|
|
257
394
|
this.cache.clear();
|
|
258
|
-
|
|
395
|
+
logger.debug(`[WuLoader] 🗑️ Cache cleared completely`);
|
|
259
396
|
}
|
|
260
397
|
}
|
|
261
398
|
|
|
@@ -271,142 +408,6 @@ class WuLoader {
|
|
|
271
408
|
}
|
|
272
409
|
}
|
|
273
410
|
|
|
274
|
-
/**
|
|
275
|
-
* 📝 WU-LOGGER: Sistema de logging inteligente para entornos
|
|
276
|
-
* Controla los logs automáticamente según el entorno
|
|
277
|
-
*/
|
|
278
|
-
|
|
279
|
-
class WuLogger {
|
|
280
|
-
constructor() {
|
|
281
|
-
// Detectar entorno automáticamente
|
|
282
|
-
this.isDevelopment = this.detectEnvironment();
|
|
283
|
-
// En desarrollo: warn (menos ruido), en producción: error
|
|
284
|
-
this.logLevel = this.isDevelopment ? 'warn' : 'error';
|
|
285
|
-
|
|
286
|
-
this.levels = {
|
|
287
|
-
debug: 0,
|
|
288
|
-
info: 1,
|
|
289
|
-
warn: 2,
|
|
290
|
-
error: 3,
|
|
291
|
-
silent: 4
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Detectar si estamos en desarrollo
|
|
297
|
-
*/
|
|
298
|
-
detectEnvironment() {
|
|
299
|
-
// Múltiples formas de detectar desarrollo
|
|
300
|
-
return (
|
|
301
|
-
// Vite development
|
|
302
|
-
window.location.hostname === 'localhost' ||
|
|
303
|
-
window.location.hostname === '127.0.0.1' ||
|
|
304
|
-
window.location.port !== '' ||
|
|
305
|
-
// NODE_ENV si está disponible
|
|
306
|
-
(typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') ||
|
|
307
|
-
// URL params para forzar debug
|
|
308
|
-
new URLSearchParams(window.location.search).has('wu-debug') ||
|
|
309
|
-
// Manual override
|
|
310
|
-
window.WU_DEBUG === true
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Configurar nivel de logging
|
|
316
|
-
*/
|
|
317
|
-
setLevel(level) {
|
|
318
|
-
this.logLevel = level;
|
|
319
|
-
return this;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Habilitar/deshabilitar development mode
|
|
324
|
-
*/
|
|
325
|
-
setDevelopment(isDev) {
|
|
326
|
-
this.isDevelopment = isDev;
|
|
327
|
-
this.logLevel = isDev ? 'debug' : 'error';
|
|
328
|
-
return this;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Verificar si debemos mostrar el log
|
|
333
|
-
*/
|
|
334
|
-
shouldLog(level) {
|
|
335
|
-
return this.levels[level] >= this.levels[this.logLevel];
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Logging methods
|
|
340
|
-
*/
|
|
341
|
-
debug(...args) {
|
|
342
|
-
if (this.shouldLog('debug')) {
|
|
343
|
-
console.log(...args);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
info(...args) {
|
|
348
|
-
if (this.shouldLog('info')) {
|
|
349
|
-
console.info(...args);
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
warn(...args) {
|
|
354
|
-
if (this.shouldLog('warn')) {
|
|
355
|
-
console.warn(...args);
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
error(...args) {
|
|
360
|
-
if (this.shouldLog('error')) {
|
|
361
|
-
console.error(...args);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* Logging con contexto Wu
|
|
367
|
-
*/
|
|
368
|
-
wu(level, ...args) {
|
|
369
|
-
if (this.shouldLog(level)) {
|
|
370
|
-
const method = level === 'debug' ? 'log' : level;
|
|
371
|
-
console[method]('[Wu]', ...args);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Helper methods específicos para Wu
|
|
377
|
-
*/
|
|
378
|
-
wuDebug(...args) { this.wu('debug', ...args); }
|
|
379
|
-
wuInfo(...args) { this.wu('info', ...args); }
|
|
380
|
-
wuWarn(...args) { this.wu('warn', ...args); }
|
|
381
|
-
wuError(...args) { this.wu('error', ...args); }
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// Singleton instance
|
|
385
|
-
const logger = new WuLogger();
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* 🔇 Silenciar todos los logs de Wu Framework
|
|
389
|
-
* Útil en producción para eliminar todo el ruido
|
|
390
|
-
*/
|
|
391
|
-
function silenceAllLogs() {
|
|
392
|
-
logger.setLevel('silent');
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* 🔊 Restaurar logs (nivel debug)
|
|
397
|
-
*/
|
|
398
|
-
function enableAllLogs() {
|
|
399
|
-
logger.setLevel('debug');
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
var wuLogger = /*#__PURE__*/Object.freeze({
|
|
403
|
-
__proto__: null,
|
|
404
|
-
WuLogger: WuLogger,
|
|
405
|
-
enableAllLogs: enableAllLogs,
|
|
406
|
-
logger: logger,
|
|
407
|
-
silenceAllLogs: silenceAllLogs
|
|
408
|
-
});
|
|
409
|
-
|
|
410
411
|
/**
|
|
411
412
|
* 🎨 WU-STYLE-BRIDGE: SHADOW DOM STYLE SHARING SYSTEM
|
|
412
413
|
*
|
|
@@ -2368,6 +2369,7 @@ class WuSandbox {
|
|
|
2368
2369
|
* Validación estricta de wu.json para seguridad
|
|
2369
2370
|
*/
|
|
2370
2371
|
|
|
2372
|
+
|
|
2371
2373
|
class WuManifest {
|
|
2372
2374
|
constructor() {
|
|
2373
2375
|
this.cache = new Map();
|
|
@@ -2427,12 +2429,12 @@ class WuManifest {
|
|
|
2427
2429
|
async load(appUrl) {
|
|
2428
2430
|
const manifestUrl = `${appUrl}/wu.json`;
|
|
2429
2431
|
|
|
2430
|
-
|
|
2432
|
+
logger.debug(`[WuManifest] 📥 Loading manifest: ${manifestUrl}`);
|
|
2431
2433
|
|
|
2432
2434
|
try {
|
|
2433
2435
|
// Verificar cache
|
|
2434
2436
|
if (this.cache.has(manifestUrl)) {
|
|
2435
|
-
|
|
2437
|
+
logger.debug(`[WuManifest] ⚡ Cache hit: ${manifestUrl}`);
|
|
2436
2438
|
return this.cache.get(manifestUrl);
|
|
2437
2439
|
}
|
|
2438
2440
|
|
|
@@ -2447,7 +2449,7 @@ class WuManifest {
|
|
|
2447
2449
|
if (!response.ok) {
|
|
2448
2450
|
// Si no hay manifest, crear uno básico
|
|
2449
2451
|
if (response.status === 404) {
|
|
2450
|
-
|
|
2452
|
+
logger.debug(`[WuManifest] 📄 No manifest found, creating default for: ${appUrl}`);
|
|
2451
2453
|
return this.createDefaultManifest(appUrl);
|
|
2452
2454
|
}
|
|
2453
2455
|
|
|
@@ -2475,7 +2477,7 @@ class WuManifest {
|
|
|
2475
2477
|
// Cachear resultado
|
|
2476
2478
|
this.cache.set(manifestUrl, validatedManifest);
|
|
2477
2479
|
|
|
2478
|
-
|
|
2480
|
+
logger.debug(`[WuManifest] ✅ Manifest loaded: ${manifest.name}`);
|
|
2479
2481
|
return validatedManifest;
|
|
2480
2482
|
|
|
2481
2483
|
} catch (error) {
|
|
@@ -2510,7 +2512,7 @@ class WuManifest {
|
|
|
2510
2512
|
}
|
|
2511
2513
|
};
|
|
2512
2514
|
|
|
2513
|
-
|
|
2515
|
+
logger.debug(`[WuManifest] 🔧 Created default manifest for: ${appName}`);
|
|
2514
2516
|
return defaultManifest;
|
|
2515
2517
|
}
|
|
2516
2518
|
|
|
@@ -2709,7 +2711,7 @@ class WuManifest {
|
|
|
2709
2711
|
// Validar imports
|
|
2710
2712
|
normalized.wu.imports = normalized.wu.imports.filter(imp => {
|
|
2711
2713
|
if (typeof imp !== 'string' || !imp.includes('.')) {
|
|
2712
|
-
|
|
2714
|
+
logger.warn(`[WuManifest] Invalid import format: ${imp}`);
|
|
2713
2715
|
return false;
|
|
2714
2716
|
}
|
|
2715
2717
|
return true;
|
|
@@ -2851,12 +2853,12 @@ class WuManifest {
|
|
|
2851
2853
|
for (const [url] of this.cache) {
|
|
2852
2854
|
if (regex.test(url)) {
|
|
2853
2855
|
this.cache.delete(url);
|
|
2854
|
-
|
|
2856
|
+
logger.debug(`[WuManifest] 🗑️ Cleared cache for: ${url}`);
|
|
2855
2857
|
}
|
|
2856
2858
|
}
|
|
2857
2859
|
} else {
|
|
2858
2860
|
this.cache.clear();
|
|
2859
|
-
|
|
2861
|
+
logger.debug(`[WuManifest] 🗑️ Manifest cache cleared completely`);
|
|
2860
2862
|
}
|
|
2861
2863
|
}
|
|
2862
2864
|
|
|
@@ -3174,6 +3176,7 @@ const store = new WuStore();
|
|
|
3174
3176
|
* Mantiene todo el core de wu-framework pero simplifica el uso
|
|
3175
3177
|
*/
|
|
3176
3178
|
|
|
3179
|
+
|
|
3177
3180
|
class WuApp {
|
|
3178
3181
|
/**
|
|
3179
3182
|
* @param {string} name - Nombre de la app
|
|
@@ -3209,7 +3212,7 @@ class WuApp {
|
|
|
3209
3212
|
keepAlive: this.keepAlive,
|
|
3210
3213
|
status: 'registered'
|
|
3211
3214
|
});
|
|
3212
|
-
|
|
3215
|
+
logger.debug(`📦 App registered: ${this.name} at ${this.url}`);
|
|
3213
3216
|
}
|
|
3214
3217
|
}
|
|
3215
3218
|
|
|
@@ -3248,7 +3251,7 @@ class WuApp {
|
|
|
3248
3251
|
*/
|
|
3249
3252
|
async unmount(options = {}) {
|
|
3250
3253
|
if (!this._mounted && !this._wu.isHidden(this.name)) {
|
|
3251
|
-
|
|
3254
|
+
logger.warn(`⚠️ App ${this.name} is not mounted`);
|
|
3252
3255
|
return this
|
|
3253
3256
|
}
|
|
3254
3257
|
|
|
@@ -3264,7 +3267,7 @@ class WuApp {
|
|
|
3264
3267
|
*/
|
|
3265
3268
|
async hide() {
|
|
3266
3269
|
if (!this._mounted) {
|
|
3267
|
-
|
|
3270
|
+
logger.warn(`⚠️ App ${this.name} is not mounted`);
|
|
3268
3271
|
return this
|
|
3269
3272
|
}
|
|
3270
3273
|
|
|
@@ -3279,7 +3282,7 @@ class WuApp {
|
|
|
3279
3282
|
*/
|
|
3280
3283
|
async show() {
|
|
3281
3284
|
if (!this._wu.isHidden(this.name)) {
|
|
3282
|
-
|
|
3285
|
+
logger.warn(`⚠️ App ${this.name} is not in keep-alive state`);
|
|
3283
3286
|
return this
|
|
3284
3287
|
}
|
|
3285
3288
|
|
|
@@ -3334,7 +3337,7 @@ class WuApp {
|
|
|
3334
3337
|
* @returns {Promise<void>}
|
|
3335
3338
|
*/
|
|
3336
3339
|
async reload() {
|
|
3337
|
-
|
|
3340
|
+
logger.debug(`🔄 Reloading app: ${this.name}`);
|
|
3338
3341
|
|
|
3339
3342
|
await this.unmount();
|
|
3340
3343
|
|
|
@@ -3347,7 +3350,7 @@ class WuApp {
|
|
|
3347
3350
|
}
|
|
3348
3351
|
|
|
3349
3352
|
await this.mount();
|
|
3350
|
-
|
|
3353
|
+
logger.debug(`✅ App reloaded: ${this.name}`);
|
|
3351
3354
|
|
|
3352
3355
|
return this
|
|
3353
3356
|
}
|
|
@@ -3398,7 +3401,7 @@ class WuApp {
|
|
|
3398
3401
|
await this.unmount({ force: true });
|
|
3399
3402
|
this._wu.apps.delete(this.name);
|
|
3400
3403
|
this._mounted = false;
|
|
3401
|
-
|
|
3404
|
+
logger.debug(`🗑️ App destroyed: ${this.name}`);
|
|
3402
3405
|
}
|
|
3403
3406
|
}
|
|
3404
3407
|
|
|
@@ -3413,6 +3416,7 @@ class WuApp {
|
|
|
3413
3416
|
* ⚠️ USO INTERNO: No exponer en API pública
|
|
3414
3417
|
*/
|
|
3415
3418
|
|
|
3419
|
+
|
|
3416
3420
|
class WuCache {
|
|
3417
3421
|
constructor(options = {}) {
|
|
3418
3422
|
this.config = {
|
|
@@ -3483,7 +3487,7 @@ class WuCache {
|
|
|
3483
3487
|
this.rateLimiting.inCooldown = true;
|
|
3484
3488
|
this.rateLimiting.cooldownUntil = now + this.rateLimiting.cooldownMs;
|
|
3485
3489
|
this.stats.rateLimited++;
|
|
3486
|
-
|
|
3490
|
+
logger.warn(`[WuCache] 🚫 Rate limit exceeded. Cooldown for ${this.rateLimiting.cooldownMs}ms`);
|
|
3487
3491
|
return false;
|
|
3488
3492
|
}
|
|
3489
3493
|
|
|
@@ -3579,7 +3583,7 @@ class WuCache {
|
|
|
3579
3583
|
// Verificar si necesitamos hacer espacio
|
|
3580
3584
|
const hasSpace = this.ensureSpace(entry.size);
|
|
3581
3585
|
if (hasSpace === false) {
|
|
3582
|
-
|
|
3586
|
+
logger.warn(`[WuCache] ⚠️ Cannot cache item: ${key} (too large)`);
|
|
3583
3587
|
return false;
|
|
3584
3588
|
}
|
|
3585
3589
|
|
|
@@ -3597,7 +3601,7 @@ class WuCache {
|
|
|
3597
3601
|
|
|
3598
3602
|
return true;
|
|
3599
3603
|
} catch (error) {
|
|
3600
|
-
|
|
3604
|
+
logger.warn('[WuCache] ⚠️ Failed to set cache:', error);
|
|
3601
3605
|
return false;
|
|
3602
3606
|
}
|
|
3603
3607
|
}
|
|
@@ -3632,7 +3636,7 @@ class WuCache {
|
|
|
3632
3636
|
this.clearStorage();
|
|
3633
3637
|
}
|
|
3634
3638
|
|
|
3635
|
-
|
|
3639
|
+
logger.debug('[WuCache] 🧹 Cache cleared');
|
|
3636
3640
|
}
|
|
3637
3641
|
|
|
3638
3642
|
/**
|
|
@@ -3675,7 +3679,7 @@ class WuCache {
|
|
|
3675
3679
|
|
|
3676
3680
|
// 🛡️ FIX: Validar que el item no sea más grande que el máximo permitido
|
|
3677
3681
|
if (neededSize > maxSizeBytes) {
|
|
3678
|
-
|
|
3682
|
+
logger.warn(`[WuCache] ⚠️ Item size (${neededSize}) exceeds max cache size (${maxSizeBytes}). Skipping.`);
|
|
3679
3683
|
return false;
|
|
3680
3684
|
}
|
|
3681
3685
|
|
|
@@ -3692,7 +3696,7 @@ class WuCache {
|
|
|
3692
3696
|
|
|
3693
3697
|
// 🛡️ FIX: Si el cache está vacío pero aún no hay espacio, salir
|
|
3694
3698
|
if (this.memoryCache.size === 0) {
|
|
3695
|
-
|
|
3699
|
+
logger.warn('[WuCache] ⚠️ Cache empty but still no space. Breaking loop.');
|
|
3696
3700
|
break;
|
|
3697
3701
|
}
|
|
3698
3702
|
|
|
@@ -3708,7 +3712,7 @@ class WuCache {
|
|
|
3708
3712
|
}
|
|
3709
3713
|
|
|
3710
3714
|
if (oldestKey) {
|
|
3711
|
-
|
|
3715
|
+
logger.debug(`[WuCache] 🗑️ Evicting LRU entry: ${oldestKey}`);
|
|
3712
3716
|
this.delete(oldestKey);
|
|
3713
3717
|
this.stats.evictions++;
|
|
3714
3718
|
} else {
|
|
@@ -3738,7 +3742,7 @@ class WuCache {
|
|
|
3738
3742
|
return JSON.parse(stored);
|
|
3739
3743
|
}
|
|
3740
3744
|
} catch (error) {
|
|
3741
|
-
|
|
3745
|
+
logger.warn('[WuCache] ⚠️ Failed to get from storage:', error);
|
|
3742
3746
|
}
|
|
3743
3747
|
return null;
|
|
3744
3748
|
}
|
|
@@ -3754,13 +3758,13 @@ class WuCache {
|
|
|
3754
3758
|
storage.setItem(`wu_cache_${key}`, JSON.stringify(entry));
|
|
3755
3759
|
} catch (error) {
|
|
3756
3760
|
// Storage lleno, limpiar entradas antiguas
|
|
3757
|
-
|
|
3761
|
+
logger.warn('[WuCache] ⚠️ Storage full, cleaning old entries');
|
|
3758
3762
|
this.cleanOldStorageEntries();
|
|
3759
3763
|
|
|
3760
3764
|
try {
|
|
3761
3765
|
storage.setItem(`wu_cache_${key}`, JSON.stringify(entry));
|
|
3762
3766
|
} catch {
|
|
3763
|
-
|
|
3767
|
+
logger.warn('[WuCache] ⚠️ Failed to save to storage after cleanup');
|
|
3764
3768
|
}
|
|
3765
3769
|
}
|
|
3766
3770
|
}
|
|
@@ -3774,7 +3778,7 @@ class WuCache {
|
|
|
3774
3778
|
const storage = this.getStorage();
|
|
3775
3779
|
storage.removeItem(`wu_cache_${key}`);
|
|
3776
3780
|
} catch (error) {
|
|
3777
|
-
|
|
3781
|
+
logger.warn('[WuCache] ⚠️ Failed to delete from storage:', error);
|
|
3778
3782
|
}
|
|
3779
3783
|
}
|
|
3780
3784
|
|
|
@@ -3792,7 +3796,7 @@ class WuCache {
|
|
|
3792
3796
|
}
|
|
3793
3797
|
});
|
|
3794
3798
|
} catch (error) {
|
|
3795
|
-
|
|
3799
|
+
logger.warn('[WuCache] ⚠️ Failed to clear storage:', error);
|
|
3796
3800
|
}
|
|
3797
3801
|
}
|
|
3798
3802
|
|
|
@@ -3824,9 +3828,9 @@ class WuCache {
|
|
|
3824
3828
|
storage.removeItem(entries[i].key);
|
|
3825
3829
|
}
|
|
3826
3830
|
|
|
3827
|
-
|
|
3831
|
+
logger.debug(`[WuCache] 🧹 Cleaned ${toRemove} old storage entries`);
|
|
3828
3832
|
} catch (error) {
|
|
3829
|
-
|
|
3833
|
+
logger.warn('[WuCache] ⚠️ Failed to clean old storage entries:', error);
|
|
3830
3834
|
}
|
|
3831
3835
|
}
|
|
3832
3836
|
|
|
@@ -3889,6 +3893,7 @@ class WuCache {
|
|
|
3889
3893
|
* - Verificación de apps autorizadas
|
|
3890
3894
|
*/
|
|
3891
3895
|
|
|
3896
|
+
|
|
3892
3897
|
class WuEventBus {
|
|
3893
3898
|
constructor() {
|
|
3894
3899
|
this.listeners = new Map();
|
|
@@ -4018,7 +4023,7 @@ class WuEventBus {
|
|
|
4018
4023
|
if (this.config.validateOrigin && this.config.strictMode) {
|
|
4019
4024
|
if (!this._validateOrigin(eventName, appName, options.token)) {
|
|
4020
4025
|
this.stats.rejected++;
|
|
4021
|
-
|
|
4026
|
+
logger.warn(`[WuEventBus] 🚫 Event rejected: ${eventName} from ${appName} (unauthorized)`);
|
|
4022
4027
|
return false;
|
|
4023
4028
|
}
|
|
4024
4029
|
}
|
|
@@ -4040,7 +4045,7 @@ class WuEventBus {
|
|
|
4040
4045
|
|
|
4041
4046
|
// Log si está habilitado
|
|
4042
4047
|
if (this.config.logEvents) {
|
|
4043
|
-
|
|
4048
|
+
logger.debug(`[WuEventBus] 📢 ${eventName}`, data);
|
|
4044
4049
|
}
|
|
4045
4050
|
|
|
4046
4051
|
// Notificar listeners exactos
|
|
@@ -4234,6 +4239,7 @@ class WuEventBus {
|
|
|
4234
4239
|
* - Estadísticas por app
|
|
4235
4240
|
*/
|
|
4236
4241
|
|
|
4242
|
+
|
|
4237
4243
|
class WuPerformance {
|
|
4238
4244
|
constructor() {
|
|
4239
4245
|
this.metrics = new Map(); // appName -> metrics
|
|
@@ -4251,7 +4257,7 @@ class WuPerformance {
|
|
|
4251
4257
|
load: 5000 // ms
|
|
4252
4258
|
};
|
|
4253
4259
|
|
|
4254
|
-
|
|
4260
|
+
logger.debug('[WuPerformance] ⚡ Framework performance monitoring initialized');
|
|
4255
4261
|
}
|
|
4256
4262
|
|
|
4257
4263
|
/**
|
|
@@ -4263,7 +4269,7 @@ class WuPerformance {
|
|
|
4263
4269
|
const markName = `${appName}:${name}:start`;
|
|
4264
4270
|
this.marks.set(markName, performance.now());
|
|
4265
4271
|
|
|
4266
|
-
|
|
4272
|
+
logger.debug(`[WuPerformance] 📊 Measure started: ${markName}`);
|
|
4267
4273
|
}
|
|
4268
4274
|
|
|
4269
4275
|
/**
|
|
@@ -4277,7 +4283,7 @@ class WuPerformance {
|
|
|
4277
4283
|
const startTime = this.marks.get(markName);
|
|
4278
4284
|
|
|
4279
4285
|
if (!startTime) {
|
|
4280
|
-
|
|
4286
|
+
// Puede ocurrir en React StrictMode (doble mount) — no es un error
|
|
4281
4287
|
return 0;
|
|
4282
4288
|
}
|
|
4283
4289
|
|
|
@@ -4295,10 +4301,10 @@ class WuPerformance {
|
|
|
4295
4301
|
|
|
4296
4302
|
// Verificar threshold
|
|
4297
4303
|
if (this.checkThreshold(name, duration)) {
|
|
4298
|
-
|
|
4304
|
+
logger.warn(`[WuPerformance] ⚠️ Threshold exceeded for ${name}: ${duration.toFixed(2)}ms`);
|
|
4299
4305
|
}
|
|
4300
4306
|
|
|
4301
|
-
|
|
4307
|
+
logger.debug(`[WuPerformance] ⏹️ Measure ended: ${markName} (${duration.toFixed(2)}ms)`);
|
|
4302
4308
|
return duration;
|
|
4303
4309
|
}
|
|
4304
4310
|
|
|
@@ -4430,7 +4436,7 @@ class WuPerformance {
|
|
|
4430
4436
|
this.measurements = [];
|
|
4431
4437
|
}
|
|
4432
4438
|
|
|
4433
|
-
|
|
4439
|
+
logger.debug(`[WuPerformance] 🧹 Metrics cleared${appName ? ` for ${appName}` : ''}`);
|
|
4434
4440
|
}
|
|
4435
4441
|
|
|
4436
4442
|
/**
|
|
@@ -4462,6 +4468,7 @@ class WuPerformance {
|
|
|
4462
4468
|
* - Timeout protection
|
|
4463
4469
|
*/
|
|
4464
4470
|
|
|
4471
|
+
|
|
4465
4472
|
class WuPluginSystem {
|
|
4466
4473
|
constructor(core) {
|
|
4467
4474
|
this._core = core; // Privado - no expuesto a plugins
|
|
@@ -4555,7 +4562,7 @@ class WuPluginSystem {
|
|
|
4555
4562
|
// 🚨 Acceso completo solo con permiso 'unsafe'
|
|
4556
4563
|
if (permissions.includes('unsafe')) {
|
|
4557
4564
|
api._unsafeCore = this._core;
|
|
4558
|
-
|
|
4565
|
+
logger.warn('[WuPlugin] ⚠️ Plugin has unsafe access to core!');
|
|
4559
4566
|
}
|
|
4560
4567
|
|
|
4561
4568
|
// Congelar API para evitar modificaciones
|
|
@@ -4620,7 +4627,7 @@ class WuPluginSystem {
|
|
|
4620
4627
|
|
|
4621
4628
|
// Verificar si ya está instalado
|
|
4622
4629
|
if (this.plugins.has(plugin.name)) {
|
|
4623
|
-
|
|
4630
|
+
logger.warn(`[WuPlugin] Plugin "${plugin.name}" already installed`);
|
|
4624
4631
|
return;
|
|
4625
4632
|
}
|
|
4626
4633
|
|
|
@@ -4658,7 +4665,7 @@ class WuPluginSystem {
|
|
|
4658
4665
|
installedAt: Date.now()
|
|
4659
4666
|
});
|
|
4660
4667
|
|
|
4661
|
-
|
|
4668
|
+
logger.debug(`[WuPlugin] ✅ Plugin "${plugin.name}" installed (permissions: ${permissions.join(', ')})`);
|
|
4662
4669
|
}
|
|
4663
4670
|
|
|
4664
4671
|
/**
|
|
@@ -4691,7 +4698,7 @@ class WuPluginSystem {
|
|
|
4691
4698
|
*/
|
|
4692
4699
|
registerHook(hookName, callback) {
|
|
4693
4700
|
if (!this.hooks.has(hookName)) {
|
|
4694
|
-
|
|
4701
|
+
logger.warn(`[WuPlugin] Unknown hook: ${hookName}`);
|
|
4695
4702
|
return;
|
|
4696
4703
|
}
|
|
4697
4704
|
this.hooks.get(hookName).push(callback);
|
|
@@ -4723,7 +4730,7 @@ class WuPluginSystem {
|
|
|
4723
4730
|
uninstall(pluginName) {
|
|
4724
4731
|
const pluginData = this.plugins.get(pluginName);
|
|
4725
4732
|
if (!pluginData) {
|
|
4726
|
-
|
|
4733
|
+
logger.warn(`[WuPlugin] Plugin "${pluginName}" not found`);
|
|
4727
4734
|
return;
|
|
4728
4735
|
}
|
|
4729
4736
|
|
|
@@ -4738,7 +4745,7 @@ class WuPluginSystem {
|
|
|
4738
4745
|
}
|
|
4739
4746
|
|
|
4740
4747
|
this.plugins.delete(pluginName);
|
|
4741
|
-
|
|
4748
|
+
logger.debug(`[WuPlugin] ✅ Plugin "${pluginName}" uninstalled`);
|
|
4742
4749
|
}
|
|
4743
4750
|
|
|
4744
4751
|
/**
|
|
@@ -4809,6 +4816,7 @@ const createPlugin = (config) => {
|
|
|
4809
4816
|
* - Idle: Carga cuando el navegador está idle
|
|
4810
4817
|
*/
|
|
4811
4818
|
|
|
4819
|
+
|
|
4812
4820
|
class WuLoadingStrategy {
|
|
4813
4821
|
constructor(core) {
|
|
4814
4822
|
this.core = core;
|
|
@@ -4819,7 +4827,7 @@ class WuLoadingStrategy {
|
|
|
4819
4827
|
this.registerDefaultStrategies();
|
|
4820
4828
|
this.setupIdleCallback();
|
|
4821
4829
|
|
|
4822
|
-
|
|
4830
|
+
logger.debug('[WuStrategies] 🎯 Loading strategies initialized');
|
|
4823
4831
|
}
|
|
4824
4832
|
|
|
4825
4833
|
/**
|
|
@@ -4830,7 +4838,7 @@ class WuLoadingStrategy {
|
|
|
4830
4838
|
this.register('lazy', {
|
|
4831
4839
|
shouldPreload: false,
|
|
4832
4840
|
load: async (appName, config) => {
|
|
4833
|
-
|
|
4841
|
+
logger.debug(`[Strategy:Lazy] Loading ${appName} on demand (no preload)`);
|
|
4834
4842
|
// No hace nada, la app se carga cuando se monta
|
|
4835
4843
|
return;
|
|
4836
4844
|
}
|
|
@@ -4841,14 +4849,14 @@ class WuLoadingStrategy {
|
|
|
4841
4849
|
shouldPreload: true,
|
|
4842
4850
|
priority: 'high',
|
|
4843
4851
|
load: async (appName, config) => {
|
|
4844
|
-
|
|
4852
|
+
logger.debug(`[Strategy:Eager] Preloading ${appName} immediately`);
|
|
4845
4853
|
|
|
4846
4854
|
// Cargar el módulo de la app
|
|
4847
4855
|
const app = this.core.apps.get(appName);
|
|
4848
4856
|
if (app) {
|
|
4849
4857
|
const moduleUrl = await this.core.resolveModulePath(app);
|
|
4850
4858
|
await import(/* @vite-ignore */ moduleUrl);
|
|
4851
|
-
|
|
4859
|
+
logger.debug(`[Strategy:Eager] ✅ ${appName} preloaded`);
|
|
4852
4860
|
}
|
|
4853
4861
|
}
|
|
4854
4862
|
});
|
|
@@ -4858,7 +4866,7 @@ class WuLoadingStrategy {
|
|
|
4858
4866
|
shouldPreload: true,
|
|
4859
4867
|
priority: 'medium',
|
|
4860
4868
|
load: async (appName, config) => {
|
|
4861
|
-
|
|
4869
|
+
logger.debug(`[Strategy:Preload] Using resource hints for ${appName}`);
|
|
4862
4870
|
|
|
4863
4871
|
// Crear <link rel="prefetch">
|
|
4864
4872
|
const app = this.core.apps.get(appName);
|
|
@@ -4871,7 +4879,7 @@ class WuLoadingStrategy {
|
|
|
4871
4879
|
link.as = 'script';
|
|
4872
4880
|
document.head.appendChild(link);
|
|
4873
4881
|
|
|
4874
|
-
|
|
4882
|
+
logger.debug(`[Strategy:Preload] ✅ Resource hint added for ${appName}`);
|
|
4875
4883
|
}
|
|
4876
4884
|
}
|
|
4877
4885
|
});
|
|
@@ -4893,7 +4901,7 @@ class WuLoadingStrategy {
|
|
|
4893
4901
|
this.register('idle', {
|
|
4894
4902
|
shouldPreload: false,
|
|
4895
4903
|
load: async (appName, config) => {
|
|
4896
|
-
|
|
4904
|
+
logger.debug(`[Strategy:Idle] Queueing ${appName} for idle loading`);
|
|
4897
4905
|
|
|
4898
4906
|
return new Promise((resolve) => {
|
|
4899
4907
|
this.loadingQueue.push({
|
|
@@ -4928,7 +4936,7 @@ class WuLoadingStrategy {
|
|
|
4928
4936
|
load: strategy.load
|
|
4929
4937
|
});
|
|
4930
4938
|
|
|
4931
|
-
|
|
4939
|
+
logger.debug(`[WuStrategies] Strategy "${name}" registered`);
|
|
4932
4940
|
}
|
|
4933
4941
|
|
|
4934
4942
|
/**
|
|
@@ -4942,7 +4950,7 @@ class WuLoadingStrategy {
|
|
|
4942
4950
|
const strategy = this.strategies.get(strategyName);
|
|
4943
4951
|
|
|
4944
4952
|
if (!strategy) {
|
|
4945
|
-
|
|
4953
|
+
logger.warn(`[WuStrategies] Strategy "${strategyName}" not found, using lazy`);
|
|
4946
4954
|
return await this.strategies.get('lazy').load(appName, config);
|
|
4947
4955
|
}
|
|
4948
4956
|
|
|
@@ -4967,7 +4975,7 @@ class WuLoadingStrategy {
|
|
|
4967
4975
|
return priorityOrder[aPriority] - priorityOrder[bPriority];
|
|
4968
4976
|
});
|
|
4969
4977
|
|
|
4970
|
-
|
|
4978
|
+
logger.debug(`[WuStrategies] Preloading ${toPreload.length} apps`);
|
|
4971
4979
|
|
|
4972
4980
|
// Precargar en orden
|
|
4973
4981
|
for (const app of toPreload) {
|
|
@@ -5020,7 +5028,7 @@ class WuLoadingStrategy {
|
|
|
5020
5028
|
if (app) {
|
|
5021
5029
|
const moduleUrl = await this.core.resolveModulePath(app);
|
|
5022
5030
|
await import(/* @vite-ignore */ moduleUrl);
|
|
5023
|
-
|
|
5031
|
+
logger.debug(`[Strategy:Idle] ✅ ${item.appName} loaded during idle time`);
|
|
5024
5032
|
item.resolve(true);
|
|
5025
5033
|
} else {
|
|
5026
5034
|
item.resolve(null);
|
|
@@ -5050,7 +5058,7 @@ class WuLoadingStrategy {
|
|
|
5050
5058
|
*/
|
|
5051
5059
|
cleanup() {
|
|
5052
5060
|
this.loadingQueue = [];
|
|
5053
|
-
|
|
5061
|
+
logger.debug('[WuStrategies] 🧹 Strategies cleaned up');
|
|
5054
5062
|
}
|
|
5055
5063
|
}
|
|
5056
5064
|
|
|
@@ -5064,6 +5072,7 @@ class WuLoadingStrategy {
|
|
|
5064
5072
|
* - Fallback rendering
|
|
5065
5073
|
*/
|
|
5066
5074
|
|
|
5075
|
+
|
|
5067
5076
|
class WuErrorBoundary {
|
|
5068
5077
|
constructor(core) {
|
|
5069
5078
|
this.core = core;
|
|
@@ -5079,7 +5088,7 @@ class WuErrorBoundary {
|
|
|
5079
5088
|
|
|
5080
5089
|
this.registerDefaultHandlers();
|
|
5081
5090
|
|
|
5082
|
-
|
|
5091
|
+
logger.debug('[WuErrorBoundary] 🛡️ Error boundary initialized');
|
|
5083
5092
|
}
|
|
5084
5093
|
|
|
5085
5094
|
/**
|
|
@@ -5094,12 +5103,12 @@ class WuErrorBoundary {
|
|
|
5094
5103
|
(error.message.includes('fetch') || error.message.includes('network'));
|
|
5095
5104
|
},
|
|
5096
5105
|
handle: async (error, context) => {
|
|
5097
|
-
|
|
5106
|
+
logger.debug('[ErrorHandler:Network] Handling network error');
|
|
5098
5107
|
|
|
5099
5108
|
// Retry con backoff
|
|
5100
5109
|
if (context.retryCount < this.config.maxRetries) {
|
|
5101
5110
|
const delay = this.config.retryDelay * Math.pow(2, context.retryCount);
|
|
5102
|
-
|
|
5111
|
+
logger.debug(`[ErrorHandler:Network] Retrying in ${delay}ms...`);
|
|
5103
5112
|
|
|
5104
5113
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
5105
5114
|
|
|
@@ -5127,11 +5136,11 @@ class WuErrorBoundary {
|
|
|
5127
5136
|
error.message.includes('Failed to fetch'));
|
|
5128
5137
|
},
|
|
5129
5138
|
handle: async (error, context) => {
|
|
5130
|
-
|
|
5139
|
+
logger.debug('[ErrorHandler:ScriptLoad] Handling script load error');
|
|
5131
5140
|
|
|
5132
5141
|
// Intentar URL alternativa si existe
|
|
5133
5142
|
if (context.fallbackUrl) {
|
|
5134
|
-
|
|
5143
|
+
logger.debug('[ErrorHandler:ScriptLoad] Trying fallback URL');
|
|
5135
5144
|
return {
|
|
5136
5145
|
recovered: true,
|
|
5137
5146
|
action: 'use-fallback-url',
|
|
@@ -5154,17 +5163,17 @@ class WuErrorBoundary {
|
|
|
5154
5163
|
return error.message && error.message.includes('mount');
|
|
5155
5164
|
},
|
|
5156
5165
|
handle: async (error, context) => {
|
|
5157
|
-
|
|
5166
|
+
logger.debug('[ErrorHandler:Mount] Handling mount error');
|
|
5158
5167
|
|
|
5159
5168
|
// Limpiar y reintentar
|
|
5160
5169
|
if (context.retryCount < 2) {
|
|
5161
|
-
|
|
5170
|
+
logger.debug('[ErrorHandler:Mount] Cleaning up and retrying...');
|
|
5162
5171
|
|
|
5163
5172
|
// Cleanup
|
|
5164
5173
|
try {
|
|
5165
5174
|
await this.core.unmount(context.appName);
|
|
5166
5175
|
} catch (cleanupError) {
|
|
5167
|
-
|
|
5176
|
+
logger.warn('[ErrorHandler:Mount] Cleanup failed:', cleanupError);
|
|
5168
5177
|
}
|
|
5169
5178
|
|
|
5170
5179
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
@@ -5192,7 +5201,7 @@ class WuErrorBoundary {
|
|
|
5192
5201
|
error.message.includes('timeout');
|
|
5193
5202
|
},
|
|
5194
5203
|
handle: async (error, context) => {
|
|
5195
|
-
|
|
5204
|
+
logger.debug('[ErrorHandler:Timeout] Handling timeout error');
|
|
5196
5205
|
|
|
5197
5206
|
// Aumentar timeout y reintentar
|
|
5198
5207
|
if (context.retryCount < 2) {
|
|
@@ -5217,7 +5226,7 @@ class WuErrorBoundary {
|
|
|
5217
5226
|
name: 'generic',
|
|
5218
5227
|
canHandle: () => true, // Maneja todo
|
|
5219
5228
|
handle: async (error, context) => {
|
|
5220
|
-
|
|
5229
|
+
logger.debug('[ErrorHandler:Generic] Handling generic error');
|
|
5221
5230
|
|
|
5222
5231
|
return {
|
|
5223
5232
|
recovered: false,
|
|
@@ -5238,7 +5247,7 @@ class WuErrorBoundary {
|
|
|
5238
5247
|
}
|
|
5239
5248
|
|
|
5240
5249
|
this.handlers.push(handler);
|
|
5241
|
-
|
|
5250
|
+
logger.debug(`[WuErrorBoundary] Handler "${handler.name}" registered`);
|
|
5242
5251
|
}
|
|
5243
5252
|
|
|
5244
5253
|
/**
|
|
@@ -5262,12 +5271,12 @@ class WuErrorBoundary {
|
|
|
5262
5271
|
for (const handler of this.handlers) {
|
|
5263
5272
|
try {
|
|
5264
5273
|
if (handler.canHandle(error, context)) {
|
|
5265
|
-
|
|
5274
|
+
logger.debug(`[WuErrorBoundary] Using handler: ${handler.name}`);
|
|
5266
5275
|
|
|
5267
5276
|
const result = await handler.handle(error, context);
|
|
5268
5277
|
|
|
5269
5278
|
if (result.recovered) {
|
|
5270
|
-
|
|
5279
|
+
logger.debug(`[WuErrorBoundary] ✅ Error recovered by ${handler.name}`);
|
|
5271
5280
|
return result;
|
|
5272
5281
|
}
|
|
5273
5282
|
|
|
@@ -5300,7 +5309,7 @@ class WuErrorBoundary {
|
|
|
5300
5309
|
*/
|
|
5301
5310
|
renderFallback(context, result) {
|
|
5302
5311
|
if (!context.container) {
|
|
5303
|
-
|
|
5312
|
+
logger.warn('[WuErrorBoundary] No container to render fallback');
|
|
5304
5313
|
return;
|
|
5305
5314
|
}
|
|
5306
5315
|
|
|
@@ -5431,7 +5440,7 @@ class WuErrorBoundary {
|
|
|
5431
5440
|
*/
|
|
5432
5441
|
cleanup() {
|
|
5433
5442
|
this.errorLog = [];
|
|
5434
|
-
|
|
5443
|
+
logger.debug('[WuErrorBoundary] 🧹 Error boundary cleaned up');
|
|
5435
5444
|
}
|
|
5436
5445
|
}
|
|
5437
5446
|
|
|
@@ -5446,6 +5455,7 @@ class WuErrorBoundary {
|
|
|
5446
5455
|
* - Async/await support
|
|
5447
5456
|
*/
|
|
5448
5457
|
|
|
5458
|
+
|
|
5449
5459
|
class WuLifecycleHooks {
|
|
5450
5460
|
constructor(core) {
|
|
5451
5461
|
this.core = core;
|
|
@@ -5472,7 +5482,7 @@ class WuLifecycleHooks {
|
|
|
5472
5482
|
this.hooks.set(phase, []);
|
|
5473
5483
|
});
|
|
5474
5484
|
|
|
5475
|
-
|
|
5485
|
+
logger.debug('[WuHooks] 🪝 Lifecycle hooks initialized');
|
|
5476
5486
|
}
|
|
5477
5487
|
|
|
5478
5488
|
/**
|
|
@@ -5503,7 +5513,7 @@ class WuLifecycleHooks {
|
|
|
5503
5513
|
// Ordenar por prioridad (mayor primero)
|
|
5504
5514
|
hooks.sort((a, b) => b.priority - a.priority);
|
|
5505
5515
|
|
|
5506
|
-
|
|
5516
|
+
logger.debug(`[WuHooks] Hook "${hook.name}" registered for ${phase} (priority: ${hook.priority})`);
|
|
5507
5517
|
|
|
5508
5518
|
// Retornar función para desregistrar
|
|
5509
5519
|
return () => this.remove(phase, hook.name);
|
|
@@ -5522,7 +5532,7 @@ class WuLifecycleHooks {
|
|
|
5522
5532
|
|
|
5523
5533
|
if (index > -1) {
|
|
5524
5534
|
hooks.splice(index, 1);
|
|
5525
|
-
|
|
5535
|
+
logger.debug(`[WuHooks] Hook "${name}" removed from ${phase}`);
|
|
5526
5536
|
}
|
|
5527
5537
|
}
|
|
5528
5538
|
|
|
@@ -5539,7 +5549,7 @@ class WuLifecycleHooks {
|
|
|
5539
5549
|
return context;
|
|
5540
5550
|
}
|
|
5541
5551
|
|
|
5542
|
-
|
|
5552
|
+
logger.debug(`[WuHooks] Executing ${hooks.length} hooks for ${phase}`);
|
|
5543
5553
|
|
|
5544
5554
|
// Log para debugging
|
|
5545
5555
|
const executionEntry = {
|
|
@@ -5583,13 +5593,13 @@ class WuLifecycleHooks {
|
|
|
5583
5593
|
|
|
5584
5594
|
// Si no se llamó next(), la operación fue cancelada
|
|
5585
5595
|
if (!nextCalled) {
|
|
5586
|
-
|
|
5596
|
+
logger.debug(`[WuHooks] Hook "${hook.name}" cancelled execution`);
|
|
5587
5597
|
cancelled = true;
|
|
5588
5598
|
return { cancelled: true };
|
|
5589
5599
|
}
|
|
5590
5600
|
|
|
5591
5601
|
const duration = Date.now() - startTime;
|
|
5592
|
-
|
|
5602
|
+
logger.debug(`[WuHooks] Hook "${hook.name}" executed in ${duration}ms`);
|
|
5593
5603
|
|
|
5594
5604
|
} catch (error) {
|
|
5595
5605
|
console.error(`[WuHooks] Error in hook "${hook.name}":`, error);
|
|
@@ -5694,13 +5704,13 @@ class WuLifecycleHooks {
|
|
|
5694
5704
|
cleanup(phase) {
|
|
5695
5705
|
if (phase) {
|
|
5696
5706
|
this.hooks.set(phase, []);
|
|
5697
|
-
|
|
5707
|
+
logger.debug(`[WuHooks] Hooks cleaned for ${phase}`);
|
|
5698
5708
|
} else {
|
|
5699
5709
|
this.lifecyclePhases.forEach(p => {
|
|
5700
5710
|
this.hooks.set(p, []);
|
|
5701
5711
|
});
|
|
5702
5712
|
this.executionLog = [];
|
|
5703
|
-
|
|
5713
|
+
logger.debug('[WuHooks] 🧹 All hooks cleaned');
|
|
5704
5714
|
}
|
|
5705
5715
|
}
|
|
5706
5716
|
}
|
|
@@ -14908,7 +14918,7 @@ function createMcpBridge(wu) {
|
|
|
14908
14918
|
|
|
14909
14919
|
function connect(url = 'ws://localhost:19100', options = {}) {
|
|
14910
14920
|
if (ws && ws.readyState <= 1) {
|
|
14911
|
-
|
|
14921
|
+
logger.warn('[wu-mcp-bridge] Already connected or connecting');
|
|
14912
14922
|
return;
|
|
14913
14923
|
}
|
|
14914
14924
|
|
|
@@ -14919,7 +14929,7 @@ function createMcpBridge(wu) {
|
|
|
14919
14929
|
ws = new WebSocket(url);
|
|
14920
14930
|
|
|
14921
14931
|
ws.onopen = () => {
|
|
14922
|
-
|
|
14932
|
+
logger.debug('[wu-mcp-bridge] Connected to wu-mcp-server');
|
|
14923
14933
|
reconnectAttempts = 0;
|
|
14924
14934
|
|
|
14925
14935
|
// Send auth handshake if token provided
|
|
@@ -14942,7 +14952,7 @@ function createMcpBridge(wu) {
|
|
|
14942
14952
|
console.error('[wu-mcp-bridge] Authentication failed:', msg.reason || 'Invalid token');
|
|
14943
14953
|
disconnect();
|
|
14944
14954
|
} else {
|
|
14945
|
-
|
|
14955
|
+
logger.debug('[wu-mcp-bridge] Authenticated successfully');
|
|
14946
14956
|
}
|
|
14947
14957
|
return;
|
|
14948
14958
|
}
|
|
@@ -14958,7 +14968,7 @@ function createMcpBridge(wu) {
|
|
|
14958
14968
|
const { id, command, params } = msg;
|
|
14959
14969
|
|
|
14960
14970
|
if (!id || !command) {
|
|
14961
|
-
|
|
14971
|
+
logger.warn('[wu-mcp-bridge] Invalid message:', msg);
|
|
14962
14972
|
return;
|
|
14963
14973
|
}
|
|
14964
14974
|
|
|
@@ -14980,7 +14990,7 @@ function createMcpBridge(wu) {
|
|
|
14980
14990
|
};
|
|
14981
14991
|
|
|
14982
14992
|
ws.onclose = () => {
|
|
14983
|
-
|
|
14993
|
+
logger.debug('[wu-mcp-bridge] Disconnected');
|
|
14984
14994
|
ws = null;
|
|
14985
14995
|
authenticated = false;
|
|
14986
14996
|
_scheduleReconnect(url, options);
|