wu-framework 1.0.6 → 1.1.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.
package/README.md CHANGED
@@ -9,11 +9,13 @@ Wu Framework es la librería de microfrontends más simple y poderosa del mercad
9
9
  | Característica | Module Federation | qiankun | **Wu Framework** |
10
10
  |---|---|---|---|
11
11
  | **Setup** | Webpack config complejo | Configuración manual | **Zero config** |
12
- | **Framework Support** | React-first | Multi framework | **Cualquier framework** |
12
+ | **Framework Support** | React-first | Multi framework | **8 frameworks nativos** |
13
13
  | **Bundler Required** | Solo Webpack 5 | Agnóstico pero complejo | **Ninguno** |
14
14
  | **CSS Isolation** | Básico | CSS hacks | **Shadow DOM nativo** |
15
+ | **JS Isolation** | ❌ | Proxy básico | **Proxy Sandbox completo** |
15
16
  | **Runtime Config** | ❌ | Limitado | **✅ Completamente dinámico** |
16
- | **API Complexity** | Alta | Media | **Súper simple** |
17
+ | **Self-Healing** | | | **✅ Auto-recovery** |
18
+ | **API Complexity** | Alta | Media | **1 línea de código** |
17
19
 
18
20
  ## 🎯 Instalación
19
21
 
@@ -23,15 +25,91 @@ npm install wu-framework
23
25
 
24
26
  **¡Y ya está!** Sin webpack config, sin plugins, sin configuración.
25
27
 
26
- ## 🔥 Uso Básico
28
+ ---
29
+
30
+ ## 🎨 Frameworks Soportados
31
+
32
+ Wu Framework incluye **adapters nativos** para los frameworks más populares:
33
+
34
+ | Framework | Adapter | Registro |
35
+ |-----------|---------|----------|
36
+ | ⚛️ React | `wuReact` | `wuReact.register('app', App)` |
37
+ | 💚 Vue | `wuVue` | `wuVue.register('app', App)` |
38
+ | 🅰️ Angular | `wuAngular` | `wuAngular.register('app', AppModule)` |
39
+ | 🧡 Svelte | `wuSvelte` | `wuSvelte.register('app', App)` |
40
+ | ⚡ Preact | `wuPreact` | `wuPreact.register('app', App)` |
41
+ | 💎 Solid.js | `wuSolid` | `wuSolid.register('app', App)` |
42
+ | 🔥 Lit | `wuLit` | `wuLit.register('app', MyElement)` |
43
+ | 📦 Vanilla JS | `wuVanilla` | `wuVanilla.register('app', config)` |
44
+
45
+ ---
46
+
47
+ ## 🔥 Quick Start
48
+
49
+ ### 1. Micro App: Crear `wu.json`
50
+
51
+ Cada microfrontend necesita un archivo `wu.json` en su raíz:
52
+
53
+ ```json
54
+ {
55
+ "name": "header",
56
+ "entry": "index.js",
57
+ "wu": {
58
+ "exports": {
59
+ "NavBar": "components/NavBar.js",
60
+ "UserMenu": "components/UserMenu.js"
61
+ },
62
+ "imports": [],
63
+ "routes": ["/", "/home"],
64
+ "permissions": ["events", "store"]
65
+ }
66
+ }
67
+ ```
68
+
69
+ | Campo | Descripción |
70
+ |-------|-------------|
71
+ | `name` | Nombre único del microfrontend |
72
+ | `entry` | Archivo JS principal (default: `index.js`) |
73
+ | `wu.exports` | Componentes que expone a otros microfrontends |
74
+ | `wu.imports` | Componentes que importa de otros microfrontends |
75
+ | `wu.routes` | Rutas que maneja este microfrontend |
76
+ | `wu.permissions` | Permisos requeridos (`events`, `store`, `dom`) |
77
+
78
+ ### 2. Micro App: Registrar con Adapter (1 línea)
79
+
80
+ **React:**
81
+ ```tsx
82
+ import { wuReact } from 'wu-framework/adapters/react';
83
+ import App from './App';
84
+
85
+ wuReact.register('header', App);
86
+ ```
87
+
88
+ **Vue:**
89
+ ```ts
90
+ import { wuVue } from 'wu-framework/adapters/vue';
91
+ import App from './App.vue';
27
92
 
28
- ### Container App (Host)
93
+ wuVue.register('sidebar', App);
94
+ ```
29
95
 
96
+ **Angular:**
97
+ ```ts
98
+ import { wuAngular } from 'wu-framework/adapters/angular';
99
+ import { AppModule } from './app/app.module';
100
+
101
+ wuAngular.register('content', AppModule);
102
+ ```
103
+
104
+ **¡Eso es todo!** El adapter se encarga de todo: detección de contexto, modo standalone, cleanup automático.
105
+
106
+ ### 3. Shell (Host Application)
107
+
108
+ **Desarrollo:**
30
109
  ```js
31
110
  import { wu } from 'wu-framework';
32
111
 
33
- // Inicializar con apps
34
- wu.init({
112
+ await wu.init({
35
113
  apps: [
36
114
  { name: 'header', url: 'http://localhost:3001' },
37
115
  { name: 'sidebar', url: 'http://localhost:3002' },
@@ -39,521 +117,1033 @@ wu.init({
39
117
  ]
40
118
  });
41
119
 
42
- // Montar en el DOM
43
- wu.mount('header', '#header-container');
44
- wu.mount('sidebar', '#sidebar-container');
45
- wu.mount('content', '#content-container');
120
+ await wu.mount('header', '#header-container');
121
+ await wu.mount('sidebar', '#sidebar-container');
122
+ await wu.mount('content', '#content-container');
46
123
  ```
47
124
 
48
- ### Micro App (Cualquier Framework)
49
-
125
+ **Producción:**
50
126
  ```js
51
127
  import { wu } from 'wu-framework';
52
128
 
53
- // React
54
- wu.define('header', {
55
- mount: (container) => {
56
- ReactDOM.render(<HeaderApp />, container);
57
- },
58
- unmount: (container) => {
59
- ReactDOM.unmountComponentAtNode(container);
60
- }
129
+ await wu.init({
130
+ apps: [
131
+ { name: 'header', url: 'https://cdn.mycompany.com/mfe/header' },
132
+ { name: 'sidebar', url: 'https://cdn.mycompany.com/mfe/sidebar' },
133
+ { name: 'content', url: 'https://cdn.mycompany.com/mfe/content' }
134
+ ]
61
135
  });
62
136
 
63
- // Vue
64
- wu.define('sidebar', {
65
- mount: (container) => {
66
- createApp(SidebarApp).mount(container);
67
- },
68
- unmount: (container) => {
69
- // Vue cleanup
70
- }
71
- });
137
+ await wu.mount('header', '#header-container');
138
+ await wu.mount('sidebar', '#sidebar-container');
139
+ await wu.mount('content', '#content-container');
140
+ ```
72
141
 
