wu-framework 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -18
- package/dist/adapters/alpine/index.js +2 -0
- package/dist/adapters/alpine/index.js.map +1 -0
- package/dist/adapters/angular/index.js +2 -0
- package/dist/adapters/angular/index.js.map +1 -0
- package/dist/adapters/htmx/index.js +2 -0
- package/dist/adapters/htmx/index.js.map +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/lit/index.js +44 -0
- package/dist/adapters/lit/index.js.map +1 -0
- package/dist/adapters/preact/index.js +2 -0
- package/dist/adapters/preact/index.js.map +1 -0
- package/dist/adapters/qwik/index.js +2 -0
- package/dist/adapters/qwik/index.js.map +1 -0
- package/dist/adapters/react/index.js +2 -0
- package/dist/adapters/react/index.js.map +1 -0
- package/dist/adapters/shared.js +2 -0
- package/dist/adapters/shared.js.map +1 -0
- package/dist/adapters/solid/index.js +2 -0
- package/dist/adapters/solid/index.js.map +1 -0
- package/dist/adapters/stencil/index.js +2 -0
- package/dist/adapters/stencil/index.js.map +1 -0
- package/dist/adapters/stimulus/index.js +2 -0
- package/dist/adapters/stimulus/index.js.map +1 -0
- package/dist/adapters/svelte/index.js +2 -0
- package/dist/adapters/svelte/index.js.map +1 -0
- package/dist/adapters/vanilla/index.js +2 -0
- package/dist/adapters/vanilla/index.js.map +1 -0
- package/dist/adapters/vue/index.js +2 -0
- package/dist/adapters/vue/index.js.map +1 -0
- package/dist/ai/wu-ai.js +2 -0
- package/dist/ai/wu-ai.js.map +1 -0
- package/dist/core/wu-mcp-bridge.js +2 -0
- package/dist/core/wu-mcp-bridge.js.map +1 -0
- package/{src → dist}/index.d.ts +445 -317
- package/dist/wu-ai-browser-primitives-BDKXJlwc.js +2 -0
- package/dist/wu-ai-browser-primitives-BDKXJlwc.js.map +1 -0
- package/dist/wu-framework.cjs.js +3 -0
- package/dist/wu-framework.cjs.js.map +1 -0
- package/dist/wu-framework.dev.js +9175 -0
- package/dist/wu-framework.dev.js.map +1 -0
- package/dist/wu-framework.esm.js +3 -0
- package/dist/wu-framework.esm.js.map +1 -0
- package/dist/wu-framework.umd.js +3 -0
- package/dist/wu-framework.umd.js.map +1 -0
- package/dist/wu-html-parser.js +2 -0
- package/dist/wu-html-parser.js.map +1 -0
- package/dist/wu-iframe-sandbox.js +2 -0
- package/dist/wu-iframe-sandbox.js.map +1 -0
- package/dist/wu-logger-fJfUHBGA.js +2 -0
- package/dist/wu-logger-fJfUHBGA.js.map +1 -0
- package/dist/wu-script-executor.js +2 -0
- package/dist/wu-script-executor.js.map +1 -0
- package/package.json +43 -34
- package/src/adapters/alpine/index.js +0 -231
- package/src/adapters/alpine.js +0 -3
- package/src/adapters/angular/ai.js +0 -30
- package/src/adapters/angular/index.js +0 -932
- package/src/adapters/angular.js +0 -3
- package/src/adapters/htmx/index.js +0 -242
- package/src/adapters/htmx.js +0 -3
- package/src/adapters/index.js +0 -225
- package/src/adapters/lit/ai.js +0 -20
- package/src/adapters/lit/index.js +0 -721
- package/src/adapters/lit.js +0 -3
- package/src/adapters/preact/ai.js +0 -33
- package/src/adapters/preact/index.js +0 -661
- package/src/adapters/preact.js +0 -3
- package/src/adapters/qwik/index.js +0 -108
- package/src/adapters/qwik.js +0 -3
- package/src/adapters/react/ai.js +0 -135
- package/src/adapters/react/index.js +0 -695
- package/src/adapters/react.js +0 -3
- package/src/adapters/shared.js +0 -64
- package/src/adapters/solid/ai.js +0 -32
- package/src/adapters/solid/index.js +0 -586
- package/src/adapters/solid.js +0 -3
- package/src/adapters/stencil/index.js +0 -228
- package/src/adapters/stencil.js +0 -3
- package/src/adapters/stimulus/index.js +0 -255
- package/src/adapters/stimulus.js +0 -3
- package/src/adapters/svelte/ai.js +0 -31
- package/src/adapters/svelte/index.js +0 -798
- package/src/adapters/svelte.js +0 -3
- package/src/adapters/vanilla/ai.js +0 -30
- package/src/adapters/vanilla/index.js +0 -785
- package/src/adapters/vanilla.js +0 -3
- package/src/adapters/vue/ai.js +0 -52
- package/src/adapters/vue/index.js +0 -618
- package/src/adapters/vue.js +0 -3
- package/src/ai/wu-ai-actions.js +0 -261
- package/src/ai/wu-ai-agent.js +0 -546
- package/src/ai/wu-ai-browser-primitives.js +0 -354
- package/src/ai/wu-ai-browser.js +0 -380
- package/src/ai/wu-ai-context.js +0 -332
- package/src/ai/wu-ai-conversation.js +0 -613
- package/src/ai/wu-ai-orchestrate.js +0 -1021
- package/src/ai/wu-ai-permissions.js +0 -381
- package/src/ai/wu-ai-provider.js +0 -700
- package/src/ai/wu-ai-schema.js +0 -225
- package/src/ai/wu-ai-triggers.js +0 -396
- package/src/ai/wu-ai.js +0 -804
- package/src/core/wu-app.js +0 -236
- package/src/core/wu-cache.js +0 -498
- package/src/core/wu-core.js +0 -1412
- package/src/core/wu-error-boundary.js +0 -396
- package/src/core/wu-event-bus.js +0 -390
- package/src/core/wu-hooks.js +0 -350
- package/src/core/wu-html-parser.js +0 -199
- package/src/core/wu-iframe-sandbox.js +0 -328
- package/src/core/wu-loader.js +0 -385
- package/src/core/wu-logger.js +0 -143
- package/src/core/wu-manifest.js +0 -533
- package/src/core/wu-mcp-bridge.js +0 -432
- package/src/core/wu-overrides.js +0 -510
- package/src/core/wu-performance.js +0 -228
- package/src/core/wu-plugin.js +0 -401
- package/src/core/wu-prefetch.js +0 -414
- package/src/core/wu-proxy-sandbox.js +0 -477
- package/src/core/wu-sandbox.js +0 -779
- package/src/core/wu-script-executor.js +0 -161
- package/src/core/wu-snapshot-sandbox.js +0 -227
- package/src/core/wu-store.js +0 -307
- package/src/core/wu-strategies.js +0 -256
- package/src/core/wu-style-bridge.js +0 -477
- package/src/index.js +0 -234
- package/src/utils/dependency-resolver.js +0 -328
- /package/{src → dist}/adapters/alpine/index.d.ts +0 -0
- /package/{src → dist}/adapters/alpine.d.ts +0 -0
- /package/{src → dist}/adapters/angular/index.d.ts +0 -0
- /package/{src → dist}/adapters/angular.d.ts +0 -0
- /package/{src → dist}/adapters/htmx/index.d.ts +0 -0
- /package/{src → dist}/adapters/htmx.d.ts +0 -0
- /package/{src → dist}/adapters/lit/index.d.ts +0 -0
- /package/{src → dist}/adapters/lit.d.ts +0 -0
- /package/{src → dist}/adapters/preact/index.d.ts +0 -0
- /package/{src → dist}/adapters/preact.d.ts +0 -0
- /package/{src → dist}/adapters/qwik/index.d.ts +0 -0
- /package/{src → dist}/adapters/qwik.d.ts +0 -0
- /package/{src → dist}/adapters/react/index.d.ts +0 -0
- /package/{src → dist}/adapters/react.d.ts +0 -0
- /package/{src → dist}/adapters/solid/index.d.ts +0 -0
- /package/{src → dist}/adapters/solid.d.ts +0 -0
- /package/{src → dist}/adapters/stencil/index.d.ts +0 -0
- /package/{src → dist}/adapters/stencil.d.ts +0 -0
- /package/{src → dist}/adapters/stimulus/index.d.ts +0 -0
- /package/{src → dist}/adapters/stimulus.d.ts +0 -0
- /package/{src → dist}/adapters/svelte/index.d.ts +0 -0
- /package/{src → dist}/adapters/svelte.d.ts +0 -0
- /package/{src → dist}/adapters/vanilla/index.d.ts +0 -0
- /package/{src → dist}/adapters/vanilla.d.ts +0 -0
- /package/{src → dist}/adapters/vue/index.d.ts +0 -0
- /package/{src → dist}/adapters/vue.d.ts +0 -0
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://www.npmjs.com/package/wu-framework"><img src="https://img.shields.io/npm/v/wu-framework.svg?color=6366f1&label=npm" alt="npm version" /></a>
|
|
13
13
|
<a href="https://github.com/LuisPadre25/wu-framework/actions"><img src="https://img.shields.io/github/actions/workflow/status/LuisPadre25/wu-framework/ci.yml?label=tests&color=14b8a6" alt="tests" /></a>
|
|
14
|
-
<img src="https://img.shields.io/badge/tests-
|
|
14
|
+
<img src="https://img.shields.io/badge/tests-702%20passed-14b8a6" alt="702 tests" />
|
|
15
15
|
<img src="https://img.shields.io/badge/dependencies-0-6366f1" alt="zero deps" />
|
|
16
16
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License" /></a>
|
|
17
17
|
</p>
|
|
@@ -33,6 +33,19 @@ Add AI to any app with one line. Connect your own LLM (OpenAI, Anthropic, Ollama
|
|
|
33
33
|
npm install wu-framework
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
> **v2.1**: honest sandbox modes + reference-counted mount/unmount for robust
|
|
37
|
+
> StrictMode + Suspense flows. New: `wu.getSandboxInfo(name)`, `strictFallback`
|
|
38
|
+
> option, `wu.tagStyleAsApp(el, name)`, styleMode aliases `none` / `own-only`.
|
|
39
|
+
> All additive — zero breaking changes from v2.0. See [CHANGELOG.md](./CHANGELOG.md#210---2026-05-17---honest-sandboxes--strictmode-robustness).
|
|
40
|
+
>
|
|
41
|
+
> 📚 **Full docs**: [`docs/`](./docs/README.md) — API reference, concepts deep dives, AI guide, 12 recipes.
|
|
42
|
+
>
|
|
43
|
+
> **v2.0**: bundle reduced from 194 → 105 KB (−46%) via lazy chunks for AI and
|
|
44
|
+
> sandbox modes. Breaking changes documented in [CHANGELOG.md](./CHANGELOG.md#200---2026-05-17---lazy-by-default-bundle-split-signed-trust).
|
|
45
|
+
> The runtime API (`wu.mount`, `wu.ai.*`, `wuReact.register`, etc.) is preserved
|
|
46
|
+
> — most apps need no code changes. AI users may want to add `await wu.aiReady()`
|
|
47
|
+
> for explicit warm-up if they need the chunk loaded before first call.
|
|
48
|
+
|
|
36
49
|
## 30-Second Demo
|
|
37
50
|
|
|
38
51
|
```js
|
|
@@ -77,7 +90,7 @@ await wu.ai.send('Add product SKU-42 to the cart');
|
|
|
77
90
|
| WebMCP (Chrome 146+) | Built-in | No | No | No |
|
|
78
91
|
| MCP Server (dev tools) | Built-in | No | No | No |
|
|
79
92
|
| Dependencies | **0** | 0 | Webpack 5 | N/A |
|
|
80
|
-
| Bundle size (min) |
|
|
93
|
+
| Bundle size (min, ESM) | **~109 KB** core + lazy chunks | ~10 KB | Varies | N/A |
|
|
81
94
|
|
|
82
95
|
*Module Federation is Webpack-coupled; Wu is bundler-agnostic.
|
|
83
96
|
|
|
@@ -193,7 +206,12 @@ setState('user.name', 'John');
|
|
|
193
206
|
getState('user.name'); // 'John'
|
|
194
207
|
```
|
|
195
208
|
|
|
196
|
-
### 4. Add AI (optional)
|
|
209
|
+
### 4. Add AI (optional, lazy-loaded)
|
|
210
|
+
|
|
211
|
+
The AI subsystem (~71 KB) is loaded on demand — the first call to `wu.ai.*`
|
|
212
|
+
triggers a dynamic import. Sync config calls (`provider`, `action`, …) queue
|
|
213
|
+
and return the proxy for chaining. Async calls (`send`, `stream`, `agent`)
|
|
214
|
+
await the chunk transparently.
|
|
197
215
|
|
|
198
216
|
```js
|
|
199
217
|
wu.ai.provider('ollama', {
|
|
@@ -201,7 +219,11 @@ wu.ai.provider('ollama', {
|
|
|
201
219
|
model: 'llama3',
|
|
202
220
|
});
|
|
203
221
|
|
|
222
|
+
// First call triggers the chunk load
|
|
204
223
|
const response = await wu.ai.send('What apps are mounted?');
|
|
224
|
+
|
|
225
|
+
// Or warm up explicitly (useful before showing an AI button in UI)
|
|
226
|
+
await wu.aiReady();
|
|
205
227
|
```
|
|
206
228
|
|
|
207
229
|
---
|
|
@@ -229,34 +251,58 @@ All 8 apps communicate through Wu's event bus and shared store. Click a customer
|
|
|
229
251
|
|
|
230
252
|
| Mode | How it works | Tree shaking | Source maps | HMR | JS isolation |
|
|
231
253
|
|------|-------------|:---:|:---:|:---:|:---:|
|
|
232
|
-
| `module` (default) | `import()` + Proxy side-effect tracking | Yes | Yes | Yes |
|
|
233
|
-
| `strict` | Hidden iframe + real `import()` | Yes | Yes | Yes | **
|
|
234
|
-
| `eval` | Fetch HTML → parse → `with(proxy){}` | No | No | No | **
|
|
254
|
+
| `module` (default) | `import()` + Proxy side-effect tracking | Yes | Yes | Yes | **None** (cleanup tracker only) |
|
|
255
|
+
| `strict` | Hidden iframe + real `import()` | Yes | Yes | Yes | **Iframe-level** (separate window) |
|
|
256
|
+
| `eval` | Fetch HTML → parse → `with(proxy){}` | No | No | No | **Proxy-trap-level** |
|
|
257
|
+
|
|
258
|
+
`module` is honest naming since v2.1: the proxy *tracks* side effects so they
|
|
259
|
+
can be undone on unmount, but **does not prevent** global pollution while the
|
|
260
|
+
app is running. Choose `strict` for real JS isolation.
|
|
235
261
|
|
|
236
262
|
```js
|
|
237
263
|
await wu.init({
|
|
264
|
+
sandbox: 'strict', // global default
|
|
265
|
+
strictFallback: false, // CORS = Error, not silent eval (v2.1)
|
|
238
266
|
apps: [
|
|
239
267
|
{ name: 'header', url: '...', sandbox: 'module' },
|
|
240
268
|
{ name: 'analytics', url: '...', sandbox: 'strict' },
|
|
241
269
|
{ name: 'legacy', url: '...', sandbox: 'eval' },
|
|
242
270
|
]
|
|
243
271
|
});
|
|
272
|
+
|
|
273
|
+
// Verify what isolation level actually got applied (v2.1)
|
|
274
|
+
const info = wu.getSandboxInfo('analytics');
|
|
275
|
+
// { requestedMode: 'strict', actualMode: 'strict', isolationLevel: 'iframe', mounted: true }
|
|
244
276
|
```
|
|
245
277
|
|
|
246
278
|
**Auto-cleaned on unmount:** timers, intervals, rAF, event listeners, localStorage keys, DOM mutations.
|
|
279
|
+
**Mount/unmount is reference-counted** (v2.1) so multi-cycle StrictMode +
|
|
280
|
+
Suspense flows don't tear down apps that are still needed.
|
|
247
281
|
|
|
248
282
|
---
|
|
249
283
|
|
|
250
284
|
## 3 CSS Isolation Modes
|
|
251
285
|
|
|
252
|
-
| Mode | What happens | When to use |
|
|
253
|
-
|
|
254
|
-
| `shared` | Host styles injected into Shadow DOM | Apps sharing a design system (Tailwind) |
|
|
255
|
-
| `isolated` | Pure Shadow DOM — no external styles | Fully independent apps |
|
|
256
|
-
| `fully-isolated` | Only the app's own styles | Apps that need their CSS but not global CSS |
|
|
286
|
+
| Mode | Alias (v2.1) | What happens | When to use |
|
|
287
|
+
|------|------|-------------|-------------|
|
|
288
|
+
| `shared` | — | Host styles injected into Shadow DOM | Apps sharing a design system (Tailwind) |
|
|
289
|
+
| `isolated` | `none` | Pure Shadow DOM — no external styles | Fully independent apps |
|
|
290
|
+
| `fully-isolated` | `own-only` | Only the app's own styles | Apps that need their CSS but not global CSS |
|
|
257
291
|
|
|
258
292
|
```json
|
|
259
|
-
{ "name": "my-app", "entry": "index.js", "styleMode": "
|
|
293
|
+
{ "name": "my-app", "entry": "index.js", "styleMode": "own-only" }
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**For non-Vite bundlers** (webpack, esbuild, plain HTML), tag your styles
|
|
297
|
+
explicitly so `own-only` mode picks them up:
|
|
298
|
+
|
|
299
|
+
```js
|
|
300
|
+
import { wu } from 'wu-framework';
|
|
301
|
+
|
|
302
|
+
const style = document.createElement('style');
|
|
303
|
+
style.textContent = `/* your styles */`;
|
|
304
|
+
wu.tagStyleAsApp(style, 'cart');
|
|
305
|
+
document.head.appendChild(style);
|
|
260
306
|
```
|
|
261
307
|
|
|
262
308
|
---
|
|
@@ -348,7 +394,8 @@ QA sets a cookie → only **their browser** sees the override. Everyone else see
|
|
|
348
394
|
| AI modules | 12 |
|
|
349
395
|
| Core modules | 23 |
|
|
350
396
|
| Runtime dependencies | **0** |
|
|
351
|
-
| Bundle (ESM, minified) |
|
|
397
|
+
| Bundle (ESM, minified) | **~109 KB** core (AI + sandbox modes lazy-loaded) |
|
|
398
|
+
| Lazy chunks | AI ~71 KB · iframe-sandbox ~4 KB · html-parser ~2 KB · script-executor ~2 KB |
|
|
352
399
|
|
|
353
400
|
---
|
|
354
401
|
|
|
@@ -356,7 +403,7 @@ QA sets a cookie → only **their browser** sees the override. Everyone else see
|
|
|
356
403
|
|
|
357
404
|
```bash
|
|
358
405
|
npm run build # ESM + CJS + UMD + Dev
|
|
359
|
-
npm run test #
|
|
406
|
+
npm run test # 702 tests (Vitest)
|
|
360
407
|
npm run test:coverage # Coverage report
|
|
361
408
|
```
|
|
362
409
|
|
|
@@ -456,15 +503,17 @@ The official CLI for wu-framework. One binary, one port, all your micro-apps.
|
|
|
456
503
|
```bash
|
|
457
504
|
npm install -g @wu-framework/cli
|
|
458
505
|
|
|
459
|
-
wu create my-project #
|
|
506
|
+
wu create my-project # Guided interactive scaffolding (13 frameworks)
|
|
460
507
|
cd my-project
|
|
461
|
-
wu dev # Native Zig dev server on one port
|
|
462
|
-
wu build # Production build (parallel Vite)
|
|
508
|
+
wu dev # Native Zig dev server on one port (Windows UTF-8 ready)
|
|
509
|
+
wu build # Production build (parallel Vite + React/Vue/Svelte shells)
|
|
463
510
|
wu serve # Serve production build
|
|
464
511
|
```
|
|
465
512
|
|
|
466
513
|
Features:
|
|
467
|
-
- Native SIMD HTTP server written in Zig
|
|
514
|
+
- Native SIMD HTTP server written in Zig 0.16.0
|
|
515
|
+
- **Guided Dialogue**: Step-by-step project creation with intelligent naming.
|
|
516
|
+
- **Multi-Framework Shells**: Generate shells in React (with `WuSlot`), Vue, or Svelte.
|
|
468
517
|
- Three-tier compilation: Native Zig JSX (0-2ms) -> Compiler Daemon (10-50ms) -> Node fallback
|
|
469
518
|
- Two-level cache with 73-138x speedup on warm restart
|
|
470
519
|
- Theme-aware production shell with dark/light toggle
|
|
@@ -474,6 +523,38 @@ See [@wu-framework/cli](https://github.com/LuisPadre25/wu-cli) for full document
|
|
|
474
523
|
|
|
475
524
|
---
|
|
476
525
|
|
|
526
|
+
## v2.0 Migration
|
|
527
|
+
|
|
528
|
+
Most code keeps working — `wu.mount`, `wu.ai.*`, `wuReact.register`, and
|
|
529
|
+
`wu.emit/on/store` are unchanged. The transparent `wu.ai` proxy means existing
|
|
530
|
+
`wu.ai.provider().action().send(...)` chains keep their sync semantics.
|
|
531
|
+
|
|
532
|
+
What did change (full list in [CHANGELOG.md](./CHANGELOG.md)):
|
|
533
|
+
|
|
534
|
+
```js
|
|
535
|
+
// AI helper classes moved to a subpath (lazy chunk).
|
|
536
|
+
- import { WuAI, WuAIAgent } from 'wu-framework';
|
|
537
|
+
+ import { WuAI, WuAIAgent } from 'wu-framework/ai';
|
|
538
|
+
|
|
539
|
+
// Sandbox internals moved to subpaths (also lazy).
|
|
540
|
+
- import { WuIframeSandbox } from 'wu-framework';
|
|
541
|
+
+ import { WuIframeSandbox } from 'wu-framework/sandbox/iframe';
|
|
542
|
+
|
|
543
|
+
// Eager `adapters` object replaced by async loader.
|
|
544
|
+
- import { adapters } from 'wu-framework/adapters';
|
|
545
|
+
- adapters.react.register('cart', App);
|
|
546
|
+
+ import { loadAdapter } from 'wu-framework/adapters';
|
|
547
|
+
+ const wuReact = await loadAdapter('react');
|
|
548
|
+
+ wuReact.register('cart', App);
|
|
549
|
+
|
|
550
|
+
// (or just import the specific subpath — same as before)
|
|
551
|
+
import { wuReact } from 'wu-framework/adapters/react';
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
Security changes worth knowing:
|
|
555
|
+
- `WuStore.set('__proto__.x', v)` now throws (was silently polluting `Object.prototype`).
|
|
556
|
+
- `wu.eventBus.emit(name, data, { appName: 'wu-ai' })` from user code is rejected in `strictMode` unless you hold the internal token. Use a registered app name + `registerApp()` token instead.
|
|
557
|
+
|
|
477
558
|
## Contributing
|
|
478
559
|
|
|
479
560
|
Contributions welcome. Please open an issue first to discuss what you'd like to change.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const n={apps:new Map};function e(){return"undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null}function o(n=5e3){return new Promise((o,t)=>{const r=e();if(r)return void o(r);const i=Date.now(),u=()=>{l(),o(e())};window.addEventListener("wu:ready",u),window.addEventListener("wu:app:ready",u);const a=setInterval(()=>{const r=e();if(r)return l(),void o(r);Date.now()-i>n&&(l(),t(new Error(`Wu Framework not found after ${n}ms`)))},200);function l(){clearInterval(a),window.removeEventListener("wu:ready",u),window.removeEventListener("wu:app:ready",u)}})}async function t(e,t,r={}){const{template:i,data:u}=t,{onMount:a=null,onUnmount:l=null,standalone:s=!0,standaloneContainer:c="#app"}=r;if(!i||"string"!=typeof i)throw new Error(`[WuAlpine] template (HTML string) is required for ${e}`);const d=o=>{if(o){n.apps.has(e)&&(console.warn(`[WuAlpine] ${e} already mounted, unmounting first`),w());try{o.innerHTML="",o.innerHTML=i;const r=window.Alpine;r?(u&&"function"==typeof u&&r.data("app",u),r.initTree(o)):console.warn("[WuAlpine] window.Alpine not found - template inserted but not initialized"),n.apps.set(e,{container:o,config:t}),console.log(`[WuAlpine] ${e} mounted successfully`),a&&a(o)}catch(n){throw console.error(`[WuAlpine] Mount error for ${e}:`,n),n}}else console.error(`[WuAlpine] Mount failed for ${e}: container is null`)},w=o=>{const t=n.apps.get(e);if(t)try{l&&l(t.container);const o=window.Alpine;o&&"function"==typeof o.destroyTree&&o.destroyTree(t.container),t.container.innerHTML="",n.apps.delete(e),console.log(`[WuAlpine] ${e} unmounted successfully`)}catch(n){console.error(`[WuAlpine] Unmount error for ${e}:`,n)}o&&(o.innerHTML="")};try{return(await o(3e3)).define(e,{mount:d,unmount:w}),console.log(`[WuAlpine] ${e} registered with Wu Framework`),!0}catch(n){if(console.warn(`[WuAlpine] Wu Framework not available for ${e}`),s){const n=document.querySelector(c);if(n)return console.log(`[WuAlpine] Running ${e} in standalone mode`),d(n),!0}return!1}}const r={register:t,getWuInstance:e,waitForWu:o};export{r as default,e as getWuInstance,t as register,o as waitForWu,r as wuAlpine};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/adapters/alpine/index.js"],"sourcesContent":["/**\n * WU-FRAMEWORK ALPINE.JS ADAPTER\n *\n * Bridges Alpine.js reactive components into Wu Framework's\n * microfrontend orchestration layer. Alpine's declarative\n * x-data / x-bind paradigm maps naturally to a template + data\n * registration model.\n *\n * @example\n * import { wuAlpine } from 'wu-framework/adapters/alpine';\n *\n * wuAlpine.register('my-app', {\n * template: '<div x-data=\"app\"><span x-text=\"message\"></span></div>',\n * data: () => ({ message: 'Hello from Alpine' })\n * });\n *\n * @example\n * // With lifecycle hooks\n * wuAlpine.register('counter', {\n * template: `\n * <div x-data=\"app\">\n * <span x-text=\"count\"></span>\n * <button @click=\"count++\">+</button>\n * </div>\n * `,\n * data: () => ({ count: 0 })\n * }, {\n * onMount: (container) => console.log('Mounted'),\n * onUnmount: (container) => console.log('Unmounted')\n * });\n */\n\n// Adapter-scoped state\nconst adapterState = {\n apps: new Map()\n};\n\n/**\n * Obtiene la instancia de Wu Framework\n */\nfunction getWuInstance() {\n if (typeof window === 'undefined') return null;\n\n return window.wu\n || window.parent?.wu\n || window.top?.wu\n || null;\n}\n\n/**\n * Espera a que Wu Framework este disponible\n */\nfunction waitForWu(timeout = 5000) {\n return new Promise((resolve, reject) => {\n const wu = getWuInstance();\n if (wu) {\n resolve(wu);\n return;\n }\n\n const startTime = Date.now();\n\n const handleWuReady = () => {\n cleanup();\n resolve(getWuInstance());\n };\n\n window.addEventListener('wu:ready', handleWuReady);\n window.addEventListener('wu:app:ready', handleWuReady);\n\n const checkInterval = setInterval(() => {\n const wu = getWuInstance();\n if (wu) {\n cleanup();\n resolve(wu);\n return;\n }\n\n if (Date.now() - startTime > timeout) {\n cleanup();\n reject(new Error(`Wu Framework not found after ${timeout}ms`));\n }\n }, 200);\n\n function cleanup() {\n clearInterval(checkInterval);\n window.removeEventListener('wu:ready', handleWuReady);\n window.removeEventListener('wu:app:ready', handleWuReady);\n }\n });\n}\n\n/**\n * Registra una app Alpine.js como microfrontend\n *\n * @param {string} appName - Nombre unico del microfrontend\n * @param {Object} appConfig - Configuracion de la app Alpine\n * @param {string} appConfig.template - HTML string con directivas Alpine (x-data, x-bind, etc.)\n * @param {Function} appConfig.data - Funcion que retorna el objeto de datos Alpine\n * @param {Object} [options] - Opciones adicionales\n * @param {Function} [options.onMount] - Callback despues de montar\n * @param {Function} [options.onUnmount] - Callback antes de desmontar\n * @param {boolean} [options.standalone=true] - Permitir ejecucion standalone\n * @param {string} [options.standaloneContainer='#app'] - Selector para modo standalone\n * @returns {Promise<boolean>} true si el registro fue exitoso\n */\nasync function register(appName, appConfig, options = {}) {\n const { template, data } = appConfig;\n\n const {\n onMount = null,\n onUnmount = null,\n standalone = true,\n standaloneContainer = '#app'\n } = options;\n\n if (!template || typeof template !== 'string') {\n throw new Error(`[WuAlpine] template (HTML string) is required for ${appName}`);\n }\n\n // Mount function\n const mountApp = (container) => {\n if (!container) {\n console.error(`[WuAlpine] Mount failed for ${appName}: container is null`);\n return;\n }\n\n // Prevent double-mount\n if (adapterState.apps.has(appName)) {\n console.warn(`[WuAlpine] ${appName} already mounted, unmounting first`);\n unmountApp();\n }\n\n try {\n container.innerHTML = '';\n\n // Inject template HTML\n container.innerHTML = template;\n\n // Initialize Alpine on this subtree\n const Alpine = window.Alpine;\n if (Alpine) {\n if (data && typeof data === 'function') {\n Alpine.data('app', data);\n }\n Alpine.initTree(container);\n } else {\n console.warn(`[WuAlpine] window.Alpine not found - template inserted but not initialized`);\n }\n\n adapterState.apps.set(appName, { container, config: appConfig });\n\n console.log(`[WuAlpine] ${appName} mounted successfully`);\n\n if (onMount) {\n onMount(container);\n }\n } catch (error) {\n console.error(`[WuAlpine] Mount error for ${appName}:`, error);\n throw error;\n }\n };\n\n // Unmount function\n const unmountApp = (container) => {\n const appData = adapterState.apps.get(appName);\n\n if (appData) {\n try {\n if (onUnmount) {\n onUnmount(appData.container);\n }\n\n // Tear down Alpine reactivity on this subtree\n const Alpine = window.Alpine;\n if (Alpine && typeof Alpine.destroyTree === 'function') {\n Alpine.destroyTree(appData.container);\n }\n\n appData.container.innerHTML = '';\n adapterState.apps.delete(appName);\n\n console.log(`[WuAlpine] ${appName} unmounted successfully`);\n } catch (error) {\n console.error(`[WuAlpine] Unmount error for ${appName}:`, error);\n }\n }\n\n if (container) {\n container.innerHTML = '';\n }\n };\n\n // Register with Wu Framework or fall back to standalone\n try {\n const wu = await waitForWu(3000);\n\n wu.define(appName, {\n mount: mountApp,\n unmount: unmountApp\n });\n\n console.log(`[WuAlpine] ${appName} registered with Wu Framework`);\n return true;\n\n } catch (error) {\n console.warn(`[WuAlpine] Wu Framework not available for ${appName}`);\n\n if (standalone) {\n const containerElement = document.querySelector(standaloneContainer);\n\n if (containerElement) {\n console.log(`[WuAlpine] Running ${appName} in standalone mode`);\n mountApp(containerElement);\n return true;\n }\n }\n\n return false;\n }\n}\n\n// Public API\nexport const wuAlpine = {\n register,\n getWuInstance,\n waitForWu\n};\n\nexport { register, getWuInstance, waitForWu };\nexport default wuAlpine;\n"],"names":["adapterState","apps","Map","getWuInstance","window","wu","parent","top","waitForWu","timeout","Promise","resolve","reject","startTime","Date","now","handleWuReady","cleanup","addEventListener","checkInterval","setInterval","Error","clearInterval","removeEventListener","async","register","appName","appConfig","options","template","data","onMount","onUnmount","standalone","standaloneContainer","mountApp","container","has","console","warn","unmountApp","innerHTML","Alpine","initTree","set","config","log","error","appData","get","destroyTree","delete","define","mount","unmount","containerElement","document","querySelector","wuAlpine"],"mappings":"AAiCA,MAAMA,EAAe,CACnBC,KAAM,IAAIC,KAMZ,SAASC,IACP,MAAsB,oBAAXC,OAA+B,KAEnCA,OAAOC,IACTD,OAAOE,QAAQD,IACfD,OAAOG,KAAKF,IACZ,IACP,CAKA,SAASG,EAAUC,EAAU,KAC3B,OAAO,IAAIC,QAAQ,CAACC,EAASC,KAC3B,MAAMP,EAAKF,IACX,GAAIE,EAEF,YADAM,EAAQN,GAIV,MAAMQ,EAAYC,KAAKC,MAEjBC,EAAgB,KACpBC,IACAN,EAAQR,MAGVC,OAAOc,iBAAiB,WAAYF,GACpCZ,OAAOc,iBAAiB,eAAgBF,GAExC,MAAMG,EAAgBC,YAAY,KAChC,MAAMf,EAAKF,IACX,GAAIE,EAGF,OAFAY,SACAN,EAAQN,GAINS,KAAKC,MAAQF,EAAYJ,IAC3BQ,IACAL,EAAO,IAAIS,MAAM,gCAAgCZ,UAElD,KAEH,SAASQ,IACPK,cAAcH,GACdf,OAAOmB,oBAAoB,WAAYP,GACvCZ,OAAOmB,oBAAoB,eAAgBP,EAC7C,GAEJ,CAgBAQ,eAAeC,EAASC,EAASC,EAAWC,EAAU,CAAA,GACpD,MAAMC,SAAEA,EAAQC,KAAEA,GAASH,GAErBI,QACJA,EAAU,KAAIC,UACdA,EAAY,KAAIC,WAChBA,GAAa,EAAIC,oBACjBA,EAAsB,QACpBN,EAEJ,IAAKC,GAAgC,iBAAbA,EACtB,MAAM,IAAIR,MAAM,qDAAqDK,KAIvE,MAAMS,EAAYC,IAChB,GAAKA,EAAL,CAMIpC,EAAaC,KAAKoC,IAAIX,KACxBY,QAAQC,KAAK,cAAcb,uCAC3Bc,KAGF,IACEJ,EAAUK,UAAY,GAGtBL,EAAUK,UAAYZ,EAGtB,MAAMa,EAAStC,OAAOsC,OAClBA,GACEZ,GAAwB,mBAATA,GACjBY,EAAOZ,KAAK,MAAOA,GAErBY,EAAOC,SAASP,IAEhBE,QAAQC,KAAK,8EAGfvC,EAAaC,KAAK2C,IAAIlB,EAAS,CAAEU,YAAWS,OAAQlB,IAEpDW,QAAQQ,IAAI,cAAcpB,0BAEtBK,GACFA,EAAQK,EAEZ,CAAE,MAAOW,GAEP,MADAT,QAAQS,MAAM,8BAA8BrB,KAAYqB,GAClDA,CACR,CAnCA,MAFET,QAAQS,MAAM,+BAA+BrB,yBAyC3Cc,EAAcJ,IAClB,MAAMY,EAAUhD,EAAaC,KAAKgD,IAAIvB,GAEtC,GAAIsB,EACF,IACMhB,GACFA,EAAUgB,EAAQZ,WAIpB,MAAMM,EAAStC,OAAOsC,OAClBA,GAAwC,mBAAvBA,EAAOQ,aAC1BR,EAAOQ,YAAYF,EAAQZ,WAG7BY,EAAQZ,UAAUK,UAAY,GAC9BzC,EAAaC,KAAKkD,OAAOzB,GAEzBY,QAAQQ,IAAI,cAAcpB,2BAC5B,CAAE,MAAOqB,GACPT,QAAQS,MAAM,gCAAgCrB,KAAYqB,EAC5D,CAGEX,IACFA,EAAUK,UAAY,KAK1B,IASE,aARiBjC,EAAU,MAExB4C,OAAO1B,EAAS,CACjB2B,MAAOlB,EACPmB,QAASd,IAGXF,QAAQQ,IAAI,cAAcpB,mCACnB,CAET,CAAE,MAAOqB,GAGP,GAFAT,QAAQC,KAAK,6CAA6Cb,KAEtDO,EAAY,CACd,MAAMsB,EAAmBC,SAASC,cAAcvB,GAEhD,GAAIqB,EAGF,OAFAjB,QAAQQ,IAAI,sBAAsBpB,wBAClCS,EAASoB,IACF,CAEX,CAEA,OAAO,CACT,CACF,CAGY,MAACG,EAAW,CACtBjC,WACAtB,gBACAK"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function n(n){return import(n)}const e={apps:new Map,platformRef:null,initialized:!1};function t(){return"undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null}function o(n=5e3){return new Promise((e,o)=>{const r=t();if(r)return void e(r);const a=Date.now(),l=()=>{i(),e(t())};window.addEventListener("wu:ready",l),window.addEventListener("wu:app:ready",l);const s=setInterval(()=>{const r=t();if(r)return i(),void e(r);Date.now()-a>n&&(i(),o(new Error(`Wu Framework not found after ${n}ms`)))},200);function i(){clearInterval(s),window.removeEventListener("wu:ready",l),window.removeEventListener("wu:app:ready",l)}})}async function r(t,r,a={}){const{platformFactory:l=null,providers:s=[],onMount:i=null,onUnmount:u=null,standalone:c=!0,standaloneContainer:m="#root",rootSelector:d="app-root"}=a,p=async o=>{if(o){e.apps.has(t)&&(console.warn(`[WuAngular] ${t} already mounted, unmounting first`),await w());try{const a=document.createElement(d);let u;if(a.setAttribute("data-wu-angular-root",t),o.innerHTML="",o.appendChild(a),l)u=l;else try{u=(await n("@angular/platform-browser-dynamic")).platformBrowserDynamic}catch(n){if(!window.ng?.platformBrowserDynamic)throw new Error("platformBrowserDynamic not available. Please provide it via options.platformFactory");u=window.ng.platformBrowserDynamic}const c=u(s),m=await c.bootstrapModule(r);e.apps.set(t,{platformRef:c,moduleRef:m,container:o,rootElement:a}),console.log(`[WuAngular] ✅ ${t} mounted successfully`),i&&i(o,m)}catch(n){throw console.error(`[WuAngular] Mount error for ${t}:`,n),n}}else console.error(`[WuAngular] Mount failed for ${t}: container is null`)},w=async n=>{const o=e.apps.get(t);if(o)try{u&&u(o.container,o.moduleRef),o.moduleRef&&o.moduleRef.destroy(),o.platformRef&&o.platformRef.destroy(),o.rootElement&&o.rootElement.parentNode&&o.rootElement.parentNode.removeChild(o.rootElement),e.apps.delete(t),console.log(`[WuAngular] ✅ ${t} unmounted successfully`)}catch(n){console.error(`[WuAngular] Unmount error for ${t}:`,n)}n&&(n.innerHTML="")};try{return(await o(3e3)).define(t,{mount:p,unmount:w}),console.log(`[WuAngular] ✅ ${t} registered with Wu Framework`),!0}catch(n){if(console.warn(`[WuAngular] Wu Framework not available for ${t}`),c){const n=document.querySelector(m);if(n)return console.log(`[WuAngular] Running ${t} in standalone mode`),await p(n),!0;console.warn(`[WuAngular] Standalone container ${m} not found`)}return!1}}async function a(t,r,a={}){const{appConfig:l={},onMount:s=null,onUnmount:i=null,standalone:u=!0,standaloneContainer:c="#root",createApplication:m=null,createComponent:d=null,provideZoneChangeDetection:p=null}=a,w=async o=>{if(o){e.apps.has(t)&&(console.warn(`[WuAngular] ${t} already mounted, unmounting first`),await g());try{let a=m,i=d,u=p;if(!a)try{a=(await n("@angular/platform-browser")).createApplication;const e=await n("@angular/core");i=e.createComponent,u=e.provideZoneChangeDetection}catch(n){if(!window.ng?.createApplication)throw new Error("Angular APIs not available. Pass createApplication, createComponent via options, or ensure @angular/platform-browser is resolvable. See docs for example.");a=window.ng.createApplication,i=window.ng.createComponent,u=window.ng.provideZoneChangeDetection}const c=[...l.providers||[]];u&&c.push(u({eventCoalescing:!0}));const w=await a({providers:c});o.innerHTML="";const g=r.ɵcmp?.selectors?.[0]?.[0]||r.__annotations__?.[0]?.selector||"app-root",f=document.createElement(g);o.appendChild(f);const h=i(r,{environmentInjector:w.injector,hostElement:f});w.attachView(h.hostView),e.apps.set(t,{appRef:w,compRef:h,container:o,hostElement:f,isStandalone:!0}),console.log(`[WuAngular] ✅ ${t} (standalone) mounted successfully`),s&&s(o,w)}catch(n){throw console.error(`[WuAngular] Mount error for ${t}:`,n),n}}else console.error(`[WuAngular] Mount failed for ${t}: container is null`)},g=async n=>{const o=e.apps.get(t);if(o)try{i&&i(o.container,o.appRef),o.compRef&&o.compRef.destroy(),o.appRef&&o.appRef.destroy(),e.apps.delete(t),console.log(`[WuAngular] ✅ ${t} (standalone) unmounted successfully`)}catch(n){console.error(`[WuAngular] Unmount error for ${t}:`,n)}n&&(n.innerHTML="")};try{return(await o(3e3)).define(t,{mount:w,unmount:g}),console.log(`[WuAngular] ✅ ${t} (standalone) registered with Wu Framework`),!0}catch(n){if(console.warn(`[WuAngular] Wu Framework not available for ${t}`),u){const n=document.querySelector(c);if(n)return console.log(`[WuAngular] Running ${t} in standalone mode`),await w(n),!0}return!1}}async function l(t,r,a={}){const{elementTag:l=`${t}-element`,appConfig:s={},onMount:i=null,onUnmount:u=null,standalone:c=!0,standaloneContainer:m="#root"}=a;let d=!1;const p=async o=>{if(o)try{await(async()=>{if(d)return!0;try{const[{createApplication:o},{createCustomElement:a}]=await Promise.all([n("@angular/platform-browser"),n("@angular/elements")]),i=await o(s),u=a(r,{injector:i.injector});return customElements.get(l)||(customElements.define(l,u),console.log(`[WuAngular] ✅ Custom element registered: ${l}`)),d=!0,e.apps.set(`${t}:element`,{app:i,elementTag:l,CustomElement:u}),!0}catch(n){throw console.error("[WuAngular] Failed to initialize Angular Element:",n),n}})();const a=document.createElement(l);return a.setAttribute("data-wu-angular-element",t),o.innerHTML="",o.appendChild(a),e.apps.set(t,{element:a,container:o,elementTag:l}),console.log(`[WuAngular] ✅ ${t} (element) mounted successfully`),i&&i(o,a),a}catch(n){throw console.error(`[WuAngular] Mount error for ${t}:`,n),n}else console.error(`[WuAngular] Mount failed for ${t}: container is null`)},w=async n=>{const o=e.apps.get(t);if(o)try{u&&u(o.container,o.element),o.element&&o.element.parentNode&&o.element.remove(),e.apps.delete(t),console.log(`[WuAngular] ✅ ${t} (element) unmounted successfully`)}catch(n){console.error(`[WuAngular] Unmount error for ${t}:`,n)}n&&(n.innerHTML="")};try{return(await o(3e3)).define(t,{mount:p,unmount:w}),console.log(`[WuAngular] ✅ ${t} (element) registered with Wu Framework`),!0}catch(n){if(console.warn(`[WuAngular] Wu Framework not available for ${t}`),c){const n=document.querySelector(m);if(n)return console.log(`[WuAngular] Running ${t} in standalone mode`),await p(n),!0}return!1}}function s(){const n=[];return{emit:(n,e,o)=>{const r=t();r?.eventBus?r.eventBus.emit(n,e,o):console.warn("[WuService] Wu Framework not available")},on:(e,o)=>{const r=t();if(r?.eventBus){const t=r.eventBus.on(e,o);return n.push(t),t}return console.warn("[WuService] Wu Framework not available"),()=>{}},once:(n,e)=>{const o=t();return o?.eventBus?o.eventBus.once(n,e):()=>{}},off:(n,e)=>{const o=t();o?.eventBus&&o.eventBus.off(n,e)},getState:n=>{const e=t();return e?.store?.get(n)||null},setState:(n,e)=>{const o=t();o?.store&&o.store.set(n,e)},onStateChange:(e,o)=>{const r=t();if(r?.store){const t=r.store.on(e,o);return n.push(t),t}return()=>{}},destroy:()=>{n.forEach(n=>n()),n.length=0},get wu(){return t()}}}function i(){return{selector:"wu-slot",template:'\n <div\n #container\n class="wu-slot"\n [class.wu-slot-loading]="loading"\n [class.wu-slot-error]="error"\n [attr.data-wu-app]="name"\n [attr.data-wu-url]="url"\n style="min-height: 100px; position: relative;">\n\n <div *ngIf="error" class="wu-slot-error-message"\n style="padding: 1rem; border: 1px solid #f5c6cb; border-radius: 4px; background: #f8d7da; color: #721c24;">\n <strong>Error loading {{ name }}</strong>\n <p style="margin: 0.5rem 0 0 0;">{{ error }}</p>\n </div>\n\n <div *ngIf="loading && !error" class="wu-slot-loading-message"\n style="display: flex; align-items: center; justify-content: center; padding: 2rem; color: #666;">\n {{ fallbackText || \'Loading \' + name + \'...\' }}\n </div>\n </div>\n ',styles:["\n .wu-slot {\n width: 100%;\n min-height: 100px;\n }\n "],methods:{async ngOnInit(){await this.mountMicrofrontend()},ngOnDestroy(){this.unmountMicrofrontend()},async mountMicrofrontend(){try{this.loading=!0,this.error=null;const n=t();if(!n)throw new Error("Wu Framework not initialized");const e=`wu-slot-${this.name}-${Date.now()}`,o=document.createElement("div");o.id=e,o.style.width="100%",o.style.height="100%",this.container.nativeElement.innerHTML="",this.container.nativeElement.appendChild(o);const r=n.app(this.name,{url:this.url,container:`#${e}`,autoInit:!0});this.appInstance=r,await r.mount(),this.loading=!1,this.load.emit({name:this.name,url:this.url})}catch(n){console.error(`[WuSlot] Error loading ${this.name}:`,n),this.error=n.message||"Failed to load microfrontend",this.loading=!1,this.errorEvent.emit(n)}},async unmountMicrofrontend(){if(this.appInstance){try{await this.appInstance.unmount()}catch(n){console.warn(`[WuSlot] Error unmounting ${this.name}:`,n)}this.appInstance=null}}}}}function u(){return{imports:["CommonModule"],declarations:["WuSlotComponent"],exports:["WuSlotComponent"]}}function c(...n){throw new Error("[WuAngular] AI module not available. Install wu-framework AI extension.")}const m={register:r,registerStandalone:a,registerElement:l,createWuService:s,createWuSlotComponent:i,getWuSlotModuleConfig:u,createWuAIService:c,getWuInstance:t,waitForWu:o};export{c as createWuAIService,s as createWuService,i as createWuSlotComponent,m as default,t as getWuInstance,u as getWuSlotModuleConfig,r as register,l as registerElement,a as registerStandalone,o as waitForWu,m as wuAngular};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/adapters/angular/index.js"],"sourcesContent":["/**\r\n * 🚀 WU-FRAMEWORK ANGULAR ADAPTER\r\n *\r\n * Integrates Angular (14+) with Wu Framework as microfrontends.\r\n * Supports NgModule-based apps, standalone components, and Angular Elements.\r\n * Works inside Shadow DOM (wu-framework's default isolation mode).\r\n *\r\n * ## Quick Start — Standalone Component (recommended)\r\n *\r\n * ```ts\r\n * // main.ts\r\n * import 'zone.js';\r\n * import '@angular/compiler'; // JIT mode (no AOT plugin needed)\r\n * import { createApplication } from '@angular/platform-browser';\r\n * import { createComponent, provideZoneChangeDetection } from '@angular/core';\r\n * import { wuAngular } from 'wu-framework/adapters/angular';\r\n * import { AppComponent } from './app/app.component';\r\n *\r\n * wuAngular.registerStandalone('my-app', AppComponent, {\r\n * createApplication, // pass Angular APIs to avoid bundler issues\r\n * createComponent,\r\n * provideZoneChangeDetection,\r\n * });\r\n * ```\r\n *\r\n * ## Using Wu Events & Store inside Angular\r\n *\r\n * ```ts\r\n * import { createWuService } from 'wu-framework/adapters/angular';\r\n *\r\n * @Component({ ... })\r\n * export class MyComponent implements OnInit, OnDestroy {\r\n * private wu = createWuService();\r\n *\r\n * ngOnInit() {\r\n * this.wu.on('some:event', (data) => { ... });\r\n * const user = this.wu.getState('user');\r\n * }\r\n *\r\n * ngOnDestroy() {\r\n * this.wu.destroy(); // cleans up all subscriptions\r\n * }\r\n * }\r\n * ```\r\n *\r\n * ## Vite Setup (no AnalogJS required)\r\n *\r\n * ```ts\r\n * // vite.config.ts\r\n * import { defineConfig } from 'vite';\r\n * export default defineConfig({\r\n * server: { port: 5008, cors: true },\r\n * esbuild: { target: 'es2022' },\r\n * });\r\n * ```\r\n *\r\n * ```json\r\n * // tsconfig.json — enable decorators for esbuild\r\n * { \"compilerOptions\": { \"experimentalDecorators\": true, \"useDefineForClassFields\": false } }\r\n * ```\r\n *\r\n * ## Why pass Angular APIs as options?\r\n *\r\n * When wu-framework is linked via `file:` or a monorepo, bundlers (Vite, Rollup)\r\n * resolve imports relative to the adapter's source file — NOT your app's node_modules.\r\n * Passing `createApplication`, `createComponent`, etc. from your own imports ensures\r\n * the bundler resolves them from your app's dependencies. The adapter falls back to\r\n * dynamic imports for environments where this isn't an issue (Webpack, non-bundled).\r\n */\r\n\r\n/**\r\n * Dynamic import helper — passes the module path through a function parameter\r\n * so that bundlers (Vite, Rollup, Webpack) cannot statically resolve it.\r\n * This is necessary because Angular dependencies (@angular/platform-browser-dynamic,\r\n * @angular/elements, etc.) are optional and may not be installed.\r\n */\r\nfunction _optionalImport(modulePath) {\r\n return import(/* @vite-ignore */ modulePath);\r\n}\r\n\r\n// Estado global del adapter\r\nconst adapterState = {\r\n apps: new Map(),\r\n platformRef: null,\r\n initialized: false\r\n};\r\n\r\n/**\r\n * Obtiene la instancia de Wu Framework\r\n */\r\nfunction getWuInstance() {\r\n if (typeof window === 'undefined') return null;\r\n\r\n return window.wu\r\n || window.parent?.wu\r\n || window.top?.wu\r\n || null;\r\n}\r\n\r\n/**\r\n * Espera a que Wu Framework esté disponible\r\n */\r\nfunction waitForWu(timeout = 5000) {\r\n return new Promise((resolve, reject) => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n\r\n const handleWuReady = () => {\r\n cleanup();\r\n resolve(getWuInstance());\r\n };\r\n\r\n window.addEventListener('wu:ready', handleWuReady);\r\n window.addEventListener('wu:app:ready', handleWuReady);\r\n\r\n const checkInterval = setInterval(() => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n cleanup();\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n if (Date.now() - startTime > timeout) {\r\n cleanup();\r\n reject(new Error(`Wu Framework not found after ${timeout}ms`));\r\n }\r\n }, 200);\r\n\r\n function cleanup() {\r\n clearInterval(checkInterval);\r\n window.removeEventListener('wu:ready', handleWuReady);\r\n window.removeEventListener('wu:app:ready', handleWuReady);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Register an NgModule-based Angular app as a microfrontend.\r\n *\r\n * NOTE: Uses platformBrowserDynamic + bootstrapModule which does NOT work inside\r\n * Shadow DOM (it calls document.querySelector internally). For Shadow DOM compatibility,\r\n * use registerStandalone() instead — it uses createApplication + createComponent with\r\n * an explicit hostElement, which works everywhere.\r\n *\r\n * @param {string} appName - Unique name for the microfrontend\r\n * @param {Type<any>} AppModule - Main Angular module (e.g. AppModule)\r\n * @param {Object} options\r\n * @param {Function} options.platformFactory - platformBrowserDynamic (pass it to avoid bundler issues)\r\n * @param {Array} options.providers - Additional bootstrap providers\r\n * @param {Function} options.onMount - Called after mount\r\n * @param {Function} options.onUnmount - Called before unmount\r\n * @param {boolean} options.standalone - Allow standalone fallback (default: true)\r\n * @param {string} options.standaloneContainer - Selector for standalone mode (default: '#root')\r\n * @param {string} options.rootSelector - Root component selector (default: 'app-root')\r\n *\r\n * @example\r\n * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\r\n * import { wuAngular } from 'wu-framework/adapters/angular';\r\n * import { AppModule } from './app/app.module';\r\n *\r\n * wuAngular.register('my-app', AppModule, {\r\n * platformFactory: platformBrowserDynamic, // pass to avoid bundler issues\r\n * });\r\n */\r\nasync function register(appName, AppModule, options = {}) {\r\n const {\r\n platformFactory = null,\r\n providers = [],\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#root',\r\n rootSelector = 'app-root'\r\n } = options;\r\n\r\n // Función de mount interna\r\n const mountApp = async (container) => {\r\n if (!container) {\r\n console.error(`[WuAngular] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n // Evitar doble mount\r\n if (adapterState.apps.has(appName)) {\r\n console.warn(`[WuAngular] ${appName} already mounted, unmounting first`);\r\n await unmountApp();\r\n }\r\n\r\n try {\r\n // Crear elemento root para Angular\r\n const appElement = document.createElement(rootSelector);\r\n appElement.setAttribute('data-wu-angular-root', appName);\r\n container.innerHTML = '';\r\n container.appendChild(appElement);\r\n\r\n // Obtener platformBrowserDynamic\r\n let platform;\r\n if (platformFactory) {\r\n platform = platformFactory;\r\n } else {\r\n // Intentar import dinámico\r\n try {\r\n const platformModule = await _optionalImport('@angular/platform-browser-dynamic');\r\n platform = platformModule.platformBrowserDynamic;\r\n } catch (e) {\r\n // Intentar desde window\r\n if (window.ng?.platformBrowserDynamic) {\r\n platform = window.ng.platformBrowserDynamic;\r\n } else {\r\n throw new Error('platformBrowserDynamic not available. Please provide it via options.platformFactory');\r\n }\r\n }\r\n }\r\n\r\n // Bootstrap del módulo\r\n const platformRef = platform(providers);\r\n const moduleRef = await platformRef.bootstrapModule(AppModule);\r\n\r\n // Guardar referencias\r\n adapterState.apps.set(appName, {\r\n platformRef,\r\n moduleRef,\r\n container,\r\n rootElement: appElement\r\n });\r\n\r\n console.log(`[WuAngular] ✅ ${appName} mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, moduleRef);\r\n }\r\n } catch (error) {\r\n console.error(`[WuAngular] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de unmount interna\r\n const unmountApp = async (container) => {\r\n const instance = adapterState.apps.get(appName);\r\n\r\n if (instance) {\r\n try {\r\n if (onUnmount) {\r\n onUnmount(instance.container, instance.moduleRef);\r\n }\r\n\r\n // Destruir el módulo\r\n if (instance.moduleRef) {\r\n instance.moduleRef.destroy();\r\n }\r\n\r\n // Destruir la plataforma\r\n if (instance.platformRef) {\r\n instance.platformRef.destroy();\r\n }\r\n\r\n // Limpiar DOM\r\n if (instance.rootElement && instance.rootElement.parentNode) {\r\n instance.rootElement.parentNode.removeChild(instance.rootElement);\r\n }\r\n\r\n adapterState.apps.delete(appName);\r\n\r\n console.log(`[WuAngular] ✅ ${appName} unmounted successfully`);\r\n } catch (error) {\r\n console.error(`[WuAngular] Unmount error for ${appName}:`, error);\r\n }\r\n }\r\n\r\n // Limpiar container si se proporciona\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n // Intentar registrar con Wu Framework\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n console.log(`[WuAngular] ✅ ${appName} registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n console.warn(`[WuAngular] Wu Framework not available for ${appName}`);\r\n\r\n // Modo standalone si está habilitado\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n\r\n if (containerElement) {\r\n console.log(`[WuAngular] Running ${appName} in standalone mode`);\r\n await mountApp(containerElement);\r\n return true;\r\n } else {\r\n console.warn(`[WuAngular] Standalone container ${standaloneContainer} not found`);\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Registra un componente Angular standalone como microfrontend (Angular 14+)\r\n *\r\n * @param {string} appName - Nombre único del microfrontend\r\n * @param {Type<any>} RootComponent - Componente standalone principal\r\n * @param {Object} options - Opciones adicionales\r\n * @param {ApplicationConfig} options.appConfig - Configuración de la aplicación\r\n * @param {Function} options.onMount - Callback después de montar\r\n * @param {Function} options.onUnmount - Callback antes de desmontar\r\n * @param {boolean} options.standalone - Permitir ejecución standalone (default: true)\r\n * @param {string} options.standaloneContainer - Selector para modo standalone (default: '#root')\r\n * @param {Function} options.createApplication - createApplication from @angular/platform-browser (recommended to avoid bundler issues)\r\n * @param {Function} options.createComponent - createComponent from @angular/core\r\n * @param {Function} options.provideZoneChangeDetection - provideZoneChangeDetection from @angular/core\r\n *\r\n * @example\r\n * // Angular 14+ con standalone components\r\n * import { AppComponent } from './app/app.component';\r\n * import { createApplication } from '@angular/platform-browser';\r\n * import { createComponent, provideZoneChangeDetection } from '@angular/core';\r\n *\r\n * wuAngular.registerStandalone('my-app', AppComponent, {\r\n * createApplication,\r\n * createComponent,\r\n * provideZoneChangeDetection,\r\n * });\r\n */\r\nasync function registerStandalone(appName, RootComponent, options = {}) {\r\n const {\r\n appConfig = {},\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#root',\r\n createApplication: createApplicationOpt = null,\r\n createComponent: createComponentOpt = null,\r\n provideZoneChangeDetection: provideZoneChangeDetectionOpt = null\r\n } = options;\r\n\r\n // Función de mount para standalone components\r\n const mountApp = async (container) => {\r\n if (!container) {\r\n console.error(`[WuAngular] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n // Evitar doble mount\r\n if (adapterState.apps.has(appName)) {\r\n console.warn(`[WuAngular] ${appName} already mounted, unmounting first`);\r\n await unmountApp();\r\n }\r\n\r\n try {\r\n // Resolve Angular APIs: prefer options > dynamic import > window.ng\r\n let createApplicationFn = createApplicationOpt;\r\n let createComponentFn = createComponentOpt;\r\n let provideZoneChangeDetectionFn = provideZoneChangeDetectionOpt;\r\n\r\n if (!createApplicationFn) {\r\n try {\r\n const browserModule = await _optionalImport('@angular/platform-browser');\r\n createApplicationFn = browserModule.createApplication;\r\n const coreModule = await _optionalImport('@angular/core');\r\n createComponentFn = coreModule.createComponent;\r\n provideZoneChangeDetectionFn = coreModule.provideZoneChangeDetection;\r\n } catch (e) {\r\n if (window.ng?.createApplication) {\r\n createApplicationFn = window.ng.createApplication;\r\n createComponentFn = window.ng.createComponent;\r\n provideZoneChangeDetectionFn = window.ng.provideZoneChangeDetection;\r\n } else {\r\n throw new Error(\r\n 'Angular APIs not available. Pass createApplication, createComponent via options, ' +\r\n 'or ensure @angular/platform-browser is resolvable. See docs for example.'\r\n );\r\n }\r\n }\r\n }\r\n\r\n // Merge providers: add zone change detection if available\r\n const providers = [...(appConfig.providers || [])];\r\n if (provideZoneChangeDetectionFn) {\r\n providers.push(provideZoneChangeDetectionFn({ eventCoalescing: true }));\r\n }\r\n\r\n // Create Angular application\r\n const appRef = await createApplicationFn({ providers });\r\n\r\n // Create host element inside the container (Shadow DOM compatible)\r\n container.innerHTML = '';\r\n const selector = RootComponent.ɵcmp?.selectors?.[0]?.[0]\r\n || RootComponent.__annotations__?.[0]?.selector\r\n || 'app-root';\r\n const hostEl = document.createElement(selector);\r\n container.appendChild(hostEl);\r\n\r\n // Create and attach the component using hostElement (bypasses document.querySelector)\r\n const compRef = createComponentFn(RootComponent, {\r\n environmentInjector: appRef.injector,\r\n hostElement: hostEl,\r\n });\r\n appRef.attachView(compRef.hostView);\r\n\r\n // Guardar referencias\r\n adapterState.apps.set(appName, {\r\n appRef,\r\n compRef,\r\n container,\r\n hostElement: hostEl,\r\n isStandalone: true\r\n });\r\n\r\n console.log(`[WuAngular] ✅ ${appName} (standalone) mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, appRef);\r\n }\r\n } catch (error) {\r\n console.error(`[WuAngular] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de unmount para standalone\r\n const unmountApp = async (container) => {\r\n const instance = adapterState.apps.get(appName);\r\n\r\n if (instance) {\r\n try {\r\n if (onUnmount) {\r\n onUnmount(instance.container, instance.appRef);\r\n }\r\n\r\n // Destruir el componente\r\n if (instance.compRef) {\r\n instance.compRef.destroy();\r\n }\r\n\r\n // Destruir la aplicación\r\n if (instance.appRef) {\r\n instance.appRef.destroy();\r\n }\r\n\r\n adapterState.apps.delete(appName);\r\n\r\n console.log(`[WuAngular] ✅ ${appName} (standalone) unmounted successfully`);\r\n } catch (error) {\r\n console.error(`[WuAngular] Unmount error for ${appName}:`, error);\r\n }\r\n }\r\n\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n // Intentar registrar con Wu Framework\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n console.log(`[WuAngular] ✅ ${appName} (standalone) registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n console.warn(`[WuAngular] Wu Framework not available for ${appName}`);\r\n\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n\r\n if (containerElement) {\r\n console.log(`[WuAngular] Running ${appName} in standalone mode`);\r\n await mountApp(containerElement);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Register an Angular Elements (Web Component) as a microfrontend.\r\n * Requires @angular/elements to be installed.\r\n *\r\n * @param {string} appName - Unique microfrontend name\r\n * @param {Type<any>} Component - Angular standalone component\r\n * @param {Object} options\r\n * @param {string} options.elementTag - Custom element tag (default: `${appName}-element`)\r\n * @param {ApplicationConfig} options.appConfig - Angular application config\r\n * @param {Function} options.onMount - Called after mount\r\n * @param {Function} options.onUnmount - Called before unmount\r\n * @param {boolean} options.standalone - Allow standalone fallback (default: true)\r\n * @param {string} options.standaloneContainer - Selector for standalone mode (default: '#root')\r\n *\r\n * @example\r\n * import { wuAngular } from 'wu-framework/adapters/angular';\r\n * import { AppComponent } from './app/app.component';\r\n *\r\n * wuAngular.registerElement('mfe-angular', AppComponent, {\r\n * elementTag: 'mfe-angular-content',\r\n * });\r\n */\r\nasync function registerElement(appName, Component, options = {}) {\r\n const {\r\n elementTag = `${appName}-element`,\r\n appConfig = {},\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#root'\r\n } = options;\r\n\r\n let customElementRegistered = false;\r\n\r\n // Función para inicializar Angular Elements\r\n const initializeElement = async () => {\r\n if (customElementRegistered) return true;\r\n\r\n try {\r\n // Import dinámico de Angular\r\n const [{ createApplication }, { createCustomElement }] = await Promise.all([\r\n _optionalImport('@angular/platform-browser'),\r\n _optionalImport('@angular/elements')\r\n ]);\r\n\r\n // Crear aplicación Angular\r\n const app = await createApplication(appConfig);\r\n\r\n // Crear y registrar el custom element\r\n const CustomElement = createCustomElement(Component, { injector: app.injector });\r\n\r\n if (!customElements.get(elementTag)) {\r\n customElements.define(elementTag, CustomElement);\r\n console.log(`[WuAngular] ✅ Custom element registered: ${elementTag}`);\r\n }\r\n\r\n customElementRegistered = true;\r\n\r\n // Guardar referencia\r\n adapterState.apps.set(`${appName}:element`, {\r\n app,\r\n elementTag,\r\n CustomElement\r\n });\r\n\r\n return true;\r\n } catch (error) {\r\n console.error(`[WuAngular] Failed to initialize Angular Element:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de mount\r\n const mountApp = async (container) => {\r\n if (!container) {\r\n console.error(`[WuAngular] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n try {\r\n // Asegurar que el elemento está registrado\r\n await initializeElement();\r\n\r\n // Crear el elemento custom\r\n const element = document.createElement(elementTag);\r\n element.setAttribute('data-wu-angular-element', appName);\r\n\r\n // Limpiar y agregar al container\r\n container.innerHTML = '';\r\n container.appendChild(element);\r\n\r\n // Guardar referencia del mount\r\n adapterState.apps.set(appName, {\r\n element,\r\n container,\r\n elementTag\r\n });\r\n\r\n console.log(`[WuAngular] ✅ ${appName} (element) mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, element);\r\n }\r\n\r\n return element;\r\n } catch (error) {\r\n console.error(`[WuAngular] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de unmount\r\n const unmountApp = async (container) => {\r\n const instance = adapterState.apps.get(appName);\r\n\r\n if (instance) {\r\n try {\r\n if (onUnmount) {\r\n onUnmount(instance.container, instance.element);\r\n }\r\n\r\n // Remover elemento del DOM\r\n if (instance.element && instance.element.parentNode) {\r\n instance.element.remove();\r\n }\r\n\r\n adapterState.apps.delete(appName);\r\n\r\n console.log(`[WuAngular] ✅ ${appName} (element) unmounted successfully`);\r\n } catch (error) {\r\n console.error(`[WuAngular] Unmount error for ${appName}:`, error);\r\n }\r\n }\r\n\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n // Intentar registrar con Wu Framework\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n console.log(`[WuAngular] ✅ ${appName} (element) registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n console.warn(`[WuAngular] Wu Framework not available for ${appName}`);\r\n\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n\r\n if (containerElement) {\r\n console.log(`[WuAngular] Running ${appName} in standalone mode`);\r\n await mountApp(containerElement);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Creates a lightweight service for wu-framework events and store access.\r\n * Call destroy() in ngOnDestroy to clean up all subscriptions.\r\n *\r\n * @returns {{ emit, on, once, off, getState, setState, onStateChange, destroy, wu }}\r\n *\r\n * @example\r\n * import { createWuService } from 'wu-framework/adapters/angular';\r\n *\r\n * @Component({ selector: 'app-root', standalone: true, template: '...' })\r\n * export class AppComponent implements OnInit, OnDestroy {\r\n * private wu = createWuService();\r\n *\r\n * ngOnInit() {\r\n * this.wu.on('order:new', (e) => this.orders.push(e.data));\r\n * this.wu.onStateChange('theme.mode', (e) => this.theme = e.value);\r\n * const user = this.wu.getState('user');\r\n * }\r\n *\r\n * save() {\r\n * this.wu.setState('store.name', this.storeName);\r\n * this.wu.emit('settings:saved', { name: this.storeName });\r\n * }\r\n *\r\n * ngOnDestroy() {\r\n * this.wu.destroy(); // removes all on/onStateChange listeners\r\n * }\r\n * }\r\n */\r\nfunction createWuService() {\r\n const subscriptions = [];\r\n\r\n return {\r\n // Event Bus\r\n emit: (event, data, options) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n wu.eventBus.emit(event, data, options);\r\n } else {\r\n console.warn('[WuService] Wu Framework not available');\r\n }\r\n },\r\n\r\n on: (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n const unsubscribe = wu.eventBus.on(event, callback);\r\n subscriptions.push(unsubscribe);\r\n return unsubscribe;\r\n }\r\n console.warn('[WuService] Wu Framework not available');\r\n return () => {};\r\n },\r\n\r\n once: (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n return wu.eventBus.once(event, callback);\r\n }\r\n return () => {};\r\n },\r\n\r\n off: (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n wu.eventBus.off(event, callback);\r\n }\r\n },\r\n\r\n // Store\r\n getState: (path) => {\r\n const wu = getWuInstance();\r\n return wu?.store?.get(path) || null;\r\n },\r\n\r\n setState: (path, value) => {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n wu.store.set(path, value);\r\n }\r\n },\r\n\r\n onStateChange: (pattern, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n const unsubscribe = wu.store.on(pattern, callback);\r\n subscriptions.push(unsubscribe);\r\n return unsubscribe;\r\n }\r\n return () => {};\r\n },\r\n\r\n // Cleanup\r\n destroy: () => {\r\n subscriptions.forEach(unsub => unsub());\r\n subscriptions.length = 0;\r\n },\r\n\r\n // Access to raw Wu instance\r\n get wu() {\r\n return getWuInstance();\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Crea un componente Angular para cargar microfrontends (para el Shell)\r\n * Retorna la configuración del componente para ser usado con @Component\r\n *\r\n * @example\r\n * // wu-slot.component.ts\r\n * import { Component, Input, Output, EventEmitter } from '@angular/core';\r\n * import { createWuSlotComponent } from 'wu-framework/adapters/angular';\r\n *\r\n * const config = createWuSlotComponent();\r\n *\r\n * @Component({\r\n * selector: 'wu-slot',\r\n * template: config.template,\r\n * styles: config.styles\r\n * })\r\n * export class WuSlotComponent {\r\n * @Input() name!: string;\r\n * @Input() url!: string;\r\n * @Output() load = new EventEmitter();\r\n * @Output() error = new EventEmitter();\r\n *\r\n * // ... implement lifecycle methods from config.methods\r\n * }\r\n */\r\nfunction createWuSlotComponent() {\r\n return {\r\n selector: 'wu-slot',\r\n\r\n template: `\r\n <div\r\n #container\r\n class=\"wu-slot\"\r\n [class.wu-slot-loading]=\"loading\"\r\n [class.wu-slot-error]=\"error\"\r\n [attr.data-wu-app]=\"name\"\r\n [attr.data-wu-url]=\"url\"\r\n style=\"min-height: 100px; position: relative;\">\r\n\r\n <div *ngIf=\"error\" class=\"wu-slot-error-message\"\r\n style=\"padding: 1rem; border: 1px solid #f5c6cb; border-radius: 4px; background: #f8d7da; color: #721c24;\">\r\n <strong>Error loading {{ name }}</strong>\r\n <p style=\"margin: 0.5rem 0 0 0;\">{{ error }}</p>\r\n </div>\r\n\r\n <div *ngIf=\"loading && !error\" class=\"wu-slot-loading-message\"\r\n style=\"display: flex; align-items: center; justify-content: center; padding: 2rem; color: #666;\">\r\n {{ fallbackText || 'Loading ' + name + '...' }}\r\n </div>\r\n </div>\r\n `,\r\n\r\n styles: [`\r\n .wu-slot {\r\n width: 100%;\r\n min-height: 100px;\r\n }\r\n `],\r\n\r\n // Métodos para implementar en el componente\r\n methods: {\r\n async ngOnInit() {\r\n await this.mountMicrofrontend();\r\n },\r\n\r\n ngOnDestroy() {\r\n this.unmountMicrofrontend();\r\n },\r\n\r\n async mountMicrofrontend() {\r\n try {\r\n this.loading = true;\r\n this.error = null;\r\n\r\n const wu = getWuInstance();\r\n if (!wu) {\r\n throw new Error('Wu Framework not initialized');\r\n }\r\n\r\n // Crear container único\r\n const containerId = `wu-slot-${this.name}-${Date.now()}`;\r\n const innerContainer = document.createElement('div');\r\n innerContainer.id = containerId;\r\n innerContainer.style.width = '100%';\r\n innerContainer.style.height = '100%';\r\n\r\n this.container.nativeElement.innerHTML = '';\r\n this.container.nativeElement.appendChild(innerContainer);\r\n\r\n // Crear y montar la app\r\n const app = wu.app(this.name, {\r\n url: this.url,\r\n container: `#${containerId}`,\r\n autoInit: true\r\n });\r\n\r\n this.appInstance = app;\r\n await app.mount();\r\n\r\n this.loading = false;\r\n this.load.emit({ name: this.name, url: this.url });\r\n\r\n } catch (err) {\r\n console.error(`[WuSlot] Error loading ${this.name}:`, err);\r\n this.error = err.message || 'Failed to load microfrontend';\r\n this.loading = false;\r\n this.errorEvent.emit(err);\r\n }\r\n },\r\n\r\n async unmountMicrofrontend() {\r\n if (this.appInstance) {\r\n try {\r\n await this.appInstance.unmount();\r\n } catch (err) {\r\n console.warn(`[WuSlot] Error unmounting ${this.name}:`, err);\r\n }\r\n this.appInstance = null;\r\n }\r\n }\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Helper para crear un módulo Angular que exporta WuSlotComponent\r\n * Útil para shells que quieren usar <wu-slot> directamente\r\n */\r\nfunction getWuSlotModuleConfig() {\r\n return {\r\n imports: ['CommonModule'],\r\n declarations: ['WuSlotComponent'],\r\n exports: ['WuSlotComponent']\r\n };\r\n}\r\n\r\n// ============================================\r\n// AI INTEGRATION (placeholder — ai.js loaded on demand)\r\n// ============================================\r\nfunction createWuAIService(...args) {\r\n throw new Error('[WuAngular] AI module not available. Install wu-framework AI extension.');\r\n}\r\n\r\n// Named exports for direct imports (e.g. import { createWuService } from 'wu-framework/adapters/angular')\r\nexport { createWuService, register, registerStandalone, registerElement, createWuSlotComponent, getWuSlotModuleConfig, createWuAIService, getWuInstance, waitForWu };\r\n\r\n// API pública del adapter\r\nexport const wuAngular = {\r\n register,\r\n registerStandalone,\r\n registerElement,\r\n createWuService,\r\n createWuSlotComponent,\r\n getWuSlotModuleConfig,\r\n createWuAIService,\r\n getWuInstance,\r\n waitForWu\r\n};\r\n\r\nexport default wuAngular;\r\n"],"names":["_optionalImport","modulePath","import","adapterState","apps","Map","platformRef","initialized","getWuInstance","window","wu","parent","top","waitForWu","timeout","Promise","resolve","reject","startTime","Date","now","handleWuReady","cleanup","addEventListener","checkInterval","setInterval","Error","clearInterval","removeEventListener","async","register","appName","AppModule","options","platformFactory","providers","onMount","onUnmount","standalone","standaloneContainer","rootSelector","mountApp","container","has","console","warn","unmountApp","appElement","document","createElement","platform","setAttribute","innerHTML","appendChild","platformBrowserDynamic","e","ng","moduleRef","bootstrapModule","set","rootElement","log","error","instance","get","destroy","parentNode","removeChild","delete","define","mount","unmount","containerElement","querySelector","registerStandalone","RootComponent","appConfig","createApplication","createApplicationOpt","createComponent","createComponentOpt","provideZoneChangeDetection","provideZoneChangeDetectionOpt","createApplicationFn","createComponentFn","provideZoneChangeDetectionFn","coreModule","push","eventCoalescing","appRef","selector","selectors","__annotations__","hostEl","compRef","environmentInjector","injector","hostElement","attachView","hostView","isStandalone","registerElement","Component","elementTag","customElementRegistered","createCustomElement","all","app","CustomElement","customElements","initializeElement","element","remove","createWuService","subscriptions","emit","event","data","eventBus","on","callback","unsubscribe","once","off","getState","path","store","setState","value","onStateChange","pattern","forEach","unsub","length","createWuSlotComponent","template","styles","methods","ngOnInit","this","mountMicrofrontend","ngOnDestroy","unmountMicrofrontend","loading","containerId","name","innerContainer","id","style","width","height","nativeElement","url","autoInit","appInstance","load","err","message","errorEvent","getWuSlotModuleConfig","imports","declarations","exports","createWuAIService","args","wuAngular"],"mappings":"AA4EA,SAASA,EAAgBC,GACvB,OAAOC,OAA0BD,EACnC,CAGA,MAAME,EAAe,CACnBC,KAAM,IAAIC,IACVC,YAAa,KACbC,aAAa,GAMf,SAASC,IACP,MAAsB,oBAAXC,OAA+B,KAEnCA,OAAOC,IACTD,OAAOE,QAAQD,IACfD,OAAOG,KAAKF,IACZ,IACP,CAKA,SAASG,EAAUC,EAAU,KAC3B,OAAO,IAAIC,QAAQ,CAACC,EAASC,KAC3B,MAAMP,EAAKF,IACX,GAAIE,EAEF,YADAM,EAAQN,GAIV,MAAMQ,EAAYC,KAAKC,MAEjBC,EAAgB,KACpBC,IACAN,EAAQR,MAGVC,OAAOc,iBAAiB,WAAYF,GACpCZ,OAAOc,iBAAiB,eAAgBF,GAExC,MAAMG,EAAgBC,YAAY,KAChC,MAAMf,EAAKF,IACX,GAAIE,EAGF,OAFAY,SACAN,EAAQN,GAINS,KAAKC,MAAQF,EAAYJ,IAC3BQ,IACAL,EAAO,IAAIS,MAAM,gCAAgCZ,UAElD,KAEH,SAASQ,IACPK,cAAcH,GACdf,OAAOmB,oBAAoB,WAAYP,GACvCZ,OAAOmB,oBAAoB,eAAgBP,EAC7C,GAEJ,CA8BAQ,eAAeC,EAASC,EAASC,EAAWC,EAAU,CAAA,GACpD,MAAMC,gBACJA,EAAkB,KAAIC,UACtBA,EAAY,GAAEC,QACdA,EAAU,KAAIC,UACdA,EAAY,KAAIC,WAChBA,GAAa,EAAIC,oBACjBA,EAAsB,QAAOC,aAC7BA,EAAe,YACbP,EAGEQ,EAAWZ,MAAOa,IACtB,GAAKA,EAAL,CAMIvC,EAAaC,KAAKuC,IAAIZ,KACxBa,QAAQC,KAAK,eAAed,6CACtBe,KAGR,IAEE,MAAMC,EAAaC,SAASC,cAAcT,GAM1C,IAAIU,EACJ,GANAH,EAAWI,aAAa,uBAAwBpB,GAChDW,EAAUU,UAAY,GACtBV,EAAUW,YAAYN,GAIlBb,EACFgB,EAAWhB,OAGX,IAEEgB,SAD6BlD,EAAgB,sCACnBsD,sBAC5B,CAAE,MAAOC,GAEP,IAAI9C,OAAO+C,IAAIF,uBAGb,MAAM,IAAI5B,MAAM,uFAFhBwB,EAAWzC,OAAO+C,GAAGF,sBAIzB,CAIF,MAAMhD,EAAc4C,EAASf,GACvBsB,QAAkBnD,EAAYoD,gBAAgB1B,GAGpD7B,EAAaC,KAAKuD,IAAI5B,EAAS,CAC7BzB,cACAmD,YACAf,YACAkB,YAAab,IAGfH,QAAQiB,IAAI,iBAAiB9B,0BAEzBK,GACFA,EAAQM,EAAWe,EAEvB,CAAE,MAAOK,GAEP,MADAlB,QAAQkB,MAAM,+BAA+B/B,KAAY+B,GACnDA,CACR,CAtDA,MAFElB,QAAQkB,MAAM,gCAAgC/B,yBA4D5Ce,EAAajB,MAAOa,IACxB,MAAMqB,EAAW5D,EAAaC,KAAK4D,IAAIjC,GAEvC,GAAIgC,EACF,IACM1B,GACFA,EAAU0B,EAASrB,UAAWqB,EAASN,WAIrCM,EAASN,WACXM,EAASN,UAAUQ,UAIjBF,EAASzD,aACXyD,EAASzD,YAAY2D,UAInBF,EAASH,aAAeG,EAASH,YAAYM,YAC/CH,EAASH,YAAYM,WAAWC,YAAYJ,EAASH,aAGvDzD,EAAaC,KAAKgE,OAAOrC,GAEzBa,QAAQiB,IAAI,iBAAiB9B,2BAC/B,CAAE,MAAO+B,GACPlB,QAAQkB,MAAM,iCAAiC/B,KAAY+B,EAC7D,CAIEpB,IACFA,EAAUU,UAAY,KAK1B,IASE,aARiBvC,EAAU,MAExBwD,OAAOtC,EAAS,CACjBuC,MAAO7B,EACP8B,QAASzB,IAGXF,QAAQiB,IAAI,iBAAiB9B,mCACtB,CAET,CAAE,MAAO+B,GAIP,GAHAlB,QAAQC,KAAK,8CAA8Cd,KAGvDO,EAAY,CACd,MAAMkC,EAAmBxB,SAASyB,cAAclC,GAEhD,GAAIiC,EAGF,OAFA5B,QAAQiB,IAAI,uBAAuB9B,8BAC7BU,EAAS+B,IACR,EAEP5B,QAAQC,KAAK,oCAAoCN,cAErD,CAEA,OAAO,CACT,CACF,CA6BAV,eAAe6C,EAAmB3C,EAAS4C,EAAe1C,EAAU,CAAA,GAClE,MAAM2C,UACJA,EAAY,CAAA,EAAExC,QACdA,EAAU,KAAIC,UACdA,EAAY,KAAIC,WAChBA,GAAa,EAAIC,oBACjBA,EAAsB,QACtBsC,kBAAmBC,EAAuB,KAC1CC,gBAAiBC,EAAqB,KACtCC,2BAA4BC,EAAgC,MAC1DjD,EAGEQ,EAAWZ,MAAOa,IACtB,GAAKA,EAAL,CAMIvC,EAAaC,KAAKuC,IAAIZ,KACxBa,QAAQC,KAAK,eAAed,6CACtBe,KAGR,IAEE,IAAIqC,EAAsBL,EACtBM,EAAoBJ,EACpBK,EAA+BH,EAEnC,IAAKC,EACH,IAEEA,SAD4BnF,EAAgB,8BACR6E,kBACpC,MAAMS,QAAmBtF,EAAgB,iBACzCoF,EAAoBE,EAAWP,gBAC/BM,EAA+BC,EAAWL,0BAC5C,CAAE,MAAO1B,GACP,IAAI9C,OAAO+C,IAAIqB,kBAKb,MAAM,IAAInD,MACR,6JALFyD,EAAsB1E,OAAO+C,GAAGqB,kBAChCO,EAAoB3E,OAAO+C,GAAGuB,gBAC9BM,EAA+B5E,OAAO+C,GAAGyB,0BAO7C,CAIF,MAAM9C,EAAY,IAAKyC,EAAUzC,WAAa,IAC1CkD,GACFlD,EAAUoD,KAAKF,EAA6B,CAAEG,iBAAiB,KAIjE,MAAMC,QAAeN,EAAoB,CAAEhD,cAG3CO,EAAUU,UAAY,GACtB,MAAMsC,EAAWf,EAAc,MAAMgB,YAAY,KAAK,IACjDhB,EAAciB,kBAAkB,IAAIF,UACpC,WACCG,EAAS7C,SAASC,cAAcyC,GACtChD,EAAUW,YAAYwC,GAGtB,MAAMC,EAAUV,EAAkBT,EAAe,CAC/CoB,oBAAqBN,EAAOO,SAC5BC,YAAaJ,IAEfJ,EAAOS,WAAWJ,EAAQK,UAG1BhG,EAAaC,KAAKuD,IAAI5B,EAAS,CAC7B0D,SACAK,UACApD,YACAuD,YAAaJ,EACbO,cAAc,IAGhBxD,QAAQiB,IAAI,iBAAiB9B,uCAEzBK,GACFA,EAAQM,EAAW+C,EAEvB,CAAE,MAAO3B,GAEP,MADAlB,QAAQkB,MAAM,+BAA+B/B,KAAY+B,GACnDA,CACR,CA5EA,MAFElB,QAAQkB,MAAM,gCAAgC/B,yBAkF5Ce,EAAajB,MAAOa,IACxB,MAAMqB,EAAW5D,EAAaC,KAAK4D,IAAIjC,GAEvC,GAAIgC,EACF,IACM1B,GACFA,EAAU0B,EAASrB,UAAWqB,EAAS0B,QAIrC1B,EAAS+B,SACX/B,EAAS+B,QAAQ7B,UAIfF,EAAS0B,QACX1B,EAAS0B,OAAOxB,UAGlB9D,EAAaC,KAAKgE,OAAOrC,GAEzBa,QAAQiB,IAAI,iBAAiB9B,wCAC/B,CAAE,MAAO+B,GACPlB,QAAQkB,MAAM,iCAAiC/B,KAAY+B,EAC7D,CAGEpB,IACFA,EAAUU,UAAY,KAK1B,IASE,aARiBvC,EAAU,MAExBwD,OAAOtC,EAAS,CACjBuC,MAAO7B,EACP8B,QAASzB,IAGXF,QAAQiB,IAAI,iBAAiB9B,gDACtB,CAET,CAAE,MAAO+B,GAGP,GAFAlB,QAAQC,KAAK,8CAA8Cd,KAEvDO,EAAY,CACd,MAAMkC,EAAmBxB,SAASyB,cAAclC,GAEhD,GAAIiC,EAGF,OAFA5B,QAAQiB,IAAI,uBAAuB9B,8BAC7BU,EAAS+B,IACR,CAEX,CAEA,OAAO,CACT,CACF,CAwBA3C,eAAewE,EAAgBtE,EAASuE,EAAWrE,EAAU,CAAA,GAC3D,MAAMsE,WACJA,EAAa,GAAGxE,YAAiB6C,UACjCA,EAAY,CAAA,EAAExC,QACdA,EAAU,KAAIC,UACdA,EAAY,KAAIC,WAChBA,GAAa,EAAIC,oBACjBA,EAAsB,SACpBN,EAEJ,IAAIuE,GAA0B,EAG9B,MAsCM/D,EAAWZ,MAAOa,IACtB,GAAKA,EAKL,SA5CwBb,WACxB,GAAI2E,EAAyB,OAAO,EAEpC,IAEE,OAAO3B,kBAAEA,IAAqB4B,oBAAEA,UAA+B1F,QAAQ2F,IAAI,CACzE1G,EAAgB,6BAChBA,EAAgB,uBAIZ2G,QAAY9B,EAAkBD,GAG9BgC,EAAgBH,EAAoBH,EAAW,CAAEN,SAAUW,EAAIX,WAgBrE,OAdKa,eAAe7C,IAAIuC,KACtBM,eAAexC,OAAOkC,EAAYK,GAClChE,QAAQiB,IAAI,4CAA4C0C,MAG1DC,GAA0B,EAG1BrG,EAAaC,KAAKuD,IAAI,GAAG5B,YAAmB,CAC1C4E,MACAJ,aACAK,mBAGK,CACT,CAAE,MAAO9C,GAEP,MADAlB,QAAQkB,MAAM,oDAAqDA,GAC7DA,CACR,GAYQgD,GAGN,MAAMC,EAAU/D,SAASC,cAAcsD,GAoBvC,OAnBAQ,EAAQ5D,aAAa,0BAA2BpB,GAGhDW,EAAUU,UAAY,GACtBV,EAAUW,YAAY0D,GAGtB5G,EAAaC,KAAKuD,IAAI5B,EAAS,CAC7BgF,UACArE,YACA6D,eAGF3D,QAAQiB,IAAI,iBAAiB9B,oCAEzBK,GACFA,EAAQM,EAAWqE,GAGdA,CACT,CAAE,MAAOjD,GAEP,MADAlB,QAAQkB,MAAM,+BAA+B/B,KAAY+B,GACnDA,CACR,MAjCElB,QAAQkB,MAAM,gCAAgC/B,yBAqC5Ce,EAAajB,MAAOa,IACxB,MAAMqB,EAAW5D,EAAaC,KAAK4D,IAAIjC,GAEvC,GAAIgC,EACF,IACM1B,GACFA,EAAU0B,EAASrB,UAAWqB,EAASgD,SAIrChD,EAASgD,SAAWhD,EAASgD,QAAQ7C,YACvCH,EAASgD,QAAQC,SAGnB7G,EAAaC,KAAKgE,OAAOrC,GAEzBa,QAAQiB,IAAI,iBAAiB9B,qCAC/B,CAAE,MAAO+B,GACPlB,QAAQkB,MAAM,iCAAiC/B,KAAY+B,EAC7D,CAGEpB,IACFA,EAAUU,UAAY,KAK1B,IASE,aARiBvC,EAAU,MAExBwD,OAAOtC,EAAS,CACjBuC,MAAO7B,EACP8B,QAASzB,IAGXF,QAAQiB,IAAI,iBAAiB9B,6CACtB,CAET,CAAE,MAAO+B,GAGP,GAFAlB,QAAQC,KAAK,8CAA8Cd,KAEvDO,EAAY,CACd,MAAMkC,EAAmBxB,SAASyB,cAAclC,GAEhD,GAAIiC,EAGF,OAFA5B,QAAQiB,IAAI,uBAAuB9B,8BAC7BU,EAAS+B,IACR,CAEX,CAEA,OAAO,CACT,CACF,CA+BA,SAASyC,IACP,MAAMC,EAAgB,GAEtB,MAAO,CAELC,KAAM,CAACC,EAAOC,EAAMpF,KAClB,MAAMvB,EAAKF,IACPE,GAAI4G,SACN5G,EAAG4G,SAASH,KAAKC,EAAOC,EAAMpF,GAE9BW,QAAQC,KAAK,2CAIjB0E,GAAI,CAACH,EAAOI,KACV,MAAM9G,EAAKF,IACX,GAAIE,GAAI4G,SAAU,CAChB,MAAMG,EAAc/G,EAAG4G,SAASC,GAAGH,EAAOI,GAE1C,OADAN,EAAc3B,KAAKkC,GACZA,CACT,CAEA,OADA7E,QAAQC,KAAK,0CACN,QAGT6E,KAAM,CAACN,EAAOI,KACZ,MAAM9G,EAAKF,IACX,OAAIE,GAAI4G,SACC5G,EAAG4G,SAASI,KAAKN,EAAOI,GAE1B,QAGTG,IAAK,CAACP,EAAOI,KACX,MAAM9G,EAAKF,IACPE,GAAI4G,UACN5G,EAAG4G,SAASK,IAAIP,EAAOI,IAK3BI,SAAWC,IACT,MAAMnH,EAAKF,IACX,OAAOE,GAAIoH,OAAO9D,IAAI6D,IAAS,MAGjCE,SAAU,CAACF,EAAMG,KACf,MAAMtH,EAAKF,IACPE,GAAIoH,OACNpH,EAAGoH,MAAMnE,IAAIkE,EAAMG,IAIvBC,cAAe,CAACC,EAASV,KACvB,MAAM9G,EAAKF,IACX,GAAIE,GAAIoH,MAAO,CACb,MAAML,EAAc/G,EAAGoH,MAAMP,GAAGW,EAASV,GAEzC,OADAN,EAAc3B,KAAKkC,GACZA,CACT,CACA,MAAO,QAITxD,QAAS,KACPiD,EAAciB,QAAQC,GAASA,KAC/BlB,EAAcmB,OAAS,GAIzB,MAAI3H,GACF,OAAOF,GACT,EAEJ,CA2BA,SAAS8H,IACP,MAAO,CACL5C,SAAU,UAEV6C,SAAU,g2BAuBVC,OAAQ,CAAC,uFAQTC,QAAS,CACP,cAAMC,SACEC,KAAKC,oBACb,EAEA,WAAAC,GACEF,KAAKG,sBACP,EAEA,wBAAMF,GACJ,IACED,KAAKI,SAAU,EACfJ,KAAK7E,MAAQ,KAEb,MAAMpD,EAAKF,IACX,IAAKE,EACH,MAAM,IAAIgB,MAAM,gCAIlB,MAAMsH,EAAc,WAAWL,KAAKM,QAAQ9H,KAAKC,QAC3C8H,EAAiBlG,SAASC,cAAc,OAC9CiG,EAAeC,GAAKH,EACpBE,EAAeE,MAAMC,MAAQ,OAC7BH,EAAeE,MAAME,OAAS,OAE9BX,KAAKjG,UAAU6G,cAAcnG,UAAY,GACzCuF,KAAKjG,UAAU6G,cAAclG,YAAY6F,GAGzC,MAAMvC,EAAMjG,EAAGiG,IAAIgC,KAAKM,KAAM,CAC5BO,IAAKb,KAAKa,IACV9G,UAAW,IAAIsG,IACfS,UAAU,IAGZd,KAAKe,YAAc/C,QACbA,EAAIrC,QAEVqE,KAAKI,SAAU,EACfJ,KAAKgB,KAAKxC,KAAK,CAAE8B,KAAMN,KAAKM,KAAMO,IAAKb,KAAKa,KAE9C,CAAE,MAAOI,GACPhH,QAAQkB,MAAM,0BAA0B6E,KAAKM,QAASW,GACtDjB,KAAK7E,MAAQ8F,EAAIC,SAAW,+BAC5BlB,KAAKI,SAAU,EACfJ,KAAKmB,WAAW3C,KAAKyC,EACvB,CACF,EAEA,0BAAMd,GACJ,GAAIH,KAAKe,YAAa,CACpB,UACQf,KAAKe,YAAYnF,SACzB,CAAE,MAAOqF,GACPhH,QAAQC,KAAK,6BAA6B8F,KAAKM,QAASW,EAC1D,CACAjB,KAAKe,YAAc,IACrB,CACF,GAGN,CAMA,SAASK,IACP,MAAO,CACLC,QAAS,CAAC,gBACVC,aAAc,CAAC,mBACfC,QAAS,CAAC,mBAEd,CAKA,SAASC,KAAqBC,GAC5B,MAAM,IAAI1I,MAAM,0EAClB,CAMY,MAAC2I,EAAY,CACvBvI,WACA4C,qBACA2B,kBACAY,kBACAqB,wBACAyB,wBACAI,oBACA3J,gBACAK"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const n={apps:new Map};function t(){return"undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null}function e(n=5e3){return new Promise((e,o)=>{const r=t();if(r)return void e(r);const u=Date.now(),i=()=>{s(),e(t())};window.addEventListener("wu:ready",i),window.addEventListener("wu:app:ready",i);const a=setInterval(()=>{const r=t();if(r)return s(),void e(r);Date.now()-u>n&&(s(),o(new Error(`Wu Framework not found after ${n}ms`)))},200);function s(){clearInterval(a),window.removeEventListener("wu:ready",i),window.removeEventListener("wu:app:ready",i)}})}async function o(t,o,r={}){const{template:u,baseUrl:i=null}=o,{onMount:a=null,onUnmount:s=null,standalone:l=!0,standaloneContainer:c="#app"}=r;if(!u||"string"!=typeof u)throw new Error(`[WuHtmx] template (HTML string with hx-* attributes) is required for ${t}`);const w=e=>{if(e){n.apps.has(t)&&(console.warn(`[WuHtmx] ${t} already mounted, unmounting first`),d());try{if(e.innerHTML="",e.innerHTML=u,i){["hx-get","hx-post","hx-put","hx-patch","hx-delete"].forEach(n=>{e.querySelectorAll(`[${n}]`).forEach(t=>{const e=t.getAttribute(n);e&&e.startsWith("/")&&t.setAttribute(n,i+e)})})}window.htmx?window.htmx.process(e):console.warn("[WuHtmx] window.htmx not found - template inserted but hx-* attributes will not function"),n.apps.set(t,{container:e,config:o}),console.log(`[WuHtmx] ${t} mounted successfully`),a&&a(e)}catch(n){throw console.error(`[WuHtmx] Mount error for ${t}:`,n),n}}else console.error(`[WuHtmx] Mount failed for ${t}: container is null`)},d=e=>{const o=n.apps.get(t);if(o)try{s&&s(o.container),o.container.innerHTML="",n.apps.delete(t),console.log(`[WuHtmx] ${t} unmounted successfully`)}catch(n){console.error(`[WuHtmx] Unmount error for ${t}:`,n)}e&&(e.innerHTML="")};try{return(await e(3e3)).define(t,{mount:w,unmount:d}),console.log(`[WuHtmx] ${t} registered with Wu Framework`),!0}catch(n){if(console.warn(`[WuHtmx] Wu Framework not available for ${t}`),l){const n=document.querySelector(c);if(n)return console.log(`[WuHtmx] Running ${t} in standalone mode`),w(n),!0}return!1}}const r={register:o,getWuInstance:t,waitForWu:e};export{r as default,t as getWuInstance,o as register,e as waitForWu,r as wuHtmx};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/adapters/htmx/index.js"],"sourcesContent":["/**\n * WU-FRAMEWORK HTMX ADAPTER\n *\n * Bridges HTMX's hypermedia-driven approach into Wu Framework's\n * microfrontend graph. HTMX replaces JavaScript-heavy SPAs with\n * HTML-over-the-wire -- the server returns HTML fragments and HTMX\n * swaps them into the DOM. This adapter injects an HTML template\n * containing hx-* attributes, then calls htmx.process() to activate\n * the HTMX engine on that subtree.\n *\n * The inversion is elegant: instead of the client framework owning\n * the render cycle, the server does. Wu merely provides the container\n * and lifecycle boundaries.\n *\n * @example\n * import { wuHtmx } from 'wu-framework/adapters/htmx';\n *\n * wuHtmx.register('search', {\n * template: `\n * <div>\n * <input type=\"text\" name=\"q\"\n * hx-get=\"/api/search\"\n * hx-trigger=\"keyup changed delay:300ms\"\n * hx-target=\"#results\" />\n * <div id=\"results\"></div>\n * </div>\n * `\n * });\n *\n * @example\n * // With base URL configuration for HTMX endpoints\n * wuHtmx.register('feed', {\n * template: '<div hx-get=\"/api/feed\" hx-trigger=\"load\"></div>',\n * baseUrl: 'https://api.example.com'\n * }, {\n * onMount: (container) => console.log('HTMX fragment active')\n * });\n */\n\n// Adapter-scoped state\nconst adapterState = {\n apps: new Map()\n};\n\n/**\n * Obtiene la instancia de Wu Framework\n */\nfunction getWuInstance() {\n if (typeof window === 'undefined') return null;\n\n return window.wu\n || window.parent?.wu\n || window.top?.wu\n || null;\n}\n\n/**\n * Espera a que Wu Framework este disponible\n */\nfunction waitForWu(timeout = 5000) {\n return new Promise((resolve, reject) => {\n const wu = getWuInstance();\n if (wu) {\n resolve(wu);\n return;\n }\n\n const startTime = Date.now();\n\n const handleWuReady = () => {\n cleanup();\n resolve(getWuInstance());\n };\n\n window.addEventListener('wu:ready', handleWuReady);\n window.addEventListener('wu:app:ready', handleWuReady);\n\n const checkInterval = setInterval(() => {\n const wu = getWuInstance();\n if (wu) {\n cleanup();\n resolve(wu);\n return;\n }\n\n if (Date.now() - startTime > timeout) {\n cleanup();\n reject(new Error(`Wu Framework not found after ${timeout}ms`));\n }\n }, 200);\n\n function cleanup() {\n clearInterval(checkInterval);\n window.removeEventListener('wu:ready', handleWuReady);\n window.removeEventListener('wu:app:ready', handleWuReady);\n }\n });\n}\n\n/**\n * Registra una app HTMX como microfrontend\n *\n * @param {string} appName - Nombre unico del microfrontend\n * @param {Object} config - Configuracion de la app HTMX\n * @param {string} config.template - HTML string con atributos hx-*\n * @param {string} [config.baseUrl] - URL base para endpoints HTMX (se inyecta como hx-base)\n * @param {Object} [options] - Opciones adicionales\n * @param {Function} [options.onMount] - Callback despues de montar\n * @param {Function} [options.onUnmount] - Callback antes de desmontar\n * @param {boolean} [options.standalone=true] - Permitir ejecucion standalone\n * @param {string} [options.standaloneContainer='#app'] - Selector para modo standalone\n * @returns {Promise<boolean>} true si el registro fue exitoso\n */\nasync function register(appName, config, options = {}) {\n const { template, baseUrl = null } = config;\n\n const {\n onMount = null,\n onUnmount = null,\n standalone = true,\n standaloneContainer = '#app'\n } = options;\n\n if (!template || typeof template !== 'string') {\n throw new Error(`[WuHtmx] template (HTML string with hx-* attributes) is required for ${appName}`);\n }\n\n // Mount function\n const mountApp = (container) => {\n if (!container) {\n console.error(`[WuHtmx] Mount failed for ${appName}: container is null`);\n return;\n }\n\n // Prevent double-mount\n if (adapterState.apps.has(appName)) {\n console.warn(`[WuHtmx] ${appName} already mounted, unmounting first`);\n unmountApp();\n }\n\n try {\n container.innerHTML = '';\n\n // Inject template\n container.innerHTML = template;\n\n // If baseUrl is provided, rewrite relative hx-get/hx-post/etc. paths\n if (baseUrl) {\n const hxAttributes = ['hx-get', 'hx-post', 'hx-put', 'hx-patch', 'hx-delete'];\n hxAttributes.forEach((attr) => {\n container.querySelectorAll(`[${attr}]`).forEach((el) => {\n const val = el.getAttribute(attr);\n if (val && val.startsWith('/')) {\n el.setAttribute(attr, baseUrl + val);\n }\n });\n });\n }\n\n // Activate HTMX on this subtree\n if (window.htmx) {\n window.htmx.process(container);\n } else {\n console.warn(`[WuHtmx] window.htmx not found - template inserted but hx-* attributes will not function`);\n }\n\n adapterState.apps.set(appName, { container, config });\n\n console.log(`[WuHtmx] ${appName} mounted successfully`);\n\n if (onMount) {\n onMount(container);\n }\n } catch (error) {\n console.error(`[WuHtmx] Mount error for ${appName}:`, error);\n throw error;\n }\n };\n\n // Unmount function\n const unmountApp = (container) => {\n const appData = adapterState.apps.get(appName);\n\n if (appData) {\n try {\n if (onUnmount) {\n onUnmount(appData.container);\n }\n\n // Clear all HTMX-managed event listeners by wiping the subtree\n appData.container.innerHTML = '';\n adapterState.apps.delete(appName);\n\n console.log(`[WuHtmx] ${appName} unmounted successfully`);\n } catch (error) {\n console.error(`[WuHtmx] Unmount error for ${appName}:`, error);\n }\n }\n\n if (container) {\n container.innerHTML = '';\n }\n };\n\n // Register with Wu Framework or fall back to standalone\n try {\n const wu = await waitForWu(3000);\n\n wu.define(appName, {\n mount: mountApp,\n unmount: unmountApp\n });\n\n console.log(`[WuHtmx] ${appName} registered with Wu Framework`);\n return true;\n\n } catch (error) {\n console.warn(`[WuHtmx] Wu Framework not available for ${appName}`);\n\n if (standalone) {\n const containerElement = document.querySelector(standaloneContainer);\n\n if (containerElement) {\n console.log(`[WuHtmx] Running ${appName} in standalone mode`);\n mountApp(containerElement);\n return true;\n }\n }\n\n return false;\n }\n}\n\n// Public API\nexport const wuHtmx = {\n register,\n getWuInstance,\n waitForWu\n};\n\nexport { register, getWuInstance, waitForWu };\nexport default wuHtmx;\n"],"names":["adapterState","apps","Map","getWuInstance","window","wu","parent","top","waitForWu","timeout","Promise","resolve","reject","startTime","Date","now","handleWuReady","cleanup","addEventListener","checkInterval","setInterval","Error","clearInterval","removeEventListener","async","register","appName","config","options","template","baseUrl","onMount","onUnmount","standalone","standaloneContainer","mountApp","container","has","console","warn","unmountApp","innerHTML","forEach","attr","querySelectorAll","el","val","getAttribute","startsWith","setAttribute","htmx","process","set","log","error","appData","get","delete","define","mount","unmount","containerElement","document","querySelector","wuHtmx"],"mappings":"AAwCA,MAAMA,EAAe,CACnBC,KAAM,IAAIC,KAMZ,SAASC,IACP,MAAsB,oBAAXC,OAA+B,KAEnCA,OAAOC,IACTD,OAAOE,QAAQD,IACfD,OAAOG,KAAKF,IACZ,IACP,CAKA,SAASG,EAAUC,EAAU,KAC3B,OAAO,IAAIC,QAAQ,CAACC,EAASC,KAC3B,MAAMP,EAAKF,IACX,GAAIE,EAEF,YADAM,EAAQN,GAIV,MAAMQ,EAAYC,KAAKC,MAEjBC,EAAgB,KACpBC,IACAN,EAAQR,MAGVC,OAAOc,iBAAiB,WAAYF,GACpCZ,OAAOc,iBAAiB,eAAgBF,GAExC,MAAMG,EAAgBC,YAAY,KAChC,MAAMf,EAAKF,IACX,GAAIE,EAGF,OAFAY,SACAN,EAAQN,GAINS,KAAKC,MAAQF,EAAYJ,IAC3BQ,IACAL,EAAO,IAAIS,MAAM,gCAAgCZ,UAElD,KAEH,SAASQ,IACPK,cAAcH,GACdf,OAAOmB,oBAAoB,WAAYP,GACvCZ,OAAOmB,oBAAoB,eAAgBP,EAC7C,GAEJ,CAgBAQ,eAAeC,EAASC,EAASC,EAAQC,EAAU,CAAA,GACjD,MAAMC,SAAEA,EAAQC,QAAEA,EAAU,MAASH,GAE/BI,QACJA,EAAU,KAAIC,UACdA,EAAY,KAAIC,WAChBA,GAAa,EAAIC,oBACjBA,EAAsB,QACpBN,EAEJ,IAAKC,GAAgC,iBAAbA,EACtB,MAAM,IAAIR,MAAM,wEAAwEK,KAI1F,MAAMS,EAAYC,IAChB,GAAKA,EAAL,CAMIpC,EAAaC,KAAKoC,IAAIX,KACxBY,QAAQC,KAAK,YAAYb,uCACzBc,KAGF,IAOE,GANAJ,EAAUK,UAAY,GAGtBL,EAAUK,UAAYZ,EAGlBC,EAAS,CACU,CAAC,SAAU,UAAW,SAAU,WAAY,aACpDY,QAASC,IACpBP,EAAUQ,iBAAiB,IAAID,MAASD,QAASG,IAC/C,MAAMC,EAAMD,EAAGE,aAAaJ,GACxBG,GAAOA,EAAIE,WAAW,MACxBH,EAAGI,aAAaN,EAAMb,EAAUgB,MAIxC,CAGI1C,OAAO8C,KACT9C,OAAO8C,KAAKC,QAAQf,GAEpBE,QAAQC,KAAK,4FAGfvC,EAAaC,KAAKmD,IAAI1B,EAAS,CAAEU,YAAWT,WAE5CW,QAAQe,IAAI,YAAY3B,0BAEpBK,GACFA,EAAQK,EAEZ,CAAE,MAAOkB,GAEP,MADAhB,QAAQgB,MAAM,4BAA4B5B,KAAY4B,GAChDA,CACR,CA5CA,MAFEhB,QAAQgB,MAAM,6BAA6B5B,yBAkDzCc,EAAcJ,IAClB,MAAMmB,EAAUvD,EAAaC,KAAKuD,IAAI9B,GAEtC,GAAI6B,EACF,IACMvB,GACFA,EAAUuB,EAAQnB,WAIpBmB,EAAQnB,UAAUK,UAAY,GAC9BzC,EAAaC,KAAKwD,OAAO/B,GAEzBY,QAAQe,IAAI,YAAY3B,2BAC1B,CAAE,MAAO4B,GACPhB,QAAQgB,MAAM,8BAA8B5B,KAAY4B,EAC1D,CAGElB,IACFA,EAAUK,UAAY,KAK1B,IASE,aARiBjC,EAAU,MAExBkD,OAAOhC,EAAS,CACjBiC,MAAOxB,EACPyB,QAASpB,IAGXF,QAAQe,IAAI,YAAY3B,mCACjB,CAET,CAAE,MAAO4B,GAGP,GAFAhB,QAAQC,KAAK,2CAA2Cb,KAEpDO,EAAY,CACd,MAAM4B,EAAmBC,SAASC,cAAc7B,GAEhD,GAAI2B,EAGF,OAFAvB,QAAQe,IAAI,oBAAoB3B,wBAChCS,EAAS0B,IACF,CAEX,CAEA,OAAO,CACT,CACF,CAGY,MAACG,EAAS,CACpBvC,WACAtB,gBACAK"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export{createUseWuAI,createUseWuEvents,createUseWuStore,createWuSlot,register as registerReact,default as wuReact}from"./react/index.js";export{WuSlot,createUseWuAI as createVueUseWuAI,register as registerVue,useWuAI as useVueWuAI,useWuEvents,useWuStore,default as wuVue,wuVuePlugin}from"./vue/index.js";export{createWuAIService,createWuService,createWuSlotComponent,getWuSlotModuleConfig,register as registerAngular,registerStandalone as registerAngularStandalone,default as wuAngular}from"./angular/index.js";export{createWuStore as createSvelteWuStore,createWuAIStore,createWuEventStore,createWuSlotConfig,register as registerSvelte,registerSvelte5,useWuEvents as useSvelteWuEvents,default as wuSvelte}from"./svelte/index.js";export{createUseWuAI as createPreactUseWuAI,createUseWuEvents as createPreactUseWuEvents,createUseWuStore as createPreactUseWuStore,createWuSlot as createPreactWuSlot,register as registerPreact,registerCompat as registerPreactCompat,default as wuPreact}from"./preact/index.js";export{createUseWuAI as createSolidUseWuAI,createWuSlot as createSolidWuSlot,createWuStore as createSolidWuStore,createWuContext,createWuEvent,register as registerSolid,useWuEvents as useSolidWuEvents,default as wuSolid}from"./solid/index.js";export{WuAIMixin,WuMixin,createSimpleElement,createWuSlotElement,register as registerLit,registerWebComponent,default as wuLit,wuProperty}from"./lit/index.js";export{createComponent,createWuSlot as createVanillaWuSlot,registerClass,registerTemplate,register as registerVanilla,useWuAI as useVanillaWuAI,useWuEvents as useVanillaWuEvents,useWuStore as useVanillaWuStore,default as wuVanilla}from"./vanilla/index.js";export{register as registerAlpine,default as wuAlpine}from"./alpine/index.js";export{register as registerQwik,default as wuQwik}from"./qwik/index.js";export{register as registerStencil,default as wuStencil}from"./stencil/index.js";export{register as registerHtmx,default as wuHtmx}from"./htmx/index.js";export{register as registerStimulus,default as wuStimulus}from"./stimulus/index.js";export{getWuInstance,waitForWu}from"./shared.js";const e={react:()=>import("./react/index.js").then(e=>e.wuReact),vue:()=>import("./vue/index.js").then(e=>e.wuVue),angular:()=>import("./angular/index.js").then(e=>e.wuAngular),svelte:()=>import("./svelte/index.js").then(e=>e.wuSvelte),preact:()=>import("./preact/index.js").then(e=>e.wuPreact),solid:()=>import("./solid/index.js").then(e=>e.wuSolid),lit:()=>import("./lit/index.js").then(e=>e.wuLit),vanilla:()=>import("./vanilla/index.js").then(e=>e.wuVanilla),alpine:()=>import("./alpine/index.js").then(e=>e.wuAlpine),qwik:()=>import("./qwik/index.js").then(e=>e.wuQwik),stencil:()=>import("./stencil/index.js").then(e=>e.wuStencil),htmx:()=>import("./htmx/index.js").then(e=>e.wuHtmx),stimulus:()=>import("./stimulus/index.js").then(e=>e.wuStimulus)},t={},r={};function s(s){if(t[s])return Promise.resolve(t[s]);if(r[s])return r[s];const a=e[s];return a?(r[s]=a().then(e=>(t[s]=e,delete r[s],e),e=>{throw delete r[s],e}),r[s]):Promise.reject(new Error(`[wu-framework] Unknown adapter: '${s}'. Available: ${Object.keys(e).join(", ")}.`))}const a=Object.freeze(Object.keys(e));export{a as ADAPTER_NAMES,s as loadAdapter};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/adapters/index.js"],"sourcesContent":["/**\r\n * 🚀 WU-FRAMEWORK ADAPTERS\r\n *\r\n * Adapters oficiales para integrar Wu Framework con frameworks populares.\r\n * Soporta: React, Vue, Angular, Svelte, Preact, Solid.js, Lit, Vanilla JS,\r\n * Alpine.js, Qwik, Stencil, HTMX, Stimulus\r\n *\r\n * ⚠️ TREE-SHAKING: importa siempre desde el subpath específico, NO desde el barrel.\r\n *\r\n * ✅ import { wuReact } from 'wu-framework/adapters/react'; // ~3 KB\r\n * ❌ import { wuReact } from 'wu-framework/adapters'; // arrastra otros 12\r\n *\r\n * El barrel mantiene los re-exports nombrados (tree-shakeable con bundlers que\r\n * respetan `sideEffects: false`), pero los 13 adapters como objeto eager (`adapters.react`)\r\n * fue eliminado en v2.0 — usa `loadAdapter('react')` async si lo necesitas dinámicamente.\r\n *\r\n * @example\r\n * // Recomendado: import por subpath\r\n * import { wuReact } from 'wu-framework/adapters/react';\r\n * import { wuVue } from 'wu-framework/adapters/vue';\r\n *\r\n * @example\r\n * // Dinámico (carga bajo demanda)\r\n * import { loadAdapter } from 'wu-framework/adapters';\r\n * const wuReact = await loadAdapter('react');\r\n */\r\n\r\n// ============================================\r\n// REACT ADAPTER\r\n// ============================================\r\nexport {\r\n wuReact,\r\n register as registerReact,\r\n createWuSlot,\r\n createUseWuEvents,\r\n createUseWuStore,\r\n createUseWuAI\r\n} from './react/index.js';\r\n\r\n// ============================================\r\n// VUE ADAPTER\r\n// ============================================\r\nexport {\r\n wuVue,\r\n register as registerVue,\r\n WuSlot,\r\n useWuEvents,\r\n useWuStore,\r\n wuVuePlugin,\r\n createUseWuAI as createVueUseWuAI,\r\n useWuAI as useVueWuAI\r\n} from './vue/index.js';\r\n\r\n// ============================================\r\n// ANGULAR ADAPTER\r\n// ============================================\r\nexport {\r\n wuAngular,\r\n register as registerAngular,\r\n registerStandalone as registerAngularStandalone,\r\n createWuService,\r\n createWuSlotComponent,\r\n getWuSlotModuleConfig,\r\n createWuAIService\r\n} from './angular/index.js';\r\n\r\n// ============================================\r\n// SVELTE ADAPTER\r\n// ============================================\r\nexport {\r\n wuSvelte,\r\n register as registerSvelte,\r\n registerSvelte5,\r\n createWuStore as createSvelteWuStore,\r\n createWuEventStore,\r\n useWuEvents as useSvelteWuEvents,\r\n createWuSlotConfig,\r\n createWuAIStore\r\n} from './svelte/index.js';\r\n\r\n// ============================================\r\n// PREACT ADAPTER\r\n// ============================================\r\nexport {\r\n wuPreact,\r\n register as registerPreact,\r\n registerCompat as registerPreactCompat,\r\n createWuSlot as createPreactWuSlot,\r\n createUseWuEvents as createPreactUseWuEvents,\r\n createUseWuStore as createPreactUseWuStore,\r\n createUseWuAI as createPreactUseWuAI\r\n} from './preact/index.js';\r\n\r\n// ============================================\r\n// SOLID.JS ADAPTER\r\n// ============================================\r\nexport {\r\n wuSolid,\r\n register as registerSolid,\r\n createWuSlot as createSolidWuSlot,\r\n createWuStore as createSolidWuStore,\r\n createWuEvent,\r\n useWuEvents as useSolidWuEvents,\r\n createWuContext,\r\n createUseWuAI as createSolidUseWuAI\r\n} from './solid/index.js';\r\n\r\n// ============================================\r\n// LIT (WEB COMPONENTS) ADAPTER\r\n// ============================================\r\nexport {\r\n wuLit,\r\n register as registerLit,\r\n registerWebComponent,\r\n createWuSlotElement,\r\n WuMixin,\r\n WuAIMixin,\r\n wuProperty,\r\n createSimpleElement\r\n} from './lit/index.js';\r\n\r\n// ============================================\r\n// VANILLA JS ADAPTER\r\n// ============================================\r\nexport {\r\n wuVanilla,\r\n register as registerVanilla,\r\n registerClass,\r\n registerTemplate,\r\n createComponent,\r\n createWuSlot as createVanillaWuSlot,\r\n useWuEvents as useVanillaWuEvents,\r\n useWuStore as useVanillaWuStore,\r\n useWuAI as useVanillaWuAI\r\n} from './vanilla/index.js';\r\n\r\n// ============================================\r\n// ALPINE.JS ADAPTER\r\n// ============================================\r\nexport {\r\n wuAlpine,\r\n register as registerAlpine\r\n} from './alpine/index.js';\r\n\r\n// ============================================\r\n// QWIK ADAPTER\r\n// ============================================\r\nexport {\r\n wuQwik,\r\n register as registerQwik\r\n} from './qwik/index.js';\r\n\r\n// ============================================\r\n// STENCIL ADAPTER\r\n// ============================================\r\nexport {\r\n wuStencil,\r\n register as registerStencil\r\n} from './stencil/index.js';\r\n\r\n// ============================================\r\n// HTMX ADAPTER\r\n// ============================================\r\nexport {\r\n wuHtmx,\r\n register as registerHtmx\r\n} from './htmx/index.js';\r\n\r\n// ============================================\r\n// STIMULUS ADAPTER\r\n// ============================================\r\nexport {\r\n wuStimulus,\r\n register as registerStimulus\r\n} from './stimulus/index.js';\r\n\r\n// ============================================\r\n// SHARED UTILITIES\r\n// ============================================\r\nexport { getWuInstance, waitForWu } from './shared.js';\r\n\r\n// ============================================\r\n// LAZY ADAPTER LOADER (replaces the eager `adapters` object from v1.x)\r\n// ============================================\r\n\r\nconst ADAPTER_LOADERS = {\r\n react: () => import('./react/index.js').then(m => m.wuReact),\r\n vue: () => import('./vue/index.js').then(m => m.wuVue),\r\n angular: () => import('./angular/index.js').then(m => m.wuAngular),\r\n svelte: () => import('./svelte/index.js').then(m => m.wuSvelte),\r\n preact: () => import('./preact/index.js').then(m => m.wuPreact),\r\n solid: () => import('./solid/index.js').then(m => m.wuSolid),\r\n lit: () => import('./lit/index.js').then(m => m.wuLit),\r\n vanilla: () => import('./vanilla/index.js').then(m => m.wuVanilla),\r\n alpine: () => import('./alpine/index.js').then(m => m.wuAlpine),\r\n qwik: () => import('./qwik/index.js').then(m => m.wuQwik),\r\n stencil: () => import('./stencil/index.js').then(m => m.wuStencil),\r\n htmx: () => import('./htmx/index.js').then(m => m.wuHtmx),\r\n stimulus: () => import('./stimulus/index.js').then(m => m.wuStimulus)\r\n};\r\n\r\nconst _adapterCache = {};\r\n// In-flight loads, keyed by adapter name. Two concurrent loadAdapter('react')\r\n// calls share the same Promise instead of triggering a duplicate import().\r\n// ESM caches modules by URL so the second import would resolve to the same\r\n// instance, but we'd waste the network round-trip + parse work.\r\nconst _loadingPromises = {};\r\n\r\n/**\r\n * Load an adapter on demand. Returns a Promise that resolves to the wuX object.\r\n * Concurrent calls share the same in-flight promise.\r\n *\r\n * Replaces the eager `adapters` object that pulled all 13 frameworks at load time.\r\n *\r\n * @param {keyof typeof ADAPTER_LOADERS} name\r\n * @returns {Promise<object>}\r\n *\r\n * @example\r\n * const wuReact = await loadAdapter('react');\r\n * wuReact.register('cart', CartApp);\r\n */\r\nexport function loadAdapter(name) {\r\n if (_adapterCache[name]) return Promise.resolve(_adapterCache[name]);\r\n if (_loadingPromises[name]) return _loadingPromises[name];\r\n\r\n const loader = ADAPTER_LOADERS[name];\r\n if (!loader) {\r\n return Promise.reject(new Error(\r\n `[wu-framework] Unknown adapter: '${name}'. ` +\r\n `Available: ${Object.keys(ADAPTER_LOADERS).join(', ')}.`\r\n ));\r\n }\r\n\r\n _loadingPromises[name] = loader().then(\r\n adapter => {\r\n _adapterCache[name] = adapter;\r\n delete _loadingPromises[name];\r\n return adapter;\r\n },\r\n err => {\r\n // On failure, clear the in-flight slot so a retry is possible\r\n delete _loadingPromises[name];\r\n throw err;\r\n }\r\n );\r\n return _loadingPromises[name];\r\n}\r\n\r\n/**\r\n * Names of available adapters. Use with loadAdapter() to iterate.\r\n */\r\nexport const ADAPTER_NAMES = Object.freeze(Object.keys(ADAPTER_LOADERS));\r\n"],"names":["ADAPTER_LOADERS","react","import","then","m","wuReact","vue","wuVue","angular","wuAngular","svelte","wuSvelte","preact","wuPreact","solid","wuSolid","lit","wuLit","vanilla","wuVanilla","alpine","wuAlpine","qwik","wuQwik","stencil","wuStencil","htmx","wuHtmx","stimulus","wuStimulus","_adapterCache","_loadingPromises","loadAdapter","name","Promise","resolve","loader","adapter","err","reject","Error","Object","keys","join","ADAPTER_NAMES","freeze"],"mappings":"ojEAyLA,MAAMA,EAAkB,CACtBC,MAAU,IAAMC,OAAO,oBAAoBC,KAAKC,GAAKA,EAAEC,SACvDC,IAAU,IAAMJ,OAAO,kBAAkBC,KAAKC,GAAKA,EAAEG,OACrDC,QAAU,IAAMN,OAAO,sBAAsBC,KAAKC,GAAKA,EAAEK,WACzDC,OAAU,IAAMR,OAAO,qBAAqBC,KAAKC,GAAKA,EAAEO,UACxDC,OAAU,IAAMV,OAAO,qBAAqBC,KAAKC,GAAKA,EAAES,UACxDC,MAAU,IAAMZ,OAAO,oBAAoBC,KAAKC,GAAKA,EAAEW,SACvDC,IAAU,IAAMd,OAAO,kBAAkBC,KAAKC,GAAKA,EAAEa,OACrDC,QAAU,IAAMhB,OAAO,sBAAsBC,KAAKC,GAAKA,EAAEe,WACzDC,OAAU,IAAMlB,OAAO,qBAAqBC,KAAKC,GAAKA,EAAEiB,UACxDC,KAAU,IAAMpB,OAAO,mBAAmBC,KAAKC,GAAKA,EAAEmB,QACtDC,QAAU,IAAMtB,OAAO,sBAAsBC,KAAKC,GAAKA,EAAEqB,WACzDC,KAAU,IAAMxB,OAAO,mBAAmBC,KAAKC,GAAKA,EAAEuB,QACtDC,SAAU,IAAM1B,OAAO,uBAAuBC,KAAKC,GAAKA,EAAEyB,aAGtDC,EAAgB,CAAA,EAKhBC,EAAmB,CAAA,EAelB,SAASC,EAAYC,GAC1B,GAAIH,EAAcG,GAAO,OAAOC,QAAQC,QAAQL,EAAcG,IAC9D,GAAIF,EAAiBE,GAAO,OAAOF,EAAiBE,GAEpD,MAAMG,EAASpC,EAAgBiC,GAC/B,OAAKG,GAOLL,EAAiBE,GAAQG,IAASjC,KAChCkC,IACEP,EAAcG,GAAQI,SACfN,EAAiBE,GACjBI,GAETC,IAGE,aADOP,EAAiBE,GAClBK,IAGHP,EAAiBE,IAlBfC,QAAQK,OAAO,IAAIC,MACxB,oCAAoCP,kBACtBQ,OAAOC,KAAK1C,GAAiB2C,KAAK,UAiBtD,CAKY,MAACC,EAAgBH,OAAOI,OAAOJ,OAAOC,KAAK1C"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function t(t){return class extends t{constructor(){super(),this._wuAINamespace="default"}get wuAI(){return("undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null)?.ai||null}async wuAISend(t,e={}){const n=this.wuAI;return n?n.send(t,{namespace:this._wuAINamespace,...e}):(console.warn("[WuAIMixin] wu.ai not available"),null)}wuAISetNamespace(t){this._wuAINamespace=t}}}const e={apps:new Map,elements:new Map,lit:null,initialized:!1};function n(){return"undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null}function o(t=5e3){return new Promise((e,o)=>{const s=n();if(s)return void e(s);const r=Date.now(),a=()=>{u(),e(n())};window.addEventListener("wu:ready",a),window.addEventListener("wu:app:ready",a);const i=setInterval(()=>{const s=n();if(s)return u(),void e(s);Date.now()-r>t&&(u(),o(new Error(`Wu Framework not found after ${t}ms`)))},200);function u(){clearInterval(i),window.removeEventListener("wu:ready",a),window.removeEventListener("wu:app:ready",a)}})}async function s(t,s,r={}){const{tagName:a=null,properties:i={},onMount:u=null,onUnmount:c=null,standalone:l=!0,standaloneContainer:d="#root"}=r,p=a||function(t){return t.includes("-")?`wu-${t}`:`wu-app-${t}`}(t);if(!customElements.get(p))try{customElements.define(p,s),console.log(`[WuLit] Custom element <${p}> defined`)}catch(t){throw console.error("[WuLit] Failed to define custom element:",t),t}e.elements.set(t,{ElementClass:s,tagName:p});const w=o=>{if(o){e.apps.has(t)&&(console.warn(`[WuLit] ${t} already mounted, unmounting first`),m());try{o.innerHTML="";const s=document.createElement(p);Object.entries(i).forEach(([t,e])=>{s[t]=e}),s.wuAppName=t,s.wuInstance=n(),o.appendChild(s),e.apps.set(t,{element:s,container:o,tagName:p}),console.log(`[WuLit] ✅ ${t} (<${p}>) mounted successfully`),u&&u(o,s)}catch(e){throw console.error(`[WuLit] Mount error for ${t}:`,e),e}}else console.error(`[WuLit] Mount failed for ${t}: container is null`)},m=n=>{const o=e.apps.get(t);if(o)try{c&&c(o.container,o.element),o.element&&o.element.parentNode&&o.element.remove(),o.container.innerHTML="",e.apps.delete(t),console.log(`[WuLit] ✅ ${t} unmounted successfully`)}catch(e){console.error(`[WuLit] Unmount error for ${t}:`,e)}n&&(n.innerHTML="")};try{return(await o(3e3)).define(t,{mount:w,unmount:m}),console.log(`[WuLit] ✅ ${t} registered with Wu Framework`),!0}catch(e){if(console.warn(`[WuLit] Wu Framework not available for ${t}`),l){const e=document.querySelector(d);if(e)return console.log(`[WuLit] Running ${t} in standalone mode`),w(e),!0}return!1}}async function r(t,e,n={}){return s(t,e,n)}function a(t,e,o){class s extends t{static properties={name:{type:String},url:{type:String},appName:{type:String,attribute:"app-name"},fallbackText:{type:String,attribute:"fallback-text"},loading:{type:Boolean,state:!0},error:{type:String,state:!0}};static styles=o?o`
|
|
2
|
+
:host {
|
|
3
|
+
display: block;
|
|
4
|
+
min-height: 100px;
|
|
5
|
+
position: relative;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.wu-slot-loading {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
padding: 2rem;
|
|
13
|
+
color: #666;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.wu-slot-error {
|
|
17
|
+
padding: 1rem;
|
|
18
|
+
border: 1px solid #f5c6cb;
|
|
19
|
+
border-radius: 4px;
|
|
20
|
+
background: #f8d7da;
|
|
21
|
+
color: #721c24;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.wu-slot-error strong {
|
|
25
|
+
display: block;
|
|
26
|
+
margin-bottom: 0.5rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.wu-slot-content {
|
|
30
|
+
width: 100%;
|
|
31
|
+
height: 100%;
|
|
32
|
+
}
|
|
33
|
+
`:[];constructor(){super(),this.name="",this.url="",this.appName=null,this.fallbackText=null,this.loading=!0,this.error=null,this._appInstance=null}get actualAppName(){return this.appName||this.name}async connectedCallback(){super.connectedCallback(),await this.mountMicrofrontend()}disconnectedCallback(){super.disconnectedCallback(),this.unmountMicrofrontend()}async mountMicrofrontend(){try{this.loading=!0,this.error=null;const t=n();if(!t)throw new Error("Wu Framework not initialized");await this.updateComplete;const e=this.shadowRoot.querySelector(".wu-slot-content");if(!e)return;const o=`wu-slot-${this.actualAppName}-${Date.now()}`,s=document.createElement("div");s.id=o,s.style.cssText="width: 100%; height: 100%;",e.innerHTML="",e.appendChild(s);const r=t.app(this.actualAppName,{url:this.url,container:`#${o}`,autoInit:!0});this._appInstance=r,await r.mount(),this.loading=!1,this.dispatchEvent(new CustomEvent("wu-load",{detail:{name:this.actualAppName,url:this.url},bubbles:!0,composed:!0}))}catch(t){console.error(`[WuSlot] Error loading ${this.actualAppName}:`,t),this.error=t.message||"Failed to load microfrontend",this.loading=!1,this.dispatchEvent(new CustomEvent("wu-error",{detail:t,bubbles:!0,composed:!0}))}}async unmountMicrofrontend(){if(this._appInstance){this.dispatchEvent(new CustomEvent("wu-unmount",{detail:{name:this.actualAppName},bubbles:!0,composed:!0}));try{await this._appInstance.unmount()}catch(t){}this._appInstance=null}}render(){return this.error?e`
|
|
34
|
+
<div class="wu-slot-error">
|
|
35
|
+
<strong>Error loading ${this.name}</strong>
|
|
36
|
+
<span>${this.error}</span>
|
|
37
|
+
</div>
|
|
38
|
+
`:this.loading?e`
|
|
39
|
+
<div class="wu-slot-loading">
|
|
40
|
+
${this.fallbackText||`Loading ${this.name}...`}
|
|
41
|
+
</div>
|
|
42
|
+
<div class="wu-slot-content"></div>
|
|
43
|
+
`:e`<div class="wu-slot-content"></div>`}}return customElements.get("wu-slot")||customElements.define("wu-slot",s),s}function i(t){return class extends t{constructor(){super(),this._wuSubscriptions=[]}get wu(){return n()}wuEmit(t,e,n){const o=this.wu;o?.eventBus&&o.eventBus.emit(t,e,n)}wuOn(t,e){const n=this.wu;if(n?.eventBus){const o=n.eventBus.on(t,e);return this._wuSubscriptions.push(o),o}return()=>{}}wuOnce(t,e){const n=this.wu;return n?.eventBus?n.eventBus.once(t,e):()=>{}}wuGetState(t){const e=this.wu;return e?.store?.get(t)||null}wuSetState(t,e){const n=this.wu;n?.store&&n.store.set(t,e)}wuOnStateChange(t,e){const n=this.wu;if(n?.store){const o=n.store.on(t,e);return this._wuSubscriptions.push(o),o}return()=>{}}disconnectedCallback(){super.disconnectedCallback(),this._wuSubscriptions.forEach(t=>t()),this._wuSubscriptions=[]}}}function u(t){return function(e,o){const s=`_wu_${o}`;let r=null;Object.defineProperty(e,o,{get(){return this[s]},set(e){const o=n();o?.store&&o.store.set(t,e)},configurable:!0,enumerable:!0});const a=e.connectedCallback;e.connectedCallback=function(){a&&a.call(this);const e=n();e?.store&&(this[s]=e.store.get(t),r=e.store.on(t,t=>{this[s]=t,this.requestUpdate()}))};const i=e.disconnectedCallback;e.disconnectedCallback=function(){i&&i.call(this),r&&(r(),r=null)}}}function c(t){const{name:e,template:n,styles:o="",shadow:s=!0,...r}=t;class a extends HTMLElement{constructor(){super(),s&&this.attachShadow({mode:"open"})}connectedCallback(){const t=this.shadowRoot||this;if(o){const e=document.createElement("style");e.textContent=o,t.appendChild(e)}t.innerHTML+="function"==typeof n?n(this):n,r.connectedCallback&&r.connectedCallback.call(this)}disconnectedCallback(){r.disconnectedCallback&&r.disconnectedCallback.call(this)}attributeChangedCallback(t,e,n){r.attributeChangedCallback&&r.attributeChangedCallback.call(this,t,e,n)}}return r.observedAttributes&&(a.observedAttributes=r.observedAttributes),customElements.get(e)||customElements.define(e,a),a}const l={register:s,registerWebComponent:r,createWuSlotElement:a,WuMixin:i,WuAIMixin:t,wuProperty:u,createSimpleElement:c,getWuInstance:n,waitForWu:o};export{t as WuAIMixin,i as WuMixin,c as createSimpleElement,a as createWuSlotElement,l as default,n as getWuInstance,s as register,r as registerWebComponent,o as waitForWu,l as wuLit,u as wuProperty};
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/adapters/lit/ai.js","../../../src/adapters/lit/index.js"],"sourcesContent":["/**\r\n * WU-FRAMEWORK LIT AI INTEGRATION\r\n */\r\nfunction getWuInstance() {\r\n if (typeof window === 'undefined') return null;\r\n return window.wu || window.parent?.wu || window.top?.wu || null;\r\n}\r\n\r\nexport function WuAIMixin(Base) {\r\n return class extends Base {\r\n constructor() { super(); this._wuAINamespace = 'default'; }\r\n get wuAI() { return getWuInstance()?.ai || null; }\r\n async wuAISend(text, options = {}) {\r\n const ai = this.wuAI;\r\n if (!ai) { console.warn('[WuAIMixin] wu.ai not available'); return null; }\r\n return ai.send(text, { namespace: this._wuAINamespace, ...options });\r\n }\r\n wuAISetNamespace(ns) { this._wuAINamespace = ns; }\r\n };\r\n}\r\n","/**\r\n * 🚀 WU-FRAMEWORK LIT ADAPTER\r\n *\r\n * Simplifica la integración de Lit (Web Components) con Wu Framework.\r\n * Aprovecha los Web Components nativos con Shadow DOM incluido.\r\n *\r\n * @example\r\n * // Microfrontend (main.js)\r\n * import { wuLit } from 'wu-framework/adapters/lit';\r\n * import { MyApp } from './my-app';\r\n *\r\n * wuLit.register('my-app', MyApp);\r\n *\r\n * @example\r\n * // Usando LitElement\r\n * import { LitElement, html, css } from 'lit';\r\n *\r\n * class MyApp extends LitElement {\r\n * static styles = css`:host { display: block; }`;\r\n *\r\n * render() {\r\n * return html`<h1>Hello from Lit!</h1>`;\r\n * }\r\n * }\r\n *\r\n * wuLit.register('my-app', MyApp);\r\n */\r\n\r\n// Estado global del adapter\r\nconst adapterState = {\r\n apps: new Map(),\r\n elements: new Map(),\r\n lit: null,\r\n initialized: false\r\n};\r\n\r\n/**\r\n * Obtiene la instancia de Wu Framework\r\n */\r\nfunction getWuInstance() {\r\n if (typeof window === 'undefined') return null;\r\n\r\n return window.wu\r\n || window.parent?.wu\r\n || window.top?.wu\r\n || null;\r\n}\r\n\r\n/**\r\n * Espera a que Wu Framework esté disponible\r\n */\r\nfunction waitForWu(timeout = 5000) {\r\n return new Promise((resolve, reject) => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n\r\n const handleWuReady = () => {\r\n cleanup();\r\n resolve(getWuInstance());\r\n };\r\n\r\n window.addEventListener('wu:ready', handleWuReady);\r\n window.addEventListener('wu:app:ready', handleWuReady);\r\n\r\n const checkInterval = setInterval(() => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n cleanup();\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n if (Date.now() - startTime > timeout) {\r\n cleanup();\r\n reject(new Error(`Wu Framework not found after ${timeout}ms`));\r\n }\r\n }, 200);\r\n\r\n function cleanup() {\r\n clearInterval(checkInterval);\r\n window.removeEventListener('wu:ready', handleWuReady);\r\n window.removeEventListener('wu:app:ready', handleWuReady);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Genera un nombre de tag válido para Custom Elements\r\n */\r\nfunction generateTagName(appName) {\r\n // Custom elements deben tener un guión\r\n if (appName.includes('-')) {\r\n return `wu-${appName}`;\r\n }\r\n return `wu-app-${appName}`;\r\n}\r\n\r\n/**\r\n * Registra un LitElement como microfrontend\r\n *\r\n * @param {string} appName - Nombre único del microfrontend\r\n * @param {typeof LitElement} ElementClass - Clase que extiende LitElement\r\n * @param {Object} options - Opciones adicionales\r\n * @param {string} options.tagName - Nombre del custom element (auto-generado si no se provee)\r\n * @param {Object} options.properties - Propiedades iniciales\r\n * @param {Function} options.onMount - Callback después de montar\r\n * @param {Function} options.onUnmount - Callback antes de desmontar\r\n * @param {boolean} options.standalone - Permitir ejecución standalone (default: true)\r\n * @param {string} options.standaloneContainer - Selector para modo standalone (default: '#root')\r\n *\r\n * @example\r\n * import { LitElement, html } from 'lit';\r\n *\r\n * class HeaderApp extends LitElement {\r\n * render() {\r\n * return html`<header><h1>My Header</h1></header>`;\r\n * }\r\n * }\r\n *\r\n * wuLit.register('header', HeaderApp);\r\n */\r\nasync function register(appName, ElementClass, options = {}) {\r\n const {\r\n tagName = null,\r\n properties = {},\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#root'\r\n } = options;\r\n\r\n // Generar nombre de tag\r\n const customTagName = tagName || generateTagName(appName);\r\n\r\n // Registrar el Custom Element si no existe\r\n if (!customElements.get(customTagName)) {\r\n try {\r\n customElements.define(customTagName, ElementClass);\r\n console.log(`[WuLit] Custom element <${customTagName}> defined`);\r\n } catch (error) {\r\n console.error(`[WuLit] Failed to define custom element:`, error);\r\n throw error;\r\n }\r\n }\r\n\r\n // Guardar referencia de la clase\r\n adapterState.elements.set(appName, {\r\n ElementClass,\r\n tagName: customTagName\r\n });\r\n\r\n // Función de mount\r\n const mountApp = (container) => {\r\n if (!container) {\r\n console.error(`[WuLit] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n // Evitar doble mount\r\n if (adapterState.apps.has(appName)) {\r\n console.warn(`[WuLit] ${appName} already mounted, unmounting first`);\r\n unmountApp();\r\n }\r\n\r\n try {\r\n // Limpiar container\r\n container.innerHTML = '';\r\n\r\n // Crear elemento\r\n const element = document.createElement(customTagName);\r\n\r\n // Aplicar propiedades\r\n Object.entries(properties).forEach(([key, value]) => {\r\n element[key] = value;\r\n });\r\n\r\n // Inyectar información de Wu\r\n element.wuAppName = appName;\r\n element.wuInstance = getWuInstance();\r\n\r\n // Agregar al container\r\n container.appendChild(element);\r\n\r\n // Guardar referencia\r\n adapterState.apps.set(appName, {\r\n element,\r\n container,\r\n tagName: customTagName\r\n });\r\n\r\n console.log(`[WuLit] ✅ ${appName} (<${customTagName}>) mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, element);\r\n }\r\n } catch (error) {\r\n console.error(`[WuLit] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de unmount\r\n const unmountApp = (container) => {\r\n const appData = adapterState.apps.get(appName);\r\n\r\n if (appData) {\r\n try {\r\n if (onUnmount) {\r\n onUnmount(appData.container, appData.element);\r\n }\r\n\r\n // Remover elemento\r\n if (appData.element && appData.element.parentNode) {\r\n appData.element.remove();\r\n }\r\n\r\n // Limpiar container\r\n appData.container.innerHTML = '';\r\n\r\n adapterState.apps.delete(appName);\r\n\r\n console.log(`[WuLit] ✅ ${appName} unmounted successfully`);\r\n } catch (error) {\r\n console.error(`[WuLit] Unmount error for ${appName}:`, error);\r\n }\r\n }\r\n\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n // Intentar registrar con Wu Framework\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n console.log(`[WuLit] ✅ ${appName} registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n console.warn(`[WuLit] Wu Framework not available for ${appName}`);\r\n\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n\r\n if (containerElement) {\r\n console.log(`[WuLit] Running ${appName} in standalone mode`);\r\n mountApp(containerElement);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Registra un Web Component vanilla (sin Lit) como microfrontend\r\n *\r\n * @param {string} appName - Nombre del microfrontend\r\n * @param {typeof HTMLElement} ElementClass - Clase que extiende HTMLElement\r\n * @param {Object} options - Opciones\r\n *\r\n * @example\r\n * class MyWebComponent extends HTMLElement {\r\n * connectedCallback() {\r\n * this.attachShadow({ mode: 'open' });\r\n * this.shadowRoot.innerHTML = '<h1>Hello!</h1>';\r\n * }\r\n * }\r\n *\r\n * wuLit.registerWebComponent('my-component', MyWebComponent);\r\n */\r\nasync function registerWebComponent(appName, ElementClass, options = {}) {\r\n // Usar el mismo registro pero para HTMLElement vanilla\r\n return register(appName, ElementClass, options);\r\n}\r\n\r\n/**\r\n * Crea un LitElement wrapper que carga un microfrontend\r\n *\r\n * @example\r\n * import { html, LitElement } from 'lit';\r\n * import { createWuSlotElement } from 'wu-framework/adapters/lit';\r\n *\r\n * const WuSlot = createWuSlotElement(LitElement, html);\r\n *\r\n * // Uso en otro componente\r\n * render() {\r\n * return html`<wu-slot name=\"header\" url=\"http://localhost:3001\"></wu-slot>`;\r\n * }\r\n */\r\nfunction createWuSlotElement(LitElement, html, css) {\r\n class WuSlotElement extends LitElement {\r\n static properties = {\r\n name: { type: String },\r\n url: { type: String },\r\n appName: { type: String, attribute: 'app-name' },\r\n fallbackText: { type: String, attribute: 'fallback-text' },\r\n loading: { type: Boolean, state: true },\r\n error: { type: String, state: true }\r\n };\r\n\r\n static styles = css ? css`\r\n :host {\r\n display: block;\r\n min-height: 100px;\r\n position: relative;\r\n }\r\n\r\n .wu-slot-loading {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 2rem;\r\n color: #666;\r\n }\r\n\r\n .wu-slot-error {\r\n padding: 1rem;\r\n border: 1px solid #f5c6cb;\r\n border-radius: 4px;\r\n background: #f8d7da;\r\n color: #721c24;\r\n }\r\n\r\n .wu-slot-error strong {\r\n display: block;\r\n margin-bottom: 0.5rem;\r\n }\r\n\r\n .wu-slot-content {\r\n width: 100%;\r\n height: 100%;\r\n }\r\n ` : [];\r\n\r\n constructor() {\r\n super();\r\n this.name = '';\r\n this.url = '';\r\n this.appName = null;\r\n this.fallbackText = null;\r\n this.loading = true;\r\n this.error = null;\r\n this._appInstance = null;\r\n }\r\n\r\n get actualAppName() {\r\n return this.appName || this.name;\r\n }\r\n\r\n async connectedCallback() {\r\n super.connectedCallback();\r\n await this.mountMicrofrontend();\r\n }\r\n\r\n disconnectedCallback() {\r\n super.disconnectedCallback();\r\n this.unmountMicrofrontend();\r\n }\r\n\r\n async mountMicrofrontend() {\r\n try {\r\n this.loading = true;\r\n this.error = null;\r\n\r\n const wu = getWuInstance();\r\n if (!wu) {\r\n throw new Error('Wu Framework not initialized');\r\n }\r\n\r\n // Esperar a que el componente se renderice\r\n await this.updateComplete;\r\n\r\n const contentSlot = this.shadowRoot.querySelector('.wu-slot-content');\r\n if (!contentSlot) return;\r\n\r\n const containerId = `wu-slot-${this.actualAppName}-${Date.now()}`;\r\n const innerContainer = document.createElement('div');\r\n innerContainer.id = containerId;\r\n innerContainer.style.cssText = 'width: 100%; height: 100%;';\r\n\r\n contentSlot.innerHTML = '';\r\n contentSlot.appendChild(innerContainer);\r\n\r\n const app = wu.app(this.actualAppName, {\r\n url: this.url,\r\n container: `#${containerId}`,\r\n autoInit: true\r\n });\r\n\r\n this._appInstance = app;\r\n await app.mount();\r\n\r\n this.loading = false;\r\n this.dispatchEvent(new CustomEvent('wu-load', {\r\n detail: { name: this.actualAppName, url: this.url },\r\n bubbles: true,\r\n composed: true\r\n }));\r\n\r\n } catch (err) {\r\n console.error(`[WuSlot] Error loading ${this.actualAppName}:`, err);\r\n this.error = err.message || 'Failed to load microfrontend';\r\n this.loading = false;\r\n this.dispatchEvent(new CustomEvent('wu-error', {\r\n detail: err,\r\n bubbles: true,\r\n composed: true\r\n }));\r\n }\r\n }\r\n\r\n async unmountMicrofrontend() {\r\n if (this._appInstance) {\r\n this.dispatchEvent(new CustomEvent('wu-unmount', {\r\n detail: { name: this.actualAppName },\r\n bubbles: true,\r\n composed: true\r\n }));\r\n\r\n try {\r\n await this._appInstance.unmount();\r\n } catch (e) {}\r\n\r\n this._appInstance = null;\r\n }\r\n }\r\n\r\n render() {\r\n if (this.error) {\r\n return html`\r\n <div class=\"wu-slot-error\">\r\n <strong>Error loading ${this.name}</strong>\r\n <span>${this.error}</span>\r\n </div>\r\n `;\r\n }\r\n\r\n if (this.loading) {\r\n return html`\r\n <div class=\"wu-slot-loading\">\r\n ${this.fallbackText || `Loading ${this.name}...`}\r\n </div>\r\n <div class=\"wu-slot-content\"></div>\r\n `;\r\n }\r\n\r\n return html`<div class=\"wu-slot-content\"></div>`;\r\n }\r\n }\r\n\r\n // Registrar el elemento\r\n if (!customElements.get('wu-slot')) {\r\n customElements.define('wu-slot', WuSlotElement);\r\n }\r\n\r\n return WuSlotElement;\r\n}\r\n\r\n/**\r\n * Mixin para agregar capacidades de Wu a cualquier LitElement\r\n *\r\n * @example\r\n * import { LitElement } from 'lit';\r\n * import { WuMixin } from 'wu-framework/adapters/lit';\r\n *\r\n * class MyElement extends WuMixin(LitElement) {\r\n * connectedCallback() {\r\n * super.connectedCallback();\r\n *\r\n * // Usar eventos de Wu\r\n * this.wuOn('user:login', (data) => {\r\n * console.log('User logged in:', data);\r\n * });\r\n * }\r\n *\r\n * handleClick() {\r\n * this.wuEmit('button:clicked', { id: this.id });\r\n * }\r\n * }\r\n */\r\nfunction WuMixin(Base) {\r\n return class extends Base {\r\n constructor() {\r\n super();\r\n this._wuSubscriptions = [];\r\n }\r\n\r\n get wu() {\r\n return getWuInstance();\r\n }\r\n\r\n // Event Bus methods\r\n wuEmit(event, data, options) {\r\n const wu = this.wu;\r\n if (wu?.eventBus) {\r\n wu.eventBus.emit(event, data, options);\r\n }\r\n }\r\n\r\n wuOn(event, callback) {\r\n const wu = this.wu;\r\n if (wu?.eventBus) {\r\n const unsubscribe = wu.eventBus.on(event, callback);\r\n this._wuSubscriptions.push(unsubscribe);\r\n return unsubscribe;\r\n }\r\n return () => {};\r\n }\r\n\r\n wuOnce(event, callback) {\r\n const wu = this.wu;\r\n if (wu?.eventBus) {\r\n return wu.eventBus.once(event, callback);\r\n }\r\n return () => {};\r\n }\r\n\r\n // Store methods\r\n wuGetState(path) {\r\n const wu = this.wu;\r\n return wu?.store?.get(path) || null;\r\n }\r\n\r\n wuSetState(path, value) {\r\n const wu = this.wu;\r\n if (wu?.store) {\r\n wu.store.set(path, value);\r\n }\r\n }\r\n\r\n wuOnStateChange(pattern, callback) {\r\n const wu = this.wu;\r\n if (wu?.store) {\r\n const unsubscribe = wu.store.on(pattern, callback);\r\n this._wuSubscriptions.push(unsubscribe);\r\n return unsubscribe;\r\n }\r\n return () => {};\r\n }\r\n\r\n // Cleanup\r\n disconnectedCallback() {\r\n super.disconnectedCallback();\r\n this._wuSubscriptions.forEach(unsub => unsub());\r\n this._wuSubscriptions = [];\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Decorador reactivo para propiedades conectadas al store de Wu\r\n *\r\n * @example\r\n * import { LitElement } from 'lit';\r\n * import { wuProperty } from 'wu-framework/adapters/lit';\r\n *\r\n * class MyElement extends LitElement {\r\n * @wuProperty('user.name')\r\n * userName;\r\n *\r\n * render() {\r\n * return html`<p>Hello, ${this.userName}</p>`;\r\n * }\r\n * }\r\n */\r\nfunction wuProperty(storePath) {\r\n return function(target, propertyKey) {\r\n const privateKey = `_wu_${propertyKey}`;\r\n let unsubscribe = null;\r\n\r\n Object.defineProperty(target, propertyKey, {\r\n get() {\r\n return this[privateKey];\r\n },\r\n set(value) {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n wu.store.set(storePath, value);\r\n }\r\n },\r\n configurable: true,\r\n enumerable: true\r\n });\r\n\r\n // Hook into connectedCallback\r\n const originalConnected = target.connectedCallback;\r\n target.connectedCallback = function() {\r\n if (originalConnected) originalConnected.call(this);\r\n\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n // Set initial value\r\n this[privateKey] = wu.store.get(storePath);\r\n\r\n // Subscribe to changes\r\n unsubscribe = wu.store.on(storePath, (value) => {\r\n this[privateKey] = value;\r\n this.requestUpdate();\r\n });\r\n }\r\n };\r\n\r\n // Hook into disconnectedCallback\r\n const originalDisconnected = target.disconnectedCallback;\r\n target.disconnectedCallback = function() {\r\n if (originalDisconnected) originalDisconnected.call(this);\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Helper para crear un Web Component simple sin Lit\r\n *\r\n * @example\r\n * const MyComponent = createSimpleElement({\r\n * name: 'my-component',\r\n * template: '<h1>Hello!</h1>',\r\n * styles: ':host { display: block; color: blue; }',\r\n * connectedCallback() {\r\n * console.log('Connected!');\r\n * }\r\n * });\r\n */\r\nfunction createSimpleElement(config) {\r\n const {\r\n name,\r\n template,\r\n styles = '',\r\n shadow = true,\r\n ...callbacks\r\n } = config;\r\n\r\n class SimpleElement extends HTMLElement {\r\n constructor() {\r\n super();\r\n if (shadow) {\r\n this.attachShadow({ mode: 'open' });\r\n }\r\n }\r\n\r\n connectedCallback() {\r\n const root = this.shadowRoot || this;\r\n\r\n if (styles) {\r\n const styleEl = document.createElement('style');\r\n styleEl.textContent = styles;\r\n root.appendChild(styleEl);\r\n }\r\n\r\n if (typeof template === 'function') {\r\n root.innerHTML += template(this);\r\n } else {\r\n root.innerHTML += template;\r\n }\r\n\r\n if (callbacks.connectedCallback) {\r\n callbacks.connectedCallback.call(this);\r\n }\r\n }\r\n\r\n disconnectedCallback() {\r\n if (callbacks.disconnectedCallback) {\r\n callbacks.disconnectedCallback.call(this);\r\n }\r\n }\r\n\r\n attributeChangedCallback(name, oldVal, newVal) {\r\n if (callbacks.attributeChangedCallback) {\r\n callbacks.attributeChangedCallback.call(this, name, oldVal, newVal);\r\n }\r\n }\r\n }\r\n\r\n if (callbacks.observedAttributes) {\r\n SimpleElement.observedAttributes = callbacks.observedAttributes;\r\n }\r\n\r\n if (!customElements.get(name)) {\r\n customElements.define(name, SimpleElement);\r\n }\r\n\r\n return SimpleElement;\r\n}\r\n\r\n// ============================================\r\n// AI INTEGRATION\r\n// ============================================\r\nimport { WuAIMixin } from './ai.js';\r\n\r\n// API pública del adapter\r\nexport const wuLit = {\r\n register,\r\n registerWebComponent,\r\n createWuSlotElement,\r\n WuMixin,\r\n WuAIMixin,\r\n wuProperty,\r\n createSimpleElement,\r\n getWuInstance,\r\n waitForWu\r\n};\r\n\r\nexport {\r\n register,\r\n registerWebComponent,\r\n createWuSlotElement,\r\n WuMixin,\r\n WuAIMixin,\r\n wuProperty,\r\n createSimpleElement,\r\n getWuInstance,\r\n waitForWu\r\n};\r\n\r\nexport default wuLit;\r\n"],"names":["WuAIMixin","Base","constructor","super","this","_wuAINamespace","wuAI","window","wu","parent","top","ai","wuAISend","text","options","send","namespace","console","warn","wuAISetNamespace","ns","adapterState","apps","Map","elements","lit","initialized","getWuInstance","waitForWu","timeout","Promise","resolve","reject","startTime","Date","now","handleWuReady","cleanup","addEventListener","checkInterval","setInterval","Error","clearInterval","removeEventListener","async","register","appName","ElementClass","tagName","properties","onMount","onUnmount","standalone","standaloneContainer","customTagName","includes","generateTagName","customElements","get","define","log","error","set","mountApp","container","has","unmountApp","innerHTML","element","document","createElement","Object","entries","forEach","key","value","wuAppName","wuInstance","appendChild","appData","parentNode","remove","delete","mount","unmount","containerElement","querySelector","registerWebComponent","createWuSlotElement","LitElement","html","css","WuSlotElement","static","name","type","String","url","attribute","fallbackText","loading","Boolean","state","_appInstance","actualAppName","connectedCallback","mountMicrofrontend","disconnectedCallback","unmountMicrofrontend","updateComplete","contentSlot","shadowRoot","containerId","innerContainer","id","style","cssText","app","autoInit","dispatchEvent","CustomEvent","detail","bubbles","composed","err","message","e","render","WuMixin","_wuSubscriptions","wuEmit","event","data","eventBus","emit","wuOn","callback","unsubscribe","on","push","wuOnce","once","wuGetState","path","store","wuSetState","wuOnStateChange","pattern","unsub","wuProperty","storePath","target","propertyKey","privateKey","defineProperty","configurable","enumerable","originalConnected","call","requestUpdate","originalDisconnected","createSimpleElement","config","template","styles","shadow","callbacks","SimpleElement","HTMLElement","attachShadow","mode","root","styleEl","textContent","attributeChangedCallback","oldVal","newVal","observedAttributes","wuLit"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e){const{useState:n,useCallback:t}=e;return function(e={}){const{namespace:r="default"}=e,[o,a]=n([]),[u,c]=n(!1),[s,l]=n(null);return{messages:o,isStreaming:u,error:s,send:t(async e=>{if(!e?.trim())return;const n="undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null;if(n?.ai){a(n=>[...n,{id:`user-${Date.now()}`,role:"user",content:e,timestamp:Date.now()}]),c(!0),l(null);try{const t=await n.ai.send(e,{namespace:r});a(e=>[...e,{id:`assistant-${Date.now()}`,role:"assistant",content:t.content,timestamp:Date.now()}])}catch(e){l(e.message||"AI request failed")}c(!1)}else l("Wu AI not available")},[r]),clear:t(()=>{a([]),l(null)},[])}}}const n={apps:new Map,preact:null,render:null,h:null,initialized:!1};function t(){return"undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null}function r(e=5e3){return new Promise((n,r)=>{const o=t();if(o)return void n(o);const a=Date.now(),u=()=>{s(),n(t())};window.addEventListener("wu:ready",u),window.addEventListener("wu:app:ready",u);const c=setInterval(()=>{const o=t();if(o)return s(),void n(o);Date.now()-a>e&&(s(),r(new Error(`Wu Framework not found after ${e}ms`)))},200);function s(){clearInterval(c),window.removeEventListener("wu:ready",u),window.removeEventListener("wu:app:ready",u)}})}async function o(e,o,a={}){const{props:u={},onMount:c=null,onUnmount:s=null,standalone:l=!0,standaloneContainer:i="#app"}=a;if(!await async function(){if(n.initialized)return!0;try{if("undefined"!=typeof window&&window.preact)return n.preact=window.preact,n.render=window.preact.render,n.h=window.preact.h,n.initialized=!0,!0;const e=await import("preact");return n.preact=e,n.render=e.render,n.h=e.h,n.initialized=!0,!0}catch(e){return console.error("[WuPreact] Failed to load Preact:",e),!1}}())return console.error(`[WuPreact] Cannot register ${e}: Preact not available`),!1;const{render:d,h:w}=n,p=r=>{if(r){n.apps.has(e)&&(console.warn(`[WuPreact] ${e} already mounted, unmounting first`),f());try{r.innerHTML="",d(w(o,{...u,wuAppName:e,wuInstance:t()}),r),n.apps.set(e,{container:r,Component:o}),console.log(`[WuPreact] ✅ ${e} mounted successfully`),c&&c(r)}catch(n){throw console.error(`[WuPreact] Mount error for ${e}:`,n),n}}else console.error(`[WuPreact] Mount failed for ${e}: container is null`)},f=t=>{const r=n.apps.get(e);if(r)try{s&&s(r.container),d(null,r.container),n.apps.delete(e),console.log(`[WuPreact] ✅ ${e} unmounted successfully`)}catch(n){console.error(`[WuPreact] Unmount error for ${e}:`,n)}t&&(t.innerHTML="")};try{return(await r(3e3)).define(e,{mount:p,unmount:f}),console.log(`[WuPreact] ✅ ${e} registered with Wu Framework`),!0}catch(n){if(console.warn(`[WuPreact] Wu Framework not available for ${e}`),l){const n=document.querySelector(i);if(n)return console.log(`[WuPreact] Running ${e} in standalone mode`),p(n),!0}return!1}}async function a(e,a,u={}){const{props:c={},onMount:s=null,onUnmount:l=null,standalone:i=!0,standaloneContainer:d="#app"}=u;let w,p;try{const e=await import("preact/compat");w=e.render,p=e.createElement}catch(n){return console.error("[WuPreact] preact/compat not available"),o(e,a,u)}const f=r=>{if(r){n.apps.has(e)&&m();try{r.innerHTML="",w(p(a,{...c,wuAppName:e,wuInstance:t()}),r),n.apps.set(e,{container:r,Component:a,isCompat:!0}),console.log(`[WuPreact] ✅ ${e} (compat) mounted successfully`),s&&s(r)}catch(n){throw console.error(`[WuPreact] Mount error for ${e}:`,n),n}}},m=t=>{const r=n.apps.get(e);if(r)try{l&&l(r.container),w(null,r.container),n.apps.delete(e),console.log(`[WuPreact] ✅ ${e} (compat) unmounted successfully`)}catch(n){console.error(`[WuPreact] Unmount error for ${e}:`,n)}t&&(t.innerHTML="")};try{return(await r(3e3)).define(e,{mount:f,unmount:m}),console.log(`[WuPreact] ✅ ${e} (compat) registered with Wu Framework`),!0}catch(e){if(i){const e=document.querySelector(d);if(e)return f(e),!0}return!1}}function u(e){let n,r,o,a;try{const e=require("preact/hooks");n=e.useState,r=e.useEffect,o=e.useRef,a=e.useCallback}catch(n){return function(n){const{name:r,url:o}=n;return e("div",{class:"wu-slot","data-wu-app":r,"data-wu-url":o,style:"min-height: 100px;",ref:e=>{e&&!e._mounted&&(e._mounted=!0,async function(e,n,r){try{const o=t();if(!o)return;const a=`wu-slot-${n}-${Date.now()}`,u=document.createElement("div");u.id=a,u.style.cssText="width: 100%; height: 100%;",e.innerHTML="",e.appendChild(u);const c=o.app(n,{url:r,container:`#${a}`,autoInit:!0});await c.mount()}catch(n){e.innerHTML=`<div style="color: red;">Error: ${n.message}</div>`}}(e,r,o))}},`Loading ${r}...`)}}return function(u){const{name:c,url:s,appName:l=null,fallback:i=null,onLoad:d=null,onError:w=null,className:p="",style:f={}}=u,m=o(null),y=o(null),[g,h]=n(!0),[$,v]=n(null),W=l||c,P=a(async()=>{if(m.current)try{h(!0),v(null);const e=t();if(!e)throw new Error("Wu Framework not initialized");const n=`wu-slot-${W}-${Date.now()}`,r=document.createElement("div");r.id=n,r.style.cssText="width: 100%; height: 100%;",m.current.innerHTML="",m.current.appendChild(r);const o=e.app(W,{url:s,container:`#${n}`,autoInit:!0});y.current=o,await o.mount(),h(!1),d&&d({name:W,url:s})}catch(e){console.error(`[WuSlot] Error loading ${W}:`,e),v(e.message||"Failed to load microfrontend"),h(!1),w&&w(e)}},[W,s,d,w]);return r(()=>(P(),()=>{y.current&&(y.current.unmount().catch(console.warn),y.current=null)}),[P]),$?e("div",{class:`wu-slot wu-slot-error ${p}`,style:{padding:"1rem",border:"1px solid #f5c6cb",borderRadius:"4px",backgroundColor:"#f8d7da",color:"#721c24",...f}},[e("strong",null,`Error loading ${c}`),e("p",{style:{margin:"0.5rem 0 0 0"}},$)]):e("div",{ref:m,class:`wu-slot ${g?"wu-slot-loading":"wu-slot-loaded"} ${p}`,style:{minHeight:"100px",position:"relative",...f},"data-wu-app":W,"data-wu-url":s},g&&(i||e("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",padding:"2rem",color:"#666"}},`Loading ${c}...`)))}}function c(e){const{useCallback:n,useEffect:r,useRef:o}=e;return function(){const e=o([]),a=n((e,n,r)=>{const o=t();o?.eventBus&&o.eventBus.emit(e,n,r)},[]),u=n((n,r)=>{const o=t();if(o?.eventBus){const t=o.eventBus.on(n,r);return e.current.push(t),t}return()=>{}},[]),c=n((e,n)=>{const r=t();return r?.eventBus?r.eventBus.once(e,n):()=>{}},[]);return r(()=>()=>{e.current.forEach(e=>e()),e.current=[]},[]),{emit:a,on:u,once:c}}}function s(e){const{useState:n,useCallback:r,useEffect:o}=e;return function(e=""){const[a,u]=n(()=>{const n=t();return n?.store?.get(e)||null}),c=r((n,r)=>{const o=t();if(o?.store){const t=e?`${e}.${n}`:n;o.store.set(t,r)}},[e]),s=r((n="")=>{const r=t();if(r?.store){const t=e?n?`${e}.${n}`:e:n;return r.store.get(t)}return null},[e]);return o(()=>{const n=t();if(!n?.store)return;const r=e?`${e}.*`:"*";return n.store.on(r,()=>{u(n.store.get(e))})},[e]),{state:a,setState:c,getState:s}}}const l={register:o,registerCompat:a,createWuSlot:u,createUseWuEvents:c,createUseWuStore:s,createUseWuAI:e,getWuInstance:t,waitForWu:r};export{e as createUseWuAI,c as createUseWuEvents,s as createUseWuStore,u as createWuSlot,l as default,t as getWuInstance,o as register,a as registerCompat,r as waitForWu,l as wuPreact};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|