wu-framework 1.1.7 → 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +511 -977
  2. package/dist/wu-framework.cjs.js +3 -1
  3. package/dist/wu-framework.cjs.js.map +1 -0
  4. package/dist/wu-framework.dev.js +7533 -2761
  5. package/dist/wu-framework.dev.js.map +1 -1
  6. package/dist/wu-framework.esm.js +3 -0
  7. package/dist/wu-framework.esm.js.map +1 -0
  8. package/dist/wu-framework.umd.js +3 -1
  9. package/dist/wu-framework.umd.js.map +1 -0
  10. package/integrations/astro/README.md +127 -0
  11. package/integrations/astro/WuApp.astro +63 -0
  12. package/integrations/astro/WuShell.astro +39 -0
  13. package/integrations/astro/index.js +68 -0
  14. package/integrations/astro/package.json +38 -0
  15. package/integrations/astro/types.d.ts +53 -0
  16. package/package.json +89 -71
  17. package/src/adapters/angular/ai.js +30 -0
  18. package/src/adapters/angular/index.d.ts +154 -0
  19. package/src/adapters/angular/index.js +932 -0
  20. package/src/adapters/angular.d.ts +3 -154
  21. package/src/adapters/angular.js +3 -813
  22. package/src/adapters/index.js +35 -24
  23. package/src/adapters/lit/ai.js +20 -0
  24. package/src/adapters/lit/index.d.ts +120 -0
  25. package/src/adapters/lit/index.js +721 -0
  26. package/src/adapters/lit.d.ts +3 -120
  27. package/src/adapters/lit.js +3 -726
  28. package/src/adapters/preact/ai.js +33 -0
  29. package/src/adapters/preact/index.d.ts +108 -0
  30. package/src/adapters/preact/index.js +661 -0
  31. package/src/adapters/preact.d.ts +3 -108
  32. package/src/adapters/preact.js +3 -665
  33. package/src/adapters/react/ai.js +135 -0
  34. package/src/adapters/react/index.d.ts +246 -0
  35. package/src/adapters/react/index.js +689 -0
  36. package/src/adapters/react.d.ts +3 -212
  37. package/src/adapters/react.js +3 -513
  38. package/src/adapters/shared.js +64 -0
  39. package/src/adapters/solid/ai.js +32 -0
  40. package/src/adapters/solid/index.d.ts +101 -0
  41. package/src/adapters/solid/index.js +586 -0
  42. package/src/adapters/solid.d.ts +3 -101
  43. package/src/adapters/solid.js +3 -591
  44. package/src/adapters/svelte/ai.js +31 -0
  45. package/src/adapters/svelte/index.d.ts +166 -0
  46. package/src/adapters/svelte/index.js +798 -0
  47. package/src/adapters/svelte.d.ts +3 -166
  48. package/src/adapters/svelte.js +3 -803
  49. package/src/adapters/vanilla/ai.js +30 -0
  50. package/src/adapters/vanilla/index.d.ts +179 -0
  51. package/src/adapters/vanilla/index.js +785 -0
  52. package/src/adapters/vanilla.d.ts +3 -179
  53. package/src/adapters/vanilla.js +3 -791
  54. package/src/adapters/vue/ai.js +52 -0
  55. package/src/adapters/vue/index.d.ts +299 -0
  56. package/src/adapters/vue/index.js +608 -0
  57. package/src/adapters/vue.d.ts +3 -299
  58. package/src/adapters/vue.js +3 -611
  59. package/src/ai/wu-ai-actions.js +261 -0
  60. package/src/ai/wu-ai-browser.js +663 -0
  61. package/src/ai/wu-ai-context.js +332 -0
  62. package/src/ai/wu-ai-conversation.js +554 -0
  63. package/src/ai/wu-ai-permissions.js +381 -0
  64. package/src/ai/wu-ai-provider.js +605 -0
  65. package/src/ai/wu-ai-schema.js +225 -0
  66. package/src/ai/wu-ai-triggers.js +396 -0
  67. package/src/ai/wu-ai.js +474 -0
  68. package/src/core/wu-app.js +50 -8
  69. package/src/core/wu-cache.js +1 -1
  70. package/src/core/wu-core.js +645 -677
  71. package/src/core/wu-html-parser.js +121 -211
  72. package/src/core/wu-iframe-sandbox.js +328 -0
  73. package/src/core/wu-mcp-bridge.js +647 -0
  74. package/src/core/wu-overrides.js +510 -0
  75. package/src/core/wu-prefetch.js +414 -0
  76. package/src/core/wu-proxy-sandbox.js +398 -75
  77. package/src/core/wu-sandbox.js +86 -268
  78. package/src/core/wu-script-executor.js +79 -182
  79. package/src/core/wu-snapshot-sandbox.js +149 -106
  80. package/src/core/wu-strategies.js +13 -0
  81. package/src/core/wu-style-bridge.js +0 -2
  82. package/src/index.js +139 -665
  83. package/dist/wu-framework.hex.js +0 -23
  84. package/dist/wu-framework.min.js +0 -1
  85. package/dist/wu-framework.obf.js +0 -1
  86. package/scripts/build-protected.js +0 -366
  87. package/scripts/build.js +0 -212
  88. package/scripts/rollup-plugin-hex.js +0 -143
  89. package/src/core/wu-registry.js +0 -60
  90. package/src/core/wu-sandbox-pool.js +0 -390
package/README.md CHANGED
@@ -1,893 +1,570 @@
1
1
  # Wu Framework
2
2
 
3
- **Universal Microfrontends Made Simple**
3
+ **The easiest way to turn any app into a microfrontend — and the only one that doesn't force you to stop working as a standalone app.**
4
4
 
5
- Wu Framework es la libreria de microfrontends mas simple y poderosa del mercado. Framework agnostic, zero config, Shadow DOM nativo.
6
-
7
- ## Por que Wu Framework?
8
-
9
- | Caracteristica | Module Federation | qiankun | single-spa | **Wu Framework** |
10
- |---|---|---|---|---|
11
- | **Setup** | Webpack config complejo | Configuracion manual | Config extensa | **Zero config** |
12
- | **Framework Support** | React-first | Multi framework | Multi framework | **8 frameworks nativos** |
13
- | **Bundler Required** | Solo Webpack 5 | Agnostico | Agnostico | **Ninguno requerido** |
14
- | **CSS Isolation** | Basico | CSS hacks | Manual | **Shadow DOM nativo** |
15
- | **JS Isolation** | No | Proxy basico | No | **Proxy + Snapshot Sandbox** |
16
- | **Style Modes** | No | No | No | **3 modos (shared/isolated/fully-isolated)** |
17
- | **Runtime Config** | No | Limitado | Limitado | **Completamente dinamico** |
18
- | **Self-Healing** | No | No | No | **Auto-recovery** |
19
- | **Build Protection** | No | No | No | **Minify + Obfuscate + Base64** |
20
- | **API Complexity** | Alta | Media | Alta | **1 linea de codigo** |
21
-
22
- ## Instalacion
5
+ Wu speaks the language of your framework. One line to register a React component, a Vue app, an Angular module. Your app works inside a microfrontend shell AND as a standalone app — same code, zero changes.
23
6
 
24
7
  ```bash
25
8
  npm install wu-framework
26
9
  ```
27
10
 
28
- Sin webpack config, sin plugins, sin configuracion adicional.
29
-
30
11
  ---
31
12
 
32
- ## Frameworks Soportados
13
+ ## Why Wu?
14
+
15
+ Every microfrontend framework forces you to learn its language. Single-spa makes you export `bootstrap`, `mount`, `unmount`. Module Federation requires webpack config. Qiankun needs manual registration with lifecycle callbacks.
16
+
17
+ Wu doesn't. You write React code. You write Vue code. You write Angular code. Wu adapts to you.
18
+
19
+ ```jsx
20
+ // That's it. Your React app is now a microfrontend.
21
+ wuReact.register('header', App);
22
+ ```
33
23
 
34
- Wu Framework incluye **adapters nativos** para los frameworks mas populares:
24
+ If Wu isn't running? Your app mounts directly to `#root` and works by itself. No lock-in. No dependency on a shell being alive. **Microfrontends that don't chain you.**
35
25
 
36
- | Framework | Adapter | Registro |
37
- |-----------|---------|----------|
38
- | React | `wuReact` | `wuReact.register('app', App)` |
39
- | Vue | `wuVue` | `wuVue.register('app', App)` |
40
- | Angular | `wuAngular` | `wuAngular.register('app', AppModule)` |
41
- | Angular Standalone | `wuAngular` | `wuAngular.registerStandalone('app', Component)` |
42
- | Angular Elements | `wuAngular` | `wuAngular.registerElement('app', Component)` |
43
- | Svelte | `wuSvelte` | `wuSvelte.register('app', App)` |
44
- | Preact | `wuPreact` | `wuPreact.register('app', App)` |
45
- | Solid.js | `wuSolid` | `wuSolid.register('app', App)` |
46
- | Lit | `wuLit` | `wuLit.register('app', MyElement)` |
47
- | Vanilla JS | `wuVanilla` | `wuVanilla.register('app', config)` |
26
+ ### What makes Wu different
27
+
28
+ | | single-spa | qiankun | Module Federation | **Wu** |
29
+ |---|---|---|---|---|
30
+ | **Registration** | Export lifecycle functions | Manual lifecycle callbacks | Webpack config | **One line, framework-native** |
31
+ | **CSS isolation** | Manual | CSS prefixing (fragile) | None | **Shadow DOM + 3 configurable modes** |
32
+ | **JS isolation** | None | Basic Proxy | None | **Proxy sandbox with side-effect cleanup** |
33
+ | **Standalone mode** | No | No | No | **Automatic — works without shell** |
34
+ | **Framework API** | Generic | Generic | Generic | **Native hooks, composables, stores per framework** |
35
+ | **Prefetch** | Manual | Manual preload | None | **Speculation Rules API + fallbacks** |
36
+ | **QA Overrides** | None | None | None | **Cookie-based URL overrides (secure)** |
37
+ | **Config required** | Extensive | Moderate | Webpack plugin | **Zero** |
48
38
 
