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/package.json
CHANGED
|
@@ -174,13 +174,23 @@ async function register(appName, Component, options = {}) {
|
|
|
174
174
|
return;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
// Si ya está montado en el MISMO container, ignorar (StrictMode double-mount)
|
|
178
|
+
const existing = adapterState.roots.get(appName);
|
|
179
|
+
if (existing) {
|
|
180
|
+
if (existing.container === container) {
|
|
181
|
+
return; // Ya montado aquí, nada que hacer
|
|
182
|
+
}
|
|
183
|
+
// Diferente container → desmontar primero
|
|
180
184
|
unmountApp();
|
|
181
185
|
}
|
|
182
186
|
|
|
183
187
|
try {
|
|
188
|
+
// Limpiar el DOM del container antes de crear un nuevo root.
|
|
189
|
+
// En React 18+, root.unmount() es async — si se llama createRoot()
|
|
190
|
+
// en el mismo container antes de que termine, falla silenciosamente.
|
|
191
|
+
// Limpiar innerHTML fuerza un DOM limpio para el nuevo root.
|
|
192
|
+
container.innerHTML = '';
|
|
193
|
+
|
|
184
194
|
const root = createRoot(container);
|
|
185
195
|
|
|
186
196
|
// Crear elemento con o sin StrictMode
|
|
@@ -192,8 +202,6 @@ async function register(appName, Component, options = {}) {
|
|
|
192
202
|
root.render(element);
|
|
193
203
|
adapterState.roots.set(appName, { root, container });
|
|
194
204
|
|
|
195
|
-
console.log(`[WuReact] ✅ ${appName} mounted successfully`);
|
|
196
|
-
|
|
197
205
|
if (onMount) {
|
|
198
206
|
onMount(container);
|
|
199
207
|
}
|
|
@@ -215,16 +223,15 @@ async function register(appName, Component, options = {}) {
|
|
|
215
223
|
|
|
216
224
|
instance.root.unmount();
|
|
217
225
|
adapterState.roots.delete(appName);
|
|
218
|
-
|
|
219
|
-
console.log(`[WuReact] ✅ ${appName} unmounted successfully`);
|
|
220
226
|
} catch (error) {
|
|
221
227
|
console.error(`[WuReact] Unmount error for ${appName}:`, error);
|
|
222
228
|
}
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
// Limpiar container
|
|
226
|
-
|
|
227
|
-
|
|
231
|
+
// Limpiar container
|
|
232
|
+
const target = container || instance?.container;
|
|
233
|
+
if (target) {
|
|
234
|
+
target.innerHTML = '';
|
|
228
235
|
}
|
|
229
236
|
};
|
|
230
237
|
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
* <WuSlot name="my-app" url="http://localhost:3001" />
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import { logger } from '../../core/wu-logger.js';
|
|
22
|
+
|
|
21
23
|
// Estado global del adapter
|
|
22
24
|
const adapterState = {
|
|
23
25
|
apps: new Map(),
|
|
@@ -164,7 +166,7 @@ async function register(appName, RootComponent, options = {}) {
|
|
|
164
166
|
|
|
165
167
|
// Evitar doble mount
|
|
166
168
|
if (adapterState.apps.has(appName)) {
|
|
167
|
-
|
|
169
|
+
logger.warn(`[WuVue] ${appName} already mounted, unmounting first`);
|
|
168
170
|
unmountApp();
|
|
169
171
|
}
|
|
170
172
|
|
|
@@ -206,7 +208,7 @@ async function register(appName, RootComponent, options = {}) {
|
|
|
206
208
|
if (viteId && !shadowRoot.querySelector(`style[data-vite-dev-id="${viteId}"]`)) {
|
|
207
209
|
const clonedStyle = style.cloneNode(true);
|
|
208
210
|
shadowRoot.insertBefore(clonedStyle, shadowRoot.firstChild);
|
|
209
|
-
|
|
211
|
+
logger.debug(`[WuVue] ✅ Injected style into Shadow DOM: ${viteId}`);
|
|
210
212
|
}
|
|
211
213
|
});
|
|
212
214
|
|
|
@@ -218,7 +220,7 @@ async function register(appName, RootComponent, options = {}) {
|
|
|
218
220
|
if (!shadowRoot.querySelector(`style[data-vite-dev-id="${viteId}"]`)) {
|
|
219
221
|
const clonedStyle = style.cloneNode(true);
|
|
220
222
|
shadowRoot.insertBefore(clonedStyle, shadowRoot.firstChild);
|
|
221
|
-
|
|
223
|
+
logger.debug(`[WuVue] ✅ Injected app style into Shadow DOM: ${viteId}`);
|
|
222
224
|
}
|
|
223
225
|
}
|
|
224
226
|
});
|
|
@@ -228,7 +230,7 @@ async function register(appName, RootComponent, options = {}) {
|
|
|
228
230
|
// Guardar referencia
|
|
229
231
|
adapterState.apps.set(appName, { app, container });
|
|
230
232
|
|
|
231
|
-
|
|
233
|
+
logger.debug(`[WuVue] ✅ ${appName} mounted successfully`);
|
|
232
234
|
|
|
233
235
|
if (onMount) {
|
|
234
236
|
onMount(container, app);
|
|
@@ -252,7 +254,7 @@ async function register(appName, RootComponent, options = {}) {
|
|
|
252
254
|
instance.app.unmount();
|
|
253
255
|
adapterState.apps.delete(appName);
|
|
254
256
|
|
|
255
|
-
|
|
257
|
+
logger.debug(`[WuVue] ✅ ${appName} unmounted successfully`);
|
|
256
258
|
} catch (error) {
|
|
257
259
|
console.error(`[WuVue] Unmount error for ${appName}:`, error);
|
|
258
260
|
}
|
|
@@ -273,22 +275,22 @@ async function register(appName, RootComponent, options = {}) {
|
|
|
273
275
|
unmount: unmountApp
|
|
274
276
|
});
|
|
275
277
|
|
|
276
|
-
|
|
278
|
+
logger.debug(`[WuVue] ✅ ${appName} registered with Wu Framework`);
|
|
277
279
|
return true;
|
|
278
280
|
|
|
279
281
|
} catch (error) {
|
|
280
|
-
|
|
282
|
+
logger.warn(`[WuVue] Wu Framework not available for ${appName}`);
|
|
281
283
|
|
|
282
284
|
// Modo standalone si está habilitado
|
|
283
285
|
if (standalone) {
|
|
284
286
|
const containerElement = document.querySelector(standaloneContainer);
|
|
285
287
|
|
|
286
288
|
if (containerElement) {
|
|
287
|
-
|
|
289
|
+
logger.debug(`[WuVue] Running ${appName} in standalone mode`);
|
|
288
290
|
mountApp(containerElement);
|
|
289
291
|
return true;
|
|
290
292
|
} else {
|
|
291
|
-
|
|
293
|
+
logger.warn(`[WuVue] Standalone container ${standaloneContainer} not found`);
|
|
292
294
|
}
|
|
293
295
|
}
|
|
294
296
|
|
|
@@ -405,7 +407,7 @@ const WuSlot = {
|
|
|
405
407
|
try {
|
|
406
408
|
await this.appInstance.unmount();
|
|
407
409
|
} catch (err) {
|
|
408
|
-
|
|
410
|
+
logger.warn(`[WuSlot] Error unmounting ${this.actualAppName}:`, err);
|
|
409
411
|
}
|
|
410
412
|
|
|
411
413
|
this.appInstance = null;
|
|
@@ -443,7 +445,7 @@ const WuSlot = {
|
|
|
443
445
|
* const { emit, on } = useWuEvents();
|
|
444
446
|
*
|
|
445
447
|
* onMounted(() => {
|
|
446
|
-
* on('user:login', (data) =>
|
|
448
|
+
* on('user:login', (data) => logger.debug(data));
|
|
447
449
|
* });
|
|
448
450
|
* </script>
|
|
449
451
|
*/
|
|
@@ -455,7 +457,7 @@ function useWuEvents() {
|
|
|
455
457
|
if (wu?.eventBus) {
|
|
456
458
|
wu.eventBus.emit(event, data, options);
|
|
457
459
|
} else {
|
|
458
|
-
|
|
460
|
+
logger.warn('[useWuEvents] Wu Framework not available');
|
|
459
461
|
}
|
|
460
462
|
};
|
|
461
463
|
|
|
@@ -466,7 +468,7 @@ function useWuEvents() {
|
|
|
466
468
|
subscriptions.push(unsubscribe);
|
|
467
469
|
return unsubscribe;
|
|
468
470
|
}
|
|
469
|
-
|
|
471
|
+
logger.warn('[useWuEvents] Wu Framework not available');
|
|
470
472
|
return () => {};
|
|
471
473
|
};
|
|
472
474
|
|
|
@@ -475,7 +477,7 @@ function useWuEvents() {
|
|
|
475
477
|
if (wu?.eventBus) {
|
|
476
478
|
return wu.eventBus.once(event, callback);
|
|
477
479
|
}
|
|
478
|
-
|
|
480
|
+
logger.warn('[useWuEvents] Wu Framework not available');
|
|
479
481
|
return () => {};
|
|
480
482
|
};
|
|
481
483
|
|
|
@@ -505,7 +507,7 @@ function useWuEvents() {
|
|
|
505
507
|
* const { state, setState, getState } = useWuStore('user');
|
|
506
508
|
*
|
|
507
509
|
* // state es reactivo!
|
|
508
|
-
*
|
|
510
|
+
* logger.debug(state.value);
|
|
509
511
|
* </script>
|
|
510
512
|
*/
|
|
511
513
|
function useWuStore(namespace = '') {
|
|
@@ -582,7 +584,7 @@ const wuVuePlugin = {
|
|
|
582
584
|
app.config.globalProperties.$wuEvents = useWuEvents();
|
|
583
585
|
app.config.globalProperties.$wuStore = (ns) => useWuStore(ns);
|
|
584
586
|
|
|
585
|
-
|
|
587
|
+
logger.debug('[WuVue] Plugin installed');
|
|
586
588
|
}
|
|
587
589
|
};
|
|
588
590
|
|
package/src/core/wu-app.js
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Wrapper simple para uso declarativo de microfrontends
|
|
5
5
|
* Mantiene todo el core de wu-framework pero simplifica el uso
|
|
6
6
|
*/
|
|
7
|
+
import { logger } from './wu-logger.js';
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
export class WuApp {
|
|
9
11
|
/**
|
|
@@ -40,7 +42,7 @@ export class WuApp {
|
|
|
40
42
|
keepAlive: this.keepAlive,
|
|
41
43
|
status: 'registered'
|
|
42
44
|
})
|
|
43
|
-
|
|
45
|
+
logger.debug(`📦 App registered: ${this.name} at ${this.url}`)
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
|
|
@@ -79,7 +81,7 @@ export class WuApp {
|
|
|
79
81
|
*/
|
|
80
82
|
async unmount(options = {}) {
|
|
81
83
|
if (!this._mounted && !this._wu.isHidden(this.name)) {
|
|
82
|
-
|
|
84
|
+
logger.warn(`⚠️ App ${this.name} is not mounted`)
|
|
83
85
|
return this
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -95,7 +97,7 @@ export class WuApp {
|
|
|
95
97
|
*/
|
|
96
98
|
async hide() {
|
|
97
99
|
if (!this._mounted) {
|
|
98
|
-
|
|
100
|
+
logger.warn(`⚠️ App ${this.name} is not mounted`)
|
|
99
101
|
return this
|
|
100
102
|
}
|
|
101
103
|
|
|
@@ -110,7 +112,7 @@ export class WuApp {
|
|
|
110
112
|
*/
|
|
111
113
|
async show() {
|
|
112
114
|
if (!this._wu.isHidden(this.name)) {
|
|
113
|
-
|
|
115
|
+
logger.warn(`⚠️ App ${this.name} is not in keep-alive state`)
|
|
114
116
|
return this
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -165,7 +167,7 @@ export class WuApp {
|
|
|
165
167
|
* @returns {Promise<void>}
|
|
166
168
|
*/
|
|
167
169
|
async reload() {
|
|
168
|
-
|
|
170
|
+
logger.debug(`🔄 Reloading app: ${this.name}`)
|
|
169
171
|
|
|
170
172
|
await this.unmount()
|
|
171
173
|
|
|
@@ -178,7 +180,7 @@ export class WuApp {
|
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
await this.mount()
|
|
181
|
-
|
|
183
|
+
logger.debug(`✅ App reloaded: ${this.name}`)
|
|
182
184
|
|
|
183
185
|
return this
|
|
184
186
|
}
|
|
@@ -229,6 +231,6 @@ export class WuApp {
|
|
|
229
231
|
await this.unmount({ force: true })
|
|
230
232
|
this._wu.apps.delete(this.name)
|
|
231
233
|
this._mounted = false
|
|
232
|
-
|
|
234
|
+
logger.debug(`🗑️ App destroyed: ${this.name}`)
|
|
233
235
|
}
|
|
234
236
|
}
|
package/src/core/wu-cache.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* ⚠️ USO INTERNO: No exponer en API pública
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { logger } from './wu-logger.js';
|
|
13
|
+
|
|
12
14
|
export class WuCache {
|
|
13
15
|
constructor(options = {}) {
|
|
14
16
|
this.config = {
|
|
@@ -79,7 +81,7 @@ export class WuCache {
|
|
|
79
81
|
this.rateLimiting.inCooldown = true;
|
|
80
82
|
this.rateLimiting.cooldownUntil = now + this.rateLimiting.cooldownMs;
|
|
81
83
|
this.stats.rateLimited++;
|
|
82
|
-
|
|
84
|
+
logger.warn(`[WuCache] 🚫 Rate limit exceeded. Cooldown for ${this.rateLimiting.cooldownMs}ms`);
|
|
83
85
|
return false;
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -175,7 +177,7 @@ export class WuCache {
|
|
|
175
177
|
// Verificar si necesitamos hacer espacio
|
|
176
178
|
const hasSpace = this.ensureSpace(entry.size);
|
|
177
179
|
if (hasSpace === false) {
|
|
178
|
-
|
|
180
|
+
logger.warn(`[WuCache] ⚠️ Cannot cache item: ${key} (too large)`);
|
|
179
181
|
return false;
|
|
180
182
|
}
|
|
181
183
|
|
|
@@ -193,7 +195,7 @@ export class WuCache {
|
|
|
193
195
|
|
|
194
196
|
return true;
|
|
195
197
|
} catch (error) {
|
|
196
|
-
|
|
198
|
+
logger.warn('[WuCache] ⚠️ Failed to set cache:', error);
|
|
197
199
|
return false;
|
|
198
200
|
}
|
|
199
201
|
}
|
|
@@ -228,7 +230,7 @@ export class WuCache {
|
|
|
228
230
|
this.clearStorage();
|
|
229
231
|
}
|
|
230
232
|
|
|
231
|
-
|
|
233
|
+
logger.debug('[WuCache] 🧹 Cache cleared');
|
|
232
234
|
}
|
|
233
235
|
|
|
234
236
|
/**
|
|
@@ -271,7 +273,7 @@ export class WuCache {
|
|
|
271
273
|
|
|
272
274
|
// 🛡️ FIX: Validar que el item no sea más grande que el máximo permitido
|
|
273
275
|
if (neededSize > maxSizeBytes) {
|
|
274
|
-
|
|
276
|
+
logger.warn(`[WuCache] ⚠️ Item size (${neededSize}) exceeds max cache size (${maxSizeBytes}). Skipping.`);
|
|
275
277
|
return false;
|
|
276
278
|
}
|
|
277
279
|
|
|
@@ -288,7 +290,7 @@ export class WuCache {
|
|
|
288
290
|
|
|
289
291
|
// 🛡️ FIX: Si el cache está vacío pero aún no hay espacio, salir
|
|
290
292
|
if (this.memoryCache.size === 0) {
|
|
291
|
-
|
|
293
|
+
logger.warn('[WuCache] ⚠️ Cache empty but still no space. Breaking loop.');
|
|
292
294
|
break;
|
|
293
295
|
}
|
|
294
296
|
|
|
@@ -304,7 +306,7 @@ export class WuCache {
|
|
|
304
306
|
}
|
|
305
307
|
|
|
306
308
|
if (oldestKey) {
|
|
307
|
-
|
|
309
|
+
logger.debug(`[WuCache] 🗑️ Evicting LRU entry: ${oldestKey}`);
|
|
308
310
|
this.delete(oldestKey);
|
|
309
311
|
this.stats.evictions++;
|
|
310
312
|
} else {
|
|
@@ -334,7 +336,7 @@ export class WuCache {
|
|
|
334
336
|
return JSON.parse(stored);
|
|
335
337
|
}
|
|
336
338
|
} catch (error) {
|
|
337
|
-
|
|
339
|
+
logger.warn('[WuCache] ⚠️ Failed to get from storage:', error);
|
|
338
340
|
}
|
|
339
341
|
return null;
|
|
340
342
|
}
|
|
@@ -350,13 +352,13 @@ export class WuCache {
|
|
|
350
352
|
storage.setItem(`wu_cache_${key}`, JSON.stringify(entry));
|
|
351
353
|
} catch (error) {
|
|
352
354
|
// Storage lleno, limpiar entradas antiguas
|
|
353
|
-
|
|
355
|
+
logger.warn('[WuCache] ⚠️ Storage full, cleaning old entries');
|
|
354
356
|
this.cleanOldStorageEntries();
|
|
355
357
|
|
|
356
358
|
try {
|
|
357
359
|
storage.setItem(`wu_cache_${key}`, JSON.stringify(entry));
|
|
358
360
|
} catch {
|
|
359
|
-
|
|
361
|
+
logger.warn('[WuCache] ⚠️ Failed to save to storage after cleanup');
|
|
360
362
|
}
|
|
361
363
|
}
|
|
362
364
|
}
|
|
@@ -370,7 +372,7 @@ export class WuCache {
|
|
|
370
372
|
const storage = this.getStorage();
|
|
371
373
|
storage.removeItem(`wu_cache_${key}`);
|
|
372
374
|
} catch (error) {
|
|
373
|
-
|
|
375
|
+
logger.warn('[WuCache] ⚠️ Failed to delete from storage:', error);
|
|
374
376
|
}
|
|
375
377
|
}
|
|
376
378
|
|
|
@@ -388,7 +390,7 @@ export class WuCache {
|
|
|
388
390
|
}
|
|
389
391
|
});
|
|
390
392
|
} catch (error) {
|
|
391
|
-
|
|
393
|
+
logger.warn('[WuCache] ⚠️ Failed to clear storage:', error);
|
|
392
394
|
}
|
|
393
395
|
}
|
|
394
396
|
|
|
@@ -420,9 +422,9 @@ export class WuCache {
|
|
|
420
422
|
storage.removeItem(entries[i].key);
|
|
421
423
|
}
|
|
422
424
|
|
|
423
|
-
|
|
425
|
+
logger.debug(`[WuCache] 🧹 Cleaned ${toRemove} old storage entries`);
|
|
424
426
|
} catch (error) {
|
|
425
|
-
|
|
427
|
+
logger.warn('[WuCache] ⚠️ Failed to clean old storage entries:', error);
|
|
426
428
|
}
|
|
427
429
|
}
|
|
428
430
|
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* - Fallback rendering
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { logger } from './wu-logger.js';
|
|
12
|
+
|
|
11
13
|
export class WuErrorBoundary {
|
|
12
14
|
constructor(core) {
|
|
13
15
|
this.core = core;
|
|
@@ -23,7 +25,7 @@ export class WuErrorBoundary {
|
|
|
23
25
|
|
|
24
26
|
this.registerDefaultHandlers();
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
logger.debug('[WuErrorBoundary] 🛡️ Error boundary initialized');
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
/**
|
|
@@ -38,12 +40,12 @@ export class WuErrorBoundary {
|
|
|
38
40
|
(error.message.includes('fetch') || error.message.includes('network'));
|
|
39
41
|
},
|
|
40
42
|
handle: async (error, context) => {
|
|
41
|
-
|
|
43
|
+
logger.debug('[ErrorHandler:Network] Handling network error');
|
|
42
44
|
|
|
43
45
|
// Retry con backoff
|
|
44
46
|
if (context.retryCount < this.config.maxRetries) {
|
|
45
47
|
const delay = this.config.retryDelay * Math.pow(2, context.retryCount);
|
|
46
|
-
|
|
48
|
+
logger.debug(`[ErrorHandler:Network] Retrying in ${delay}ms...`);
|
|
47
49
|
|
|
48
50
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
49
51
|
|
|
@@ -71,11 +73,11 @@ export class WuErrorBoundary {
|
|
|
71
73
|
error.message.includes('Failed to fetch'));
|
|
72
74
|
},
|
|
73
75
|
handle: async (error, context) => {
|
|
74
|
-
|
|
76
|
+
logger.debug('[ErrorHandler:ScriptLoad] Handling script load error');
|
|
75
77
|
|
|
76
78
|
// Intentar URL alternativa si existe
|
|
77
79
|
if (context.fallbackUrl) {
|
|
78
|
-
|
|
80
|
+
logger.debug('[ErrorHandler:ScriptLoad] Trying fallback URL');
|
|
79
81
|
return {
|
|
80
82
|
recovered: true,
|
|
81
83
|
action: 'use-fallback-url',
|
|
@@ -98,17 +100,17 @@ export class WuErrorBoundary {
|
|
|
98
100
|
return error.message && error.message.includes('mount');
|
|
99
101
|
},
|
|
100
102
|
handle: async (error, context) => {
|
|
101
|
-
|
|
103
|
+
logger.debug('[ErrorHandler:Mount] Handling mount error');
|
|
102
104
|
|
|
103
105
|
// Limpiar y reintentar
|
|
104
106
|
if (context.retryCount < 2) {
|
|
105
|
-
|
|
107
|
+
logger.debug('[ErrorHandler:Mount] Cleaning up and retrying...');
|
|
106
108
|
|
|
107
109
|
// Cleanup
|
|
108
110
|
try {
|
|
109
111
|
await this.core.unmount(context.appName);
|
|
110
112
|
} catch (cleanupError) {
|
|
111
|
-
|
|
113
|
+
logger.warn('[ErrorHandler:Mount] Cleanup failed:', cleanupError);
|
|
112
114
|
}
|
|
113
115
|
|
|
114
116
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
@@ -136,7 +138,7 @@ export class WuErrorBoundary {
|
|
|
136
138
|
error.message.includes('timeout');
|
|
137
139
|
},
|
|
138
140
|
handle: async (error, context) => {
|
|
139
|
-
|
|
141
|
+
logger.debug('[ErrorHandler:Timeout] Handling timeout error');
|
|
140
142
|
|
|
141
143
|
// Aumentar timeout y reintentar
|
|
142
144
|
if (context.retryCount < 2) {
|
|
@@ -161,7 +163,7 @@ export class WuErrorBoundary {
|
|
|
161
163
|
name: 'generic',
|
|
162
164
|
canHandle: () => true, // Maneja todo
|
|
163
165
|
handle: async (error, context) => {
|
|
164
|
-
|
|
166
|
+
logger.debug('[ErrorHandler:Generic] Handling generic error');
|
|
165
167
|
|
|
166
168
|
return {
|
|
167
169
|
recovered: false,
|
|
@@ -182,7 +184,7 @@ export class WuErrorBoundary {
|
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
this.handlers.push(handler);
|
|
185
|
-
|
|
187
|
+
logger.debug(`[WuErrorBoundary] Handler "${handler.name}" registered`);
|
|
186
188
|
}
|
|
187
189
|
|
|
188
190
|
/**
|
|
@@ -206,12 +208,12 @@ export class WuErrorBoundary {
|
|
|
206
208
|
for (const handler of this.handlers) {
|
|
207
209
|
try {
|
|
208
210
|
if (handler.canHandle(error, context)) {
|
|
209
|
-
|
|
211
|
+
logger.debug(`[WuErrorBoundary] Using handler: ${handler.name}`);
|
|
210
212
|
|
|
211
213
|
const result = await handler.handle(error, context);
|
|
212
214
|
|
|
213
215
|
if (result.recovered) {
|
|
214
|
-
|
|
216
|
+
logger.debug(`[WuErrorBoundary] ✅ Error recovered by ${handler.name}`);
|
|
215
217
|
return result;
|
|
216
218
|
}
|
|
217
219
|
|
|
@@ -244,7 +246,7 @@ export class WuErrorBoundary {
|
|
|
244
246
|
*/
|
|
245
247
|
renderFallback(context, result) {
|
|
246
248
|
if (!context.container) {
|
|
247
|
-
|
|
249
|
+
logger.warn('[WuErrorBoundary] No container to render fallback');
|
|
248
250
|
return;
|
|
249
251
|
}
|
|
250
252
|
|
|
@@ -375,6 +377,6 @@ export class WuErrorBoundary {
|
|
|
375
377
|
*/
|
|
376
378
|
cleanup() {
|
|
377
379
|
this.errorLog = [];
|
|
378
|
-
|
|
380
|
+
logger.debug('[WuErrorBoundary] 🧹 Error boundary cleaned up');
|
|
379
381
|
}
|
|
380
382
|
}
|
package/src/core/wu-event-bus.js
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* - Event replay
|
|
9
9
|
* - Verificación de apps autorizadas
|
|
10
10
|
*/
|
|
11
|
+
import { logger } from './wu-logger.js';
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
export class WuEventBus {
|
|
13
15
|
constructor() {
|
|
@@ -138,7 +140,7 @@ export class WuEventBus {
|
|
|
138
140
|
if (this.config.validateOrigin && this.config.strictMode) {
|
|
139
141
|
if (!this._validateOrigin(eventName, appName, options.token)) {
|
|
140
142
|
this.stats.rejected++;
|
|
141
|
-
|
|
143
|
+
logger.warn(`[WuEventBus] 🚫 Event rejected: ${eventName} from ${appName} (unauthorized)`);
|
|
142
144
|
return false;
|
|
143
145
|
}
|
|
144
146
|
}
|
|
@@ -160,7 +162,7 @@ export class WuEventBus {
|
|
|
160
162
|
|
|
161
163
|
// Log si está habilitado
|
|
162
164
|
if (this.config.logEvents) {
|
|
163
|
-
|
|
165
|
+
logger.debug(`[WuEventBus] 📢 ${eventName}`, data);
|
|
164
166
|
}
|
|
165
167
|
|
|
166
168
|
// Notificar listeners exactos
|
package/src/core/wu-hooks.js
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* - Async/await support
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { logger } from './wu-logger.js';
|
|
13
|
+
|
|
12
14
|
export class WuLifecycleHooks {
|
|
13
15
|
constructor(core) {
|
|
14
16
|
this.core = core;
|
|
@@ -35,7 +37,7 @@ export class WuLifecycleHooks {
|
|
|
35
37
|
this.hooks.set(phase, []);
|
|
36
38
|
});
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
logger.debug('[WuHooks] 🪝 Lifecycle hooks initialized');
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
/**
|
|
@@ -66,7 +68,7 @@ export class WuLifecycleHooks {
|
|
|
66
68
|
// Ordenar por prioridad (mayor primero)
|
|
67
69
|
hooks.sort((a, b) => b.priority - a.priority);
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
logger.debug(`[WuHooks] Hook "${hook.name}" registered for ${phase} (priority: ${hook.priority})`);
|
|
70
72
|
|
|
71
73
|
// Retornar función para desregistrar
|
|
72
74
|
return () => this.remove(phase, hook.name);
|
|
@@ -85,7 +87,7 @@ export class WuLifecycleHooks {
|
|
|
85
87
|
|
|
86
88
|
if (index > -1) {
|
|
87
89
|
hooks.splice(index, 1);
|
|
88
|
-
|
|
90
|
+
logger.debug(`[WuHooks] Hook "${name}" removed from ${phase}`);
|
|
89
91
|
}
|
|
90
92
|
}
|
|
91
93
|
|
|
@@ -102,7 +104,7 @@ export class WuLifecycleHooks {
|
|
|
102
104
|
return context;
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
|
|
107
|
+
logger.debug(`[WuHooks] Executing ${hooks.length} hooks for ${phase}`);
|
|
106
108
|
|
|
107
109
|
// Log para debugging
|
|
108
110
|
const executionEntry = {
|
|
@@ -146,13 +148,13 @@ export class WuLifecycleHooks {
|
|
|
146
148
|
|
|
147
149
|
// Si no se llamó next(), la operación fue cancelada
|
|
148
150
|
if (!nextCalled) {
|
|
149
|
-
|
|
151
|
+
logger.debug(`[WuHooks] Hook "${hook.name}" cancelled execution`);
|
|
150
152
|
cancelled = true;
|
|
151
153
|
return { cancelled: true };
|
|
152
154
|
}
|
|
153
155
|
|
|
154
156
|
const duration = Date.now() - startTime;
|
|
155
|
-
|
|
157
|
+
logger.debug(`[WuHooks] Hook "${hook.name}" executed in ${duration}ms`);
|
|
156
158
|
|
|
157
159
|
} catch (error) {
|
|
158
160
|
console.error(`[WuHooks] Error in hook "${hook.name}":`, error);
|
|
@@ -257,13 +259,13 @@ export class WuLifecycleHooks {
|
|
|
257
259
|
cleanup(phase) {
|
|
258
260
|
if (phase) {
|
|
259
261
|
this.hooks.set(phase, []);
|
|
260
|
-
|
|
262
|
+
logger.debug(`[WuHooks] Hooks cleaned for ${phase}`);
|
|
261
263
|
} else {
|
|
262
264
|
this.lifecyclePhases.forEach(p => {
|
|
263
265
|
this.hooks.set(p, []);
|
|
264
266
|
});
|
|
265
267
|
this.executionLog = [];
|
|
266
|
-
|
|
268
|
+
logger.debug('[WuHooks] 🧹 All hooks cleaned');
|
|
267
269
|
}
|
|
268
270
|
}
|
|
269
271
|
}
|