wu-framework 1.1.6 → 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 +94 -74
  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
@@ -1,813 +1,3 @@
1
- /**
2
- * 🚀 WU-FRAMEWORK ANGULAR ADAPTER
3
- *
4
- * Simplifica la integración de Angular con Wu Framework.
5
- * Convierte componentes Angular en microfrontends con configuración mínima.
6
- *
7
- * @example
8
- * // Microfrontend (main.ts)
9
- * import { wuAngular } from 'wu-framework/adapters/angular';
10
- * import { AppModule } from './app/app.module';
11
- * // o para standalone components
12
- * import { AppComponent } from './app/app.component';
13
- *
14
- * wuAngular.register('my-app', AppModule);
15
- * // o
16
- * wuAngular.registerStandalone('my-app', AppComponent);
17
- *
18
- * @example
19
- * // Shell (cargar microfrontend)
20
- * import { WuSlotComponent } from 'wu-framework/adapters/angular';
21
- *
22
- * <wu-slot name="my-app" url="http://localhost:3001"></wu-slot>
23
- */
24
-
25
- // Estado global del adapter
26
- const adapterState = {
27
- apps: new Map(),
28
- platformRef: null,
29
- initialized: false
30
- };
31
-
32
- /**
33
- * Obtiene la instancia de Wu Framework
34
- */
35
- function getWuInstance() {
36
- if (typeof window === 'undefined') return null;
37
-
38
- return window.wu
39
- || window.parent?.wu
40
- || window.top?.wu
41
- || null;
42
- }
43
-
44
- /**
45
- * Espera a que Wu Framework esté disponible
46
- */
47
- function waitForWu(timeout = 5000) {
48
- return new Promise((resolve, reject) => {
49
- const wu = getWuInstance();
50
- if (wu) {
51
- resolve(wu);
52
- return;
53
- }
54
-
55
- const startTime = Date.now();
56
-
57
- const handleWuReady = () => {
58
- cleanup();
59
- resolve(getWuInstance());
60
- };
61
-
62
- window.addEventListener('wu:ready', handleWuReady);
63
- window.addEventListener('wu:app:ready', handleWuReady);
64
-
65
- const checkInterval = setInterval(() => {
66
- const wu = getWuInstance();
67
- if (wu) {
68
- cleanup();
69
- resolve(wu);
70
- return;
71
- }
72
-
73
- if (Date.now() - startTime > timeout) {
74
- cleanup();
75
- reject(new Error(`Wu Framework not found after ${timeout}ms`));
76
- }
77
- }, 200);
78
-
79
- function cleanup() {
80
- clearInterval(checkInterval);
81
- window.removeEventListener('wu:ready', handleWuReady);
82
- window.removeEventListener('wu:app:ready', handleWuReady);
83
- }
84
- });
85
- }
86
-
87
- /**
88
- * Registra un módulo Angular como microfrontend
89
- *
90
- * @param {string} appName - Nombre único del microfrontend
91
- * @param {Type<any>} AppModule - Módulo Angular principal (AppModule)
92
- * @param {Object} options - Opciones adicionales
93
- * @param {Function} options.platformFactory - Factory del platform (platformBrowserDynamic por defecto)
94
- * @param {Array} options.providers - Providers adicionales para bootstrap
95
- * @param {Function} options.onMount - Callback después de montar
96
- * @param {Function} options.onUnmount - Callback antes de desmontar
97
- * @param {boolean} options.standalone - Permitir ejecución standalone (default: true)
98
- * @param {string} options.standaloneContainer - Selector para modo standalone (default: '#root')
99
- * @param {string} options.rootSelector - Selector del componente root (default: 'app-root')
100
- *
101
- * @example
102
- * // Básico
103
- * wuAngular.register('my-app', AppModule);
104
- *
105
- * @example
106
- * // Con opciones
107
- * wuAngular.register('my-app', AppModule, {
108
- * providers: [{ provide: 'API_URL', useValue: 'https://api.example.com' }],
109
- * onMount: (container) => console.log('Mounted!'),
110
- * rootSelector: 'my-app-root'
111
- * });
112
- */
113
- async function register(appName, AppModule, options = {}) {
114
- const {
115
- platformFactory = null,
116
- providers = [],
117
- onMount = null,
118
- onUnmount = null,
119
- standalone = true,
120
- standaloneContainer = '#root',
121
- rootSelector = 'app-root'
122
- } = options;
123
-
124
- // Función de mount interna
125
- const mountApp = async (container) => {
126
- if (!container) {
127
- console.error(`[WuAngular] Mount failed for ${appName}: container is null`);
128
- return;
129
- }
130
-
131
- // Evitar doble mount
132
- if (adapterState.apps.has(appName)) {
133
- console.warn(`[WuAngular] ${appName} already mounted, unmounting first`);
134
- await unmountApp();
135
- }
136
-
137
- try {
138
- // Crear elemento root para Angular
139
- const appElement = document.createElement(rootSelector);
140
- appElement.setAttribute('data-wu-angular-root', appName);
141
- container.innerHTML = '';
142
- container.appendChild(appElement);
143
-
144
- // Obtener platformBrowserDynamic
145
- let platform;
146
- if (platformFactory) {
147
- platform = platformFactory;
148
- } else {
149
- // Intentar import dinámico
150
- try {
151
- const platformModule = await import('@angular/platform-browser-dynamic');
152
- platform = platformModule.platformBrowserDynamic;
153
- } catch (e) {
154
- // Intentar desde window
155
- if (window.ng?.platformBrowserDynamic) {
156
- platform = window.ng.platformBrowserDynamic;
157
- } else {
158
- throw new Error('platformBrowserDynamic not available. Please provide it via options.platformFactory');
159
- }
160
- }
161
- }
162
-
163
- // Bootstrap del módulo
164
- const platformRef = platform(providers);
165
- const moduleRef = await platformRef.bootstrapModule(AppModule);
166
-
167
- // Guardar referencias
168
- adapterState.apps.set(appName, {
169
- platformRef,
170
- moduleRef,
171
- container,
172
- rootElement: appElement
173
- });
174
-
175
- console.log(`[WuAngular] ✅ ${appName} mounted successfully`);
176
-
177
- if (onMount) {
178
- onMount(container, moduleRef);
179
- }
180
- } catch (error) {
181
- console.error(`[WuAngular] Mount error for ${appName}:`, error);
182
- throw error;
183
- }
184
- };
185
-
186
- // Función de unmount interna
187
- const unmountApp = async (container) => {
188
- const instance = adapterState.apps.get(appName);
189
-
190
- if (instance) {
191
- try {
192
- if (onUnmount) {
193
- onUnmount(instance.container, instance.moduleRef);
194
- }
195
-
196
- // Destruir el módulo
197
- if (instance.moduleRef) {
198
- instance.moduleRef.destroy();
199
- }
200
-
201
- // Destruir la plataforma
202
- if (instance.platformRef) {
203
- instance.platformRef.destroy();
204
- }
205
-
206
- // Limpiar DOM
207
- if (instance.rootElement && instance.rootElement.parentNode) {
208
- instance.rootElement.parentNode.removeChild(instance.rootElement);
209
- }
210
-
211
- adapterState.apps.delete(appName);
212
-
213
- console.log(`[WuAngular] ✅ ${appName} unmounted successfully`);
214
- } catch (error) {
215
- console.error(`[WuAngular] Unmount error for ${appName}:`, error);
216
- }
217
- }
218
-
219
- // Limpiar container si se proporciona
220
- if (container) {
221
- container.innerHTML = '';
222
- }
223
- };
224
-
225
- // Intentar registrar con Wu Framework
226
- try {
227
- const wu = await waitForWu(3000);
228
-
229
- wu.define(appName, {
230
- mount: mountApp,
231
- unmount: unmountApp
232
- });
233
-
234
- console.log(`[WuAngular] ✅ ${appName} registered with Wu Framework`);
235
- return true;
236
-
237
- } catch (error) {
238
- console.warn(`[WuAngular] Wu Framework not available for ${appName}`);
239
-
240
- // Modo standalone si está habilitado
241
- if (standalone) {
242
- const containerElement = document.querySelector(standaloneContainer);
243
-
244
- if (containerElement) {
245
- console.log(`[WuAngular] Running ${appName} in standalone mode`);
246
- await mountApp(containerElement);
247
- return true;
248
- } else {
249
- console.warn(`[WuAngular] Standalone container ${standaloneContainer} not found`);
250
- }
251
- }
252
-
253
- return false;
254
- }
255
- }
256
-
257
- /**
258
- * Registra un componente Angular standalone como microfrontend (Angular 14+)
259
- *
260
- * @param {string} appName - Nombre único del microfrontend
261
- * @param {Type<any>} RootComponent - Componente standalone principal
262
- * @param {Object} options - Opciones adicionales
263
- * @param {ApplicationConfig} options.appConfig - Configuración de la aplicación
264
- * @param {Function} options.onMount - Callback después de montar
265
- * @param {Function} options.onUnmount - Callback antes de desmontar
266
- * @param {boolean} options.standalone - Permitir ejecución standalone (default: true)
267
- * @param {string} options.standaloneContainer - Selector para modo standalone (default: '#root')
268
- *
269
- * @example
270
- * // Angular 14+ con standalone components
271
- * import { AppComponent } from './app/app.component';
272
- * import { appConfig } from './app/app.config';
273
- *
274
- * wuAngular.registerStandalone('my-app', AppComponent, { appConfig });
275
- */
276
- async function registerStandalone(appName, RootComponent, options = {}) {
277
- const {
278
- appConfig = {},
279
- onMount = null,
280
- onUnmount = null,
281
- standalone = true,
282
- standaloneContainer = '#root'
283
- } = options;
284
-
285
- // Función de mount para standalone components
286
- const mountApp = async (container) => {
287
- if (!container) {
288
- console.error(`[WuAngular] Mount failed for ${appName}: container is null`);
289
- return;
290
- }
291
-
292
- // Evitar doble mount
293
- if (adapterState.apps.has(appName)) {
294
- console.warn(`[WuAngular] ${appName} already mounted, unmounting first`);
295
- await unmountApp();
296
- }
297
-
298
- try {
299
- // Obtener bootstrapApplication
300
- let bootstrapApplication;
301
- try {
302
- const browserModule = await import('@angular/platform-browser');
303
- bootstrapApplication = browserModule.bootstrapApplication;
304
- } catch (e) {
305
- if (window.ng?.bootstrapApplication) {
306
- bootstrapApplication = window.ng.bootstrapApplication;
307
- } else {
308
- throw new Error('bootstrapApplication not available. Requires Angular 14+');
309
- }
310
- }
311
-
312
- // Bootstrap del componente standalone
313
- const appRef = await bootstrapApplication(RootComponent, appConfig);
314
-
315
- // Guardar referencias
316
- adapterState.apps.set(appName, {
317
- appRef,
318
- container,
319
- isStandalone: true
320
- });
321
-
322
- console.log(`[WuAngular] ✅ ${appName} (standalone) mounted successfully`);
323
-
324
- if (onMount) {
325
- onMount(container, appRef);
326
- }
327
- } catch (error) {
328
- console.error(`[WuAngular] Mount error for ${appName}:`, error);
329
- throw error;
330
- }
331
- };
332
-
333
- // Función de unmount para standalone
334
- const unmountApp = async (container) => {
335
- const instance = adapterState.apps.get(appName);
336
-
337
- if (instance) {
338
- try {
339
- if (onUnmount) {
340
- onUnmount(instance.container, instance.appRef);
341
- }
342
-
343
- // Destruir la aplicación
344
- if (instance.appRef) {
345
- instance.appRef.destroy();
346
- }
347
-
348
- adapterState.apps.delete(appName);
349
-
350
- console.log(`[WuAngular] ✅ ${appName} (standalone) unmounted successfully`);
351
- } catch (error) {
352
- console.error(`[WuAngular] Unmount error for ${appName}:`, error);
353
- }
354
- }
355
-
356
- if (container) {
357
- container.innerHTML = '';
358
- }
359
- };
360
-
361
- // Intentar registrar con Wu Framework
362
- try {
363
- const wu = await waitForWu(3000);
364
-
365
- wu.define(appName, {
366
- mount: mountApp,
367
- unmount: unmountApp
368
- });
369
-
370
- console.log(`[WuAngular] ✅ ${appName} (standalone) registered with Wu Framework`);
371
- return true;
372
-
373
- } catch (error) {
374
- console.warn(`[WuAngular] Wu Framework not available for ${appName}`);
375
-
376
- if (standalone) {
377
- const containerElement = document.querySelector(standaloneContainer);
378
-
379
- if (containerElement) {
380
- console.log(`[WuAngular] Running ${appName} in standalone mode`);
381
- await mountApp(containerElement);
382
- return true;
383
- }
384
- }
385
-
386
- return false;
387
- }
388
- }
389
-
390
- /**
391
- * Registra un componente Angular Elements (Web Component) como microfrontend
392
- *
393
- * @param {string} appName - Nombre único del microfrontend
394
- * @param {Type<any>} Component - Componente Angular standalone
395
- * @param {Object} options - Opciones adicionales
396
- * @param {string} options.elementTag - Tag del custom element (default: basado en appName)
397
- * @param {ApplicationConfig} options.appConfig - Configuración de la aplicación Angular
398
- * @param {Function} options.onMount - Callback después de montar
399
- * @param {Function} options.onUnmount - Callback antes de desmontar
400
- * @param {boolean} options.standalone - Permitir ejecución standalone (default: true)
401
- * @param {string} options.standaloneContainer - Selector para modo standalone (default: '#root')
402
- *
403
- * @example
404
- * // Angular Elements (Web Components)
405
- * import { App } from './app/app';
406
- * import { appConfig } from './app/app.config';
407
- *
408
- * wuAngular.registerElement('mfe-angular', App, {
409
- * elementTag: 'mfe-angular-content',
410
- * appConfig
411
- * });
412
- */
413
- async function registerElement(appName, Component, options = {}) {
414
- const {
415
- elementTag = `${appName}-element`,
416
- appConfig = {},
417
- onMount = null,
418
- onUnmount = null,
419
- standalone = true,
420
- standaloneContainer = '#root'
421
- } = options;
422
-
423
- let customElementRegistered = false;
424
-
425
- // Función para inicializar Angular Elements
426
- const initializeElement = async () => {
427
- if (customElementRegistered) return true;
428
-
429
- try {
430
- // Import dinámico de Angular
431
- const [{ createApplication }, { createCustomElement }] = await Promise.all([
432
- import('@angular/platform-browser'),
433
- import('@angular/elements')
434
- ]);
435
-
436
- // Crear aplicación Angular
437
- const app = await createApplication(appConfig);
438
-
439
- // Crear y registrar el custom element
440
- const CustomElement = createCustomElement(Component, { injector: app.injector });
441
-
442
- if (!customElements.get(elementTag)) {
443
- customElements.define(elementTag, CustomElement);
444
- console.log(`[WuAngular] ✅ Custom element registered: ${elementTag}`);
445
- }
446
-
447
- customElementRegistered = true;
448
-
449
- // Guardar referencia
450
- adapterState.apps.set(`${appName}:element`, {
451
- app,
452
- elementTag,
453
- CustomElement
454
- });
455
-
456
- return true;
457
- } catch (error) {
458
- console.error(`[WuAngular] Failed to initialize Angular Element:`, error);
459
- throw error;
460
- }
461
- };
462
-
463
- // Función de mount
464
- const mountApp = async (container) => {
465
- if (!container) {
466
- console.error(`[WuAngular] Mount failed for ${appName}: container is null`);
467
- return;
468
- }
469
-
470
- try {
471
- // Asegurar que el elemento está registrado
472
- await initializeElement();
473
-
474
- // Crear el elemento custom
475
- const element = document.createElement(elementTag);
476
- element.setAttribute('data-wu-angular-element', appName);
477
-
478
- // Limpiar y agregar al container
479
- container.innerHTML = '';
480
- container.appendChild(element);
481
-
482
- // Guardar referencia del mount
483
- adapterState.apps.set(appName, {
484
- element,
485
- container,
486
- elementTag
487
- });
488
-
489
- console.log(`[WuAngular] ✅ ${appName} (element) mounted successfully`);
490
-
491
- if (onMount) {
492
- onMount(container, element);
493
- }
494
-
495
- return element;
496
- } catch (error) {
497
- console.error(`[WuAngular] Mount error for ${appName}:`, error);
498
- throw error;
499
- }
500
- };
501
-
502
- // Función de unmount
503
- const unmountApp = async (container) => {
504
- const instance = adapterState.apps.get(appName);
505
-
506
- if (instance) {
507
- try {
508
- if (onUnmount) {
509
- onUnmount(instance.container, instance.element);
510
- }
511
-
512
- // Remover elemento del DOM
513
- if (instance.element && instance.element.parentNode) {
514
- instance.element.remove();
515
- }
516
-
517
- adapterState.apps.delete(appName);
518
-
519
- console.log(`[WuAngular] ✅ ${appName} (element) unmounted successfully`);
520
- } catch (error) {
521
- console.error(`[WuAngular] Unmount error for ${appName}:`, error);
522
- }
523
- }
524
-
525
- if (container) {
526
- container.innerHTML = '';
527
- }
528
- };
529
-
530
- // Intentar registrar con Wu Framework
531
- try {
532
- const wu = await waitForWu(3000);
533
-
534
- wu.define(appName, {
535
- mount: mountApp,
536
- unmount: unmountApp
537
- });
538
-
539
- console.log(`[WuAngular] ✅ ${appName} (element) registered with Wu Framework`);
540
- return true;
541
-
542
- } catch (error) {
543
- console.warn(`[WuAngular] Wu Framework not available for ${appName}`);
544
-
545
- if (standalone) {
546
- const containerElement = document.querySelector(standaloneContainer);
547
-
548
- if (containerElement) {
549
- console.log(`[WuAngular] Running ${appName} in standalone mode`);
550
- await mountApp(containerElement);
551
- return true;
552
- }
553
- }
554
-
555
- return false;
556
- }
557
- }
558
-
559
- /**
560
- * Servicio Injectable para usar Wu Framework en Angular
561
- *
562
- * @example
563
- * // En tu módulo o componente
564
- * import { WuService } from 'wu-framework/adapters/angular';
565
- *
566
- * @Injectable()
567
- * export class MyService {
568
- * constructor() {
569
- * this.wu = createWuService();
570
- * }
571
- *
572
- * sendEvent() {
573
- * this.wu.emit('user:action', { data: 'test' });
574
- * }
575
- * }
576
- */
577
- function createWuService() {
578
- const subscriptions = [];
579
-
580
- return {
581
- // Event Bus
582
- emit: (event, data, options) => {
583
- const wu = getWuInstance();
584
- if (wu?.eventBus) {
585
- wu.eventBus.emit(event, data, options);
586
- } else {
587
- console.warn('[WuService] Wu Framework not available');
588
- }
589
- },
590
-
591
- on: (event, callback) => {
592
- const wu = getWuInstance();
593
- if (wu?.eventBus) {
594
- const unsubscribe = wu.eventBus.on(event, callback);
595
- subscriptions.push(unsubscribe);
596
- return unsubscribe;
597
- }
598
- console.warn('[WuService] Wu Framework not available');
599
- return () => {};
600
- },
601
-
602
- once: (event, callback) => {
603
- const wu = getWuInstance();
604
- if (wu?.eventBus) {
605
- return wu.eventBus.once(event, callback);
606
- }
607
- return () => {};
608
- },
609
-
610
- off: (event, callback) => {
611
- const wu = getWuInstance();
612
- if (wu?.eventBus) {
613
- wu.eventBus.off(event, callback);
614
- }
615
- },
616
-
617
- // Store
618
- getState: (path) => {
619
- const wu = getWuInstance();
620
- return wu?.store?.get(path) || null;
621
- },
622
-
623
- setState: (path, value) => {
624
- const wu = getWuInstance();
625
- if (wu?.store) {
626
- wu.store.set(path, value);
627
- }
628
- },
629
-
630
- onStateChange: (pattern, callback) => {
631
- const wu = getWuInstance();
632
- if (wu?.store) {
633
- const unsubscribe = wu.store.on(pattern, callback);
634
- subscriptions.push(unsubscribe);
635
- return unsubscribe;
636
- }
637
- return () => {};
638
- },
639
-
640
- // Cleanup
641
- destroy: () => {
642
- subscriptions.forEach(unsub => unsub());
643
- subscriptions.length = 0;
644
- },
645
-
646
- // Access to raw Wu instance
647
- get wu() {
648
- return getWuInstance();
649
- }
650
- };
651
- }
652
-
653
- /**
654
- * Crea un componente Angular para cargar microfrontends (para el Shell)
655
- * Retorna la configuración del componente para ser usado con @Component
656
- *
657
- * @example
658
- * // wu-slot.component.ts
659
- * import { Component, Input, Output, EventEmitter } from '@angular/core';
660
- * import { createWuSlotComponent } from 'wu-framework/adapters/angular';
661
- *
662
- * const config = createWuSlotComponent();
663
- *
664
- * @Component({
665
- * selector: 'wu-slot',
666
- * template: config.template,
667
- * styles: config.styles
668
- * })
669
- * export class WuSlotComponent {
670
- * @Input() name!: string;
671
- * @Input() url!: string;
672
- * @Output() load = new EventEmitter();
673
- * @Output() error = new EventEmitter();
674
- *
675
- * // ... implement lifecycle methods from config.methods
676
- * }
677
- */
678
- function createWuSlotComponent() {
679
- return {
680
- selector: 'wu-slot',
681
-
682
- template: `
683
- <div
684
- #container
685
- class="wu-slot"
686
- [class.wu-slot-loading]="loading"
687
- [class.wu-slot-error]="error"
688
- [attr.data-wu-app]="name"
689
- [attr.data-wu-url]="url"
690
- style="min-height: 100px; position: relative;">
691
-
692
- <div *ngIf="error" class="wu-slot-error-message"
693
- style="padding: 1rem; border: 1px solid #f5c6cb; border-radius: 4px; background: #f8d7da; color: #721c24;">
694
- <strong>Error loading {{ name }}</strong>
695
- <p style="margin: 0.5rem 0 0 0;">{{ error }}</p>
696
- </div>
697
-
698
- <div *ngIf="loading && !error" class="wu-slot-loading-message"
699
- style="display: flex; align-items: center; justify-content: center; padding: 2rem; color: #666;">
700
- {{ fallbackText || 'Loading ' + name + '...' }}
701
- </div>
702
- </div>
703
- `,
704
-
705
- styles: [`
706
- .wu-slot {
707
- width: 100%;
708
- min-height: 100px;
709
- }
710
- `],
711
-
712
- // Métodos para implementar en el componente
713
- methods: {
714
- async ngOnInit() {
715
- await this.mountMicrofrontend();
716
- },
717
-
718
- ngOnDestroy() {
719
- this.unmountMicrofrontend();
720
- },
721
-
722
- async mountMicrofrontend() {
723
- try {
724
- this.loading = true;
725
- this.error = null;
726
-
727
- const wu = getWuInstance();
728
- if (!wu) {
729
- throw new Error('Wu Framework not initialized');
730
- }
731
-
732
- // Crear container único
733
- const containerId = `wu-slot-${this.name}-${Date.now()}`;
734
- const innerContainer = document.createElement('div');
735
- innerContainer.id = containerId;
736
- innerContainer.style.width = '100%';
737
- innerContainer.style.height = '100%';
738
-
739
- this.container.nativeElement.innerHTML = '';
740
- this.container.nativeElement.appendChild(innerContainer);
741
-
742
- // Crear y montar la app
743
- const app = wu.app(this.name, {
744
- url: this.url,
745
- container: `#${containerId}`,
746
- autoInit: true
747
- });
748
-
749
- this.appInstance = app;
750
- await app.mount();
751
-
752
- this.loading = false;
753
- this.load.emit({ name: this.name, url: this.url });
754
-
755
- } catch (err) {
756
- console.error(`[WuSlot] Error loading ${this.name}:`, err);
757
- this.error = err.message || 'Failed to load microfrontend';
758
- this.loading = false;
759
- this.errorEvent.emit(err);
760
- }
761
- },
762
-
763
- async unmountMicrofrontend() {
764
- if (this.appInstance) {
765
- try {
766
- await this.appInstance.unmount();
767
- } catch (err) {
768
- console.warn(`[WuSlot] Error unmounting ${this.name}:`, err);
769
- }
770
- this.appInstance = null;
771
- }
772
- }
773
- }
774
- };
775
- }
776
-
777
- /**
778
- * Helper para crear un módulo Angular que exporta WuSlotComponent
779
- * Útil para shells que quieren usar <wu-slot> directamente
780
- */
781
- function getWuSlotModuleConfig() {
782
- return {
783
- imports: ['CommonModule'],
784
- declarations: ['WuSlotComponent'],
785
- exports: ['WuSlotComponent']
786
- };
787
- }
788
-
789
- // API pública del adapter
790
- export const wuAngular = {
791
- register,
792
- registerStandalone,
793
- registerElement,
794
- createWuService,
795
- createWuSlotComponent,
796
- getWuSlotModuleConfig,
797
- getWuInstance,
798
- waitForWu
799
- };
800
-
801
- // Named exports para conveniencia
802
- export {
803
- register,
804
- registerStandalone,
805
- registerElement,
806
- createWuService,
807
- createWuSlotComponent,
808
- getWuSlotModuleConfig,
809
- getWuInstance,
810
- waitForWu
811
- };
812
-
813
- export default wuAngular;
1
+ // Re-export from folder structure — backward compatibility
2
+ export * from './angular/index.js';
3
+ export { default } from './angular/index.js';