49
39
  ---
50
40
 
51
- ## Quick Start
41
+ ## WuCommerce — Real-World Example
52
42
 
53
- ### 1. Micro App: Crear `wu.json`
43
+ Wu Framework ships with **WuCommerce**, a Shopify-like merchant dashboard where every section is a real micro-app built with a different framework. The narrative: each module was built by a different team or acquired, unified under wu-framework.
54
44
 
55
- Cada microfrontend necesita un archivo `wu.json` en su raiz:
45
+ | Micro-app | Framework | What it does |
46
+ |-----------|-----------|-------------|
47
+ | **Topbar** | Preact | Store name, nav tabs, search, notifications, theme toggle |
48
+ | **Dashboard** | Svelte 5 | KPI cards, sparklines, recent orders, revenue chart |
49
+ | **Orders** | React | Order table with filters, search, status badges |
50
+ | **Products** | Vue 3 | Product catalog grid, stock badges, category filter |
51
+ | **Customers** | Solid.js | Customer list, segment badges, click-to-filter-orders |
52
+ | **Analytics** | Lit | Revenue bar chart, traffic donut, top products |
53
+ | **Chat** | Vanilla JS | Floating chat widget with conversations and messages |
54
+ | **Settings** | Angular 21 | Store config form, shipping zones, payment methods |
56
55
 
57
- ```json
58
- {
59
- "name": "header",
60
- "version": "1.0.0",
61
- "entry": "index.js",
62
- "styleMode": "shared",
63
- "wu": {
64
- "exports": {
65
- "NavBar": "components/NavBar.js",
66
- "UserMenu": "components/UserMenu.js"
67
- },
68
- "imports": [],
69
- "routes": ["/", "/home"],
70
- "permissions": ["events", "store"]
71
- }
72
- }
56
+ All 8 apps communicate through Wu's event bus and shared store. Click a customer → orders filter by that customer. Toggle theme → all 8 apps update. Change store name in settings → topbar updates.
57
+
58
+ ```
59
+ npm run dev # starts all 9 servers (1 shell + 8 micro-apps)
60
+ open http://localhost:4321
73
61
  ```
74
62
 
75
- | Campo | Descripcion |
76
- |-------|-------------|
77
- | `name` | Nombre unico del microfrontend |
78
- | `version` | Version del microfrontend |
79
- | `entry` | Archivo JS principal (default: `index.js`) |
80
- | `styleMode` | Modo de estilos: `shared`, `isolated`, `fully-isolated` |
81
- | `wu.exports` | Componentes que expone a otros microfrontends |
82
- | `wu.imports` | Componentes que importa de otros microfrontends |
83
- | `wu.routes` | Rutas que maneja este microfrontend |
84
- | `wu.permissions` | Permisos requeridos (`events`, `store`, `dom`) |
63
+ Source: `examples/astro-multi-framework/`
64
+
65
+ ---
66
+
67
+ ## Quick Start
85
68
 
86
- ### 2. Micro App: Registrar con Adapter (1 linea)
69
+ ### 1. Register your micro app
87
70
 
88
71
  **React:**
89
- ```tsx
72
+ ```jsx
90
73
  import { wuReact } from 'wu-framework/adapters/react';
91
74
  import App from './App';
92
-
93
- wuReact.register('header', App);
75
+ wuReact.register('orders', App);
94
76
  ```
95
77
 
96
78
  **Vue:**
97
- ```ts
79
+ ```js
98
80
  import { wuVue } from 'wu-framework/adapters/vue';
99
81
  import App from './App.vue';
100
-
101
- wuVue.register('sidebar', App);
82
+ wuVue.register('products', App);
102
83
  ```
103
84
 
104
- **Angular:**
85
+ **Angular (standalone component):**
105
86
  ```ts
87
+ import 'zone.js';
88
+ import '@angular/compiler';
89
+ import { createApplication } from '@angular/platform-browser';
90
+ import { createComponent, provideZoneChangeDetection } from '@angular/core';
106
91
  import { wuAngular } from 'wu-framework/adapters/angular';
107
- import { AppModule } from './app/app.module';
92
+ import { AppComponent } from './app/app.component';
108
93
 
109
- wuAngular.register('content', AppModule);
94
+ wuAngular.registerStandalone('settings', AppComponent, {
95
+ createApplication,
96
+ createComponent,
97
+ provideZoneChangeDetection,
98
+ });
110
99
  ```
111
100
 
112
- El adapter se encarga de todo: deteccion de contexto, modo standalone, cleanup automatico.
101
+ **Svelte 5:**
102
+ ```js
103
+ import { wuSvelte } from 'wu-framework/adapters/svelte';
104
+ import App from './App.svelte';
105
+ wuSvelte.registerSvelte5('dashboard', App);
106
+ ```
113
107
 
114
- ### 3. Shell (Host Application)
108
+ **Solid:**
109
+ ```jsx
110
+ import { wuSolid } from 'wu-framework/adapters/solid';
111
+ import App from './App';
112
+ wuSolid.register('customers', App);
113
+ ```
114
+
115
+ **Preact:**
116
+ ```jsx
117
+ import { wuPreact } from 'wu-framework/adapters/preact';
118
+ import App from './App';
119
+ wuPreact.register('topbar', App);
120
+ ```
121
+
122
+ **Lit:**
123
+ ```js
124
+ import { wuLit } from 'wu-framework/adapters/lit';
125
+ import { MyApp } from './my-app.js';
126
+ wuLit.register('analytics', MyApp);
127
+ ```
128
+
129
+ **Vanilla JS:**
130
+ ```js
131
+ import wuVanilla from 'wu-framework/adapters/vanilla';
132
+ // use wuVanilla.useWuEvents() and wuVanilla.useWuStore() inside mount/unmount
133
+ ```
134
+
135
+ ### 2. Mount from the shell
115
136
 
116
- **Desarrollo:**
117
137
  ```js
118
138
  import { wu } from 'wu-framework';
119
139
 
120
140
  await wu.init({
121
141
  apps: [
122
- { name: 'header', url: 'http://localhost:3001' },
142
+ { name: 'header', url: 'http://localhost:3001' },
123
143
  { name: 'sidebar', url: 'http://localhost:3002' },
124
144
  { name: 'content', url: 'http://localhost:3003' }
125
145
  ]
126
146
  });
127
147
 
128
- await wu.mount('header', '#header-container');
148
+ await wu.mount('header', '#header-container');
129
149
  await wu.mount('sidebar', '#sidebar-container');
130
150
  await wu.mount('content', '#content-container');
131
151
  ```
132
152
 
133
- **Produccion:**
134
- ```js
135
- import { wu } from 'wu-framework';
153
+ Each app runs inside its own Shadow DOM with a JS sandbox that tracks and cleans up all side effects on unmount.
136
154
 
137
- await wu.init({
138
- apps: [
139
- { name: 'header', url: 'https://cdn.mycompany.com/mfe/header' },
140
- { name: 'sidebar', url: 'https://cdn.mycompany.com/mfe/sidebar' },
141
- { name: 'content', url: 'https://cdn.mycompany.com/mfe/content' }
142
- ]
143
- });
144
- ```
155
+ ---
145
156
 
146
- ### Estructura de Archivos (Microfrontend)
157
+ ## 8 Framework Adapters
147
158
 
148
- ```
149
- my-header-mfe/
150
- ├── wu.json # Manifest requerido
151
- ├── index.js # Entry point (registra con adapter)
152
- ├── App.jsx # Componente principal
153
- ├── components/
154
- │ ├── NavBar.js
155
- │ └── UserMenu.js
156
- └── package.json
157
- ```
159
+ Wu doesn't give you a generic API and tell you to figure it out. Each adapter speaks the native language of its framework.
160
+
161
+ | Framework | Adapter | Register | Native APIs |
162
+ |-----------|---------|----------|-------------|
163
+ | React | `wuReact` | `.register(name, Component)` | `createUseWuEvents(React)`, `createUseWuStore(React)` |
164
+ | Vue 3 | `wuVue` | `.register(name, Component)` | `useWuEvents()`, `useWuStore()`, `WuSlot`, plugin |
165
+ | Angular 14+ | `wuAngular` | `.registerStandalone(name, Component, opts)` | `createWuService()` |
166
+ | Angular (NgModule) | `wuAngular` | `.register(name, Module)` | Same |
167
+ | Angular Elements | `wuAngular` | `.registerElement(name, Component)` | Same |
168
+ | Svelte 3/4 | `wuSvelte` | `.register(name, Component)` | `createWuStore()`, `useWuEvents()` |
169
+ | Svelte 5 | `wuSvelte` | `.registerSvelte5(name, Component)` | Same + `createWuEventStore()` |
170
+ | Preact | `wuPreact` | `.register(name, Component)` | `createUseWuEvents(hooks)`, `createUseWuStore(hooks)` |
171
+ | Preact (compat) | `wuPreact` | `.registerCompat(name, Component)` | Same |
172
+ | Solid.js | `wuSolid` | `.register(name, Component)` | `useWuEvents()`, `createWuStore()`, `createWuEvent()` |
173
+ | Lit | `wuLit` | `.register(name, Element)` | `WuMixin(LitElement)`, `wuProperty()` decorator |
174
+ | Web Component | `wuLit` | `.registerWebComponent(name, Element)` | Same |
175
+ | Vanilla JS | `wuVanilla` | `.register(name, config)` | `useWuEvents()`, `useWuStore()`, `createComponent()` |
176
+ | Vanilla (class) | `wuVanilla` | `.registerClass(name, Class)` | Same |
177
+ | Vanilla (template) | `wuVanilla` | `.registerTemplate(name, html)` | Same |
178
+
179
+ > **Note:** React and Preact hooks are *factory functions* — pass `React` or `{ useCallback, useEffect, useRef }` to get the actual hooks. Vue composables work directly with no arguments. Angular's `registerStandalone` is recommended over `register` because it works inside Shadow DOM.
180
+
181
+ Every adapter detects if Wu is present. If not, the app mounts standalone. Your microfrontend never stops working.
158
182
 
159
183
  ---
160
184
 
161
- ## Modos de Inyeccion de Estilos
185
+ ## 3 CSS Isolation Modes
162
186
 
163
- Wu Framework soporta **3 modos de inyeccion de estilos** en Shadow DOM:
187
+ This is something no other microfrontend framework offers: **per-app configurable style isolation**.
164
188
 
165
- | Modo | Descripcion | Riesgo Colision |
166
- |------|-------------|-----------------|
167
- | `shared` | Inyecta TODOS los estilos del documento padre | Alto |
168
- | `isolated` | NO inyecta estilos externos (Shadow DOM nativo) | Ninguno |
169
- | `fully-isolated` | Inyecta SOLO estilos propios de la app | Ninguno |
189
+ | Mode | What happens | When to use |
190
+ |------|-------------|-------------|
191
+ | `shared` | Host document styles are injected into Shadow DOM | Apps sharing a design system (Tailwind, Element Plus) |
192
+ | `isolated` | Pure Shadow DOM no external styles enter | Fully independent apps with their own CSS |
193
+ | `fully-isolated` | Only the app's own styles are injected | Apps that need their CSS but not global CSS |
170
194
 
171
- ### Configuracion en wu.json
195
+ Set it in `wu.json`:
172
196
 
173
197
  ```json