73
- // Vanilla JS
74
- wu.define('content', {
75
- mount: (container) => {
76
- container.innerHTML = `
77
- <h1>Content App</h1>
78
- <p>Pure vanilla JavaScript!</p>
79
- `;
80
- },
81
- unmount: (container) => {
82
- container.innerHTML = '';
83
- }
142
+ **Con configuración dinámica:**
143
+ ```js
144
+ import { wu } from 'wu-framework';
145
+
146
+ const isDev = process.env.NODE_ENV !== 'production';
147
+
148
+ await wu.init({
149
+ apps: [
150
+ { name: 'header', url: isDev ? 'http://localhost:3001' : 'https://cdn.mycompany.com/mfe/header' },
151
+ { name: 'sidebar', url: isDev ? 'http://localhost:3002' : 'https://cdn.mycompany.com/mfe/sidebar' },
152
+ { name: 'content', url: isDev ? 'http://localhost:3003' : 'https://cdn.mycompany.com/mfe/content' }
153
+ ]
84
154
  });
85
155
  ```
86
156
 
87
- ## 📋 Wu Manifest (wu.json)
157
+ ### Estructura de Archivos (Microfrontend)
88
158
 
89
- Cada micro-app puede tener un archivo `wu.json` para configuración:
159
+ ```
160
+ my-header-mfe/
161
+ ├── wu.json # ← Manifest requerido
162
+ ├── index.js # ← Entry point (registra con adapter)
163
+ ├── App.jsx # ← Componente principal
164
+ ├── components/
165
+ │ ├── NavBar.js
166
+ │ └── UserMenu.js
167
+ └── package.json
168
+ ```
90
169
 
91
- ```json
92
- {
93
- "name": "header-app",
94
- "entry": "index.js",
95
- "wu": {
96
- "exports": {
97
- "HeaderComponent": "./components/Header",
98
- "useAuth": "./hooks/useAuth"
99
- },
100
- "imports": [
101
- "shared.Button",
102
- "shared.Theme"
103
- ],
104
- "routes": ["/header", "/nav"],
105
- "permissions": ["localStorage", "eventBus"]
106
- }
107
- }
170
+ ---
171
+
172
+ ## ⚛️ React Adapter
173
+
174
+ ### Registro Básico
175
+
176
+ ```tsx
177
+ import { wuReact } from 'wu-framework/adapters/react';
178
+ import App from './App';
179
+
180
+ wuReact.register('my-app', App);
108
181
  ```
109
182
 
110
- ### Component Sharing
183
+ ### Con Opciones
111
184
 
112
- ```js
113
- // Exportar componentes
114
- wu.define('shared', {
115
- mount: (container) => {
116
- // App shared con componentes reutilizables
117
- }
185
+ ```tsx
186
+ wuReact.register('my-app', App, {
187
+ strictMode: true, // Envolver en React.StrictMode
188
+ props: { theme: 'dark' }, // Props iniciales
189
+ standalone: true, // Ejecutar independiente si Wu no está
190
+ standaloneContainer: '#root',
191
+ onMount: (container) => console.log('Mounted!'),
192
+ onUnmount: (container) => console.log('Unmounted!')
118
193
  });
119
-
120
- // Usar componentes compartidos
121
- const Button = await wu.use('shared.Button');
122
- const Theme = await wu.use('shared.Theme');
123
194
  ```
124
195
 
125
- ## 🏗️ Arquitectura
196
+ ### Hooks para React
197
+
198
+ ```tsx
199
+ import React from 'react';
200
+ import { createUseWuEvents, createUseWuStore } from 'wu-framework/adapters/react';
201
+
202
+ const useWuEvents = createUseWuEvents(React);
203
+ const useWuStore = createUseWuStore(React);
126
204
 
127
- Wu Framework usa **Shadow DOM nativo** para verdadero aislamiento:
205
+ function MyComponent() {
206
+ const { emit, on } = useWuEvents();
207
+ const { state, setState } = useWuStore('user');
128
208
 
209
+ useEffect(() => {
210
+ const unsub = on('cart:updated', (data) => {
211
+ console.log('Cart updated:', data);
212
+ });
213
+ return unsub;
214
+ }, [on]);
215
+
216
+ return (
217
+ <button onClick={() => emit('user:logout')}>
218
+ Logout {state?.name}
219
+ </button>
220
+ );
221
+ }
129
222
  ```
130
- ┌─────────────────────────────────────┐
131
- │ Host Application │
132
- ├─────────────────────────────────────┤
133
- │ ┌─────────────┐ ┌─────────────┐ │
134
- │ │ #shadow-root│ │ #shadow-root│ │
135
- │ │ ┌─────────┐│ │ ┌─────────┐│ │
136
- │ │ │Header ││ │ │Sidebar ││ │
137
- │ │ │(React) ││ │ │(Vue) ││ │
138
- │ │ └─────────┘│ │ └─────────┘│ │
139
- │ └─────────────┘ └─────────────┘ │
140
- └─────────────────────────────────────┘
223
+
224
+ ### Cargar Microfrontends en React (Shell)
225
+
226
+ ```tsx
227
+ import React from 'react';
228
+ import { createWuSlot } from 'wu-framework/adapters/react';
229
+
230
+ const WuSlot = createWuSlot(React);
231
+
232
+ // URLs pueden ser localhost (dev) o CDN (prod)
233
+ const HEADER_URL = process.env.REACT_APP_HEADER_URL || 'http://localhost:3001';
234
+ const CONTENT_URL = process.env.REACT_APP_CONTENT_URL || 'http://localhost:3002';
235
+
236
+ function Shell() {
237
+ return (
238
+ <div>
239
+ <WuSlot
240
+ name="header"
241
+ url={HEADER_URL}
242
+ onLoad={() => console.log('Header loaded!')}
243
+ onError={(err) => console.error(err)}
244
+ />
245
+ <WuSlot name="content" url={CONTENT_URL} />
246
+ </div>
247
+ );
248
+ }
141
249
  ```
142
250
 
143
- ### Ventajas del Shadow DOM:
251
+ ---
144
252
 
145
- - **CSS completamente aislado** - No hay conflictos de estilos
146
- - ✅ **JavaScript scope aislado** - Variables globales separadas
147
- - ✅ **DOM encapsulado** - No hay interferencia entre apps
148
- - ✅ **Performance nativo** - Sin overhead de hacks CSS
149
- - ✅ **Debugging fácil** - Cada app en su propio DevTools tree
253
+ ## 💚 Vue Adapter
150
254
 
151
- ## 🎨 Ejemplos de Frameworks
255
+ ### Registro Básico
152
256
 
153
- ### React + TypeScript
257
+ ```ts
258
+ import { wuVue } from 'wu-framework/adapters/vue';
259
+ import App from './App.vue';
154
260
 
155
- ```tsx
156
- // header-app/src/index.tsx
157
- import React from 'react';
158
- import ReactDOM from 'react-dom';
159
- import { wu } from 'wu-framework';
261
+ wuVue.register('my-app', App);
262
+ ```
160
263
 
161
- const HeaderApp: React.FC = () => (
162
- <header className="app-header">
163
- <h1>Header App (React)</h1>
164
- </header>
165
- );
264
+ ### Con Plugins (Pinia, Router, etc.)
166
265
 
167
- wu.define('header', {
168
- mount: (container: HTMLElement) => {
169
- ReactDOM.render(<HeaderApp />, container);
170
- },
171
- unmount: (container: HTMLElement) => {
172
- ReactDOM.unmountComponentAtNode(container);
266
+ ```ts
267
+ import { wuVue } from 'wu-framework/adapters/vue';
268
+ import { createPinia } from 'pinia';
269
+ import router from './router';
270
+ import App from './App.vue';
271
+
272
+ wuVue.register('my-app', App, {
273
+ setup: (app) => {
274
+ app.use(createPinia());
275
+ app.use(router);
173
276
  }
174
277
  });
175
278
  ```
176
279
 
177
- ### Vue 3 + Composition API
280
+ ### Composables para Vue
178
281
 
179
282
  ```vue
180
- <!-- sidebar-app/src/App.vue -->
283
+ <script setup>
284
+ import { onMounted, onUnmounted } from 'vue';
285
+ import { useWuEvents, useWuStore } from 'wu-framework/adapters/vue';
286
+
287
+ const { emit, on, cleanup } = useWuEvents();
288
+ const { state, setState } = useWuStore('cart');
289
+
290
+ onMounted(() => {
291
+ on('user:login', (data) => console.log('Login:', data));
292
+ });
293
+
294
+ onUnmounted(() => cleanup());
295
+ </script>
296
+
181
297
  <template>
182
- <aside class="app-sidebar">
183
- <h2>Sidebar App (Vue)</h2>
184
- <nav>
185
- <ul>
186
- <li v-for="item in items" :key="item.id">
187
- {{ item.name }}
188
- </li>
189
- </ul>
190
- </nav>
191
- </aside>
298
+ <div>
299
+ <p>Items: {{ state?.items?.length }}</p>
300
+ <button @click="emit('cart:clear')">Clear Cart</button>
301
+ </div>
192
302
  </template>
303
+ ```
304
+
305
+ ### Cargar Microfrontends en Vue (Shell)
193
306
 
307
+ ```vue
194
308
  <script setup>
195
- import { ref } from 'vue';
309
+ import { WuSlot } from 'wu-framework/adapters/vue';
196
310
 
197
- const items = ref([
198
- { id: 1, name: 'Home' },
199
- { id: 2, name: 'About' },
200
- { id: 3, name: 'Contact' }
201
- ]);
311
+ // URLs: localhost en dev, CDN en prod
312
+ const headerUrl = import.meta.env.VITE_HEADER_URL || 'http://localhost:3001';
313
+ const sidebarUrl = import.meta.env.VITE_SIDEBAR_URL || 'http://localhost:3002';
202
314
  </script>
315
+
316
+ <template>
317
+ <div>
318
+ <WuSlot
319
+ name="header"
320
+ :url="headerUrl"
321
+ @load="onLoad"
322
+ @error="onError"
323
+ />
324
+ <WuSlot name="sidebar" :url="sidebarUrl" />
325
+ </div>
326
+ </template>
203
327
  ```
204
328
 
205
- ```js
206
- // sidebar-app/src/index.js
207
- import { createApp } from 'vue';
208
- import { wu } from 'wu-framework';
209
- import App from './App.vue';
329
+ ### Plugin Global
210
330
 
211
- let app;
331
+ ```ts
332
+ import { createApp } from 'vue';
333
+ import { wuVuePlugin } from 'wu-framework/adapters/vue';
212
334
 
213
- wu.define('sidebar', {
214
- mount: (container) => {
215
- app = createApp(App);
216
- app.mount(container);
217
- },
218
- unmount: (container) => {
219
- if (app) {
220
- app.unmount();
221
- app = null;
222
- }
223
- }
224
- });
335
+ const app = createApp(App);
336
+ app.use(wuVuePlugin); // Registra <WuSlot> globalmente
225
337
  ```
226
338
 
227
- ### Angular
339
+ ---
228
340
 
229
- ```typescript
230
- // content-app/src/main.ts
231
- import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
232
- import { wu } from 'wu-framework';
341
+ ## 🅰️ Angular Adapter
342
+
343
+ ### Registro con NgModule
344
+
345
+ ```ts
346
+ import { wuAngular } from 'wu-framework/adapters/angular';
233
347
  import { AppModule } from './app/app.module';
234
348
 
235
- let platformRef: any;
349
+ wuAngular.register('my-app', AppModule);
350
+ ```
236
351
 
237
- wu.define('content', {
238
- mount: async (container: HTMLElement) => {
239
- // Crear elemento para Angular
240
- const appElement = document.createElement('app-root');
241
- container.appendChild(appElement);
352
+ ### Registro con Standalone Components (Angular 14+)
242
353
 
243
- // Bootstrap Angular
244
- platformRef = await platformBrowserDynamic().bootstrapModule(AppModule);
245
- },
246
- unmount: (container: HTMLElement) => {
247
- if (platformRef) {
248
- platformRef.destroy();
249
- platformRef = null;
250
- }
251
- container.innerHTML = '';
252
- }
354
+ ```ts
355
+ import { wuAngular } from 'wu-framework/adapters/angular';
356
+ import { AppComponent } from './app/app.component';
357
+ import { appConfig } from './app/app.config';
358
+
359
+ wuAngular.registerStandalone('my-app', AppComponent, {
360
+ appConfig
253
361
  });
254
362
  ```
255
363
 
256
- ### Svelte
364
+ ### Servicio para Componentes
257
365
 
258
- ```js
259
- // footer-app/src/index.js
260
- import { wu } from 'wu-framework';
261
- import App from './App.svelte';
366
+ ```ts
367
+ import { Component, OnInit, OnDestroy } from '@angular/core';
368
+ import { createWuService } from 'wu-framework/adapters/angular';
262
369
 
263
- let app;
370
+ @Component({
371
+ selector: 'app-root',
372
+ template: `<button (click)="sendEvent()">Send Event</button>`
373
+ })
374
+ export class AppComponent implements OnInit, OnDestroy {
375
+ private wuService = createWuService();
264
376
 
265
- wu.define('footer', {
266
- mount: (container) => {
267
- app = new App({
268
- target: container,
269
- props: {
270
- name: 'Footer App'
271
- }
377
+ ngOnInit() {
378
+ this.wuService.on('user:login', (data) => {
379
+ console.log('User logged in:', data);
272
380
  });
273
- },
274
- unmount: (container) => {
275
- if (app) {
276
- app.$destroy();
277
- app = null;
278
- }
279
381
  }
280
- });
382
+
383
+ sendEvent() {
384
+ this.wuService.emit('app:ready', { timestamp: Date.now() });
385
+ }
386
+
387
+ ngOnDestroy() {
388
+ this.wuService.destroy();
389
+ }
390
+ }
281
391
  ```
282
392
 
283
- ## 🛠️ API Reference
393
+ ---
394
+
395
+ ## 🧡 Svelte Adapter
284
396
 
285
- ### Core API
397
+ ### Registro Básico
286
398
 
287
399
  ```js
288
- import { wu } from 'wu-framework';
400
+ import { wuSvelte } from 'wu-framework/adapters/svelte';
401
+ import App from './App.svelte';
289
402
 
290
- // Inicializar framework
291
- await wu.init({ apps: [...] });
403
+ wuSvelte.register('my-app', App);
404
+ ```
292
405
 
293
- // Montar app
294
- await wu.mount('appName', '#container');
406
+ ### Svelte 5 (con runes)
295
407
 
296
- // Desmontar app
297
- await wu.unmount('appName');
408
+ ```js
409
+ import { wuSvelte } from 'wu-framework/adapters/svelte';
410
+ import App from './App.svelte';
298
411
 
299
- // Definir lifecycle
300
- wu.define('appName', { mount, unmount });
412
+ wuSvelte.registerSvelte5('my-app', App);
413
+ ```
301
414
 
302
- // Usar componente compartido
303
- const Component = await wu.use('app.Component');
415
+ ### Stores Reactivos
304
416
 
305
- // Obtener información
306
- const info = wu.getAppInfo('appName');
307
- const stats = wu.getStats();
417
+ ```svelte
418
+ <script>
419
+ import { createWuStore, useWuEvents } from 'wu-framework/adapters/svelte';
420
+ import { onDestroy } from 'svelte';
308
421
 
309
- // Limpiar framework
310
- await wu.destroy();
422
+ // Store reactivo (compatible con $store)
423
+ const userStore = createWuStore('user');
424
+
425
+ // Eventos
426
+ const { emit, on, cleanup } = useWuEvents();
427
+
428
+ on('cart:updated', (data) => {
429
+ console.log('Cart updated:', data);
430
+ });
431
+
432
+ onDestroy(cleanup);
433
+ </script>
434
+
435
+ <p>Hello, {$userStore?.name}</p>
436
+ <button on:click={() => emit('user:logout')}>Logout</button>
311
437
  ```
312
438
 
313
- ### Utils API
439
+ ---
314
440
 
315
- ```js
316
- import { init, mount, define, use } from 'wu-framework';
441
+ ## ⚡ Preact Adapter
442
+
443
+ ### Registro Básico
317
444
 
318
- // API de conveniencia
319
- await init([{ name: 'app', url: 'http://localhost:3000' }]);
320
- await mount('app', '#container');
321
- define('app', { mount, unmount });
322
- const Component = await use('shared.Button');
445
+ ```jsx
446
+ import { wuPreact } from 'wu-framework/adapters/preact';
447
+ import App from './App';
448
+
449
+ wuPreact.register('my-app', App);
450
+ ```
451
+
452
+ ### Compatible con React (preact/compat)
453
+
454
+ ```jsx
455
+ import { wuPreact } from 'wu-framework/adapters/preact';
456
+ import App from './App'; // Componente estilo React
457
+
458
+ wuPreact.registerCompat('my-app', App);
323
459
  ```
324
460
 
325
- ### Development API
461
+ ### Hooks
462
+
463
+ ```jsx
464
+ import { h } from 'preact';
465
+ import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
466
+ import { createUseWuEvents, createUseWuStore } from 'wu-framework/adapters/preact';
467
+
468
+ const useWuEvents = createUseWuEvents({ useCallback, useEffect, useRef });
469
+ const useWuStore = createUseWuStore({ useState, useCallback, useEffect });
470
+
471
+ function MyComponent() {
472
+ const { emit, on } = useWuEvents();
473
+ const { state } = useWuStore('user');
474
+
475
+ return <div>Hello {state?.name}</div>;
476
+ }
477
+ ```
478
+
479
+ ---
480
+
481
+ ## 💎 Solid.js Adapter
482
+
483
+ ### Registro Básico
484
+
485
+ ```jsx
486
+ import { wuSolid } from 'wu-framework/adapters/solid';
487
+ import App from './App';
488
+
489
+ wuSolid.register('my-app', App);
490
+ ```
491
+
492
+ ### Stores Reactivos
493
+
494
+ ```jsx
495
+ import { createWuStore, createWuEvent } from 'wu-framework/adapters/solid';
496
+
497
+ function MyComponent() {
498
+ // Store reactivo
499
+ const [user, setUser] = createWuStore('user');
500
+
501
+ // Eventos reactivos
502
+ const lastEvent = createWuEvent('notification:*');
503
+
504
+ return (
505
+ <div>
506
+ <p>Hello, {user()?.name}</p>
507
+ <Show when={lastEvent()}>
508
+ <p>Last notification: {lastEvent()?.data}</p>
509
+ </Show>
510
+ <button onClick={() => setUser('name', 'John')}>
511
+ Set Name
512
+ </button>
513
+ </div>
514
+ );
515
+ }
516
+ ```
517
+
518
+ ---
519
+
520
+ ## 🔥 Lit Adapter (Web Components)
521
+
522
+ ### Registro con LitElement
326
523
 
327
524
  ```js
328
- import { dev } from 'wu-framework';
525
+ import { LitElement, html, css } from 'lit';
526
+ import { wuLit } from 'wu-framework/adapters/lit';
329
527
 
330
- // Debugging
331
- dev.enableDebug();
332
- dev.inspect();
528
+ class MyApp extends LitElement {
529
+ static styles = css`
530
+ :host { display: block; padding: 16px; }
531
+ `;
532
+
533
+ render() {
534
+ return html`<h1>Hello from Lit!</h1>`;
535
+ }
536
+ }
333
537
 
334
- // Hot reload (desarrollo)
335
- await dev.reload('appName');
538
+ wuLit.register('my-app', MyApp);
336
539
  ```
337
540
 
338
- ## 🔧 Configuración Avanzada
541
+ ### Con WuMixin
542
+
543
+ ```js
544
+ import { LitElement, html } from 'lit';
545
+ import { WuMixin } from 'wu-framework/adapters/lit';
546
+
547
+ class MyApp extends WuMixin(LitElement) {
548
+ connectedCallback() {
549
+ super.connectedCallback();
550
+
551
+ // Usar eventos de Wu
552
+ this.wuOn('user:login', (data) => {
553
+ console.log('User logged in:', data);
554
+ });
555
+ }
556
+
557
+ handleClick() {
558
+ this.wuEmit('button:clicked', { id: 'my-button' });
559
+ }
339
560
 
340
- ### Presets
561
+ render() {
562
+ return html`
563
+ <button @click=${this.handleClick}>Click me</button>
564
+ `;
565
+ }
566
+ }
567
+
568
+ wuLit.register('my-app', MyApp);
569
+ ```
570
+
571
+ ### Web Component Vanilla (sin Lit)
341
572
 
342
573
  ```js
343
- import { wu, presets } from 'wu-framework';
574
+ import { wuLit } from 'wu-framework/adapters/lit';
344
575
 
345
- // Desarrollo
346
- await wu.init(presets.development([
347
- { name: 'header', port: 3001 },
348
- { name: 'sidebar', port: 3002 }
349
- ]));
576
+ class MyComponent extends HTMLElement {
577
+ connectedCallback() {
578
+ this.attachShadow({ mode: 'open' });
579
+ this.shadowRoot.innerHTML = '<h1>Hello Web Component!</h1>';
580
+ }
581
+ }
350
582
 
351
- // Producción
352
- await wu.init(presets.production([
353
- { name: 'header', url: 'https://header.myapp.com' },
354
- { name: 'sidebar', url: 'https://sidebar.myapp.com' }
355
- ]));
583
+ wuLit.registerWebComponent('my-component', MyComponent);
356
584
  ```
357
585
 
358
- ### Eventos
586
+ ---
587
+
588
+ ## 📦 Vanilla JS Adapter
589
+
590
+ ### Registro con Objeto
359
591
 
360
592
  ```js
361
- import { events } from 'wu-framework';
593
+ import { wuVanilla } from 'wu-framework/adapters/vanilla';
362
594
 
363
- // Escuchar eventos del ciclo de vida
364
- events.onAppMounted((event) => {
365
- console.log('App mounted:', event.detail.appName);
366
- });
595
+ wuVanilla.register('my-app', {
596
+ state: { count: 0 },
597
+
598
+ render: (container, state) => {
599
+ container.innerHTML = `
600
+ <div>
601
+ <h1>Count: ${state.count}</h1>
602
+ <button id="increment">+</button>
603
+ </div>
604
+ `;
605
+ container.querySelector('#increment').onclick = () => {
606
+ state.count++;
607
+ // Re-render manual
608
+ };
609
+ },
367
610
 
368
- events.onAppError((event) => {
369
- console.error('App error:', event.detail);
611
+ destroy: (container) => {
612
+ container.innerHTML = '';
613
+ }
370
614
  });
371
615
  ```
372
616
 
373
- ## 🌟 Ventajas Competitivas
617
+ ### Registro con Clase
618
+
619
+ ```js
620
+ import { wuVanilla } from 'wu-framework/adapters/vanilla';
621
+
622
+ class TodoApp {
623
+ constructor(container) {
624
+ this.container = container;
625
+ this.todos = [];
626
+ }
374
627
 
375
- ### vs Module Federation
628
+ render() {
629
+ this.container.innerHTML = `
630
+ <ul>
631
+ ${this.todos.map(t => `<li>${t}</li>`).join('')}
632
+ </ul>
633
+ <input type="text" id="input" />
634
+ <button id="add">Add</button>
635
+ `;
376
636
 
377
- - **No requiere Webpack 5** - Funciona con cualquier bundler
378
- - **Runtime configuration** - No necesita build-time config
379
- - ✅ **Framework agnostic real** - No solo React
380
- - ✅ **API más simple** - Menos boilerplate
637
+ this.container.querySelector('#add').onclick = () => {
638
+ const input = this.container.querySelector('#input');
639
+ this.todos.push(input.value);
640
+ this.render();
641
+ };
642
+ }
381
643
 
382
- ### vs qiankun
644
+ destroy() {
645
+ this.container.innerHTML = '';
646
+ }
647
+ }
383
648
 
384
- - ✅ **Shadow DOM nativo** - No hacks CSS
385
- - ✅ **Mejor DX** - DevTools integration
386
- - ✅ **Sandbox más ligero** - Menos overhead
387
- - ✅ **Component sharing** - Sistema declarativo
649
+ wuVanilla.registerClass('todo-app', TodoApp);
650
+ ```
388
651
 
389
- ### vs single-spa
652
+ ### Registro con Template
390
653
 
391
- - ✅ **Zero config** - Sin setup complejo
392
- - **Shadow DOM** - Aislamiento real
393
- - ✅ **Manifest system** - Configuración declarativa
394
- - ✅ **API moderna** - ES modules nativo
654
+ ```js
655
+ import { wuVanilla } from 'wu-framework/adapters/vanilla';
395
656
 
396
- ## 📦 Bundler Support
657
+ wuVanilla.registerTemplate('header', `
658
+ <header>
659
+ <h1>My Header</h1>
660
+ <nav>
661
+ <a href="/">Home</a>
662
+ <a href="/about">About</a>
663
+ </nav>
664
+ </header>
665
+ `);
397
666
 
398
- Wu Framework funciona con **cualquier bundler** o sin bundler:
667
+ // Template dinámico
668
+ wuVanilla.registerTemplate('greeting',
669
+ (data) => `<h1>Hello, ${data.name}!</h1>`,
670
+ { data: { name: 'World' } }
671
+ );
672
+ ```
399
673
 
400
- ### Vite
674
+ ### Componente Reactivo
401
675
 
402
676
  ```js
403
- // vite.config.js
404
- export default {
405
- // Wu Framework funciona out-of-the-box con Vite
406
- // No necesita configuración especial
407
- }
677
+ import { wuVanilla } from 'wu-framework/adapters/vanilla';
678
+
679
+ const Counter = wuVanilla.createComponent({
680
+ state: { count: 0 },
681
+
682
+ template: (state) => `
683
+ <div>
684
+ <h1>Count: ${state.count}</h1>
685
+ <button data-action="increment">+</button>
686
+ <button data-action="decrement">-</button>
687
+ </div>
688
+ `,
689
+
690
+ actions: {
691
+ increment: (state) => ({ count: state.count + 1 }),
692
+ decrement: (state) => ({ count: state.count - 1 })
693
+ }
694
+ });
695
+
696
+ wuVanilla.register('counter', Counter);
408
697
  ```
409
698
 
410
- ### Webpack
699
+ ---
700
+
701
+ ## 📡 Event Bus
702
+
703
+ Sistema de eventos para comunicación entre microfrontends con soporte para wildcards y replay.
411
704
 
412
705
  ```js
413
- // webpack.config.js
414
- module.exports = {
415
- // Wu Framework funciona con cualquier versión de Webpack
416
- // Sin plugins especiales requeridos
417
- }
706
+ import { emit, on, once, off, replayEvents } from 'wu-framework';
707
+
708
+ // Emitir evento
709
+ emit('user:login', { userId: 123, name: 'John' });
710
+
711
+ // Suscribirse a evento
712
+ const unsubscribe = on('user:login', (event) => {
713
+ console.log('User logged in:', event.data);
714
+ });
715
+
716
+ // Suscribirse con wildcards
717
+ on('user:*', (event) => {
718
+ console.log('User event:', event.name, event.data);
719
+ });
720
+
721
+ // Suscribirse una sola vez
722
+ once('app:ready', (event) => {
723
+ console.log('App is ready!');
724
+ });
725
+
726
+ // Desuscribirse
727
+ off('user:login', callback);
728
+ unsubscribe(); // También funciona
729
+
730
+ // Replay eventos del historial
731
+ replayEvents('user:*', (event) => {
732
+ console.log('Past event:', event);
733
+ });
418
734
  ```
419
735
 
420
- ### Sin Bundler (ES Modules)
736
+ ---
421
737
 
422
- ```html
423
- <!-- Funciona directamente en el browser -->
424
- <script type="module">
425
- import { wu } from './node_modules/wu-framework/src/index.js';
738
+ ## 🗄️ Store (State Management)
426
739
 
427
- wu.init({
428
- apps: [{ name: 'app', url: './my-app' }]
429
- });
430
- </script>
740
+ Store de alto rendimiento con pattern matching.
741
+
742
+ ```js
743
+ import {
744
+ getState,
745
+ setState,
746
+ onStateChange,
747
+ batchState,
748
+ clearState,
749
+ getStoreMetrics
750
+ } from 'wu-framework';
751
+
752
+ // Establecer estado (dot notation)
753
+ setState('user.name', 'John');
754
+ setState('user.preferences.theme', 'dark');
755
+
756
+ // Obtener estado
757
+ const name = getState('user.name'); // 'John'
758
+ const user = getState('user'); // { name: 'John', preferences: { theme: 'dark' } }
759
+
760
+ // Suscribirse a cambios
761
+ const unsubscribe = onStateChange('user.name', (value, path) => {
762
+ console.log(`${path} changed to:`, value);
763
+ });
764
+
765
+ // Suscribirse con wildcards
766
+ onStateChange('user.*', (value, path) => {
767
+ console.log(`User property changed: ${path} =`, value);
768
+ });
769
+
770
+ // Batch updates (más eficiente)
771
+ batchState({
772
+ 'user.name': 'Jane',
773
+ 'user.email': 'jane@example.com',
774
+ 'settings.notifications': true
775
+ });
776
+
777
+ // Métricas de performance
778
+ const metrics = getStoreMetrics();
431
779
  ```
432
780
 
433
- ## 🚀 Getting Started
781
+ ---
434
782
 
435
- ### 1. Crear Container App
783
+ ## 🔌 Sistema de Plugins
436
784
 
437
- ```bash
438
- mkdir my-container-app
439
- cd my-container-app
440
- npm init -y
441
- npm install wu-framework
785
+ ```js
786
+ import { usePlugin, createPlugin, uninstallPlugin } from 'wu-framework';
787
+
788
+ const analyticsPlugin = createPlugin({
789
+ name: 'analytics',
790
+ permissions: ['events', 'store'],
791
+
792
+ install: (api, options) => {
793
+ api.on('app:mounted', (event) => {
794
+ trackEvent('mount', event.data.appName);
795
+ });
796
+ },
797
+
798
+ beforeMount: async (context) => {
799
+ console.log('Before mount:', context.appName);
800
+ },
801
+
802
+ afterMount: async (context) => {
803
+ console.log('Mounted in', context.mountTime, 'ms');
804
+ }
805
+ });
806
+
807
+ usePlugin(analyticsPlugin, { trackingId: 'UA-123456' });
442
808
  ```
443
809
 
810
+ ---
811
+
812
+ ## 🪝 Lifecycle Hooks
813
+
444
814
  ```js
445
- // index.js
446
- import { wu } from 'wu-framework';
815
+ import { useHook, createGuardHook, createTimedHook } from 'wu-framework';
816
+
817
+ // Hook básico
818
+ useHook('beforeMount', async (context, next) => {
819
+ console.log('Before mounting:', context.appName);
820
+ await next();
821
+ }, { name: 'my-hook', priority: 10 });
822
+
823
+ // Guard hook (puede cancelar)
824
+ const authGuard = createGuardHook(async (ctx) => {
825
+ return await isUserAuthenticated();
826
+ });
827
+ useHook('beforeMount', authGuard);
447
828
 
448
- wu.init({
829
+ // Hook con timeout
830
+ const timedHook = createTimedHook(async (ctx) => {
831
+ await slowOperation();
832
+ }, 5000);
833
+ ```
834
+
835
+ ### Fases Disponibles
836
+
837
+ | Fase | Descripción |
838
+ |------|-------------|
839
+ | `beforeInit` | Antes de inicializar framework |
840
+ | `afterInit` | Después de inicializar |
841
+ | `beforeLoad` | Antes de cargar una app |
842
+ | `afterLoad` | Después de cargar |
843
+ | `beforeMount` | Antes de montar |
844
+ | `afterMount` | Después de montar |
845
+ | `beforeUnmount` | Antes de desmontar |
846
+ | `afterUnmount` | Después de desmontar |
847
+
848
+ ---
849
+
850
+ ## 🎯 Loading Strategies
851
+
852
+ ```js
853
+ await wu.init({
449
854
  apps: [
450
- { name: 'header', url: 'http://localhost:3001' },
451
- { name: 'content', url: 'http://localhost:3002' }
855
+ { name: 'header', url: '/mfe/header', strategy: 'lazy' }, // Default - carga cuando se monta
856
+ { name: 'sidebar', url: '/mfe/sidebar', strategy: 'eager' }, // Precarga inmediata
857
+ { name: 'footer', url: '/mfe/footer', strategy: 'preload' }, // <link prefetch>
858
+ { name: 'analytics', url: '/mfe/analytics', strategy: 'idle' } // requestIdleCallback
452
859
  ]
453
860
  });
454
-
455
- wu.mount('header', '#header');
456
- wu.mount('content', '#content');
457
861
  ```
458
862
 
459
- ```html
460
- <!-- index.html -->
461
- <!DOCTYPE html>
462
- <html>
463
- <head>
464
- <title>Wu Framework Container</title>
465
- </head>
466
- <body>
467
- <div id="header"></div>
468
- <div id="content"></div>
863
+ | Estrategia | Descripción | Uso recomendado |
864
+ |------------|-------------|-----------------|
865
+ | `lazy` | Carga cuando se monta (default) | Contenido below-the-fold |
866
+ | `eager` | Precarga inmediata | Componentes críticos |
867
+ | `preload` | Usa `<link rel="prefetch">` | Navegación anticipada |
868
+ | `idle` | Usa `requestIdleCallback` | Analytics, features secundarias |
869
+
870
+ ---
871
+
872
+ ## ⚡ Performance Monitoring
469
873
 
470
- <script type="module" src="index.js"></script>
471
- </body>
472
- </html>
874
+ ```js
875
+ import {
876
+ startMeasure,
877
+ endMeasure,
878
+ getPerformanceMetrics,
879
+ generatePerformanceReport
880
+ } from 'wu-framework';
881
+
882
+ // Medición personalizada
883
+ startMeasure('data-fetch', 'my-app');
884
+ await fetchData();
885
+ const duration = endMeasure('data-fetch', 'my-app');
886
+
887
+ // Reporte completo
888
+ const report = generatePerformanceReport();
473
889
  ```
474
890
 
475
- ### 2. Crear Micro App
891
+ ---
476
892
 
477
- ```bash
478
- mkdir header-app
479
- cd header-app
480
- npm init -y
481
- npm install wu-framework react react-dom
893
+ ## 🛡️ Error Handling
894
+
895
+ ```js
896
+ import { registerErrorHandler, configureErrorBoundary } from 'wu-framework';
897
+
898
+ registerErrorHandler({
899
+ name: 'api-error',
900
+ canHandle: (error) => error.message.includes('API'),
901
+ handle: async (error, context) => {
902
+ if (context.retryCount < 3) {
903
+ return { recovered: true, action: 'retry' };
904
+ }
905
+ return { recovered: false, action: 'fallback' };
906
+ }
907
+ });
908
+
909
+ configureErrorBoundary({
910
+ maxRetries: 3,
911
+ retryDelay: 1000,
912
+ showErrorUI: true
913
+ });
482
914
  ```
483
915
 
916
+ ---
917
+
918
+ ## 🎯 API Simplificada (wu.app)
919
+
484
920
  ```js
485
- // index.js
486
- import React from 'react';
487
- import ReactDOM from 'react-dom';
488
921
  import { wu } from 'wu-framework';
489
922
 
490
- const HeaderApp = () => (
491
- <header style={{ background: '#f0f0f0', padding: '1rem' }}>
492
- <h1>My Header App</h1>
493
- </header>
494
- );
923
+ // URL puede ser localhost (dev) o CDN (prod)
924
+ const header = wu.app('header', {
925
+ url: 'http://localhost:3001', // o 'https://cdn.mycompany.com/mfe/header'
926
+ container: '#header-container'
927
+ });
928
+
929
+ await header.mount();
930
+ console.log(header.isMounted); // true
931
+
932
+ await header.unmount();
933
+ await header.remount();
934
+ await header.reload(); // Limpia cache
935
+
936
+ const health = await header.verify();
937
+ await header.destroy();
938
+ ```
939
+
940
+ ---
941
+
942
+ ## 🚀 Deployment
495
943
 
496
- wu.define('header', {
497
- mount: (container) => {
498
- ReactDOM.render(<HeaderApp />, container);
944
+ ### Estructura de Producción
945
+
946
+ Cada microfrontend se despliega de forma independiente:
947
+
948
+ ```
949
+ https://cdn.mycompany.com/
950
+ ├── mfe/
951
+ │ ├── header/
952
+ │ │ ├── wu.json # Manifest
953
+ │ │ ├── index.js # Entry point
954
+ │ │ └── assets/
955
+ │ ├── sidebar/
956
+ │ │ ├── wu.json
957
+ │ │ ├── index.js
958
+ │ │ └── assets/
959
+ │ └── content/
960
+ │ ├── wu.json
961
+ │ ├── index.js
962
+ │ └── assets/
963
+ ```
964
+
965
+ ### Configuración por Entorno
966
+
967
+ ```js
968
+ // config.js
969
+ const config = {
970
+ development: {
971
+ header: 'http://localhost:3001',
972
+ sidebar: 'http://localhost:3002',
973
+ content: 'http://localhost:3003'
499
974
  },
500
- unmount: (container) => {
501
- ReactDOM.unmountComponentAtNode(container);
975
+ staging: {
976
+ header: 'https://staging-cdn.mycompany.com/mfe/header',
977
+ sidebar: 'https://staging-cdn.mycompany.com/mfe/sidebar',
978
+ content: 'https://staging-cdn.mycompany.com/mfe/content'
979
+ },
980
+ production: {
981
+ header: 'https://cdn.mycompany.com/mfe/header',
982
+ sidebar: 'https://cdn.mycompany.com/mfe/sidebar',
983
+ content: 'https://cdn.mycompany.com/mfe/content'
502
984
  }
985
+ };
986
+
987
+ const env = process.env.NODE_ENV || 'development';
988
+ const urls = config[env];
989
+
990
+ await wu.init({
991
+ apps: [
992
+ { name: 'header', url: urls.header },
993
+ { name: 'sidebar', url: urls.sidebar },
994
+ { name: 'content', url: urls.content }
995
+ ]
503
996
  });
504
997
  ```
505
998
 
999
+ ### CORS Configuration
1000
+
1001
+ Los microfrontends deben permitir CORS desde el shell:
1002
+
1003
+ ```nginx
1004
+ # nginx.conf para CDN
1005
+ location /mfe/ {
1006
+ add_header Access-Control-Allow-Origin *;
1007
+ add_header Access-Control-Allow-Methods "GET, OPTIONS";
1008
+ add_header Access-Control-Allow-Headers "Content-Type";
1009
+ }
1010
+ ```
1011
+
1012
+ ### Versionado
1013
+
506
1014
  ```json
507
- // wu.json
1015
+ // wu.json con versión
508
1016
  {
509
- "name": "header-app",
510
- "entry": "index.js",
511
- "wu": {
512
- "exports": {
513
- "HeaderComponent": "./components/Header"
514
- },
515
- "imports": [],
516
- "routes": ["/header"]
517
- }
1017
+ "name": "header",
1018
+ "version": "1.2.0",
1019
+ "entry": "index.js"
518
1020
  }
519
1021
  ```
520
1022
 
521
- ### 3. Servir Apps
1023
+ ```js
1024
+ // Shell con versiones específicas
1025
+ await wu.init({
1026
+ apps: [
1027
+ { name: 'header', url: 'https://cdn.mycompany.com/mfe/header/v1.2.0' },
1028
+ { name: 'sidebar', url: 'https://cdn.mycompany.com/mfe/sidebar/v2.0.0' }
1029
+ ]
1030
+ });
1031
+ ```
522
1032
 
523
- ```bash
524
- # Terminal 1 - Container
525
- cd my-container-app
526
- npx serve -p 3000
1033
+ ---
527
1034
 
528
- # Terminal 2 - Header App
529
- cd header-app
530
- npx serve -p 3001
1035
+ ## 🏗️ Arquitectura
531
1036
 
532
- # Abrir http://localhost:3000
1037
+ ```
1038
+ ┌─────────────────────────────────────────────────────────────┐
1039
+ │ HOST APPLICATION │
1040
+ ├─────────────────────────────────────────────────────────────┤
1041
+ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
1042
+ │ │ #shadow-root │ │ #shadow-root │ │ #shadow-root│ │
1043
+ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌─────────┐ │ │
1044
+ │ │ │ Header │ │ │ │ Sidebar │ │ │ │ Content │ │ │
1045
+ │ │ │ (React) │ │ │ │ (Vue) │ │ │ │(Angular)│ │ │
1046
+ │ │ └───────────┘ │ │ └───────────┘ │ │ └─────────┘ │ │
1047
+ │ │ CSS Isolated │ │ CSS Isolated │ │ CSS Isolated│ │
1048
+ │ │ JS Sandboxed │ │ JS Sandboxed │ │ JS Sandboxed│ │
1049
+ │ └─────────────────┘ └─────────────────┘ └─────────────┘ │
1050
+ ├─────────────────────────────────────────────────────────────┤
1051
+ │ WU FRAMEWORK CORE │
1052
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
1053
+ │ │ EventBus │ │ Store │ │ Plugins │ │ Sandbox Pool │ │
1054
+ │ └──────────┘ └──────────┘ └──────────┘ └────────────────┘ │
1055
+ └─────────────────────────────────────────────────────────────┘
533
1056
  ```
534
1057
 
535
- ## 🤝 Contributing
1058
+ ---
536
1059
 
537
- Wu Framework es open source. ¡Contribuciones bienvenidas!
1060
+ ## 📋 API Reference
538
1061
 
539
- 1. Fork el repositorio
540
- 2. Crear feature branch (`git checkout -b feature/amazing-feature`)
541
- 3. Commit cambios (`git commit -m 'Add amazing feature'`)
542
- 4. Push branch (`git push origin feature/amazing-feature`)
543
- 5. Abrir Pull Request
1062
+ ### Core
544
1063
 
545
- ## 📄 License
1064
+ ```js
1065
+ import { wu, init, mount, unmount, destroy, getStats } from 'wu-framework';
1066
+ ```
546
1067
 
547
- MIT License - ver [LICENSE](LICENSE) para detalles.
1068
+ ### Event Bus
548
1069
 
549
- ## 🙏 Acknowledgments
1070
+ ```js
1071
+ import { emit, on, once, off, replayEvents, getEventBusStats } from 'wu-framework';
1072
+ ```
1073
+
1074
+ ### Store
1075
+
1076
+ ```js
1077
+ import { getState, setState, onStateChange, batchState, clearState } from 'wu-framework';
1078
+ ```
550
1079
 
551
- - Inspirado por qiankun, single-spa, y Module Federation
552
- - Construido con amor para la comunidad de microfrontends
553
- - Gracias a todos los contributors
1080
+ ### Plugins & Hooks
1081
+
1082
+ ```js
1083
+ import { usePlugin, createPlugin, useHook, removeHook } from 'wu-framework';
1084
+ ```
1085
+
1086
+ ### Performance & Errors
1087
+
1088
+ ```js
1089
+ import { startMeasure, endMeasure, generatePerformanceReport } from 'wu-framework';
1090
+ import { registerErrorHandler, configureErrorBoundary } from 'wu-framework';
1091
+ ```
1092
+
1093
+ ### Adapters
1094
+
1095
+ ```js
1096
+ import { wuReact } from 'wu-framework/adapters/react';
1097
+ import { wuVue } from 'wu-framework/adapters/vue';
1098
+ import { wuAngular } from 'wu-framework/adapters/angular';
1099
+ import { wuSvelte } from 'wu-framework/adapters/svelte';
1100
+ import { wuPreact } from 'wu-framework/adapters/preact';
1101
+ import { wuSolid } from 'wu-framework/adapters/solid';
1102
+ import { wuLit } from 'wu-framework/adapters/lit';
1103
+ import { wuVanilla } from 'wu-framework/adapters/vanilla';
1104
+ ```
1105
+
1106
+ ### Utilities
1107
+
1108
+ ```js
1109
+ import { presets, dev, events } from 'wu-framework';
1110
+
1111
+ // Presets
1112
+ await wu.init(presets.development([{ name: 'app', port: 3001 }]));
1113
+ await wu.init(presets.production([{ name: 'app', url: 'https://...' }]));
1114
+
1115
+ // Dev tools
1116
+ dev.enableDebug();
1117
+ dev.inspect();
1118
+ await dev.reload('app');
1119
+
1120
+ // Silenciar logs
1121
+ wu.silence();
1122
+ wu.verbose();
1123
+ ```
1124
+
1125
+ ---
1126
+
1127
+ ## 🤝 Contributing
1128
+
1129
+ ¡Las contribuciones son bienvenidas!
1130
+
1131
+ 1. **Fork** el repositorio
1132
+ 2. **Crear** branch (`git checkout -b feature/amazing-feature`)
1133
+ 3. **Commit** tus cambios (`git commit -m 'Add amazing feature'`)
1134
+ 4. **Push** al branch (`git push origin feature/amazing-feature`)
1135
+ 5. **Abrir** un Pull Request
554
1136
 
555
1137
  ---
556
1138
 
557
- **🚀 Wu Framework - Universal Microfrontends Made Simple**
1139
+ ## 📄 License
1140
+
1141
+ MIT License - Copyright (c) 2025 Wu Framework Team
1142
+
1143
+ ---
558
1144
 
559
- *Framework agnostic • Zero config • Shadow DOM • Runtime loading*
1145
+ <p align="center">
1146
+ <b>🚀 Wu Framework - Universal Microfrontends Made Simple</b>
1147
+ <br><br>
1148
+ <i>Zero dependencies • 8 Frameworks • Shadow DOM • Proxy Sandbox • Self-Healing</i>
1149
+ </p>