174
198
  {
175
199
  "name": "my-app",
200
+ "entry": "index.js",
176
201
  "styleMode": "isolated"
177
202
  }
178
203
  ```
179
204
 
180
- ### shared (default)
181
-
182
- - Inyecta estilos de librerias (Element Plus, Tailwind, Vue Flow, etc.)
183
- - Inyecta estilos globales del documento
184
- - Observer HMR para cambios en desarrollo
185
- - **Ideal para:** Apps que comparten un design system comun
186
-
187
- ### isolated
188
-
189
- - NO inyecta ningun estilo externo
190
- - Usa encapsulamiento nativo del Shadow DOM
191
- - La app debe incluir sus propios estilos (CSS-in-JS, scoped, imports)
192
- - **Ideal para:** Apps con estilos completamente independientes
193
-
194
- ### fully-isolated
195
-
196
- - Detecta y inyecta SOLO estilos propios de la app especifica
197
- - Patron de deteccion: `packages/appName/src/`
198
- - MutationObserver persistente para HMR de Vite
199
- - **Ideal para:** Apps que necesitan sus estilos pero no los globales
205
+ In a real team, your header might need `shared` (same design system as the shell), your analytics dashboard might need `isolated` (completely independent), and your sidebar might need `fully-isolated` (own styles only). Wu handles all three in the same page.
200
206
 
201
207
  ---
202
208
 
203
- ## React Adapter
209
+ ## JS Sandbox — Three Modes, Real Isolation
204
210
 
205
- ### Registro Basico
211
+ Wu offers three sandbox modes. Pick the one that fits your workflow:
206
212
 
207
- ```tsx
208
- import { wuReact } from 'wu-framework/adapters/react';
209
- import App from './App';
210
-
211
- wuReact.register('my-app', App);
212
- ```
213
+ | Mode | How it works | Tree shaking | Source maps | HMR | JS isolation |
214
+ |------|-------------|:---:|:---:|:---:|:---:|
215
+ | `module` (default) | `import()` + Proxy side-effect tracking | ✅ | ✅ | ✅ | Side effects only |
216
+ | `strict` | Hidden iframe + real `import()` | ✅ | ✅ | ✅ | **Full** (separate window) |
217
+ | `eval` | Fetch HTML → parse → `with(proxy){}` | ❌ | ❌ | ❌ | **Full** (proxy traps) |
213
218
 
214
- ### Con Opciones
219
+ ```js
220
+ // Global setting
221
+ await wu.init({
222
+ sandbox: 'strict', // or 'module' (default) or 'eval'
223
+ apps: [...]
224
+ });
215
225
 
216
- ```tsx
217
- wuReact.register('my-app', App, {
218
- strictMode: true, // Envolver en React.StrictMode
219
- props: { theme: 'dark' }, // Props iniciales
220
- standalone: true, // Ejecutar independiente si Wu no esta
221
- standaloneContainer: '#root',
222
- onMount: (container) => console.log('Mounted!'),
223
- onUnmount: (container) => console.log('Unmounted!')
226
+ // Per-app override — mix modes in the same page
227
+ await wu.init({
228
+ apps: [
229
+ { name: 'header', url: '...', sandbox: 'module' }, // Fast dev, no isolation
230
+ { name: 'analytics', url: '...', sandbox: 'strict' }, // Full isolation + modern DX
231
+ { name: 'legacy', url: '...', sandbox: 'eval' }, // UMD bundle, max isolation
232
+ ]
224
233
  });
225
234
  ```
226
235
 
227
- ### Hooks para React
236
+ **Module mode** loads your app via `import()`. Side effects (timers, listeners, storage) are tracked through the Proxy and cleaned on unmount. App code runs in the global scope — the proxy is a cleanup tracker. Works with ES modules, Vite HMR, and all modern tooling.
228
237
 
229
- ```tsx
230
- import React from 'react';
231
- import { createUseWuEvents, createUseWuStore } from 'wu-framework/adapters/react';
238
+ **Strict mode** creates a hidden iframe as an isolated execution context, then runs `import()` inside it. Your app gets a **separate `window`** — globals, timers, and listeners are isolated by the browser itself. Document operations (`querySelector`, `createElement`, `body`) are proxied to the Shadow DOM container. Destroying the iframe nukes all side effects at once. If `import()` fails (CORS), it falls back to eval mode automatically.
232
239
 
233
- const useWuEvents = createUseWuEvents(React);
234
- const useWuStore = createUseWuStore(React);
240
+ **Eval mode** fetches your app's HTML, parses out `<script>` and `<style>` tags, and executes all scripts inside the Proxy sandbox using `with(proxy){}`. Every unqualified identifier (`setTimeout`, `document`, `fetch`) resolves through the proxy's traps. This is qiankun-level isolation. Requires bundled apps (UMD/IIFE), not ES modules.
235
241
 
236
- function MyComponent() {
237
- const { emit, on } = useWuEvents();
238
- const { state, setState } = useWuStore('user');
239
-
240
- useEffect(() => {
241
- const unsub = on('cart:updated', (data) => {
242
- console.log('Cart updated:', data);
243
- });
244
- return unsub;
245
- }, [on]);
242
+ ### How strict mode works
246
243
 
247
- return (
248
- <button onClick={() => emit('user:logout')}>
249
- Logout {state?.name}
250
- </button>
251
- );
252
- }
253
244
  ```
254
-
255
- ### Cargar Microfrontends en React (Shell)
256
-
257
- ```tsx
258
- import React from 'react';
259
- import { createWuSlot } from 'wu-framework/adapters/react';
260
-
261
- const WuSlot = createWuSlot(React);
262
-
263
- const HEADER_URL = process.env.REACT_APP_HEADER_URL || 'http://localhost:3001';
264
-
265
- function Shell() {
266
- return (
267
- <div>
268
- <WuSlot
269
- name="header"
270
- url={HEADER_URL}
271
- onLoad={() => console.log('Header loaded!')}
272
- onError={(err) => console.error(err)}
273
- />
274
- </div>
275
- );
276
- }
245
+ ┌── Main Window ──────────────────────────────────┐
246
+ │ ┌── Shadow DOM ──────────────────────────────┐
247
+ │ │ App renders here (CSS isolated) │ │
248
+ │ │ document.querySelector → scoped here │ │
249
+ │ └────────────────────────────────────────────┘
250
+ │ ┌── Hidden iframe ──────────────────────────┐ │
251
+ │ │ import() runs here (REAL ES modules) │ │
252
+ │ │ window = separate context (ISOLATED) │ │
253
+ │ │ document.createElement → main document │ │
254
+ │ │ Destroy iframe = kill everything │ │
255
+ │ └────────────────────────────────────────────┘ │
256
+ └──────────────────────────────────────────────────┘
277
257
  ```
278
258
 
279
- ---
259
+ Strict mode preserves your entire development workflow:
260
+ - **Tree shaking** — real `import()`, bundler optimizations work as normal
261
+ - **Source maps** — browser loads real modules, maps resolve correctly
262
+ - **Vite HMR** — HMR client runs inside iframe, WebSocket connects to dev server
263
+ - **Full isolation** — separate `window` context, no global leaks between apps
280
264
 
281
- ## Vue Adapter
265
+ **What gets tracked and auto-cleaned (all modes):**
266
+ - `setTimeout` / `setInterval` / `requestAnimationFrame` — all IDs tracked, all cleared
267
+ - `addEventListener` / `removeEventListener` — all listeners tracked, all removed
268
+ - `document.querySelector` — scoped to the app's Shadow DOM
269
+ - `localStorage` / `sessionStorage` — keys prefixed with `wu_{appName}_`
282
270
 
283
- ### Registro Basico
271
+ **277 tests verify this works.** Unit tests for every isolation feature, integration tests proving two sandboxes don't contaminate each other.
284
272
 
285
- ```ts
286
- import { wuVue } from 'wu-framework/adapters/vue';
287
- import App from './App.vue';
288
-
289
- wuVue.register('my-app', App);
290
- ```
291
-
292
- ### Con Plugins (Pinia, Router, etc.)
273
+ ---
293
274
 
294
- ```ts
295
- import { wuVue } from 'wu-framework/adapters/vue';
296
- import { createPinia } from 'pinia';
297
- import router from './router';
298
- import App from './App.vue';
275
+ ## Cross-App Communication
299
276
 
300
- wuVue.register('my-app', App, {
301
- setup: (app) => {
302
- app.use(createPinia());
303
- app.use(router);
304
- }
305
- });
306
- ```
307
-
308
- ### Composables para Vue
277
+ ### Event Bus
309
278
 
310
- ```vue
311
- <script setup>
312
- import { onMounted, onUnmounted } from 'vue';
313
- import { useWuEvents, useWuStore } from 'wu-framework/adapters/vue';
279
+ ```js
280
+ import { emit, on, once, off } from 'wu-framework';
314
281
 
315
- const { emit, on, cleanup } = useWuEvents();
316
- const { state, setState } = useWuStore('cart');
282
+ emit('user:login', { userId: 123 });
317
283
 
318
- onMounted(() => {
319
- on('user:login', (data) => console.log('Login:', data));
284
+ const unsub = on('user:*', (event) => {
285
+ console.log(event.name, event.data);
320
286
  });
321
287
 
322
- onUnmounted(() => cleanup());
323
- </script>
324
-
325
- <template>
326
- <div>
327
- <p>Items: {{ state?.items?.length }}</p>
328
- <button @click="emit('cart:clear')">Clear Cart</button>
329
- </div>
330
- </template>
288
+ once('app:ready', (e) => console.log('Ready'));
289
+ unsub();
331
290
  ```
332
291
 
333
- ### Cargar Microfrontends en Vue (Shell)
292
+ Features: wildcard patterns (`user:*`, `*.error`, `app.*.ready`), event replay for late-joining apps, strict mode (only registered apps can emit), history buffer.
334
293
 
335
- ```vue
336
- <script setup>
337
- import { WuSlot } from 'wu-framework/adapters/vue';
338
-
339
- const headerUrl = import.meta.env.VITE_HEADER_URL || 'http://localhost:3001';
340
- </script>
341
-
342
- <template>
343
- <div>
344
- <WuSlot
345
- name="header"
346
- :url="headerUrl"
347
- @load="onLoad"
348
- @error="onError"
349
- />
350
- </div>
351
- </template>
352
- ```
353
-
354
- ### Plugin Global
355
-
356
- ```ts
357
- import { createApp } from 'vue';
358
- import { wuVuePlugin } from 'wu-framework/adapters/vue';
359
-
360
- const app = createApp(App);
361
- app.use(wuVuePlugin); // Registra <WuSlot> globalmente
362
- ```
294
+ ### Store
363
295
 
364
- ---
296
+ ```js
297
+ import { getState, setState, onStateChange } from 'wu-framework';
365
298
 
366
- ## Angular Adapter
299
+ setState('user.name', 'John');
300
+ setState('user.preferences.theme', 'dark');
367
301
 
368
- ### Registro con NgModule
302
+ getState('user.name'); // 'John'
369
303
 
370
- ```ts
371
- import { wuAngular } from 'wu-framework/adapters/angular';
372
- import { AppModule } from './app/app.module';
304
+ const unsub = onStateChange('user.*', (value, path) => {
305
+ console.log(`${path} = ${value}`);
306
+ });
373
307
 
374
- wuAngular.register('my-app', AppModule);
308
+ // Batch updates
309
+ wu.store.batch({ 'cart.count': 5, 'cart.total': 99.99 });
375
310
  ```
376
311
 
377
- ### Registro con Standalone Components (Angular 14+)
312
+ Ring buffer event history. Wildcard subscriptions. Dot-notation paths with auto-creation of nested objects.
378
313
 
379
- ```ts
380
- import { wuAngular } from 'wu-framework/adapters/angular';
381
- import { AppComponent } from './app/app.component';
382
- import { appConfig } from './app/app.config';
314
+ ---
383
315
 
384
- wuAngular.registerStandalone('my-app', AppComponent, {
385
- appConfig
386
- });
387
- ```
316
+ ## Framework-Native Integration Examples
388
317
 
389
- ### Registro con Angular Elements (Web Components)
318
+ > All examples below are from **WuCommerce**, a real merchant dashboard built with Wu Framework.
319
+ > 8 micro-apps, 8 different frameworks, running together in one shell.
320
+ > See `examples/astro-multi-framework/` for the full source.
390
321
 
391
- Para proyectos que usan Angular Elements para crear Web Components:
322
+ ### React Orders (mf-eventlab)
392
323
 
393
- ```ts
394
- import { wuAngular } from 'wu-framework/adapters/angular';
395
- import { AppComponent } from './app/app.component';
396
- import { appConfig } from './app/app.config';
397
-
398
- wuAngular.registerElement('my-app', AppComponent, {
399
- elementTag: 'my-app-element', // Tag del custom element
400
- appConfig, // Configuracion de Angular
401
- standaloneContainer: '#root', // Container para modo standalone
402
- onMount: (container, element) => {
403
- console.log('Angular Element mounted');
404
- },
405
- onUnmount: (container, element) => {
406
- console.log('Angular Element unmounted');
407
- }
408
- });
409
- ```
410
-
411
- El adapter se encarga de:
412
- - Crear la aplicacion Angular
413
- - Registrar el Custom Element con `customElements.define()`
414
- - Gestionar el ciclo de vida mount/unmount
415
- - Soportar modo standalone si Wu Framework no esta disponible
324
+ ```jsx
325
+ // main.jsx
326
+ import { wuReact } from 'wu-framework/adapters/react';
327
+ import App from './App';
328
+ wuReact.register('orders', App);
416
329
 
417
- ### Servicio para Componentes
330
+ // App.jsx hooks are factories, pass React to get the hook
331
+ import React, { useState, useEffect, useMemo } from 'react';
332
+ import { createUseWuEvents, createUseWuStore } from 'wu-framework/adapters/react';
418
333
 
419
- ```ts
420
- import { Component, OnInit, OnDestroy } from '@angular/core';
421
- import { createWuService } from 'wu-framework/adapters/angular';
334
+ const useWuEvents = createUseWuEvents(React);
335
+ const useWuStore = createUseWuStore(React);
422
336
 
423
- @Component({
424
- selector: 'app-root',
425
- template: `<button (click)="sendEvent()">Send Event</button>`
426
- })
427
- export class AppComponent implements OnInit, OnDestroy {
428
- private wuService = createWuService();
337
+ function Orders() {
338
+ const { emit, on } = useWuEvents();
339
+ const [filter, setFilter] = useState('all');
429
340
 
430
- ngOnInit() {
431
- this.wuService.on('user:login', (data) => {
432
- console.log('User logged in:', data);
341
+ useEffect(() => {
342
+ const unsub = on('customer:selected', (e) => {
343
+ setFilter(e.data?.customerName || 'all');
433
344
  });
434
- }
435
-
436
- sendEvent() {
437
- this.wuService.emit('app:ready', { timestamp: Date.now() });
438
- }
345
+ return unsub;
346
+ }, []);
439
347
 
440
- ngOnDestroy() {
441
- this.wuService.destroy();
442
- }
348
+ return <button onClick={() => emit('order:new', { id: 1001, total: 49.99 })}>New Order</button>;
443
349
  }
444
350
  ```
445
351
 
446
- ---
447
-
448
- ## Svelte Adapter
352
+ ### Vue 3 — Products (mf-statebridge)
449
353
 
450
- ### Registro Basico
354
+ ```vue
355
+ <!-- main.js -->
356
+ <!-- import { wuVue } from 'wu-framework/adapters/vue'; -->
357
+ <!-- import App from './App.vue'; -->
358
+ <!-- wuVue.register('products', App); -->
451
359
 
452
- ```js
453
- import { wuSvelte } from 'wu-framework/adapters/svelte';
454
- import App from './App.svelte';
360
+ <script setup>
361
+ import { ref, computed, onMounted, onUnmounted } from 'vue';
362
+ import { wuVue } from 'wu-framework/adapters/vue';
455
363
 
456
- wuSvelte.register('my-app', App);
457
- ```
364
+ const { useWuEvents, useWuStore } = wuVue;
365
+ const events = useWuEvents();
458
366
 
459
- ### Svelte 5 (con runes)
367
+ onMounted(() => {
368
+ events.on('search:global', (e) => {
369
+ search.value = e.data?.query || '';
370
+ });
371
+ });
460
372
 
461
- ```js
462
- import { wuSvelte } from 'wu-framework/adapters/svelte';
463
- import App from './App.svelte';
373
+ function handleStockAlert(product) {
374
+ events.emit('product:stockAlert', { productId: product.id, stock: product.stock });
375
+ }
464
376
 
465
- wuSvelte.registerSvelte5('my-app', App);
377
+ onUnmounted(() => events.cleanup());
378
+ </script>
466
379
  ```
467
380
 
468
- ### Stores Reactivos
381
+ ### Svelte 5 — Dashboard (mf-hero)
469
382
 
470
383
  ```svelte
384
+ <!-- main.js: wuSvelte.registerSvelte5('dashboard', App) -->
471
385
  <script>
472
- import { createWuStore, useWuEvents } from 'wu-framework/adapters/svelte';
473
- import { onDestroy } from 'svelte';
386
+ import { wuSvelte } from 'wu-framework/adapters/svelte';
474
387
 
475
- const userStore = createWuStore('user');
388
+ const { createWuStore, createWuEventStore, useWuEvents } = wuSvelte;
476
389
  const { emit, on, cleanup } = useWuEvents();
477
390
 
478
- on('cart:updated', (data) => {
479
- console.log('Cart updated:', data);
480
- });
481
-
482
- onDestroy(cleanup);
483
- </script>
391
+ let stats = $state({ revenue: 12847, orders: 156, visitors: 2341, conversion: 4.2 });
484
392
 
485
- <p>Hello, {$userStore?.name}</p>
486
- <button on:click={() => emit('user:logout')}>Logout</button>
487
- ```
393
+ on('theme:toggle', (e) => console.log('Theme:', e.data?.theme));
488
394
 
489
- ---
395
+ function handleNewOrder() {
396
+ emit('order:new', { orderId: `ORD-${Date.now()}`, total: 49.99, status: 'pending' });
397
+ }
490
398
 
491
- ## Preact Adapter
399
+ // cleanup is called automatically on component destroy
400
+ </script>
401
+ ```
492
402
 
493
- ### Registro Basico
403
+ ### Solid.js — Customers (mf-features)
494
404
 
495
405
  ```jsx
496
- import { wuPreact } from 'wu-framework/adapters/preact';
497
- import App from './App';
406
+ // main.jsx: wuSolid.register('customers', App)
407
+ import { createSignal, onMount } from 'solid-js';
408
+ import { wuSolid } from 'wu-framework/adapters/solid';
498
409
 
499
- wuPreact.register('my-app', App);
500
- ```
410
+ export default function Customers() {
411
+ const [search, setSearch] = createSignal('');
412
+ const { emit, on } = wuSolid.useWuEvents(); // auto-cleanup via onCleanup
501
413
 
502
- ### Compatible con React (preact/compat)
414
+ onMount(() => {
415
+ on('search:global', (e) => setSearch(e.data?.query || ''));
416
+ });
503
417
 
504
- ```jsx
505
- import { wuPreact } from 'wu-framework/adapters/preact';
506
- import App from './App';
418
+ const handleRowClick = (customer) => {
419
+ emit('customer:selected', { customerId: customer.id, customerName: customer.name });
420
+ emit('nav:section', { section: 'orders' });
421
+ };
507
422
 
508
- wuPreact.registerCompat('my-app', App);
423
+ return <div>...</div>;
424
+ }
509
425
  ```
510
426
 
511
- ### Hooks
427
+ ### Preact — Topbar (mf-header)
512
428
 
513
429
  ```jsx
514
- import { h } from 'preact';
515
- import { useState, useEffect, useCallback, useRef } from 'preact/hooks';
516
- import { createUseWuEvents, createUseWuStore } from 'wu-framework/adapters/preact';
430
+ // main.jsx: wuPreact.register('topbar', App)
431
+ import { useState, useCallback, useEffect, useRef } from 'preact/hooks';
432
+ import { wuPreact } from 'wu-framework/adapters/preact';
517
433
 
518
- const useWuEvents = createUseWuEvents({ useCallback, useEffect, useRef });
519
- const useWuStore = createUseWuStore({ useState, useCallback, useEffect });
434
+ // Factory pattern pass hooks as argument
435
+ const useWuEvents = wuPreact.createUseWuEvents({ useCallback, useEffect, useRef });
436
+ const useWuStore = wuPreact.createUseWuStore({ useState, useCallback, useEffect });
520
437
 
521
- function MyComponent() {
438
+ function Topbar() {
522
439
  const { emit, on } = useWuEvents();
523
- const { state } = useWuStore('user');
440
+ const storeData = useWuStore('store');
441
+
442
+ const handleSearch = (query) => emit('search:global', { query });
443
+ const toggleTheme = () => emit('theme:toggle', { theme: isDark ? 'light' : 'dark' });
524
444
 
525
- return <div>Hello {state?.name}</div>;
445
+ return <header>...</header>;
526
446
  }
527
447
  ```
528
448
 
529
- ---
449
+ ### Angular 21 — Settings (mf-pluginperf)
530
450
 
531
- ## Solid.js Adapter
451
+ ```ts
452
+ // main.ts — full setup (JIT mode, no AnalogJS needed)
453
+ import 'zone.js';
454
+ import '@angular/compiler';
455
+ import { createApplication } from '@angular/platform-browser';
456
+ import { createComponent, provideZoneChangeDetection } from '@angular/core';
457
+ import { wuAngular } from 'wu-framework/adapters/angular';
458
+ import { SettingsComponent } from './app/settings.component';
532
459
 
533
- ### Registro Basico
460
+ wuAngular.registerStandalone('settings', SettingsComponent, {
461
+ standaloneContainer: '#app',
462
+ createApplication, // pass Angular APIs to avoid bundler issues
463
+ createComponent,
464
+ provideZoneChangeDetection,
465
+ });
534
466
 
535
- ```jsx
536
- import { wuSolid } from 'wu-framework/adapters/solid';
537
- import App from './App';
467
+ // settings.component.ts — use createWuService for events/store
468
+ import { Component, OnInit, OnDestroy } from '@angular/core';
469
+ import { createWuService } from 'wu-framework/adapters/angular';
538
470
 
539
- wuSolid.register('my-app', App);
540
- ```
471
+ @Component({ selector: 'app-settings', standalone: true, template: '...' })
472
+ export class SettingsComponent implements OnInit, OnDestroy {
473
+ private wu = createWuService();
474
+ storeName = '';
541
475
 
542
- ### Stores Reactivos
476
+ ngOnInit() {
477
+ this.storeName = this.wu.getState('store')?.name || '';
478
+ this.wu.on('theme:toggle', (e) => console.log('Theme:', e.data?.theme));
479
+ }
543
480
 
544
- ```jsx
545
- import { createWuStore, createWuEvent } from 'wu-framework/adapters/solid';
546
-
547
- function MyComponent() {
548
- const [user, setUser] = createWuStore('user');
549
- const lastEvent = createWuEvent('notification:*');
550
-
551
- return (
552
- <div>
553
- <p>Hello, {user()?.name}</p>
554
- <Show when={lastEvent()}>
555
- <p>Last notification: {lastEvent()?.data}</p>
556
- </Show>
557
- <button onClick={() => setUser('name', 'John')}>
558
- Set Name
559
- </button>
560
- </div>
561
- );
481
+ save() {
482
+ this.wu.setState('store', { name: this.storeName });
483
+ this.wu.emit('settings:saved', { name: this.storeName });
484
+ }
485
+
486
+ ngOnDestroy() { this.wu.destroy(); }
562
487
  }
563
488
  ```
564
489
 
565
- ---
566
-
567
- ## Lit Adapter (Web Components)
490
+ > **Angular + Vite setup:** No AnalogJS or Angular CLI required. Plain Vite with
491
+ > `esbuild: { target: 'es2022' }` and `tsconfig.json` with `experimentalDecorators: true`.
492
+ > `@angular/compiler` import enables JIT mode at runtime. Pass `createApplication`,
493
+ > `createComponent`, `provideZoneChangeDetection` as options to `registerStandalone`
494
+ > so the bundler resolves them from your app's `node_modules`.
568
495
 
569
- ### Registro con LitElement
496
+ ### Lit Analytics (mf-showcase)
570
497
 
571
498
  ```js
499
+ // main.js: wuLit.register('analytics', AnalyticsApp)
572
500
  import { LitElement, html, css } from 'lit';
573
- import { wuLit } from 'wu-framework/adapters/lit';
574
-
575
- class MyApp extends LitElement {
576
- static styles = css`
577
- :host { display: block; padding: 16px; }
578
- `;
579
-
580
- render() {
581
- return html`<h1>Hello from Lit!</h1>`;
582
- }
583
- }
584
-
585
- wuLit.register('my-app', MyApp);
586
- ```
587
-
588
- ### Con WuMixin
589
-
590
- ```js
591
- import { LitElement, html } from 'lit';
592
501
  import { WuMixin } from 'wu-framework/adapters/lit';
593
502
 
594
- class MyApp extends WuMixin(LitElement) {
503
+ class AnalyticsApp extends WuMixin(LitElement) {
504
+ static styles = css`...`;
505
+
595
506
  connectedCallback() {
596
507
  super.connectedCallback();
597
- this.wuOn('user:login', (data) => {
598
- console.log('User logged in:', data);
599
- });
600
- }
601
-
602
- handleClick() {
603
- this.wuEmit('button:clicked', { id: 'my-button' });
508
+ this.wuOn('theme:toggle', () => this.requestUpdate());
509
+ const stats = this.wuGetState('stats');
604
510
  }
605
511
 
606
512
  render() {
607
513
  return html`
608
- <button @click=${this.handleClick}>Click me</button>
514
+ <button @click=${() => this.wuEmit('analytics:export')}>Export</button>
609
515
  `;
610
516
  }
611
517
  }
612
-
613
- wuLit.register('my-app', MyApp);
518
+ customElements.define('analytics-app', AnalyticsApp);
614
519
  ```
615
520
 
616
- ### Web Component Vanilla (sin Lit)
521
+ ### Vanilla JS Chat Widget (mf-sandbox)
617
522
 
618
523
  ```js
619
- import { wuLit } from 'wu-framework/adapters/lit';
524
+ // main.js default import
525
+ import wuVanilla from 'wu-framework/adapters/vanilla';
620
526
 
621
- class MyComponent extends HTMLElement {
622
- connectedCallback() {
623
- this.attachShadow({ mode: 'open' });
624
- this.shadowRoot.innerHTML = '<h1>Hello Web Component!</h1>';
625
- }
626
- }
627
-
628
- wuLit.registerWebComponent('my-component', MyComponent);
629
- ```
630
-
631
- ---
527
+ const { useWuEvents, useWuStore } = wuVanilla;
528
+ const events = useWuEvents();
529
+ const store = useWuStore();
632
530
 
633
- ## Vanilla JS Adapter
634
-
635
- ### Registro con Objeto
636
-
637
- ```js
638
- import { wuVanilla } from 'wu-framework/adapters/vanilla';
639
-
640
- wuVanilla.register('my-app', {
641
- state: { count: 0 },
642
-
643
- render: (container, state) => {
644
- container.innerHTML = `
645
- <div>
646
- <h1>Count: ${state.count}</h1>
647
- <button id="increment">+</button>
648
- </div>
649
- `;
650
- container.querySelector('#increment').onclick = () => {
651
- state.count++;
652
- };
653
- },
654
-
655
- destroy: (container) => {
656
- container.innerHTML = '';
657
- }
658
- });
659
- ```
660
-
661
- ### Registro con Clase
662
-
663
- ```js
664
- import { wuVanilla } from 'wu-framework/adapters/vanilla';
665
-
666
- class TodoApp {
667
- constructor(container) {
668
- this.container = container;
669
- this.todos = [];
670
- }
671
-
672
- render() {
673
- this.container.innerHTML = `
674
- <ul>
675
- ${this.todos.map(t => `<li>${t}</li>`).join('')}
676
- </ul>
677
- <input type="text" id="input" />
678
- <button id="add">Add</button>
679
- `;
680
-
681
- this.container.querySelector('#add').onclick = () => {
682
- const input = this.container.querySelector('#input');
683
- this.todos.push(input.value);
684
- this.render();
685
- };
686
- }
687
-
688
- destroy() {
689
- this.container.innerHTML = '';
690
- }
531
+ function mount(container) {
532
+ events.on('theme:toggle', (e) => applyTheme(e.data?.theme));
533
+ const user = store.get('user');
534
+ // render chat UI into container...
691
535
  }
692
536
 
693
- wuVanilla.registerClass('todo-app', TodoApp);
694
- ```
695
-
696
- ### Registro con Template
697
-
698
- ```js
699
- import { wuVanilla } from 'wu-framework/adapters/vanilla';
700
-
701
- wuVanilla.registerTemplate('header', `
702
- <header>
703
- <h1>My Header</h1>
704
- <nav>
705
- <a href="/">Home</a>
706
- <a href="/about">About</a>
707
- </nav>
708
- </header>
709
- `);
710
-
711
- // Template dinamico
712
- wuVanilla.registerTemplate('greeting',
713
- (data) => `<h1>Hello, ${data.name}!</h1>`,
714
- { data: { name: 'World' } }
715
- );
716
- ```
717
-
718
- ### Componente Reactivo
719
-
720
- ```js
721
- import { wuVanilla } from 'wu-framework/adapters/vanilla';
722
-
723
- const Counter = wuVanilla.createComponent({
724
- state: { count: 0 },
725
-
726
- template: (state) => `
727
- <div>
728
- <h1>Count: ${state.count}</h1>
729
- <button data-action="increment">+</button>
730
- <button data-action="decrement">-</button>
731
- </div>
732
- `,
733
-
734
- actions: {
735
- increment: (state) => ({ count: state.count + 1 }),
736
- decrement: (state) => ({ count: state.count - 1 })
737
- }
738
- });
739
-
740
- wuVanilla.register('counter', Counter);
741
- ```
742
-
743
- ---
744
-
745
- ## Event Bus
746
-
747
- Sistema de eventos para comunicacion entre microfrontends con soporte para wildcards y replay.
748
-
749
- ```js
750
- import { emit, on, once, off, replayEvents } from 'wu-framework';
751
-
752
- // Emitir evento
753
- emit('user:login', { userId: 123, name: 'John' });
754
-
755
- // Suscribirse a evento
756
- const unsubscribe = on('user:login', (event) => {
757
- console.log('User logged in:', event.data);
758
- });
759
-
760
- // Suscribirse con wildcards
761
- on('user:*', (event) => {
762
- console.log('User event:', event.name, event.data);
763
- });
764
-
765
- // Suscribirse una sola vez
766
- once('app:ready', (event) => {
767
- console.log('App is ready!');
768
- });
769
-
770
- // Desuscribirse
771
- off('user:login', callback);
772
- unsubscribe();
773
-
774
- // Replay eventos del historial
775
- replayEvents('user:*', (event) => {
776
- console.log('Past event:', event);
777
- });
778
- ```
779
-
780
- ---
781
-
782
- ## Store (State Management)
783
-
784
- Store de alto rendimiento con pattern matching.
785
-
786
- ```js
787
- import {
788
- getState,
789
- setState,
790
- onStateChange,
791
- batchState,
792
- clearState,
793
- getStoreMetrics
794
- } from 'wu-framework';
795
-
796
- // Establecer estado (dot notation)
797
- setState('user.name', 'John');
798
- setState('user.preferences.theme', 'dark');
799
-
800
- // Obtener estado
801
- const name = getState('user.name'); // 'John'
802
- const user = getState('user'); // { name: 'John', preferences: { theme: 'dark' } }
803
-
804
- // Suscribirse a cambios
805
- const unsubscribe = onStateChange('user.name', (value, path) => {
806
- console.log(`${path} changed to:`, value);
807
- });
808
-
809
- // Suscribirse con wildcards
810
- onStateChange('user.*', (value, path) => {
811
- console.log(`User property changed: ${path} =`, value);
812
- });
813
-
814
- // Batch updates (mas eficiente)
815
- batchState({
816
- 'user.name': 'Jane',
817
- 'user.email': 'jane@example.com',
818
- 'settings.notifications': true
819
- });
820
-
821
- // Metricas de performance
822
- const metrics = getStoreMetrics();
537
+ function unmount(container) {
538
+ events.cleanup();
539
+ container.innerHTML = '';
540
+ }
823
541
  ```
824
542
 
825
543
  ---
826
544
 
827
- ## Sistema de Plugins
545
+ ## Plugins & Lifecycle Hooks
828
546
 
829
547
  ```js
830
- import { usePlugin, createPlugin, uninstallPlugin } from 'wu-framework';
548
+ import { usePlugin, createPlugin, useHook, createGuardHook } from 'wu-framework';
831
549
 
832
- const analyticsPlugin = createPlugin({
550
+ // Plugin
551
+ usePlugin(createPlugin({
833
552
  name: 'analytics',
834
- permissions: ['events', 'store'],
835
-
836
- install: (api, options) => {
837
- api.on('app:mounted', (event) => {
838
- trackEvent('mount', event.data.appName);
839
- });
840
- },
553
+ install: (api) => api.on('app:mounted', (e) => track(e)),
554
+ afterMount: async (ctx) => log('mounted in', ctx.mountTime, 'ms')
555
+ }));
841
556
 
842
- beforeMount: async (context) => {
843
- console.log('Before mount:', context.appName);
844
- },
845
-
846
- afterMount: async (context) => {
847
- console.log('Mounted in', context.mountTime, 'ms');
848
- }
849
- });
850
-
851
- usePlugin(analyticsPlugin, { trackingId: 'UA-123456' });
852
- ```
853
-
854
- ---
855
-
856
- ## Lifecycle Hooks
857
-
858
- ```js
859
- import { useHook, createGuardHook, createTimedHook } from 'wu-framework';
860
-
861
- // Hook basico
557
+ // Lifecycle hook
862
558
  useHook('beforeMount', async (context, next) => {
863
- console.log('Before mounting:', context.appName);
559
+ console.log('Mounting:', context.appName);
864
560
  await next();
865
- }, { name: 'my-hook', priority: 10 });
866
-
867
- // Guard hook (puede cancelar)
868
- const authGuard = createGuardHook(async (ctx) => {
869
- return await isUserAuthenticated();
870
561
  });
871
- useHook('beforeMount', authGuard);
872
562
 
873
- // Hook con timeout
874
- const timedHook = createTimedHook(async (ctx) => {
875
- await slowOperation();
876
- }, 5000);
563
+ // Guard can cancel mount
564
+ useHook('beforeMount', createGuardHook(async () => isAuthenticated()));
877
565
  ```
878
566
 
879
- ### Fases Disponibles
880
-
881
- | Fase | Descripcion |
882
- |------|-------------|
883
- | `beforeInit` | Antes de inicializar framework |
884
- | `afterInit` | Despues de inicializar |
885
- | `beforeLoad` | Antes de cargar una app |
886
- | `afterLoad` | Despues de cargar |
887
- | `beforeMount` | Antes de montar |
888
- | `afterMount` | Despues de montar |
889
- | `beforeUnmount` | Antes de desmontar |
890
- | `afterUnmount` | Despues de desmontar |
567
+ Phases: `beforeInit` → `afterInit` → `beforeLoad` → `afterLoad` → `beforeMount` → `afterMount` → `beforeUnmount` → `afterUnmount`
891
568
 
892
569
  ---
893
570
 
@@ -896,378 +573,235 @@ const timedHook = createTimedHook(async (ctx) => {
896
573
  ```js
897
574
  await wu.init({
898
575
  apps: [
899
- { name: 'header', url: '/mfe/header', strategy: 'lazy' },
900
- { name: 'sidebar', url: '/mfe/sidebar', strategy: 'eager' },
901
- { name: 'footer', url: '/mfe/footer', strategy: 'preload' },
576
+ { name: 'header', url: '/mfe/header', strategy: 'eager' },
577
+ { name: 'content', url: '/mfe/content', strategy: 'lazy' },
902
578
  { name: 'analytics', url: '/mfe/analytics', strategy: 'idle' }
903
579
  ]
904
580
  });
905
581
  ```
906
582
 
907
- | Estrategia | Descripcion | Uso recomendado |
908
- |------------|-------------|-----------------|
909
- | `lazy` | Carga cuando se monta (default) | Contenido below-the-fold |
910
- | `eager` | Precarga inmediata | Componentes criticos |
911
- | `preload` | Usa `<link rel="prefetch">` | Navegacion anticipada |
912
- | `idle` | Usa `requestIdleCallback` | Analytics, features secundarias |
583
+ | Strategy | Behavior |
584
+ |----------|----------|
585
+ | `lazy` | Load when mounted (default) |
586
+ | `eager` | Load immediately |
587
+ | `preload` | `<link rel="prefetch">` |
588
+ | `idle` | `requestIdleCallback` |
589
+ | `speculate` | Speculation Rules API with automatic fallback chain |
913
590
 
914
591
  ---
915
592
 
916
- ## Performance Monitoring
593
+ ## Intelligent Prefetch (Speculation Rules API)
917
594
 
918
- ```js
919
- import {
920
- startMeasure,
921
- endMeasure,
922
- getPerformanceMetrics,
923
- generatePerformanceReport
924
- } from 'wu-framework';
925
-
926
- // Medicion personalizada
927
- startMeasure('data-fetch', 'my-app');
928
- await fetchData();
929
- const duration = endMeasure('data-fetch', 'my-app');
930
-
931
- // Reporte completo
932
- const report = generatePerformanceReport();
933
- ```
934
-
935
- ---
595
+ Wu uses the browser-native [Speculation Rules API](https://developer.chrome.com/docs/web-platform/prerender-pages) (Chrome 121+) for near-instant microfrontend loads, with automatic fallbacks for older browsers.
936
596
 
937
- ## Error Handling
597
+ ### Fallback chain
938
598
 
939
- ```js
940
- import { registerErrorHandler, configureErrorBoundary } from 'wu-framework';
941
-
942
- registerErrorHandler({
943
- name: 'api-error',
944
- canHandle: (error) => error.message.includes('API'),
945
- handle: async (error, context) => {
946
- if (context.retryCount < 3) {
947
- return { recovered: true, action: 'retry' };
948
- }
949
- return { recovered: false, action: 'fallback' };
950
- }
951
- });
952
-
953
- configureErrorBoundary({
954
- maxRetries: 3,
955
- retryDelay: 1000,
956
- showErrorUI: true
957
- });
599
+ ```
600
+ Speculation Rules API → <link rel="modulepreload"> → <link rel="prefetch">
601
+ (Chrome 121+) (modern browsers) (all browsers)
958
602
  ```
959
603
 
960
- ---
961
-
962
- ## API Simplificada (wu.app)
604
+ ### Usage
963
605
 
964
606
  ```js
965
- import { wu } from 'wu-framework';
966
-
967
- const header = wu.app('header', {
968
- url: 'http://localhost:3001',
969
- container: '#header-container'
970
- });
971
-
972
- await header.mount();
973
- console.log(header.isMounted); // true
607
+ // Prefetch specific apps
608
+ wu.prefetch(['sidebar', 'analytics']);
974
609
 
975
- await header.unmount();
976
- await header.remount();
977
- await header.reload(); // Limpia cache
610
+ // Prefetch all registered apps
611
+ wu.prefetchAll();
978
612
 
979
- const health = await header.verify();
980
- await header.destroy();
613
+ // With options
614
+ wu.prefetch(['sidebar'], {
615
+ trigger: 'hover', // 'immediate' | 'hover' | 'visible' | 'idle'
616
+ action: 'prefetch', // 'prefetch' | 'prerender'
617
+ eagerness: 'moderate', // 'immediate' | 'eager' | 'moderate' | 'conservative'
618
+ });
981
619
  ```
982
620
 
983
- ---
984
-
985
- ## Sistema de Build
986
-
987
- Wu Framework incluye un sistema de build completo para proteger el codigo.
988
-
989
- ### Comandos Disponibles
990
-
991
- ```bash
992
- # Instalar dependencias
993
- npm install
994
-
995
- # Build completo (todos los formatos)
996
- npm run build
621
+ ### Triggers
997
622
 
998
- # Builds individuales
999
- npm run build:dev # Desarrollo (sin minificar)
1000
- npm run build:prod # Produccion (minificado)
1001
- npm run build:obf # Ofuscado
1002
- npm run build:umd # UMD para browsers
1003
- npm run build:cjs # CommonJS para Node
623
+ | Trigger | Behavior |
624
+ |---------|----------|
625
+ | `immediate` | Prefetch now (default) |
626
+ | `hover` | Prefetch when user hovers over the app's container |
627
+ | `visible` | Prefetch when app's container enters viewport (IntersectionObserver, 200px margin) |
628
+ | `idle` | Prefetch during browser idle time (`requestIdleCallback`) |
1004
629
 
1005
- # Build protegido (pipeline completo)
1006
- npm run build:protected # Bundle -> Minify -> Obfuscate -> Base64
1007
- ```
1008
-
1009
- ### Pipeline de Proteccion
630
+ ### As loading strategy
1010
631
 
632
+ ```js
633
+ await wu.init({
634
+ apps: [
635
+ { name: 'header', url: '/mfe/header', strategy: 'eager' },
636
+ { name: 'sidebar', url: '/mfe/sidebar', strategy: 'speculate' },
637
+ { name: 'analytics', url: '/mfe/analytics', strategy: 'idle' },
638
+ ]
639
+ });
1011
640
  ```
1012
- Source Code
1013
- |
1014
- v
1015
- [1] Bundle (Rollup) -> Empaqueta todos los modulos
1016
- |
1017
- v
1018
- [2] Minify (Terser) -> Reduce ~60% del tamanio
1019
- |
1020
- v
1021
- [3] Obfuscate -> Codigo ilegible
1022
- |
1023
- v
1024
- [4] Base64 Encode -> Capa adicional de proteccion
1025
- |
1026
- v
1027
- Output: wu-framework.protected.js (~250KB)
1028
- ```
1029
-
1030
- ### Archivos Generados
1031
641
 
1032
- | Archivo | Formato | Uso |
1033
- |---------|---------|-----|
1034
- | `wu-framework.dev.js` | ES Module | Desarrollo |
1035
- | `wu-framework.min.js` | ES Module | Produccion |
1036
- | `wu-framework.obf.js` | ES Module | Produccion protegida |
1037
- | `wu-framework.protected.js` | ES Module | Maxima proteccion |
1038
- | `wu-framework.umd.js` | UMD | Browsers via CDN |
1039
- | `wu-framework.cjs.js` | CommonJS | Node.js |
642
+ The `speculate` strategy uses the Speculation Rules API by default with `immediate` trigger. It degrades gracefully — your app works on any browser, it just loads faster on Chrome 121+.
1040
643
 
1041
644
  ---
1042
645
 
1043
- ## Sandbox System
646
+ ## Cookie Overrides for QA/Testing
1044
647
 
1045
- Wu Framework usa dos estrategias de aislamiento JS:
648
+ Redirect individual microfrontends to different URLs without changing code or deploying. QA sets a cookie, and only **their browser** sees the override — everyone else sees production.
1046
649
 
1047
- ### Proxy Sandbox (Default)
650
+ ### How it works
1048
651
 
1049
- - Usa ES6 Proxy para interceptar acceso a globales
1050
- - Aislamiento completo sin side effects
1051
- - Requiere soporte de Proxy (navegadores modernos)
1052
-
1053
- ### Snapshot Sandbox (Fallback)
652
+ ```
653
+ 1. QA opens DevTools Application → Cookies
654
+ 2. Sets: wu-override:sidebar=http://localhost:5174
655
+ 3. Reloads → only "sidebar" loads from localhost
656
+ 4. Everyone else sees production sidebar
657
+ ```
1054
658
 
1055
- - Toma snapshots del estado global
1056
- - Restaura al desmontar
1057
- - Compatible con navegadores legacy
659
+ ### Programmatic API
1058
660
 
1059
661
  ```js
1060
- // El framework detecta automaticamente la mejor estrategia
1061
- const stats = wu.sandbox.getStats();
1062
- console.log(stats.strategy); // 'proxy' o 'snapshot'
1063
- ```
662
+ // Set an override (persists as cookie for 24h)
663
+ wu.override('sidebar', 'http://localhost:5174');
1064
664
 
1065
- ---
665
+ // Check active overrides
666
+ wu.getOverrides();
667
+ // → { sidebar: 'http://localhost:5174' }
1066
668
 
1067
- ## Deployment
669
+ // Remove one
670
+ wu.removeOverride('sidebar');
1068
671
 
1069
- ### Estructura de Produccion
1070
-
1071
- ```
1072
- https://cdn.mycompany.com/
1073
- ├── mfe/
1074
- │ ├── header/
1075
- │ │ ├── wu.json
1076
- │ │ ├── index.js
1077
- │ │ └── assets/
1078
- │ ├── sidebar/
1079
- │ │ ├── wu.json
1080
- │ │ ├── index.js
1081
- │ │ └── assets/
1082
- │ └── content/
1083
- │ ├── wu.json
1084
- │ ├── index.js
1085
- │ └── assets/
672
+ // Clear all
673
+ wu.clearOverrides();
1086
674
  ```
1087
675
 
1088
- ### Configuracion por Entorno
676
+ ### Security model (3 layers)
1089
677
 
1090
- ```js
1091
- const config = {
1092
- development: {
1093
- header: 'http://localhost:3001',
1094
- sidebar: 'http://localhost:3002',
1095
- content: 'http://localhost:3003'
1096
- },
1097
- staging: {
1098
- header: 'https://staging-cdn.mycompany.com/mfe/header',
1099
- sidebar: 'https://staging-cdn.mycompany.com/mfe/sidebar',
1100
- content: 'https://staging-cdn.mycompany.com/mfe/content'
1101
- },
1102
- production: {
1103
- header: 'https://cdn.mycompany.com/mfe/header',
1104
- sidebar: 'https://cdn.mycompany.com/mfe/sidebar',
1105
- content: 'https://cdn.mycompany.com/mfe/content'
1106
- }
1107
- };
678
+ | Layer | Protection |
679
+ |-------|-----------|
680
+ | **Environment gate** | Disabled in production by default. Auto-enabled only on `localhost` / `127.0.0.1`. Must explicitly opt-in for production. |
681
+ | **Domain allowlist** | Only overrides to whitelisted domains are accepted. Supports wildcards: `*.company.com`. |
682
+ | **Visual indicator** | Fixed yellow banner shows active overrides. Prevents silent phishing. Click to hide, double-click to clear. |
1108
683
 
1109
- const env = process.env.NODE_ENV || 'development';
1110
- const urls = config[env];
684
+ ### Enable in production (for QA teams)
1111
685
 
1112
- await wu.init({
1113
- apps: [
1114
- { name: 'header', url: urls.header },
1115
- { name: 'sidebar', url: urls.sidebar },
1116
- { name: 'content', url: urls.content }
1117
- ]
686
+ ```js
687
+ wu.overrides.configure({
688
+ enabled: true,
689
+ allowedDomains: ['*.mycompany.com', 'localhost', '*.vercel.app'],
690
+ showIndicator: true,
1118
691
  });
1119
692
  ```
1120
693
 
1121
- ### CORS Configuration
694
+ ### Cookie format
1122
695
 
1123
- ```nginx
1124
- location /mfe/ {
1125
- add_header Access-Control-Allow-Origin *;
1126
- add_header Access-Control-Allow-Methods "GET, OPTIONS";
1127
- add_header Access-Control-Allow-Headers "Content-Type";
1128
- }
1129
696
  ```
697
+ wu-override:<appName>=<url>
1130
698
 
1131
- ### Versionado
1132
-
1133
- ```json
1134
- {
1135
- "name": "header",
1136
- "version": "1.2.0",
1137
- "entry": "index.js"
1138
- }
699
+ # Examples:
700
+ wu-override:sidebar=http://localhost:5174
701
+ wu-override:header=https://staging.mycompany.com/header
1139
702
  ```
1140
703
 
1141
- ```js
1142
- await wu.init({
1143
- apps: [
1144
- { name: 'header', url: 'https://cdn.mycompany.com/mfe/header/v1.2.0' },
1145
- { name: 'sidebar', url: 'https://cdn.mycompany.com/mfe/sidebar/v2.0.0' }
1146
- ]
1147
- });
1148
- ```
704
+ No proxy. No server changes. Pure client-side URL substitution at init time.
1149
705
 
1150
706
  ---
1151
707
 
1152
- ## Arquitectura
708
+ ## Build & Test
1153
709
 
1154
- ```
1155
- ┌─────────────────────────────────────────────────────────────┐
1156
- │ HOST APPLICATION │
1157
- ├─────────────────────────────────────────────────────────────┤
1158
- │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
1159
- #shadow-root │ │ #shadow-root │ │ #shadow-root│ │
1160
- │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌─────────┐ │ │
1161
- │ │ │ Header │ │ │ │ Sidebar │ │ │ │ Content │ │ │
1162
- │ │ │ (React) │ │ │ │ (Vue) │ │ │ │(Angular)│ │ │
1163
- │ │ └───────────┘ │ │ └───────────┘ │ │ └─────────┘ │ │
1164
- │ │ CSS Isolated │ │ CSS Isolated │ │ CSS Isolated│ │
1165
- │ │ JS Sandboxed │ │ JS Sandboxed │ │ JS Sandboxed│ │
1166
- │ └─────────────────┘ └─────────────────┘ └─────────────┘ │
1167
- ├─────────────────────────────────────────────────────────────┤
1168
- │ WU FRAMEWORK CORE │
1169
- │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
1170
- │ │ EventBus │ │ Store │ │ Plugins │ │ Sandbox Pool │ │
1171
- │ └──────────┘ └──────────┘ └──────────┘ └────────────────┘ │
1172
- │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
1173
- │ │ Loader │ │ Manifest │ │ Hooks │ │ Style Bridge │ │
1174
- │ └──────────┘ └──────────┘ └──────────┘ └────────────────┘ │
1175
- └─────────────────────────────────────────────────────────────┘
710
+ ```bash
711
+ npm run build # ESM + CJS + UMD + Dev
712
+ npm run build:prod # Production (minified)
713
+ npm run build:dev # Development (unminified)
714
+ npm run test # 277 tests (Vitest)
715
+ npm run test:coverage # Coverage report
1176
716
  ```
1177
717
 
1178
- ---
718
+ | Output | Format | Use |
719
+ |--------|--------|-----|
720
+ | `wu-framework.esm.js` | ES Module | Bundler imports |
721
+ | `wu-framework.cjs.js` | CommonJS | Node.js require |
722
+ | `wu-framework.umd.js` | UMD | CDN / script tag |
723
+ | `wu-framework.dev.js` | ES Module | Development |
1179
724
 
1180
- ## API Reference
725
+ ---
1181
726
 
1182
- ### Core
727
+ ## Architecture
1183
728
 
1184
- ```js
1185
- import { wu, init, mount, unmount, destroy, getStats } from 'wu-framework';
729
+ ```
730
+ ┌───────────────────────────────────────────────────────────────────────┐
731
+ │ SHELL (Astro) │
732
+ │ Sidebar + Section Containers + wu.init() + wu.mount() │
733
+ ├──────────┬──────────┬──────────┬──────────┬──────────┬────────────────┤
734
+ │ Shadow │ Shadow │ Shadow │ Shadow │ Shadow │ Shadow ... │
735
+ │ ┌──────┐ │ ┌──────┐ │ ┌──────┐ │ ┌──────┐ │ ┌──────┐ │ ┌──────┐ │
736
+ │ │Topbar│ │ │Dashbd│ │ │Orders│ │ │Produc│ │ │Custo.│ │ │Analyt│ │
737
+ │ │Preact│ │ │Svelte│ │ │React │ │ │Vue 3 │ │ │Solid │ │ │ Lit │ │
738
+ │ └──────┘ │ └──────┘ │ └──────┘ │ └──────┘ │ └──────┘ │ └──────┘ │
739
+ ├──────────┴──────────┴──────────┴──────────┴──────────┴────────────────┤
740
+ │ WU FRAMEWORK CORE │
741
+ │ Sandbox (module/strict/eval) · EventBus (wildcards, replay) │
742
+ │ Store (dot-paths, batch) · StyleBridge (shared/isolated/fully-iso) │
743
+ │ Loader · Hooks · Plugins · Cache · Prefetch · Overrides │
744
+ └───────────────────────────────────────────────────────────────────────┘
1186
745
  ```
1187
746
 
1188
- ### Event Bus
747
+ Each micro-app runs inside its own Shadow DOM with configurable CSS isolation and a JS sandbox that tracks and auto-cleans all side effects on unmount.
1189
748
 
1190
- ```js
1191
- import { emit, on, once, off, replayEvents, getEventBusStats } from 'wu-framework';
1192
- ```
749
+ ---
1193
750
 
1194
- ### Store
751
+ ## API Reference
1195
752
 
1196
753
  ```js
1197
- import { getState, setState, onStateChange, batchState, clearState } from 'wu-framework';
1198
- ```
754
+ // Core
755
+ import { wu, init, mount, unmount, destroy, app, define } from 'wu-framework';
1199
756
 
1200
- ### Plugins & Hooks
757
+ // Events
758
+ import { emit, on, once, off } from 'wu-framework';
1201
759
 
1202
- ```js
1203
- import { usePlugin, createPlugin, useHook, removeHook } from 'wu-framework';
1204
- ```
760
+ // State
761
+ import { getState, setState, onStateChange } from 'wu-framework';
1205
762
 
1206
- ### Performance & Errors
763
+ // Plugins & Hooks
764
+ import { usePlugin, createPlugin, useHook } from 'wu-framework';
765
+ import { createGuardHook, createTimedHook, createTransformHook } from 'wu-framework';
1207
766
 
1208
- ```js
767
+ // Performance
1209
768
  import { startMeasure, endMeasure, generatePerformanceReport } from 'wu-framework';
1210
- import { registerErrorHandler, configureErrorBoundary } from 'wu-framework';
1211
- ```
1212
769
 
1213
- ### Style Management
1214
-
1215
- ```js
1216
- import { configureStyleSharing, reinjectStyles, getStyleStats } from 'wu-framework';
1217
- ```
770
+ // Prefetch (Speculation Rules API)
771
+ import { prefetch, prefetchAll } from 'wu-framework';
1218
772
 
1219
- ### Adapters
773
+ // Overrides (QA/Testing)
774
+ import { override, removeOverride, getOverrides, clearOverrides } from 'wu-framework';
1220
775
 
1221
- ```js
1222
- import { wuReact } from 'wu-framework/adapters/react';
1223
- import { wuVue } from 'wu-framework/adapters/vue';
776
+ // Adapters
777
+ import { wuReact } from 'wu-framework/adapters/react';
778
+ import { wuVue } from 'wu-framework/adapters/vue';
1224
779
  import { wuAngular } from 'wu-framework/adapters/angular';
1225
- import { wuSvelte } from 'wu-framework/adapters/svelte';
1226
- import { wuPreact } from 'wu-framework/adapters/preact';
1227
- import { wuSolid } from 'wu-framework/adapters/solid';
1228
- import { wuLit } from 'wu-framework/adapters/lit';
780
+ import { wuSvelte } from 'wu-framework/adapters/svelte';
781
+ import { wuPreact } from 'wu-framework/adapters/preact';
782
+ import { wuSolid } from 'wu-framework/adapters/solid';
783
+ import { wuLit } from 'wu-framework/adapters/lit';
1229
784
  import { wuVanilla } from 'wu-framework/adapters/vanilla';
1230
- ```
1231
-
1232
- ### Utilities
1233
-
1234
- ```js
1235
- import { presets, dev, events } from 'wu-framework';
1236
785
 
1237
- // Presets
1238
- await wu.init(presets.development([{ name: 'app', port: 3001 }]));
1239
- await wu.init(presets.production([{ name: 'app', url: 'https://...' }]));
786
+ // Prefetch
787
+ wu.prefetch(['sidebar', 'analytics']);
788
+ wu.prefetch(['sidebar'], { trigger: 'hover' });
789
+ wu.prefetchAll();
1240
790
 
1241
- // Dev tools
1242
- dev.enableDebug();
1243
- dev.inspect();
1244
- await dev.reload('app');
791
+ // Overrides (QA)
792
+ wu.override('sidebar', 'http://localhost:5174');
793
+ wu.removeOverride('sidebar');
794
+ wu.getOverrides();
795
+ wu.clearOverrides();
796
+ wu.overrides.configure({ enabled: true, allowedDomains: ['*.company.com'] });
1245
797
 
1246
- // Silenciar logs
798
+ // Log control
1247
799
  wu.silence();
1248
800
  wu.verbose();
1249
801
  ```
1250
802
 
1251
803
  ---
1252
804
 
1253
- ## Contributing
1254
-
1255
- Las contribuciones son bienvenidas!
1256
-
1257
- 1. **Fork** el repositorio
1258
- 2. **Crear** branch (`git checkout -b feature/amazing-feature`)
1259
- 3. **Commit** tus cambios (`git commit -m 'Add amazing feature'`)
1260
- 4. **Push** al branch (`git push origin feature/amazing-feature`)
1261
- 5. **Abrir** un Pull Request
1262
-
1263
- ---
1264
-
1265
805
  ## License
1266
806
 
1267
- MIT License - Copyright (c) 2025 Wu Framework Team
1268
-
1269
- ---
1270
-
1271
- **Wu Framework - Universal Microfrontends Made Simple**
1272
-
1273
- *Zero dependencies - 8 Frameworks - Shadow DOM - Proxy Sandbox - Self-Healing - Build Protection*
807
+ MIT